xref: /openbmc/linux/include/sound/wss.h (revision ece11c9b6db5b96179df8eb9cdc54c78953a4c0f)
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 
2561ef19d7SKrzysztof Helt #include "control.h"
2661ef19d7SKrzysztof Helt #include "pcm.h"
2761ef19d7SKrzysztof Helt #include "timer.h"
2861ef19d7SKrzysztof Helt 
2961ef19d7SKrzysztof Helt #include "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 */
58*ece11c9bSKrzysztof Helt #define WSS_HW_AD1848_MASK	0x0800	/* AD1848 serie (half duplex) */
59*ece11c9bSKrzysztof Helt #define WSS_HW_AD1847		0x0801	/* AD1847 chip */
60*ece11c9bSKrzysztof Helt #define WSS_HW_AD1848		0x0802	/* AD1848 chip */
61*ece11c9bSKrzysztof Helt #define WSS_HW_CS4248		0x0803	/* CS4248 chip */
62*ece11c9bSKrzysztof Helt #define WSS_HW_CMI8330		0x0804	/* CMI8330 chip */
63*ece11c9bSKrzysztof 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 
747779f75fSKrzysztof Helt struct snd_wss {
7561ef19d7SKrzysztof Helt 	unsigned long port;		/* base i/o port */
7661ef19d7SKrzysztof Helt 	struct resource *res_port;
7761ef19d7SKrzysztof Helt 	unsigned long cport;		/* control base i/o port (CS4236) */
7861ef19d7SKrzysztof Helt 	struct resource *res_cport;
7961ef19d7SKrzysztof Helt 	int irq;			/* IRQ line */
8061ef19d7SKrzysztof Helt 	int dma1;			/* playback DMA */
8161ef19d7SKrzysztof Helt 	int dma2;			/* record DMA */
8261ef19d7SKrzysztof Helt 	unsigned short version;		/* version of CODEC chip */
837779f75fSKrzysztof Helt 	unsigned short mode;		/* see to WSS_MODE_XXXX */
847779f75fSKrzysztof Helt 	unsigned short hardware;	/* see to WSS_HW_XXXX */
8561ef19d7SKrzysztof Helt 	unsigned short hwshare;		/* shared resources */
86241b3ee7SKrzysztof Helt 	unsigned short single_dma:1,	/* forced single DMA mode (GUS 16-bit */
87241b3ee7SKrzysztof Helt 					/* daughter board) or dma1 == dma2 */
88241b3ee7SKrzysztof Helt 		       ebus_flag:1,	/* SPARC: EBUS present */
89241b3ee7SKrzysztof Helt 		       thinkpad_flag:1;	/* Thinkpad CS4248 needs extra help */
9061ef19d7SKrzysztof Helt 
9161ef19d7SKrzysztof Helt 	struct snd_card *card;
9261ef19d7SKrzysztof Helt 	struct snd_pcm *pcm;
9361ef19d7SKrzysztof Helt 	struct snd_pcm_substream *playback_substream;
9461ef19d7SKrzysztof Helt 	struct snd_pcm_substream *capture_substream;
9561ef19d7SKrzysztof Helt 	struct snd_timer *timer;
9661ef19d7SKrzysztof Helt 
9761ef19d7SKrzysztof Helt 	unsigned char image[32];	/* registers image */
9861ef19d7SKrzysztof Helt 	unsigned char eimage[32];	/* extended registers image */
9961ef19d7SKrzysztof Helt 	unsigned char cimage[16];	/* control registers image */
10061ef19d7SKrzysztof Helt 	int mce_bit;
10161ef19d7SKrzysztof Helt 	int calibrate_mute;
10261ef19d7SKrzysztof Helt 	int sw_3d_bit;
10361ef19d7SKrzysztof Helt 	unsigned int p_dma_size;
10461ef19d7SKrzysztof Helt 	unsigned int c_dma_size;
10561ef19d7SKrzysztof Helt 
10661ef19d7SKrzysztof Helt 	spinlock_t reg_lock;
10761ef19d7SKrzysztof Helt 	struct mutex mce_mutex;
10861ef19d7SKrzysztof Helt 	struct mutex open_mutex;
10961ef19d7SKrzysztof Helt 
11061ef19d7SKrzysztof Helt 	int (*rate_constraint) (struct snd_pcm_runtime *runtime);
1117779f75fSKrzysztof Helt 	void (*set_playback_format) (struct snd_wss *chip,
1127779f75fSKrzysztof Helt 				     struct snd_pcm_hw_params *hw_params,
1137779f75fSKrzysztof Helt 				     unsigned char pdfr);
1147779f75fSKrzysztof Helt 	void (*set_capture_format) (struct snd_wss *chip,
1157779f75fSKrzysztof Helt 				    struct snd_pcm_hw_params *hw_params,
1167779f75fSKrzysztof Helt 				    unsigned char cdfr);
1177779f75fSKrzysztof Helt 	void (*trigger) (struct snd_wss *chip, unsigned int what, int start);
11861ef19d7SKrzysztof Helt #ifdef CONFIG_PM
1197779f75fSKrzysztof Helt 	void (*suspend) (struct snd_wss *chip);
1207779f75fSKrzysztof Helt 	void (*resume) (struct snd_wss *chip);
12161ef19d7SKrzysztof Helt #endif
12261ef19d7SKrzysztof Helt 	void *dma_private_data;
1237779f75fSKrzysztof Helt 	int (*claim_dma) (struct snd_wss *chip,
1247779f75fSKrzysztof Helt 			  void *dma_private_data, int dma);
1257779f75fSKrzysztof Helt 	int (*release_dma) (struct snd_wss *chip,
1267779f75fSKrzysztof Helt 			    void *dma_private_data, int dma);
12761ef19d7SKrzysztof Helt };
12861ef19d7SKrzysztof Helt 
12961ef19d7SKrzysztof Helt /* exported functions */
13061ef19d7SKrzysztof Helt 
1317779f75fSKrzysztof Helt void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char val);
1327779f75fSKrzysztof Helt unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg);
1337779f75fSKrzysztof Helt void snd_cs4236_ext_out(struct snd_wss *chip,
1347779f75fSKrzysztof Helt 			unsigned char reg, unsigned char val);
1357779f75fSKrzysztof Helt unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg);
1367779f75fSKrzysztof Helt void snd_wss_mce_up(struct snd_wss *chip);
1377779f75fSKrzysztof Helt void snd_wss_mce_down(struct snd_wss *chip);
13861ef19d7SKrzysztof Helt 
1397779f75fSKrzysztof Helt void snd_wss_overrange(struct snd_wss *chip);
14061ef19d7SKrzysztof Helt 
1417779f75fSKrzysztof Helt irqreturn_t snd_wss_interrupt(int irq, void *dev_id);
14261ef19d7SKrzysztof Helt 
1437779f75fSKrzysztof Helt const char *snd_wss_chip_id(struct snd_wss *chip);
14461ef19d7SKrzysztof Helt 
1457779f75fSKrzysztof Helt int snd_wss_create(struct snd_card *card,
14661ef19d7SKrzysztof Helt 		      unsigned long port,
14761ef19d7SKrzysztof Helt 		      unsigned long cport,
14861ef19d7SKrzysztof Helt 		      int irq, int dma1, int dma2,
14961ef19d7SKrzysztof Helt 		      unsigned short hardware,
15061ef19d7SKrzysztof Helt 		      unsigned short hwshare,
1517779f75fSKrzysztof Helt 		      struct snd_wss **rchip);
1527779f75fSKrzysztof Helt int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
1537779f75fSKrzysztof Helt int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer);
1547779f75fSKrzysztof Helt int snd_wss_mixer(struct snd_wss *chip);
15561ef19d7SKrzysztof Helt 
15661ef19d7SKrzysztof Helt int snd_cs4236_create(struct snd_card *card,
15761ef19d7SKrzysztof Helt 		      unsigned long port,
15861ef19d7SKrzysztof Helt 		      unsigned long cport,
15961ef19d7SKrzysztof Helt 		      int irq, int dma1, int dma2,
16061ef19d7SKrzysztof Helt 		      unsigned short hardware,
16161ef19d7SKrzysztof Helt 		      unsigned short hwshare,
1627779f75fSKrzysztof Helt 		      struct snd_wss **rchip);
1637779f75fSKrzysztof Helt int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
1647779f75fSKrzysztof Helt int snd_cs4236_mixer(struct snd_wss *chip);
16561ef19d7SKrzysztof Helt 
16661ef19d7SKrzysztof Helt /*
16761ef19d7SKrzysztof Helt  *  mixer library
16861ef19d7SKrzysztof Helt  */
16961ef19d7SKrzysztof Helt 
1707779f75fSKrzysztof Helt #define WSS_SINGLE(xname, xindex, reg, shift, mask, invert) \
1717779f75fSKrzysztof Helt { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1727779f75fSKrzysztof Helt   .name = xname, \
1737779f75fSKrzysztof Helt   .index = xindex, \
1747779f75fSKrzysztof Helt   .info = snd_wss_info_single, \
1757779f75fSKrzysztof Helt   .get = snd_wss_get_single, \
1767779f75fSKrzysztof Helt   .put = snd_wss_put_single, \
17761ef19d7SKrzysztof Helt   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
17861ef19d7SKrzysztof Helt 
1797779f75fSKrzysztof Helt int snd_wss_info_single(struct snd_kcontrol *kcontrol,
1807779f75fSKrzysztof Helt 			struct snd_ctl_elem_info *uinfo);
1817779f75fSKrzysztof Helt int snd_wss_get_single(struct snd_kcontrol *kcontrol,
1827779f75fSKrzysztof Helt 			struct snd_ctl_elem_value *ucontrol);
1837779f75fSKrzysztof Helt int snd_wss_put_single(struct snd_kcontrol *kcontrol,
1847779f75fSKrzysztof Helt 			struct snd_ctl_elem_value *ucontrol);
18561ef19d7SKrzysztof Helt 
1867779f75fSKrzysztof Helt #define WSS_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
1877779f75fSKrzysztof Helt { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1887779f75fSKrzysztof Helt   .name = xname, \
1897779f75fSKrzysztof Helt   .index = xindex, \
1907779f75fSKrzysztof Helt   .info = snd_wss_info_double, \
1917779f75fSKrzysztof Helt   .get = snd_wss_get_double, \
1927779f75fSKrzysztof Helt   .put = snd_wss_put_double, \
1937779f75fSKrzysztof Helt   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
1947779f75fSKrzysztof Helt 		   (shift_right << 19) | (mask << 24) | (invert << 22) }
19561ef19d7SKrzysztof Helt 
1967779f75fSKrzysztof Helt int snd_wss_info_double(struct snd_kcontrol *kcontrol,
1977779f75fSKrzysztof Helt 			struct snd_ctl_elem_info *uinfo);
1987779f75fSKrzysztof Helt int snd_wss_get_double(struct snd_kcontrol *kcontrol,
1997779f75fSKrzysztof Helt 			struct snd_ctl_elem_value *ucontrol);
2007779f75fSKrzysztof Helt int snd_wss_put_double(struct snd_kcontrol *kcontrol,
2017779f75fSKrzysztof Helt 			struct snd_ctl_elem_value *ucontrol);
20261ef19d7SKrzysztof Helt 
2037779f75fSKrzysztof Helt #endif /* __SOUND_WSS_H */
204