diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2008-06-09 17:07:28 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-06-13 10:47:33 -0400 |
commit | abf1f5aafc1939db1f252e33914a3689e0f5830f (patch) | |
tree | cd459744443de51e5ffead43215e541653c98fe7 /sound | |
parent | a6a950a8a8e1431e8527809339e089ac926a7d34 (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>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/isa/cs423x/cs4231_lib.c | 118 |
1 files changed, 109 insertions, 9 deletions
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 | ||
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 | * 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 | ||
898 | static void snd_cs4231_overrange(struct snd_cs4231 *chip) | 934 | void 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), | |||
1790 | CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1) | 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 | int snd_cs4231_mixer(struct snd_cs4231 *chip) | 1880 | int 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); | |||
1815 | EXPORT_SYMBOL(snd_cs4236_ext_in); | 1914 | EXPORT_SYMBOL(snd_cs4236_ext_in); |
1816 | EXPORT_SYMBOL(snd_cs4231_mce_up); | 1915 | EXPORT_SYMBOL(snd_cs4231_mce_up); |
1817 | EXPORT_SYMBOL(snd_cs4231_mce_down); | 1916 | EXPORT_SYMBOL(snd_cs4231_mce_down); |
1917 | EXPORT_SYMBOL(snd_cs4231_overrange); | ||
1818 | EXPORT_SYMBOL(snd_cs4231_interrupt); | 1918 | EXPORT_SYMBOL(snd_cs4231_interrupt); |
1819 | EXPORT_SYMBOL(snd_cs4231_chip_id); | 1919 | EXPORT_SYMBOL(snd_cs4231_chip_id); |
1820 | EXPORT_SYMBOL(snd_cs4231_create); | 1920 | EXPORT_SYMBOL(snd_cs4231_create); |