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

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

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * ADAV80X Audio Codec driver supporting ADAV801, ADAV803
  3  *
  4  * Copyright 2011 Analog Devices Inc.
  5  * Author: Yi Li <yi.li@analog.com>
  6  * Author: Lars-Peter Clausen <lars@metafoo.de>
  7  *
  8  * Licensed under the GPL-2 or later.
  9  */
 10 
 11 #include <linux/module.h>
 12 #include <linux/kernel.h>
 13 #include <linux/regmap.h>
 14 #include <linux/slab.h>
 15 
 16 #include <sound/pcm.h>
 17 #include <sound/pcm_params.h>
 18 #include <sound/soc.h>
 19 #include <sound/tlv.h>
 20 
 21 #include "adav80x.h"
 22 
 23 #define ADAV80X_PLAYBACK_CTRL   0x04
 24 #define ADAV80X_AUX_IN_CTRL     0x05
 25 #define ADAV80X_REC_CTRL        0x06
 26 #define ADAV80X_AUX_OUT_CTRL    0x07
 27 #define ADAV80X_DPATH_CTRL1     0x62
 28 #define ADAV80X_DPATH_CTRL2     0x63
 29 #define ADAV80X_DAC_CTRL1       0x64
 30 #define ADAV80X_DAC_CTRL2       0x65
 31 #define ADAV80X_DAC_CTRL3       0x66
 32 #define ADAV80X_DAC_L_VOL       0x68
 33 #define ADAV80X_DAC_R_VOL       0x69
 34 #define ADAV80X_PGA_L_VOL       0x6c
 35 #define ADAV80X_PGA_R_VOL       0x6d
 36 #define ADAV80X_ADC_CTRL1       0x6e
 37 #define ADAV80X_ADC_CTRL2       0x6f
 38 #define ADAV80X_ADC_L_VOL       0x70
 39 #define ADAV80X_ADC_R_VOL       0x71
 40 #define ADAV80X_PLL_CTRL1       0x74
 41 #define ADAV80X_PLL_CTRL2       0x75
 42 #define ADAV80X_ICLK_CTRL1      0x76
 43 #define ADAV80X_ICLK_CTRL2      0x77
 44 #define ADAV80X_PLL_CLK_SRC     0x78
 45 #define ADAV80X_PLL_OUTE        0x7a
 46 
 47 #define ADAV80X_PLL_CLK_SRC_PLL_XIN(pll)        0x00
 48 #define ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll)      (0x40 << (pll))
 49 #define ADAV80X_PLL_CLK_SRC_PLL_MASK(pll)       (0x40 << (pll))
 50 
 51 #define ADAV80X_ICLK_CTRL1_DAC_SRC(src)         ((src) << 5)
 52 #define ADAV80X_ICLK_CTRL1_ADC_SRC(src)         ((src) << 2)
 53 #define ADAV80X_ICLK_CTRL1_ICLK2_SRC(src)       (src)
 54 #define ADAV80X_ICLK_CTRL2_ICLK1_SRC(src)       ((src) << 3)
 55 
 56 #define ADAV80X_PLL_CTRL1_PLLDIV                0x10
 57 #define ADAV80X_PLL_CTRL1_PLLPD(pll)            (0x04 << (pll))
 58 #define ADAV80X_PLL_CTRL1_XTLPD                 0x02
 59 
 60 #define ADAV80X_PLL_CTRL2_FIELD(pll, x)         ((x) << ((pll) * 4))
 61 
 62 #define ADAV80X_PLL_CTRL2_FS_48(pll)    ADAV80X_PLL_CTRL2_FIELD((pll), 0x00)
 63 #define ADAV80X_PLL_CTRL2_FS_32(pll)    ADAV80X_PLL_CTRL2_FIELD((pll), 0x08)
 64 #define ADAV80X_PLL_CTRL2_FS_44(pll)    ADAV80X_PLL_CTRL2_FIELD((pll), 0x0c)
 65 
 66 #define ADAV80X_PLL_CTRL2_SEL(pll)      ADAV80X_PLL_CTRL2_FIELD((pll), 0x02)
 67 #define ADAV80X_PLL_CTRL2_DOUB(pll)     ADAV80X_PLL_CTRL2_FIELD((pll), 0x01)
 68 #define ADAV80X_PLL_CTRL2_PLL_MASK(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0f)
 69 
 70 #define ADAV80X_ADC_CTRL1_MODULATOR_MASK        0x80
 71 #define ADAV80X_ADC_CTRL1_MODULATOR_128FS       0x00
 72 #define ADAV80X_ADC_CTRL1_MODULATOR_64FS        0x80
 73 
 74 #define ADAV80X_DAC_CTRL1_PD                    0x80
 75 
 76 #define ADAV80X_DAC_CTRL2_DIV1                  0x00
 77 #define ADAV80X_DAC_CTRL2_DIV1_5                0x10
 78 #define ADAV80X_DAC_CTRL2_DIV2                  0x20
 79 #define ADAV80X_DAC_CTRL2_DIV3                  0x30
 80 #define ADAV80X_DAC_CTRL2_DIV_MASK              0x30
 81 
 82 #define ADAV80X_DAC_CTRL2_INTERPOL_256FS        0x00
 83 #define ADAV80X_DAC_CTRL2_INTERPOL_128FS        0x40
 84 #define ADAV80X_DAC_CTRL2_INTERPOL_64FS         0x80
 85 #define ADAV80X_DAC_CTRL2_INTERPOL_MASK         0xc0
 86 
 87 #define ADAV80X_DAC_CTRL2_DEEMPH_NONE           0x00
 88 #define ADAV80X_DAC_CTRL2_DEEMPH_44             0x01
 89 #define ADAV80X_DAC_CTRL2_DEEMPH_32             0x02
 90 #define ADAV80X_DAC_CTRL2_DEEMPH_48             0x03
 91 #define ADAV80X_DAC_CTRL2_DEEMPH_MASK           0x01
 92 
 93 #define ADAV80X_CAPTURE_MODE_MASTER             0x20
 94 #define ADAV80X_CAPTURE_WORD_LEN24              0x00
 95 #define ADAV80X_CAPTURE_WORD_LEN20              0x04
 96 #define ADAV80X_CAPTRUE_WORD_LEN18              0x08
 97 #define ADAV80X_CAPTURE_WORD_LEN16              0x0c
 98 #define ADAV80X_CAPTURE_WORD_LEN_MASK           0x0c
 99 
100 #define ADAV80X_CAPTURE_MODE_LEFT_J             0x00
101 #define ADAV80X_CAPTURE_MODE_I2S                0x01
102 #define ADAV80X_CAPTURE_MODE_RIGHT_J            0x03
103 #define ADAV80X_CAPTURE_MODE_MASK               0x03
104 
105 #define ADAV80X_PLAYBACK_MODE_MASTER            0x10
106 #define ADAV80X_PLAYBACK_MODE_LEFT_J            0x00
107 #define ADAV80X_PLAYBACK_MODE_I2S               0x01
108 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_24        0x04
109 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_20        0x05
110 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_18        0x06
111 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_16        0x07
112 #define ADAV80X_PLAYBACK_MODE_MASK              0x07
113 
114 #define ADAV80X_PLL_OUTE_SYSCLKPD(x)            BIT(2 - (x))
115 
116 static struct reg_default adav80x_reg_defaults[] = {
117         { ADAV80X_PLAYBACK_CTRL,        0x01 },
118         { ADAV80X_AUX_IN_CTRL,          0x01 },
119         { ADAV80X_REC_CTRL,             0x02 },
120         { ADAV80X_AUX_OUT_CTRL,         0x01 },
121         { ADAV80X_DPATH_CTRL1,          0xc0 },
122         { ADAV80X_DPATH_CTRL2,          0x11 },
123         { ADAV80X_DAC_CTRL1,            0x00 },
124         { ADAV80X_DAC_CTRL2,            0x00 },
125         { ADAV80X_DAC_CTRL3,            0x00 },
126         { ADAV80X_DAC_L_VOL,            0xff },
127         { ADAV80X_DAC_R_VOL,            0xff },
128         { ADAV80X_PGA_L_VOL,            0x00 },
129         { ADAV80X_PGA_R_VOL,            0x00 },
130         { ADAV80X_ADC_CTRL1,            0x00 },
131         { ADAV80X_ADC_CTRL2,            0x00 },
132         { ADAV80X_ADC_L_VOL,            0xff },
133         { ADAV80X_ADC_R_VOL,            0xff },
134         { ADAV80X_PLL_CTRL1,            0x00 },
135         { ADAV80X_PLL_CTRL2,            0x00 },
136         { ADAV80X_ICLK_CTRL1,           0x00 },
137         { ADAV80X_ICLK_CTRL2,           0x00 },
138         { ADAV80X_PLL_CLK_SRC,          0x00 },
139         { ADAV80X_PLL_OUTE,             0x00 },
140 };
141 
142 struct adav80x {
143         struct regmap *regmap;
144 
145         enum adav80x_clk_src clk_src;
146         unsigned int sysclk;
147         enum adav80x_pll_src pll_src;
148 
149         unsigned int dai_fmt[2];
150         unsigned int rate;
151         bool deemph;
152         bool sysclk_pd[3];
153 };
154 
155 static const char *adav80x_mux_text[] = {
156         "ADC",
157         "Playback",
158         "Aux Playback",
159 };
160 
161 static const unsigned int adav80x_mux_values[] = {
162         0, 2, 3,
163 };
164 
165 #define ADAV80X_MUX_ENUM_DECL(name, reg, shift) \
166         SOC_VALUE_ENUM_DOUBLE_DECL(name, reg, shift, 7, \
167                 ARRAY_SIZE(adav80x_mux_text), adav80x_mux_text, \
168                 adav80x_mux_values)
169 
170 static ADAV80X_MUX_ENUM_DECL(adav80x_aux_capture_enum, ADAV80X_DPATH_CTRL1, 0);
171 static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3);
172 static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3);
173 
174 static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl =
175         SOC_DAPM_VALUE_ENUM("Route", adav80x_aux_capture_enum);
176 static const struct snd_kcontrol_new adav80x_capture_mux_ctrl =
177         SOC_DAPM_VALUE_ENUM("Route", adav80x_capture_enum);
178 static const struct snd_kcontrol_new adav80x_dac_mux_ctrl =
179         SOC_DAPM_VALUE_ENUM("Route", adav80x_dac_enum);
180 
181 #define ADAV80X_MUX(name, ctrl) \
182         SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
183 
184 static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {
185         SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1),
186         SND_SOC_DAPM_ADC("ADC", NULL, ADAV80X_ADC_CTRL1, 5, 1),
187 
188         SND_SOC_DAPM_PGA("Right PGA", ADAV80X_ADC_CTRL1, 0, 1, NULL, 0),
189         SND_SOC_DAPM_PGA("Left PGA", ADAV80X_ADC_CTRL1, 1, 1, NULL, 0),
190 
191         SND_SOC_DAPM_AIF_OUT("AIFOUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
192         SND_SOC_DAPM_AIF_IN("AIFIN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
193 
194         SND_SOC_DAPM_AIF_OUT("AIFAUXOUT", "Aux Capture", 0, SND_SOC_NOPM, 0, 0),
195         SND_SOC_DAPM_AIF_IN("AIFAUXIN", "Aux Playback", 0, SND_SOC_NOPM, 0, 0),
196 
197         ADAV80X_MUX("Aux Capture Select", &adav80x_aux_capture_mux_ctrl),
198         ADAV80X_MUX("Capture Select", &adav80x_capture_mux_ctrl),
199         ADAV80X_MUX("DAC Select", &adav80x_dac_mux_ctrl),
200 
201         SND_SOC_DAPM_INPUT("VINR"),
202         SND_SOC_DAPM_INPUT("VINL"),
203         SND_SOC_DAPM_OUTPUT("VOUTR"),
204         SND_SOC_DAPM_OUTPUT("VOUTL"),
205 
206         SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
207         SND_SOC_DAPM_SUPPLY("PLL1", ADAV80X_PLL_CTRL1, 2, 1, NULL, 0),
208         SND_SOC_DAPM_SUPPLY("PLL2", ADAV80X_PLL_CTRL1, 3, 1, NULL, 0),
209         SND_SOC_DAPM_SUPPLY("OSC", ADAV80X_PLL_CTRL1, 1, 1, NULL, 0),
210 };
211 
212 static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
213                          struct snd_soc_dapm_widget *sink)
214 {
215         struct snd_soc_codec *codec = source->codec;
216         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
217         const char *clk;
218 
219         switch (adav80x->clk_src) {
220         case ADAV80X_CLK_PLL1:
221                 clk = "PLL1";
222                 break;
223         case ADAV80X_CLK_PLL2:
224                 clk = "PLL2";
225                 break;
226         case ADAV80X_CLK_XTAL:
227                 clk = "OSC";
228                 break;
229         default:
230                 return 0;
231         }
232 
233         return strcmp(source->name, clk) == 0;
234 }
235 
236 static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
237                          struct snd_soc_dapm_widget *sink)
238 {
239         struct snd_soc_codec *codec = source->codec;
240         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
241 
242         return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
243 }
244 
245 
246 static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {
247         { "DAC Select", "ADC", "ADC" },
248         { "DAC Select", "Playback", "AIFIN" },
249         { "DAC Select", "Aux Playback", "AIFAUXIN" },
250         { "DAC", NULL,  "DAC Select" },
251 
252         { "Capture Select", "ADC", "ADC" },
253         { "Capture Select", "Playback", "AIFIN" },
254         { "Capture Select", "Aux Playback", "AIFAUXIN" },
255         { "AIFOUT", NULL,  "Capture Select" },
256 
257         { "Aux Capture Select", "ADC", "ADC" },
258         { "Aux Capture Select", "Playback", "AIFIN" },
259         { "Aux Capture Select", "Aux Playback", "AIFAUXIN" },
260         { "AIFAUXOUT", NULL,  "Aux Capture Select" },
261 
262         { "VOUTR",  NULL, "DAC" },
263         { "VOUTL",  NULL, "DAC" },
264 
265         { "Left PGA", NULL, "VINL" },
266         { "Right PGA", NULL, "VINR" },
267         { "ADC", NULL, "Left PGA" },
268         { "ADC", NULL, "Right PGA" },
269 
270         { "SYSCLK", NULL, "PLL1", adav80x_dapm_sysclk_check },
271         { "SYSCLK", NULL, "PLL2", adav80x_dapm_sysclk_check },
272         { "SYSCLK", NULL, "OSC", adav80x_dapm_sysclk_check },
273         { "PLL1", NULL, "OSC", adav80x_dapm_pll_check },
274         { "PLL2", NULL, "OSC", adav80x_dapm_pll_check },
275 
276         { "ADC", NULL, "SYSCLK" },
277         { "DAC", NULL, "SYSCLK" },
278         { "AIFOUT", NULL, "SYSCLK" },
279         { "AIFAUXOUT", NULL, "SYSCLK" },
280         { "AIFIN", NULL, "SYSCLK" },
281         { "AIFAUXIN", NULL, "SYSCLK" },
282 };
283 
284 static int adav80x_set_deemph(struct snd_soc_codec *codec)
285 {
286         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
287         unsigned int val;
288 
289         if (adav80x->deemph) {
290                 switch (adav80x->rate) {
291                 case 32000:
292                         val = ADAV80X_DAC_CTRL2_DEEMPH_32;
293                         break;
294                 case 44100:
295                         val = ADAV80X_DAC_CTRL2_DEEMPH_44;
296                         break;
297                 case 48000:
298                 case 64000:
299                 case 88200:
300                 case 96000:
301                         val = ADAV80X_DAC_CTRL2_DEEMPH_48;
302                         break;
303                 default:
304                         val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
305                         break;
306                 }
307         } else {
308                 val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
309         }
310 
311         return regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2,
312                 ADAV80X_DAC_CTRL2_DEEMPH_MASK, val);
313 }
314 
315 static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
316                 struct snd_ctl_elem_value *ucontrol)
317 {
318         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
319         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
320         unsigned int deemph = ucontrol->value.enumerated.item[0];
321 
322         if (deemph > 1)
323                 return -EINVAL;
324 
325         adav80x->deemph = deemph;
326 
327         return adav80x_set_deemph(codec);
328 }
329 
330 static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
331                                 struct snd_ctl_elem_value *ucontrol)
332 {
333         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
334         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
335 
336         ucontrol->value.enumerated.item[0] = adav80x->deemph;
337         return 0;
338 };
339 
340 static const DECLARE_TLV_DB_SCALE(adav80x_inpga_tlv, 0, 50, 0);
341 static const DECLARE_TLV_DB_MINMAX(adav80x_digital_tlv, -9563, 0);
342 
343 static const struct snd_kcontrol_new adav80x_controls[] = {
344         SOC_DOUBLE_R_TLV("Master Playback Volume", ADAV80X_DAC_L_VOL,
345                 ADAV80X_DAC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
346         SOC_DOUBLE_R_TLV("Master Capture Volume", ADAV80X_ADC_L_VOL,
347                         ADAV80X_ADC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
348 
349         SOC_DOUBLE_R_TLV("PGA Capture Volume", ADAV80X_PGA_L_VOL,
350                         ADAV80X_PGA_R_VOL, 0, 0x30, 0, adav80x_inpga_tlv),
351 
352         SOC_DOUBLE("Master Playback Switch", ADAV80X_DAC_CTRL1, 0, 1, 1, 0),
353         SOC_DOUBLE("Master Capture Switch", ADAV80X_ADC_CTRL1, 2, 3, 1, 1),
354 
355         SOC_SINGLE("ADC High Pass Filter Switch", ADAV80X_ADC_CTRL1, 6, 1, 0),
356 
357         SOC_SINGLE_BOOL_EXT("Playback De-emphasis Switch", 0,
358                         adav80x_get_deemph, adav80x_put_deemph),
359 };
360 
361 static unsigned int adav80x_port_ctrl_regs[2][2] = {
362         { ADAV80X_REC_CTRL, ADAV80X_PLAYBACK_CTRL, },
363         { ADAV80X_AUX_OUT_CTRL, ADAV80X_AUX_IN_CTRL },
364 };
365 
366 static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
367 {
368         struct snd_soc_codec *codec = dai->codec;
369         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
370         unsigned int capture = 0x00;
371         unsigned int playback = 0x00;
372 
373         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
374         case SND_SOC_DAIFMT_CBM_CFM:
375                 capture |= ADAV80X_CAPTURE_MODE_MASTER;
376                 playback |= ADAV80X_PLAYBACK_MODE_MASTER;
377         case SND_SOC_DAIFMT_CBS_CFS:
378                 break;
379         default:
380                 return -EINVAL;
381         }
382 
383         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
384         case SND_SOC_DAIFMT_I2S:
385                 capture |= ADAV80X_CAPTURE_MODE_I2S;
386                 playback |= ADAV80X_PLAYBACK_MODE_I2S;
387                 break;
388         case SND_SOC_DAIFMT_LEFT_J:
389                 capture |= ADAV80X_CAPTURE_MODE_LEFT_J;
390                 playback |= ADAV80X_PLAYBACK_MODE_LEFT_J;
391                 break;
392         case SND_SOC_DAIFMT_RIGHT_J:
393                 capture |= ADAV80X_CAPTURE_MODE_RIGHT_J;
394                 playback |= ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
395                 break;
396         default:
397                 return -EINVAL;
398         }
399 
400         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
401         case SND_SOC_DAIFMT_NB_NF:
402                 break;
403         default:
404                 return -EINVAL;
405         }
406 
407         regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0],
408                 ADAV80X_CAPTURE_MODE_MASK | ADAV80X_CAPTURE_MODE_MASTER,
409                 capture);
410         regmap_write(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1],
411                 playback);
412 
413         adav80x->dai_fmt[dai->id] = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
414 
415         return 0;
416 }
417 
418 static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
419                 unsigned int sample_rate)
420 {
421         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
422         unsigned int val;
423 
424         if (sample_rate <= 48000)
425                 val = ADAV80X_ADC_CTRL1_MODULATOR_128FS;
426         else
427                 val = ADAV80X_ADC_CTRL1_MODULATOR_64FS;
428 
429         regmap_update_bits(adav80x->regmap, ADAV80X_ADC_CTRL1,
430                 ADAV80X_ADC_CTRL1_MODULATOR_MASK, val);
431 
432         return 0;
433 }
434 
435 static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
436                 unsigned int sample_rate)
437 {
438         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
439         unsigned int val;
440 
441         if (sample_rate <= 48000)
442                 val = ADAV80X_DAC_CTRL2_DIV1 | ADAV80X_DAC_CTRL2_INTERPOL_256FS;
443         else
444                 val = ADAV80X_DAC_CTRL2_DIV2 | ADAV80X_DAC_CTRL2_INTERPOL_128FS;
445 
446         regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2,
447                 ADAV80X_DAC_CTRL2_DIV_MASK | ADAV80X_DAC_CTRL2_INTERPOL_MASK,
448                 val);
449 
450         return 0;
451 }
452 
453 static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
454                 struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
455 {
456         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
457         unsigned int val;
458 
459         switch (params_width(params)) {
460         case 16:
461                 val = ADAV80X_CAPTURE_WORD_LEN16;
462                 break;
463         case 18:
464                 val = ADAV80X_CAPTRUE_WORD_LEN18;
465                 break;
466         case 20:
467                 val = ADAV80X_CAPTURE_WORD_LEN20;
468                 break;
469         case 24:
470                 val = ADAV80X_CAPTURE_WORD_LEN24;
471                 break;
472         default:
473                 return -EINVAL;
474         }
475 
476         regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0],
477                 ADAV80X_CAPTURE_WORD_LEN_MASK, val);
478 
479         return 0;
480 }
481 
482 static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
483                 struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
484 {
485         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
486         unsigned int val;
487 
488         if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
489                 return 0;
490 
491         switch (params_width(params)) {
492         case 16:
493                 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
494                 break;
495         case 18:
496                 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
497                 break;
498         case 20:
499                 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
500                 break;
501         case 24:
502                 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
503                 break;
504         default:
505                 return -EINVAL;
506         }
507 
508         regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1],
509                 ADAV80X_PLAYBACK_MODE_MASK, val);
510 
511         return 0;
512 }
513 
514 static int adav80x_hw_params(struct snd_pcm_substream *substream,
515                 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
516 {
517         struct snd_soc_codec *codec = dai->codec;
518         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
519         unsigned int rate = params_rate(params);
520 
521         if (rate * 256 != adav80x->sysclk)
522                 return -EINVAL;
523 
524         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
525                 adav80x_set_playback_pcm_format(codec, dai, params);
526                 adav80x_set_dac_clock(codec, rate);
527         } else {
528                 adav80x_set_capture_pcm_format(codec, dai, params);
529                 adav80x_set_adc_clock(codec, rate);
530         }
531         adav80x->rate = rate;
532         adav80x_set_deemph(codec);
533 
534         return 0;
535 }
536 
537 static int adav80x_set_sysclk(struct snd_soc_codec *codec,
538                               int clk_id, int source,
539                               unsigned int freq, int dir)
540 {
541         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
542         struct snd_soc_dapm_context *dapm = &codec->dapm;
543 
544         if (dir == SND_SOC_CLOCK_IN) {
545                 switch (clk_id) {
546                 case ADAV80X_CLK_XIN:
547                 case ADAV80X_CLK_XTAL:
548                 case ADAV80X_CLK_MCLKI:
549                 case ADAV80X_CLK_PLL1:
550                 case ADAV80X_CLK_PLL2:
551                         break;
552                 default:
553                         return -EINVAL;
554                 }
555 
556                 adav80x->sysclk = freq;
557 
558                 if (adav80x->clk_src != clk_id) {
559                         unsigned int iclk_ctrl1, iclk_ctrl2;
560 
561                         adav80x->clk_src = clk_id;
562                         if (clk_id == ADAV80X_CLK_XTAL)
563                                 clk_id = ADAV80X_CLK_XIN;
564 
565                         iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) |
566                                         ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) |
567                                         ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id);
568                         iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id);
569 
570                         regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL1,
571                                 iclk_ctrl1);
572                         regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2,
573                                 iclk_ctrl2);
574 
575                         snd_soc_dapm_sync(dapm);
576                 }
577         } else {
578                 unsigned int mask;
579 
580                 switch (clk_id) {
581                 case ADAV80X_CLK_SYSCLK1:
582                 case ADAV80X_CLK_SYSCLK2:
583                 case ADAV80X_CLK_SYSCLK3:
584                         break;
585                 default:
586                         return -EINVAL;
587                 }
588 
589                 clk_id -= ADAV80X_CLK_SYSCLK1;
590                 mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id);
591 
592                 if (freq == 0) {
593                         regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE,
594                                 mask, mask);
595                         adav80x->sysclk_pd[clk_id] = true;
596                 } else {
597                         regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE,
598                                 mask, 0);
599                         adav80x->sysclk_pd[clk_id] = false;
600                 }
601 
602                 snd_soc_dapm_mutex_lock(dapm);
603 
604                 if (adav80x->sysclk_pd[0])
605                         snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1");
606                 else
607                         snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1");
608 
609                 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
610                         snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2");
611                 else
612                         snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2");
613 
614                 snd_soc_dapm_sync_unlocked(dapm);
615 
616                 snd_soc_dapm_mutex_unlock(dapm);
617         }
618 
619         return 0;
620 }
621 
622 static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
623                 int source, unsigned int freq_in, unsigned int freq_out)
624 {
625         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
626         unsigned int pll_ctrl1 = 0;
627         unsigned int pll_ctrl2 = 0;
628         unsigned int pll_src;
629 
630         switch (source) {
631         case ADAV80X_PLL_SRC_XTAL:
632         case ADAV80X_PLL_SRC_XIN:
633         case ADAV80X_PLL_SRC_MCLKI:
634                 break;
635         default:
636                 return -EINVAL;
637         }
638 
639         if (!freq_out)
640                 return 0;
641 
642         switch (freq_in) {
643         case 27000000:
644                 break;
645         case 54000000:
646                 if (source == ADAV80X_PLL_SRC_XIN) {
647                         pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV;
648                         break;
649                 }
650         default:
651                 return -EINVAL;
652         }
653 
654         if (freq_out > 12288000) {
655                 pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id);
656                 freq_out /= 2;
657         }
658 
659         /* freq_out = sample_rate * 256 */
660         switch (freq_out) {
661         case 8192000:
662                 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id);
663                 break;
664         case 11289600:
665                 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id);
666                 break;
667         case 12288000:
668                 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id);
669                 break;
670         default:
671                 return -EINVAL;
672         }
673 
674         regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL1,
675                         ADAV80X_PLL_CTRL1_PLLDIV, pll_ctrl1);
676         regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL2,
677                         ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2);
678 
679         if (source != adav80x->pll_src) {
680                 if (source == ADAV80X_PLL_SRC_MCLKI)
681                         pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id);
682                 else
683                         pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id);
684 
685                 regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CLK_SRC,
686                                 ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src);
687 
688                 adav80x->pll_src = source;
689 
690                 snd_soc_dapm_sync(&codec->dapm);
691         }
692 
693         return 0;
694 }
695 
696 static int adav80x_set_bias_level(struct snd_soc_codec *codec,
697                 enum snd_soc_bias_level level)
698 {
699         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
700         unsigned int mask = ADAV80X_DAC_CTRL1_PD;
701 
702         switch (level) {
703         case SND_SOC_BIAS_ON:
704                 break;
705         case SND_SOC_BIAS_PREPARE:
706                 break;
707         case SND_SOC_BIAS_STANDBY:
708                 regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask,
709                         0x00);
710                 break;
711         case SND_SOC_BIAS_OFF:
712                 regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask,
713                         mask);
714                 break;
715         }
716 
717         codec->dapm.bias_level = level;
718         return 0;
719 }
720 
721 /* Enforce the same sample rate on all audio interfaces */
722 static int adav80x_dai_startup(struct snd_pcm_substream *substream,
723         struct snd_soc_dai *dai)
724 {
725         struct snd_soc_codec *codec = dai->codec;
726         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
727 
728         if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
729                 return 0;
730 
731         return snd_pcm_hw_constraint_minmax(substream->runtime,
732                         SNDRV_PCM_HW_PARAM_RATE, adav80x->rate, adav80x->rate);
733 }
734 
735 static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
736                 struct snd_soc_dai *dai)
737 {
738         struct snd_soc_codec *codec = dai->codec;
739         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
740 
741         if (!snd_soc_codec_is_active(codec))
742                 adav80x->rate = 0;
743 }
744 
745 static const struct snd_soc_dai_ops adav80x_dai_ops = {
746         .set_fmt = adav80x_set_dai_fmt,
747         .hw_params = adav80x_hw_params,
748         .startup = adav80x_dai_startup,
749         .shutdown = adav80x_dai_shutdown,
750 };
751 
752 #define ADAV80X_PLAYBACK_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
753         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | \
754         SNDRV_PCM_RATE_96000)
755 
756 #define ADAV80X_CAPTURE_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
757 
758 #define ADAV80X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
759         SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
760 
761 static struct snd_soc_dai_driver adav80x_dais[] = {
762         {
763                 .name = "adav80x-hifi",
764                 .id = 0,
765                 .playback = {
766                         .stream_name = "HiFi Playback",
767                         .channels_min = 2,
768                         .channels_max = 2,
769                         .rates = ADAV80X_PLAYBACK_RATES,
770                         .formats = ADAV80X_FORMATS,
771         },
772                 .capture = {
773                         .stream_name = "HiFi Capture",
774                         .channels_min = 2,
775                         .channels_max = 2,
776                         .rates = ADAV80X_CAPTURE_RATES,
777                         .formats = ADAV80X_FORMATS,
778                 },
779                 .ops = &adav80x_dai_ops,
780         },
781         {
782                 .name = "adav80x-aux",
783                 .id = 1,
784                 .playback = {
785                         .stream_name = "Aux Playback",
786                         .channels_min = 2,
787                         .channels_max = 2,
788                         .rates = ADAV80X_PLAYBACK_RATES,
789                         .formats = ADAV80X_FORMATS,
790                 },
791                 .capture = {
792                         .stream_name = "Aux Capture",
793                         .channels_min = 2,
794                         .channels_max = 2,
795                         .rates = ADAV80X_CAPTURE_RATES,
796                         .formats = ADAV80X_FORMATS,
797                 },
798                 .ops = &adav80x_dai_ops,
799         },
800 };
801 
802 static int adav80x_probe(struct snd_soc_codec *codec)
803 {
804         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
805 
806         /* Force PLLs on for SYSCLK output */
807         snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
808         snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
809 
810         /* Power down S/PDIF receiver, since it is currently not supported */
811         regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);
812         /* Disable DAC zero flag */
813         regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6);
814 
815         return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
816 }
817 
818 static int adav80x_suspend(struct snd_soc_codec *codec)
819 {
820         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
821         int ret;
822 
823         ret = adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
824         regcache_cache_only(adav80x->regmap, true);
825 
826         return ret;
827 }
828 
829 static int adav80x_resume(struct snd_soc_codec *codec)
830 {
831         struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
832 
833         regcache_cache_only(adav80x->regmap, false);
834         adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
835         regcache_sync(adav80x->regmap);
836 
837         return 0;
838 }
839 
840 static int adav80x_remove(struct snd_soc_codec *codec)
841 {
842         return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
843 }
844 
845 static struct snd_soc_codec_driver adav80x_codec_driver = {
846         .probe = adav80x_probe,
847         .remove = adav80x_remove,
848         .suspend = adav80x_suspend,
849         .resume = adav80x_resume,
850         .set_bias_level = adav80x_set_bias_level,
851 
852         .set_pll = adav80x_set_pll,
853         .set_sysclk = adav80x_set_sysclk,
854 
855         .controls = adav80x_controls,
856         .num_controls = ARRAY_SIZE(adav80x_controls),
857         .dapm_widgets = adav80x_dapm_widgets,
858         .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),
859         .dapm_routes = adav80x_dapm_routes,
860         .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
861 };
862 
863 int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
864 {
865         struct adav80x *adav80x;
866 
867         if (IS_ERR(regmap))
868                 return PTR_ERR(regmap);
869 
870         adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL);
871         if (!adav80x)
872                 return -ENOMEM;
873 
874         dev_set_drvdata(dev, adav80x);
875         adav80x->regmap = regmap;
876 
877         return snd_soc_register_codec(dev, &adav80x_codec_driver,
878                 adav80x_dais, ARRAY_SIZE(adav80x_dais));
879 }
880 EXPORT_SYMBOL_GPL(adav80x_bus_probe);
881 
882 const struct regmap_config adav80x_regmap_config = {
883         .val_bits = 8,
884         .pad_bits = 1,
885         .reg_bits = 7,
886         .read_flag_mask = 0x01,
887 
888         .max_register = ADAV80X_PLL_OUTE,
889 
890         .cache_type = REGCACHE_RBTREE,
891         .reg_defaults = adav80x_reg_defaults,
892         .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
893 };
894 EXPORT_SYMBOL_GPL(adav80x_regmap_config);
895 
896 MODULE_DESCRIPTION("ASoC ADAV80x driver");
897 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
898 MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");
899 MODULE_LICENSE("GPL");
900 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp