aboutsummaryrefslogtreecommitdiffstats
path: root/sound/i2c/other/ak4xxx-adda.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/i2c/other/ak4xxx-adda.c')
-rw-r--r--sound/i2c/other/ak4xxx-adda.c110
1 files changed, 96 insertions, 14 deletions
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 5da49e2eb350..8805110017a7 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -140,7 +140,7 @@ EXPORT_SYMBOL(snd_akm4xxx_reset);
140 * Used for AK4524 input/ouput attenuation, AK4528, and 140 * Used for AK4524 input/ouput attenuation, AK4528, and
141 * AK5365 input attenuation 141 * AK5365 input attenuation
142 */ 142 */
143static unsigned char vol_cvt_datt[128] = { 143static const unsigned char vol_cvt_datt[128] = {
144 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 144 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04,
145 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, 145 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06,
146 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a, 146 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a,
@@ -162,17 +162,17 @@ static unsigned char vol_cvt_datt[128] = {
162/* 162/*
163 * dB tables 163 * dB tables
164 */ 164 */
165static DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1); 165static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1);
166static DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1); 166static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1);
167static DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1); 167static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1);
168static DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0); 168static const DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0);
169 169
170/* 170/*
171 * initialize all the ak4xxx chips 171 * initialize all the ak4xxx chips
172 */ 172 */
173void snd_akm4xxx_init(struct snd_akm4xxx *ak) 173void snd_akm4xxx_init(struct snd_akm4xxx *ak)
174{ 174{
175 static unsigned char inits_ak4524[] = { 175 static const unsigned char inits_ak4524[] = {
176 0x00, 0x07, /* 0: all power up */ 176 0x00, 0x07, /* 0: all power up */
177 0x01, 0x00, /* 1: ADC/DAC reset */ 177 0x01, 0x00, /* 1: ADC/DAC reset */
178 0x02, 0x60, /* 2: 24bit I2S */ 178 0x02, 0x60, /* 2: 24bit I2S */
@@ -184,7 +184,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
184 0x07, 0x00, /* 7: DAC right muted */ 184 0x07, 0x00, /* 7: DAC right muted */
185 0xff, 0xff 185 0xff, 0xff
186 }; 186 };
187 static unsigned char inits_ak4528[] = { 187 static const unsigned char inits_ak4528[] = {
188 0x00, 0x07, /* 0: all power up */ 188 0x00, 0x07, /* 0: all power up */
189 0x01, 0x00, /* 1: ADC/DAC reset */ 189 0x01, 0x00, /* 1: ADC/DAC reset */
190 0x02, 0x60, /* 2: 24bit I2S */ 190 0x02, 0x60, /* 2: 24bit I2S */
@@ -194,7 +194,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
194 0x05, 0x00, /* 5: ADC right muted */ 194 0x05, 0x00, /* 5: ADC right muted */
195 0xff, 0xff 195 0xff, 0xff
196 }; 196 };
197 static unsigned char inits_ak4529[] = { 197 static const unsigned char inits_ak4529[] = {
198 0x09, 0x01, /* 9: ATS=0, RSTN=1 */ 198 0x09, 0x01, /* 9: ATS=0, RSTN=1 */
199 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */ 199 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
200 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */ 200 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
@@ -210,7 +210,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
210 0x08, 0x55, /* 8: deemphasis all off */ 210 0x08, 0x55, /* 8: deemphasis all off */
211 0xff, 0xff 211 0xff, 0xff
212 }; 212 };
213 static unsigned char inits_ak4355[] = { 213 static const unsigned char inits_ak4355[] = {
214 0x01, 0x02, /* 1: reset and soft-mute */ 214 0x01, 0x02, /* 1: reset and soft-mute */
215 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, 215 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
216 * disable DZF, sharp roll-off, RSTN#=0 */ 216 * disable DZF, sharp roll-off, RSTN#=0 */
@@ -227,7 +227,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
227 0x01, 0x01, /* 1: un-reset, unmute */ 227 0x01, 0x01, /* 1: un-reset, unmute */
228 0xff, 0xff 228 0xff, 0xff
229 }; 229 };
230 static unsigned char inits_ak4358[] = { 230 static const unsigned char inits_ak4358[] = {
231 0x01, 0x02, /* 1: reset and soft-mute */ 231 0x01, 0x02, /* 1: reset and soft-mute */
232 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, 232 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
233 * disable DZF, sharp roll-off, RSTN#=0 */ 233 * disable DZF, sharp roll-off, RSTN#=0 */
@@ -246,7 +246,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
246 0x01, 0x01, /* 1: un-reset, unmute */ 246 0x01, 0x01, /* 1: un-reset, unmute */
247 0xff, 0xff 247 0xff, 0xff
248 }; 248 };
249 static unsigned char inits_ak4381[] = { 249 static const unsigned char inits_ak4381[] = {
250 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ 250 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
251 0x01, 0x02, /* 1: de-emphasis off, normal speed, 251 0x01, 0x02, /* 1: de-emphasis off, normal speed,
252 * sharp roll-off, DZF off */ 252 * sharp roll-off, DZF off */
@@ -259,7 +259,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
259 }; 259 };
260 260
261 int chip, num_chips; 261 int chip, num_chips;
262 unsigned char *ptr, reg, data, *inits; 262 const unsigned char *ptr, *inits;
263 unsigned char reg, data;
263 264
264 memset(ak->images, 0, sizeof(ak->images)); 265 memset(ak->images, 0, sizeof(ak->images));
265 memset(ak->volumes, 0, sizeof(ak->volumes)); 266 memset(ak->volumes, 0, sizeof(ak->volumes));
@@ -513,6 +514,66 @@ static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
513 return change; 514 return change;
514} 515}
515 516
517#define AK5365_NUM_INPUTS 5
518
519static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_info *uinfo)
521{
522 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
523 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
524 const char **input_names;
525 int num_names, idx;
526
527 input_names = ak->adc_info[mixer_ch].input_names;
528
529 num_names = 0;
530 while (num_names < AK5365_NUM_INPUTS && input_names[num_names])
531 ++num_names;
532
533 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
534 uinfo->count = 1;
535 uinfo->value.enumerated.items = num_names;
536 idx = uinfo->value.enumerated.item;
537 if (idx >= num_names)
538 return -EINVAL;
539 strncpy(uinfo->value.enumerated.name, input_names[idx],
540 sizeof(uinfo->value.enumerated.name));
541 return 0;
542}
543
544static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
546{
547 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
548 int chip = AK_GET_CHIP(kcontrol->private_value);
549 int addr = AK_GET_ADDR(kcontrol->private_value);
550 int mask = AK_GET_MASK(kcontrol->private_value);
551 unsigned char val;
552
553 val = snd_akm4xxx_get(ak, chip, addr) & mask;
554 ucontrol->value.enumerated.item[0] = val;
555 return 0;
556}
557
558static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol,
559 struct snd_ctl_elem_value *ucontrol)
560{
561 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
562 int chip = AK_GET_CHIP(kcontrol->private_value);
563 int addr = AK_GET_ADDR(kcontrol->private_value);
564 int mask = AK_GET_MASK(kcontrol->private_value);
565 unsigned char oval, val;
566
567 oval = snd_akm4xxx_get(ak, chip, addr);
568 val = oval & ~mask;
569 val |= ucontrol->value.enumerated.item[0] & mask;
570 if (val != oval) {
571 snd_akm4xxx_write(ak, chip, addr, val);
572 return 1;
573 }
574 return 0;
575}
576
516/* 577/*
517 * build AK4xxx controls 578 * build AK4xxx controls
518 */ 579 */
@@ -647,9 +708,10 @@ static int build_adc_controls(struct snd_akm4xxx *ak)
647 708
648 if (ak->type == SND_AK5365 && (idx % 2) == 0) { 709 if (ak->type == SND_AK5365 && (idx % 2) == 0) {
649 if (! ak->adc_info || 710 if (! ak->adc_info ||
650 ! ak->adc_info[mixer_ch].switch_name) 711 ! ak->adc_info[mixer_ch].switch_name) {
651 knew.name = "Capture Switch"; 712 knew.name = "Capture Switch";
652 else 713 knew.index = mixer_ch + ak->idx_offset * 2;
714 } else
653 knew.name = ak->adc_info[mixer_ch].switch_name; 715 knew.name = ak->adc_info[mixer_ch].switch_name;
654 knew.info = ak4xxx_switch_info; 716 knew.info = ak4xxx_switch_info;
655 knew.get = ak4xxx_switch_get; 717 knew.get = ak4xxx_switch_get;
@@ -662,6 +724,26 @@ static int build_adc_controls(struct snd_akm4xxx *ak)
662 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); 724 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
663 if (err < 0) 725 if (err < 0)
664 return err; 726 return err;
727
728 memset(&knew, 0, sizeof(knew));
729 knew.name = ak->adc_info[mixer_ch].selector_name;
730 if (!knew.name) {
731 knew.name = "Capture Channel";
732 knew.index = mixer_ch + ak->idx_offset * 2;
733 }
734
735 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
736 knew.info = ak4xxx_capture_source_info;
737 knew.get = ak4xxx_capture_source_get;
738 knew.put = ak4xxx_capture_source_put;
739 knew.access = 0;
740 /* input selector control: reg. 1, bits 0-2.
741 * mis-use 'shift' to pass mixer_ch */
742 knew.private_value
743 = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07);
744 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
745 if (err < 0)
746 return err;
665 } 747 }
666 748
667 idx += num_stereo; 749 idx += num_stereo;