1// SPDX-License-Identifier: GPL-2.0
2//
3// Ingenic JZ4760 CODEC driver
4//
5// Copyright (C) 2021, Christophe Branchereau <cbranchereau@gmail.com>
6// Copyright (C) 2021, Paul Cercueil <paul@crapouillou.net>
7
8#include <linux/bitfield.h>
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/iopoll.h>
12#include <linux/module.h>
13#include <linux/regmap.h>
14#include <linux/time64.h>
15
16#include <sound/pcm_params.h>
17#include <sound/soc.h>
18#include <sound/soc-dai.h>
19#include <sound/soc-dapm.h>
20#include <sound/tlv.h>
21
22#define ICDC_RGADW_OFFSET 0x00
23#define ICDC_RGDATA_OFFSET 0x04
24
25/* ICDC internal register access control register(RGADW) */
26#define ICDC_RGADW_RGWR BIT(16)
27#define ICDC_RGADW_RGADDR_MASK GENMASK(14, 8)
28#define ICDC_RGADW_RGDIN_MASK GENMASK(7, 0)
29
30/* ICDC internal register data output register (RGDATA)*/
31#define ICDC_RGDATA_IRQ BIT(8)
32#define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, 0)
33
34/* Internal register space, accessed through regmap */
35enum {
36 JZ4760_CODEC_REG_SR,
37 JZ4760_CODEC_REG_AICR,
38 JZ4760_CODEC_REG_CR1,
39 JZ4760_CODEC_REG_CR2,
40 JZ4760_CODEC_REG_CR3,
41 JZ4760_CODEC_REG_CR4,
42 JZ4760_CODEC_REG_CCR1,
43 JZ4760_CODEC_REG_CCR2,
44 JZ4760_CODEC_REG_PMR1,
45 JZ4760_CODEC_REG_PMR2,
46 JZ4760_CODEC_REG_ICR,
47 JZ4760_CODEC_REG_IFR,
48 JZ4760_CODEC_REG_GCR1,
49 JZ4760_CODEC_REG_GCR2,
50 JZ4760_CODEC_REG_GCR3,
51 JZ4760_CODEC_REG_GCR4,
52 JZ4760_CODEC_REG_GCR5,
53 JZ4760_CODEC_REG_GCR6,
54 JZ4760_CODEC_REG_GCR7,
55 JZ4760_CODEC_REG_GCR8,
56 JZ4760_CODEC_REG_GCR9,
57 JZ4760_CODEC_REG_AGC1,
58 JZ4760_CODEC_REG_AGC2,
59 JZ4760_CODEC_REG_AGC3,
60 JZ4760_CODEC_REG_AGC4,
61 JZ4760_CODEC_REG_AGC5,
62 JZ4760_CODEC_REG_MIX1,
63 JZ4760_CODEC_REG_MIX2,
64};
65
66#define REG_AICR_DAC_ADWL_MASK GENMASK(7, 6)
67#define REG_AICR_DAC_SERIAL BIT(3)
68#define REG_AICR_DAC_I2S BIT(1)
69
70#define REG_AICR_ADC_ADWL_MASK GENMASK(5, 4)
71
72#define REG_AICR_ADC_SERIAL BIT(2)
73#define REG_AICR_ADC_I2S BIT(0)
74
75#define REG_CR1_HP_LOAD BIT(7)
76#define REG_CR1_HP_MUTE BIT(5)
77#define REG_CR1_LO_MUTE_OFFSET 4
78#define REG_CR1_BTL_MUTE_OFFSET 3
79#define REG_CR1_OUTSEL_OFFSET 0
80#define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET)
81
82#define REG_CR2_DAC_MONO BIT(7)
83#define REG_CR2_DAC_MUTE BIT(5)
84#define REG_CR2_DAC_NOMAD BIT(1)
85#define REG_CR2_DAC_RIGHT_ONLY BIT(0)
86
87#define REG_CR3_ADC_INSEL_OFFSET 2
88#define REG_CR3_ADC_INSEL_MASK GENMASK(3, REG_CR3_ADC_INSEL_OFFSET)
89#define REG_CR3_MICSTEREO_OFFSET 1
90#define REG_CR3_MICDIFF_OFFSET 0
91
92#define REG_CR4_ADC_HPF_OFFSET 7
93#define REG_CR4_ADC_RIGHT_ONLY BIT(0)
94
95#define REG_CCR1_CRYSTAL_MASK GENMASK(3, 0)
96
97#define REG_CCR2_DAC_FREQ_MASK GENMASK(7, 4)
98#define REG_CCR2_ADC_FREQ_MASK GENMASK(3, 0)
99
100#define REG_PMR1_SB BIT(7)
101#define REG_PMR1_SB_SLEEP BIT(6)
102#define REG_PMR1_SB_AIP_OFFSET 5
103#define REG_PMR1_SB_LINE_OFFSET 4
104#define REG_PMR1_SB_MIC1_OFFSET 3
105#define REG_PMR1_SB_MIC2_OFFSET 2
106#define REG_PMR1_SB_BYPASS_OFFSET 1
107#define REG_PMR1_SB_MICBIAS_OFFSET 0
108
109#define REG_PMR2_SB_ADC_OFFSET 4
110#define REG_PMR2_SB_HP_OFFSET 3
111#define REG_PMR2_SB_BTL_OFFSET 2
112#define REG_PMR2_SB_LOUT_OFFSET 1
113#define REG_PMR2_SB_DAC_OFFSET 0
114
115#define REG_ICR_INT_FORM_MASK GENMASK(7, 6)
116#define REG_ICR_ALL_MASK GENMASK(5, 0)
117#define REG_ICR_JACK_MASK BIT(5)
118#define REG_ICR_SCMC_MASK BIT(4)
119#define REG_ICR_RUP_MASK BIT(3)
120#define REG_ICR_RDO_MASK BIT(2)
121#define REG_ICR_GUP_MASK BIT(1)
122#define REG_ICR_GDO_MASK BIT(0)
123
124#define REG_IFR_ALL_MASK GENMASK(5, 0)
125#define REG_IFR_JACK BIT(6)
126#define REG_IFR_JACK_EVENT BIT(5)
127#define REG_IFR_SCMC BIT(4)
128#define REG_IFR_RUP BIT(3)
129#define REG_IFR_RDO BIT(2)
130#define REG_IFR_GUP BIT(1)
131#define REG_IFR_GDO BIT(0)
132
133#define REG_GCR_GAIN_OFFSET 0
134#define REG_GCR_GAIN_MAX 0x1f
135
136#define REG_GCR_RL BIT(7)
137
138#define REG_GCR_GIM1_MASK GENMASK(5, 3)
139#define REG_GCR_GIM2_MASK GENMASK(2, 0)
140#define REG_GCR_GIM_GAIN_MAX 7
141
142#define REG_AGC1_EN BIT(7)
143#define REG_AGC1_TARGET_MASK GENMASK(5, 2)
144
145#define REG_AGC2_NG_THR_MASK GENMASK(6, 4)
146#define REG_AGC2_HOLD_MASK GENMASK(3, 0)
147
148#define REG_AGC3_ATK_MASK GENMASK(7, 4)
149#define REG_AGC3_DCY_MASK GENMASK(3, 0)
150
151#define REG_AGC4_AGC_MAX_MASK GENMASK(4, 0)
152
153#define REG_AGC5_AGC_MIN_MASK GENMASK(4, 0)
154
155#define REG_MIX1_MIX_REC_MASK GENMASK(7, 6)
156#define REG_MIX1_GIMIX_MASK GENMASK(4, 0)
157
158#define REG_MIX2_DAC_MIX_MASK GENMASK(7, 6)
159#define REG_MIX2_GOMIX_MASK GENMASK(4, 0)
160
161/* codec private data */
162struct jz_codec {
163 struct device *dev;
164 struct regmap *regmap;
165 void __iomem *base;
166 struct clk *clk;
167};
168
169static int jz4760_codec_set_bias_level(struct snd_soc_component *codec,
170 enum snd_soc_bias_level level)
171{
172 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(c: codec);
173 struct regmap *regmap = jz_codec->regmap;
174
175 switch (level) {
176 case SND_SOC_BIAS_PREPARE:
177 /* Reset all interrupt flags. */
178 regmap_write(map: regmap, reg: JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK);
179
180 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
181 msleep(msecs: 250);
182 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
183 msleep(msecs: 400);
184 break;
185 case SND_SOC_BIAS_STANDBY:
186 regmap_set_bits(map: regmap, reg: JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
187 regmap_set_bits(map: regmap, reg: JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
188 break;
189 default:
190 break;
191 }
192
193 return 0;
194}
195
196static int jz4760_codec_startup(struct snd_pcm_substream *substream,
197 struct snd_soc_dai *dai)
198{
199 struct snd_soc_component *codec = dai->component;
200 struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component: codec);
201 int ret = 0;
202
203 /*
204 * SYSCLK output from the codec to the AIC is required to keep the
205 * DMA transfer going during playback when all audible outputs have
206 * been disabled.
207 */
208 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
209 ret = snd_soc_dapm_force_enable_pin(dapm, pin: "SYSCLK");
210 return ret;
211}
212
213static void jz4760_codec_shutdown(struct snd_pcm_substream *substream,
214 struct snd_soc_dai *dai)
215{
216 struct snd_soc_component *codec = dai->component;
217 struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component: codec);
218
219 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
220 snd_soc_dapm_disable_pin(dapm, pin: "SYSCLK");
221}
222
223
224static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream,
225 int cmd, struct snd_soc_dai *dai)
226{
227 struct snd_soc_component *codec = dai->component;
228 struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component: codec);
229 int ret = 0;
230
231 switch (cmd) {
232 case SNDRV_PCM_TRIGGER_START:
233 case SNDRV_PCM_TRIGGER_RESUME:
234 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
235 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
236 snd_soc_dapm_force_bias_level(dapm, level: SND_SOC_BIAS_ON);
237 break;
238 case SNDRV_PCM_TRIGGER_STOP:
239 case SNDRV_PCM_TRIGGER_SUSPEND:
240 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
241 /* do nothing */
242 break;
243 default:
244 ret = -EINVAL;
245 }
246
247 return ret;
248}
249
250static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
251{
252 struct snd_soc_component *codec = dai->component;
253 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(c: codec);
254 unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
255 unsigned int val, reg;
256 int change, err;
257
258 change = snd_soc_component_update_bits(component: codec, reg: JZ4760_CODEC_REG_CR2,
259 REG_CR2_DAC_MUTE,
260 val: mute ? REG_CR2_DAC_MUTE : 0);
261 if (change == 1) {
262 regmap_read(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_PMR2, val: &val);
263
264 if (val & BIT(REG_PMR2_SB_DAC_OFFSET))
265 return 1;
266
267 err = regmap_read_poll_timeout(jz_codec->regmap,
268 JZ4760_CODEC_REG_IFR,
269 val, val & gain_bit,
270 1000, 1 * USEC_PER_SEC);
271 if (err) {
272 dev_err(jz_codec->dev,
273 "Timeout while setting digital mute: %d", err);
274 return err;
275 }
276
277 /* clear GUP/GDO flag */
278 regmap_write(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_IFR, val: gain_bit);
279 }
280
281 regmap_read(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_CR2, val: &reg);
282
283 return 0;
284}
285
286/* unit: 0.01dB */
287static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100);
288static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
289static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100);
290static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
291static const DECLARE_TLV_DB_MINMAX(mixer_tlv, -3100, 0);
292
293/* Unconditional controls. */
294static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = {
295 /* record gain control */
296 SOC_DOUBLE_R_TLV("PCM Capture Volume",
297 JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8,
298 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv),
299
300 SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
301 JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3,
302 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
303
304 SOC_SINGLE_TLV("Mixer Capture Volume",
305 JZ4760_CODEC_REG_MIX1,
306 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
307
308 SOC_SINGLE_TLV("Mixer Playback Volume",
309 JZ4760_CODEC_REG_MIX2,
310 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
311
312 SOC_SINGLE("High-Pass Filter Capture Switch",
313 JZ4760_CODEC_REG_CR4,
314 REG_CR4_ADC_HPF_OFFSET, 1, 0),
315};
316
317static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = {
318 SOC_DAPM_DOUBLE_R_TLV("Volume", JZ4760_CODEC_REG_GCR6, JZ4760_CODEC_REG_GCR5,
319 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, dac_tlv),
320};
321
322static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = {
323 SOC_DAPM_DOUBLE_R_TLV("Volume", JZ4760_CODEC_REG_GCR2, JZ4760_CODEC_REG_GCR1,
324 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, out_tlv),
325};
326
327static int hpout_event(struct snd_soc_dapm_widget *w,
328 struct snd_kcontrol *kcontrol, int event)
329{
330 struct snd_soc_component *codec = snd_soc_dapm_to_component(dapm: w->dapm);
331 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(c: codec);
332 unsigned int val;
333 int err;
334
335 switch (event) {
336 case SND_SOC_DAPM_PRE_PMU:
337 /* unmute HP */
338 regmap_clear_bits(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_CR1,
339 REG_CR1_HP_MUTE);
340 break;
341
342 case SND_SOC_DAPM_POST_PMU:
343 /* wait for ramp-up complete (RUP) */
344 err = regmap_read_poll_timeout(jz_codec->regmap,
345 JZ4760_CODEC_REG_IFR,
346 val, val & REG_IFR_RUP,
347 1000, 1 * USEC_PER_SEC);
348 if (err) {
349 dev_err(jz_codec->dev, "RUP timeout: %d", err);
350 return err;
351 }
352
353 /* clear RUP flag */
354 regmap_set_bits(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_IFR,
355 REG_IFR_RUP);
356
357 break;
358
359 case SND_SOC_DAPM_POST_PMD:
360 /* mute HP */
361 regmap_set_bits(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_CR1,
362 REG_CR1_HP_MUTE);
363
364 err = regmap_read_poll_timeout(jz_codec->regmap,
365 JZ4760_CODEC_REG_IFR,
366 val, val & REG_IFR_RDO,
367 1000, 1 * USEC_PER_SEC);
368 if (err) {
369 dev_err(jz_codec->dev, "RDO timeout: %d", err);
370 return err;
371 }
372
373 /* clear RDO flag */
374 regmap_set_bits(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_IFR,
375 REG_IFR_RDO);
376
377 break;
378 }
379
380 return 0;
381}
382
383static const char * const jz4760_codec_hp_texts[] = {
384 "PCM", "Line In", "Mic 1", "Mic 2"
385};
386
387static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 };
388
389static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum,
390 JZ4760_CODEC_REG_CR1,
391 REG_CR1_OUTSEL_OFFSET,
392 REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET,
393 jz4760_codec_hp_texts,
394 jz4760_codec_hp_values);
395static const struct snd_kcontrol_new jz4760_codec_hp_source =
396 SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum);
397
398static const char * const jz4760_codec_cap_texts[] = {
399 "Line In", "Mic 1", "Mic 2"
400};
401
402static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 };
403
404static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum,
405 JZ4760_CODEC_REG_CR3,
406 REG_CR3_ADC_INSEL_OFFSET,
407 REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET,
408 jz4760_codec_cap_texts,
409 jz4760_codec_cap_values);
410static const struct snd_kcontrol_new jz4760_codec_cap_source =
411 SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum);
412
413static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = {
414 SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3,
415 REG_CR3_MICSTEREO_OFFSET, 1, 0),
416};
417
418static const struct snd_kcontrol_new jz4760_codec_line_out_switch =
419 SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
420 REG_CR1_LO_MUTE_OFFSET, 0, 0);
421static const struct snd_kcontrol_new jz4760_codec_btl_out_switch =
422 SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
423 REG_CR1_BTL_MUTE_OFFSET, 0, 0);
424
425static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = {
426 SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2,
427 REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event,
428 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
429 SND_SOC_DAPM_POST_PMD),
430
431 SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2,
432 REG_PMR2_SB_LOUT_OFFSET, 1,
433 &jz4760_codec_line_out_switch),
434
435 SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2,
436 REG_PMR2_SB_BTL_OFFSET, 1,
437 &jz4760_codec_btl_out_switch),
438
439 SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1,
440 REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0),
441
442 SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
443 &jz4760_codec_hp_source),
444
445 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
446 &jz4760_codec_cap_source),
447
448 SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1,
449 REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0),
450
451 SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1,
452 REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0),
453
454 SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3,
455 REG_CR3_MICDIFF_OFFSET, 0, NULL, 0),
456
457 SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
458 jz4760_codec_mic_controls,
459 ARRAY_SIZE(jz4760_codec_mic_controls)),
460
461 SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1,
462 REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0),
463
464 SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2,
465 REG_PMR2_SB_ADC_OFFSET, 1),
466
467 SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2,
468 REG_PMR2_SB_DAC_OFFSET, 1),
469
470 SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
471 jz4760_codec_pcm_playback_controls,
472 ARRAY_SIZE(jz4760_codec_pcm_playback_controls)),
473
474 SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
475 jz4760_codec_hp_playback_controls,
476 ARRAY_SIZE(jz4760_codec_hp_playback_controls)),
477
478 SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1,
479 REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
480
481 SND_SOC_DAPM_INPUT("MIC1P"),
482 SND_SOC_DAPM_INPUT("MIC1N"),
483 SND_SOC_DAPM_INPUT("MIC2P"),
484 SND_SOC_DAPM_INPUT("MIC2N"),
485
486 SND_SOC_DAPM_INPUT("LLINEIN"),
487 SND_SOC_DAPM_INPUT("RLINEIN"),
488
489 SND_SOC_DAPM_OUTPUT("LHPOUT"),
490 SND_SOC_DAPM_OUTPUT("RHPOUT"),
491
492 SND_SOC_DAPM_OUTPUT("LOUT"),
493 SND_SOC_DAPM_OUTPUT("ROUT"),
494
495 SND_SOC_DAPM_OUTPUT("BTLP"),
496 SND_SOC_DAPM_OUTPUT("BTLN"),
497
498 SND_SOC_DAPM_OUTPUT("SYSCLK"),
499};
500
501/* Unconditional routes. */
502static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = {
503 { "Mic 1", NULL, "MIC1P" },
504 { "Mic Diff", NULL, "MIC1N" },
505 { "Mic 1", NULL, "Mic Diff" },
506 { "Mic 2", NULL, "MIC2P" },
507 { "Mic Diff", NULL, "MIC2N" },
508 { "Mic 2", NULL, "Mic Diff" },
509
510 { "Line In", NULL, "LLINEIN" },
511 { "Line In", NULL, "RLINEIN" },
512
513 { "Mic", "Stereo Capture Switch", "Mic 1" },
514 { "Mic", "Stereo Capture Switch", "Mic 2" },
515 { "Headphones Source", "Mic 1", "Mic" },
516 { "Headphones Source", "Mic 2", "Mic" },
517 { "Capture Source", "Mic 1", "Mic" },
518 { "Capture Source", "Mic 2", "Mic" },
519
520 { "Capture Source", "Line In", "Line In" },
521 { "Capture Source", "Mic 1", "Mic 1" },
522 { "Capture Source", "Mic 2", "Mic 2" },
523 { "ADC", NULL, "Capture Source" },
524
525 { "Line In Bypass", NULL, "Line In" },
526
527 { "Headphones Source", "Mic 1", "Mic 1" },
528 { "Headphones Source", "Mic 2", "Mic 2" },
529 { "Headphones Source", "Line In", "Line In Bypass" },
530 { "Headphones Source", "PCM", "Headphones Playback" },
531 { "HP Out", NULL, "Headphones Source" },
532
533 { "LHPOUT", NULL, "HP Out" },
534 { "RHPOUT", NULL, "HP Out" },
535 { "Line Out", "Switch", "HP Out" },
536
537 { "LOUT", NULL, "Line Out" },
538 { "ROUT", NULL, "Line Out" },
539 { "BTL Out", "Switch", "Line Out" },
540
541 { "BTLP", NULL, "BTL Out"},
542 { "BTLN", NULL, "BTL Out"},
543
544 { "PCM Playback", "Volume", "DAC" },
545 { "Headphones Playback", "Volume", "PCM Playback" },
546
547 { "SYSCLK", NULL, "DAC" },
548};
549
550static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec)
551{
552 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(c: codec);
553 struct regmap *regmap = jz_codec->regmap;
554
555 /* Collect updates for later sending. */
556 regcache_cache_only(map: regmap, enable: true);
557
558 /* default Amp output to PCM */
559 regmap_set_bits(map: regmap, reg: JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK);
560
561 /* Disable stereo mic */
562 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_CR3,
563 BIT(REG_CR3_MICSTEREO_OFFSET));
564
565 /* Set mic 1 as default source for ADC */
566 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_CR3,
567 REG_CR3_ADC_INSEL_MASK);
568
569 /* ADC/DAC: serial + i2s */
570 regmap_set_bits(map: regmap, reg: JZ4760_CODEC_REG_AICR,
571 REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S |
572 REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
573
574 /* The generated IRQ is a high level */
575 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
576 regmap_update_bits(map: regmap, reg: JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK,
577 REG_ICR_JACK_MASK | REG_ICR_RUP_MASK |
578 REG_ICR_RDO_MASK | REG_ICR_GUP_MASK |
579 REG_ICR_GDO_MASK);
580
581 /* 12M oscillator */
582 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK);
583
584 /* 0: 16ohm/220uF, 1: 10kohm/1uF */
585 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD);
586
587 /* default to NOMAD */
588 regmap_set_bits(map: jz_codec->regmap, reg: JZ4760_CODEC_REG_CR2,
589 REG_CR2_DAC_NOMAD);
590
591 /* disable automatic gain */
592 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_AGC1, REG_AGC1_EN);
593
594 /* Independent L/R DAC gain control */
595 regmap_clear_bits(map: regmap, reg: JZ4760_CODEC_REG_GCR5,
596 REG_GCR_RL);
597
598 /* Send collected updates. */
599 regcache_cache_only(map: regmap, enable: false);
600 regcache_sync(map: regmap);
601}
602
603static int jz4760_codec_codec_probe(struct snd_soc_component *codec)
604{
605 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(c: codec);
606
607 clk_prepare_enable(clk: jz_codec->clk);
608
609 jz4760_codec_codec_init_regs(codec);
610
611 return 0;
612}
613
614static void jz4760_codec_codec_remove(struct snd_soc_component *codec)
615{
616 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(c: codec);
617
618 clk_disable_unprepare(clk: jz_codec->clk);
619}
620
621static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = {
622 .probe = jz4760_codec_codec_probe,
623 .remove = jz4760_codec_codec_remove,
624 .set_bias_level = jz4760_codec_set_bias_level,
625 .controls = jz4760_codec_snd_controls,
626 .num_controls = ARRAY_SIZE(jz4760_codec_snd_controls),
627 .dapm_widgets = jz4760_codec_dapm_widgets,
628 .num_dapm_widgets = ARRAY_SIZE(jz4760_codec_dapm_widgets),
629 .dapm_routes = jz4760_codec_dapm_routes,
630 .num_dapm_routes = ARRAY_SIZE(jz4760_codec_dapm_routes),
631 .suspend_bias_off = 1,
632 .use_pmdown_time = 1,
633};
634
635static const unsigned int jz4760_codec_sample_rates[] = {
636 96000, 48000, 44100, 32000,
637 24000, 22050, 16000, 12000,
638 11025, 9600, 8000,
639};
640
641static int jz4760_codec_hw_params(struct snd_pcm_substream *substream,
642 struct snd_pcm_hw_params *params,
643 struct snd_soc_dai *dai)
644{
645 struct jz_codec *codec = snd_soc_component_get_drvdata(c: dai->component);
646 unsigned int rate, bit_width;
647
648 switch (params_format(p: params)) {
649 case SNDRV_PCM_FORMAT_S16_LE:
650 bit_width = 0;
651 break;
652 case SNDRV_PCM_FORMAT_S18_3LE:
653 bit_width = 1;
654 break;
655 case SNDRV_PCM_FORMAT_S20_3LE:
656 bit_width = 2;
657 break;
658 case SNDRV_PCM_FORMAT_S24_3LE:
659 bit_width = 3;
660 break;
661 default:
662 return -EINVAL;
663 }
664
665 for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) {
666 if (jz4760_codec_sample_rates[rate] == params_rate(p: params))
667 break;
668 }
669
670 if (rate == ARRAY_SIZE(jz4760_codec_sample_rates))
671 return -EINVAL;
672
673 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
674 regmap_update_bits(map: codec->regmap, reg: JZ4760_CODEC_REG_AICR,
675 REG_AICR_DAC_ADWL_MASK,
676 FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width));
677 regmap_update_bits(map: codec->regmap, reg: JZ4760_CODEC_REG_CCR2,
678 REG_CCR2_DAC_FREQ_MASK,
679 FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate));
680 } else {
681 regmap_update_bits(map: codec->regmap, reg: JZ4760_CODEC_REG_AICR,
682 REG_AICR_ADC_ADWL_MASK,
683 FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width));
684 regmap_update_bits(map: codec->regmap, reg: JZ4760_CODEC_REG_CCR2,
685 REG_CCR2_ADC_FREQ_MASK,
686 FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate));
687 }
688
689 return 0;
690}
691
692static const struct snd_soc_dai_ops jz4760_codec_dai_ops = {
693 .startup = jz4760_codec_startup,
694 .shutdown = jz4760_codec_shutdown,
695 .hw_params = jz4760_codec_hw_params,
696 .trigger = jz4760_codec_pcm_trigger,
697 .mute_stream = jz4760_codec_mute_stream,
698 .no_capture_mute = 1,
699};
700
701#define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
702 SNDRV_PCM_FMTBIT_S18_3LE | \
703 SNDRV_PCM_FMTBIT_S20_3LE | \
704 SNDRV_PCM_FMTBIT_S24_3LE)
705
706static struct snd_soc_dai_driver jz4760_codec_dai = {
707 .name = "jz4760-hifi",
708 .playback = {
709 .stream_name = "Playback",
710 .channels_min = 2,
711 .channels_max = 2,
712 .rates = SNDRV_PCM_RATE_8000_96000,
713 .formats = JZ_CODEC_FORMATS,
714 },
715 .capture = {
716 .stream_name = "Capture",
717 .channels_min = 2,
718 .channels_max = 2,
719 .rates = SNDRV_PCM_RATE_8000_96000,
720 .formats = JZ_CODEC_FORMATS,
721 },
722 .ops = &jz4760_codec_dai_ops,
723};
724
725static bool jz4760_codec_volatile(struct device *dev, unsigned int reg)
726{
727 return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR;
728}
729
730static bool jz4760_codec_writeable(struct device *dev, unsigned int reg)
731{
732 switch (reg) {
733 case JZ4760_CODEC_REG_SR:
734 return false;
735 default:
736 return true;
737 }
738}
739
740static int jz4760_codec_io_wait(struct jz_codec *codec)
741{
742 u32 reg;
743
744 return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
745 !(reg & ICDC_RGADW_RGWR),
746 1000, 1 * USEC_PER_SEC);
747}
748
749static int jz4760_codec_reg_read(void *context, unsigned int reg,
750 unsigned int *val)
751{
752 struct jz_codec *codec = context;
753 unsigned int i;
754 u32 tmp;
755 int ret;
756
757 ret = jz4760_codec_io_wait(codec);
758 if (ret)
759 return ret;
760
761 tmp = readl(addr: codec->base + ICDC_RGADW_OFFSET);
762 tmp &= ~ICDC_RGADW_RGADDR_MASK;
763 tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg);
764 writel(val: tmp, addr: codec->base + ICDC_RGADW_OFFSET);
765
766 /* wait 6+ cycles */
767 for (i = 0; i < 6; i++)
768 *val = readl(addr: codec->base + ICDC_RGDATA_OFFSET) &
769 ICDC_RGDATA_RGDOUT_MASK;
770
771 return 0;
772}
773
774static int jz4760_codec_reg_write(void *context, unsigned int reg,
775 unsigned int val)
776{
777 struct jz_codec *codec = context;
778 int ret;
779
780 ret = jz4760_codec_io_wait(codec);
781 if (ret)
782 return ret;
783
784 writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val,
785 addr: codec->base + ICDC_RGADW_OFFSET);
786
787 ret = jz4760_codec_io_wait(codec);
788 if (ret)
789 return ret;
790
791 return 0;
792}
793
794static const u8 jz4760_codec_reg_defaults[] = {
795 0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00,
796 0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06,
797 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44,
798 0x1F, 0x00, 0x00, 0x00
799};
800
801static const struct regmap_config jz4760_codec_regmap_config = {
802 .reg_bits = 7,
803 .val_bits = 8,
804
805 .max_register = JZ4760_CODEC_REG_MIX2,
806 .volatile_reg = jz4760_codec_volatile,
807 .writeable_reg = jz4760_codec_writeable,
808
809 .reg_read = jz4760_codec_reg_read,
810 .reg_write = jz4760_codec_reg_write,
811
812 .reg_defaults_raw = jz4760_codec_reg_defaults,
813 .num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults),
814 .cache_type = REGCACHE_FLAT,
815};
816
817static int jz4760_codec_probe(struct platform_device *pdev)
818{
819 struct device *dev = &pdev->dev;
820 struct jz_codec *codec;
821 int ret;
822
823 codec = devm_kzalloc(dev, size: sizeof(*codec), GFP_KERNEL);
824 if (!codec)
825 return -ENOMEM;
826
827 codec->dev = dev;
828
829 codec->base = devm_platform_ioremap_resource(pdev, index: 0);
830 if (IS_ERR(ptr: codec->base))
831 return PTR_ERR(ptr: codec->base);
832
833 codec->regmap = devm_regmap_init(dev, NULL, codec,
834 &jz4760_codec_regmap_config);
835 if (IS_ERR(ptr: codec->regmap))
836 return PTR_ERR(ptr: codec->regmap);
837
838 codec->clk = devm_clk_get(dev, id: "aic");
839 if (IS_ERR(ptr: codec->clk))
840 return PTR_ERR(ptr: codec->clk);
841
842 platform_set_drvdata(pdev, data: codec);
843
844 ret = devm_snd_soc_register_component(dev, component_driver: &jz4760_codec_soc_codec_dev,
845 dai_drv: &jz4760_codec_dai, num_dai: 1);
846 if (ret) {
847 dev_err(dev, "Failed to register codec: %d\n", ret);
848 return ret;
849 }
850
851 return 0;
852}
853
854static const struct of_device_id jz4760_codec_of_matches[] = {
855 { .compatible = "ingenic,jz4760-codec", },
856 { /* sentinel */ }
857};
858MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches);
859
860static struct platform_driver jz4760_codec_driver = {
861 .probe = jz4760_codec_probe,
862 .driver = {
863 .name = "jz4760-codec",
864 .of_match_table = jz4760_codec_of_matches,
865 },
866};
867module_platform_driver(jz4760_codec_driver);
868
869MODULE_DESCRIPTION("JZ4760 SoC internal codec driver");
870MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
871MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
872MODULE_LICENSE("GPL v2");
873

source code of linux/sound/soc/codecs/jz4760.c