xref: /openbmc/linux/sound/pci/ice1712/delta.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
41da177e4SLinus Torvalds  *
5ef2cd2ccSJaroslav Kysela  *   Lowlevel functions for M-Audio Delta 1010, 1010E, 44, 66, 66E, Dio2496,
6ef2cd2ccSJaroslav Kysela  *			    Audiophile, Digigram VX442
71da177e4SLinus Torvalds  *
8c1017a4cSJaroslav Kysela  *	Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include <linux/delay.h>
121da177e4SLinus Torvalds #include <linux/interrupt.h>
131da177e4SLinus Torvalds #include <linux/init.h>
141da177e4SLinus Torvalds #include <linux/slab.h>
1562932df8SIngo Molnar #include <linux/mutex.h>
1662932df8SIngo Molnar 
171da177e4SLinus Torvalds #include <sound/core.h>
181da177e4SLinus Torvalds #include <sound/cs8427.h>
191da177e4SLinus Torvalds #include <sound/asoundef.h>
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds #include "ice1712.h"
221da177e4SLinus Torvalds #include "delta.h"
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds #define SND_CS8403
251da177e4SLinus Torvalds #include <sound/cs8403.h>
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds /*
291da177e4SLinus Torvalds  * CS8427 via SPI mode (for Audiophile), emulated I2C
301da177e4SLinus Torvalds  */
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds /* send 8 bits */
ap_cs8427_write_byte(struct snd_ice1712 * ice,unsigned char data,unsigned char tmp)336ca308d4STakashi Iwai static void ap_cs8427_write_byte(struct snd_ice1712 *ice, unsigned char data, unsigned char tmp)
341da177e4SLinus Torvalds {
351da177e4SLinus Torvalds 	int idx;
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds 	for (idx = 7; idx >= 0; idx--) {
381da177e4SLinus Torvalds 		tmp &= ~(ICE1712_DELTA_AP_DOUT|ICE1712_DELTA_AP_CCLK);
391da177e4SLinus Torvalds 		if (data & (1 << idx))
401da177e4SLinus Torvalds 			tmp |= ICE1712_DELTA_AP_DOUT;
411da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
421da177e4SLinus Torvalds 		udelay(5);
431da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_AP_CCLK;
441da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
451da177e4SLinus Torvalds 		udelay(5);
461da177e4SLinus Torvalds 	}
471da177e4SLinus Torvalds }
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds /* read 8 bits */
ap_cs8427_read_byte(struct snd_ice1712 * ice,unsigned char tmp)506ca308d4STakashi Iwai static unsigned char ap_cs8427_read_byte(struct snd_ice1712 *ice, unsigned char tmp)
511da177e4SLinus Torvalds {
521da177e4SLinus Torvalds 	unsigned char data = 0;
531da177e4SLinus Torvalds 	int idx;
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds 	for (idx = 7; idx >= 0; idx--) {
561da177e4SLinus Torvalds 		tmp &= ~ICE1712_DELTA_AP_CCLK;
571da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
581da177e4SLinus Torvalds 		udelay(5);
591da177e4SLinus Torvalds 		if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN)
601da177e4SLinus Torvalds 			data |= 1 << idx;
611da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_AP_CCLK;
621da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
631da177e4SLinus Torvalds 		udelay(5);
641da177e4SLinus Torvalds 	}
651da177e4SLinus Torvalds 	return data;
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds /* assert chip select */
ap_cs8427_codec_select(struct snd_ice1712 * ice)696ca308d4STakashi Iwai static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
701da177e4SLinus Torvalds {
711da177e4SLinus Torvalds 	unsigned char tmp;
721da177e4SLinus Torvalds 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
731da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
74a60567d1SJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA1010E:
751da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
761da177e4SLinus Torvalds 		tmp &= ~ICE1712_DELTA_1010LT_CS;
771da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427;
781da177e4SLinus Torvalds 		break;
791da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_AUDIOPHILE:
801da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA410:
811da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
821da177e4SLinus Torvalds 		tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
831da177e4SLinus Torvalds 		break;
8493430096SBrian Bloniarz 	case ICE1712_SUBDEVICE_DELTA66E:
8593430096SBrian Bloniarz 		tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
8693430096SBrian Bloniarz 		       ICE1712_DELTA_66E_CS_CHIP_B;
8793430096SBrian Bloniarz 		tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
8893430096SBrian Bloniarz 		break;
891da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_VX442:
901da177e4SLinus Torvalds 		tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
911da177e4SLinus Torvalds 		tmp &= ~ICE1712_VX442_CS_DIGITAL;
921da177e4SLinus Torvalds 		break;
931da177e4SLinus Torvalds 	}
941da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
951da177e4SLinus Torvalds 	udelay(5);
961da177e4SLinus Torvalds 	return tmp;
971da177e4SLinus Torvalds }
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds /* deassert chip select */
ap_cs8427_codec_deassert(struct snd_ice1712 * ice,unsigned char tmp)1006ca308d4STakashi Iwai static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
1011da177e4SLinus Torvalds {
1021da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
103a60567d1SJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA1010E:
1041da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
1051da177e4SLinus Torvalds 		tmp &= ~ICE1712_DELTA_1010LT_CS;
1061da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_1010LT_CS_NONE;
1071da177e4SLinus Torvalds 		break;
1081da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_AUDIOPHILE:
1091da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA410:
1101da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
1111da177e4SLinus Torvalds 		break;
11293430096SBrian Bloniarz 	case ICE1712_SUBDEVICE_DELTA66E:
11393430096SBrian Bloniarz 		tmp |= ICE1712_DELTA_66E_CS_CS8427;
11493430096SBrian Bloniarz 		break;
1151da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_VX442:
1161da177e4SLinus Torvalds 		tmp |= ICE1712_VX442_CS_DIGITAL;
1171da177e4SLinus Torvalds 		break;
1181da177e4SLinus Torvalds 	}
1191da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds /* sequential write */
ap_cs8427_sendbytes(struct snd_i2c_device * device,unsigned char * bytes,int count)1236ca308d4STakashi Iwai static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
1241da177e4SLinus Torvalds {
1256ca308d4STakashi Iwai 	struct snd_ice1712 *ice = device->bus->private_data;
1261da177e4SLinus Torvalds 	int res = count;
1271da177e4SLinus Torvalds 	unsigned char tmp;
1281da177e4SLinus Torvalds 
12962932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
1301da177e4SLinus Torvalds 	tmp = ap_cs8427_codec_select(ice);
1311da177e4SLinus Torvalds 	ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */
1321da177e4SLinus Torvalds 	while (count-- > 0)
1331da177e4SLinus Torvalds 		ap_cs8427_write_byte(ice, *bytes++, tmp);
1341da177e4SLinus Torvalds 	ap_cs8427_codec_deassert(ice, tmp);
13562932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
1361da177e4SLinus Torvalds 	return res;
1371da177e4SLinus Torvalds }
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds /* sequential read */
ap_cs8427_readbytes(struct snd_i2c_device * device,unsigned char * bytes,int count)1406ca308d4STakashi Iwai static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
1411da177e4SLinus Torvalds {
1426ca308d4STakashi Iwai 	struct snd_ice1712 *ice = device->bus->private_data;
1431da177e4SLinus Torvalds 	int res = count;
1441da177e4SLinus Torvalds 	unsigned char tmp;
1451da177e4SLinus Torvalds 
14662932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
1471da177e4SLinus Torvalds 	tmp = ap_cs8427_codec_select(ice);
1481da177e4SLinus Torvalds 	ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */
1491da177e4SLinus Torvalds 	while (count-- > 0)
1501da177e4SLinus Torvalds 		*bytes++ = ap_cs8427_read_byte(ice, tmp);
1511da177e4SLinus Torvalds 	ap_cs8427_codec_deassert(ice, tmp);
15262932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
1531da177e4SLinus Torvalds 	return res;
1541da177e4SLinus Torvalds }
1551da177e4SLinus Torvalds 
ap_cs8427_probeaddr(struct snd_i2c_bus * bus,unsigned short addr)1566ca308d4STakashi Iwai static int ap_cs8427_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
1571da177e4SLinus Torvalds {
1581da177e4SLinus Torvalds 	if (addr == 0x10)
1591da177e4SLinus Torvalds 		return 1;
1601da177e4SLinus Torvalds 	return -ENOENT;
1611da177e4SLinus Torvalds }
1621da177e4SLinus Torvalds 
1635df29bcaSJulia Lawall static const struct snd_i2c_ops ap_cs8427_i2c_ops = {
1641da177e4SLinus Torvalds 	.sendbytes = ap_cs8427_sendbytes,
1651da177e4SLinus Torvalds 	.readbytes = ap_cs8427_readbytes,
1661da177e4SLinus Torvalds 	.probeaddr = ap_cs8427_probeaddr,
1671da177e4SLinus Torvalds };
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds /*
1701da177e4SLinus Torvalds  */
1711da177e4SLinus Torvalds 
snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 * ice,unsigned char bits)1726ca308d4STakashi Iwai static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
1731da177e4SLinus Torvalds {
1741da177e4SLinus Torvalds 	unsigned char tmp, mask1, mask2;
1751da177e4SLinus Torvalds 	int idx;
1761da177e4SLinus Torvalds 	/* send byte to transmitter */
1771da177e4SLinus Torvalds 	mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
1781da177e4SLinus Torvalds 	mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
17962932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
1801da177e4SLinus Torvalds 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
1811da177e4SLinus Torvalds 	for (idx = 7; idx >= 0; idx--) {
1821da177e4SLinus Torvalds 		tmp &= ~(mask1 | mask2);
1831da177e4SLinus Torvalds 		if (bits & (1 << idx))
1841da177e4SLinus Torvalds 			tmp |= mask2;
1851da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
1861da177e4SLinus Torvalds 		udelay(100);
1871da177e4SLinus Torvalds 		tmp |= mask1;
1881da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
1891da177e4SLinus Torvalds 		udelay(100);
1901da177e4SLinus Torvalds 	}
1911da177e4SLinus Torvalds 	tmp &= ~mask1;
1921da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
19362932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
1941da177e4SLinus Torvalds }
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 
delta_spdif_default_get(struct snd_ice1712 * ice,struct snd_ctl_elem_value * ucontrol)1976ca308d4STakashi Iwai static void delta_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
1981da177e4SLinus Torvalds {
1991da177e4SLinus Torvalds 	snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
2001da177e4SLinus Torvalds }
2011da177e4SLinus Torvalds 
delta_spdif_default_put(struct snd_ice1712 * ice,struct snd_ctl_elem_value * ucontrol)2026ca308d4STakashi Iwai static int delta_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
2031da177e4SLinus Torvalds {
2041da177e4SLinus Torvalds 	unsigned int val;
2051da177e4SLinus Torvalds 	int change;
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
2081da177e4SLinus Torvalds 	spin_lock_irq(&ice->reg_lock);
2091da177e4SLinus Torvalds 	change = ice->spdif.cs8403_bits != val;
2101da177e4SLinus Torvalds 	ice->spdif.cs8403_bits = val;
2111da177e4SLinus Torvalds 	if (change && ice->playback_pro_substream == NULL) {
2121da177e4SLinus Torvalds 		spin_unlock_irq(&ice->reg_lock);
2131da177e4SLinus Torvalds 		snd_ice1712_delta_cs8403_spdif_write(ice, val);
2141da177e4SLinus Torvalds 	} else {
2151da177e4SLinus Torvalds 		spin_unlock_irq(&ice->reg_lock);
2161da177e4SLinus Torvalds 	}
2171da177e4SLinus Torvalds 	return change;
2181da177e4SLinus Torvalds }
2191da177e4SLinus Torvalds 
delta_spdif_stream_get(struct snd_ice1712 * ice,struct snd_ctl_elem_value * ucontrol)2206ca308d4STakashi Iwai static void delta_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
2211da177e4SLinus Torvalds {
2221da177e4SLinus Torvalds 	snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
2231da177e4SLinus Torvalds }
2241da177e4SLinus Torvalds 
delta_spdif_stream_put(struct snd_ice1712 * ice,struct snd_ctl_elem_value * ucontrol)2256ca308d4STakashi Iwai static int delta_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
2261da177e4SLinus Torvalds {
2271da177e4SLinus Torvalds 	unsigned int val;
2281da177e4SLinus Torvalds 	int change;
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds 	val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
2311da177e4SLinus Torvalds 	spin_lock_irq(&ice->reg_lock);
2321da177e4SLinus Torvalds 	change = ice->spdif.cs8403_stream_bits != val;
2331da177e4SLinus Torvalds 	ice->spdif.cs8403_stream_bits = val;
2341da177e4SLinus Torvalds 	if (change && ice->playback_pro_substream != NULL) {
2351da177e4SLinus Torvalds 		spin_unlock_irq(&ice->reg_lock);
2361da177e4SLinus Torvalds 		snd_ice1712_delta_cs8403_spdif_write(ice, val);
2371da177e4SLinus Torvalds 	} else {
2381da177e4SLinus Torvalds 		spin_unlock_irq(&ice->reg_lock);
2391da177e4SLinus Torvalds 	}
2401da177e4SLinus Torvalds 	return change;
2411da177e4SLinus Torvalds }
2421da177e4SLinus Torvalds 
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds /*
2451da177e4SLinus Torvalds  * AK4524 on Delta 44 and 66 to choose the chip mask
2461da177e4SLinus Torvalds  */
delta_ak4524_lock(struct snd_akm4xxx * ak,int chip)2476ca308d4STakashi Iwai static void delta_ak4524_lock(struct snd_akm4xxx *ak, int chip)
2481da177e4SLinus Torvalds {
2491da177e4SLinus Torvalds         struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
2506ca308d4STakashi Iwai         struct snd_ice1712 *ice = ak->private_data[0];
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds 	snd_ice1712_save_gpio_status(ice);
2531da177e4SLinus Torvalds 	priv->cs_mask =
2541da177e4SLinus Torvalds 	priv->cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A :
2551da177e4SLinus Torvalds 				    ICE1712_DELTA_CODEC_CHIP_B;
2561da177e4SLinus Torvalds }
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds /*
2591da177e4SLinus Torvalds  * AK4524 on Delta1010LT to choose the chip address
2601da177e4SLinus Torvalds  */
delta1010lt_ak4524_lock(struct snd_akm4xxx * ak,int chip)2616ca308d4STakashi Iwai static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
2621da177e4SLinus Torvalds {
2631da177e4SLinus Torvalds         struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
2646ca308d4STakashi Iwai         struct snd_ice1712 *ice = ak->private_data[0];
2651da177e4SLinus Torvalds 
2661da177e4SLinus Torvalds 	snd_ice1712_save_gpio_status(ice);
2671da177e4SLinus Torvalds 	priv->cs_mask = ICE1712_DELTA_1010LT_CS;
2681da177e4SLinus Torvalds 	priv->cs_addr = chip << 4;
2691da177e4SLinus Torvalds }
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds /*
27293430096SBrian Bloniarz  * AK4524 on Delta66 rev E to choose the chip address
27393430096SBrian Bloniarz  */
delta66e_ak4524_lock(struct snd_akm4xxx * ak,int chip)27493430096SBrian Bloniarz static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
27593430096SBrian Bloniarz {
27693430096SBrian Bloniarz 	struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
27793430096SBrian Bloniarz 	struct snd_ice1712 *ice = ak->private_data[0];
27893430096SBrian Bloniarz 
27993430096SBrian Bloniarz 	snd_ice1712_save_gpio_status(ice);
28093430096SBrian Bloniarz 	priv->cs_mask =
28193430096SBrian Bloniarz 	priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
28293430096SBrian Bloniarz 				    ICE1712_DELTA_66E_CS_CHIP_B;
28393430096SBrian Bloniarz }
28493430096SBrian Bloniarz 
28593430096SBrian Bloniarz /*
2861da177e4SLinus Torvalds  * AK4528 on VX442 to choose the chip mask
2871da177e4SLinus Torvalds  */
vx442_ak4524_lock(struct snd_akm4xxx * ak,int chip)2886ca308d4STakashi Iwai static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
2891da177e4SLinus Torvalds {
2901da177e4SLinus Torvalds         struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
2916ca308d4STakashi Iwai         struct snd_ice1712 *ice = ak->private_data[0];
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	snd_ice1712_save_gpio_status(ice);
2941da177e4SLinus Torvalds 	priv->cs_mask =
2951da177e4SLinus Torvalds 	priv->cs_addr = chip == 0 ? ICE1712_VX442_CODEC_CHIP_A :
2961da177e4SLinus Torvalds 				    ICE1712_VX442_CODEC_CHIP_B;
2971da177e4SLinus Torvalds }
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds /*
3001da177e4SLinus Torvalds  * change the DFS bit according rate for Delta1010
3011da177e4SLinus Torvalds  */
delta_1010_set_rate_val(struct snd_ice1712 * ice,unsigned int rate)3026ca308d4STakashi Iwai static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
3031da177e4SLinus Torvalds {
3041da177e4SLinus Torvalds 	unsigned char tmp, tmp2;
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds 	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
3071da177e4SLinus Torvalds 		return;
3081da177e4SLinus Torvalds 
30962932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
3101da177e4SLinus Torvalds 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
3111da177e4SLinus Torvalds 	tmp2 = tmp & ~ICE1712_DELTA_DFS;
3121da177e4SLinus Torvalds 	if (rate > 48000)
3131da177e4SLinus Torvalds 		tmp2 |= ICE1712_DELTA_DFS;
3141da177e4SLinus Torvalds 	if (tmp != tmp2)
3151da177e4SLinus Torvalds 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2);
31662932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
3171da177e4SLinus Torvalds }
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds /*
3201da177e4SLinus Torvalds  * change the rate of AK4524 on Delta 44/66, AP, 1010LT
3211da177e4SLinus Torvalds  */
delta_ak4524_set_rate_val(struct snd_akm4xxx * ak,unsigned int rate)3226ca308d4STakashi Iwai static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
3231da177e4SLinus Torvalds {
3241da177e4SLinus Torvalds 	unsigned char tmp, tmp2;
3256ca308d4STakashi Iwai 	struct snd_ice1712 *ice = ak->private_data[0];
3261da177e4SLinus Torvalds 
3271da177e4SLinus Torvalds 	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
3281da177e4SLinus Torvalds 		return;
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds 	/* check before reset ak4524 to avoid unnecessary clicks */
33162932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
3321da177e4SLinus Torvalds 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
33362932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
3341da177e4SLinus Torvalds 	tmp2 = tmp & ~ICE1712_DELTA_DFS;
3351da177e4SLinus Torvalds 	if (rate > 48000)
3361da177e4SLinus Torvalds 		tmp2 |= ICE1712_DELTA_DFS;
3371da177e4SLinus Torvalds 	if (tmp == tmp2)
3381da177e4SLinus Torvalds 		return;
3391da177e4SLinus Torvalds 
3401da177e4SLinus Torvalds 	/* do it again */
3411da177e4SLinus Torvalds 	snd_akm4xxx_reset(ak, 1);
34262932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
3431da177e4SLinus Torvalds 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
3441da177e4SLinus Torvalds 	if (rate > 48000)
3451da177e4SLinus Torvalds 		tmp |= ICE1712_DELTA_DFS;
3461da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
34762932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
3481da177e4SLinus Torvalds 	snd_akm4xxx_reset(ak, 0);
3491da177e4SLinus Torvalds }
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds /*
3521da177e4SLinus Torvalds  * change the rate of AK4524 on VX442
3531da177e4SLinus Torvalds  */
vx442_ak4524_set_rate_val(struct snd_akm4xxx * ak,unsigned int rate)3546ca308d4STakashi Iwai static void vx442_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
3551da177e4SLinus Torvalds {
3561da177e4SLinus Torvalds 	unsigned char val;
3571da177e4SLinus Torvalds 
3581da177e4SLinus Torvalds 	val = (rate > 48000) ? 0x65 : 0x60;
3591da177e4SLinus Torvalds 	if (snd_akm4xxx_get(ak, 0, 0x02) != val ||
3601da177e4SLinus Torvalds 	    snd_akm4xxx_get(ak, 1, 0x02) != val) {
3611da177e4SLinus Torvalds 		snd_akm4xxx_reset(ak, 1);
3621da177e4SLinus Torvalds 		snd_akm4xxx_write(ak, 0, 0x02, val);
3631da177e4SLinus Torvalds 		snd_akm4xxx_write(ak, 1, 0x02, val);
3641da177e4SLinus Torvalds 		snd_akm4xxx_reset(ak, 0);
3651da177e4SLinus Torvalds 	}
3661da177e4SLinus Torvalds }
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds 
3691da177e4SLinus Torvalds /*
3701da177e4SLinus Torvalds  * SPDIF ops for Delta 1010, Dio, 66
3711da177e4SLinus Torvalds  */
3721da177e4SLinus Torvalds 
3731da177e4SLinus Torvalds /* open callback */
delta_open_spdif(struct snd_ice1712 * ice,struct snd_pcm_substream * substream)3746ca308d4STakashi Iwai static void delta_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
3751da177e4SLinus Torvalds {
3761da177e4SLinus Torvalds 	ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
3771da177e4SLinus Torvalds }
3781da177e4SLinus Torvalds 
3791da177e4SLinus Torvalds /* set up */
delta_setup_spdif(struct snd_ice1712 * ice,int rate)3806ca308d4STakashi Iwai static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
3811da177e4SLinus Torvalds {
3821da177e4SLinus Torvalds 	unsigned long flags;
3831da177e4SLinus Torvalds 	unsigned int tmp;
3841da177e4SLinus Torvalds 	int change;
3851da177e4SLinus Torvalds 
3861da177e4SLinus Torvalds 	spin_lock_irqsave(&ice->reg_lock, flags);
3871da177e4SLinus Torvalds 	tmp = ice->spdif.cs8403_stream_bits;
3881da177e4SLinus Torvalds 	if (tmp & 0x01)		/* consumer */
3891da177e4SLinus Torvalds 		tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
3901da177e4SLinus Torvalds 	switch (rate) {
3911da177e4SLinus Torvalds 	case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
3921da177e4SLinus Torvalds 	case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
3931da177e4SLinus Torvalds 	case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
3941da177e4SLinus Torvalds 	default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
3951da177e4SLinus Torvalds 	}
3961da177e4SLinus Torvalds 	change = ice->spdif.cs8403_stream_bits != tmp;
3971da177e4SLinus Torvalds 	ice->spdif.cs8403_stream_bits = tmp;
3981da177e4SLinus Torvalds 	spin_unlock_irqrestore(&ice->reg_lock, flags);
3991da177e4SLinus Torvalds 	if (change)
4001da177e4SLinus Torvalds 		snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
4011da177e4SLinus Torvalds 	snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
4021da177e4SLinus Torvalds }
4031da177e4SLinus Torvalds 
404a5ce8890STakashi Iwai #define snd_ice1712_delta1010lt_wordclock_status_info \
405a5ce8890STakashi Iwai 	snd_ctl_boolean_mono_info
406f7004f39SJaroslav Kysela 
snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)407ecefb192SAdrian Bunk static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol,
408f7004f39SJaroslav Kysela 			 struct snd_ctl_elem_value *ucontrol)
409f7004f39SJaroslav Kysela {
410cc67b7f7SVedran Miletic 	char reg = 0x10; /* CS8427 receiver error register */
411f7004f39SJaroslav Kysela 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
412f7004f39SJaroslav Kysela 
413f7004f39SJaroslav Kysela 	if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1)
4146dfb5affSTakashi Iwai 		dev_err(ice->card->dev,
4156dfb5affSTakashi Iwai 			"unable to send register 0x%x byte to CS8427\n", reg);
416f7004f39SJaroslav Kysela 	snd_i2c_readbytes(ice->cs8427, &reg, 1);
4171005f66fSTakashi Iwai 	ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0;
418f7004f39SJaroslav Kysela 	return 0;
419f7004f39SJaroslav Kysela }
420f7004f39SJaroslav Kysela 
421f3b827e0SBhumika Goyal static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status =
422f7004f39SJaroslav Kysela {
423f7004f39SJaroslav Kysela 	.access =	(SNDRV_CTL_ELEM_ACCESS_READ),
424f7004f39SJaroslav Kysela 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
425f7004f39SJaroslav Kysela 	.name =         "Word Clock Status",
426f7004f39SJaroslav Kysela 	.info =		snd_ice1712_delta1010lt_wordclock_status_info,
427f7004f39SJaroslav Kysela 	.get =		snd_ice1712_delta1010lt_wordclock_status_get,
428f7004f39SJaroslav Kysela };
4291da177e4SLinus Torvalds 
4301da177e4SLinus Torvalds /*
4311da177e4SLinus Torvalds  * initialize the chips on M-Audio cards
4321da177e4SLinus Torvalds  */
4331da177e4SLinus Torvalds 
4343135432eSBhumika Goyal static const struct snd_akm4xxx akm_audiophile = {
4351da177e4SLinus Torvalds 	.type = SND_AK4528,
4361da177e4SLinus Torvalds 	.num_adcs = 2,
4371da177e4SLinus Torvalds 	.num_dacs = 2,
4381da177e4SLinus Torvalds 	.ops = {
4391da177e4SLinus Torvalds 		.set_rate_val = delta_ak4524_set_rate_val
4401da177e4SLinus Torvalds 	}
4411da177e4SLinus Torvalds };
4421da177e4SLinus Torvalds 
4434647e8d5SBhumika Goyal static const struct snd_ak4xxx_private akm_audiophile_priv = {
4441da177e4SLinus Torvalds 	.caddr = 2,
4451da177e4SLinus Torvalds 	.cif = 0,
4461da177e4SLinus Torvalds 	.data_mask = ICE1712_DELTA_AP_DOUT,
4471da177e4SLinus Torvalds 	.clk_mask = ICE1712_DELTA_AP_CCLK,
4481da177e4SLinus Torvalds 	.cs_mask = ICE1712_DELTA_AP_CS_CODEC,
4491da177e4SLinus Torvalds 	.cs_addr = ICE1712_DELTA_AP_CS_CODEC,
4501da177e4SLinus Torvalds 	.cs_none = 0,
4511da177e4SLinus Torvalds 	.add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
4521da177e4SLinus Torvalds 	.mask_flags = 0,
4531da177e4SLinus Torvalds };
4541da177e4SLinus Torvalds 
4553135432eSBhumika Goyal static const struct snd_akm4xxx akm_delta410 = {
4561da177e4SLinus Torvalds 	.type = SND_AK4529,
4571da177e4SLinus Torvalds 	.num_adcs = 2,
4581da177e4SLinus Torvalds 	.num_dacs = 8,
4591da177e4SLinus Torvalds 	.ops = {
4601da177e4SLinus Torvalds 		.set_rate_val = delta_ak4524_set_rate_val
4611da177e4SLinus Torvalds 	}
4621da177e4SLinus Torvalds };
4631da177e4SLinus Torvalds 
4644647e8d5SBhumika Goyal static const struct snd_ak4xxx_private akm_delta410_priv = {
4651da177e4SLinus Torvalds 	.caddr = 0,
4661da177e4SLinus Torvalds 	.cif = 0,
4671da177e4SLinus Torvalds 	.data_mask = ICE1712_DELTA_AP_DOUT,
4681da177e4SLinus Torvalds 	.clk_mask = ICE1712_DELTA_AP_CCLK,
4691da177e4SLinus Torvalds 	.cs_mask = ICE1712_DELTA_AP_CS_CODEC,
4701da177e4SLinus Torvalds 	.cs_addr = ICE1712_DELTA_AP_CS_CODEC,
4711da177e4SLinus Torvalds 	.cs_none = 0,
4721da177e4SLinus Torvalds 	.add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
4731da177e4SLinus Torvalds 	.mask_flags = 0,
4741da177e4SLinus Torvalds };
4751da177e4SLinus Torvalds 
4763135432eSBhumika Goyal static const struct snd_akm4xxx akm_delta1010lt = {
4771da177e4SLinus Torvalds 	.type = SND_AK4524,
4781da177e4SLinus Torvalds 	.num_adcs = 8,
4791da177e4SLinus Torvalds 	.num_dacs = 8,
4801da177e4SLinus Torvalds 	.ops = {
4811da177e4SLinus Torvalds 		.lock = delta1010lt_ak4524_lock,
4821da177e4SLinus Torvalds 		.set_rate_val = delta_ak4524_set_rate_val
4831da177e4SLinus Torvalds 	}
4841da177e4SLinus Torvalds };
4851da177e4SLinus Torvalds 
4864647e8d5SBhumika Goyal static const struct snd_ak4xxx_private akm_delta1010lt_priv = {
4871da177e4SLinus Torvalds 	.caddr = 2,
4881da177e4SLinus Torvalds 	.cif = 0, /* the default level of the CIF pin from AK4524 */
4891da177e4SLinus Torvalds 	.data_mask = ICE1712_DELTA_1010LT_DOUT,
4901da177e4SLinus Torvalds 	.clk_mask = ICE1712_DELTA_1010LT_CCLK,
4911da177e4SLinus Torvalds 	.cs_mask = 0,
4921da177e4SLinus Torvalds 	.cs_addr = 0, /* set later */
4931da177e4SLinus Torvalds 	.cs_none = ICE1712_DELTA_1010LT_CS_NONE,
4941da177e4SLinus Torvalds 	.add_flags = 0,
4951da177e4SLinus Torvalds 	.mask_flags = 0,
4961da177e4SLinus Torvalds };
4971da177e4SLinus Torvalds 
4983135432eSBhumika Goyal static const struct snd_akm4xxx akm_delta66e = {
49993430096SBrian Bloniarz 	.type = SND_AK4524,
50093430096SBrian Bloniarz 	.num_adcs = 4,
50193430096SBrian Bloniarz 	.num_dacs = 4,
50293430096SBrian Bloniarz 	.ops = {
50393430096SBrian Bloniarz 		.lock = delta66e_ak4524_lock,
50493430096SBrian Bloniarz 		.set_rate_val = delta_ak4524_set_rate_val
50593430096SBrian Bloniarz 	}
50693430096SBrian Bloniarz };
50793430096SBrian Bloniarz 
5084647e8d5SBhumika Goyal static const struct snd_ak4xxx_private akm_delta66e_priv = {
50993430096SBrian Bloniarz 	.caddr = 2,
51093430096SBrian Bloniarz 	.cif = 0, /* the default level of the CIF pin from AK4524 */
51193430096SBrian Bloniarz 	.data_mask = ICE1712_DELTA_66E_DOUT,
51293430096SBrian Bloniarz 	.clk_mask = ICE1712_DELTA_66E_CCLK,
51393430096SBrian Bloniarz 	.cs_mask = 0,
51493430096SBrian Bloniarz 	.cs_addr = 0, /* set later */
51593430096SBrian Bloniarz 	.cs_none = 0,
51693430096SBrian Bloniarz 	.add_flags = 0,
51793430096SBrian Bloniarz 	.mask_flags = 0,
51893430096SBrian Bloniarz };
51993430096SBrian Bloniarz 
52093430096SBrian Bloniarz 
5213135432eSBhumika Goyal static const struct snd_akm4xxx akm_delta44 = {
5221da177e4SLinus Torvalds 	.type = SND_AK4524,
5231da177e4SLinus Torvalds 	.num_adcs = 4,
5241da177e4SLinus Torvalds 	.num_dacs = 4,
5251da177e4SLinus Torvalds 	.ops = {
5261da177e4SLinus Torvalds 		.lock = delta_ak4524_lock,
5271da177e4SLinus Torvalds 		.set_rate_val = delta_ak4524_set_rate_val
5281da177e4SLinus Torvalds 	}
5291da177e4SLinus Torvalds };
5301da177e4SLinus Torvalds 
5314647e8d5SBhumika Goyal static const struct snd_ak4xxx_private akm_delta44_priv = {
5321da177e4SLinus Torvalds 	.caddr = 2,
5331da177e4SLinus Torvalds 	.cif = 0, /* the default level of the CIF pin from AK4524 */
5341da177e4SLinus Torvalds 	.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
5351da177e4SLinus Torvalds 	.clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK,
5361da177e4SLinus Torvalds 	.cs_mask = 0,
5371da177e4SLinus Torvalds 	.cs_addr = 0, /* set later */
5381da177e4SLinus Torvalds 	.cs_none = 0,
5391da177e4SLinus Torvalds 	.add_flags = 0,
5401da177e4SLinus Torvalds 	.mask_flags = 0,
5411da177e4SLinus Torvalds };
5421da177e4SLinus Torvalds 
5433135432eSBhumika Goyal static const struct snd_akm4xxx akm_vx442 = {
5441da177e4SLinus Torvalds 	.type = SND_AK4524,
5451da177e4SLinus Torvalds 	.num_adcs = 4,
5461da177e4SLinus Torvalds 	.num_dacs = 4,
5471da177e4SLinus Torvalds 	.ops = {
5481da177e4SLinus Torvalds 		.lock = vx442_ak4524_lock,
5491da177e4SLinus Torvalds 		.set_rate_val = vx442_ak4524_set_rate_val
5501da177e4SLinus Torvalds 	}
5511da177e4SLinus Torvalds };
5521da177e4SLinus Torvalds 
5534647e8d5SBhumika Goyal static const struct snd_ak4xxx_private akm_vx442_priv = {
5541da177e4SLinus Torvalds 	.caddr = 2,
5551da177e4SLinus Torvalds 	.cif = 0,
5561da177e4SLinus Torvalds 	.data_mask = ICE1712_VX442_DOUT,
5571da177e4SLinus Torvalds 	.clk_mask = ICE1712_VX442_CCLK,
5581da177e4SLinus Torvalds 	.cs_mask = 0,
5591da177e4SLinus Torvalds 	.cs_addr = 0, /* set later */
5601da177e4SLinus Torvalds 	.cs_none = 0,
5611da177e4SLinus Torvalds 	.add_flags = 0,
5621da177e4SLinus Torvalds 	.mask_flags = 0,
5631da177e4SLinus Torvalds };
5641da177e4SLinus Torvalds 
5658c1d8434SOndrej Zary #ifdef CONFIG_PM_SLEEP
snd_ice1712_delta_resume(struct snd_ice1712 * ice)5668c1d8434SOndrej Zary static int snd_ice1712_delta_resume(struct snd_ice1712 *ice)
5678c1d8434SOndrej Zary {
5686e61246fSOndrej Zary 	unsigned char akm_img_bak[AK4XXX_IMAGE_SIZE];
5696e61246fSOndrej Zary 	unsigned char akm_vol_bak[AK4XXX_IMAGE_SIZE];
570d272ccd0SOndrej Zary 
571d272ccd0SOndrej Zary 	/* init spdif */
572d272ccd0SOndrej Zary 	switch (ice->eeprom.subvendor) {
573d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_AUDIOPHILE:
574d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTA410:
575d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTA1010E:
576d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTA1010LT:
577d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_VX442:
578d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTA66E:
579d272ccd0SOndrej Zary 		snd_cs8427_init(ice->i2c, ice->cs8427);
580d272ccd0SOndrej Zary 		break;
581d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTA1010:
582d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_MEDIASTATION:
583d272ccd0SOndrej Zary 		/* nothing */
584d272ccd0SOndrej Zary 		break;
585d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTADIO2496:
586d272ccd0SOndrej Zary 	case ICE1712_SUBDEVICE_DELTA66:
587d272ccd0SOndrej Zary 		/* Set spdif defaults */
588d272ccd0SOndrej Zary 		snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits);
589d272ccd0SOndrej Zary 		break;
590d272ccd0SOndrej Zary 	}
591d272ccd0SOndrej Zary 
5928c1d8434SOndrej Zary 	/* init codec and restore registers */
5938c1d8434SOndrej Zary 	if (ice->akm_codecs) {
5946e61246fSOndrej Zary 		memcpy(akm_img_bak, ice->akm->images, sizeof(akm_img_bak));
5956e61246fSOndrej Zary 		memcpy(akm_vol_bak, ice->akm->volumes, sizeof(akm_vol_bak));
5968c1d8434SOndrej Zary 		snd_akm4xxx_init(ice->akm);
5976e61246fSOndrej Zary 		memcpy(ice->akm->images, akm_img_bak, sizeof(akm_img_bak));
5986e61246fSOndrej Zary 		memcpy(ice->akm->volumes, akm_vol_bak, sizeof(akm_vol_bak));
5998c1d8434SOndrej Zary 		snd_akm4xxx_reset(ice->akm, 0);
6008c1d8434SOndrej Zary 	}
6018c1d8434SOndrej Zary 
6028c1d8434SOndrej Zary 	return 0;
6038c1d8434SOndrej Zary }
6048c1d8434SOndrej Zary 
snd_ice1712_delta_suspend(struct snd_ice1712 * ice)6058c1d8434SOndrej Zary static int snd_ice1712_delta_suspend(struct snd_ice1712 *ice)
6068c1d8434SOndrej Zary {
6078c1d8434SOndrej Zary 	if (ice->akm_codecs) /* reset & mute codec */
6088c1d8434SOndrej Zary 		snd_akm4xxx_reset(ice->akm, 1);
6098c1d8434SOndrej Zary 
6108c1d8434SOndrej Zary 	return 0;
6118c1d8434SOndrej Zary }
6128c1d8434SOndrej Zary #endif
6138c1d8434SOndrej Zary 
snd_ice1712_delta_init(struct snd_ice1712 * ice)614e23e7a14SBill Pemberton static int snd_ice1712_delta_init(struct snd_ice1712 *ice)
6151da177e4SLinus Torvalds {
6161da177e4SLinus Torvalds 	int err;
6176ca308d4STakashi Iwai 	struct snd_akm4xxx *ak;
618b8b1a4cbSBrian Bloniarz 	unsigned char tmp;
6191da177e4SLinus Torvalds 
620ef2cd2ccSJaroslav Kysela 	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 &&
621ef2cd2ccSJaroslav Kysela 	    ice->eeprom.gpiodir == 0x7b)
622a60567d1SJaroslav Kysela 		ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA1010E;
623a60567d1SJaroslav Kysela 
624ef2cd2ccSJaroslav Kysela 	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA66 &&
625ef2cd2ccSJaroslav Kysela 	    ice->eeprom.gpiodir == 0xfb)
626ef2cd2ccSJaroslav Kysela 	    	ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA66E;
627ef2cd2ccSJaroslav Kysela 
6281da177e4SLinus Torvalds 	/* determine I2C, DACs and ADCs */
6291da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
6301da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_AUDIOPHILE:
6311da177e4SLinus Torvalds 		ice->num_total_dacs = 2;
6321da177e4SLinus Torvalds 		ice->num_total_adcs = 2;
6331da177e4SLinus Torvalds 		break;
6341da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA410:
6351da177e4SLinus Torvalds 		ice->num_total_dacs = 8;
6361da177e4SLinus Torvalds 		ice->num_total_adcs = 2;
6371da177e4SLinus Torvalds 		break;
6381da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA44:
6391da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA66:
6401da177e4SLinus Torvalds 		ice->num_total_dacs = ice->omni ? 8 : 4;
6411da177e4SLinus Torvalds 		ice->num_total_adcs = ice->omni ? 8 : 4;
6421da177e4SLinus Torvalds 		break;
6431da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010:
644a60567d1SJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA1010E:
6451da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
6461da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_MEDIASTATION:
64723b224d9SGarnet MacPhee 	case ICE1712_SUBDEVICE_EDIROLDA2496:
6481da177e4SLinus Torvalds 		ice->num_total_dacs = 8;
6491da177e4SLinus Torvalds 		ice->num_total_adcs = 8;
6501da177e4SLinus Torvalds 		break;
6511da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTADIO2496:
6521da177e4SLinus Torvalds 		ice->num_total_dacs = 4;	/* two AK4324 codecs */
6531da177e4SLinus Torvalds 		break;
6541da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_VX442:
65502582e9bSMasanari Iida 	case ICE1712_SUBDEVICE_DELTA66E:	/* omni not supported yet */
6561da177e4SLinus Torvalds 		ice->num_total_dacs = 4;
6571da177e4SLinus Torvalds 		ice->num_total_adcs = 4;
6581da177e4SLinus Torvalds 		break;
6591da177e4SLinus Torvalds 	}
6608c1d8434SOndrej Zary #ifdef CONFIG_PM_SLEEP
6618c1d8434SOndrej Zary 	ice->pm_resume = snd_ice1712_delta_resume;
6628c1d8434SOndrej Zary 	ice->pm_suspend = snd_ice1712_delta_suspend;
6638c1d8434SOndrej Zary 	ice->pm_suspend_enabled = 1;
6648c1d8434SOndrej Zary #endif
665b8b1a4cbSBrian Bloniarz 	/* initialize the SPI clock to high */
666b8b1a4cbSBrian Bloniarz 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
667b8b1a4cbSBrian Bloniarz 	tmp |= ICE1712_DELTA_AP_CCLK;
668b8b1a4cbSBrian Bloniarz 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
669b8b1a4cbSBrian Bloniarz 	udelay(5);
670b8b1a4cbSBrian Bloniarz 
6711da177e4SLinus Torvalds 	/* initialize spdif */
6721da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
6731da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_AUDIOPHILE:
6741da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA410:
675a60567d1SJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA1010E:
6761da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
6771da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_VX442:
678ef2cd2ccSJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA66E:
679*3635f862STakashi Iwai 		err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c);
680*3635f862STakashi Iwai 		if (err < 0) {
6816dfb5affSTakashi Iwai 			dev_err(ice->card->dev, "unable to create I2C bus\n");
6821da177e4SLinus Torvalds 			return err;
6831da177e4SLinus Torvalds 		}
6841da177e4SLinus Torvalds 		ice->i2c->private_data = ice;
6851da177e4SLinus Torvalds 		ice->i2c->ops = &ap_cs8427_i2c_ops;
686*3635f862STakashi Iwai 		err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR);
687*3635f862STakashi Iwai 		if (err < 0)
6881da177e4SLinus Torvalds 			return err;
6891da177e4SLinus Torvalds 		break;
6901da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010:
6911da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_MEDIASTATION:
6921da177e4SLinus Torvalds 		ice->gpio.set_pro_rate = delta_1010_set_rate_val;
6931da177e4SLinus Torvalds 		break;
6941da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTADIO2496:
6951da177e4SLinus Torvalds 		ice->gpio.set_pro_rate = delta_1010_set_rate_val;
696c0dbbdadSGustavo A. R. Silva 		fallthrough;
6971da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA66:
6981da177e4SLinus Torvalds 		ice->spdif.ops.open = delta_open_spdif;
6991da177e4SLinus Torvalds 		ice->spdif.ops.setup_rate = delta_setup_spdif;
7001da177e4SLinus Torvalds 		ice->spdif.ops.default_get = delta_spdif_default_get;
7011da177e4SLinus Torvalds 		ice->spdif.ops.default_put = delta_spdif_default_put;
7021da177e4SLinus Torvalds 		ice->spdif.ops.stream_get = delta_spdif_stream_get;
7031da177e4SLinus Torvalds 		ice->spdif.ops.stream_put = delta_spdif_stream_put;
7041da177e4SLinus Torvalds 		/* Set spdif defaults */
7051da177e4SLinus Torvalds 		snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits);
7061da177e4SLinus Torvalds 		break;
7071da177e4SLinus Torvalds 	}
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 	/* no analog? */
7101da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
7111da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010:
712a60567d1SJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA1010E:
7131da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTADIO2496:
7141da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_MEDIASTATION:
7151da177e4SLinus Torvalds 		return 0;
7161da177e4SLinus Torvalds 	}
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds 	/* second stage of initialization, analog parts and others */
7196ca308d4STakashi Iwai 	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
7201da177e4SLinus Torvalds 	if (! ak)
7211da177e4SLinus Torvalds 		return -ENOMEM;
7221da177e4SLinus Torvalds 	ice->akm_codecs = 1;
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
7251da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_AUDIOPHILE:
7261da177e4SLinus Torvalds 		err = snd_ice1712_akm4xxx_init(ak, &akm_audiophile, &akm_audiophile_priv, ice);
7271da177e4SLinus Torvalds 		break;
7281da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA410:
7291da177e4SLinus Torvalds 		err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
7301da177e4SLinus Torvalds 		break;
7311da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
73223b224d9SGarnet MacPhee 	case ICE1712_SUBDEVICE_EDIROLDA2496:
7331da177e4SLinus Torvalds 		err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
7341da177e4SLinus Torvalds 		break;
7351da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA66:
7361da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA44:
7371da177e4SLinus Torvalds 		err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
7381da177e4SLinus Torvalds 		break;
7391da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_VX442:
7401da177e4SLinus Torvalds 		err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
7411da177e4SLinus Torvalds 		break;
74293430096SBrian Bloniarz 	case ICE1712_SUBDEVICE_DELTA66E:
74393430096SBrian Bloniarz 		err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
74493430096SBrian Bloniarz 		break;
7451da177e4SLinus Torvalds 	default:
7461da177e4SLinus Torvalds 		snd_BUG();
7471da177e4SLinus Torvalds 		return -EINVAL;
7481da177e4SLinus Torvalds 	}
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 	return err;
7511da177e4SLinus Torvalds }
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds /*
7551da177e4SLinus Torvalds  * additional controls for M-Audio cards
7561da177e4SLinus Torvalds  */
7571da177e4SLinus Torvalds 
758b4e5e707STakashi Iwai static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select =
75967ed4161SClemens Ladisch ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
760b4e5e707STakashi Iwai static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select =
761f7004f39SJaroslav Kysela ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
762b4e5e707STakashi Iwai static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status =
76367ed4161SClemens Ladisch ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
764b4e5e707STakashi Iwai static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select =
76567ed4161SClemens Ladisch ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
766b4e5e707STakashi Iwai static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status =
76767ed4161SClemens Ladisch ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds 
snd_ice1712_delta_add_controls(struct snd_ice1712 * ice)770e23e7a14SBill Pemberton static int snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
7711da177e4SLinus Torvalds {
7721da177e4SLinus Torvalds 	int err;
7731da177e4SLinus Torvalds 
7741da177e4SLinus Torvalds 	/* 1010 and dio specific controls */
7751da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
7761da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010:
7771da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_MEDIASTATION:
7781da177e4SLinus Torvalds 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice));
7791da177e4SLinus Torvalds 		if (err < 0)
7801da177e4SLinus Torvalds 			return err;
7811da177e4SLinus Torvalds 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_status, ice));
7821da177e4SLinus Torvalds 		if (err < 0)
7831da177e4SLinus Torvalds 			return err;
7841da177e4SLinus Torvalds 		break;
7851da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTADIO2496:
7861da177e4SLinus Torvalds 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_deltadio2496_spdif_in_select, ice));
7871da177e4SLinus Torvalds 		if (err < 0)
7881da177e4SLinus Torvalds 			return err;
7891da177e4SLinus Torvalds 		break;
790a60567d1SJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA1010E:
7911da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
7921da177e4SLinus Torvalds 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice));
7931da177e4SLinus Torvalds 		if (err < 0)
7941da177e4SLinus Torvalds 			return err;
795f7004f39SJaroslav Kysela 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_status, ice));
796f7004f39SJaroslav Kysela 		if (err < 0)
797f7004f39SJaroslav Kysela 			return err;
7981da177e4SLinus Torvalds 		break;
7991da177e4SLinus Torvalds 	}
8001da177e4SLinus Torvalds 
8011da177e4SLinus Torvalds 	/* normal spdif controls */
8021da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
8031da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010:
8041da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTADIO2496:
8051da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA66:
8061da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_MEDIASTATION:
8071da177e4SLinus Torvalds 		err = snd_ice1712_spdif_build_controls(ice);
8081da177e4SLinus Torvalds 		if (err < 0)
8091da177e4SLinus Torvalds 			return err;
8101da177e4SLinus Torvalds 		break;
8111da177e4SLinus Torvalds 	}
8121da177e4SLinus Torvalds 
8131da177e4SLinus Torvalds 	/* spdif status in */
8141da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
8151da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010:
8161da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTADIO2496:
8171da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA66:
8181da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_MEDIASTATION:
8191da177e4SLinus Torvalds 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice));
8201da177e4SLinus Torvalds 		if (err < 0)
8211da177e4SLinus Torvalds 			return err;
8221da177e4SLinus Torvalds 		break;
8231da177e4SLinus Torvalds 	}
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 	/* ak4524 controls */
8261da177e4SLinus Torvalds 	switch (ice->eeprom.subvendor) {
8271da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA1010LT:
8281da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_AUDIOPHILE:
8291da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA410:
8301da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA44:
8311da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_DELTA66:
8321da177e4SLinus Torvalds 	case ICE1712_SUBDEVICE_VX442:
833ef2cd2ccSJaroslav Kysela 	case ICE1712_SUBDEVICE_DELTA66E:
83423b224d9SGarnet MacPhee 	case ICE1712_SUBDEVICE_EDIROLDA2496:
8351da177e4SLinus Torvalds 		err = snd_ice1712_akm4xxx_build_controls(ice);
8361da177e4SLinus Torvalds 		if (err < 0)
8371da177e4SLinus Torvalds 			return err;
8381da177e4SLinus Torvalds 		break;
8391da177e4SLinus Torvalds 	}
8401da177e4SLinus Torvalds 
8411da177e4SLinus Torvalds 	return 0;
8421da177e4SLinus Torvalds }
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds 
8451da177e4SLinus Torvalds /* entry point */
846e23e7a14SBill Pemberton struct snd_ice1712_card_info snd_ice1712_delta_cards[] = {
8471da177e4SLinus Torvalds 	{
8481da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_DELTA1010,
8491da177e4SLinus Torvalds 		.name = "M Audio Delta 1010",
8501da177e4SLinus Torvalds 		.model = "delta1010",
8511da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8521da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8531da177e4SLinus Torvalds 	},
8541da177e4SLinus Torvalds 	{
8551da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_DELTADIO2496,
8561da177e4SLinus Torvalds 		.name = "M Audio Delta DiO 2496",
8571da177e4SLinus Torvalds 		.model = "dio2496",
8581da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8591da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8601da177e4SLinus Torvalds 		.no_mpu401 = 1,
8611da177e4SLinus Torvalds 	},
8621da177e4SLinus Torvalds 	{
8631da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_DELTA66,
8641da177e4SLinus Torvalds 		.name = "M Audio Delta 66",
8651da177e4SLinus Torvalds 		.model = "delta66",
8661da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8671da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8681da177e4SLinus Torvalds 		.no_mpu401 = 1,
8691da177e4SLinus Torvalds 	},
8701da177e4SLinus Torvalds 	{
8711da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_DELTA44,
8721da177e4SLinus Torvalds 		.name = "M Audio Delta 44",
8731da177e4SLinus Torvalds 		.model = "delta44",
8741da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8751da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8761da177e4SLinus Torvalds 		.no_mpu401 = 1,
8771da177e4SLinus Torvalds 	},
8781da177e4SLinus Torvalds 	{
8791da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_AUDIOPHILE,
8801da177e4SLinus Torvalds 		.name = "M Audio Audiophile 24/96",
8811da177e4SLinus Torvalds 		.model = "audiophile",
8821da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8831da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8841da177e4SLinus Torvalds 	},
8851da177e4SLinus Torvalds 	{
8861da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_DELTA410,
8871da177e4SLinus Torvalds 		.name = "M Audio Delta 410",
8881da177e4SLinus Torvalds 		.model = "delta410",
8891da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8901da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8911da177e4SLinus Torvalds 	},
8921da177e4SLinus Torvalds 	{
8931da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_DELTA1010LT,
8941da177e4SLinus Torvalds 		.name = "M Audio Delta 1010LT",
8951da177e4SLinus Torvalds 		.model = "delta1010lt",
8961da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
8971da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
8981da177e4SLinus Torvalds 	},
8991da177e4SLinus Torvalds 	{
9001da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_VX442,
9011da177e4SLinus Torvalds 		.name = "Digigram VX442",
9021da177e4SLinus Torvalds 		.model = "vx442",
9031da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
9041da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
9051da177e4SLinus Torvalds 		.no_mpu401 = 1,
9061da177e4SLinus Torvalds 	},
9071da177e4SLinus Torvalds 	{
9081da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_MEDIASTATION,
9091da177e4SLinus Torvalds 		.name = "Lionstracs Mediastation",
9101da177e4SLinus Torvalds 		.model = "mediastation",
9111da177e4SLinus Torvalds 		.chip_init = snd_ice1712_delta_init,
9121da177e4SLinus Torvalds 		.build_controls = snd_ice1712_delta_add_controls,
9131da177e4SLinus Torvalds 	},
91423b224d9SGarnet MacPhee 	{
91523b224d9SGarnet MacPhee 		.subvendor = ICE1712_SUBDEVICE_EDIROLDA2496,
91623b224d9SGarnet MacPhee 		.name = "Edirol DA2496",
91723b224d9SGarnet MacPhee 		.model = "da2496",
91823b224d9SGarnet MacPhee 		.chip_init = snd_ice1712_delta_init,
91923b224d9SGarnet MacPhee 		.build_controls = snd_ice1712_delta_add_controls,
92023b224d9SGarnet MacPhee 	},
9211da177e4SLinus Torvalds 	{ } /* terminator */
9221da177e4SLinus Torvalds };
923