aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic23.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic23.c')
-rw-r--r--sound/soc/codecs/tlv320aic23.c181
1 files changed, 55 insertions, 126 deletions
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 33bb52f3f68..ab27dbcd126 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -47,63 +47,6 @@ static const u16 tlv320aic23_reg[] = {
47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ 47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
48}; 48};
49 49
50/*
51 * read tlv320aic23 register cache
52 */
53static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
54 *codec, unsigned int reg)
55{
56 u16 *cache = codec->reg_cache;
57 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
58 return -1;
59 return cache[reg];
60}
61
62/*
63 * write tlv320aic23 register cache
64 */
65static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
66 u8 reg, u16 value)
67{
68 u16 *cache = codec->reg_cache;
69 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
70 return;
71 cache[reg] = value;
72}
73
74/*
75 * write to the tlv320aic23 register space
76 */
77static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80
81 u8 data[2];
82
83 /* TLV320AIC23 has 7 bit address and 9 bits of data
84 * so we need to switch one data bit into reg and rest
85 * of data into val
86 */
87
88 if (reg > 9 && reg != 15) {
89 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90 return -1;
91 }
92
93 data[0] = (reg << 1) | (value >> 8 & 0x01);
94 data[1] = value & 0xff;
95
96 tlv320aic23_write_reg_cache(codec, reg, value);
97
98 if (codec->hw_write(codec->control_data, data, 2) == 2)
99 return 0;
100
101 printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
102 value, reg);
103
104 return -EIO;
105}
106
107static const char *rec_src_text[] = { "Line", "Mic" }; 50static const char *rec_src_text[] = { "Line", "Mic" };
108static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 51static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
109 52
@@ -139,8 +82,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
139 */ 82 */
140 val = (val >= 4) ? 4 : (3 - val); 83 val = (val >= 4) ? 4 : (3 - val);
141 84
142 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0); 85 reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
143 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6)); 86 snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
144 87
145 return 0; 88 return 0;
146} 89}
@@ -151,7 +94,7 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 94 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152 u16 val; 95 u16 val;
153 96
154 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0); 97 val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
155 val = val >> 6; 98 val = val >> 6;
156 val = (val >= 4) ? 4 : (3 - val); 99 val = (val >= 4) ? 4 : (3 - val);
157 ucontrol->value.integer.value[0] = val; 100 ucontrol->value.integer.value[0] = val;
@@ -159,15 +102,6 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
159 102
160} 103}
161 104
162#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
164 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
165 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
166 .tlv.p = (tlv_array), \
167 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
168 .put = snd_soc_tlv320aic23_put_volsw, \
169 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
170
171static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { 105static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
172 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, 106 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
173 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv), 107 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
@@ -178,8 +112,9 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
178 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), 112 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
179 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), 113 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
180 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), 114 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
181 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG, 115 SOC_SINGLE_EXT_TLV("Sidetone Volume", TLV320AIC23_ANLG, 6, 4, 0,
182 6, 4, 0, sidetone_vol_tlv), 116 snd_soc_tlv320aic23_get_volsw,
117 snd_soc_tlv320aic23_put_volsw, sidetone_vol_tlv),
183 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), 118 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
184}; 119};
185 120
@@ -240,7 +175,6 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
240/* AIC23 driver data */ 175/* AIC23 driver data */
241struct aic23 { 176struct aic23 {
242 enum snd_soc_control_type control_type; 177 enum snd_soc_control_type control_type;
243 void *control_data;
244 int mclk; 178 int mclk;
245 int requested_adc; 179 int requested_adc;
246 int requested_dac; 180 int requested_dac;
@@ -352,7 +286,7 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac)
352static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk, 286static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
353 u32 *sample_rate_adc, u32 *sample_rate_dac) 287 u32 *sample_rate_adc, u32 *sample_rate_dac)
354{ 288{
355 int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE); 289 int src = snd_soc_read(codec, TLV320AIC23_SRATE);
356 int sr = (src >> 2) & 0x0f; 290 int sr = (src >> 2) & 0x0f;
357 int val = (mclk / bosr_usb_divisor_table[src & 3]); 291 int val = (mclk / bosr_usb_divisor_table[src & 3]);
358 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT; 292 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
@@ -376,7 +310,7 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
376 __func__, sample_rate_adc, sample_rate_dac); 310 __func__, sample_rate_adc, sample_rate_dac);
377 return -EINVAL; 311 return -EINVAL;
378 } 312 }
379 tlv320aic23_write(codec, TLV320AIC23_SRATE, data); 313 snd_soc_write(codec, TLV320AIC23_SRATE, data);
380#ifdef DEBUG 314#ifdef DEBUG
381 { 315 {
382 u32 adc, dac; 316 u32 adc, dac;
@@ -415,9 +349,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
415 if (ret < 0) 349 if (ret < 0)
416 return ret; 350 return ret;
417 351
418 iface_reg = 352 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
419 tlv320aic23_read_reg_cache(codec, 353
420 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
421 switch (params_format(params)) { 354 switch (params_format(params)) {
422 case SNDRV_PCM_FORMAT_S16_LE: 355 case SNDRV_PCM_FORMAT_S16_LE:
423 break; 356 break;
@@ -431,7 +364,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
431 iface_reg |= (0x03 << 2); 364 iface_reg |= (0x03 << 2);
432 break; 365 break;
433 } 366 }
434 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 367 snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
435 368
436 return 0; 369 return 0;
437} 370}
@@ -443,7 +376,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
443 struct snd_soc_codec *codec = rtd->codec; 376 struct snd_soc_codec *codec = rtd->codec;
444 377
445 /* set active */ 378 /* set active */
446 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 379 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
447 380
448 return 0; 381 return 0;
449} 382}
@@ -458,7 +391,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
458 /* deactivate */ 391 /* deactivate */
459 if (!codec->active) { 392 if (!codec->active) {
460 udelay(50); 393 udelay(50);
461 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 394 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
462 } 395 }
463 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 396 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
464 aic23->requested_dac = 0; 397 aic23->requested_dac = 0;
@@ -471,14 +404,14 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
471 struct snd_soc_codec *codec = dai->codec; 404 struct snd_soc_codec *codec = dai->codec;
472 u16 reg; 405 u16 reg;
473 406
474 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT); 407 reg = snd_soc_read(codec, TLV320AIC23_DIGT);
475 if (mute) 408 if (mute)
476 reg |= TLV320AIC23_DACM_MUTE; 409 reg |= TLV320AIC23_DACM_MUTE;
477 410
478 else 411 else
479 reg &= ~TLV320AIC23_DACM_MUTE; 412 reg &= ~TLV320AIC23_DACM_MUTE;
480 413
481 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg); 414 snd_soc_write(codec, TLV320AIC23_DIGT, reg);
482 415
483 return 0; 416 return 0;
484} 417}
@@ -489,8 +422,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
489 struct snd_soc_codec *codec = codec_dai->codec; 422 struct snd_soc_codec *codec = codec_dai->codec;
490 u16 iface_reg; 423 u16 iface_reg;
491 424
492 iface_reg = 425 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
493 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
494 426
495 /* set master/slave audio interface */ 427 /* set master/slave audio interface */
496 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 428 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -524,7 +456,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
524 456
525 } 457 }
526 458
527 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 459 snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
528 460
529 return 0; 461 return 0;
530} 462}
@@ -540,26 +472,26 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
540static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, 472static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
541 enum snd_soc_bias_level level) 473 enum snd_soc_bias_level level)
542{ 474{
543 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f; 475 u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f;
544 476
545 switch (level) { 477 switch (level) {
546 case SND_SOC_BIAS_ON: 478 case SND_SOC_BIAS_ON:
547 /* vref/mid, osc on, dac unmute */ 479 /* vref/mid, osc on, dac unmute */
548 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \ 480 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
549 TLV320AIC23_DAC_OFF); 481 TLV320AIC23_DAC_OFF);
550 tlv320aic23_write(codec, TLV320AIC23_PWR, reg); 482 snd_soc_write(codec, TLV320AIC23_PWR, reg);
551 break; 483 break;
552 case SND_SOC_BIAS_PREPARE: 484 case SND_SOC_BIAS_PREPARE:
553 break; 485 break;
554 case SND_SOC_BIAS_STANDBY: 486 case SND_SOC_BIAS_STANDBY:
555 /* everything off except vref/vmid, */ 487 /* everything off except vref/vmid, */
556 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \ 488 snd_soc_write(codec, TLV320AIC23_PWR,
557 TLV320AIC23_CLK_OFF); 489 reg | TLV320AIC23_CLK_OFF);
558 break; 490 break;
559 case SND_SOC_BIAS_OFF: 491 case SND_SOC_BIAS_OFF:
560 /* everything off, dac mute, inactive */ 492 /* everything off, dac mute, inactive */
561 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 493 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
562 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); 494 snd_soc_write(codec, TLV320AIC23_PWR, 0xffff);
563 break; 495 break;
564 } 496 }
565 codec->dapm.bias_level = level; 497 codec->dapm.bias_level = level;
@@ -606,13 +538,7 @@ static int tlv320aic23_suspend(struct snd_soc_codec *codec,
606 538
607static int tlv320aic23_resume(struct snd_soc_codec *codec) 539static int tlv320aic23_resume(struct snd_soc_codec *codec)
608{ 540{
609 u16 reg; 541 snd_soc_cache_sync(codec);
610
611 /* Sync reg_cache with the hardware */
612 for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) {
613 u16 val = tlv320aic23_read_reg_cache(codec, reg);
614 tlv320aic23_write(codec, reg, val);
615 }
616 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 542 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
617 543
618 return 0; 544 return 0;
@@ -621,46 +547,52 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
621static int tlv320aic23_probe(struct snd_soc_codec *codec) 547static int tlv320aic23_probe(struct snd_soc_codec *codec)
622{ 548{
623 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 549 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
624 int reg; 550 int ret;
625 551
626 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); 552 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
627 codec->control_data = aic23->control_data; 553
628 codec->hw_write = (hw_write_t)i2c_master_send; 554 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
629 codec->hw_read = NULL; 555 if (ret < 0) {
556 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
557 return ret;
558 }
630 559
631 /* Reset codec */ 560 /* Reset codec */
632 tlv320aic23_write(codec, TLV320AIC23_RESET, 0); 561 snd_soc_write(codec, TLV320AIC23_RESET, 0);
562
563 /* Write the register default value to cache for reserved registers,
564 * so the write to the these registers are suppressed by the cache
565 * restore code when it skips writes of default registers.
566 */
567 snd_soc_cache_write(codec, 0x0A, 0);
568 snd_soc_cache_write(codec, 0x0B, 0);
569 snd_soc_cache_write(codec, 0x0C, 0);
570 snd_soc_cache_write(codec, 0x0D, 0);
571 snd_soc_cache_write(codec, 0x0E, 0);
633 572
634 /* power on device */ 573 /* power on device */
635 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 574 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
636 575
637 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K); 576 snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
638 577
639 /* Unmute input */ 578 /* Unmute input */
640 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL); 579 snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
641 tlv320aic23_write(codec, TLV320AIC23_LINVOL, 580 TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
642 (reg & (~TLV320AIC23_LIM_MUTED)) |
643 (TLV320AIC23_LRS_ENABLED));
644 581
645 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL); 582 snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
646 tlv320aic23_write(codec, TLV320AIC23_RINVOL, 583 TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
647 (reg & (~TLV320AIC23_LIM_MUTED)) |
648 TLV320AIC23_LRS_ENABLED);
649 584
650 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG); 585 snd_soc_update_bits(codec, TLV320AIC23_ANLG,
651 tlv320aic23_write(codec, TLV320AIC23_ANLG, 586 TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
652 (reg) & (~TLV320AIC23_BYPASS_ON) & 587 0);
653 (~TLV320AIC23_MICM_MUTED));
654 588
655 /* Default output volume */ 589 /* Default output volume */
656 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL, 590 snd_soc_write(codec, TLV320AIC23_LCHNVOL,
657 TLV320AIC23_DEFAULT_OUT_VOL & 591 TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
658 TLV320AIC23_OUT_VOL_MASK); 592 snd_soc_write(codec, TLV320AIC23_RCHNVOL,
659 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL, 593 TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
660 TLV320AIC23_DEFAULT_OUT_VOL &
661 TLV320AIC23_OUT_VOL_MASK);
662 594
663 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); 595 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
664 596
665 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 597 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
666 ARRAY_SIZE(tlv320aic23_snd_controls)); 598 ARRAY_SIZE(tlv320aic23_snd_controls));
@@ -682,8 +614,6 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
682 .remove = tlv320aic23_remove, 614 .remove = tlv320aic23_remove,
683 .suspend = tlv320aic23_suspend, 615 .suspend = tlv320aic23_suspend,
684 .resume = tlv320aic23_resume, 616 .resume = tlv320aic23_resume,
685 .read = tlv320aic23_read_reg_cache,
686 .write = tlv320aic23_write,
687 .set_bias_level = tlv320aic23_set_bias_level, 617 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets, 618 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), 619 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
@@ -710,7 +640,6 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
710 return -ENOMEM; 640 return -ENOMEM;
711 641
712 i2c_set_clientdata(i2c, aic23); 642 i2c_set_clientdata(i2c, aic23);
713 aic23->control_data = i2c;
714 aic23->control_type = SND_SOC_I2C; 643 aic23->control_type = SND_SOC_I2C;
715 644
716 ret = snd_soc_register_codec(&i2c->dev, 645 ret = snd_soc_register_codec(&i2c->dev,