0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/delay.h>
0032 #include <linux/interrupt.h>
0033 #include <linux/init.h>
0034 #include <linux/slab.h>
0035 #include <linux/mutex.h>
0036
0037 #include <sound/core.h>
0038
0039 #include "ice1712.h"
0040 #include "envy24ht.h"
0041 #include "phase.h"
0042 #include <sound/tlv.h>
0043
0044
0045 struct phase28_spec {
0046 unsigned short master[2];
0047 unsigned short vol[8];
0048 };
0049
0050
0051 #define WM_DAC_ATTEN 0x00
0052 #define WM_DAC_MASTER_ATTEN 0x08
0053 #define WM_DAC_DIG_ATTEN 0x09
0054 #define WM_DAC_DIG_MASTER_ATTEN 0x11
0055 #define WM_PHASE_SWAP 0x12
0056 #define WM_DAC_CTRL1 0x13
0057 #define WM_MUTE 0x14
0058 #define WM_DAC_CTRL2 0x15
0059 #define WM_INT_CTRL 0x16
0060 #define WM_MASTER 0x17
0061 #define WM_POWERDOWN 0x18
0062 #define WM_ADC_GAIN 0x19
0063 #define WM_ADC_MUX 0x1b
0064 #define WM_OUT_MUX1 0x1c
0065 #define WM_OUT_MUX2 0x1e
0066 #define WM_RESET 0x1f
0067
0068
0069
0070
0071
0072
0073 static const unsigned char wm_vol[256] = {
0074 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
0075 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
0076 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
0077 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
0078 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
0079 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
0080 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
0081 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
0082 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
0083 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0084 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0085 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0086 };
0087
0088 #define WM_VOL_MAX (sizeof(wm_vol) - 1)
0089 #define WM_VOL_MUTE 0x8000
0090
0091 static const struct snd_akm4xxx akm_phase22 = {
0092 .type = SND_AK4524,
0093 .num_dacs = 2,
0094 .num_adcs = 2,
0095 };
0096
0097 static const struct snd_ak4xxx_private akm_phase22_priv = {
0098 .caddr = 2,
0099 .cif = 1,
0100 .data_mask = 1 << 4,
0101 .clk_mask = 1 << 5,
0102 .cs_mask = 1 << 10,
0103 .cs_addr = 1 << 10,
0104 .cs_none = 0,
0105 .add_flags = 1 << 3,
0106 .mask_flags = 0,
0107 };
0108
0109 static int phase22_init(struct snd_ice1712 *ice)
0110 {
0111 struct snd_akm4xxx *ak;
0112 int err;
0113
0114
0115 switch (ice->eeprom.subvendor) {
0116 case VT1724_SUBDEVICE_PHASE22:
0117 case VT1724_SUBDEVICE_TS22:
0118 ice->num_total_dacs = 2;
0119 ice->num_total_adcs = 2;
0120 ice->vt1720 = 1;
0121 break;
0122 default:
0123 snd_BUG();
0124 return -EINVAL;
0125 }
0126
0127
0128 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
0129 ak = ice->akm;
0130 if (!ak)
0131 return -ENOMEM;
0132 ice->akm_codecs = 1;
0133 switch (ice->eeprom.subvendor) {
0134 case VT1724_SUBDEVICE_PHASE22:
0135 case VT1724_SUBDEVICE_TS22:
0136 err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
0137 &akm_phase22_priv, ice);
0138 if (err < 0)
0139 return err;
0140 break;
0141 }
0142
0143 return 0;
0144 }
0145
0146 static int phase22_add_controls(struct snd_ice1712 *ice)
0147 {
0148 int err = 0;
0149
0150 switch (ice->eeprom.subvendor) {
0151 case VT1724_SUBDEVICE_PHASE22:
0152 case VT1724_SUBDEVICE_TS22:
0153 err = snd_ice1712_akm4xxx_build_controls(ice);
0154 if (err < 0)
0155 return err;
0156 }
0157 return 0;
0158 }
0159
0160 static const unsigned char phase22_eeprom[] = {
0161 [ICE_EEP2_SYSCONF] = 0x28,
0162
0163 [ICE_EEP2_ACLINK] = 0x80,
0164 [ICE_EEP2_I2S] = 0xf0,
0165 [ICE_EEP2_SPDIF] = 0xc3,
0166 [ICE_EEP2_GPIO_DIR] = 0xff,
0167 [ICE_EEP2_GPIO_DIR1] = 0xff,
0168 [ICE_EEP2_GPIO_DIR2] = 0xff,
0169 [ICE_EEP2_GPIO_MASK] = 0x00,
0170 [ICE_EEP2_GPIO_MASK1] = 0x00,
0171 [ICE_EEP2_GPIO_MASK2] = 0x00,
0172 [ICE_EEP2_GPIO_STATE] = 0x00,
0173 [ICE_EEP2_GPIO_STATE1] = 0x00,
0174 [ICE_EEP2_GPIO_STATE2] = 0x00,
0175 };
0176
0177 static const unsigned char phase28_eeprom[] = {
0178 [ICE_EEP2_SYSCONF] = 0x2b,
0179
0180 [ICE_EEP2_ACLINK] = 0x80,
0181 [ICE_EEP2_I2S] = 0xfc,
0182 [ICE_EEP2_SPDIF] = 0xc3,
0183 [ICE_EEP2_GPIO_DIR] = 0xff,
0184 [ICE_EEP2_GPIO_DIR1] = 0xff,
0185 [ICE_EEP2_GPIO_DIR2] = 0x5f,
0186 [ICE_EEP2_GPIO_MASK] = 0x00,
0187 [ICE_EEP2_GPIO_MASK1] = 0x00,
0188 [ICE_EEP2_GPIO_MASK2] = 0x00,
0189 [ICE_EEP2_GPIO_STATE] = 0x00,
0190 [ICE_EEP2_GPIO_STATE1] = 0x00,
0191 [ICE_EEP2_GPIO_STATE2] = 0x00,
0192 };
0193
0194
0195
0196
0197 static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
0198 unsigned int data, int bits)
0199 {
0200 unsigned int tmp;
0201 int i;
0202
0203 tmp = snd_ice1712_gpio_read(ice);
0204
0205 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
0206 PHASE28_SPI_CLK|PHASE28_WM_CS));
0207 tmp |= PHASE28_WM_RW;
0208 tmp &= ~cs;
0209 snd_ice1712_gpio_write(ice, tmp);
0210 udelay(1);
0211
0212 for (i = bits - 1; i >= 0; i--) {
0213 tmp &= ~PHASE28_SPI_CLK;
0214 snd_ice1712_gpio_write(ice, tmp);
0215 udelay(1);
0216 if (data & (1 << i))
0217 tmp |= PHASE28_SPI_MOSI;
0218 else
0219 tmp &= ~PHASE28_SPI_MOSI;
0220 snd_ice1712_gpio_write(ice, tmp);
0221 udelay(1);
0222 tmp |= PHASE28_SPI_CLK;
0223 snd_ice1712_gpio_write(ice, tmp);
0224 udelay(1);
0225 }
0226
0227 tmp &= ~PHASE28_SPI_CLK;
0228 tmp |= cs;
0229 snd_ice1712_gpio_write(ice, tmp);
0230 udelay(1);
0231 tmp |= PHASE28_SPI_CLK;
0232 snd_ice1712_gpio_write(ice, tmp);
0233 udelay(1);
0234 }
0235
0236
0237
0238
0239 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
0240 {
0241 reg <<= 1;
0242 return ((unsigned short)ice->akm[0].images[reg] << 8) |
0243 ice->akm[0].images[reg + 1];
0244 }
0245
0246
0247
0248
0249 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
0250 {
0251 phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
0252 }
0253
0254
0255
0256
0257 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
0258 {
0259 wm_put_nocache(ice, reg, val);
0260 reg <<= 1;
0261 ice->akm[0].images[reg] = val >> 8;
0262 ice->akm[0].images[reg + 1] = val;
0263 }
0264
0265 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
0266 unsigned short vol, unsigned short master)
0267 {
0268 unsigned char nvol;
0269
0270 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
0271 nvol = 0;
0272 else
0273 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
0274 (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
0275
0276 wm_put(ice, index, nvol);
0277 wm_put_nocache(ice, index, 0x180 | nvol);
0278 }
0279
0280
0281
0282
0283 #define wm_pcm_mute_info snd_ctl_boolean_mono_info
0284
0285 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
0286 struct snd_ctl_elem_value *ucontrol)
0287 {
0288 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0289
0290 mutex_lock(&ice->gpio_mutex);
0291 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
0292 0 : 1;
0293 mutex_unlock(&ice->gpio_mutex);
0294 return 0;
0295 }
0296
0297 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
0298 struct snd_ctl_elem_value *ucontrol)
0299 {
0300 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0301 unsigned short nval, oval;
0302 int change;
0303
0304 snd_ice1712_save_gpio_status(ice);
0305 oval = wm_get(ice, WM_MUTE);
0306 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
0307 change = (nval != oval);
0308 if (change)
0309 wm_put(ice, WM_MUTE, nval);
0310 snd_ice1712_restore_gpio_status(ice);
0311
0312 return change;
0313 }
0314
0315
0316
0317
0318 static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
0319 struct snd_ctl_elem_info *uinfo)
0320 {
0321 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0322 uinfo->count = 2;
0323 uinfo->value.integer.min = 0;
0324 uinfo->value.integer.max = WM_VOL_MAX;
0325 return 0;
0326 }
0327
0328 static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
0329 struct snd_ctl_elem_value *ucontrol)
0330 {
0331 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0332 struct phase28_spec *spec = ice->spec;
0333 int i;
0334 for (i = 0; i < 2; i++)
0335 ucontrol->value.integer.value[i] = spec->master[i] &
0336 ~WM_VOL_MUTE;
0337 return 0;
0338 }
0339
0340 static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
0341 struct snd_ctl_elem_value *ucontrol)
0342 {
0343 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0344 struct phase28_spec *spec = ice->spec;
0345 int ch, change = 0;
0346
0347 snd_ice1712_save_gpio_status(ice);
0348 for (ch = 0; ch < 2; ch++) {
0349 unsigned int vol = ucontrol->value.integer.value[ch];
0350 if (vol > WM_VOL_MAX)
0351 continue;
0352 vol |= spec->master[ch] & WM_VOL_MUTE;
0353 if (vol != spec->master[ch]) {
0354 int dac;
0355 spec->master[ch] = vol;
0356 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
0357 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
0358 spec->vol[dac + ch],
0359 spec->master[ch]);
0360 change = 1;
0361 }
0362 }
0363 snd_ice1712_restore_gpio_status(ice);
0364 return change;
0365 }
0366
0367 static int phase28_init(struct snd_ice1712 *ice)
0368 {
0369 static const unsigned short wm_inits_phase28[] = {
0370
0371 0x1b, 0x044,
0372 0x1c, 0x00B,
0373 0x1d, 0x009,
0374
0375 0x18, 0x000,
0376
0377 0x16, 0x122,
0378 0x17, 0x022,
0379 0x00, 0,
0380 0x01, 0,
0381 0x02, 0,
0382 0x03, 0,
0383 0x04, 0,
0384 0x05, 0,
0385 0x06, 0,
0386 0x07, 0,
0387 0x08, 0x100,
0388 0x09, 0xff,
0389 0x0a, 0xff,
0390 0x0b, 0xff,
0391 0x0c, 0xff,
0392 0x0d, 0xff,
0393 0x0e, 0xff,
0394 0x0f, 0xff,
0395 0x10, 0xff,
0396 0x11, 0x1ff,
0397 0x12, 0x000,
0398 0x13, 0x090,
0399 0x14, 0x000,
0400 0x15, 0x000,
0401 0x19, 0x000,
0402 0x1a, 0x000,
0403 (unsigned short)-1
0404 };
0405
0406 unsigned int tmp;
0407 struct snd_akm4xxx *ak;
0408 struct phase28_spec *spec;
0409 const unsigned short *p;
0410 int i;
0411
0412 ice->num_total_dacs = 8;
0413 ice->num_total_adcs = 2;
0414
0415 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0416 if (!spec)
0417 return -ENOMEM;
0418 ice->spec = spec;
0419
0420
0421 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
0422 ak = ice->akm;
0423 if (!ak)
0424 return -ENOMEM;
0425 ice->akm_codecs = 1;
0426
0427 snd_ice1712_gpio_set_dir(ice, 0x5fffff);
0428
0429
0430 snd_ice1712_save_gpio_status(ice);
0431 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
0432 PHASE28_HP_SEL));
0433
0434 tmp = snd_ice1712_gpio_read(ice);
0435 tmp &= ~PHASE28_WM_RESET;
0436 snd_ice1712_gpio_write(ice, tmp);
0437 udelay(1);
0438 tmp |= PHASE28_WM_CS;
0439 snd_ice1712_gpio_write(ice, tmp);
0440 udelay(1);
0441 tmp |= PHASE28_WM_RESET;
0442 snd_ice1712_gpio_write(ice, tmp);
0443 udelay(1);
0444
0445 p = wm_inits_phase28;
0446 for (; *p != (unsigned short)-1; p += 2)
0447 wm_put(ice, p[0], p[1]);
0448
0449 snd_ice1712_restore_gpio_status(ice);
0450
0451 spec->master[0] = WM_VOL_MUTE;
0452 spec->master[1] = WM_VOL_MUTE;
0453 for (i = 0; i < ice->num_total_dacs; i++) {
0454 spec->vol[i] = WM_VOL_MUTE;
0455 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
0456 }
0457
0458 return 0;
0459 }
0460
0461
0462
0463
0464 static int wm_vol_info(struct snd_kcontrol *kcontrol,
0465 struct snd_ctl_elem_info *uinfo)
0466 {
0467 int voices = kcontrol->private_value >> 8;
0468 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0469 uinfo->count = voices;
0470 uinfo->value.integer.min = 0;
0471 uinfo->value.integer.max = 0x7F;
0472 return 0;
0473 }
0474
0475 static int wm_vol_get(struct snd_kcontrol *kcontrol,
0476 struct snd_ctl_elem_value *ucontrol)
0477 {
0478 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0479 struct phase28_spec *spec = ice->spec;
0480 int i, ofs, voices;
0481
0482 voices = kcontrol->private_value >> 8;
0483 ofs = kcontrol->private_value & 0xff;
0484 for (i = 0; i < voices; i++)
0485 ucontrol->value.integer.value[i] =
0486 spec->vol[ofs+i] & ~WM_VOL_MUTE;
0487 return 0;
0488 }
0489
0490 static int wm_vol_put(struct snd_kcontrol *kcontrol,
0491 struct snd_ctl_elem_value *ucontrol)
0492 {
0493 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0494 struct phase28_spec *spec = ice->spec;
0495 int i, idx, ofs, voices;
0496 int change = 0;
0497
0498 voices = kcontrol->private_value >> 8;
0499 ofs = kcontrol->private_value & 0xff;
0500 snd_ice1712_save_gpio_status(ice);
0501 for (i = 0; i < voices; i++) {
0502 unsigned int vol;
0503 vol = ucontrol->value.integer.value[i];
0504 if (vol > 0x7f)
0505 continue;
0506 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
0507 if (vol != spec->vol[ofs+i]) {
0508 spec->vol[ofs+i] = vol;
0509 idx = WM_DAC_ATTEN + ofs + i;
0510 wm_set_vol(ice, idx, spec->vol[ofs+i],
0511 spec->master[i]);
0512 change = 1;
0513 }
0514 }
0515 snd_ice1712_restore_gpio_status(ice);
0516 return change;
0517 }
0518
0519
0520
0521
0522 static int wm_mute_info(struct snd_kcontrol *kcontrol,
0523 struct snd_ctl_elem_info *uinfo) {
0524 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
0525 uinfo->count = kcontrol->private_value >> 8;
0526 uinfo->value.integer.min = 0;
0527 uinfo->value.integer.max = 1;
0528 return 0;
0529 }
0530
0531 static int wm_mute_get(struct snd_kcontrol *kcontrol,
0532 struct snd_ctl_elem_value *ucontrol)
0533 {
0534 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0535 struct phase28_spec *spec = ice->spec;
0536 int voices, ofs, i;
0537
0538 voices = kcontrol->private_value >> 8;
0539 ofs = kcontrol->private_value & 0xFF;
0540
0541 for (i = 0; i < voices; i++)
0542 ucontrol->value.integer.value[i] =
0543 (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
0544 return 0;
0545 }
0546
0547 static int wm_mute_put(struct snd_kcontrol *kcontrol,
0548 struct snd_ctl_elem_value *ucontrol)
0549 {
0550 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0551 struct phase28_spec *spec = ice->spec;
0552 int change = 0, voices, ofs, i;
0553
0554 voices = kcontrol->private_value >> 8;
0555 ofs = kcontrol->private_value & 0xFF;
0556
0557 snd_ice1712_save_gpio_status(ice);
0558 for (i = 0; i < voices; i++) {
0559 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
0560 if (ucontrol->value.integer.value[i] != val) {
0561 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
0562 spec->vol[ofs + i] |=
0563 ucontrol->value.integer.value[i] ? 0 :
0564 WM_VOL_MUTE;
0565 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
0566 spec->master[i]);
0567 change = 1;
0568 }
0569 }
0570 snd_ice1712_restore_gpio_status(ice);
0571
0572 return change;
0573 }
0574
0575
0576
0577
0578 #define wm_master_mute_info snd_ctl_boolean_stereo_info
0579
0580 static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
0581 struct snd_ctl_elem_value *ucontrol)
0582 {
0583 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0584 struct phase28_spec *spec = ice->spec;
0585
0586 ucontrol->value.integer.value[0] =
0587 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
0588 ucontrol->value.integer.value[1] =
0589 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
0590 return 0;
0591 }
0592
0593 static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
0594 struct snd_ctl_elem_value *ucontrol)
0595 {
0596 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0597 struct phase28_spec *spec = ice->spec;
0598 int change = 0, i;
0599
0600 snd_ice1712_save_gpio_status(ice);
0601 for (i = 0; i < 2; i++) {
0602 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
0603 if (ucontrol->value.integer.value[i] != val) {
0604 int dac;
0605 spec->master[i] &= ~WM_VOL_MUTE;
0606 spec->master[i] |=
0607 ucontrol->value.integer.value[i] ? 0 :
0608 WM_VOL_MUTE;
0609 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
0610 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
0611 spec->vol[dac + i],
0612 spec->master[i]);
0613 change = 1;
0614 }
0615 }
0616 snd_ice1712_restore_gpio_status(ice);
0617
0618 return change;
0619 }
0620
0621
0622 #define PCM_0dB 0xff
0623 #define PCM_RES 128
0624 #define PCM_MIN (PCM_0dB - PCM_RES)
0625 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
0626 struct snd_ctl_elem_info *uinfo)
0627 {
0628 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0629 uinfo->count = 1;
0630 uinfo->value.integer.min = 0;
0631 uinfo->value.integer.max = PCM_RES;
0632 return 0;
0633 }
0634
0635 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
0636 struct snd_ctl_elem_value *ucontrol)
0637 {
0638 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0639 unsigned short val;
0640
0641 mutex_lock(&ice->gpio_mutex);
0642 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
0643 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
0644 ucontrol->value.integer.value[0] = val;
0645 mutex_unlock(&ice->gpio_mutex);
0646 return 0;
0647 }
0648
0649 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
0650 struct snd_ctl_elem_value *ucontrol)
0651 {
0652 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0653 unsigned short ovol, nvol;
0654 int change = 0;
0655
0656 nvol = ucontrol->value.integer.value[0];
0657 if (nvol > PCM_RES)
0658 return -EINVAL;
0659 snd_ice1712_save_gpio_status(ice);
0660 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
0661 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
0662 if (ovol != nvol) {
0663 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol);
0664
0665 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
0666 change = 1;
0667 }
0668 snd_ice1712_restore_gpio_status(ice);
0669 return change;
0670 }
0671
0672
0673
0674
0675 #define phase28_deemp_info snd_ctl_boolean_mono_info
0676
0677 static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
0678 struct snd_ctl_elem_value *ucontrol)
0679 {
0680 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0681 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
0682 0xf;
0683 return 0;
0684 }
0685
0686 static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
0687 struct snd_ctl_elem_value *ucontrol)
0688 {
0689 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0690 int temp, temp2;
0691 temp = wm_get(ice, WM_DAC_CTRL2);
0692 temp2 = temp;
0693 if (ucontrol->value.integer.value[0])
0694 temp |= 0xf;
0695 else
0696 temp &= ~0xf;
0697 if (temp != temp2) {
0698 wm_put(ice, WM_DAC_CTRL2, temp);
0699 return 1;
0700 }
0701 return 0;
0702 }
0703
0704
0705
0706
0707 static int phase28_oversampling_info(struct snd_kcontrol *k,
0708 struct snd_ctl_elem_info *uinfo)
0709 {
0710 static const char * const texts[2] = { "128x", "64x" };
0711
0712 return snd_ctl_enum_info(uinfo, 1, 2, texts);
0713 }
0714
0715 static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
0716 struct snd_ctl_elem_value *ucontrol)
0717 {
0718 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0719 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
0720 0x8;
0721 return 0;
0722 }
0723
0724 static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
0725 struct snd_ctl_elem_value *ucontrol)
0726 {
0727 int temp, temp2;
0728 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0729
0730 temp = wm_get(ice, WM_MASTER);
0731 temp2 = temp;
0732
0733 if (ucontrol->value.enumerated.item[0])
0734 temp |= 0x8;
0735 else
0736 temp &= ~0x8;
0737
0738 if (temp != temp2) {
0739 wm_put(ice, WM_MASTER, temp);
0740 return 1;
0741 }
0742 return 0;
0743 }
0744
0745 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
0746 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
0747
0748 static const struct snd_kcontrol_new phase28_dac_controls[] = {
0749 {
0750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0751 .name = "Master Playback Switch",
0752 .info = wm_master_mute_info,
0753 .get = wm_master_mute_get,
0754 .put = wm_master_mute_put
0755 },
0756 {
0757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0759 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0760 .name = "Master Playback Volume",
0761 .info = wm_master_vol_info,
0762 .get = wm_master_vol_get,
0763 .put = wm_master_vol_put,
0764 .tlv = { .p = db_scale_wm_dac }
0765 },
0766 {
0767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0768 .name = "Front Playback Switch",
0769 .info = wm_mute_info,
0770 .get = wm_mute_get,
0771 .put = wm_mute_put,
0772 .private_value = (2 << 8) | 0
0773 },
0774 {
0775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0776 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0777 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0778 .name = "Front Playback Volume",
0779 .info = wm_vol_info,
0780 .get = wm_vol_get,
0781 .put = wm_vol_put,
0782 .private_value = (2 << 8) | 0,
0783 .tlv = { .p = db_scale_wm_dac }
0784 },
0785 {
0786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0787 .name = "Rear Playback Switch",
0788 .info = wm_mute_info,
0789 .get = wm_mute_get,
0790 .put = wm_mute_put,
0791 .private_value = (2 << 8) | 2
0792 },
0793 {
0794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0795 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0796 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0797 .name = "Rear Playback Volume",
0798 .info = wm_vol_info,
0799 .get = wm_vol_get,
0800 .put = wm_vol_put,
0801 .private_value = (2 << 8) | 2,
0802 .tlv = { .p = db_scale_wm_dac }
0803 },
0804 {
0805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0806 .name = "Center Playback Switch",
0807 .info = wm_mute_info,
0808 .get = wm_mute_get,
0809 .put = wm_mute_put,
0810 .private_value = (1 << 8) | 4
0811 },
0812 {
0813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0814 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0815 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0816 .name = "Center Playback Volume",
0817 .info = wm_vol_info,
0818 .get = wm_vol_get,
0819 .put = wm_vol_put,
0820 .private_value = (1 << 8) | 4,
0821 .tlv = { .p = db_scale_wm_dac }
0822 },
0823 {
0824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0825 .name = "LFE Playback Switch",
0826 .info = wm_mute_info,
0827 .get = wm_mute_get,
0828 .put = wm_mute_put,
0829 .private_value = (1 << 8) | 5
0830 },
0831 {
0832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0833 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0834 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0835 .name = "LFE Playback Volume",
0836 .info = wm_vol_info,
0837 .get = wm_vol_get,
0838 .put = wm_vol_put,
0839 .private_value = (1 << 8) | 5,
0840 .tlv = { .p = db_scale_wm_dac }
0841 },
0842 {
0843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0844 .name = "Side Playback Switch",
0845 .info = wm_mute_info,
0846 .get = wm_mute_get,
0847 .put = wm_mute_put,
0848 .private_value = (2 << 8) | 6
0849 },
0850 {
0851 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0852 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0853 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0854 .name = "Side Playback Volume",
0855 .info = wm_vol_info,
0856 .get = wm_vol_get,
0857 .put = wm_vol_put,
0858 .private_value = (2 << 8) | 6,
0859 .tlv = { .p = db_scale_wm_dac }
0860 }
0861 };
0862
0863 static const struct snd_kcontrol_new wm_controls[] = {
0864 {
0865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0866 .name = "PCM Playback Switch",
0867 .info = wm_pcm_mute_info,
0868 .get = wm_pcm_mute_get,
0869 .put = wm_pcm_mute_put
0870 },
0871 {
0872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0873 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0874 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0875 .name = "PCM Playback Volume",
0876 .info = wm_pcm_vol_info,
0877 .get = wm_pcm_vol_get,
0878 .put = wm_pcm_vol_put,
0879 .tlv = { .p = db_scale_wm_pcm }
0880 },
0881 {
0882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0883 .name = "DAC Deemphasis Switch",
0884 .info = phase28_deemp_info,
0885 .get = phase28_deemp_get,
0886 .put = phase28_deemp_put
0887 },
0888 {
0889 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0890 .name = "ADC Oversampling",
0891 .info = phase28_oversampling_info,
0892 .get = phase28_oversampling_get,
0893 .put = phase28_oversampling_put
0894 }
0895 };
0896
0897 static int phase28_add_controls(struct snd_ice1712 *ice)
0898 {
0899 unsigned int i, counts;
0900 int err;
0901
0902 counts = ARRAY_SIZE(phase28_dac_controls);
0903 for (i = 0; i < counts; i++) {
0904 err = snd_ctl_add(ice->card,
0905 snd_ctl_new1(&phase28_dac_controls[i],
0906 ice));
0907 if (err < 0)
0908 return err;
0909 }
0910
0911 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
0912 err = snd_ctl_add(ice->card,
0913 snd_ctl_new1(&wm_controls[i], ice));
0914 if (err < 0)
0915 return err;
0916 }
0917
0918 return 0;
0919 }
0920
0921 struct snd_ice1712_card_info snd_vt1724_phase_cards[] = {
0922 {
0923 .subvendor = VT1724_SUBDEVICE_PHASE22,
0924 .name = "Terratec PHASE 22",
0925 .model = "phase22",
0926 .chip_init = phase22_init,
0927 .build_controls = phase22_add_controls,
0928 .eeprom_size = sizeof(phase22_eeprom),
0929 .eeprom_data = phase22_eeprom,
0930 },
0931 {
0932 .subvendor = VT1724_SUBDEVICE_PHASE28,
0933 .name = "Terratec PHASE 28",
0934 .model = "phase28",
0935 .chip_init = phase28_init,
0936 .build_controls = phase28_add_controls,
0937 .eeprom_size = sizeof(phase28_eeprom),
0938 .eeprom_data = phase28_eeprom,
0939 },
0940 {
0941 .subvendor = VT1724_SUBDEVICE_TS22,
0942 .name = "Terrasoniq TS22 PCI",
0943 .model = "TS22",
0944 .chip_init = phase22_init,
0945 .build_controls = phase22_add_controls,
0946 .eeprom_size = sizeof(phase22_eeprom),
0947 .eeprom_data = phase22_eeprom,
0948 },
0949 { }
0950 };