^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) * ALSA driver for ICEnsemble ICE1712 (Envy24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * 2002 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/cs8427.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "ice1712.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ews.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define SND_CS8404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/cs8403.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) EWS_I2C_CS8404 = 0, EWS_I2C_PCF1, EWS_I2C_PCF2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) EWS_I2C_88D = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) EWS_I2C_6FIRE = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* additional i2c devices for EWS boards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct ews_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct snd_i2c_device *i2cdevs[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * access via i2c mode (for EWX 24/96, EWS 88MT&D)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* send SDA and SCL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static void ewx_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned char tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) tmp |= ICE1712_EWX2496_SERIAL_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) tmp |= ICE1712_EWX2496_SERIAL_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int ewx_i2c_getclock(struct snd_i2c_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int ewx_i2c_getdata(struct snd_i2c_bus *bus, int ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* set RW pin to low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) bit = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_DATA ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* set RW pin to high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_EWX2496_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* reset write mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_SERIAL_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void ewx_i2c_start(struct snd_i2c_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) unsigned char mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* set RW high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mask = ICE1712_EWX2496_RW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) case ICE1712_SUBDEVICE_EWX2496:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mask |= ICE1712_EWX2496_AK4524_CS; /* CS high also */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mask |= ICE1712_6FIRE_AK4524_CS_MASK; /* CS high also */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) snd_ice1712_gpio_write_bits(ice, mask, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void ewx_i2c_stop(struct snd_i2c_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void ewx_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned char mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ice->gpio.direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ice->gpio.direction |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio.direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static struct snd_i2c_bit_ops snd_ice1712_ewx_cs8427_bit_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .start = ewx_i2c_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .stop = ewx_i2c_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .direction = ewx_i2c_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .setlines = ewx_i2c_setlines,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .getclock = ewx_i2c_getclock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .getdata = ewx_i2c_getdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * AK4524 access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* AK4524 chip select; address 0x48 bit 0-3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned char data, ndata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (snd_BUG_ON(chip_mask < 0 || chip_mask > 0x0f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ndata = (data & 0xf0) | chip_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (ndata != data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], &ndata, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) __error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dev_err(ice->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "AK4524 chip select failed, check cable to the front module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* start callback for EWS88MT, needs to select a certain chip mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void ews88mt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct snd_ice1712 *ice = ak->private_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* assert AK4524 CS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) dev_err(ice->card->dev, "fatal error (ews88mt chip select)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) tmp = ICE1712_EWS88_SERIAL_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ICE1712_EWS88_SERIAL_CLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ICE1712_EWS88_RW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ice->gpio.direction | tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* stop callback for EWS88MT, needs to deselect chip mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void ews88mt_ak4524_unlock(struct snd_akm4xxx *ak, int chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct snd_ice1712 *ice = ak->private_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) snd_ice1712_ews88mt_chip_select(ice, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* start callback for EWX24/96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void ewx2496_ak4524_lock(struct snd_akm4xxx *ak, int chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct snd_ice1712 *ice = ak->private_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) tmp = ICE1712_EWX2496_SERIAL_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ICE1712_EWX2496_SERIAL_CLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ICE1712_EWX2496_AK4524_CS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ICE1712_EWX2496_RW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ice->gpio.direction | tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* start callback for DMX 6fire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void dmx6fire_ak4524_lock(struct snd_akm4xxx *ak, int chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct snd_ice1712 *ice = ak->private_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) tmp = priv->cs_mask = priv->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) tmp |= ICE1712_6FIRE_SERIAL_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ICE1712_6FIRE_SERIAL_CLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ICE1712_6FIRE_RW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ice->gpio.direction | tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * CS8404 interface on EWS88MT/D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned char bytes[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_CS8404], &bits, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case ICE1712_SUBDEVICE_EWS88D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], bytes, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (bits != bytes[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bytes[1] = bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) bytes, 2) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) _error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /*
^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) static void ews88_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int ews88_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_lock_irq(&ice->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) change = ice->spdif.cs8403_bits != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ice->spdif.cs8403_bits = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (change && ice->playback_pro_substream == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) spin_unlock_irq(&ice->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) snd_ice1712_ews_cs8404_spdif_write(ice, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_unlock_irq(&ice->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void ews88_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int ews88_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) spin_lock_irq(&ice->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) change = ice->spdif.cs8403_stream_bits != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ice->spdif.cs8403_stream_bits = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (change && ice->playback_pro_substream != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) spin_unlock_irq(&ice->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) snd_ice1712_ews_cs8404_spdif_write(ice, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) spin_unlock_irq(&ice->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^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) /* open callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static void ews88_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* set up SPDIF for EWS88MT / EWS88D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) spin_lock_irqsave(&ice->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) tmp = ice->spdif.cs8403_stream_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (tmp & 0x10) /* consumer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) change = ice->spdif.cs8403_stream_bits != tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ice->spdif.cs8403_stream_bits = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) spin_unlock_irqrestore(&ice->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) snd_ice1712_ews_cs8404_spdif_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static const struct snd_akm4xxx akm_ews88mt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .num_adcs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .num_dacs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .type = SND_AK4524,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .lock = ews88mt_ak4524_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .unlock = ews88mt_ak4524_unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static const struct snd_ak4xxx_private akm_ews88mt_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .caddr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .cif = 1, /* CIF high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .data_mask = ICE1712_EWS88_SERIAL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .cs_mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .cs_addr = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .cs_none = 0, /* no chip select on gpio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static const struct snd_akm4xxx akm_ewx2496 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .num_adcs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .num_dacs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) .type = SND_AK4524,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .lock = ewx2496_ak4524_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static const struct snd_ak4xxx_private akm_ewx2496_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .caddr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .cif = 1, /* CIF high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .data_mask = ICE1712_EWS88_SERIAL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .cs_mask = ICE1712_EWX2496_AK4524_CS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .cs_addr = ICE1712_EWX2496_AK4524_CS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .cs_none = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .mask_flags = 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) static const struct snd_akm4xxx akm_6fire = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .num_adcs = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .num_dacs = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .type = SND_AK4524,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .lock = dmx6fire_ak4524_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static const struct snd_ak4xxx_private akm_6fire_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .caddr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .cif = 1, /* CIF high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .data_mask = ICE1712_6FIRE_SERIAL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .clk_mask = ICE1712_6FIRE_SERIAL_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .cs_mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .cs_addr = 0, /* set later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .cs_none = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .add_flags = ICE1712_6FIRE_RW, /* set rw bit high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * initialize the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* 6fire specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #define PCF9554_REG_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) #define PCF9554_REG_OUTPUT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #define PCF9554_REG_POLARITY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #define PCF9554_REG_CONFIG 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static int snd_ice1712_ews_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct snd_akm4xxx *ak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct ews_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* set the analog DACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case ICE1712_SUBDEVICE_EWX2496:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ice->num_total_dacs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ice->num_total_adcs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ice->num_total_dacs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ice->num_total_adcs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case ICE1712_SUBDEVICE_EWS88D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* Note: not analog but ADAT I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ice->num_total_dacs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ice->num_total_adcs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ice->num_total_dacs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ice->num_total_adcs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ice->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* create i2c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dev_err(ice->card->dev, "unable to create I2C bus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ice->i2c->private_data = ice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ice->i2c->hw_ops.bit = &snd_ice1712_ewx_cs8427_bit_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* create i2c devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) err = snd_i2c_device_create(ice->i2c, "PCF9554",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ICE1712_6FIRE_PCF9554_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) &spec->i2cdevs[EWS_I2C_6FIRE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev_err(ice->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) "PCF9554 initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) err = snd_i2c_device_create(ice->i2c, "CS8404",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ICE1712_EWS88MT_CS8404_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) &spec->i2cdevs[EWS_I2C_CS8404]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ICE1712_EWS88MT_INPUT_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) &spec->i2cdevs[EWS_I2C_PCF1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ICE1712_EWS88MT_OUTPUT_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) &spec->i2cdevs[EWS_I2C_PCF2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Check if the front module is connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case ICE1712_SUBDEVICE_EWS88D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) err = snd_i2c_device_create(ice->i2c, "PCF8575",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ICE1712_EWS88D_PCF_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) &spec->i2cdevs[EWS_I2C_88D]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^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) /* set up SPDIF interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case ICE1712_SUBDEVICE_EWX2496:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case ICE1712_SUBDEVICE_EWS88D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* set up CS8404 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ice->spdif.ops.open = ews88_open_spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ice->spdif.ops.setup_rate = ews88_setup_spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ice->spdif.ops.default_get = ews88_spdif_default_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ice->spdif.ops.default_put = ews88_spdif_default_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ice->spdif.ops.stream_get = ews88_spdif_stream_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ice->spdif.ops.stream_put = ews88_spdif_stream_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* Set spdif defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) snd_ice1712_ews_cs8404_spdif_write(ice, ice->spdif.cs8403_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* no analog? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case ICE1712_SUBDEVICE_EWS88D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* analog section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (! ak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ice->akm_codecs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) err = snd_ice1712_akm4xxx_init(ak, &akm_ews88mt, &akm_ews88mt_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case ICE1712_SUBDEVICE_EWX2496:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) err = snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, &akm_ewx2496_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) err = snd_ice1712_akm4xxx_init(ak, &akm_6fire, &akm_6fire_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return err;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * EWX 24/96 specific controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* i/o sensitivity - this callback is shared among other devices, too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static const char * const texts[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) "+4dBu", "-10dBV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return snd_ctl_enum_info(uinfo, 1, 2, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) unsigned char mask = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned char mask = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int val, nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (kcontrol->private_value & (1 << 31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) nval = ucontrol->value.enumerated.item[0] ? mask : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) nval |= val & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return val != nval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .name = "Input Sensitivity Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .info = snd_ice1712_ewx_io_sense_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .get = snd_ice1712_ewx_io_sense_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .put = snd_ice1712_ewx_io_sense_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .private_value = ICE1712_EWX2496_AIN_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) .name = "Output Sensitivity Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .info = snd_ice1712_ewx_io_sense_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .get = snd_ice1712_ewx_io_sense_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .put = snd_ice1712_ewx_io_sense_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .private_value = ICE1712_EWX2496_AOUT_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * EWS88MT specific controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* analog output sensitivity;; address 0x48 bit 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) unsigned char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* analog output sensitivity;; address 0x48 bit 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned char data, ndata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) &ndata, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return ndata != data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* analog input sensitivity; address 0x46 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) unsigned char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (snd_BUG_ON(channel < 0 || channel > 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* reversed; high = +4dBu, low = -10dBV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* analog output sensitivity; address 0x46 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) unsigned char data, ndata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (snd_BUG_ON(channel < 0 || channel > 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) &ndata, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return ndata != data;
^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_kcontrol_new snd_ice1712_ews88mt_input_sense = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) .name = "Input Sensitivity Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) .info = snd_ice1712_ewx_io_sense_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .get = snd_ice1712_ews88mt_input_sense_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) .put = snd_ice1712_ews88mt_input_sense_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .count = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) .name = "Output Sensitivity Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .info = snd_ice1712_ewx_io_sense_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .get = snd_ice1712_ews88mt_output_sense_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .put = snd_ice1712_ews88mt_output_sense_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * EWS88D specific controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) #define snd_ice1712_ews88d_control_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int shift = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) int invert = (kcontrol->private_value >> 8) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) unsigned char data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) data[0] ^= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ucontrol->value.integer.value[0] = data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int shift = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int invert = (kcontrol->private_value >> 8) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned char data[2], ndata[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (! ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ndata[shift >> 3] |= (1 << (shift & 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ndata[shift >> 3] |= (1 << (shift & 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) change = (data[shift >> 3] != ndata[shift >> 3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (change &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) { .iface = xiface,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .name = xname,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .access = xaccess,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .info = snd_ice1712_ews88d_control_info,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .get = snd_ice1712_ews88d_control_get,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .put = snd_ice1712_ews88d_control_put,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .private_value = xshift | (xinvert << 8),\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * DMX 6Fire specific controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) byte = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dev_err(ice->card->dev, "cannot send pca\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dev_err(ice->card->dev, "cannot read pca\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unsigned char bytes[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct ews_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) snd_i2c_lock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) bytes[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) bytes[1] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) snd_i2c_unlock(ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) #define snd_ice1712_6fire_control_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int shift = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int invert = (kcontrol->private_value >> 8) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) data = (data >> shift) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) data ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ucontrol->value.integer.value[0] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) int shift = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) int invert = (kcontrol->private_value >> 8) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int data, ndata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ndata = data & ~(1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ndata |= (1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ndata ^= (1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (data != ndata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static const char * const texts[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) "Internal", "Front Input", "Rear Input", "Wave Table"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return snd_ctl_enum_info(uinfo, 1, 4, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ucontrol->value.integer.value[0] = data & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) int data, ndata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ndata = data & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ndata |= (ucontrol->value.integer.value[0] & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (data != ndata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) #define DMX6FIRE_CONTROL(xname, xshift, xinvert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .name = xname,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .info = snd_ice1712_6fire_control_info,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) .get = snd_ice1712_6fire_control_get,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) .put = snd_ice1712_6fire_control_put,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) .private_value = xshift | (xinvert << 8),\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .name = "Analog Input Select",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .info = snd_ice1712_6fire_select_input_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .get = snd_ice1712_6fire_select_input_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .put = snd_ice1712_6fire_select_input_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) // DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) DMX6FIRE_CONTROL("Breakbox LED", 6, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static int snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* all terratec cards have spdif, but cs8427 module builds it's own controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (ice->cs8427 == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) err = snd_ice1712_spdif_build_controls(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* ak4524 controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) case ICE1712_SUBDEVICE_EWX2496:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) err = snd_ice1712_akm4xxx_build_controls(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /* card specific controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) case ICE1712_SUBDEVICE_EWX2496:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) case ICE1712_SUBDEVICE_EWS88MT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) case ICE1712_SUBDEVICE_EWS88MT_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) case ICE1712_SUBDEVICE_PHASE88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case ICE1712_SUBDEVICE_TS88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case ICE1712_SUBDEVICE_EWS88D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) case ICE1712_SUBDEVICE_DMX6FIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* entry point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct snd_ice1712_card_info snd_ice1712_ews_cards[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .subvendor = ICE1712_SUBDEVICE_EWX2496,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .name = "TerraTec EWX24/96",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) .model = "ewx2496",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .build_controls = snd_ice1712_ews_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .subvendor = ICE1712_SUBDEVICE_EWS88MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .name = "TerraTec EWS88MT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .model = "ews88mt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .build_controls = snd_ice1712_ews_add_controls,
^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) .subvendor = ICE1712_SUBDEVICE_EWS88MT_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .name = "TerraTec EWS88MT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .model = "ews88mt_new",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .build_controls = snd_ice1712_ews_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .subvendor = ICE1712_SUBDEVICE_PHASE88,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .name = "TerraTec Phase88",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .model = "phase88",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .build_controls = snd_ice1712_ews_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .subvendor = ICE1712_SUBDEVICE_TS88,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .name = "terrasoniq TS88",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .model = "phase88",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .build_controls = snd_ice1712_ews_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .subvendor = ICE1712_SUBDEVICE_EWS88D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .name = "TerraTec EWS88D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .model = "ews88d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .build_controls = snd_ice1712_ews_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .subvendor = ICE1712_SUBDEVICE_DMX6FIRE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .name = "TerraTec DMX6Fire",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .model = "dmx6fire",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .chip_init = snd_ice1712_ews_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .build_controls = snd_ice1712_ews_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .mpu401_1_name = "MIDI-Front DMX6fire",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .mpu401_2_name = "Wavetable DMX6fire",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .mpu401_2_info_flags = MPU401_INFO_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) { } /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) };