1// SPDX-License-Identifier: GPL-2.0
2//
3// JZ4725B CODEC driver
4//
5// Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/platform_device.h>
10#include <linux/slab.h>
11#include <linux/io.h>
12#include <linux/iopoll.h>
13#include <linux/regmap.h>
14#include <linux/clk.h>
15
16#include <linux/delay.h>
17
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/initval.h>
22#include <sound/soc.h>
23#include <sound/tlv.h>
24
25#define ICDC_RGADW_OFFSET		0x00
26#define ICDC_RGDATA_OFFSET		0x04
27
28/* ICDC internal register access control register(RGADW) */
29#define ICDC_RGADW_RGWR			BIT(16)
30
31#define ICDC_RGADW_RGADDR_OFFSET	8
32#define	ICDC_RGADW_RGADDR_MASK		GENMASK(14, ICDC_RGADW_RGADDR_OFFSET)
33
34#define ICDC_RGADW_RGDIN_OFFSET		0
35#define	ICDC_RGADW_RGDIN_MASK		GENMASK(7, ICDC_RGADW_RGDIN_OFFSET)
36
37/* ICDC internal register data output register (RGDATA)*/
38#define ICDC_RGDATA_IRQ			BIT(8)
39
40#define ICDC_RGDATA_RGDOUT_OFFSET	0
41#define ICDC_RGDATA_RGDOUT_MASK		GENMASK(7, ICDC_RGDATA_RGDOUT_OFFSET)
42
43/* JZ internal register space */
44enum {
45	JZ4725B_CODEC_REG_AICR,
46	JZ4725B_CODEC_REG_CR1,
47	JZ4725B_CODEC_REG_CR2,
48	JZ4725B_CODEC_REG_CCR1,
49	JZ4725B_CODEC_REG_CCR2,
50	JZ4725B_CODEC_REG_PMR1,
51	JZ4725B_CODEC_REG_PMR2,
52	JZ4725B_CODEC_REG_CRR,
53	JZ4725B_CODEC_REG_ICR,
54	JZ4725B_CODEC_REG_IFR,
55	JZ4725B_CODEC_REG_CGR1,
56	JZ4725B_CODEC_REG_CGR2,
57	JZ4725B_CODEC_REG_CGR3,
58	JZ4725B_CODEC_REG_CGR4,
59	JZ4725B_CODEC_REG_CGR5,
60	JZ4725B_CODEC_REG_CGR6,
61	JZ4725B_CODEC_REG_CGR7,
62	JZ4725B_CODEC_REG_CGR8,
63	JZ4725B_CODEC_REG_CGR9,
64	JZ4725B_CODEC_REG_CGR10,
65	JZ4725B_CODEC_REG_TR1,
66	JZ4725B_CODEC_REG_TR2,
67	JZ4725B_CODEC_REG_CR3,
68	JZ4725B_CODEC_REG_AGC1,
69	JZ4725B_CODEC_REG_AGC2,
70	JZ4725B_CODEC_REG_AGC3,
71	JZ4725B_CODEC_REG_AGC4,
72	JZ4725B_CODEC_REG_AGC5,
73};
74
75#define REG_AICR_CONFIG1_OFFSET		0
76#define REG_AICR_CONFIG1_MASK		(0xf << REG_AICR_CONFIG1_OFFSET)
77
78#define REG_CR1_SB_MICBIAS_OFFSET	7
79#define REG_CR1_MONO_OFFSET		6
80#define REG_CR1_DAC_MUTE_OFFSET		5
81#define REG_CR1_HP_DIS_OFFSET		4
82#define REG_CR1_DACSEL_OFFSET		3
83#define REG_CR1_BYPASS_OFFSET		2
84
85#define REG_CR2_DAC_DEEMP_OFFSET	7
86#define REG_CR2_DAC_ADWL_OFFSET		5
87#define REG_CR2_DAC_ADWL_MASK		(0x3 << REG_CR2_DAC_ADWL_OFFSET)
88#define REG_CR2_ADC_ADWL_OFFSET		3
89#define REG_CR2_ADC_ADWL_MASK		(0x3 << REG_CR2_ADC_ADWL_OFFSET)
90#define REG_CR2_ADC_HPF_OFFSET		2
91
92#define REG_CR3_SB_MIC1_OFFSET		7
93#define REG_CR3_SB_MIC2_OFFSET		6
94#define REG_CR3_SIDETONE1_OFFSET	5
95#define REG_CR3_SIDETONE2_OFFSET	4
96#define REG_CR3_MICDIFF_OFFSET		3
97#define REG_CR3_MICSTEREO_OFFSET	2
98#define REG_CR3_INSEL_OFFSET		0
99#define REG_CR3_INSEL_MASK		(0x3 << REG_CR3_INSEL_OFFSET)
100
101#define REG_CCR1_CONFIG4_OFFSET		0
102#define REG_CCR1_CONFIG4_MASK		(0xf << REG_CCR1_CONFIG4_OFFSET)
103
104#define REG_CCR2_DFREQ_OFFSET		4
105#define REG_CCR2_DFREQ_MASK		(0xf << REG_CCR2_DFREQ_OFFSET)
106#define REG_CCR2_AFREQ_OFFSET		0
107#define REG_CCR2_AFREQ_MASK		(0xf << REG_CCR2_AFREQ_OFFSET)
108
109#define REG_PMR1_SB_DAC_OFFSET		7
110#define REG_PMR1_SB_OUT_OFFSET		6
111#define REG_PMR1_SB_MIX_OFFSET		5
112#define REG_PMR1_SB_ADC_OFFSET		4
113#define REG_PMR1_SB_LIN_OFFSET		3
114#define REG_PMR1_SB_IND_OFFSET		0
115
116#define REG_PMR2_LRGI_OFFSET		7
117#define REG_PMR2_RLGI_OFFSET		6
118#define REG_PMR2_LRGOD_OFFSET		5
119#define REG_PMR2_RLGOD_OFFSET		4
120#define REG_PMR2_GIM_OFFSET		3
121#define REG_PMR2_SB_MC_OFFSET		2
122#define REG_PMR2_SB_OFFSET		1
123#define REG_PMR2_SB_SLEEP_OFFSET	0
124
125#define REG_IFR_RAMP_UP_DONE_OFFSET	3
126#define REG_IFR_RAMP_DOWN_DONE_OFFSET	2
127
128#define REG_CGR1_GODL_OFFSET		4
129#define REG_CGR1_GODL_MASK		(0xf << REG_CGR1_GODL_OFFSET)
130#define REG_CGR1_GODR_OFFSET		0
131#define REG_CGR1_GODR_MASK		(0xf << REG_CGR1_GODR_OFFSET)
132
133#define REG_CGR2_GO1R_OFFSET		0
134#define REG_CGR2_GO1R_MASK		(0x1f << REG_CGR2_GO1R_OFFSET)
135
136#define REG_CGR3_GO1L_OFFSET		0
137#define REG_CGR3_GO1L_MASK		(0x1f << REG_CGR3_GO1L_OFFSET)
138
139#define REG_CGR4_GO2R_OFFSET		0
140#define REG_CGR4_GO2R_MASK		(0x1f << REG_CGR4_GO2R_OFFSET)
141
142#define REG_CGR5_GO2L_OFFSET		0
143#define REG_CGR5_GO2L_MASK		(0x1f << REG_CGR5_GO2L_OFFSET)
144
145#define REG_CGR6_GO3R_OFFSET		0
146#define REG_CGR6_GO3R_MASK		(0x1f << REG_CGR6_GO3R_OFFSET)
147
148#define REG_CGR7_GO3L_OFFSET		0
149#define REG_CGR7_GO3L_MASK		(0x1f << REG_CGR7_GO3L_OFFSET)
150
151#define REG_CGR8_GOR_OFFSET		0
152#define REG_CGR8_GOR_MASK		(0x1f << REG_CGR8_GOR_OFFSET)
153
154#define REG_CGR9_GOL_OFFSET		0
155#define REG_CGR9_GOL_MASK		(0x1f << REG_CGR9_GOL_OFFSET)
156
157#define REG_CGR10_GIL_OFFSET		0
158#define REG_CGR10_GIR_OFFSET		4
159
160struct jz_icdc {
161	struct regmap *regmap;
162	void __iomem *base;
163	struct clk *clk;
164};
165
166static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv,     0, 150, 0);
167static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
168static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(jz4725b_mix_tlv,
169	 0, 11, TLV_DB_SCALE_ITEM(-2250,   0, 0),
170	12, 31, TLV_DB_SCALE_ITEM(-2250, 150, 0),
171);
172
173static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(jz4725b_out_tlv,
174	 0, 11, TLV_DB_SCALE_ITEM(-3350, 200, 0),
175	12, 23, TLV_DB_SCALE_ITEM(-1050, 100, 0),
176	24, 31, TLV_DB_SCALE_ITEM(  100,  50, 0),
177);
178static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_mic_boost_tlv, 0, 2000, 0);
179
180static const char * const jz4725b_mic_mode_texts[] = {
181	"Single Ended", "Differential",
182};
183
184static const struct soc_enum jz4725b_mic_mode_enum =
185	SOC_ENUM_SINGLE(JZ4725B_CODEC_REG_CR3, REG_CR3_MICDIFF_OFFSET,
186			2, jz4725b_mic_mode_texts);
187
188static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
189	SOC_DOUBLE_TLV("DAC Playback Volume",
190		       JZ4725B_CODEC_REG_CGR1,
191		       REG_CGR1_GODL_OFFSET,
192		       REG_CGR1_GODR_OFFSET,
193		       0xf, 1, jz4725b_dac_tlv),
194	SOC_DOUBLE_TLV("Master Capture Volume",
195		       JZ4725B_CODEC_REG_CGR10,
196		       REG_CGR10_GIL_OFFSET,
197		       REG_CGR10_GIR_OFFSET,
198		       0xf, 0, jz4725b_adc_tlv),
199	SOC_DOUBLE_R_TLV("Mixer Line In Bypass Playback Volume",
200			 JZ4725B_CODEC_REG_CGR3,
201			 JZ4725B_CODEC_REG_CGR2,
202			 REG_CGR2_GO1R_OFFSET,
203			 0x1f, 1, jz4725b_mix_tlv),
204	SOC_DOUBLE_R_TLV("Mixer Mic 1 Bypass Playback Volume",
205			 JZ4725B_CODEC_REG_CGR5,
206			 JZ4725B_CODEC_REG_CGR4,
207			 REG_CGR4_GO2R_OFFSET,
208			 0x1f, 1, jz4725b_mix_tlv),
209	SOC_DOUBLE_R_TLV("Mixer Mic 2 Bypass Playback Volume",
210			 JZ4725B_CODEC_REG_CGR7,
211			 JZ4725B_CODEC_REG_CGR6,
212			 REG_CGR6_GO3R_OFFSET,
213			 0x1f, 1, jz4725b_mix_tlv),
214
215	SOC_DOUBLE_R_TLV("Master Playback Volume",
216			 JZ4725B_CODEC_REG_CGR9,
217			 JZ4725B_CODEC_REG_CGR8,
218			 REG_CGR8_GOR_OFFSET,
219			 0x1f, 1, jz4725b_out_tlv),
220
221	SOC_SINGLE("DAC Playback Switch", JZ4725B_CODEC_REG_CR1,
222		   REG_CR1_DAC_MUTE_OFFSET, 1, 1),
223
224	SOC_SINGLE("Deemphasize Filter Playback Switch",
225		   JZ4725B_CODEC_REG_CR2,
226		   REG_CR2_DAC_DEEMP_OFFSET, 1, 0),
227
228	SOC_SINGLE("High-Pass Filter Capture Switch",
229		   JZ4725B_CODEC_REG_CR2,
230		   REG_CR2_ADC_HPF_OFFSET, 1, 0),
231
232	SOC_ENUM("Mic Mode Capture Switch", jz4725b_mic_mode_enum),
233
234	SOC_SINGLE_TLV("Mic1 Boost Capture Volume",
235		       JZ4725B_CODEC_REG_PMR2,
236		       REG_PMR2_GIM_OFFSET,
237		       1, 0, jz4725b_mic_boost_tlv),
238};
239
240static const char * const jz4725b_codec_adc_src_texts[] = {
241	"Mic 1", "Mic 2", "Line In", "Mixer",
242};
243static const unsigned int jz4725b_codec_adc_src_values[] = { 0, 1, 2, 3, };
244static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
245				  JZ4725B_CODEC_REG_CR3,
246				  REG_CR3_INSEL_OFFSET,
247				  REG_CR3_INSEL_MASK,
248				  jz4725b_codec_adc_src_texts,
249				  jz4725b_codec_adc_src_values);
250static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
251	SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
252
253static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
254	SOC_DAPM_SINGLE("Line In Bypass Playback Switch", JZ4725B_CODEC_REG_CR1,
255			REG_CR1_BYPASS_OFFSET, 1, 0),
256	SOC_DAPM_SINGLE("Mic 1 Bypass Playback Switch", JZ4725B_CODEC_REG_CR3,
257			REG_CR3_SIDETONE1_OFFSET, 1, 0),
258	SOC_DAPM_SINGLE("Mic 2 Bypass Playback Switch", JZ4725B_CODEC_REG_CR3,
259			REG_CR3_SIDETONE2_OFFSET, 1, 0),
260};
261
262static int jz4725b_out_stage_enable(struct snd_soc_dapm_widget *w,
263				    struct snd_kcontrol *kcontrol,
264				    int event)
265{
266	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
267	struct jz_icdc *icdc = snd_soc_component_get_drvdata(codec);
268	struct regmap *map = icdc->regmap;
269	unsigned int val;
270
271	switch (event) {
272	case SND_SOC_DAPM_PRE_PMU:
273		return regmap_clear_bits(map, JZ4725B_CODEC_REG_IFR,
274					 BIT(REG_IFR_RAMP_UP_DONE_OFFSET));
275	case SND_SOC_DAPM_POST_PMU:
276		return regmap_read_poll_timeout(map, JZ4725B_CODEC_REG_IFR,
277			       val, val & BIT(REG_IFR_RAMP_UP_DONE_OFFSET),
278			       100000, 500000);
279	case SND_SOC_DAPM_PRE_PMD:
280		return regmap_clear_bits(map, JZ4725B_CODEC_REG_IFR,
281				BIT(REG_IFR_RAMP_DOWN_DONE_OFFSET));
282	case SND_SOC_DAPM_POST_PMD:
283		return regmap_read_poll_timeout(map, JZ4725B_CODEC_REG_IFR,
284			       val, val & BIT(REG_IFR_RAMP_DOWN_DONE_OFFSET),
285			       100000, 500000);
286	default:
287		return -EINVAL;
288	}
289}
290
291static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
292	/* DAC */
293	SND_SOC_DAPM_DAC("DAC", "Playback",
294			 JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_DAC_OFFSET, 1),
295
296	/* ADC */
297	SND_SOC_DAPM_ADC("ADC", "Capture",
298			 JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
299
300	SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
301			 &jz4725b_codec_adc_src_ctrl),
302
303	/* Mixer */
304	SND_SOC_DAPM_MIXER("Mixer", JZ4725B_CODEC_REG_PMR1,
305			   REG_PMR1_SB_MIX_OFFSET, 1,
306			   jz4725b_codec_mixer_controls,
307			   ARRAY_SIZE(jz4725b_codec_mixer_controls)),
308	SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
309			   REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
310
311	SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
312			   REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
313	SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
314			   REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
315
316	SND_SOC_DAPM_MIXER("Mic 1", JZ4725B_CODEC_REG_CR3,
317			   REG_CR3_SB_MIC1_OFFSET, 1, NULL, 0),
318	SND_SOC_DAPM_MIXER("Mic 2", JZ4725B_CODEC_REG_CR3,
319			   REG_CR3_SB_MIC2_OFFSET, 1, NULL, 0),
320
321	SND_SOC_DAPM_MIXER_E("Out Stage", JZ4725B_CODEC_REG_PMR1,
322			     REG_PMR1_SB_OUT_OFFSET, 1, NULL, 0,
323			     jz4725b_out_stage_enable,
324			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
325			     SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
326	SND_SOC_DAPM_MIXER("Mixer to ADC", JZ4725B_CODEC_REG_PMR1,
327			   REG_PMR1_SB_IND_OFFSET, 1, NULL, 0),
328
329	SND_SOC_DAPM_SUPPLY("Mic Bias", JZ4725B_CODEC_REG_CR1,
330			    REG_CR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
331
332	/* Pins */
333	SND_SOC_DAPM_INPUT("MIC1P"),
334	SND_SOC_DAPM_INPUT("MIC1N"),
335	SND_SOC_DAPM_INPUT("MIC2P"),
336	SND_SOC_DAPM_INPUT("MIC2N"),
337
338	SND_SOC_DAPM_INPUT("LLINEIN"),
339	SND_SOC_DAPM_INPUT("RLINEIN"),
340
341	SND_SOC_DAPM_OUTPUT("LHPOUT"),
342	SND_SOC_DAPM_OUTPUT("RHPOUT"),
343};
344
345static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
346	{"Mic 1", NULL, "MIC1P"},
347	{"Mic 1", NULL, "MIC1N"},
348	{"Mic 2", NULL, "MIC2P"},
349	{"Mic 2", NULL, "MIC2N"},
350
351	{"Line In", NULL, "LLINEIN"},
352	{"Line In", NULL, "RLINEIN"},
353
354	{"Mixer", "Mic 1 Bypass Playback Switch", "Mic 1"},
355	{"Mixer", "Mic 2 Bypass Playback Switch", "Mic 2"},
356	{"Mixer", "Line In Bypass Playback Switch", "Line In"},
357	{"DAC to Mixer", NULL, "DAC"},
358	{"Mixer", NULL, "DAC to Mixer"},
359
360	{"Mixer to ADC", NULL, "Mixer"},
361	{"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
362	{"ADC Source Capture Route", "Line In", "Line In"},
363	{"ADC Source Capture Route", "Mic 1", "Mic 1"},
364	{"ADC Source Capture Route", "Mic 2", "Mic 2"},
365	{"ADC", NULL, "ADC Source Capture Route"},
366
367	{"Out Stage", NULL, "Mixer"},
368	{"HP Out", NULL, "Out Stage"},
369	{"LHPOUT", NULL, "HP Out"},
370	{"RHPOUT", NULL, "HP Out"},
371};
372
373static int jz4725b_codec_set_bias_level(struct snd_soc_component *component,
374					enum snd_soc_bias_level level)
375{
376	struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
377	struct regmap *map = icdc->regmap;
378
379	switch (level) {
380	case SND_SOC_BIAS_ON:
381		regmap_clear_bits(map, JZ4725B_CODEC_REG_PMR2,
382				  BIT(REG_PMR2_SB_SLEEP_OFFSET));
383		break;
384	case SND_SOC_BIAS_PREPARE:
385		/* Enable sound hardware */
386		regmap_clear_bits(map, JZ4725B_CODEC_REG_PMR2,
387				  BIT(REG_PMR2_SB_OFFSET));
388		msleep(224);
389		break;
390	case SND_SOC_BIAS_STANDBY:
391		regmap_set_bits(map, JZ4725B_CODEC_REG_PMR2,
392				BIT(REG_PMR2_SB_SLEEP_OFFSET));
393		break;
394	case SND_SOC_BIAS_OFF:
395		regmap_set_bits(map, JZ4725B_CODEC_REG_PMR2,
396				BIT(REG_PMR2_SB_OFFSET));
397		break;
398	}
399
400	return 0;
401}
402
403static int jz4725b_codec_dev_probe(struct snd_soc_component *component)
404{
405	struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
406	struct regmap *map = icdc->regmap;
407
408	clk_prepare_enable(icdc->clk);
409
410	/* Write CONFIGn (n=1 to 8) bits.
411	 * The value 0x0f is specified in the datasheet as a requirement.
412	 */
413	regmap_write(map, JZ4725B_CODEC_REG_AICR,
414		     0xf << REG_AICR_CONFIG1_OFFSET);
415	regmap_write(map, JZ4725B_CODEC_REG_CCR1,
416		     0x0 << REG_CCR1_CONFIG4_OFFSET);
417
418	return 0;
419}
420
421static void jz4725b_codec_dev_remove(struct snd_soc_component *component)
422{
423	struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
424
425	clk_disable_unprepare(icdc->clk);
426}
427
428static const struct snd_soc_component_driver jz4725b_codec = {
429	.probe			= jz4725b_codec_dev_probe,
430	.remove			= jz4725b_codec_dev_remove,
431	.set_bias_level		= jz4725b_codec_set_bias_level,
432	.controls		= jz4725b_codec_controls,
433	.num_controls		= ARRAY_SIZE(jz4725b_codec_controls),
434	.dapm_widgets		= jz4725b_codec_dapm_widgets,
435	.num_dapm_widgets	= ARRAY_SIZE(jz4725b_codec_dapm_widgets),
436	.dapm_routes		= jz4725b_codec_dapm_routes,
437	.num_dapm_routes	= ARRAY_SIZE(jz4725b_codec_dapm_routes),
438	.suspend_bias_off	= 1,
439	.use_pmdown_time	= 1,
440};
441
442static const unsigned int jz4725b_codec_sample_rates[] = {
443	96000, 48000, 44100, 32000,
444	24000, 22050, 16000, 12000,
445	11025, 9600, 8000,
446};
447
448static int jz4725b_codec_hw_params(struct snd_pcm_substream *substream,
449	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
450{
451	struct jz_icdc *icdc = snd_soc_component_get_drvdata(dai->component);
452	unsigned int rate, bit_width;
453
454	switch (params_format(params)) {
455	case SNDRV_PCM_FORMAT_S16_LE:
456		bit_width = 0;
457		break;
458	case SNDRV_PCM_FORMAT_S18_3LE:
459		bit_width = 1;
460		break;
461	case SNDRV_PCM_FORMAT_S20_3LE:
462		bit_width = 2;
463		break;
464	case SNDRV_PCM_FORMAT_S24_3LE:
465		bit_width = 3;
466		break;
467	default:
468		return -EINVAL;
469	}
470
471	for (rate = 0; rate < ARRAY_SIZE(jz4725b_codec_sample_rates); rate++) {
472		if (jz4725b_codec_sample_rates[rate] == params_rate(params))
473			break;
474	}
475
476	if (rate == ARRAY_SIZE(jz4725b_codec_sample_rates))
477		return -EINVAL;
478
479	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
480		regmap_update_bits(icdc->regmap,
481				   JZ4725B_CODEC_REG_CR2,
482				   REG_CR2_DAC_ADWL_MASK,
483				   bit_width << REG_CR2_DAC_ADWL_OFFSET);
484
485		regmap_update_bits(icdc->regmap,
486				   JZ4725B_CODEC_REG_CCR2,
487				   REG_CCR2_DFREQ_MASK,
488				   rate << REG_CCR2_DFREQ_OFFSET);
489	} else {
490		regmap_update_bits(icdc->regmap,
491				   JZ4725B_CODEC_REG_CR2,
492				   REG_CR2_ADC_ADWL_MASK,
493				   bit_width << REG_CR2_ADC_ADWL_OFFSET);
494
495		regmap_update_bits(icdc->regmap,
496				   JZ4725B_CODEC_REG_CCR2,
497				   REG_CCR2_AFREQ_MASK,
498				   rate << REG_CCR2_AFREQ_OFFSET);
499	}
500
501	return 0;
502}
503
504static const struct snd_soc_dai_ops jz4725b_codec_dai_ops = {
505	.hw_params = jz4725b_codec_hw_params,
506};
507
508#define JZ_ICDC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S18_3LE | \
509			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE)
510
511static struct snd_soc_dai_driver jz4725b_codec_dai = {
512	.name = "jz4725b-hifi",
513	.playback = {
514		.stream_name = "Playback",
515		.channels_min = 2,
516		.channels_max = 2,
517		.rates = SNDRV_PCM_RATE_8000_96000,
518		.formats = JZ_ICDC_FORMATS,
519	},
520	.capture = {
521		.stream_name = "Capture",
522		.channels_min = 2,
523		.channels_max = 2,
524		.rates = SNDRV_PCM_RATE_8000_96000,
525		.formats = JZ_ICDC_FORMATS,
526	},
527	.ops = &jz4725b_codec_dai_ops,
528};
529
530static bool jz4725b_codec_volatile(struct device *dev, unsigned int reg)
531{
532	return reg == JZ4725B_CODEC_REG_IFR;
533}
534
535static bool jz4725b_codec_can_access_reg(struct device *dev, unsigned int reg)
536{
537	return (reg != JZ4725B_CODEC_REG_TR1) && (reg != JZ4725B_CODEC_REG_TR2);
538}
539
540static int jz4725b_codec_io_wait(struct jz_icdc *icdc)
541{
542	u32 reg;
543
544	return readl_poll_timeout(icdc->base + ICDC_RGADW_OFFSET, reg,
545				  !(reg & ICDC_RGADW_RGWR), 1000, 10000);
546}
547
548static int jz4725b_codec_reg_read(void *context, unsigned int reg,
549				  unsigned int *val)
550{
551	struct jz_icdc *icdc = context;
552	unsigned int i;
553	u32 tmp;
554	int ret;
555
556	ret = jz4725b_codec_io_wait(icdc);
557	if (ret)
558		return ret;
559
560	tmp = readl(icdc->base + ICDC_RGADW_OFFSET);
561	tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
562	    | (reg << ICDC_RGADW_RGADDR_OFFSET);
563	writel(tmp, icdc->base + ICDC_RGADW_OFFSET);
564
565	/* wait 6+ cycles */
566	for (i = 0; i < 6; i++)
567		*val = readl(icdc->base + ICDC_RGDATA_OFFSET) &
568			ICDC_RGDATA_RGDOUT_MASK;
569
570	return 0;
571}
572
573static int jz4725b_codec_reg_write(void *context, unsigned int reg,
574				   unsigned int val)
575{
576	struct jz_icdc *icdc = context;
577	int ret;
578
579	ret = jz4725b_codec_io_wait(icdc);
580	if (ret)
581		return ret;
582
583	writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
584			icdc->base + ICDC_RGADW_OFFSET);
585
586	ret = jz4725b_codec_io_wait(icdc);
587	if (ret)
588		return ret;
589
590	return 0;
591}
592
593static const u8 jz4725b_codec_reg_defaults[] = {
594	0x0c, 0xaa, 0x78, 0x00, 0x00, 0xff, 0x03, 0x51,
595	0x3f, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04,
596	0x04, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0xc0, 0x34,
597	0x07, 0x44, 0x1f, 0x00,
598};
599
600static const struct regmap_config jz4725b_codec_regmap_config = {
601	.reg_bits = 7,
602	.val_bits = 8,
603
604	.max_register = JZ4725B_CODEC_REG_AGC5,
605	.volatile_reg = jz4725b_codec_volatile,
606	.readable_reg = jz4725b_codec_can_access_reg,
607	.writeable_reg = jz4725b_codec_can_access_reg,
608
609	.reg_read = jz4725b_codec_reg_read,
610	.reg_write = jz4725b_codec_reg_write,
611
612	.reg_defaults_raw = jz4725b_codec_reg_defaults,
613	.num_reg_defaults_raw = ARRAY_SIZE(jz4725b_codec_reg_defaults),
614	.cache_type = REGCACHE_FLAT,
615};
616
617static int jz4725b_codec_probe(struct platform_device *pdev)
618{
619	struct device *dev = &pdev->dev;
620	struct jz_icdc *icdc;
621	int ret;
622
623	icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL);
624	if (!icdc)
625		return -ENOMEM;
626
627	icdc->base = devm_platform_ioremap_resource(pdev, 0);
628	if (IS_ERR(icdc->base))
629		return PTR_ERR(icdc->base);
630
631	icdc->regmap = devm_regmap_init(dev, NULL, icdc,
632					&jz4725b_codec_regmap_config);
633	if (IS_ERR(icdc->regmap))
634		return PTR_ERR(icdc->regmap);
635
636	icdc->clk = devm_clk_get(&pdev->dev, "aic");
637	if (IS_ERR(icdc->clk))
638		return PTR_ERR(icdc->clk);
639
640	platform_set_drvdata(pdev, icdc);
641
642	ret = devm_snd_soc_register_component(dev, &jz4725b_codec,
643					      &jz4725b_codec_dai, 1);
644	if (ret)
645		dev_err(dev, "Failed to register codec\n");
646
647	return ret;
648}
649
650static const struct of_device_id jz4725b_codec_of_matches[] = {
651	{ .compatible = "ingenic,jz4725b-codec", },
652	{ }
653};
654MODULE_DEVICE_TABLE(of, jz4725b_codec_of_matches);
655
656static struct platform_driver jz4725b_codec_driver = {
657	.probe = jz4725b_codec_probe,
658	.driver = {
659		.name = "jz4725b-codec",
660		.of_match_table = jz4725b_codec_of_matches,
661	},
662};
663module_platform_driver(jz4725b_codec_driver);
664
665MODULE_DESCRIPTION("JZ4725B SoC internal codec driver");
666MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
667MODULE_LICENSE("GPL v2");
668