aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712/aureon.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ice1712/aureon.c')
-rw-r--r--sound/pci/ice1712/aureon.c130
1 files changed, 88 insertions, 42 deletions
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 8809812a1c22..7e6608b14abc 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -53,6 +53,8 @@
53#include <linux/interrupt.h> 53#include <linux/interrupt.h>
54#include <linux/init.h> 54#include <linux/init.h>
55#include <linux/slab.h> 55#include <linux/slab.h>
56#include <linux/mutex.h>
57
56#include <sound/core.h> 58#include <sound/core.h>
57 59
58#include "ice1712.h" 60#include "ice1712.h"
@@ -210,14 +212,14 @@ static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
210 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 212 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
211 unsigned short vol; 213 unsigned short vol;
212 214
213 down(&ice->gpio_mutex); 215 mutex_lock(&ice->gpio_mutex);
214 216
215 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); 217 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
216 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F); 218 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
217 if (kcontrol->private_value & AUREON_AC97_STEREO) 219 if (kcontrol->private_value & AUREON_AC97_STEREO)
218 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F); 220 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
219 221
220 up(&ice->gpio_mutex); 222 mutex_unlock(&ice->gpio_mutex);
221 return 0; 223 return 0;
222} 224}
223 225
@@ -252,11 +254,11 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
252{ 254{
253 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 255 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
254 256
255 down(&ice->gpio_mutex); 257 mutex_lock(&ice->gpio_mutex);
256 258
257 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; 259 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
258 260
259 up(&ice->gpio_mutex); 261 mutex_unlock(&ice->gpio_mutex);
260 return 0; 262 return 0;
261} 263}
262 264
@@ -288,11 +290,11 @@ static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ct
288{ 290{
289 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 291 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
290 292
291 down(&ice->gpio_mutex); 293 mutex_lock(&ice->gpio_mutex);
292 294
293 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1; 295 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
294 296
295 up(&ice->gpio_mutex); 297 mutex_unlock(&ice->gpio_mutex);
296 return 0; 298 return 0;
297} 299}
298 300
@@ -322,36 +324,48 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned
322{ 324{
323 unsigned int tmp; 325 unsigned int tmp;
324 int i; 326 int i;
327 unsigned int mosi, clk;
325 328
326 tmp = snd_ice1712_gpio_read(ice); 329 tmp = snd_ice1712_gpio_read(ice);
327 330
328 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| 331 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) {
329 AUREON_WM_CS|AUREON_CS8415_CS)); 332 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
330 tmp |= AUREON_WM_RW; 333 mosi = PRODIGY_SPI_MOSI;
334 clk = PRODIGY_SPI_CLK;
335 }
336 else {
337 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
338 AUREON_WM_CS|AUREON_CS8415_CS));
339 mosi = AUREON_SPI_MOSI;
340 clk = AUREON_SPI_CLK;
341
342 tmp |= AUREON_WM_RW;
343 }
344
331 tmp &= ~cs; 345 tmp &= ~cs;
332 snd_ice1712_gpio_write(ice, tmp); 346 snd_ice1712_gpio_write(ice, tmp);
333 udelay(1); 347 udelay(1);
334 348
335 for (i = bits - 1; i >= 0; i--) { 349 for (i = bits - 1; i >= 0; i--) {
336 tmp &= ~AUREON_SPI_CLK; 350 tmp &= ~clk;
337 snd_ice1712_gpio_write(ice, tmp); 351 snd_ice1712_gpio_write(ice, tmp);
338 udelay(1); 352 udelay(1);
339 if (data & (1 << i)) 353 if (data & (1 << i))
340 tmp |= AUREON_SPI_MOSI; 354 tmp |= mosi;
341 else 355 else
342 tmp &= ~AUREON_SPI_MOSI; 356 tmp &= ~mosi;
343 snd_ice1712_gpio_write(ice, tmp); 357 snd_ice1712_gpio_write(ice, tmp);
344 udelay(1); 358 udelay(1);
345 tmp |= AUREON_SPI_CLK; 359 tmp |= clk;
346 snd_ice1712_gpio_write(ice, tmp); 360 snd_ice1712_gpio_write(ice, tmp);
347 udelay(1); 361 udelay(1);
348 } 362 }
349 363
350 tmp &= ~AUREON_SPI_CLK; 364 tmp &= ~clk;
351 tmp |= cs; 365 tmp |= cs;
352 snd_ice1712_gpio_write(ice, tmp); 366 snd_ice1712_gpio_write(ice, tmp);
353 udelay(1); 367 udelay(1);
354 tmp |= AUREON_SPI_CLK; 368 tmp |= clk;
355 snd_ice1712_gpio_write(ice, tmp); 369 snd_ice1712_gpio_write(ice, tmp);
356 udelay(1); 370 udelay(1);
357} 371}
@@ -440,7 +454,9 @@ static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
440 */ 454 */
441static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) 455static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
442{ 456{
443 aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16); 457 aureon_spi_write(ice,
458 (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS),
459 (reg << 9) | (val & 0x1ff), 16);
444} 460}
445 461
446/* 462/*
@@ -474,11 +490,11 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
474{ 490{
475 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 491 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
476 492
477 down(&ice->gpio_mutex); 493 mutex_lock(&ice->gpio_mutex);
478 494
479 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01; 495 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
480 496
481 up(&ice->gpio_mutex); 497 mutex_unlock(&ice->gpio_mutex);
482 return 0; 498 return 0;
483} 499}
484 500
@@ -543,9 +559,9 @@ static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
543{ 559{
544 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 560 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
545 561
546 down(&ice->gpio_mutex); 562 mutex_lock(&ice->gpio_mutex);
547 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; 563 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
548 up(&ice->gpio_mutex); 564 mutex_unlock(&ice->gpio_mutex);
549 return 0; 565 return 0;
550} 566}
551 567
@@ -768,11 +784,11 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
768 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 784 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
769 unsigned short val; 785 unsigned short val;
770 786
771 down(&ice->gpio_mutex); 787 mutex_lock(&ice->gpio_mutex);
772 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; 788 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
773 val = val > PCM_MIN ? (val - PCM_MIN) : 0; 789 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
774 ucontrol->value.integer.value[0] = val; 790 ucontrol->value.integer.value[0] = val;
775 up(&ice->gpio_mutex); 791 mutex_unlock(&ice->gpio_mutex);
776 return 0; 792 return 0;
777} 793}
778 794
@@ -813,12 +829,12 @@ static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
813 unsigned short val; 829 unsigned short val;
814 int i; 830 int i;
815 831
816 down(&ice->gpio_mutex); 832 mutex_lock(&ice->gpio_mutex);
817 for (i = 0; i < 2; i++) { 833 for (i = 0; i < 2; i++) {
818 val = wm_get(ice, WM_ADC_GAIN + i); 834 val = wm_get(ice, WM_ADC_GAIN + i);
819 ucontrol->value.integer.value[i] = ~val>>5 & 0x1; 835 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
820 } 836 }
821 up(&ice->gpio_mutex); 837 mutex_unlock(&ice->gpio_mutex);
822 return 0; 838 return 0;
823} 839}
824 840
@@ -860,13 +876,13 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
860 int i, idx; 876 int i, idx;
861 unsigned short vol; 877 unsigned short vol;
862 878
863 down(&ice->gpio_mutex); 879 mutex_lock(&ice->gpio_mutex);
864 for (i = 0; i < 2; i++) { 880 for (i = 0; i < 2; i++) {
865 idx = WM_ADC_GAIN + i; 881 idx = WM_ADC_GAIN + i;
866 vol = wm_get(ice, idx) & 0x1f; 882 vol = wm_get(ice, idx) & 0x1f;
867 ucontrol->value.integer.value[i] = vol; 883 ucontrol->value.integer.value[i] = vol;
868 } 884 }
869 up(&ice->gpio_mutex); 885 mutex_unlock(&ice->gpio_mutex);
870 return 0; 886 return 0;
871} 887}
872 888
@@ -937,11 +953,11 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
937 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 953 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
938 unsigned short val; 954 unsigned short val;
939 955
940 down(&ice->gpio_mutex); 956 mutex_lock(&ice->gpio_mutex);
941 val = wm_get(ice, WM_ADC_MUX); 957 val = wm_get(ice, WM_ADC_MUX);
942 ucontrol->value.integer.value[0] = val & 7; 958 ucontrol->value.enumerated.item[0] = val & 7;
943 ucontrol->value.integer.value[1] = (val >> 4) & 7; 959 ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
944 up(&ice->gpio_mutex); 960 mutex_unlock(&ice->gpio_mutex);
945 return 0; 961 return 0;
946} 962}
947 963
@@ -954,8 +970,8 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
954 snd_ice1712_save_gpio_status(ice); 970 snd_ice1712_save_gpio_status(ice);
955 oval = wm_get(ice, WM_ADC_MUX); 971 oval = wm_get(ice, WM_ADC_MUX);
956 nval = oval & ~0x77; 972 nval = oval & ~0x77;
957 nval |= ucontrol->value.integer.value[0] & 7; 973 nval |= ucontrol->value.enumerated.item[0] & 7;
958 nval |= (ucontrol->value.integer.value[1] & 7) << 4; 974 nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
959 change = (oval != nval); 975 change = (oval != nval);
960 if (change) 976 if (change)
961 wm_put(ice, WM_ADC_MUX, nval); 977 wm_put(ice, WM_ADC_MUX, nval);
@@ -995,7 +1011,7 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
995 1011
996 //snd_ice1712_save_gpio_status(ice); 1012 //snd_ice1712_save_gpio_status(ice);
997 //val = aureon_cs8415_get(ice, CS8415_CTRL2); 1013 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
998 ucontrol->value.integer.value[0] = ice->spec.aureon.cs8415_mux; 1014 ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux;
999 //snd_ice1712_restore_gpio_status(ice); 1015 //snd_ice1712_restore_gpio_status(ice);
1000 return 0; 1016 return 0;
1001} 1017}
@@ -1009,12 +1025,12 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1009 snd_ice1712_save_gpio_status(ice); 1025 snd_ice1712_save_gpio_status(ice);
1010 oval = aureon_cs8415_get(ice, CS8415_CTRL2); 1026 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1011 nval = oval & ~0x07; 1027 nval = oval & ~0x07;
1012 nval |= ucontrol->value.integer.value[0] & 7; 1028 nval |= ucontrol->value.enumerated.item[0] & 7;
1013 change = (oval != nval); 1029 change = (oval != nval);
1014 if (change) 1030 if (change)
1015 aureon_cs8415_put(ice, CS8415_CTRL2, nval); 1031 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1016 snd_ice1712_restore_gpio_status(ice); 1032 snd_ice1712_restore_gpio_status(ice);
1017 ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0]; 1033 ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0];
1018 return change; 1034 return change;
1019} 1035}
1020 1036
@@ -1659,7 +1675,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1659 return err; 1675 return err;
1660 } 1676 }
1661 } 1677 }
1662 else { 1678 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1663 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { 1679 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1664 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); 1680 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1665 if (err < 0) 1681 if (err < 0)
@@ -1667,7 +1683,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1667 } 1683 }
1668 } 1684 }
1669 1685
1670 { 1686 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1671 unsigned char id; 1687 unsigned char id;
1672 snd_ice1712_save_gpio_status(ice); 1688 snd_ice1712_save_gpio_status(ice);
1673 id = aureon_cs8415_get(ice, CS8415_ID); 1689 id = aureon_cs8415_get(ice, CS8415_ID);
@@ -1822,7 +1838,8 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
1822 udelay(1); 1838 udelay(1);
1823 1839
1824 /* initialize WM8770 codec */ 1840 /* initialize WM8770 codec */
1825 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) 1841 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
1842 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT)
1826 p = wm_inits_prodigy; 1843 p = wm_inits_prodigy;
1827 else 1844 else
1828 p = wm_inits_aureon; 1845 p = wm_inits_aureon;
@@ -1830,11 +1847,13 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
1830 wm_put(ice, p[0], p[1]); 1847 wm_put(ice, p[0], p[1]);
1831 1848
1832 /* initialize CS8415A codec */ 1849 /* initialize CS8415A codec */
1833 for (p = cs_inits; *p != (unsigned short)-1; p++) 1850 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1834 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); 1851 for (p = cs_inits; *p != (unsigned short)-1; p++)
1835 ice->spec.aureon.cs8415_mux = 1; 1852 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
1853 ice->spec.aureon.cs8415_mux = 1;
1836 1854
1837 aureon_set_headphone_amp(ice, 1); 1855 aureon_set_headphone_amp(ice, 1);
1856 }
1838 1857
1839 snd_ice1712_restore_gpio_status(ice); 1858 snd_ice1712_restore_gpio_status(ice);
1840 1859
@@ -1902,6 +1921,23 @@ static unsigned char prodigy71_eeprom[] __devinitdata = {
1902 0x00, /* GPIO_STATE2 */ 1921 0x00, /* GPIO_STATE2 */
1903}; 1922};
1904 1923
1924static unsigned char prodigy71lt_eeprom[] __devinitdata = {
1925 0x0b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
1926 0x80, /* ACLINK: I2S */
1927 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1928 0xc3, /* SPDUF: out-en, out-int */
1929 0x00, /* GPIO_DIR */
1930 0x07, /* GPIO_DIR1 */
1931 0x00, /* GPIO_DIR2 */
1932 0xff, /* GPIO_MASK */
1933 0xf8, /* GPIO_MASK1 */
1934 0xff, /* GPIO_MASK2 */
1935 0x00, /* GPIO_STATE */
1936 0x00, /* GPIO_STATE1 */
1937 0x00, /* GPIO_STATE2 */
1938};
1939
1940
1905/* entry point */ 1941/* entry point */
1906struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { 1942struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
1907 { 1943 {
@@ -1944,5 +1980,15 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
1944 .eeprom_data = prodigy71_eeprom, 1980 .eeprom_data = prodigy71_eeprom,
1945 .driver = "Prodigy71", /* should be identical with Aureon71 */ 1981 .driver = "Prodigy71", /* should be identical with Aureon71 */
1946 }, 1982 },
1983 {
1984 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
1985 .name = "Audiotrak Prodigy 7.1 LT",
1986 .model = "prodigy71lt",
1987 .chip_init = aureon_init,
1988 .build_controls = aureon_add_controls,
1989 .eeprom_size = sizeof(prodigy71lt_eeprom),
1990 .eeprom_data = prodigy71lt_eeprom,
1991 .driver = "Prodigy71LT",
1992 },
1947 { } /* terminator */ 1993 { } /* terminator */
1948}; 1994};