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