0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/io.h>
0011 #include <linux/delay.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <sound/core.h>
0016 #include <sound/control.h>
0017 #include <sound/tlv.h>
0018 #include <sound/ak4xxx-adda.h>
0019 #include <sound/info.h>
0020
0021 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
0022 MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters");
0023 MODULE_LICENSE("GPL");
0024
0025
0026 void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg,
0027 unsigned char val)
0028 {
0029 ak->ops.lock(ak, chip);
0030 ak->ops.write(ak, chip, reg, val);
0031
0032
0033 snd_akm4xxx_set(ak, chip, reg, val);
0034 ak->ops.unlock(ak, chip);
0035 }
0036
0037 EXPORT_SYMBOL(snd_akm4xxx_write);
0038
0039
0040 static void ak4524_reset(struct snd_akm4xxx *ak, int state)
0041 {
0042 unsigned int chip;
0043 unsigned char reg;
0044
0045 for (chip = 0; chip < ak->num_dacs/2; chip++) {
0046 snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);
0047 if (state)
0048 continue;
0049
0050 for (reg = 0x04; reg < ak->total_regs; reg++)
0051 snd_akm4xxx_write(ak, chip, reg,
0052 snd_akm4xxx_get(ak, chip, reg));
0053 }
0054 }
0055
0056
0057 static void ak435X_reset(struct snd_akm4xxx *ak, int state)
0058 {
0059 unsigned char reg;
0060
0061 if (state) {
0062 snd_akm4xxx_write(ak, 0, 0x01, 0x02);
0063 return;
0064 }
0065 for (reg = 0x00; reg < ak->total_regs; reg++)
0066 if (reg != 0x01)
0067 snd_akm4xxx_write(ak, 0, reg,
0068 snd_akm4xxx_get(ak, 0, reg));
0069 snd_akm4xxx_write(ak, 0, 0x01, 0x01);
0070 }
0071
0072
0073 static void ak4381_reset(struct snd_akm4xxx *ak, int state)
0074 {
0075 unsigned int chip;
0076 unsigned char reg;
0077 for (chip = 0; chip < ak->num_dacs/2; chip++) {
0078 snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);
0079 if (state)
0080 continue;
0081 for (reg = 0x01; reg < ak->total_regs; reg++)
0082 snd_akm4xxx_write(ak, chip, reg,
0083 snd_akm4xxx_get(ak, chip, reg));
0084 }
0085 }
0086
0087
0088
0089
0090
0091
0092
0093 void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
0094 {
0095 switch (ak->type) {
0096 case SND_AK4524:
0097 case SND_AK4528:
0098 case SND_AK4620:
0099 ak4524_reset(ak, state);
0100 break;
0101 case SND_AK4529:
0102
0103 break;
0104 case SND_AK4355:
0105 ak435X_reset(ak, state);
0106 break;
0107 case SND_AK4358:
0108 ak435X_reset(ak, state);
0109 break;
0110 case SND_AK4381:
0111 ak4381_reset(ak, state);
0112 break;
0113 default:
0114 break;
0115 }
0116 }
0117
0118 EXPORT_SYMBOL(snd_akm4xxx_reset);
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 static const unsigned char vol_cvt_datt[128] = {
0129 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04,
0130 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06,
0131 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a,
0132 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f,
0133 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14,
0134 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1c,
0135 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x23,
0136 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2d,
0137 0x2e, 0x30, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0138 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3e, 0x3f, 0x40,
0139 0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4a,
0140 0x4b, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54,
0141 0x55, 0x56, 0x58, 0x59, 0x5b, 0x5c, 0x5e, 0x5f,
0142 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x69,
0143 0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x73,
0144 0x75, 0x76, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7f,
0145 };
0146
0147
0148
0149
0150 static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1);
0151 static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1);
0152 static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1);
0153 static const DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0);
0154
0155
0156
0157
0158 void snd_akm4xxx_init(struct snd_akm4xxx *ak)
0159 {
0160 static const unsigned char inits_ak4524[] = {
0161 0x00, 0x07,
0162 0x01, 0x00,
0163 0x02, 0x60,
0164 0x03, 0x19,
0165 0x01, 0x03,
0166 0x04, 0x00,
0167 0x05, 0x00,
0168 0x06, 0x00,
0169 0x07, 0x00,
0170 0xff, 0xff
0171 };
0172 static const unsigned char inits_ak4528[] = {
0173 0x00, 0x07,
0174 0x01, 0x00,
0175 0x02, 0x60,
0176 0x03, 0x0d,
0177 0x01, 0x03,
0178 0x04, 0x00,
0179 0x05, 0x00,
0180 0xff, 0xff
0181 };
0182 static const unsigned char inits_ak4529[] = {
0183 0x09, 0x01,
0184 0x0a, 0x3f,
0185 0x00, 0x0c,
0186 0x01, 0x00,
0187 0x02, 0xff,
0188 0x03, 0xff,
0189 0x04, 0xff,
0190 0x05, 0xff,
0191 0x06, 0xff,
0192 0x07, 0xff,
0193 0x0b, 0xff,
0194 0x0c, 0xff,
0195 0x08, 0x55,
0196 0xff, 0xff
0197 };
0198 static const unsigned char inits_ak4355[] = {
0199 0x01, 0x02,
0200 0x00, 0x06,
0201
0202 0x02, 0x0e,
0203
0204 0x03, 0x01,
0205 0x04, 0x00,
0206 0x05, 0x00,
0207 0x06, 0x00,
0208 0x07, 0x00,
0209 0x08, 0x00,
0210 0x09, 0x00,
0211 0x0a, 0x00,
0212 0x01, 0x01,
0213 0xff, 0xff
0214 };
0215 static const unsigned char inits_ak4358[] = {
0216 0x01, 0x02,
0217 0x00, 0x06,
0218
0219 0x02, 0x4e,
0220
0221 0x03, 0x01,
0222 0x04, 0x00,
0223 0x05, 0x00,
0224 0x06, 0x00,
0225 0x07, 0x00,
0226 0x08, 0x00,
0227 0x09, 0x00,
0228 0x0b, 0x00,
0229 0x0c, 0x00,
0230 0x0a, 0x00,
0231 0x01, 0x01,
0232 0xff, 0xff
0233 };
0234 static const unsigned char inits_ak4381[] = {
0235 0x00, 0x0c,
0236 0x01, 0x02,
0237
0238
0239 0x02, 0x00,
0240 0x03, 0x00,
0241 0x04, 0x00,
0242 0x00, 0x0f,
0243 0xff, 0xff
0244 };
0245 static const unsigned char inits_ak4620[] = {
0246 0x00, 0x07,
0247 0x01, 0x00,
0248 0x01, 0x02,
0249 0x01, 0x03,
0250 0x01, 0x0f,
0251 0x02, 0x60,
0252 0x03, 0x01,
0253 0x04, 0x00,
0254 0x05, 0x00,
0255 0x06, 0x00,
0256 0x07, 0x00,
0257 0xff, 0xff
0258 };
0259
0260 int chip;
0261 const unsigned char *ptr, *inits;
0262 unsigned char reg, data;
0263
0264 memset(ak->images, 0, sizeof(ak->images));
0265 memset(ak->volumes, 0, sizeof(ak->volumes));
0266
0267 switch (ak->type) {
0268 case SND_AK4524:
0269 inits = inits_ak4524;
0270 ak->num_chips = ak->num_dacs / 2;
0271 ak->name = "ak4524";
0272 ak->total_regs = 0x08;
0273 break;
0274 case SND_AK4528:
0275 inits = inits_ak4528;
0276 ak->num_chips = ak->num_dacs / 2;
0277 ak->name = "ak4528";
0278 ak->total_regs = 0x06;
0279 break;
0280 case SND_AK4529:
0281 inits = inits_ak4529;
0282 ak->num_chips = 1;
0283 ak->name = "ak4529";
0284 ak->total_regs = 0x0d;
0285 break;
0286 case SND_AK4355:
0287 inits = inits_ak4355;
0288 ak->num_chips = 1;
0289 ak->name = "ak4355";
0290 ak->total_regs = 0x0b;
0291 break;
0292 case SND_AK4358:
0293 inits = inits_ak4358;
0294 ak->num_chips = 1;
0295 ak->name = "ak4358";
0296 ak->total_regs = 0x10;
0297 break;
0298 case SND_AK4381:
0299 inits = inits_ak4381;
0300 ak->num_chips = ak->num_dacs / 2;
0301 ak->name = "ak4381";
0302 ak->total_regs = 0x05;
0303 break;
0304 case SND_AK5365:
0305
0306 ak->num_chips = 1;
0307 ak->name = "ak5365";
0308 ak->total_regs = 0x08;
0309 return;
0310 case SND_AK4620:
0311 inits = inits_ak4620;
0312 ak->num_chips = ak->num_dacs / 2;
0313 ak->name = "ak4620";
0314 ak->total_regs = 0x08;
0315 break;
0316 default:
0317 snd_BUG();
0318 return;
0319 }
0320
0321 for (chip = 0; chip < ak->num_chips; chip++) {
0322 ptr = inits;
0323 while (*ptr != 0xff) {
0324 reg = *ptr++;
0325 data = *ptr++;
0326 snd_akm4xxx_write(ak, chip, reg, data);
0327 udelay(10);
0328 }
0329 }
0330 }
0331
0332 EXPORT_SYMBOL(snd_akm4xxx_init);
0333
0334
0335
0336
0337 #define AK_IPGA (1<<20)
0338 #define AK_VOL_CVT (1<<21)
0339 #define AK_NEEDSMSB (1<<22)
0340 #define AK_INVERT (1<<23)
0341 #define AK_GET_CHIP(val) (((val) >> 8) & 0xff)
0342 #define AK_GET_ADDR(val) ((val) & 0xff)
0343 #define AK_GET_SHIFT(val) (((val) >> 16) & 0x0f)
0344 #define AK_GET_VOL_CVT(val) (((val) >> 21) & 1)
0345 #define AK_GET_IPGA(val) (((val) >> 20) & 1)
0346 #define AK_GET_NEEDSMSB(val) (((val) >> 22) & 1)
0347 #define AK_GET_INVERT(val) (((val) >> 23) & 1)
0348 #define AK_GET_MASK(val) (((val) >> 24) & 0xff)
0349 #define AK_COMPOSE(chip,addr,shift,mask) \
0350 (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
0351
0352 static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
0353 struct snd_ctl_elem_info *uinfo)
0354 {
0355 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
0356
0357 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0358 uinfo->count = 1;
0359 uinfo->value.integer.min = 0;
0360 uinfo->value.integer.max = mask;
0361 return 0;
0362 }
0363
0364 static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
0365 struct snd_ctl_elem_value *ucontrol)
0366 {
0367 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0368 int chip = AK_GET_CHIP(kcontrol->private_value);
0369 int addr = AK_GET_ADDR(kcontrol->private_value);
0370
0371 ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
0372 return 0;
0373 }
0374
0375 static int put_ak_reg(struct snd_kcontrol *kcontrol, int addr,
0376 unsigned char nval)
0377 {
0378 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0379 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
0380 int chip = AK_GET_CHIP(kcontrol->private_value);
0381
0382 if (snd_akm4xxx_get_vol(ak, chip, addr) == nval)
0383 return 0;
0384
0385 snd_akm4xxx_set_vol(ak, chip, addr, nval);
0386 if (AK_GET_VOL_CVT(kcontrol->private_value) && nval < 128)
0387 nval = vol_cvt_datt[nval];
0388 if (AK_GET_IPGA(kcontrol->private_value) && nval >= 128)
0389 nval++;
0390 if (AK_GET_INVERT(kcontrol->private_value))
0391 nval = mask - nval;
0392 if (AK_GET_NEEDSMSB(kcontrol->private_value))
0393 nval |= 0x80;
0394
0395
0396 snd_akm4xxx_write(ak, chip, addr, nval);
0397 return 1;
0398 }
0399
0400 static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
0401 struct snd_ctl_elem_value *ucontrol)
0402 {
0403 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
0404 unsigned int val = ucontrol->value.integer.value[0];
0405 if (val > mask)
0406 return -EINVAL;
0407 return put_ak_reg(kcontrol, AK_GET_ADDR(kcontrol->private_value), val);
0408 }
0409
0410 static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol,
0411 struct snd_ctl_elem_info *uinfo)
0412 {
0413 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
0414
0415 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0416 uinfo->count = 2;
0417 uinfo->value.integer.min = 0;
0418 uinfo->value.integer.max = mask;
0419 return 0;
0420 }
0421
0422 static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol,
0423 struct snd_ctl_elem_value *ucontrol)
0424 {
0425 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0426 int chip = AK_GET_CHIP(kcontrol->private_value);
0427 int addr = AK_GET_ADDR(kcontrol->private_value);
0428
0429 ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
0430 ucontrol->value.integer.value[1] = snd_akm4xxx_get_vol(ak, chip, addr+1);
0431 return 0;
0432 }
0433
0434 static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
0435 struct snd_ctl_elem_value *ucontrol)
0436 {
0437 int addr = AK_GET_ADDR(kcontrol->private_value);
0438 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
0439 unsigned int val[2];
0440 int change;
0441
0442 val[0] = ucontrol->value.integer.value[0];
0443 val[1] = ucontrol->value.integer.value[1];
0444 if (val[0] > mask || val[1] > mask)
0445 return -EINVAL;
0446 change = put_ak_reg(kcontrol, addr, val[0]);
0447 change |= put_ak_reg(kcontrol, addr + 1, val[1]);
0448 return change;
0449 }
0450
0451 static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol,
0452 struct snd_ctl_elem_info *uinfo)
0453 {
0454 static const char * const texts[4] = {
0455 "44.1kHz", "Off", "48kHz", "32kHz",
0456 };
0457 return snd_ctl_enum_info(uinfo, 1, 4, texts);
0458 }
0459
0460 static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol,
0461 struct snd_ctl_elem_value *ucontrol)
0462 {
0463 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0464 int chip = AK_GET_CHIP(kcontrol->private_value);
0465 int addr = AK_GET_ADDR(kcontrol->private_value);
0466 int shift = AK_GET_SHIFT(kcontrol->private_value);
0467 ucontrol->value.enumerated.item[0] =
0468 (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3;
0469 return 0;
0470 }
0471
0472 static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
0473 struct snd_ctl_elem_value *ucontrol)
0474 {
0475 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0476 int chip = AK_GET_CHIP(kcontrol->private_value);
0477 int addr = AK_GET_ADDR(kcontrol->private_value);
0478 int shift = AK_GET_SHIFT(kcontrol->private_value);
0479 unsigned char nval = ucontrol->value.enumerated.item[0] & 3;
0480 int change;
0481
0482 nval = (nval << shift) |
0483 (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift));
0484 change = snd_akm4xxx_get(ak, chip, addr) != nval;
0485 if (change)
0486 snd_akm4xxx_write(ak, chip, addr, nval);
0487 return change;
0488 }
0489
0490 #define ak4xxx_switch_info snd_ctl_boolean_mono_info
0491
0492 static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
0493 struct snd_ctl_elem_value *ucontrol)
0494 {
0495 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0496 int chip = AK_GET_CHIP(kcontrol->private_value);
0497 int addr = AK_GET_ADDR(kcontrol->private_value);
0498 int shift = AK_GET_SHIFT(kcontrol->private_value);
0499 int invert = AK_GET_INVERT(kcontrol->private_value);
0500
0501 unsigned char val = snd_akm4xxx_get(ak, chip, addr) & (1<<shift);
0502 if (invert)
0503 val = ! val;
0504 ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0;
0505 return 0;
0506 }
0507
0508 static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
0509 struct snd_ctl_elem_value *ucontrol)
0510 {
0511 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0512 int chip = AK_GET_CHIP(kcontrol->private_value);
0513 int addr = AK_GET_ADDR(kcontrol->private_value);
0514 int shift = AK_GET_SHIFT(kcontrol->private_value);
0515 int invert = AK_GET_INVERT(kcontrol->private_value);
0516 long flag = ucontrol->value.integer.value[0];
0517 unsigned char val, oval;
0518 int change;
0519
0520 if (invert)
0521 flag = ! flag;
0522 oval = snd_akm4xxx_get(ak, chip, addr);
0523 if (flag)
0524 val = oval | (1<<shift);
0525 else
0526 val = oval & ~(1<<shift);
0527 change = (oval != val);
0528 if (change)
0529 snd_akm4xxx_write(ak, chip, addr, val);
0530 return change;
0531 }
0532
0533 #define AK5365_NUM_INPUTS 5
0534
0535 static int ak4xxx_capture_num_inputs(struct snd_akm4xxx *ak, int mixer_ch)
0536 {
0537 int num_names;
0538 const char **input_names;
0539
0540 input_names = ak->adc_info[mixer_ch].input_names;
0541 num_names = 0;
0542 while (num_names < AK5365_NUM_INPUTS && input_names[num_names])
0543 ++num_names;
0544 return num_names;
0545 }
0546
0547 static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
0548 struct snd_ctl_elem_info *uinfo)
0549 {
0550 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0551 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
0552 unsigned int num_names;
0553
0554 num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
0555 if (!num_names)
0556 return -EINVAL;
0557 return snd_ctl_enum_info(uinfo, 1, num_names,
0558 ak->adc_info[mixer_ch].input_names);
0559 }
0560
0561 static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol,
0562 struct snd_ctl_elem_value *ucontrol)
0563 {
0564 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0565 int chip = AK_GET_CHIP(kcontrol->private_value);
0566 int addr = AK_GET_ADDR(kcontrol->private_value);
0567 int mask = AK_GET_MASK(kcontrol->private_value);
0568 unsigned char val;
0569
0570 val = snd_akm4xxx_get(ak, chip, addr) & mask;
0571 ucontrol->value.enumerated.item[0] = val;
0572 return 0;
0573 }
0574
0575 static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol,
0576 struct snd_ctl_elem_value *ucontrol)
0577 {
0578 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
0579 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
0580 int chip = AK_GET_CHIP(kcontrol->private_value);
0581 int addr = AK_GET_ADDR(kcontrol->private_value);
0582 int mask = AK_GET_MASK(kcontrol->private_value);
0583 unsigned char oval, val;
0584 int num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
0585
0586 if (ucontrol->value.enumerated.item[0] >= num_names)
0587 return -EINVAL;
0588
0589 oval = snd_akm4xxx_get(ak, chip, addr);
0590 val = oval & ~mask;
0591 val |= ucontrol->value.enumerated.item[0] & mask;
0592 if (val != oval) {
0593 snd_akm4xxx_write(ak, chip, addr, val);
0594 return 1;
0595 }
0596 return 0;
0597 }
0598
0599
0600
0601
0602
0603 static int build_dac_controls(struct snd_akm4xxx *ak)
0604 {
0605 int idx, err, mixer_ch, num_stereo;
0606 struct snd_kcontrol_new knew;
0607
0608 mixer_ch = 0;
0609 for (idx = 0; idx < ak->num_dacs; ) {
0610
0611 if (ak->type == SND_AK4381
0612 && ak->dac_info[mixer_ch].switch_name) {
0613 memset(&knew, 0, sizeof(knew));
0614 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0615 knew.count = 1;
0616 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
0617 knew.name = ak->dac_info[mixer_ch].switch_name;
0618 knew.info = ak4xxx_switch_info;
0619 knew.get = ak4xxx_switch_get;
0620 knew.put = ak4xxx_switch_put;
0621 knew.access = 0;
0622
0623
0624 knew.private_value =
0625 AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT;
0626 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
0627 if (err < 0)
0628 return err;
0629 }
0630 memset(&knew, 0, sizeof(knew));
0631 if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) {
0632 knew.name = "DAC Volume";
0633 knew.index = mixer_ch + ak->idx_offset * 2;
0634 num_stereo = 1;
0635 } else {
0636 knew.name = ak->dac_info[mixer_ch].name;
0637 num_stereo = ak->dac_info[mixer_ch].num_channels;
0638 }
0639 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0640 knew.count = 1;
0641 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
0642 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
0643 if (num_stereo == 2) {
0644 knew.info = snd_akm4xxx_stereo_volume_info;
0645 knew.get = snd_akm4xxx_stereo_volume_get;
0646 knew.put = snd_akm4xxx_stereo_volume_put;
0647 } else {
0648 knew.info = snd_akm4xxx_volume_info;
0649 knew.get = snd_akm4xxx_volume_get;
0650 knew.put = snd_akm4xxx_volume_put;
0651 }
0652 switch (ak->type) {
0653 case SND_AK4524:
0654
0655 knew.private_value =
0656 AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127) |
0657 AK_VOL_CVT;
0658 knew.tlv.p = db_scale_vol_datt;
0659 break;
0660 case SND_AK4528:
0661
0662 knew.private_value =
0663 AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127) |
0664 AK_VOL_CVT;
0665 knew.tlv.p = db_scale_vol_datt;
0666 break;
0667 case SND_AK4529: {
0668
0669 int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb;
0670 knew.private_value =
0671 AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
0672 knew.tlv.p = db_scale_8bit;
0673 break;
0674 }
0675 case SND_AK4355:
0676
0677 knew.private_value = AK_COMPOSE(0, idx + 4, 0, 255);
0678 knew.tlv.p = db_scale_8bit;
0679 break;
0680 case SND_AK4358: {
0681
0682 int addr = idx < 6 ? idx + 4 : idx + 5;
0683 knew.private_value =
0684 AK_COMPOSE(0, addr, 0, 127) | AK_NEEDSMSB;
0685 knew.tlv.p = db_scale_7bit;
0686 break;
0687 }
0688 case SND_AK4381:
0689
0690 knew.private_value =
0691 AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255);
0692 knew.tlv.p = db_scale_linear;
0693 break;
0694 case SND_AK4620:
0695
0696 knew.private_value =
0697 AK_COMPOSE(idx/2, (idx%2) + 6, 0, 255);
0698 knew.tlv.p = db_scale_linear;
0699 break;
0700 default:
0701 return -EINVAL;
0702 }
0703
0704 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
0705 if (err < 0)
0706 return err;
0707
0708 idx += num_stereo;
0709 mixer_ch++;
0710 }
0711 return 0;
0712 }
0713
0714 static int build_adc_controls(struct snd_akm4xxx *ak)
0715 {
0716 int idx, err, mixer_ch, num_stereo, max_steps;
0717 struct snd_kcontrol_new knew;
0718
0719 mixer_ch = 0;
0720 if (ak->type == SND_AK4528)
0721 return 0;
0722 for (idx = 0; idx < ak->num_adcs;) {
0723 memset(&knew, 0, sizeof(knew));
0724 if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) {
0725 knew.name = "ADC Volume";
0726 knew.index = mixer_ch + ak->idx_offset * 2;
0727 num_stereo = 1;
0728 } else {
0729 knew.name = ak->adc_info[mixer_ch].name;
0730 num_stereo = ak->adc_info[mixer_ch].num_channels;
0731 }
0732 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0733 knew.count = 1;
0734 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
0735 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
0736 if (num_stereo == 2) {
0737 knew.info = snd_akm4xxx_stereo_volume_info;
0738 knew.get = snd_akm4xxx_stereo_volume_get;
0739 knew.put = snd_akm4xxx_stereo_volume_put;
0740 } else {
0741 knew.info = snd_akm4xxx_volume_info;
0742 knew.get = snd_akm4xxx_volume_get;
0743 knew.put = snd_akm4xxx_volume_put;
0744 }
0745
0746 if (ak->type == SND_AK5365)
0747 max_steps = 152;
0748 else
0749 max_steps = 164;
0750 knew.private_value =
0751 AK_COMPOSE(idx/2, (idx%2) + 4, 0, max_steps) |
0752 AK_VOL_CVT | AK_IPGA;
0753 knew.tlv.p = db_scale_vol_datt;
0754 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
0755 if (err < 0)
0756 return err;
0757
0758 if (ak->type == SND_AK5365 && (idx % 2) == 0) {
0759 if (! ak->adc_info ||
0760 ! ak->adc_info[mixer_ch].switch_name) {
0761 knew.name = "Capture Switch";
0762 knew.index = mixer_ch + ak->idx_offset * 2;
0763 } else
0764 knew.name = ak->adc_info[mixer_ch].switch_name;
0765 knew.info = ak4xxx_switch_info;
0766 knew.get = ak4xxx_switch_get;
0767 knew.put = ak4xxx_switch_put;
0768 knew.access = 0;
0769
0770
0771 knew.private_value =
0772 AK_COMPOSE(idx/2, 2, 0, 0) | AK_INVERT;
0773 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
0774 if (err < 0)
0775 return err;
0776
0777 memset(&knew, 0, sizeof(knew));
0778 if (!ak->adc_info ||
0779 !ak->adc_info[mixer_ch].selector_name) {
0780 knew.name = "Capture Channel";
0781 knew.index = mixer_ch + ak->idx_offset * 2;
0782 } else
0783 knew.name = ak->adc_info[mixer_ch].selector_name;
0784
0785 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0786 knew.info = ak4xxx_capture_source_info;
0787 knew.get = ak4xxx_capture_source_get;
0788 knew.put = ak4xxx_capture_source_put;
0789 knew.access = 0;
0790
0791
0792 knew.private_value
0793 = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07);
0794 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
0795 if (err < 0)
0796 return err;
0797 }
0798
0799 idx += num_stereo;
0800 mixer_ch++;
0801 }
0802 return 0;
0803 }
0804
0805 static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
0806 {
0807 int idx, err;
0808 struct snd_kcontrol_new knew;
0809
0810 for (idx = 0; idx < num_emphs; idx++) {
0811 memset(&knew, 0, sizeof(knew));
0812 knew.name = "Deemphasis";
0813 knew.index = idx + ak->idx_offset;
0814 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0815 knew.count = 1;
0816 knew.info = snd_akm4xxx_deemphasis_info;
0817 knew.get = snd_akm4xxx_deemphasis_get;
0818 knew.put = snd_akm4xxx_deemphasis_put;
0819 switch (ak->type) {
0820 case SND_AK4524:
0821 case SND_AK4528:
0822 case SND_AK4620:
0823
0824 knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
0825 break;
0826 case SND_AK4529: {
0827 int shift = idx == 3 ? 6 : (2 - idx) * 2;
0828
0829 knew.private_value = AK_COMPOSE(0, 8, shift, 0);
0830 break;
0831 }
0832 case SND_AK4355:
0833 case SND_AK4358:
0834 knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
0835 break;
0836 case SND_AK4381:
0837 knew.private_value = AK_COMPOSE(idx, 1, 1, 0);
0838 break;
0839 default:
0840 return -EINVAL;
0841 }
0842 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
0843 if (err < 0)
0844 return err;
0845 }
0846 return 0;
0847 }
0848
0849 static void proc_regs_read(struct snd_info_entry *entry,
0850 struct snd_info_buffer *buffer)
0851 {
0852 struct snd_akm4xxx *ak = entry->private_data;
0853 int reg, val, chip;
0854 for (chip = 0; chip < ak->num_chips; chip++) {
0855 for (reg = 0; reg < ak->total_regs; reg++) {
0856 val = snd_akm4xxx_get(ak, chip, reg);
0857 snd_iprintf(buffer, "chip %d: 0x%02x = 0x%02x\n", chip,
0858 reg, val);
0859 }
0860 }
0861 }
0862
0863 static int proc_init(struct snd_akm4xxx *ak)
0864 {
0865 return snd_card_ro_proc_new(ak->card, ak->name, ak, proc_regs_read);
0866 }
0867
0868 int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
0869 {
0870 int err, num_emphs;
0871
0872 err = build_dac_controls(ak);
0873 if (err < 0)
0874 return err;
0875
0876 err = build_adc_controls(ak);
0877 if (err < 0)
0878 return err;
0879 if (ak->type == SND_AK4355 || ak->type == SND_AK4358)
0880 num_emphs = 1;
0881 else if (ak->type == SND_AK4620)
0882 num_emphs = 0;
0883 else
0884 num_emphs = ak->num_dacs / 2;
0885 err = build_deemphasis(ak, num_emphs);
0886 if (err < 0)
0887 return err;
0888 err = proc_init(ak);
0889 if (err < 0)
0890 return err;
0891
0892 return 0;
0893 }
0894 EXPORT_SYMBOL(snd_akm4xxx_build_controls);