aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/da7210.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/da7210.c')
-rw-r--r--sound/soc/codecs/da7210.c157
1 files changed, 134 insertions, 23 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 366daf1d044e..75af2d6e0e78 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -56,8 +56,14 @@
56#define DA7210_DAI_SRC_SEL 0x25 56#define DA7210_DAI_SRC_SEL 0x25
57#define DA7210_DAI_CFG1 0x26 57#define DA7210_DAI_CFG1 0x26
58#define DA7210_DAI_CFG3 0x28 58#define DA7210_DAI_CFG3 0x28
59#define DA7210_PLL_DIV1 0x29
60#define DA7210_PLL_DIV2 0x2A
59#define DA7210_PLL_DIV3 0x2B 61#define DA7210_PLL_DIV3 0x2B
60#define DA7210_PLL 0x2C 62#define DA7210_PLL 0x2C
63#define DA7210_A_HID_UNLOCK 0x8A
64#define DA7210_A_TEST_UNLOCK 0x8B
65#define DA7210_A_PLL1 0x90
66#define DA7210_A_CP_MODE 0xA7
61 67
62/* STARTUP1 bit fields */ 68/* STARTUP1 bit fields */
63#define DA7210_SC_MST_EN (1 << 0) 69#define DA7210_SC_MST_EN (1 << 0)
@@ -75,15 +81,14 @@
75/* INMIX_R bit fields */ 81/* INMIX_R bit fields */
76#define DA7210_IN_R_EN (1 << 7) 82#define DA7210_IN_R_EN (1 << 7)
77 83
78/* ADC_HPF bit fields */
79#define DA7210_ADC_VOICE_EN (1 << 7)
80
81/* ADC bit fields */ 84/* ADC bit fields */
82#define DA7210_ADC_L_EN (1 << 3) 85#define DA7210_ADC_L_EN (1 << 3)
83#define DA7210_ADC_R_EN (1 << 7) 86#define DA7210_ADC_R_EN (1 << 7)
84 87
85/* DAC_HPF fields */ 88/* DAC/ADC HPF fields */
86#define DA7210_DAC_VOICE_EN (1 << 7) 89#define DA7210_VOICE_F0_MASK (0x7 << 4)
90#define DA7210_VOICE_F0_25 (1 << 4)
91#define DA7210_VOICE_EN (1 << 7)
87 92
88/* DAC_SEL bit fields */ 93/* DAC_SEL bit fields */
89#define DA7210_DAC_L_SRC_DAI_L (4 << 0) 94#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
@@ -124,7 +129,19 @@
124#define DA7210_PLL_BYP (1 << 6) 129#define DA7210_PLL_BYP (1 << 6)
125 130
126/* PLL bit fields */ 131/* PLL bit fields */
127#define DA7210_PLL_FS_48000 (11 << 0) 132#define DA7210_PLL_FS_MASK (0xF << 0)
133#define DA7210_PLL_FS_8000 (0x1 << 0)
134#define DA7210_PLL_FS_11025 (0x2 << 0)
135#define DA7210_PLL_FS_12000 (0x3 << 0)
136#define DA7210_PLL_FS_16000 (0x5 << 0)
137#define DA7210_PLL_FS_22050 (0x6 << 0)
138#define DA7210_PLL_FS_24000 (0x7 << 0)
139#define DA7210_PLL_FS_32000 (0x9 << 0)
140#define DA7210_PLL_FS_44100 (0xA << 0)
141#define DA7210_PLL_FS_48000 (0xB << 0)
142#define DA7210_PLL_FS_88200 (0xE << 0)
143#define DA7210_PLL_FS_96000 (0xF << 0)
144#define DA7210_PLL_EN (0x1 << 7)
128 145
129#define DA7210_VERSION "0.0.1" 146#define DA7210_VERSION "0.0.1"
130 147
@@ -165,7 +182,7 @@ static const u8 da7210_reg[] = {
165static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) 182static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
166{ 183{
167 u8 *cache = codec->reg_cache; 184 u8 *cache = codec->reg_cache;
168 BUG_ON(reg > ARRAY_SIZE(da7210_reg)); 185 BUG_ON(reg >= ARRAY_SIZE(da7210_reg));
169 return cache[reg]; 186 return cache[reg];
170} 187}
171 188
@@ -242,7 +259,8 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
242 struct snd_soc_device *socdev = rtd->socdev; 259 struct snd_soc_device *socdev = rtd->socdev;
243 struct snd_soc_codec *codec = socdev->card->codec; 260 struct snd_soc_codec *codec = socdev->card->codec;
244 u32 dai_cfg1; 261 u32 dai_cfg1;
245 u32 reg, mask; 262 u32 hpf_reg, hpf_mask, hpf_value;
263 u32 fs, bypass;
246 264
247 /* set DAI source to Left and Right ADC */ 265 /* set DAI source to Left and Right ADC */
248 da7210_write(codec, DA7210_DAI_SRC_SEL, 266 da7210_write(codec, DA7210_DAI_SRC_SEL,
@@ -266,25 +284,84 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
266 284
267 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 285 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
268 286
269 /* FIXME 287 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
270 * 288 DA7210_DAC_HPF : DA7210_ADC_HPF;
271 * It support 48K only now 289
272 */
273 switch (params_rate(params)) { 290 switch (params_rate(params)) {
291 case 8000:
292 fs = DA7210_PLL_FS_8000;
293 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
294 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
295 bypass = DA7210_PLL_BYP;
296 break;
297 case 11025:
298 fs = DA7210_PLL_FS_11025;
299 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
300 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
301 bypass = 0;
302 break;
303 case 12000:
304 fs = DA7210_PLL_FS_12000;
305 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
306 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
307 bypass = DA7210_PLL_BYP;
308 break;
309 case 16000:
310 fs = DA7210_PLL_FS_16000;
311 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
312 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
313 bypass = DA7210_PLL_BYP;
314 break;
315 case 22050:
316 fs = DA7210_PLL_FS_22050;
317 hpf_mask = DA7210_VOICE_EN;
318 hpf_value = 0;
319 bypass = 0;
320 break;
321 case 32000:
322 fs = DA7210_PLL_FS_32000;
323 hpf_mask = DA7210_VOICE_EN;
324 hpf_value = 0;
325 bypass = DA7210_PLL_BYP;
326 break;
327 case 44100:
328 fs = DA7210_PLL_FS_44100;
329 hpf_mask = DA7210_VOICE_EN;
330 hpf_value = 0;
331 bypass = 0;
332 break;
274 case 48000: 333 case 48000:
275 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 334 fs = DA7210_PLL_FS_48000;
276 reg = DA7210_DAC_HPF; 335 hpf_mask = DA7210_VOICE_EN;
277 mask = DA7210_DAC_VOICE_EN; 336 hpf_value = 0;
278 } else { 337 bypass = DA7210_PLL_BYP;
279 reg = DA7210_ADC_HPF; 338 break;
280 mask = DA7210_ADC_VOICE_EN; 339 case 88200:
281 } 340 fs = DA7210_PLL_FS_88200;
341 hpf_mask = DA7210_VOICE_EN;
342 hpf_value = 0;
343 bypass = 0;
344 break;
345 case 96000:
346 fs = DA7210_PLL_FS_96000;
347 hpf_mask = DA7210_VOICE_EN;
348 hpf_value = 0;
349 bypass = DA7210_PLL_BYP;
282 break; 350 break;
283 default: 351 default:
284 return -EINVAL; 352 return -EINVAL;
285 } 353 }
286 354
287 snd_soc_update_bits(codec, reg, mask, 0); 355 /* Disable active mode */
356 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
357
358 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
359 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
360 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
361
362 /* Enable active mode */
363 snd_soc_update_bits(codec, DA7210_STARTUP1,
364 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
288 365
289 return 0; 366 return 0;
290} 367}
@@ -362,6 +439,7 @@ struct snd_soc_dai da7210_dai = {
362 .formats = DA7210_FORMATS, 439 .formats = DA7210_FORMATS,
363 }, 440 },
364 .ops = &da7210_dai_ops, 441 .ops = &da7210_dai_ops,
442 .symmetric_rates = 1,
365}; 443};
366EXPORT_SYMBOL_GPL(da7210_dai); 444EXPORT_SYMBOL_GPL(da7210_dai);
367 445
@@ -383,7 +461,7 @@ static int da7210_init(struct da7210_priv *da7210)
383 INIT_LIST_HEAD(&codec->dapm_widgets); 461 INIT_LIST_HEAD(&codec->dapm_widgets);
384 INIT_LIST_HEAD(&codec->dapm_paths); 462 INIT_LIST_HEAD(&codec->dapm_paths);
385 463
386 codec->private_data = da7210; 464 snd_soc_codec_set_drvdata(codec, da7210);
387 codec->name = "DA7210"; 465 codec->name = "DA7210";
388 codec->owner = THIS_MODULE; 466 codec->owner = THIS_MODULE;
389 codec->read = da7210_read; 467 codec->read = da7210_read;
@@ -416,9 +494,23 @@ static int da7210_init(struct da7210_priv *da7210)
416 /* FIXME 494 /* FIXME
417 * 495 *
418 * This driver use fixed value here 496 * This driver use fixed value here
497 * And below settings expects MCLK = 12.288MHz
498 *
499 * When you select different MCLK, please check...
500 * DA7210_PLL_DIV1 val
501 * DA7210_PLL_DIV2 val
502 * DA7210_PLL_DIV3 val
503 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
419 */ 504 */
420 505
421 /* 506 /*
507 * make sure that DA7210 use bypass mode before start up
508 */
509 da7210_write(codec, DA7210_STARTUP1, 0);
510 da7210_write(codec, DA7210_PLL_DIV3,
511 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
512
513 /*
422 * ADC settings 514 * ADC settings
423 */ 515 */
424 516
@@ -454,9 +546,28 @@ static int da7210_init(struct da7210_priv *da7210)
454 /* Diable PLL and bypass it */ 546 /* Diable PLL and bypass it */
455 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 547 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
456 548
457 /* Bypass PLL and set MCLK freq rang to 10-20MHz */ 549 /*
458 da7210_write(codec, DA7210_PLL_DIV3, 550 * If 48kHz sound came, it use bypass mode,
551 * and when it is 44.1kHz, it use PLL.
552 *
553 * This time, this driver sets PLL always ON
554 * and controls bypass/PLL mode by switching
555 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
556 * see da7210_hw_params
557 */
558 da7210_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
559 da7210_write(codec, DA7210_PLL_DIV2, 0x99);
560 da7210_write(codec, DA7210_PLL_DIV3, 0x0A |
459 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 561 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
562 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
563
564 /* As suggested by Dialog */
565 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
566 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
567 da7210_write(codec, DA7210_A_PLL1, 0x01);
568 da7210_write(codec, DA7210_A_CP_MODE, 0x7C);
569 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
570 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
460 571
461 /* Activate all enabled subsystem */ 572 /* Activate all enabled subsystem */
462 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 573 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);