GNU Linux-libre 5.10.217-gnu1
[releases.git] / sound / soc / codecs / jz4725b.c
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 */
44 enum {
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_CGR10_GIL_OFFSET            0
140 #define REG_CGR10_GIR_OFFSET            4
141
142 struct jz_icdc {
143         struct regmap *regmap;
144         void __iomem *base;
145         struct clk *clk;
146 };
147
148 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv,     0, 150, 0);
149 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
150
151 static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
152         SOC_DOUBLE_TLV("Master Playback Volume",
153                        JZ4725B_CODEC_REG_CGR1,
154                        REG_CGR1_GODL_OFFSET,
155                        REG_CGR1_GODR_OFFSET,
156                        0xf, 1, jz4725b_dac_tlv),
157         SOC_DOUBLE_TLV("Master Capture Volume",
158                        JZ4725B_CODEC_REG_CGR10,
159                        REG_CGR10_GIL_OFFSET,
160                        REG_CGR10_GIR_OFFSET,
161                        0xf, 0, jz4725b_adc_tlv),
162
163         SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
164                    REG_CR1_DAC_MUTE_OFFSET, 1, 1),
165
166         SOC_SINGLE("Deemphasize Filter Playback Switch",
167                    JZ4725B_CODEC_REG_CR2,
168                    REG_CR2_DAC_DEEMP_OFFSET, 1, 0),
169
170         SOC_SINGLE("High-Pass Filter Capture Switch",
171                    JZ4725B_CODEC_REG_CR2,
172                    REG_CR2_ADC_HPF_OFFSET, 1, 0),
173 };
174
175 static const char * const jz4725b_codec_adc_src_texts[] = {
176         "Mic 1", "Mic 2", "Line In", "Mixer",
177 };
178 static const unsigned int jz4725b_codec_adc_src_values[] = { 0, 1, 2, 3, };
179 static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
180                                   JZ4725B_CODEC_REG_CR3,
181                                   REG_CR3_INSEL_OFFSET,
182                                   REG_CR3_INSEL_MASK,
183                                   jz4725b_codec_adc_src_texts,
184                                   jz4725b_codec_adc_src_values);
185 static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
186         SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
187
188 static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
189         SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
190                         REG_CR1_BYPASS_OFFSET, 1, 0),
191 };
192
193 static int jz4725b_out_stage_enable(struct snd_soc_dapm_widget *w,
194                                     struct snd_kcontrol *kcontrol,
195                                     int event)
196 {
197         struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
198         struct jz_icdc *icdc = snd_soc_component_get_drvdata(codec);
199         struct regmap *map = icdc->regmap;
200         unsigned int val;
201
202         switch (event) {
203         case SND_SOC_DAPM_PRE_PMU:
204                 return regmap_update_bits(map, JZ4725B_CODEC_REG_IFR,
205                                           BIT(REG_IFR_RAMP_UP_DONE_OFFSET), 0);
206         case SND_SOC_DAPM_POST_PMU:
207                 return regmap_read_poll_timeout(map, JZ4725B_CODEC_REG_IFR,
208                                val, val & BIT(REG_IFR_RAMP_UP_DONE_OFFSET),
209                                100000, 500000);
210         case SND_SOC_DAPM_PRE_PMD:
211                 return regmap_update_bits(map, JZ4725B_CODEC_REG_IFR,
212                                 BIT(REG_IFR_RAMP_DOWN_DONE_OFFSET), 0);
213         case SND_SOC_DAPM_POST_PMD:
214                 return regmap_read_poll_timeout(map, JZ4725B_CODEC_REG_IFR,
215                                val, val & BIT(REG_IFR_RAMP_DOWN_DONE_OFFSET),
216                                100000, 500000);
217         default:
218                 return -EINVAL;
219         }
220 }
221
222 static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
223         /* DAC */
224         SND_SOC_DAPM_DAC("DAC", "Playback",
225                          JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_DAC_OFFSET, 1),
226
227         /* ADC */
228         SND_SOC_DAPM_ADC("ADC", "Capture",
229                          JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
230
231         SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
232                          &jz4725b_codec_adc_src_ctrl),
233
234         /* Mixer */
235         SND_SOC_DAPM_MIXER("Mixer", JZ4725B_CODEC_REG_PMR1,
236                            REG_PMR1_SB_MIX_OFFSET, 1,
237                            jz4725b_codec_mixer_controls,
238                            ARRAY_SIZE(jz4725b_codec_mixer_controls)),
239         SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
240                            REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
241
242         SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
243                            REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
244         SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
245                            REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
246
247         SND_SOC_DAPM_MIXER("Mic 1", JZ4725B_CODEC_REG_CR3,
248                            REG_CR3_SB_MIC1_OFFSET, 1, NULL, 0),
249         SND_SOC_DAPM_MIXER("Mic 2", JZ4725B_CODEC_REG_CR3,
250                            REG_CR3_SB_MIC2_OFFSET, 1, NULL, 0),
251
252         SND_SOC_DAPM_MIXER_E("Out Stage", JZ4725B_CODEC_REG_PMR1,
253                              REG_PMR1_SB_OUT_OFFSET, 1, NULL, 0,
254                              jz4725b_out_stage_enable,
255                              SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
256                              SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
257         SND_SOC_DAPM_MIXER("Mixer to ADC", JZ4725B_CODEC_REG_PMR1,
258                            REG_PMR1_SB_IND_OFFSET, 1, NULL, 0),
259
260         SND_SOC_DAPM_SUPPLY("Mic Bias", JZ4725B_CODEC_REG_CR1,
261                             REG_CR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
262
263         /* Pins */
264         SND_SOC_DAPM_INPUT("MIC1P"),
265         SND_SOC_DAPM_INPUT("MIC1N"),
266         SND_SOC_DAPM_INPUT("MIC2P"),
267         SND_SOC_DAPM_INPUT("MIC2N"),
268
269         SND_SOC_DAPM_INPUT("LLINEIN"),
270         SND_SOC_DAPM_INPUT("RLINEIN"),
271
272         SND_SOC_DAPM_OUTPUT("LHPOUT"),
273         SND_SOC_DAPM_OUTPUT("RHPOUT"),
274 };
275
276 static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
277         {"Mic 1", NULL, "MIC1P"},
278         {"Mic 1", NULL, "MIC1N"},
279         {"Mic 2", NULL, "MIC2P"},
280         {"Mic 2", NULL, "MIC2N"},
281
282         {"Line In", NULL, "LLINEIN"},
283         {"Line In", NULL, "RLINEIN"},
284
285         {"Mixer", "Line In Bypass", "Line In"},
286         {"DAC to Mixer", NULL, "DAC"},
287         {"Mixer", NULL, "DAC to Mixer"},
288
289         {"Mixer to ADC", NULL, "Mixer"},
290         {"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
291         {"ADC Source Capture Route", "Line In", "Line In"},
292         {"ADC Source Capture Route", "Mic 1", "Mic 1"},
293         {"ADC Source Capture Route", "Mic 2", "Mic 2"},
294         {"ADC", NULL, "ADC Source Capture Route"},
295
296         {"Out Stage", NULL, "Mixer"},
297         {"HP Out", NULL, "Out Stage"},
298         {"LHPOUT", NULL, "HP Out"},
299         {"RHPOUT", NULL, "HP Out"},
300 };
301
302 static int jz4725b_codec_set_bias_level(struct snd_soc_component *component,
303                                         enum snd_soc_bias_level level)
304 {
305         struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
306         struct regmap *map = icdc->regmap;
307
308         switch (level) {
309         case SND_SOC_BIAS_ON:
310                 regmap_update_bits(map, JZ4725B_CODEC_REG_PMR2,
311                                    BIT(REG_PMR2_SB_SLEEP_OFFSET), 0);
312                 break;
313         case SND_SOC_BIAS_PREPARE:
314                 /* Enable sound hardware */
315                 regmap_update_bits(map, JZ4725B_CODEC_REG_PMR2,
316                                    BIT(REG_PMR2_SB_OFFSET), 0);
317                 msleep(224);
318                 break;
319         case SND_SOC_BIAS_STANDBY:
320                 regmap_update_bits(map, JZ4725B_CODEC_REG_PMR2,
321                                    BIT(REG_PMR2_SB_SLEEP_OFFSET),
322                                    BIT(REG_PMR2_SB_SLEEP_OFFSET));
323                 break;
324         case SND_SOC_BIAS_OFF:
325                 regmap_update_bits(map, JZ4725B_CODEC_REG_PMR2,
326                                    BIT(REG_PMR2_SB_OFFSET),
327                                    BIT(REG_PMR2_SB_OFFSET));
328                 break;
329         }
330
331         return 0;
332 }
333
334 static int jz4725b_codec_dev_probe(struct snd_soc_component *component)
335 {
336         struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
337         struct regmap *map = icdc->regmap;
338
339         clk_prepare_enable(icdc->clk);
340
341         /* Write CONFIGn (n=1 to 8) bits.
342          * The value 0x0f is specified in the datasheet as a requirement.
343          */
344         regmap_write(map, JZ4725B_CODEC_REG_AICR,
345                      0xf << REG_AICR_CONFIG1_OFFSET);
346         regmap_write(map, JZ4725B_CODEC_REG_CCR1,
347                      0x0 << REG_CCR1_CONFIG4_OFFSET);
348
349         return 0;
350 }
351
352 static void jz4725b_codec_dev_remove(struct snd_soc_component *component)
353 {
354         struct jz_icdc *icdc = snd_soc_component_get_drvdata(component);
355
356         clk_disable_unprepare(icdc->clk);
357 }
358
359 static const struct snd_soc_component_driver jz4725b_codec = {
360         .probe                  = jz4725b_codec_dev_probe,
361         .remove                 = jz4725b_codec_dev_remove,
362         .set_bias_level         = jz4725b_codec_set_bias_level,
363         .controls               = jz4725b_codec_controls,
364         .num_controls           = ARRAY_SIZE(jz4725b_codec_controls),
365         .dapm_widgets           = jz4725b_codec_dapm_widgets,
366         .num_dapm_widgets       = ARRAY_SIZE(jz4725b_codec_dapm_widgets),
367         .dapm_routes            = jz4725b_codec_dapm_routes,
368         .num_dapm_routes        = ARRAY_SIZE(jz4725b_codec_dapm_routes),
369         .suspend_bias_off       = 1,
370         .use_pmdown_time        = 1,
371 };
372
373 static const unsigned int jz4725b_codec_sample_rates[] = {
374         96000, 48000, 44100, 32000,
375         24000, 22050, 16000, 12000,
376         11025, 9600, 8000,
377 };
378
379 static int jz4725b_codec_hw_params(struct snd_pcm_substream *substream,
380         struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
381 {
382         struct jz_icdc *icdc = snd_soc_component_get_drvdata(dai->component);
383         unsigned int rate, bit_width;
384
385         switch (params_format(params)) {
386         case SNDRV_PCM_FORMAT_S16_LE:
387                 bit_width = 0;
388                 break;
389         case SNDRV_PCM_FORMAT_S18_3LE:
390                 bit_width = 1;
391                 break;
392         case SNDRV_PCM_FORMAT_S20_3LE:
393                 bit_width = 2;
394                 break;
395         case SNDRV_PCM_FORMAT_S24_3LE:
396                 bit_width = 3;
397                 break;
398         default:
399                 return -EINVAL;
400         }
401
402         for (rate = 0; rate < ARRAY_SIZE(jz4725b_codec_sample_rates); rate++) {
403                 if (jz4725b_codec_sample_rates[rate] == params_rate(params))
404                         break;
405         }
406
407         if (rate == ARRAY_SIZE(jz4725b_codec_sample_rates))
408                 return -EINVAL;
409
410         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
411                 regmap_update_bits(icdc->regmap,
412                                    JZ4725B_CODEC_REG_CR2,
413                                    REG_CR2_DAC_ADWL_MASK,
414                                    bit_width << REG_CR2_DAC_ADWL_OFFSET);
415
416                 regmap_update_bits(icdc->regmap,
417                                    JZ4725B_CODEC_REG_CCR2,
418                                    REG_CCR2_DFREQ_MASK,
419                                    rate << REG_CCR2_DFREQ_OFFSET);
420         } else {
421                 regmap_update_bits(icdc->regmap,
422                                    JZ4725B_CODEC_REG_CR2,
423                                    REG_CR2_ADC_ADWL_MASK,
424                                    bit_width << REG_CR2_ADC_ADWL_OFFSET);
425
426                 regmap_update_bits(icdc->regmap,
427                                    JZ4725B_CODEC_REG_CCR2,
428                                    REG_CCR2_AFREQ_MASK,
429                                    rate << REG_CCR2_AFREQ_OFFSET);
430         }
431
432         return 0;
433 }
434
435 static const struct snd_soc_dai_ops jz4725b_codec_dai_ops = {
436         .hw_params = jz4725b_codec_hw_params,
437 };
438
439 #define JZ_ICDC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S18_3LE | \
440                          SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE)
441
442 static struct snd_soc_dai_driver jz4725b_codec_dai = {
443         .name = "jz4725b-hifi",
444         .playback = {
445                 .stream_name = "Playback",
446                 .channels_min = 2,
447                 .channels_max = 2,
448                 .rates = SNDRV_PCM_RATE_8000_96000,
449                 .formats = JZ_ICDC_FORMATS,
450         },
451         .capture = {
452                 .stream_name = "Capture",
453                 .channels_min = 2,
454                 .channels_max = 2,
455                 .rates = SNDRV_PCM_RATE_8000_96000,
456                 .formats = JZ_ICDC_FORMATS,
457         },
458         .ops = &jz4725b_codec_dai_ops,
459 };
460
461 static bool jz4725b_codec_volatile(struct device *dev, unsigned int reg)
462 {
463         return reg == JZ4725B_CODEC_REG_IFR;
464 }
465
466 static bool jz4725b_codec_can_access_reg(struct device *dev, unsigned int reg)
467 {
468         return (reg != JZ4725B_CODEC_REG_TR1) && (reg != JZ4725B_CODEC_REG_TR2);
469 }
470
471 static int jz4725b_codec_io_wait(struct jz_icdc *icdc)
472 {
473         u32 reg;
474
475         return readl_poll_timeout(icdc->base + ICDC_RGADW_OFFSET, reg,
476                                   !(reg & ICDC_RGADW_RGWR), 1000, 10000);
477 }
478
479 static int jz4725b_codec_reg_read(void *context, unsigned int reg,
480                                   unsigned int *val)
481 {
482         struct jz_icdc *icdc = context;
483         unsigned int i;
484         u32 tmp;
485         int ret;
486
487         ret = jz4725b_codec_io_wait(icdc);
488         if (ret)
489                 return ret;
490
491         tmp = readl(icdc->base + ICDC_RGADW_OFFSET);
492         tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
493             | (reg << ICDC_RGADW_RGADDR_OFFSET);
494         writel(tmp, icdc->base + ICDC_RGADW_OFFSET);
495
496         /* wait 6+ cycles */
497         for (i = 0; i < 6; i++)
498                 *val = readl(icdc->base + ICDC_RGDATA_OFFSET) &
499                         ICDC_RGDATA_RGDOUT_MASK;
500
501         return 0;
502 }
503
504 static int jz4725b_codec_reg_write(void *context, unsigned int reg,
505                                    unsigned int val)
506 {
507         struct jz_icdc *icdc = context;
508         int ret;
509
510         ret = jz4725b_codec_io_wait(icdc);
511         if (ret)
512                 return ret;
513
514         writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
515                         icdc->base + ICDC_RGADW_OFFSET);
516
517         ret = jz4725b_codec_io_wait(icdc);
518         if (ret)
519                 return ret;
520
521         return 0;
522 }
523
524 static const u8 jz4725b_codec_reg_defaults[] = {
525         0x0c, 0xaa, 0x78, 0x00, 0x00, 0xff, 0x03, 0x51,
526         0x3f, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04,
527         0x04, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0xc0, 0x34,
528         0x07, 0x44, 0x1f, 0x00,
529 };
530
531 static const struct regmap_config jz4725b_codec_regmap_config = {
532         .reg_bits = 7,
533         .val_bits = 8,
534
535         .max_register = JZ4725B_CODEC_REG_AGC5,
536         .volatile_reg = jz4725b_codec_volatile,
537         .readable_reg = jz4725b_codec_can_access_reg,
538         .writeable_reg = jz4725b_codec_can_access_reg,
539
540         .reg_read = jz4725b_codec_reg_read,
541         .reg_write = jz4725b_codec_reg_write,
542
543         .reg_defaults_raw = jz4725b_codec_reg_defaults,
544         .num_reg_defaults_raw = ARRAY_SIZE(jz4725b_codec_reg_defaults),
545         .cache_type = REGCACHE_FLAT,
546 };
547
548 static int jz4725b_codec_probe(struct platform_device *pdev)
549 {
550         struct device *dev = &pdev->dev;
551         struct jz_icdc *icdc;
552         int ret;
553
554         icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL);
555         if (!icdc)
556                 return -ENOMEM;
557
558         icdc->base = devm_platform_ioremap_resource(pdev, 0);
559         if (IS_ERR(icdc->base))
560                 return PTR_ERR(icdc->base);
561
562         icdc->regmap = devm_regmap_init(dev, NULL, icdc,
563                                         &jz4725b_codec_regmap_config);
564         if (IS_ERR(icdc->regmap))
565                 return PTR_ERR(icdc->regmap);
566
567         icdc->clk = devm_clk_get(&pdev->dev, "aic");
568         if (IS_ERR(icdc->clk))
569                 return PTR_ERR(icdc->clk);
570
571         platform_set_drvdata(pdev, icdc);
572
573         ret = devm_snd_soc_register_component(dev, &jz4725b_codec,
574                                               &jz4725b_codec_dai, 1);
575         if (ret)
576                 dev_err(dev, "Failed to register codec\n");
577
578         return ret;
579 }
580
581 static const struct of_device_id jz4725b_codec_of_matches[] = {
582         { .compatible = "ingenic,jz4725b-codec", },
583         { }
584 };
585 MODULE_DEVICE_TABLE(of, jz4725b_codec_of_matches);
586
587 static struct platform_driver jz4725b_codec_driver = {
588         .probe = jz4725b_codec_probe,
589         .driver = {
590                 .name = "jz4725b-codec",
591                 .of_match_table = jz4725b_codec_of_matches,
592         },
593 };
594 module_platform_driver(jz4725b_codec_driver);
595
596 MODULE_DESCRIPTION("JZ4725B SoC internal codec driver");
597 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
598 MODULE_LICENSE("GPL v2");