Commit abf1f5aafc1939db1f252e33914a3689e0f5830f

Authored by Krzysztof Helt
Committed by Jaroslav Kysela
1 parent a6a950a8a8

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);