1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2d0ce9946SClemens Ladisch #ifndef OXYGEN_H_INCLUDED
3d0ce9946SClemens Ladisch #define OXYGEN_H_INCLUDED
4d0ce9946SClemens Ladisch
5d0ce9946SClemens Ladisch #include <linux/mutex.h>
6d0ce9946SClemens Ladisch #include <linux/spinlock.h>
71e821dd2SClemens Ladisch #include <linux/wait.h>
8d0ce9946SClemens Ladisch #include <linux/workqueue.h>
9d0ce9946SClemens Ladisch #include "oxygen_regs.h"
10d0ce9946SClemens Ladisch
11d0ce9946SClemens Ladisch /* 1 << PCM_x == OXYGEN_CHANNEL_x */
12d0ce9946SClemens Ladisch #define PCM_A 0
13d0ce9946SClemens Ladisch #define PCM_B 1
14d0ce9946SClemens Ladisch #define PCM_C 2
15d0ce9946SClemens Ladisch #define PCM_SPDIF 3
16d0ce9946SClemens Ladisch #define PCM_MULTICH 4
17d0ce9946SClemens Ladisch #define PCM_AC97 5
18d0ce9946SClemens Ladisch #define PCM_COUNT 6
19d0ce9946SClemens Ladisch
205b8bf2a5SClemens Ladisch #define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \
215b8bf2a5SClemens Ladisch (MCLK_##f_double << 2) | \
225b8bf2a5SClemens Ladisch (MCLK_##f_quad << 4))
235b8bf2a5SClemens Ladisch
24c1365007SClemens Ladisch #define OXYGEN_IO_SIZE 0x100
25c1365007SClemens Ladisch
261275d6f6SClemens Ladisch #define OXYGEN_EEPROM_ID 0x434d /* "CM" */
271275d6f6SClemens Ladisch
28f009ad9bSClemens Ladisch /* model-specific configuration of outputs/inputs */
29dbbbd674SClemens Ladisch #define PLAYBACK_0_TO_I2S 0x0001
30dbbbd674SClemens Ladisch /* PLAYBACK_0_TO_AC97_0 not implemented */
31dbbbd674SClemens Ladisch #define PLAYBACK_1_TO_SPDIF 0x0004
32dbbbd674SClemens Ladisch #define PLAYBACK_2_TO_AC97_1 0x0008
33dbbbd674SClemens Ladisch #define CAPTURE_0_FROM_I2S_1 0x0010
34dbbbd674SClemens Ladisch #define CAPTURE_0_FROM_I2S_2 0x0020
35dbbbd674SClemens Ladisch /* CAPTURE_0_FROM_AC97_0 not implemented */
36dbbbd674SClemens Ladisch #define CAPTURE_1_FROM_SPDIF 0x0080
37dbbbd674SClemens Ladisch #define CAPTURE_2_FROM_I2S_2 0x0100
38dbbbd674SClemens Ladisch #define CAPTURE_2_FROM_AC97_1 0x0200
390902fbb9SClemens Ladisch #define CAPTURE_3_FROM_I2S_3 0x0400
40dbbbd674SClemens Ladisch #define MIDI_OUTPUT 0x0800
41dbbbd674SClemens Ladisch #define MIDI_INPUT 0x1000
42b6ca8ab3SClemens Ladisch #define AC97_CD_INPUT 0x2000
43e96f38f7SClemens Ladisch #define AC97_FMIC_SWITCH 0x4000
44f009ad9bSClemens Ladisch
4501a3affbSClemens Ladisch enum {
4601a3affbSClemens Ladisch CONTROL_SPDIF_PCM,
4701a3affbSClemens Ladisch CONTROL_SPDIF_INPUT_BITS,
48893e44baSClemens Ladisch CONTROL_MIC_CAPTURE_SWITCH,
49893e44baSClemens Ladisch CONTROL_LINE_CAPTURE_SWITCH,
50893e44baSClemens Ladisch CONTROL_CD_CAPTURE_SWITCH,
51893e44baSClemens Ladisch CONTROL_AUX_CAPTURE_SWITCH,
5201a3affbSClemens Ladisch CONTROL_COUNT
5301a3affbSClemens Ladisch };
5401a3affbSClemens Ladisch
55d0ce9946SClemens Ladisch #define OXYGEN_PCI_SUBID(sv, sd) \
56d0ce9946SClemens Ladisch .vendor = PCI_VENDOR_ID_CMEDIA, \
57d0ce9946SClemens Ladisch .device = 0x8788, \
58d0ce9946SClemens Ladisch .subvendor = sv, \
59d0ce9946SClemens Ladisch .subdevice = sd
60d0ce9946SClemens Ladisch
6130459d7bSClemens Ladisch #define BROKEN_EEPROM_DRIVER_DATA ((unsigned long)-1)
6230459d7bSClemens Ladisch #define OXYGEN_PCI_SUBID_BROKEN_EEPROM \
6330459d7bSClemens Ladisch OXYGEN_PCI_SUBID(PCI_VENDOR_ID_CMEDIA, 0x8788), \
6430459d7bSClemens Ladisch .driver_data = BROKEN_EEPROM_DRIVER_DATA
6530459d7bSClemens Ladisch
66d0ce9946SClemens Ladisch struct pci_dev;
6730459d7bSClemens Ladisch struct pci_device_id;
68d0ce9946SClemens Ladisch struct snd_card;
69d0ce9946SClemens Ladisch struct snd_pcm_substream;
70747c6016SClemens Ladisch struct snd_pcm_hardware;
71d0ce9946SClemens Ladisch struct snd_pcm_hw_params;
72ccc80fb4SClemens Ladisch struct snd_kcontrol_new;
73d0ce9946SClemens Ladisch struct snd_rawmidi;
749719fcaaSClemens Ladisch struct snd_info_buffer;
759bd6a73aSClemens Ladisch struct oxygen;
76d0ce9946SClemens Ladisch
77d0ce9946SClemens Ladisch struct oxygen_model {
78d0ce9946SClemens Ladisch const char *shortname;
79d0ce9946SClemens Ladisch const char *longname;
80d0ce9946SClemens Ladisch const char *chip;
81d0ce9946SClemens Ladisch void (*init)(struct oxygen *chip);
82ccc80fb4SClemens Ladisch int (*control_filter)(struct snd_kcontrol_new *template);
83d0ce9946SClemens Ladisch int (*mixer_init)(struct oxygen *chip);
84d0ce9946SClemens Ladisch void (*cleanup)(struct oxygen *chip);
854a4bc53bSClemens Ladisch void (*suspend)(struct oxygen *chip);
864a4bc53bSClemens Ladisch void (*resume)(struct oxygen *chip);
87747c6016SClemens Ladisch void (*pcm_hardware_filter)(unsigned int channel,
88747c6016SClemens Ladisch struct snd_pcm_hardware *hardware);
89d0ce9946SClemens Ladisch void (*set_dac_params)(struct oxygen *chip,
90d0ce9946SClemens Ladisch struct snd_pcm_hw_params *params);
91d0ce9946SClemens Ladisch void (*set_adc_params)(struct oxygen *chip,
92d0ce9946SClemens Ladisch struct snd_pcm_hw_params *params);
93d0ce9946SClemens Ladisch void (*update_dac_volume)(struct oxygen *chip);
94d0ce9946SClemens Ladisch void (*update_dac_mute)(struct oxygen *chip);
953d8bb454SClemens Ladisch void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
96efbeb071SClemens Ladisch unsigned int (*adjust_dac_routing)(struct oxygen *chip,
97efbeb071SClemens Ladisch unsigned int play_routing);
987c014159SClemens Ladisch void (*gpio_changed)(struct oxygen *chip);
99397b1dccSClemens Ladisch void (*uart_input)(struct oxygen *chip);
10011864b4bSClemens Ladisch void (*ac97_switch)(struct oxygen *chip,
10111864b4bSClemens Ladisch unsigned int reg, unsigned int mute);
1029719fcaaSClemens Ladisch void (*dump_registers)(struct oxygen *chip,
1039719fcaaSClemens Ladisch struct snd_info_buffer *buffer);
1044972a177SClemens Ladisch const unsigned int *dac_tlv;
1057ef37cd9SClemens Ladisch size_t model_data_size;
106d76596b1SClemens Ladisch unsigned int device_config;
1071f4d7be7SClemens Ladisch u8 dac_channels_pcm;
1081f4d7be7SClemens Ladisch u8 dac_channels_mixer;
109193e8138SClemens Ladisch u8 dac_volume_min;
110193e8138SClemens Ladisch u8 dac_volume_max;
111db12b8e3SClemens Ladisch u8 misc_flags;
11284aa6b7bSClemens Ladisch u8 function_flags;
1135b8bf2a5SClemens Ladisch u8 dac_mclks;
1145b8bf2a5SClemens Ladisch u8 adc_mclks;
11505855ba3SClemens Ladisch u16 dac_i2s_format;
11605855ba3SClemens Ladisch u16 adc_i2s_format;
117d0ce9946SClemens Ladisch };
118d0ce9946SClemens Ladisch
1199bd6a73aSClemens Ladisch struct oxygen {
1209bd6a73aSClemens Ladisch unsigned long addr;
1219bd6a73aSClemens Ladisch spinlock_t reg_lock;
1229bd6a73aSClemens Ladisch struct mutex mutex;
1239bd6a73aSClemens Ladisch struct snd_card *card;
1249bd6a73aSClemens Ladisch struct pci_dev *pci;
1259bd6a73aSClemens Ladisch struct snd_rawmidi *midi;
1269bd6a73aSClemens Ladisch int irq;
1279bd6a73aSClemens Ladisch void *model_data;
1289bd6a73aSClemens Ladisch unsigned int interrupt_mask;
1299bd6a73aSClemens Ladisch u8 dac_volume[8];
1309bd6a73aSClemens Ladisch u8 dac_mute;
1319bd6a73aSClemens Ladisch u8 pcm_active;
1329bd6a73aSClemens Ladisch u8 pcm_running;
1339bd6a73aSClemens Ladisch u8 dac_routing;
1349bd6a73aSClemens Ladisch u8 spdif_playback_enable;
1359bd6a73aSClemens Ladisch u8 has_ac97_0;
1369bd6a73aSClemens Ladisch u8 has_ac97_1;
1379bd6a73aSClemens Ladisch u32 spdif_bits;
1389bd6a73aSClemens Ladisch u32 spdif_pcm_bits;
1399bd6a73aSClemens Ladisch struct snd_pcm_substream *streams[PCM_COUNT];
1409bd6a73aSClemens Ladisch struct snd_kcontrol *controls[CONTROL_COUNT];
1419bd6a73aSClemens Ladisch struct work_struct spdif_input_bits_work;
1429bd6a73aSClemens Ladisch struct work_struct gpio_work;
1439bd6a73aSClemens Ladisch wait_queue_head_t ac97_waitqueue;
1449bd6a73aSClemens Ladisch union {
1459bd6a73aSClemens Ladisch u8 _8[OXYGEN_IO_SIZE];
1469bd6a73aSClemens Ladisch __le16 _16[OXYGEN_IO_SIZE / 2];
1479bd6a73aSClemens Ladisch __le32 _32[OXYGEN_IO_SIZE / 4];
1489bd6a73aSClemens Ladisch } saved_registers;
1499bd6a73aSClemens Ladisch u16 saved_ac97_registers[2][0x40];
150397b1dccSClemens Ladisch unsigned int uart_input_count;
151397b1dccSClemens Ladisch u8 uart_input[32];
1529bd6a73aSClemens Ladisch struct oxygen_model model;
1539bd6a73aSClemens Ladisch };
1549bd6a73aSClemens Ladisch
155d0ce9946SClemens Ladisch /* oxygen_lib.c */
156d0ce9946SClemens Ladisch
157db12b8e3SClemens Ladisch int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
158bb718588SClemens Ladisch struct module *owner,
15930459d7bSClemens Ladisch const struct pci_device_id *ids,
16030459d7bSClemens Ladisch int (*get_model)(struct oxygen *chip,
16130459d7bSClemens Ladisch const struct pci_device_id *id
16230459d7bSClemens Ladisch )
16330459d7bSClemens Ladisch );
164c7561cd8STakashi Iwai #ifdef CONFIG_PM_SLEEP
16568cb2b55STakashi Iwai extern const struct dev_pm_ops oxygen_pci_pm;
1664a4bc53bSClemens Ladisch #endif
1674c25b932SClemens Ladisch void oxygen_pci_shutdown(struct pci_dev *pci);
168d0ce9946SClemens Ladisch
169d0ce9946SClemens Ladisch /* oxygen_mixer.c */
170d0ce9946SClemens Ladisch
171d0ce9946SClemens Ladisch int oxygen_mixer_init(struct oxygen *chip);
172d0ce9946SClemens Ladisch void oxygen_update_dac_routing(struct oxygen *chip);
173d0ce9946SClemens Ladisch void oxygen_update_spdif_source(struct oxygen *chip);
174d0ce9946SClemens Ladisch
175d0ce9946SClemens Ladisch /* oxygen_pcm.c */
176d0ce9946SClemens Ladisch
177d0ce9946SClemens Ladisch int oxygen_pcm_init(struct oxygen *chip);
178d0ce9946SClemens Ladisch
179d0ce9946SClemens Ladisch /* oxygen_io.c */
180d0ce9946SClemens Ladisch
181d0ce9946SClemens Ladisch u8 oxygen_read8(struct oxygen *chip, unsigned int reg);
182d0ce9946SClemens Ladisch u16 oxygen_read16(struct oxygen *chip, unsigned int reg);
183d0ce9946SClemens Ladisch u32 oxygen_read32(struct oxygen *chip, unsigned int reg);
184d0ce9946SClemens Ladisch void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value);
185d0ce9946SClemens Ladisch void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value);
186d0ce9946SClemens Ladisch void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value);
187d0ce9946SClemens Ladisch void oxygen_write8_masked(struct oxygen *chip, unsigned int reg,
188d0ce9946SClemens Ladisch u8 value, u8 mask);
189d0ce9946SClemens Ladisch void oxygen_write16_masked(struct oxygen *chip, unsigned int reg,
190d0ce9946SClemens Ladisch u16 value, u16 mask);
191d0ce9946SClemens Ladisch void oxygen_write32_masked(struct oxygen *chip, unsigned int reg,
192d0ce9946SClemens Ladisch u32 value, u32 mask);
193d0ce9946SClemens Ladisch
194d0ce9946SClemens Ladisch u16 oxygen_read_ac97(struct oxygen *chip, unsigned int codec,
195d0ce9946SClemens Ladisch unsigned int index);
196d0ce9946SClemens Ladisch void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,
197d0ce9946SClemens Ladisch unsigned int index, u16 data);
198d0ce9946SClemens Ladisch void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
199d0ce9946SClemens Ladisch unsigned int index, u16 data, u16 mask);
200d0ce9946SClemens Ladisch
201303cff30SRoman Volkov int oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
20210e6d5f9SClemens Ladisch void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
203d0ce9946SClemens Ladisch
204397b1dccSClemens Ladisch void oxygen_reset_uart(struct oxygen *chip);
205397b1dccSClemens Ladisch void oxygen_write_uart(struct oxygen *chip, u8 data);
206397b1dccSClemens Ladisch
20730459d7bSClemens Ladisch u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index);
2081275d6f6SClemens Ladisch void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value);
20930459d7bSClemens Ladisch
oxygen_set_bits8(struct oxygen * chip,unsigned int reg,u8 value)210d0ce9946SClemens Ladisch static inline void oxygen_set_bits8(struct oxygen *chip,
211d0ce9946SClemens Ladisch unsigned int reg, u8 value)
212d0ce9946SClemens Ladisch {
213d0ce9946SClemens Ladisch oxygen_write8_masked(chip, reg, value, value);
214d0ce9946SClemens Ladisch }
215d0ce9946SClemens Ladisch
oxygen_set_bits16(struct oxygen * chip,unsigned int reg,u16 value)216d0ce9946SClemens Ladisch static inline void oxygen_set_bits16(struct oxygen *chip,
217d0ce9946SClemens Ladisch unsigned int reg, u16 value)
218d0ce9946SClemens Ladisch {
219d0ce9946SClemens Ladisch oxygen_write16_masked(chip, reg, value, value);
220d0ce9946SClemens Ladisch }
221d0ce9946SClemens Ladisch
oxygen_set_bits32(struct oxygen * chip,unsigned int reg,u32 value)222d0ce9946SClemens Ladisch static inline void oxygen_set_bits32(struct oxygen *chip,
223d0ce9946SClemens Ladisch unsigned int reg, u32 value)
224d0ce9946SClemens Ladisch {
225d0ce9946SClemens Ladisch oxygen_write32_masked(chip, reg, value, value);
226d0ce9946SClemens Ladisch }
227d0ce9946SClemens Ladisch
oxygen_clear_bits8(struct oxygen * chip,unsigned int reg,u8 value)228d0ce9946SClemens Ladisch static inline void oxygen_clear_bits8(struct oxygen *chip,
229d0ce9946SClemens Ladisch unsigned int reg, u8 value)
230d0ce9946SClemens Ladisch {
231d0ce9946SClemens Ladisch oxygen_write8_masked(chip, reg, 0, value);
232d0ce9946SClemens Ladisch }
233d0ce9946SClemens Ladisch
oxygen_clear_bits16(struct oxygen * chip,unsigned int reg,u16 value)234d0ce9946SClemens Ladisch static inline void oxygen_clear_bits16(struct oxygen *chip,
235d0ce9946SClemens Ladisch unsigned int reg, u16 value)
236d0ce9946SClemens Ladisch {
237d0ce9946SClemens Ladisch oxygen_write16_masked(chip, reg, 0, value);
238d0ce9946SClemens Ladisch }
239d0ce9946SClemens Ladisch
oxygen_clear_bits32(struct oxygen * chip,unsigned int reg,u32 value)240d0ce9946SClemens Ladisch static inline void oxygen_clear_bits32(struct oxygen *chip,
241d0ce9946SClemens Ladisch unsigned int reg, u32 value)
242d0ce9946SClemens Ladisch {
243d0ce9946SClemens Ladisch oxygen_write32_masked(chip, reg, 0, value);
244d0ce9946SClemens Ladisch }
245d0ce9946SClemens Ladisch
oxygen_ac97_set_bits(struct oxygen * chip,unsigned int codec,unsigned int index,u16 value)246d0ce9946SClemens Ladisch static inline void oxygen_ac97_set_bits(struct oxygen *chip, unsigned int codec,
247d0ce9946SClemens Ladisch unsigned int index, u16 value)
248d0ce9946SClemens Ladisch {
249d0ce9946SClemens Ladisch oxygen_write_ac97_masked(chip, codec, index, value, value);
250d0ce9946SClemens Ladisch }
251d0ce9946SClemens Ladisch
oxygen_ac97_clear_bits(struct oxygen * chip,unsigned int codec,unsigned int index,u16 value)252d0ce9946SClemens Ladisch static inline void oxygen_ac97_clear_bits(struct oxygen *chip,
253d0ce9946SClemens Ladisch unsigned int codec,
254d0ce9946SClemens Ladisch unsigned int index, u16 value)
255d0ce9946SClemens Ladisch {
256d0ce9946SClemens Ladisch oxygen_write_ac97_masked(chip, codec, index, 0, value);
257d0ce9946SClemens Ladisch }
258d0ce9946SClemens Ladisch
259d0ce9946SClemens Ladisch #endif
260