61 #include <linux/slab.h>
76 static inline void stac9460_put(
struct snd_ice1712 *ice,
int reg,
unsigned char val)
81 static inline unsigned char stac9460_get(
struct snd_ice1712 *ice,
int reg)
96 unsigned char new, old;
98 old = stac9460_get(ice, idx);
99 new = (~mute << 7 & 0x80) | (old & ~0x80);
100 change = (
new != old);
103 stac9460_put(ice, idx,
new);
107 #define stac9460_dac_mute_info snd_ctl_boolean_mono_info
119 val = stac9460_get(ice, idx);
120 ucontrol->
value.integer.value[0] = (~val >> 7) & 0x1;
140 change = stac9460_dac_mute(ice, idx, ucontrol->
value.integer.value[0]);
167 vol = stac9460_get(ice, idx) & 0x7f;
168 ucontrol->
value.integer.value[0] = 0x7f -
vol;
177 unsigned char tmp, ovol, nvol;
184 nvol = ucontrol->
value.integer.value[0];
185 tmp = stac9460_get(ice, idx);
186 ovol = 0x7f - (tmp & 0x7f);
187 change = (ovol != nvol);
189 ovol = (0x7f - nvol) | (tmp & 0x80);
194 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
202 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
210 for (i = 0; i < 2; ++
i) {
212 ucontrol->
value.integer.value[
i] = ~val>>7 & 0x1;
221 unsigned char new, old;
225 for (i = 0; i < 2; ++
i) {
227 old = stac9460_get(ice, reg);
228 new = (~ucontrol->
value.integer.value[
i]<<7&0x80) | (old&~0x80);
229 change = (
new != old);
231 stac9460_put(ice, reg,
new);
255 for (i = 0; i < 2; ++
i) {
257 vol = stac9460_get(ice, reg) & 0x0f;
258 ucontrol->
value.integer.value[
i] = 0x0f -
vol;
268 unsigned char ovol, nvol;
271 for (i = 0; i < 2; ++
i) {
273 nvol = ucontrol->
value.integer.value[
i] & 0x0f;
274 ovol = 0x0f - stac9460_get(ice, reg);
275 change = ((ovol & 0x0f) != nvol);
277 stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
286 static char *texts[2] = {
"Line In",
"Mic" };
300 static int stac9460_mic_sw_get(
struct snd_kcontrol *kcontrol,
307 ucontrol->
value.enumerated.item[0] = (val >> 7) & 0x1;
311 static int stac9460_mic_sw_put(
struct snd_kcontrol *kcontrol,
315 unsigned char new, old;
318 new = (ucontrol->
value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
319 change = (
new != old);
327 static void stac9460_set_rate_val(
struct snd_ice1712 *ice,
unsigned int rate)
329 unsigned char old,
new;
336 else if (rate <= 48000)
338 else if (rate <= 96000)
349 for (idx = 0; idx < 7 ; ++
idx)
350 changed[idx] = stac9460_dac_mute(ice,
357 for (idx = 0; idx < 7 ; ++
idx) {
375 .name =
"Master Playback Switch",
377 .get = stac9460_dac_mute_get,
378 .put = stac9460_dac_mute_put,
380 .tlv = { .p = db_scale_dac }
386 .
name =
"Master Playback Volume",
387 .
info = stac9460_dac_vol_info,
388 .
get = stac9460_dac_vol_get,
389 .
put = stac9460_dac_vol_put,
391 .
tlv = { .p = db_scale_dac }
395 .name =
"DAC Switch",
398 .get = stac9460_dac_mute_get,
399 .put = stac9460_dac_mute_put,
405 .
name =
"DAC Volume",
407 .
info = stac9460_dac_vol_info,
408 .
get = stac9460_dac_vol_get,
409 .
put = stac9460_dac_vol_put,
410 .
tlv = { .p = db_scale_dac }
414 .name =
"ADC Capture Switch",
417 .get = stac9460_adc_mute_get,
418 .put = stac9460_adc_mute_put,
425 .
name =
"ADC Capture Volume",
427 .
info = stac9460_adc_vol_info,
428 .
get = stac9460_adc_vol_get,
429 .
put = stac9460_adc_vol_put,
430 .
tlv = { .p = db_scale_adc }
434 .name =
"Analog Capture Input",
436 .get = stac9460_mic_sw_get,
437 .put = stac9460_mic_sw_put,
448 #define AK4114_ADDR 0x00
456 unsigned int data,
int idx)
458 for (; idx >= 0; idx--) {
461 snd_ice1712_gpio_write(ice, gpio);
464 if (data & (1 << idx))
468 snd_ice1712_gpio_write(ice, gpio);
472 snd_ice1712_gpio_write(ice, gpio);
480 static unsigned char read_data(
struct snd_ice1712 *ice,
unsigned int gpio,
483 unsigned char data = 0;
485 for (; idx >= 0; idx--) {
488 snd_ice1712_gpio_write(ice, gpio);
496 snd_ice1712_gpio_write(ice, gpio);
504 static unsigned int prodigy192_4wire_start(
struct snd_ice1712 *ice)
508 snd_ice1712_save_gpio_status(ice);
509 tmp = snd_ice1712_gpio_read(ice);
513 snd_ice1712_gpio_write(ice, tmp);
521 static void prodigy192_4wire_finish(
struct snd_ice1712 *ice,
unsigned int tmp)
524 snd_ice1712_gpio_write(ice, tmp);
526 snd_ice1712_restore_gpio_status(ice);
536 unsigned int tmp, addrdata;
537 tmp = prodigy192_4wire_start(ice);
538 addrdata = (
AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
539 addrdata = (addrdata << 8) | data;
540 write_data(ice, tmp, addrdata, 15);
541 prodigy192_4wire_finish(ice, tmp);
547 static unsigned char prodigy192_ak4114_read(
void *private_data,
554 tmp = prodigy192_4wire_start(ice);
555 write_data(ice, tmp, (
AK4114_ADDR << 6) | (addr & 0x1f), 7);
556 data = read_data(ice, tmp, 7);
557 prodigy192_4wire_finish(ice, tmp);
562 static int ak4114_input_sw_info(
struct snd_kcontrol *kcontrol,
565 static char *texts[2] = {
"Toslink",
"Coax" };
577 static int ak4114_input_sw_get(
struct snd_kcontrol *kcontrol,
591 static int ak4114_input_sw_put(
struct snd_kcontrol *kcontrol,
595 unsigned char new, old, itemvalue;
600 itemvalue = (ucontrol->
value.enumerated.item[0]) ? 0xff : 0x00;
603 change = (
new != old);
613 .name =
"MIODIO IEC958 Capture Input",
614 .info = ak4114_input_sw_info,
615 .get = ak4114_input_sw_get,
616 .put = ak4114_input_sw_put,
622 static int prodigy192_ak4114_init(
struct snd_ice1712 *ice)
624 static const unsigned char ak4114_init_vals[] = {
635 static const unsigned char ak4114_init_txcsb[] = {
636 0x41, 0x02, 0x2c, 0x00, 0x00
642 prodigy192_ak4114_read,
643 prodigy192_ak4114_write,
644 ak4114_init_vals, ak4114_init_txcsb,
660 for (reg = 0; reg <= 0x15; reg++) {
661 val = stac9460_get(ice, reg);
662 snd_iprintf(buffer,
"0x%02x = 0x%02x\n", reg, val);
667 static void stac9460_proc_init(
struct snd_ice1712 *ice)
670 if (!snd_card_proc_new(ice->
card,
"stac9460_codec", &entry))
671 snd_info_set_text_ops(entry, ice, stac9460_proc_regs_read);
681 for (i = 0; i <
ARRAY_SIZE(stac_controls); i++) {
689 for (i = 0; i <
ARRAY_SIZE(ak4114_controls); i++) {
702 stac9460_proc_init(ice);
709 static int prodigy192_miodio_exists(
struct snd_ice1712 *ice)
712 unsigned char orig_value;
713 const unsigned char test_data = 0xd1;
717 orig_value = prodigy192_ak4114_read(ice, addr);
718 prodigy192_ak4114_write(ice, addr, test_data);
719 if (prodigy192_ak4114_read(ice, addr) == test_data) {
722 prodigy192_ak4114_write(ice, addr, orig_value);
733 static const unsigned short stac_inits_prodigy[] = {
745 const unsigned short *
p;
761 p = stac_inits_prodigy;
762 for (; *p != (
unsigned short)-1; p += 2)
763 stac9460_put(ice, p[0], p[1]);
764 ice->
gpio.set_pro_rate = stac9460_set_rate_val;
767 if (prodigy192_miodio_exists(ice)) {
768 err = prodigy192_ak4114_init(ice);
772 snd_printdd(
"AK4114 initialized with status %d\n", err);
814 .name =
"Audiotrak Prodigy 192",
815 .model =
"prodigy192",
816 .chip_init = prodigy192_init,
817 .build_controls = prodigy192_add_controls,