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