~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/jz4760.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 */
 35 enum {
 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 */
162 struct jz_codec {
163         struct device *dev;
164         struct regmap *regmap;
165         void __iomem *base;
166         struct clk *clk;
167 };
168 
169 static 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(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(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK);
179 
180                 regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
181                 msleep(250);
182                 regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
183                 msleep(400);
184                 break;
185         case SND_SOC_BIAS_STANDBY:
186                 regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
187                 regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
188                 break;
189         default:
190                 break;
191         }
192 
193         return 0;
194 }
195 
196 static 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_get_dapm(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, "SYSCLK");
210         return ret;
211 }
212 
213 static 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_get_dapm(codec);
218 
219         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
220                 snd_soc_dapm_disable_pin(dapm, "SYSCLK");
221 }
222 
223 
224 static 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         int ret = 0;
229 
230         switch (cmd) {
231         case SNDRV_PCM_TRIGGER_START:
232         case SNDRV_PCM_TRIGGER_RESUME:
233         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
234                 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
235                         snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON);
236                 break;
237         case SNDRV_PCM_TRIGGER_STOP:
238         case SNDRV_PCM_TRIGGER_SUSPEND:
239         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
240                 /* do nothing */
241                 break;
242         default:
243                 ret = -EINVAL;
244         }
245 
246         return ret;
247 }
248 
249 static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
250 {
251         struct snd_soc_component *codec = dai->component;
252         struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
253         unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
254         unsigned int val, reg;
255         int change, err;
256 
257         change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2,
258                                                REG_CR2_DAC_MUTE,
259                                                mute ? REG_CR2_DAC_MUTE : 0);
260         if (change == 1) {
261                 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val);
262 
263                 if (val & BIT(REG_PMR2_SB_DAC_OFFSET))
264                         return 1;
265 
266                 err = regmap_read_poll_timeout(jz_codec->regmap,
267                                                JZ4760_CODEC_REG_IFR,
268                                                val, val & gain_bit,
269                                                1000, 1 * USEC_PER_SEC);
270                 if (err) {
271                         dev_err(jz_codec->dev,
272                                 "Timeout while setting digital mute: %d", err);
273                         return err;
274                 }
275 
276                 /* clear GUP/GDO flag */
277                 regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit);
278         }
279 
280         regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, &reg);
281 
282         return 0;
283 }
284 
285 /* unit: 0.01dB */
286 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100);
287 static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
288 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100);
289 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
290 static const DECLARE_TLV_DB_MINMAX(mixer_tlv, -3100, 0);
291 
292 /* Unconditional controls. */
293 static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = {
294         /* record gain control */
295         SOC_DOUBLE_R_TLV("PCM Capture Volume",
296                          JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8,
297                          REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv),
298 
299         SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
300                          JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3,
301                          REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
302 
303         SOC_SINGLE_TLV("Mixer Capture Volume",
304                        JZ4760_CODEC_REG_MIX1,
305                        REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
306 
307         SOC_SINGLE_TLV("Mixer Playback Volume",
308                        JZ4760_CODEC_REG_MIX2,
309                        REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
310 
311         SOC_SINGLE("High-Pass Filter Capture Switch",
312                    JZ4760_CODEC_REG_CR4,
313                    REG_CR4_ADC_HPF_OFFSET, 1, 0),
314 };
315 
316 static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = {
317         {
318                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
319                 .name = "Volume",
320                 .info = snd_soc_info_volsw,
321                 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
322                         | SNDRV_CTL_ELEM_ACCESS_READWRITE,
323                 .tlv.p = dac_tlv,
324                 .get = snd_soc_dapm_get_volsw,
325                 .put = snd_soc_dapm_put_volsw,
326                 .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6,
327                                                     JZ4760_CODEC_REG_GCR5,
328                                                     REG_GCR_GAIN_OFFSET,
329                                                     REG_GCR_GAIN_MAX, 1),
330         },
331 };
332 
333 static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = {
334         {
335                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
336                 .name = "Volume",
337                 .info = snd_soc_info_volsw,
338                 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
339                         | SNDRV_CTL_ELEM_ACCESS_READWRITE,
340                 .tlv.p = out_tlv,
341                 .get = snd_soc_dapm_get_volsw,
342                 .put = snd_soc_dapm_put_volsw,
343                 .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2,
344                                                     JZ4760_CODEC_REG_GCR1,
345                                                     REG_GCR_GAIN_OFFSET,
346                                                     REG_GCR_GAIN_MAX, 1),
347         },
348 };
349 
350 static int hpout_event(struct snd_soc_dapm_widget *w,
351                        struct snd_kcontrol *kcontrol, int event)
352 {
353         struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
354         struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
355         unsigned int val;
356         int err;
357 
358         switch (event) {
359         case SND_SOC_DAPM_PRE_PMU:
360                 /* unmute HP */
361                 regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
362                                   REG_CR1_HP_MUTE);
363                 break;
364 
365         case SND_SOC_DAPM_POST_PMU:
366                 /* wait for ramp-up complete (RUP) */
367                 err = regmap_read_poll_timeout(jz_codec->regmap,
368                                                JZ4760_CODEC_REG_IFR,
369                                                val, val & REG_IFR_RUP,
370                                                1000, 1 * USEC_PER_SEC);
371                 if (err) {
372                         dev_err(jz_codec->dev, "RUP timeout: %d", err);
373                         return err;
374                 }
375 
376                 /* clear RUP flag */
377                 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
378                                 REG_IFR_RUP);
379 
380                 break;
381 
382         case SND_SOC_DAPM_POST_PMD:
383                 /* mute HP */
384                 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
385                                 REG_CR1_HP_MUTE);
386 
387                 err = regmap_read_poll_timeout(jz_codec->regmap,
388                                                JZ4760_CODEC_REG_IFR,
389                                                val, val & REG_IFR_RDO,
390                                                1000, 1 * USEC_PER_SEC);
391                 if (err) {
392                         dev_err(jz_codec->dev, "RDO timeout: %d", err);
393                         return err;
394                 }
395 
396                 /* clear RDO flag */
397                 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
398                                 REG_IFR_RDO);
399 
400                 break;
401         }
402 
403         return 0;
404 }
405 
406 static const char * const jz4760_codec_hp_texts[] = {
407         "PCM", "Line In", "Mic 1", "Mic 2"
408 };
409 
410 static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 };
411 
412 static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum,
413                                   JZ4760_CODEC_REG_CR1,
414                                   REG_CR1_OUTSEL_OFFSET,
415                                   REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET,
416                                   jz4760_codec_hp_texts,
417                                   jz4760_codec_hp_values);
418 static const struct snd_kcontrol_new jz4760_codec_hp_source =
419                         SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum);
420 
421 static const char * const jz4760_codec_cap_texts[] = {
422         "Line In", "Mic 1", "Mic 2"
423 };
424 
425 static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 };
426 
427 static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum,
428                                   JZ4760_CODEC_REG_CR3,
429                                   REG_CR3_ADC_INSEL_OFFSET,
430                                   REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET,
431                                   jz4760_codec_cap_texts,
432                                   jz4760_codec_cap_values);
433 static const struct snd_kcontrol_new jz4760_codec_cap_source =
434                         SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum);
435 
436 static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = {
437         SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3,
438                         REG_CR3_MICSTEREO_OFFSET, 1, 0),
439 };
440 
441 static const struct snd_kcontrol_new jz4760_codec_line_out_switch =
442         SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
443                         REG_CR1_LO_MUTE_OFFSET, 0, 0);
444 static const struct snd_kcontrol_new jz4760_codec_btl_out_switch =
445         SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
446                         REG_CR1_BTL_MUTE_OFFSET, 0, 0);
447 
448 static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = {
449         SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2,
450                            REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event,
451                            SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
452                            SND_SOC_DAPM_POST_PMD),
453 
454         SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2,
455                             REG_PMR2_SB_LOUT_OFFSET, 1,
456                             &jz4760_codec_line_out_switch),
457 
458         SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2,
459                             REG_PMR2_SB_BTL_OFFSET, 1,
460                             &jz4760_codec_btl_out_switch),
461 
462         SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1,
463                          REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0),
464 
465         SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
466                          &jz4760_codec_hp_source),
467 
468         SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
469                          &jz4760_codec_cap_source),
470 
471         SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1,
472                          REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0),
473 
474         SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1,
475                          REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0),
476 
477         SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3,
478                          REG_CR3_MICDIFF_OFFSET, 0, NULL, 0),
479 
480         SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
481                            jz4760_codec_mic_controls,
482                            ARRAY_SIZE(jz4760_codec_mic_controls)),
483 
484         SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1,
485                          REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0),
486 
487         SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2,
488                          REG_PMR2_SB_ADC_OFFSET, 1),
489 
490         SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2,
491                          REG_PMR2_SB_DAC_OFFSET, 1),
492 
493         SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
494                            jz4760_codec_pcm_playback_controls,
495                            ARRAY_SIZE(jz4760_codec_pcm_playback_controls)),
496 
497         SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
498                            jz4760_codec_hp_playback_controls,
499                            ARRAY_SIZE(jz4760_codec_hp_playback_controls)),
500 
501         SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1,
502                             REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
503 
504         SND_SOC_DAPM_INPUT("MIC1P"),
505         SND_SOC_DAPM_INPUT("MIC1N"),
506         SND_SOC_DAPM_INPUT("MIC2P"),
507         SND_SOC_DAPM_INPUT("MIC2N"),
508 
509         SND_SOC_DAPM_INPUT("LLINEIN"),
510         SND_SOC_DAPM_INPUT("RLINEIN"),
511 
512         SND_SOC_DAPM_OUTPUT("LHPOUT"),
513         SND_SOC_DAPM_OUTPUT("RHPOUT"),
514 
515         SND_SOC_DAPM_OUTPUT("LOUT"),
516         SND_SOC_DAPM_OUTPUT("ROUT"),
517 
518         SND_SOC_DAPM_OUTPUT("BTLP"),
519         SND_SOC_DAPM_OUTPUT("BTLN"),
520 
521         SND_SOC_DAPM_OUTPUT("SYSCLK"),
522 };
523 
524 /* Unconditional routes. */
525 static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = {
526         { "Mic 1", NULL, "MIC1P" },
527         { "Mic Diff", NULL, "MIC1N" },
528         { "Mic 1", NULL, "Mic Diff" },
529         { "Mic 2", NULL, "MIC2P" },
530         { "Mic Diff", NULL, "MIC2N" },
531         { "Mic 2", NULL, "Mic Diff" },
532 
533         { "Line In", NULL, "LLINEIN" },
534         { "Line In", NULL, "RLINEIN" },
535 
536         { "Mic", "Stereo Capture Switch", "Mic 1" },
537         { "Mic", "Stereo Capture Switch", "Mic 2" },
538         { "Headphones Source", "Mic 1", "Mic" },
539         { "Headphones Source", "Mic 2", "Mic" },
540         { "Capture Source", "Mic 1", "Mic" },
541         { "Capture Source", "Mic 2", "Mic" },
542 
543         { "Capture Source", "Line In", "Line In" },
544         { "Capture Source", "Mic 1", "Mic 1" },
545         { "Capture Source", "Mic 2", "Mic 2" },
546         { "ADC", NULL, "Capture Source" },
547 
548         { "Line In Bypass", NULL, "Line In" },
549 
550         { "Headphones Source", "Mic 1", "Mic 1" },
551         { "Headphones Source", "Mic 2", "Mic 2" },
552         { "Headphones Source", "Line In", "Line In Bypass" },
553         { "Headphones Source", "PCM", "Headphones Playback" },
554         { "HP Out", NULL, "Headphones Source" },
555 
556         { "LHPOUT", NULL, "HP Out" },
557         { "RHPOUT", NULL, "HP Out" },
558         { "Line Out", "Switch", "HP Out" },
559 
560         { "LOUT", NULL, "Line Out" },
561         { "ROUT", NULL, "Line Out" },
562         { "BTL Out", "Switch", "Line Out" },
563 
564         { "BTLP", NULL, "BTL Out"},
565         { "BTLN", NULL, "BTL Out"},
566 
567         { "PCM Playback", "Volume", "DAC" },
568         { "Headphones Playback", "Volume", "PCM Playback" },
569 
570         { "SYSCLK", NULL, "DAC" },
571 };
572 
573 static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec)
574 {
575         struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
576         struct regmap *regmap = jz_codec->regmap;
577 
578         /* Collect updates for later sending. */
579         regcache_cache_only(regmap, true);
580 
581         /* default Amp output to PCM */
582         regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK);
583 
584         /* Disable stereo mic */
585         regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
586                           BIT(REG_CR3_MICSTEREO_OFFSET));
587 
588         /* Set mic 1 as default source for ADC */
589         regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
590                           REG_CR3_ADC_INSEL_MASK);
591 
592         /* ADC/DAC: serial + i2s */
593         regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR,
594                         REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S |
595                         REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
596 
597         /* The generated IRQ is a high level */
598         regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
599         regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK,
600                            REG_ICR_JACK_MASK | REG_ICR_RUP_MASK |
601                            REG_ICR_RDO_MASK  | REG_ICR_GUP_MASK |
602                            REG_ICR_GDO_MASK);
603 
604         /* 12M oscillator */
605         regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK);
606 
607         /* 0: 16ohm/220uF, 1: 10kohm/1uF */
608         regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD);
609 
610         /* default to NOMAD */
611         regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2,
612                         REG_CR2_DAC_NOMAD);
613 
614         /* disable automatic gain */
615         regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN);
616 
617         /* Independent L/R DAC gain control */
618         regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5,
619                           REG_GCR_RL);
620 
621         /* Send collected updates. */
622         regcache_cache_only(regmap, false);
623         regcache_sync(regmap);
624 }
625 
626 static int jz4760_codec_codec_probe(struct snd_soc_component *codec)
627 {
628         struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
629 
630         clk_prepare_enable(jz_codec->clk);
631 
632         jz4760_codec_codec_init_regs(codec);
633 
634         return 0;
635 }
636 
637 static void jz4760_codec_codec_remove(struct snd_soc_component *codec)
638 {
639         struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
640 
641         clk_disable_unprepare(jz_codec->clk);
642 }
643 
644 static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = {
645         .probe                  = jz4760_codec_codec_probe,
646         .remove                 = jz4760_codec_codec_remove,
647         .set_bias_level         = jz4760_codec_set_bias_level,
648         .controls               = jz4760_codec_snd_controls,
649         .num_controls           = ARRAY_SIZE(jz4760_codec_snd_controls),
650         .dapm_widgets           = jz4760_codec_dapm_widgets,
651         .num_dapm_widgets       = ARRAY_SIZE(jz4760_codec_dapm_widgets),
652         .dapm_routes            = jz4760_codec_dapm_routes,
653         .num_dapm_routes        = ARRAY_SIZE(jz4760_codec_dapm_routes),
654         .suspend_bias_off       = 1,
655         .use_pmdown_time        = 1,
656 };
657 
658 static const unsigned int jz4760_codec_sample_rates[] = {
659         96000, 48000, 44100, 32000,
660         24000, 22050, 16000, 12000,
661         11025, 9600, 8000,
662 };
663 
664 static int jz4760_codec_hw_params(struct snd_pcm_substream *substream,
665                                   struct snd_pcm_hw_params *params,
666                                   struct snd_soc_dai *dai)
667 {
668         struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
669         unsigned int rate, bit_width;
670 
671         switch (params_format(params)) {
672         case SNDRV_PCM_FORMAT_S16_LE:
673                 bit_width = 0;
674                 break;
675         case SNDRV_PCM_FORMAT_S18_3LE:
676                 bit_width = 1;
677                 break;
678         case SNDRV_PCM_FORMAT_S20_3LE:
679                 bit_width = 2;
680                 break;
681         case SNDRV_PCM_FORMAT_S24_3LE:
682                 bit_width = 3;
683                 break;
684         default:
685                 return -EINVAL;
686         }
687 
688         for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) {
689                 if (jz4760_codec_sample_rates[rate] == params_rate(params))
690                         break;
691         }
692 
693         if (rate == ARRAY_SIZE(jz4760_codec_sample_rates))
694                 return -EINVAL;
695 
696         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
697                 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
698                                    REG_AICR_DAC_ADWL_MASK,
699                                    FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width));
700                 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
701                                    REG_CCR2_DAC_FREQ_MASK,
702                                    FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate));
703         } else {
704                 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
705                                    REG_AICR_ADC_ADWL_MASK,
706                                    FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width));
707                 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
708                                    REG_CCR2_ADC_FREQ_MASK,
709                                    FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate));
710         }
711 
712         return 0;
713 }
714 
715 static const struct snd_soc_dai_ops jz4760_codec_dai_ops = {
716         .startup        = jz4760_codec_startup,
717         .shutdown       = jz4760_codec_shutdown,
718         .hw_params      = jz4760_codec_hw_params,
719         .trigger        = jz4760_codec_pcm_trigger,
720         .mute_stream    = jz4760_codec_mute_stream,
721         .no_capture_mute = 1,
722 };
723 
724 #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | \
725                           SNDRV_PCM_FMTBIT_S18_3LE | \
726                           SNDRV_PCM_FMTBIT_S20_3LE | \
727                           SNDRV_PCM_FMTBIT_S24_3LE)
728 
729 static struct snd_soc_dai_driver jz4760_codec_dai = {
730         .name = "jz4760-hifi",
731         .playback = {
732                 .stream_name = "Playback",
733                 .channels_min = 2,
734                 .channels_max = 2,
735                 .rates = SNDRV_PCM_RATE_8000_96000,
736                 .formats = JZ_CODEC_FORMATS,
737         },
738         .capture = {
739                 .stream_name = "Capture",
740                 .channels_min = 2,
741                 .channels_max = 2,
742                 .rates = SNDRV_PCM_RATE_8000_96000,
743                 .formats = JZ_CODEC_FORMATS,
744         },
745         .ops = &jz4760_codec_dai_ops,
746 };
747 
748 static bool jz4760_codec_volatile(struct device *dev, unsigned int reg)
749 {
750         return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR;
751 }
752 
753 static bool jz4760_codec_writeable(struct device *dev, unsigned int reg)
754 {
755         switch (reg) {
756         case JZ4760_CODEC_REG_SR:
757                 return false;
758         default:
759                 return true;
760         }
761 }
762 
763 static int jz4760_codec_io_wait(struct jz_codec *codec)
764 {
765         u32 reg;
766 
767         return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
768                                   !(reg & ICDC_RGADW_RGWR),
769                                   1000, 1 * USEC_PER_SEC);
770 }
771 
772 static int jz4760_codec_reg_read(void *context, unsigned int reg,
773                                  unsigned int *val)
774 {
775         struct jz_codec *codec = context;
776         unsigned int i;
777         u32 tmp;
778         int ret;
779 
780         ret = jz4760_codec_io_wait(codec);
781         if (ret)
782                 return ret;
783 
784         tmp = readl(codec->base + ICDC_RGADW_OFFSET);
785         tmp &= ~ICDC_RGADW_RGADDR_MASK;
786         tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg);
787         writel(tmp, codec->base + ICDC_RGADW_OFFSET);
788 
789         /* wait 6+ cycles */
790         for (i = 0; i < 6; i++)
791                 *val = readl(codec->base + ICDC_RGDATA_OFFSET) &
792                         ICDC_RGDATA_RGDOUT_MASK;
793 
794         return 0;
795 }
796 
797 static int jz4760_codec_reg_write(void *context, unsigned int reg,
798                                   unsigned int val)
799 {
800         struct jz_codec *codec = context;
801         int ret;
802 
803         ret = jz4760_codec_io_wait(codec);
804         if (ret)
805                 return ret;
806 
807         writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val,
808                codec->base + ICDC_RGADW_OFFSET);
809 
810         ret = jz4760_codec_io_wait(codec);
811         if (ret)
812                 return ret;
813 
814         return 0;
815 }
816 
817 static const u8 jz4760_codec_reg_defaults[] = {
818         0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00,
819         0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06,
820         0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44,
821         0x1F, 0x00, 0x00, 0x00
822 };
823 
824 static const struct regmap_config jz4760_codec_regmap_config = {
825         .reg_bits = 7,
826         .val_bits = 8,
827 
828         .max_register = JZ4760_CODEC_REG_MIX2,
829         .volatile_reg = jz4760_codec_volatile,
830         .writeable_reg = jz4760_codec_writeable,
831 
832         .reg_read = jz4760_codec_reg_read,
833         .reg_write = jz4760_codec_reg_write,
834 
835         .reg_defaults_raw = jz4760_codec_reg_defaults,
836         .num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults),
837         .cache_type = REGCACHE_FLAT,
838 };
839 
840 static int jz4760_codec_probe(struct platform_device *pdev)
841 {
842         struct device *dev = &pdev->dev;
843         struct jz_codec *codec;
844         int ret;
845 
846         codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
847         if (!codec)
848                 return -ENOMEM;
849 
850         codec->dev = dev;
851 
852         codec->base = devm_platform_ioremap_resource(pdev, 0);
853         if (IS_ERR(codec->base))
854                 return PTR_ERR(codec->base);
855 
856         codec->regmap = devm_regmap_init(dev, NULL, codec,
857                                         &jz4760_codec_regmap_config);
858         if (IS_ERR(codec->regmap))
859                 return PTR_ERR(codec->regmap);
860 
861         codec->clk = devm_clk_get(dev, "aic");
862         if (IS_ERR(codec->clk))
863                 return PTR_ERR(codec->clk);
864 
865         platform_set_drvdata(pdev, codec);
866 
867         ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev,
868                                               &jz4760_codec_dai, 1);
869         if (ret) {
870                 dev_err(dev, "Failed to register codec: %d\n", ret);
871                 return ret;
872         }
873 
874         return 0;
875 }
876 
877 static const struct of_device_id jz4760_codec_of_matches[] = {
878         { .compatible = "ingenic,jz4760-codec", },
879         { /* sentinel */ }
880 };
881 MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches);
882 
883 static struct platform_driver jz4760_codec_driver = {
884         .probe                  = jz4760_codec_probe,
885         .driver                 = {
886                 .name           = "jz4760-codec",
887                 .of_match_table = jz4760_codec_of_matches,
888         },
889 };
890 module_platform_driver(jz4760_codec_driver);
891 
892 MODULE_DESCRIPTION("JZ4760 SoC internal codec driver");
893 MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
894 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
895 MODULE_LICENSE("GPL v2");
896 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php