aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2008-06-09 17:07:28 -0400
committerJaroslav Kysela <perex@perex.cz>2008-06-13 10:47:33 -0400
commitabf1f5aafc1939db1f252e33914a3689e0f5830f (patch)
treecd459744443de51e5ffead43215e541653c98fe7
parenta6a950a8a8e1431e8527809339e089ac926a7d34 (diff)
ALSA: opti93x: add support for Opti93x codec in cs4231-lib
This patch adds support for WSS compatible Opti93x codec to the cs4231-lib. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Tested-by: Rene Herman <rene.herman@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--include/sound/cs4231-regs.h8
-rw-r--r--include/sound/cs4231.h3
-rw-r--r--sound/isa/cs423x/cs4231_lib.c118
3 files changed, 120 insertions, 9 deletions
diff --git a/include/sound/cs4231-regs.h b/include/sound/cs4231-regs.h
index e8d1f3e31f9e..92647532c454 100644
--- a/include/sound/cs4231-regs.h
+++ b/include/sound/cs4231-regs.h
@@ -177,4 +177,12 @@
177#define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */ 177#define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */
178#define CS4236_VERSION 0x9c /* chip version and ID */ 178#define CS4236_VERSION 0x9c /* chip version and ID */
179 179
180/* definitions for extended registers - OPTI93X */
181#define OPTi931_AUX_LEFT_INPUT 0x10
182#define OPTi931_AUX_RIGHT_INPUT 0x11
183#define OPTi93X_MIC_LEFT_INPUT 0x14
184#define OPTi93X_MIC_RIGHT_INPUT 0x15
185#define OPTi93X_OUT_LEFT 0x16
186#define OPTi93X_OUT_RIGHT 0x17
187
180#endif /* __SOUND_CS4231_REGS_H */ 188#endif /* __SOUND_CS4231_REGS_H */
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h
index 66055d702aa3..f0785f9f4ae4 100644
--- a/include/sound/cs4231.h
+++ b/include/sound/cs4231.h
@@ -58,6 +58,7 @@
58/* compatible, but clones */ 58/* compatible, but clones */
59#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */ 59#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */
60#define CS4231_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */ 60#define CS4231_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */
61#define CS4231_HW_OPTI93X 0x1102 /* Opti 930/931/933 */
61 62
62/* defines for codec.hwshare */ 63/* defines for codec.hwshare */
63#define CS4231_HWSHARE_IRQ (1<<0) 64#define CS4231_HWSHARE_IRQ (1<<0)
@@ -120,6 +121,8 @@ unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg);
120void snd_cs4231_mce_up(struct snd_cs4231 *chip); 121void snd_cs4231_mce_up(struct snd_cs4231 *chip);
121void snd_cs4231_mce_down(struct snd_cs4231 *chip); 122void snd_cs4231_mce_down(struct snd_cs4231 *chip);
122 123
124void snd_cs4231_overrange(struct snd_cs4231 *chip);
125
123irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id); 126irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id);
124 127
125const char *snd_cs4231_chip_id(struct snd_cs4231 *chip); 128const char *snd_cs4231_chip_id(struct snd_cs4231 *chip);
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 0aa8649e5c7f..521db705d179 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -119,6 +119,42 @@ static unsigned char snd_cs4231_original_image[32] =
119 0x00, /* 1f/31 - cbrl */ 119 0x00, /* 1f/31 - cbrl */
120}; 120};
121 121
122static unsigned char snd_opti93x_original_image[32] =
123{
124 0x00, /* 00/00 - l_mixout_outctrl */
125 0x00, /* 01/01 - r_mixout_outctrl */
126 0x88, /* 02/02 - l_cd_inctrl */
127 0x88, /* 03/03 - r_cd_inctrl */
128 0x88, /* 04/04 - l_a1/fm_inctrl */
129 0x88, /* 05/05 - r_a1/fm_inctrl */
130 0x80, /* 06/06 - l_dac_inctrl */
131 0x80, /* 07/07 - r_dac_inctrl */
132 0x00, /* 08/08 - ply_dataform_reg */
133 0x00, /* 09/09 - if_conf */
134 0x00, /* 0a/10 - pin_ctrl */
135 0x00, /* 0b/11 - err_init_reg */
136 0x0a, /* 0c/12 - id_reg */
137 0x00, /* 0d/13 - reserved */
138 0x00, /* 0e/14 - ply_upcount_reg */
139 0x00, /* 0f/15 - ply_lowcount_reg */
140 0x88, /* 10/16 - reserved/l_a1_inctrl */
141 0x88, /* 11/17 - reserved/r_a1_inctrl */
142 0x88, /* 12/18 - l_line_inctrl */
143 0x88, /* 13/19 - r_line_inctrl */
144 0x88, /* 14/20 - l_mic_inctrl */
145 0x88, /* 15/21 - r_mic_inctrl */
146 0x80, /* 16/22 - l_out_outctrl */
147 0x80, /* 17/23 - r_out_outctrl */
148 0x00, /* 18/24 - reserved */
149 0x00, /* 19/25 - reserved */
150 0x00, /* 1a/26 - reserved */
151 0x00, /* 1b/27 - reserved */
152 0x00, /* 1c/28 - cap_dataform_reg */
153 0x00, /* 1d/29 - reserved */
154 0x00, /* 1e/30 - cap_upcount_reg */
155 0x00 /* 1f/31 - cap_lowcount_reg */
156};
157
122/* 158/*
123 * Basic I/O functions 159 * Basic I/O functions
124 */ 160 */
@@ -895,7 +931,7 @@ static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
895 return 0; 931 return 0;
896} 932}
897 933
898static void snd_cs4231_overrange(struct snd_cs4231 *chip) 934void snd_cs4231_overrange(struct snd_cs4231 *chip)
899{ 935{
900 unsigned long flags; 936 unsigned long flags;
901 unsigned char res; 937 unsigned char res;
@@ -1054,8 +1090,11 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip)
1054 chip->image[CS4231_IFACE_CTRL] = 1090 chip->image[CS4231_IFACE_CTRL] =
1055 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) | 1091 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1056 (chip->single_dma ? CS4231_SINGLE_DMA : 0); 1092 (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1057 chip->image[CS4231_ALT_FEATURE_1] = 0x80; 1093 if (chip->hardware != CS4231_HW_OPTI93X) {
1058 chip->image[CS4231_ALT_FEATURE_2] = chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01; 1094 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1095 chip->image[CS4231_ALT_FEATURE_2] =
1096 chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01;
1097 }
1059 ptr = (unsigned char *) &chip->image; 1098 ptr = (unsigned char *) &chip->image;
1060 snd_cs4231_mce_down(chip); 1099 snd_cs4231_mce_down(chip);
1061 spin_lock_irqsave(&chip->reg_lock, flags); 1100 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1376,6 +1415,7 @@ const char *snd_cs4231_chip_id(struct snd_cs4231 *chip)
1376 case CS4231_HW_INTERWAVE: return "AMD InterWave"; 1415 case CS4231_HW_INTERWAVE: return "AMD InterWave";
1377 case CS4231_HW_OPL3SA2: return chip->card->shortname; 1416 case CS4231_HW_OPL3SA2: return chip->card->shortname;
1378 case CS4231_HW_AD1845: return "AD1845"; 1417 case CS4231_HW_AD1845: return "AD1845";
1418 case CS4231_HW_OPTI93X: return "OPTi 93x";
1379 default: return "???"; 1419 default: return "???";
1380 } 1420 }
1381} 1421}
@@ -1401,8 +1441,13 @@ static int snd_cs4231_new(struct snd_card *card,
1401 chip->rate_constraint = snd_cs4231_xrate; 1441 chip->rate_constraint = snd_cs4231_xrate;
1402 chip->set_playback_format = snd_cs4231_playback_format; 1442 chip->set_playback_format = snd_cs4231_playback_format;
1403 chip->set_capture_format = snd_cs4231_capture_format; 1443 chip->set_capture_format = snd_cs4231_capture_format;
1404 memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); 1444 if (chip->hardware == CS4231_HW_OPTI93X)
1405 1445 memcpy(&chip->image, &snd_opti93x_original_image,
1446 sizeof(snd_opti93x_original_image));
1447 else
1448 memcpy(&chip->image, &snd_cs4231_original_image,
1449 sizeof(snd_cs4231_original_image));
1450
1406 *rchip = chip; 1451 *rchip = chip;
1407 return 0; 1452 return 0;
1408} 1453}
@@ -1790,6 +1835,48 @@ CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
1790CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) 1835CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1)
1791}; 1836};
1792 1837
1838static struct snd_kcontrol_new snd_opti93x_controls[] = {
1839CS4231_DOUBLE("Master Playback Switch", 0,
1840 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
1841CS4231_DOUBLE("Master Playback Volume", 0,
1842 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
1843CS4231_DOUBLE("PCM Playback Switch", 0,
1844 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
1845CS4231_DOUBLE("PCM Playback Volume", 0,
1846 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
1847CS4231_DOUBLE("FM Playback Switch", 0,
1848 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1849CS4231_DOUBLE("FM Playback Volume", 0,
1850 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
1851CS4231_DOUBLE("Line Playback Switch", 0,
1852 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
1853CS4231_DOUBLE("Line Playback Volume", 0,
1854 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
1855CS4231_DOUBLE("Mic Playback Switch", 0,
1856 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
1857CS4231_DOUBLE("Mic Playback Volume", 0,
1858 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
1859CS4231_DOUBLE("Mic Boost", 0,
1860 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
1861CS4231_DOUBLE("CD Playback Switch", 0,
1862 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1863CS4231_DOUBLE("CD Playback Volume", 0,
1864 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
1865CS4231_DOUBLE("Aux Playback Switch", 0,
1866 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
1867CS4231_DOUBLE("Aux Playback Volume", 0,
1868 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
1869CS4231_DOUBLE("Capture Volume", 0,
1870 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
1871{
1872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1873 .name = "Capture Source",
1874 .info = snd_cs4231_info_mux,
1875 .get = snd_cs4231_get_mux,
1876 .put = snd_cs4231_put_mux,
1877}
1878};
1879
1793int snd_cs4231_mixer(struct snd_cs4231 *chip) 1880int snd_cs4231_mixer(struct snd_cs4231 *chip)
1794{ 1881{
1795 struct snd_card *card; 1882 struct snd_card *card;
@@ -1802,10 +1889,22 @@ int snd_cs4231_mixer(struct snd_cs4231 *chip)
1802 1889
1803 strcpy(card->mixername, chip->pcm->name); 1890 strcpy(card->mixername, chip->pcm->name);
1804 1891
1805 for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { 1892 if (chip->hardware == CS4231_HW_OPTI93X)
1806 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4231_controls[idx], chip))) < 0) 1893 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
1807 return err; 1894 err = snd_ctl_add(card,
1808 } 1895 snd_ctl_new1(&snd_opti93x_controls[idx],
1896 chip));
1897 if (err < 0)
1898 return err;
1899 }
1900 else
1901 for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) {
1902 err = snd_ctl_add(card,
1903 snd_ctl_new1(&snd_cs4231_controls[idx],
1904 chip));
1905 if (err < 0)
1906 return err;
1907 }
1809 return 0; 1908 return 0;
1810} 1909}
1811 1910
@@ -1815,6 +1914,7 @@ EXPORT_SYMBOL(snd_cs4236_ext_out);
1815EXPORT_SYMBOL(snd_cs4236_ext_in); 1914EXPORT_SYMBOL(snd_cs4236_ext_in);
1816EXPORT_SYMBOL(snd_cs4231_mce_up); 1915EXPORT_SYMBOL(snd_cs4231_mce_up);
1817EXPORT_SYMBOL(snd_cs4231_mce_down); 1916EXPORT_SYMBOL(snd_cs4231_mce_down);
1917EXPORT_SYMBOL(snd_cs4231_overrange);
1818EXPORT_SYMBOL(snd_cs4231_interrupt); 1918EXPORT_SYMBOL(snd_cs4231_interrupt);
1819EXPORT_SYMBOL(snd_cs4231_chip_id); 1919EXPORT_SYMBOL(snd_cs4231_chip_id);
1820EXPORT_SYMBOL(snd_cs4231_create); 1920EXPORT_SYMBOL(snd_cs4231_create);