diff options
Diffstat (limited to 'sound/i2c/other/ak4xxx-adda.c')
-rw-r--r-- | sound/i2c/other/ak4xxx-adda.c | 110 |
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 | */ |
143 | static unsigned char vol_cvt_datt[128] = { | 143 | static 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 | */ |
165 | static DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1); | 165 | static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1); |
166 | static DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1); | 166 | static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1); |
167 | static DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1); | 167 | static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1); |
168 | static DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0); | 168 | static 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 | */ |
173 | void snd_akm4xxx_init(struct snd_akm4xxx *ak) | 173 | void 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 | |||
519 | static 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 | |||
544 | static 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 | |||
558 | static 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; |