diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-05-20 06:00:43 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-05-20 06:00:43 -0400 |
commit | d71f4cece4bd97d05592836202fc04ff2e7817e3 (patch) | |
tree | 6c877c7a938758b1323d9c97d46b9c536e618c69 /sound/soc/codecs/da7210.c | |
parent | 19008bdacb9f7841166ebafe0aef361ee582ffbf (diff) | |
parent | ad8332c1302bcb4f80d593fd3eb477be9d7f5604 (diff) |
Merge branch 'topic/asoc' into for-linus
Conflicts:
sound/soc/codecs/ad1938.c
Diffstat (limited to 'sound/soc/codecs/da7210.c')
-rw-r--r-- | sound/soc/codecs/da7210.c | 157 |
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[] = { | |||
165 | static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) | 182 | static 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 | }; |
366 | EXPORT_SYMBOL_GPL(da7210_dai); | 444 | EXPORT_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); |