17779f75fSKrzysztof Helt #ifndef __SOUND_WSS_H 27779f75fSKrzysztof Helt #define __SOUND_WSS_H 361ef19d7SKrzysztof Helt 461ef19d7SKrzysztof Helt /* 561ef19d7SKrzysztof Helt * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 661ef19d7SKrzysztof Helt * Definitions for CS4231 & InterWave chips & compatible chips 761ef19d7SKrzysztof Helt * 861ef19d7SKrzysztof Helt * 961ef19d7SKrzysztof Helt * This program is free software; you can redistribute it and/or modify 1061ef19d7SKrzysztof Helt * it under the terms of the GNU General Public License as published by 1161ef19d7SKrzysztof Helt * the Free Software Foundation; either version 2 of the License, or 1261ef19d7SKrzysztof Helt * (at your option) any later version. 1361ef19d7SKrzysztof Helt * 1461ef19d7SKrzysztof Helt * This program is distributed in the hope that it will be useful, 1561ef19d7SKrzysztof Helt * but WITHOUT ANY WARRANTY; without even the implied warranty of 1661ef19d7SKrzysztof Helt * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1761ef19d7SKrzysztof Helt * GNU General Public License for more details. 1861ef19d7SKrzysztof Helt * 1961ef19d7SKrzysztof Helt * You should have received a copy of the GNU General Public License 2061ef19d7SKrzysztof Helt * along with this program; if not, write to the Free Software 2161ef19d7SKrzysztof Helt * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2261ef19d7SKrzysztof Helt * 2361ef19d7SKrzysztof Helt */ 2461ef19d7SKrzysztof Helt 25a1ce3928SDavid Howells #include <sound/control.h> 26a1ce3928SDavid Howells #include <sound/pcm.h> 27a1ce3928SDavid Howells #include <sound/timer.h> 2861ef19d7SKrzysztof Helt 29a1ce3928SDavid Howells #include <sound/cs4231-regs.h> 3061ef19d7SKrzysztof Helt 3161ef19d7SKrzysztof Helt /* defines for codec.mode */ 3261ef19d7SKrzysztof Helt 337779f75fSKrzysztof Helt #define WSS_MODE_NONE 0x0000 347779f75fSKrzysztof Helt #define WSS_MODE_PLAY 0x0001 357779f75fSKrzysztof Helt #define WSS_MODE_RECORD 0x0002 367779f75fSKrzysztof Helt #define WSS_MODE_TIMER 0x0004 377779f75fSKrzysztof Helt #define WSS_MODE_OPEN (WSS_MODE_PLAY|WSS_MODE_RECORD|WSS_MODE_TIMER) 3861ef19d7SKrzysztof Helt 3961ef19d7SKrzysztof Helt /* defines for codec.hardware */ 4061ef19d7SKrzysztof Helt 417779f75fSKrzysztof Helt #define WSS_HW_DETECT 0x0000 /* let CS4231 driver detect chip */ 427779f75fSKrzysztof Helt #define WSS_HW_DETECT3 0x0001 /* allow mode 3 */ 437779f75fSKrzysztof Helt #define WSS_HW_TYPE_MASK 0xff00 /* type mask */ 447779f75fSKrzysztof Helt #define WSS_HW_CS4231_MASK 0x0100 /* CS4231 serie */ 457779f75fSKrzysztof Helt #define WSS_HW_CS4231 0x0100 /* CS4231 chip */ 467779f75fSKrzysztof Helt #define WSS_HW_CS4231A 0x0101 /* CS4231A chip */ 477779f75fSKrzysztof Helt #define WSS_HW_AD1845 0x0102 /* AD1845 chip */ 487779f75fSKrzysztof Helt #define WSS_HW_CS4232_MASK 0x0200 /* CS4232 serie (has control ports) */ 497779f75fSKrzysztof Helt #define WSS_HW_CS4232 0x0200 /* CS4232 */ 507779f75fSKrzysztof Helt #define WSS_HW_CS4232A 0x0201 /* CS4232A */ 517779f75fSKrzysztof Helt #define WSS_HW_CS4236 0x0202 /* CS4236 */ 527779f75fSKrzysztof Helt #define WSS_HW_CS4236B_MASK 0x0400 /* CS4236B serie (has extended control regs) */ 537779f75fSKrzysztof Helt #define WSS_HW_CS4235 0x0400 /* CS4235 - Crystal Clear (tm) stereo enhancement */ 547779f75fSKrzysztof Helt #define WSS_HW_CS4236B 0x0401 /* CS4236B */ 557779f75fSKrzysztof Helt #define WSS_HW_CS4237B 0x0402 /* CS4237B - SRS 3D */ 567779f75fSKrzysztof Helt #define WSS_HW_CS4238B 0x0403 /* CS4238B - QSOUND 3D */ 577779f75fSKrzysztof Helt #define WSS_HW_CS4239 0x0404 /* CS4239 - Crystal Clear (tm) stereo enhancement */ 58ece11c9bSKrzysztof Helt #define WSS_HW_AD1848_MASK 0x0800 /* AD1848 serie (half duplex) */ 59ece11c9bSKrzysztof Helt #define WSS_HW_AD1847 0x0801 /* AD1847 chip */ 60ece11c9bSKrzysztof Helt #define WSS_HW_AD1848 0x0802 /* AD1848 chip */ 61ece11c9bSKrzysztof Helt #define WSS_HW_CS4248 0x0803 /* CS4248 chip */ 62ece11c9bSKrzysztof Helt #define WSS_HW_CMI8330 0x0804 /* CMI8330 chip */ 63ece11c9bSKrzysztof Helt #define WSS_HW_THINKPAD 0x0805 /* Thinkpad 360/750/755 */ 6461ef19d7SKrzysztof Helt /* compatible, but clones */ 657779f75fSKrzysztof Helt #define WSS_HW_INTERWAVE 0x1000 /* InterWave chip */ 667779f75fSKrzysztof Helt #define WSS_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */ 677779f75fSKrzysztof Helt #define WSS_HW_OPTI93X 0x1102 /* Opti 930/931/933 */ 6861ef19d7SKrzysztof Helt 6961ef19d7SKrzysztof Helt /* defines for codec.hwshare */ 707779f75fSKrzysztof Helt #define WSS_HWSHARE_IRQ (1<<0) 717779f75fSKrzysztof Helt #define WSS_HWSHARE_DMA1 (1<<1) 727779f75fSKrzysztof Helt #define WSS_HWSHARE_DMA2 (1<<2) 7361ef19d7SKrzysztof Helt 74ead893c0SKrzysztof Helt /* IBM Thinkpad specific stuff */ 75ead893c0SKrzysztof Helt #define AD1848_THINKPAD_CTL_PORT1 0x15e8 76ead893c0SKrzysztof Helt #define AD1848_THINKPAD_CTL_PORT2 0x15e9 77ead893c0SKrzysztof Helt #define AD1848_THINKPAD_CS4248_ENABLE_BIT 0x02 78ead893c0SKrzysztof Helt 797779f75fSKrzysztof Helt struct snd_wss { 8061ef19d7SKrzysztof Helt unsigned long port; /* base i/o port */ 8161ef19d7SKrzysztof Helt struct resource *res_port; 8261ef19d7SKrzysztof Helt unsigned long cport; /* control base i/o port (CS4236) */ 8361ef19d7SKrzysztof Helt struct resource *res_cport; 8461ef19d7SKrzysztof Helt int irq; /* IRQ line */ 8561ef19d7SKrzysztof Helt int dma1; /* playback DMA */ 8661ef19d7SKrzysztof Helt int dma2; /* record DMA */ 8761ef19d7SKrzysztof Helt unsigned short version; /* version of CODEC chip */ 887779f75fSKrzysztof Helt unsigned short mode; /* see to WSS_MODE_XXXX */ 897779f75fSKrzysztof Helt unsigned short hardware; /* see to WSS_HW_XXXX */ 9061ef19d7SKrzysztof Helt unsigned short hwshare; /* shared resources */ 91241b3ee7SKrzysztof Helt unsigned short single_dma:1, /* forced single DMA mode (GUS 16-bit */ 92241b3ee7SKrzysztof Helt /* daughter board) or dma1 == dma2 */ 93241b3ee7SKrzysztof Helt ebus_flag:1, /* SPARC: EBUS present */ 94241b3ee7SKrzysztof Helt thinkpad_flag:1; /* Thinkpad CS4248 needs extra help */ 9561ef19d7SKrzysztof Helt 9661ef19d7SKrzysztof Helt struct snd_card *card; 9761ef19d7SKrzysztof Helt struct snd_pcm *pcm; 9861ef19d7SKrzysztof Helt struct snd_pcm_substream *playback_substream; 9961ef19d7SKrzysztof Helt struct snd_pcm_substream *capture_substream; 10061ef19d7SKrzysztof Helt struct snd_timer *timer; 10161ef19d7SKrzysztof Helt 10261ef19d7SKrzysztof Helt unsigned char image[32]; /* registers image */ 10361ef19d7SKrzysztof Helt unsigned char eimage[32]; /* extended registers image */ 10461ef19d7SKrzysztof Helt unsigned char cimage[16]; /* control registers image */ 10561ef19d7SKrzysztof Helt int mce_bit; 10661ef19d7SKrzysztof Helt int calibrate_mute; 10761ef19d7SKrzysztof Helt int sw_3d_bit; 10861ef19d7SKrzysztof Helt unsigned int p_dma_size; 10961ef19d7SKrzysztof Helt unsigned int c_dma_size; 11061ef19d7SKrzysztof Helt 11161ef19d7SKrzysztof Helt spinlock_t reg_lock; 11261ef19d7SKrzysztof Helt struct mutex mce_mutex; 11361ef19d7SKrzysztof Helt struct mutex open_mutex; 11461ef19d7SKrzysztof Helt 11561ef19d7SKrzysztof Helt int (*rate_constraint) (struct snd_pcm_runtime *runtime); 1167779f75fSKrzysztof Helt void (*set_playback_format) (struct snd_wss *chip, 1177779f75fSKrzysztof Helt struct snd_pcm_hw_params *hw_params, 1187779f75fSKrzysztof Helt unsigned char pdfr); 1197779f75fSKrzysztof Helt void (*set_capture_format) (struct snd_wss *chip, 1207779f75fSKrzysztof Helt struct snd_pcm_hw_params *hw_params, 1217779f75fSKrzysztof Helt unsigned char cdfr); 1227779f75fSKrzysztof Helt void (*trigger) (struct snd_wss *chip, unsigned int what, int start); 12361ef19d7SKrzysztof Helt #ifdef CONFIG_PM 1247779f75fSKrzysztof Helt void (*suspend) (struct snd_wss *chip); 1257779f75fSKrzysztof Helt void (*resume) (struct snd_wss *chip); 12661ef19d7SKrzysztof Helt #endif 12761ef19d7SKrzysztof Helt void *dma_private_data; 1287779f75fSKrzysztof Helt int (*claim_dma) (struct snd_wss *chip, 1297779f75fSKrzysztof Helt void *dma_private_data, int dma); 1307779f75fSKrzysztof Helt int (*release_dma) (struct snd_wss *chip, 1317779f75fSKrzysztof Helt void *dma_private_data, int dma); 13261ef19d7SKrzysztof Helt }; 13361ef19d7SKrzysztof Helt 13461ef19d7SKrzysztof Helt /* exported functions */ 13561ef19d7SKrzysztof Helt 1367779f75fSKrzysztof Helt void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char val); 1377779f75fSKrzysztof Helt unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg); 1387779f75fSKrzysztof Helt void snd_cs4236_ext_out(struct snd_wss *chip, 1397779f75fSKrzysztof Helt unsigned char reg, unsigned char val); 1407779f75fSKrzysztof Helt unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg); 1417779f75fSKrzysztof Helt void snd_wss_mce_up(struct snd_wss *chip); 1427779f75fSKrzysztof Helt void snd_wss_mce_down(struct snd_wss *chip); 14361ef19d7SKrzysztof Helt 1447779f75fSKrzysztof Helt void snd_wss_overrange(struct snd_wss *chip); 14561ef19d7SKrzysztof Helt 1467779f75fSKrzysztof Helt irqreturn_t snd_wss_interrupt(int irq, void *dev_id); 14761ef19d7SKrzysztof Helt 1487779f75fSKrzysztof Helt const char *snd_wss_chip_id(struct snd_wss *chip); 14961ef19d7SKrzysztof Helt 1507779f75fSKrzysztof Helt int snd_wss_create(struct snd_card *card, 15161ef19d7SKrzysztof Helt unsigned long port, 15261ef19d7SKrzysztof Helt unsigned long cport, 15361ef19d7SKrzysztof Helt int irq, int dma1, int dma2, 15461ef19d7SKrzysztof Helt unsigned short hardware, 15561ef19d7SKrzysztof Helt unsigned short hwshare, 1567779f75fSKrzysztof Helt struct snd_wss **rchip); 157*fa60c065SLars-Peter Clausen int snd_wss_pcm(struct snd_wss *chip, int device); 158*fa60c065SLars-Peter Clausen int snd_wss_timer(struct snd_wss *chip, int device); 1597779f75fSKrzysztof Helt int snd_wss_mixer(struct snd_wss *chip); 16061ef19d7SKrzysztof Helt 161ead893c0SKrzysztof Helt const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction); 162ead893c0SKrzysztof Helt 16361ef19d7SKrzysztof Helt int snd_cs4236_create(struct snd_card *card, 16461ef19d7SKrzysztof Helt unsigned long port, 16561ef19d7SKrzysztof Helt unsigned long cport, 16661ef19d7SKrzysztof Helt int irq, int dma1, int dma2, 16761ef19d7SKrzysztof Helt unsigned short hardware, 16861ef19d7SKrzysztof Helt unsigned short hwshare, 1697779f75fSKrzysztof Helt struct snd_wss **rchip); 170*fa60c065SLars-Peter Clausen int snd_cs4236_pcm(struct snd_wss *chip, int device); 1717779f75fSKrzysztof Helt int snd_cs4236_mixer(struct snd_wss *chip); 17261ef19d7SKrzysztof Helt 17361ef19d7SKrzysztof Helt /* 17461ef19d7SKrzysztof Helt * mixer library 17561ef19d7SKrzysztof Helt */ 17661ef19d7SKrzysztof Helt 1777779f75fSKrzysztof Helt #define WSS_SINGLE(xname, xindex, reg, shift, mask, invert) \ 1787779f75fSKrzysztof Helt { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1797779f75fSKrzysztof Helt .name = xname, \ 1807779f75fSKrzysztof Helt .index = xindex, \ 1817779f75fSKrzysztof Helt .info = snd_wss_info_single, \ 1827779f75fSKrzysztof Helt .get = snd_wss_get_single, \ 1837779f75fSKrzysztof Helt .put = snd_wss_put_single, \ 18461ef19d7SKrzysztof Helt .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 18561ef19d7SKrzysztof Helt 1867779f75fSKrzysztof Helt int snd_wss_info_single(struct snd_kcontrol *kcontrol, 1877779f75fSKrzysztof Helt struct snd_ctl_elem_info *uinfo); 1887779f75fSKrzysztof Helt int snd_wss_get_single(struct snd_kcontrol *kcontrol, 1897779f75fSKrzysztof Helt struct snd_ctl_elem_value *ucontrol); 1907779f75fSKrzysztof Helt int snd_wss_put_single(struct snd_kcontrol *kcontrol, 1917779f75fSKrzysztof Helt struct snd_ctl_elem_value *ucontrol); 19261ef19d7SKrzysztof Helt 1937779f75fSKrzysztof Helt #define WSS_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 1947779f75fSKrzysztof Helt { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1957779f75fSKrzysztof Helt .name = xname, \ 1967779f75fSKrzysztof Helt .index = xindex, \ 1977779f75fSKrzysztof Helt .info = snd_wss_info_double, \ 1987779f75fSKrzysztof Helt .get = snd_wss_get_double, \ 1997779f75fSKrzysztof Helt .put = snd_wss_put_double, \ 2007779f75fSKrzysztof Helt .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \ 2017779f75fSKrzysztof Helt (shift_right << 19) | (mask << 24) | (invert << 22) } 20261ef19d7SKrzysztof Helt 2035664daa1SKrzysztof Helt #define WSS_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ 2045664daa1SKrzysztof Helt { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2055664daa1SKrzysztof Helt .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 2065664daa1SKrzysztof Helt .name = xname, \ 2075664daa1SKrzysztof Helt .index = xindex, \ 2085664daa1SKrzysztof Helt .info = snd_wss_info_single, \ 2095664daa1SKrzysztof Helt .get = snd_wss_get_single, \ 2105664daa1SKrzysztof Helt .put = snd_wss_put_single, \ 2115664daa1SKrzysztof Helt .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \ 2125664daa1SKrzysztof Helt .tlv = { .p = (xtlv) } } 2135664daa1SKrzysztof Helt 2145664daa1SKrzysztof Helt #define WSS_DOUBLE_TLV(xname, xindex, left_reg, right_reg, \ 2155664daa1SKrzysztof Helt shift_left, shift_right, mask, invert, xtlv) \ 2165664daa1SKrzysztof Helt { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2175664daa1SKrzysztof Helt .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 2185664daa1SKrzysztof Helt .name = xname, \ 2195664daa1SKrzysztof Helt .index = xindex, \ 2205664daa1SKrzysztof Helt .info = snd_wss_info_double, \ 2215664daa1SKrzysztof Helt .get = snd_wss_get_double, \ 2225664daa1SKrzysztof Helt .put = snd_wss_put_double, \ 2235664daa1SKrzysztof Helt .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \ 2245664daa1SKrzysztof Helt (shift_right << 19) | (mask << 24) | (invert << 22), \ 2255664daa1SKrzysztof Helt .tlv = { .p = (xtlv) } } 2265664daa1SKrzysztof Helt 2275664daa1SKrzysztof Helt 2287779f75fSKrzysztof Helt int snd_wss_info_double(struct snd_kcontrol *kcontrol, 2297779f75fSKrzysztof Helt struct snd_ctl_elem_info *uinfo); 2307779f75fSKrzysztof Helt int snd_wss_get_double(struct snd_kcontrol *kcontrol, 2317779f75fSKrzysztof Helt struct snd_ctl_elem_value *ucontrol); 2327779f75fSKrzysztof Helt int snd_wss_put_double(struct snd_kcontrol *kcontrol, 2337779f75fSKrzysztof Helt struct snd_ctl_elem_value *ucontrol); 23461ef19d7SKrzysztof Helt 2357779f75fSKrzysztof Helt #endif /* __SOUND_WSS_H */ 236