Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  The driver for the ForteMedia FM801 based soundcards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <sound/mpu401.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <sound/opl3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #ifdef CONFIG_SND_FM801_TEA575X_BOOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <media/drv-intf/tea575x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) MODULE_DESCRIPTION("ForteMedia FM801");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 		"{Genius,SoundMaker Live 5.1}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *  Enable TEA575x tuner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  *    1 = MediaForte 256-PCS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  *    2 = MediaForte 256-PCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *    3 = MediaForte 64-PCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *   16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *  High 16-bits are video (radio) device number + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) static int tea575x_tuner[SNDRV_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) module_param_array(tea575x_tuner, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) module_param_array(radio_nr, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) MODULE_PARM_DESC(radio_nr, "Radio device numbers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define TUNER_DISABLED		(1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define TUNER_ONLY		(1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define TUNER_TYPE_MASK		(~TUNER_ONLY & 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63)  *  Direct registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define fm801_writew(chip,reg,value)	outw((value), chip->port + FM801_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define fm801_readw(chip,reg)		inw(chip->port + FM801_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define fm801_writel(chip,reg,value)	outl((value), chip->port + FM801_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define FM801_PCM_VOL		0x00	/* PCM Output Volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define FM801_FM_VOL		0x02	/* FM Output Volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define FM801_I2S_VOL		0x04	/* I2S Volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define FM801_REC_SRC		0x06	/* Record Source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define FM801_PLY_CTRL		0x08	/* Playback Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define FM801_PLY_COUNT		0x0a	/* Playback Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define FM801_PLY_BUF1		0x0c	/* Playback Bufer I */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define FM801_PLY_BUF2		0x10	/* Playback Buffer II */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define FM801_CAP_CTRL		0x14	/* Capture Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define FM801_CAP_COUNT		0x16	/* Capture Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define FM801_CAP_BUF1		0x18	/* Capture Buffer I */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define FM801_CAP_BUF2		0x1c	/* Capture Buffer II */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define FM801_CODEC_CTRL	0x22	/* Codec Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define FM801_I2S_MODE		0x24	/* I2S Mode Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define FM801_VOLUME		0x26	/* Volume Up/Down/Mute Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define FM801_I2C_CTRL		0x29	/* I2C Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define FM801_AC97_CMD		0x2a	/* AC'97 Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define FM801_AC97_DATA		0x2c	/* AC'97 Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define FM801_MPU401_DATA	0x30	/* MPU401 Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define FM801_MPU401_CMD	0x31	/* MPU401 Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define FM801_GPIO_CTRL		0x52	/* General Purpose I/O Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define FM801_GEN_CTRL		0x54	/* General Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define FM801_IRQ_MASK		0x56	/* Interrupt Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define FM801_IRQ_STATUS	0x5a	/* Interrupt Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define FM801_OPL3_BANK0	0x68	/* OPL3 Status Read / Bank 0 Write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define FM801_OPL3_DATA0	0x69	/* OPL3 Data 0 Write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define FM801_OPL3_BANK1	0x6a	/* OPL3 Bank 1 Write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define FM801_OPL3_DATA1	0x6b	/* OPL3 Bank 1 Write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define FM801_POWERDOWN		0x70	/* Blocks Power Down Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) /* codec access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define FM801_AC97_READ		(1<<7)	/* read=1, write=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define FM801_AC97_VALID	(1<<8)	/* port valid=1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define FM801_AC97_BUSY		(1<<9)	/* busy=1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define FM801_AC97_ADDR_SHIFT	10	/* codec id (2bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) /* playback and record control register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) #define FM801_BUF1_LAST		(1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define FM801_BUF2_LAST		(1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define FM801_START		(1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define FM801_PAUSE		(1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define FM801_IMMED_STOP	(1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #define FM801_RATE_SHIFT	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define FM801_RATE_MASK		(15 << FM801_RATE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define FM801_CHANNELS_4	(1<<12)	/* playback only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define FM801_CHANNELS_6	(2<<12)	/* playback only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define FM801_CHANNELS_6MS	(3<<12)	/* playback only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define FM801_CHANNELS_MASK	(3<<12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #define FM801_16BIT		(1<<14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define FM801_STEREO		(1<<15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) /* IRQ status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) #define FM801_IRQ_PLAYBACK	(1<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define FM801_IRQ_CAPTURE	(1<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define FM801_IRQ_VOLUME	(1<<14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define FM801_IRQ_MPU		(1<<15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) /* GPIO control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define FM801_GPIO_GP0		(1<<0)	/* read/write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define FM801_GPIO_GP1		(1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define FM801_GPIO_GP2		(1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define FM801_GPIO_GP3		(1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define FM801_GPIO_GP(x)	(1<<(0+(x)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) #define FM801_GPIO_GD0		(1<<8)	/* directions: 1 = input, 0 = output*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define FM801_GPIO_GD1		(1<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define FM801_GPIO_GD2		(1<<10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define FM801_GPIO_GD3		(1<<11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define FM801_GPIO_GD(x)	(1<<(8+(x)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define FM801_GPIO_GS0		(1<<12)	/* function select: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) #define FM801_GPIO_GS1		(1<<13)	/*    1 = GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) #define FM801_GPIO_GS2		(1<<14)	/*    0 = other (S/PDIF, VOL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) #define FM801_GPIO_GS3		(1<<15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) #define FM801_GPIO_GS(x)	(1<<(12+(x)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  * struct fm801 - describes FM801 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  * @dev:		device for this chio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  * @irq:		irq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  * @port:		I/O port number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  * @multichannel:	multichannel support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151)  * @secondary:		secondary codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152)  * @secondary_addr:	address of the secondary codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153)  * @tea575x_tuner:	tuner access method & flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  * @ply_ctrl:		playback control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  * @cap_ctrl:		capture control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * @ply_buffer:		playback buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * @ply_buf:		playback buffer index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  * @ply_count:		playback buffer count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * @ply_size:		playback buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  * @ply_pos:		playback position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  * @cap_buffer:		capture buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)  * @cap_buf:		capture buffer index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  * @cap_count:		capture buffer count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  * @cap_size:		capture buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  * @cap_pos:		capture position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * @ac97_bus:		ac97 bus handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * @ac97:		ac97 handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * @ac97_sec:		ac97 secondary handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * @card:		ALSA card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * @pcm:		PCM devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * @rmidi:		rmidi device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  * @playback_substream:	substream for playback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  * @capture_substream:	substream for capture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  * @p_dma_size:		playback DMA size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  * @c_dma_size:		capture DMA size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  * @reg_lock:		lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  * @proc_entry:		/proc entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  * @v4l2_dev:		v4l2 device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  * @tea:		tea575a structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  * @saved_regs:		context saved during suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) struct fm801 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	unsigned long port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	unsigned int multichannel: 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		     secondary: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	unsigned char secondary_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	unsigned int tea575x_tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	unsigned short ply_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	unsigned short cap_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	unsigned long ply_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	unsigned int ply_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	unsigned int ply_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	unsigned int ply_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	unsigned int ply_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	unsigned long cap_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	unsigned int cap_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	unsigned int cap_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	unsigned int cap_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	unsigned int cap_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	struct snd_ac97_bus *ac97_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	struct snd_ac97 *ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	struct snd_ac97 *ac97_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	struct snd_pcm_substream *playback_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	struct snd_pcm_substream *capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	unsigned int p_dma_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	unsigned int c_dma_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	struct snd_info_entry *proc_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) #ifdef CONFIG_SND_FM801_TEA575X_BOOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	struct v4l2_device v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	struct snd_tea575x tea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	u16 saved_regs[0x20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  * IO accessors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static inline void fm801_iowrite16(struct fm801 *chip, unsigned short offset, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	outw(value, chip->port + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) static inline u16 fm801_ioread16(struct fm801 *chip, unsigned short offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	return inw(chip->port + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) static const struct pci_device_id snd_fm801_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, },   /* FM801 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	{ 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, },   /* Gallant Odyssey Sound 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) MODULE_DEVICE_TABLE(pci, snd_fm801_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)  *  common I/O routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) static bool fm801_ac97_is_ready(struct fm801 *chip, unsigned int iterations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	for (idx = 0; idx < iterations; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		if (!(fm801_readw(chip, AC97_CMD) & FM801_AC97_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) static bool fm801_ac97_is_valid(struct fm801 *chip, unsigned int iterations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	for (idx = 0; idx < iterations; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		if (fm801_readw(chip, AC97_CMD) & FM801_AC97_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 				 unsigned short mask, unsigned short value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	unsigned short old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	old = fm801_ioread16(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	new = (old & ~mask) | value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	change = old != new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		fm801_iowrite16(chip, reg, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) static void snd_fm801_codec_write(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 				  unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 				  unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	struct fm801 *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	 *  Wait until the codec interface is not ready..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	if (!fm801_ac97_is_ready(chip, 100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		dev_err(chip->card->dev, "AC'97 interface is busy (1)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	/* write data and address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	fm801_writew(chip, AC97_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	fm801_writew(chip, AC97_CMD, reg | (ac97->addr << FM801_AC97_ADDR_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	 *  Wait until the write command is not completed..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	if (!fm801_ac97_is_ready(chip, 1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		dev_err(chip->card->dev, "AC'97 interface #%d is busy (2)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		ac97->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) static unsigned short snd_fm801_codec_read(struct snd_ac97 *ac97, unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	struct fm801 *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	 *  Wait until the codec interface is not ready..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	if (!fm801_ac97_is_ready(chip, 100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		dev_err(chip->card->dev, "AC'97 interface is busy (1)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	/* read command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	fm801_writew(chip, AC97_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		     reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	if (!fm801_ac97_is_ready(chip, 100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		dev_err(chip->card->dev, "AC'97 interface #%d is busy (2)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 			ac97->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	if (!fm801_ac97_is_valid(chip, 1000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			"AC'97 interface #%d is not valid (2)\n", ac97->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	return fm801_readw(chip, AC97_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) static const unsigned int rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)   5500,  8000,  9600, 11025,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356)   16000, 19200, 22050, 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357)   38400, 44100, 48000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	.count = ARRAY_SIZE(rates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	.list = rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	.mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) static const unsigned int channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)   2, 4, 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) static const struct snd_pcm_hw_constraint_list hw_constraints_channels = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	.count = ARRAY_SIZE(channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	.list = channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	.mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377)  *  Sample rate routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) static unsigned short snd_fm801_rate_bits(unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	for (idx = 0; idx < ARRAY_SIZE(rates); idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		if (rates[idx] == rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	return ARRAY_SIZE(rates) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392)  *  PCM part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) static int snd_fm801_playback_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 				      int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		chip->ply_ctrl &= ~(FM801_BUF1_LAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 				     FM801_BUF2_LAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 				     FM801_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		chip->ply_ctrl |= FM801_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 				   FM801_IMMED_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		chip->ply_ctrl &= ~(FM801_START | FM801_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		chip->ply_ctrl |= FM801_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		chip->ply_ctrl &= ~FM801_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	fm801_writew(chip, PLY_CTRL, chip->ply_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) static int snd_fm801_capture_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				     int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		chip->cap_ctrl &= ~(FM801_BUF1_LAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 				     FM801_BUF2_LAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 				     FM801_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		chip->cap_ctrl |= FM801_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				   FM801_IMMED_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		chip->cap_ctrl &= ~(FM801_START | FM801_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		chip->cap_ctrl |= FM801_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		chip->cap_ctrl &= ~FM801_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	fm801_writew(chip, CAP_CTRL, chip->cap_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	chip->ply_size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	chip->ply_count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	chip->ply_ctrl &= ~(FM801_START | FM801_16BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			     FM801_STEREO | FM801_RATE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			     FM801_CHANNELS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	if (snd_pcm_format_width(runtime->format) == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		chip->ply_ctrl |= FM801_16BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (runtime->channels > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		chip->ply_ctrl |= FM801_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		if (runtime->channels == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			chip->ply_ctrl |= FM801_CHANNELS_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		else if (runtime->channels == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			chip->ply_ctrl |= FM801_CHANNELS_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	chip->ply_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	chip->ply_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	fm801_writew(chip, PLY_CTRL, chip->ply_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	fm801_writew(chip, PLY_COUNT, chip->ply_count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	chip->ply_buffer = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	chip->ply_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	fm801_writel(chip, PLY_BUF1, chip->ply_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	fm801_writel(chip, PLY_BUF2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		     chip->ply_buffer + (chip->ply_count % chip->ply_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) static int snd_fm801_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	chip->cap_size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	chip->cap_count = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	chip->cap_ctrl &= ~(FM801_START | FM801_16BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			     FM801_STEREO | FM801_RATE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	if (snd_pcm_format_width(runtime->format) == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		chip->cap_ctrl |= FM801_16BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (runtime->channels > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		chip->cap_ctrl |= FM801_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	chip->cap_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	chip->cap_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	fm801_writew(chip, CAP_CTRL, chip->cap_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	fm801_writew(chip, CAP_COUNT, chip->cap_count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	chip->cap_buffer = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	chip->cap_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	fm801_writel(chip, CAP_BUF1, chip->cap_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	fm801_writel(chip, CAP_BUF2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		     chip->cap_buffer + (chip->cap_count % chip->cap_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static snd_pcm_uframes_t snd_fm801_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	if (!(chip->ply_ctrl & FM801_START))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	ptr = chip->ply_pos + (chip->ply_count - 1) - fm801_readw(chip, PLY_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	if (fm801_readw(chip, IRQ_STATUS) & FM801_IRQ_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		ptr += chip->ply_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		ptr %= chip->ply_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	return bytes_to_frames(substream->runtime, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	if (!(chip->cap_ctrl & FM801_START))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	ptr = chip->cap_pos + (chip->cap_count - 1) - fm801_readw(chip, CAP_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	if (fm801_readw(chip, IRQ_STATUS) & FM801_IRQ_CAPTURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		ptr += chip->cap_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		ptr %= chip->cap_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	return bytes_to_frames(substream->runtime, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	struct fm801 *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	unsigned short status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	status = fm801_readw(chip, IRQ_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	if (! status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	/* ack first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	fm801_writew(chip, IRQ_STATUS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		chip->ply_buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		chip->ply_pos += chip->ply_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		chip->ply_pos %= chip->ply_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		tmp = chip->ply_pos + chip->ply_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		tmp %= chip->ply_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		if (chip->ply_buf & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 			fm801_writel(chip, PLY_BUF1, chip->ply_buffer + tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 			fm801_writel(chip, PLY_BUF2, chip->ply_buffer + tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		snd_pcm_period_elapsed(chip->playback_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if (chip->pcm && (status & FM801_IRQ_CAPTURE) && chip->capture_substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		chip->cap_buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		chip->cap_pos += chip->cap_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		chip->cap_pos %= chip->cap_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		tmp = chip->cap_pos + chip->cap_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		tmp %= chip->cap_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		if (chip->cap_buf & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 			fm801_writel(chip, CAP_BUF1, chip->cap_buffer + tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			fm801_writel(chip, CAP_BUF2, chip->cap_buffer + tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		snd_pcm_period_elapsed(chip->capture_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	if (chip->rmidi && (status & FM801_IRQ_MPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (status & FM801_IRQ_VOLUME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		/* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) static const struct snd_pcm_hardware snd_fm801_playback =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 				 SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	.rate_min =		5500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	.rate_max =		48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	.channels_min =		1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	.channels_max =		2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	.buffer_bytes_max =	(128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	.period_bytes_min =	64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	.period_bytes_max =	(128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	.periods_min =		1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	.periods_max =		1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	.fifo_size =		0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) static const struct snd_pcm_hardware snd_fm801_capture =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				 SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	.rate_min =		5500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	.rate_max =		48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	.channels_min =		1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	.channels_max =		2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	.buffer_bytes_max =	(128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	.period_bytes_min =	64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	.period_bytes_max =	(128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	.periods_min =		1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	.periods_max =		1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	.fifo_size =		0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) static int snd_fm801_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	chip->playback_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	runtime->hw = snd_fm801_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 				   &hw_constraints_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	if (chip->multichannel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		runtime->hw.channels_max = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		snd_pcm_hw_constraint_list(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 					   SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 					   &hw_constraints_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) static int snd_fm801_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	chip->capture_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	runtime->hw = snd_fm801_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 				   &hw_constraints_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static int snd_fm801_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	chip->playback_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) static int snd_fm801_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	struct fm801 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	chip->capture_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) static const struct snd_pcm_ops snd_fm801_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	.open =		snd_fm801_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	.close =	snd_fm801_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	.prepare =	snd_fm801_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	.trigger =	snd_fm801_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	.pointer =	snd_fm801_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) static const struct snd_pcm_ops snd_fm801_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	.open =		snd_fm801_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	.close =	snd_fm801_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	.prepare =	snd_fm801_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	.trigger =	snd_fm801_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	.pointer =	snd_fm801_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static int snd_fm801_pcm(struct fm801 *chip, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	struct pci_dev *pdev = to_pci_dev(chip->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_fm801_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_fm801_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	strcpy(pcm->name, "FM801");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				       chip->multichannel ? 128*1024 : 64*1024, 128*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 				     snd_pcm_alt_chmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 				     chip->multichannel ? 6 : 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 				     NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743)  *  TEA5757 radio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) #ifdef CONFIG_SND_FM801_TEA575X_BOOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) /* GPIO to TEA575x maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) struct snd_fm801_tea575x_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	u8 data, clk, wren, most;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) static const struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	{ .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	{ .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	{ .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) #define get_tea575x_gpio(chip) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	(&snd_fm801_tea575x_gpios[((chip)->tea575x_tuner & TUNER_TYPE_MASK) - 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	struct fm801 *chip = tea->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	unsigned short reg = fm801_readw(chip, GPIO_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	reg &= ~(FM801_GPIO_GP(gpio.data) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		 FM801_GPIO_GP(gpio.clk) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		 FM801_GPIO_GP(gpio.wren));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	reg |= (pins & TEA575X_CLK)  ? FM801_GPIO_GP(gpio.clk) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	/* WRITE_ENABLE is inverted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	fm801_writew(chip, GPIO_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	struct fm801 *chip = tea->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	unsigned short reg = fm801_readw(chip, GPIO_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	u8 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	if (reg & FM801_GPIO_GP(gpio.data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		ret |= TEA575X_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (reg & FM801_GPIO_GP(gpio.most))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		ret |= TEA575X_MOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	struct fm801 *chip = tea->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	unsigned short reg = fm801_readw(chip, GPIO_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	/* use GPIO lines and set write enable bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	reg |= FM801_GPIO_GS(gpio.data) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	       FM801_GPIO_GS(gpio.wren) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	       FM801_GPIO_GS(gpio.clk) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	       FM801_GPIO_GS(gpio.most);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	if (output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		/* all of lines are in the write direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		/* clear data and clock lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		reg &= ~(FM801_GPIO_GD(gpio.data) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			 FM801_GPIO_GD(gpio.wren) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			 FM801_GPIO_GD(gpio.clk) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			 FM801_GPIO_GP(gpio.data) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			 FM801_GPIO_GP(gpio.clk) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			 FM801_GPIO_GP(gpio.wren));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		/* use GPIO lines, set data direction to input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		reg |= FM801_GPIO_GD(gpio.data) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		       FM801_GPIO_GD(gpio.most) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		       FM801_GPIO_GP(gpio.data) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		       FM801_GPIO_GP(gpio.most) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		       FM801_GPIO_GP(gpio.wren);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		/* all of lines are in the write direction, except data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		/* clear data, write enable and clock lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		reg &= ~(FM801_GPIO_GD(gpio.wren) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			 FM801_GPIO_GD(gpio.clk) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			 FM801_GPIO_GP(gpio.clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	fm801_writew(chip, GPIO_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) static const struct snd_tea575x_ops snd_fm801_tea_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	.set_pins = snd_fm801_tea575x_set_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	.get_pins = snd_fm801_tea575x_get_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	.set_direction = snd_fm801_tea575x_set_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  *  Mixer routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) #define FM801_SINGLE(xname, reg, shift, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_fm801_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846)   .get = snd_fm801_get_single, .put = snd_fm801_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847)   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static int snd_fm801_info_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) static int snd_fm801_get_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	long *value = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	value[0] = (fm801_ioread16(chip, reg) >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		value[0] = mask - value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) static int snd_fm801_put_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	val = (ucontrol->value.integer.value[0] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	return snd_fm801_update_bits(chip, reg, mask << shift, val << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) #define FM801_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_fm801_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895)   .get = snd_fm801_get_double, .put = snd_fm801_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896)   .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) #define FM801_DOUBLE_TLV(xname, reg, shift_left, shift_right, mask, invert, xtlv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899)   .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900)   .name = xname, .info = snd_fm801_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901)   .get = snd_fm801_get_double, .put = snd_fm801_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902)   .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)   .tlv = { .p = (xtlv) } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) static int snd_fm801_info_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) static int snd_fm801_get_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)         int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	int shift_right = (kcontrol->private_value >> 12) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	long *value = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	value[0] = (fm801_ioread16(chip, reg) >> shift_left) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	value[1] = (fm801_ioread16(chip, reg) >> shift_right) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		value[0] = mask - value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		value[1] = mask - value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) static int snd_fm801_put_double(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	int shift_right = (kcontrol->private_value >> 12) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	unsigned short val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	val1 = ucontrol->value.integer.value[0] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	val2 = ucontrol->value.integer.value[1] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		val1 = mask - val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		val2 = mask - val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	return snd_fm801_update_bits(chip, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 				     (mask << shift_left) | (mask << shift_right),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 				     (val1 << shift_left ) | (val2 << shift_right));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) static int snd_fm801_info_mux(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 			      struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	static const char * const texts[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		"AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	return snd_ctl_enum_info(uinfo, 1, 5, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975)         unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	val = fm801_readw(chip, REC_SRC) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	if (val > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		val = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980)         ucontrol->value.enumerated.item[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988)         unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)         if ((val = ucontrol->value.enumerated.item[0]) > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991)                 return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) #define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) static const struct snd_kcontrol_new snd_fm801_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) FM801_DOUBLE_TLV("Wave Playback Volume", FM801_PCM_VOL, 0, 8, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		 db_scale_dsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) FM801_SINGLE("Wave Playback Switch", FM801_PCM_VOL, 15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) FM801_DOUBLE_TLV("I2S Playback Volume", FM801_I2S_VOL, 0, 8, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		 db_scale_dsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) FM801_SINGLE("I2S Playback Switch", FM801_I2S_VOL, 15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) FM801_DOUBLE_TLV("FM Playback Volume", FM801_FM_VOL, 0, 8, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		 db_scale_dsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) FM801_SINGLE("FM Playback Switch", FM801_FM_VOL, 15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	.name = "Digital Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	.info = snd_fm801_info_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	.get = snd_fm801_get_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	.put = snd_fm801_put_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) #define FM801_CONTROLS_MULTI ARRAY_SIZE(snd_fm801_controls_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static const struct snd_kcontrol_new snd_fm801_controls_multi[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",PLAYBACK,SWITCH), FM801_I2S_MODE, 9, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",CAPTURE,SWITCH), FM801_I2S_MODE, 10, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), FM801_GEN_CTRL, 2, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static void snd_fm801_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	struct fm801 *chip = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	chip->ac97_bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static void snd_fm801_mixer_free_ac97(struct snd_ac97 *ac97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	struct fm801 *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	if (ac97->num == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		chip->ac97 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		chip->ac97_sec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int snd_fm801_mixer(struct fm801 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct snd_ac97_template ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	static const struct snd_ac97_bus_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		.write = snd_fm801_codec_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		.read = snd_fm801_codec_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	chip->ac97_bus->private_free = snd_fm801_mixer_free_ac97_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	memset(&ac97, 0, sizeof(ac97));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	ac97.private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	ac97.private_free = snd_fm801_mixer_free_ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	if (chip->secondary) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		ac97.num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		ac97.addr = chip->secondary_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	for (i = 0; i < FM801_CONTROLS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			snd_ctl_new1(&snd_fm801_controls[i], chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	if (chip->multichannel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		for (i = 0; i < FM801_CONTROLS_MULTI; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)  *  initialization routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static int wait_for_codec(struct fm801 *chip, unsigned int codec_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			  unsigned short reg, unsigned long waits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	unsigned long timeout = jiffies + waits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	fm801_writew(chip, AC97_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		     reg | (codec_id << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		if ((fm801_readw(chip, AC97_CMD) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		     (FM801_AC97_VALID | FM801_AC97_BUSY)) == FM801_AC97_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	} while (time_after(timeout, jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int reset_codec(struct fm801 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	/* codec cold reset + AC'97 warm reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	fm801_writew(chip, CODEC_CTRL, (1 << 5) | (1 << 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	fm801_readw(chip, CODEC_CTRL); /* flush posting data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	fm801_writew(chip, CODEC_CTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	return wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) static void snd_fm801_chip_multichannel_init(struct fm801 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	unsigned short cmdw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	if (chip->multichannel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		if (chip->secondary_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			wait_for_codec(chip, chip->secondary_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 				       AC97_VENDOR_ID1, msecs_to_jiffies(50));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			/* my card has the secondary codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			/* at address #3, so the loop is inverted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 			for (i = 3; i > 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 				if (!wait_for_codec(chip, i, AC97_VENDOR_ID1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 						     msecs_to_jiffies(50))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 					cmdw = fm801_readw(chip, AC97_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 					if (cmdw != 0xffff && cmdw != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 						chip->secondary = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 						chip->secondary_addr = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		/* the recovery phase, it seems that probing for non-existing codec might */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		/* cause timeout problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static void snd_fm801_chip_init(struct fm801 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	unsigned short cmdw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	/* init volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	fm801_writew(chip, PCM_VOL, 0x0808);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	fm801_writew(chip, FM_VOL, 0x9f1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	fm801_writew(chip, I2S_VOL, 0x8808);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	/* I2S control - I2S mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	fm801_writew(chip, I2S_MODE, 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	/* interrupt setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	cmdw = fm801_readw(chip, IRQ_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (chip->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		cmdw |= 0x00c3;		/* mask everything, no PCM nor MPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		cmdw &= ~0x0083;	/* unmask MPU, PLAYBACK & CAPTURE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	fm801_writew(chip, IRQ_MASK, cmdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	/* interrupt clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	fm801_writew(chip, IRQ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		     FM801_IRQ_PLAYBACK | FM801_IRQ_CAPTURE | FM801_IRQ_MPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) static int snd_fm801_free(struct fm801 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	unsigned short cmdw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	if (chip->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		goto __end_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	/* interrupt setup - mask everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	cmdw = fm801_readw(chip, IRQ_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	cmdw |= 0x00c3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	fm801_writew(chip, IRQ_MASK, cmdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	devm_free_irq(chip->dev, chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)       __end_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) #ifdef CONFIG_SND_FM801_TEA575X_BOOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		snd_tea575x_exit(&chip->tea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		v4l2_device_unregister(&chip->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static int snd_fm801_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	struct fm801 *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	return snd_fm801_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) static int snd_fm801_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			    struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 			    int tea575x_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 			    int radio_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			    struct fm801 **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	struct fm801 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		.dev_free =	snd_fm801_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	*rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	if ((err = pcim_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	if (chip == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	spin_lock_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	chip->dev = &pci->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	chip->tea575x_tuner = tea575x_tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	if ((err = pci_request_regions(pci, "FM801")) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	chip->port = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	if (pci->revision >= 0xb1)	/* FM801-AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		chip->multichannel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	if (!(chip->tea575x_tuner & TUNER_ONLY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 		if (reset_codec(chip) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 			dev_info(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 				 "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			chip->tea575x_tuner = 3 | TUNER_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 			snd_fm801_chip_multichannel_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if ((chip->tea575x_tuner & TUNER_ONLY) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 				IRQF_SHARED, KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 			dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 			snd_fm801_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	snd_fm801_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		snd_fm801_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) #ifdef CONFIG_SND_FM801_TEA575X_BOOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		snd_fm801_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	chip->tea.v4l2_dev = &chip->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	chip->tea.radio_nr = radio_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	chip->tea.private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	chip->tea.ops = &snd_fm801_tea_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	if ((chip->tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	    (chip->tea575x_tuner & TUNER_TYPE_MASK) < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		if (snd_tea575x_init(&chip->tea, THIS_MODULE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			dev_err(card->dev, "TEA575x radio not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			snd_fm801_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	} else if ((chip->tea575x_tuner & TUNER_TYPE_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		unsigned int tuner_only = chip->tea575x_tuner & TUNER_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		/* autodetect tuner connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			chip->tea575x_tuner = tea575x_tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 			if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 				dev_info(card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 					 "detected TEA575x radio type %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 					   get_tea575x_gpio(chip)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		if (tea575x_tuner == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 			dev_err(card->dev, "TEA575x radio not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 			chip->tea575x_tuner = TUNER_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		chip->tea575x_tuner |= tuner_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 			sizeof(chip->tea.card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	*rchip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static int snd_card_fm801_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 				const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	struct fm801 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	struct snd_opl3 *opl3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)         if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)                 return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 			   0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	card->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	strcpy(card->driver, "FM801");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	strcpy(card->shortname, "ForteMedia FM801-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	strcat(card->shortname, chip->multichannel ? "AU" : "AS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	sprintf(card->longname, "%s at 0x%lx, irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		card->shortname, chip->port, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	if (chip->tea575x_tuner & TUNER_ONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		goto __fm801_tuner_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	if ((err = snd_fm801_pcm(chip, 0)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	if ((err = snd_fm801_mixer(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 				       chip->port + FM801_MPU401_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 				       MPU401_INFO_INTEGRATED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 				       MPU401_INFO_IRQ_HOOK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 				       -1, &chip->rmidi)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	if ((err = snd_opl3_create(card, chip->port + FM801_OPL3_BANK0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 				   chip->port + FM801_OPL3_BANK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 				   OPL3_HW_OPL3_FM801, 1, &opl3)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)       __fm801_tuner_only:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	if ((err = snd_card_register(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) static void snd_card_fm801_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) static const unsigned char saved_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	FM801_PLY_CTRL, FM801_PLY_COUNT, FM801_PLY_BUF1, FM801_PLY_BUF2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	FM801_CAP_CTRL, FM801_CAP_COUNT, FM801_CAP_BUF1, FM801_CAP_BUF2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static int snd_fm801_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	struct fm801 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		chip->saved_regs[i] = fm801_ioread16(chip, saved_regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	if (chip->tea575x_tuner & TUNER_ONLY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		/* FIXME: tea575x suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		snd_ac97_suspend(chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		snd_ac97_suspend(chip->ac97_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static int snd_fm801_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	struct fm801 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	if (chip->tea575x_tuner & TUNER_ONLY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		snd_fm801_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 		reset_codec(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 		snd_fm801_chip_multichannel_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 		snd_fm801_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		snd_ac97_resume(chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		snd_ac97_resume(chip->ac97_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		fm801_iowrite16(chip, saved_regs[i], chip->saved_regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) #ifdef CONFIG_SND_FM801_TEA575X_BOOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	if (!(chip->tea575x_tuner & TUNER_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		snd_tea575x_set_freq(&chip->tea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static SIMPLE_DEV_PM_OPS(snd_fm801_pm, snd_fm801_suspend, snd_fm801_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) #define SND_FM801_PM_OPS	&snd_fm801_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) #define SND_FM801_PM_OPS	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static struct pci_driver fm801_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	.name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	.id_table = snd_fm801_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	.probe = snd_card_fm801_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	.remove = snd_card_fm801_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		.pm = SND_FM801_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) module_pci_driver(fm801_driver);