Commit abf1f5aafc1939db1f252e33914a3689e0f5830f
Committed by
Jaroslav Kysela
1 parent
a6a950a8a8
Exists in
master
and in
7 other branches
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>
Showing 3 changed files with 120 additions and 9 deletions Side-by-side Diff
include/sound/cs4231-regs.h
... | ... | @@ -177,5 +177,13 @@ |
177 | 177 | #define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */ |
178 | 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 | 188 | #endif /* __SOUND_CS4231_REGS_H */ |
include/sound/cs4231.h
... | ... | @@ -58,6 +58,7 @@ |
58 | 58 | /* compatible, but clones */ |
59 | 59 | #define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */ |
60 | 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 | 63 | /* defines for codec.hwshare */ |
63 | 64 | #define CS4231_HWSHARE_IRQ (1<<0) |
... | ... | @@ -119,6 +120,8 @@ |
119 | 120 | unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg); |
120 | 121 | void snd_cs4231_mce_up(struct snd_cs4231 *chip); |
121 | 122 | void snd_cs4231_mce_down(struct snd_cs4231 *chip); |
123 | + | |
124 | +void snd_cs4231_overrange(struct snd_cs4231 *chip); | |
122 | 125 | |
123 | 126 | irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id); |
124 | 127 |
sound/isa/cs423x/cs4231_lib.c
... | ... | @@ -119,6 +119,42 @@ |
119 | 119 | 0x00, /* 1f/31 - cbrl */ |
120 | 120 | }; |
121 | 121 | |
122 | +static 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 | 159 | * Basic I/O functions |
124 | 160 | */ |
... | ... | @@ -895,7 +931,7 @@ |
895 | 931 | return 0; |
896 | 932 | } |
897 | 933 | |
898 | -static void snd_cs4231_overrange(struct snd_cs4231 *chip) | |
934 | +void snd_cs4231_overrange(struct snd_cs4231 *chip) | |
899 | 935 | { |
900 | 936 | unsigned long flags; |
901 | 937 | unsigned char res; |
... | ... | @@ -1054,8 +1090,11 @@ |
1054 | 1090 | chip->image[CS4231_IFACE_CTRL] = |
1055 | 1091 | (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) | |
1056 | 1092 | (chip->single_dma ? CS4231_SINGLE_DMA : 0); |
1057 | - chip->image[CS4231_ALT_FEATURE_1] = 0x80; | |
1058 | - chip->image[CS4231_ALT_FEATURE_2] = chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01; | |
1093 | + if (chip->hardware != CS4231_HW_OPTI93X) { | |
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 | 1098 | ptr = (unsigned char *) &chip->image; |
1060 | 1099 | snd_cs4231_mce_down(chip); |
1061 | 1100 | spin_lock_irqsave(&chip->reg_lock, flags); |
... | ... | @@ -1376,6 +1415,7 @@ |
1376 | 1415 | case CS4231_HW_INTERWAVE: return "AMD InterWave"; |
1377 | 1416 | case CS4231_HW_OPL3SA2: return chip->card->shortname; |
1378 | 1417 | case CS4231_HW_AD1845: return "AD1845"; |
1418 | + case CS4231_HW_OPTI93X: return "OPTi 93x"; | |
1379 | 1419 | default: return "???"; |
1380 | 1420 | } |
1381 | 1421 | } |
... | ... | @@ -1401,8 +1441,13 @@ |
1401 | 1441 | chip->rate_constraint = snd_cs4231_xrate; |
1402 | 1442 | chip->set_playback_format = snd_cs4231_playback_format; |
1403 | 1443 | chip->set_capture_format = snd_cs4231_capture_format; |
1404 | - memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); | |
1405 | - | |
1444 | + if (chip->hardware == CS4231_HW_OPTI93X) | |
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 | 1451 | *rchip = chip; |
1407 | 1452 | return 0; |
1408 | 1453 | } |
... | ... | @@ -1790,6 +1835,48 @@ |
1790 | 1835 | CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) |
1791 | 1836 | }; |
1792 | 1837 | |
1838 | +static struct snd_kcontrol_new snd_opti93x_controls[] = { | |
1839 | +CS4231_DOUBLE("Master Playback Switch", 0, | |
1840 | + OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), | |
1841 | +CS4231_DOUBLE("Master Playback Volume", 0, | |
1842 | + OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), | |
1843 | +CS4231_DOUBLE("PCM Playback Switch", 0, | |
1844 | + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), | |
1845 | +CS4231_DOUBLE("PCM Playback Volume", 0, | |
1846 | + CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1), | |
1847 | +CS4231_DOUBLE("FM Playback Switch", 0, | |
1848 | + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), | |
1849 | +CS4231_DOUBLE("FM Playback Volume", 0, | |
1850 | + CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1), | |
1851 | +CS4231_DOUBLE("Line Playback Switch", 0, | |
1852 | + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), | |
1853 | +CS4231_DOUBLE("Line Playback Volume", 0, | |
1854 | + CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1), | |
1855 | +CS4231_DOUBLE("Mic Playback Switch", 0, | |
1856 | + OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), | |
1857 | +CS4231_DOUBLE("Mic Playback Volume", 0, | |
1858 | + OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1), | |
1859 | +CS4231_DOUBLE("Mic Boost", 0, | |
1860 | + CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), | |
1861 | +CS4231_DOUBLE("CD Playback Switch", 0, | |
1862 | + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), | |
1863 | +CS4231_DOUBLE("CD Playback Volume", 0, | |
1864 | + CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1), | |
1865 | +CS4231_DOUBLE("Aux Playback Switch", 0, | |
1866 | + OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1), | |
1867 | +CS4231_DOUBLE("Aux Playback Volume", 0, | |
1868 | + OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1), | |
1869 | +CS4231_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 | + | |
1793 | 1880 | int snd_cs4231_mixer(struct snd_cs4231 *chip) |
1794 | 1881 | { |
1795 | 1882 | struct snd_card *card; |
... | ... | @@ -1802,10 +1889,22 @@ |
1802 | 1889 | |
1803 | 1890 | strcpy(card->mixername, chip->pcm->name); |
1804 | 1891 | |
1805 | - for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { | |
1806 | - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4231_controls[idx], chip))) < 0) | |
1807 | - return err; | |
1808 | - } | |
1892 | + if (chip->hardware == CS4231_HW_OPTI93X) | |
1893 | + for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { | |
1894 | + err = snd_ctl_add(card, | |
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 | 1908 | return 0; |
1810 | 1909 | } |
1811 | 1910 | |
... | ... | @@ -1815,6 +1914,7 @@ |
1815 | 1914 | EXPORT_SYMBOL(snd_cs4236_ext_in); |
1816 | 1915 | EXPORT_SYMBOL(snd_cs4231_mce_up); |
1817 | 1916 | EXPORT_SYMBOL(snd_cs4231_mce_down); |
1917 | +EXPORT_SYMBOL(snd_cs4231_overrange); | |
1818 | 1918 | EXPORT_SYMBOL(snd_cs4231_interrupt); |
1819 | 1919 | EXPORT_SYMBOL(snd_cs4231_chip_id); |
1820 | 1920 | EXPORT_SYMBOL(snd_cs4231_create); |