xref: /openbmc/linux/sound/pci/ice1712/hoontech.c (revision 1a59d1b8)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *   Lowlevel functions for Hoontech STDSP24
61da177e4SLinus Torvalds  *
7c1017a4cSJaroslav Kysela  *	Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
81da177e4SLinus Torvalds  */
91da177e4SLinus Torvalds 
101da177e4SLinus Torvalds #include <linux/delay.h>
111da177e4SLinus Torvalds #include <linux/interrupt.h>
121da177e4SLinus Torvalds #include <linux/init.h>
131da177e4SLinus Torvalds #include <linux/slab.h>
1462932df8SIngo Molnar #include <linux/mutex.h>
1562932df8SIngo Molnar 
161da177e4SLinus Torvalds #include <sound/core.h>
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds #include "ice1712.h"
191da177e4SLinus Torvalds #include "hoontech.h"
201da177e4SLinus Torvalds 
217cda8ba9STakashi Iwai /* Hoontech-specific setting */
227cda8ba9STakashi Iwai struct hoontech_spec {
237cda8ba9STakashi Iwai 	unsigned char boxbits[4];
247cda8ba9STakashi Iwai 	unsigned int config;
257cda8ba9STakashi Iwai 	unsigned short boxconfig[4];
267cda8ba9STakashi Iwai };
271da177e4SLinus Torvalds 
snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 * ice,unsigned char byte)28e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds 	byte |= ICE1712_STDSP24_CLOCK_BIT;
311da177e4SLinus Torvalds 	udelay(100);
321da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
331da177e4SLinus Torvalds 	byte &= ~ICE1712_STDSP24_CLOCK_BIT;
341da177e4SLinus Torvalds 	udelay(100);
351da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
361da177e4SLinus Torvalds 	byte |= ICE1712_STDSP24_CLOCK_BIT;
371da177e4SLinus Torvalds 	udelay(100);
381da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
391da177e4SLinus Torvalds }
401da177e4SLinus Torvalds 
snd_ice1712_stdsp24_darear(struct snd_ice1712 * ice,int activate)41e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
421da177e4SLinus Torvalds {
437cda8ba9STakashi Iwai 	struct hoontech_spec *spec = ice->spec;
4462932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
457cda8ba9STakashi Iwai 	ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
467cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
4762932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
481da177e4SLinus Torvalds }
491da177e4SLinus Torvalds 
snd_ice1712_stdsp24_mute(struct snd_ice1712 * ice,int activate)50e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
511da177e4SLinus Torvalds {
527cda8ba9STakashi Iwai 	struct hoontech_spec *spec = ice->spec;
5362932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
547cda8ba9STakashi Iwai 	ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
557cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
5662932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds 
snd_ice1712_stdsp24_insel(struct snd_ice1712 * ice,int activate)59e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
601da177e4SLinus Torvalds {
617cda8ba9STakashi Iwai 	struct hoontech_spec *spec = ice->spec;
6262932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
637cda8ba9STakashi Iwai 	ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
647cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
6562932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds 
snd_ice1712_stdsp24_box_channel(struct snd_ice1712 * ice,int box,int chn,int activate)68e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
691da177e4SLinus Torvalds {
707cda8ba9STakashi Iwai 	struct hoontech_spec *spec = ice->spec;
717cda8ba9STakashi Iwai 
7262932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds 	/* select box */
757cda8ba9STakashi Iwai 	ICE1712_STDSP24_0_BOX(spec->boxbits, box);
767cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 	/* prepare for write */
791da177e4SLinus Torvalds 	if (chn == 3)
807cda8ba9STakashi Iwai 		ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
817cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
827cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
837cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
841da177e4SLinus Torvalds 
857cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
867cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
877cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
887cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
897cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
907cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
911da177e4SLinus Torvalds 	udelay(100);
921da177e4SLinus Torvalds 	if (chn == 3) {
937cda8ba9STakashi Iwai 		ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
947cda8ba9STakashi Iwai 		snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
951da177e4SLinus Torvalds 	} else {
961da177e4SLinus Torvalds 		switch (chn) {
977cda8ba9STakashi Iwai 		case 0:	ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
987cda8ba9STakashi Iwai 		case 1:	ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
997cda8ba9STakashi Iwai 		case 2:	ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
1001da177e4SLinus Torvalds 		}
1017cda8ba9STakashi Iwai 		snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
1021da177e4SLinus Torvalds 	}
1031da177e4SLinus Torvalds 	udelay(100);
1047cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
1057cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
1067cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
1077cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
1087cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
1097cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
1101da177e4SLinus Torvalds 	udelay(100);
1111da177e4SLinus Torvalds 
1127cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
1137cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
1141da177e4SLinus Torvalds 
11562932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
1161da177e4SLinus Torvalds }
1171da177e4SLinus Torvalds 
snd_ice1712_stdsp24_box_midi(struct snd_ice1712 * ice,int box,int master)118e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
1191da177e4SLinus Torvalds {
1207cda8ba9STakashi Iwai 	struct hoontech_spec *spec = ice->spec;
1217cda8ba9STakashi Iwai 
12262932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 	/* select box */
1257cda8ba9STakashi Iwai 	ICE1712_STDSP24_0_BOX(spec->boxbits, box);
1267cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
1271da177e4SLinus Torvalds 
1287cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
1297cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
1307cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
1317cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 	udelay(100);
1341da177e4SLinus Torvalds 
1357cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
1367cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds 	mdelay(10);
1391da177e4SLinus Torvalds 
1407cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
1417cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
1421da177e4SLinus Torvalds 
14362932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
1441da177e4SLinus Torvalds }
1451da177e4SLinus Torvalds 
snd_ice1712_stdsp24_midi2(struct snd_ice1712 * ice,int activate)146e23e7a14SBill Pemberton static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
1471da177e4SLinus Torvalds {
1487cda8ba9STakashi Iwai 	struct hoontech_spec *spec = ice->spec;
14962932df8SIngo Molnar 	mutex_lock(&ice->gpio_mutex);
1507cda8ba9STakashi Iwai 	ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
1517cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
15262932df8SIngo Molnar 	mutex_unlock(&ice->gpio_mutex);
1531da177e4SLinus Torvalds }
1541da177e4SLinus Torvalds 
hoontech_init(struct snd_ice1712 * ice,bool staudio)155e8a91ae1STakashi Iwai static int hoontech_init(struct snd_ice1712 *ice, bool staudio)
1561da177e4SLinus Torvalds {
1577cda8ba9STakashi Iwai 	struct hoontech_spec *spec;
1581da177e4SLinus Torvalds 	int box, chn;
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	ice->num_total_dacs = 8;
1611da177e4SLinus Torvalds 	ice->num_total_adcs = 8;
1621da177e4SLinus Torvalds 
1637cda8ba9STakashi Iwai 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1647cda8ba9STakashi Iwai 	if (!spec)
1657cda8ba9STakashi Iwai 		return -ENOMEM;
1667cda8ba9STakashi Iwai 	ice->spec = spec;
1671da177e4SLinus Torvalds 
1687cda8ba9STakashi Iwai 	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
1697cda8ba9STakashi Iwai 	ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
1707cda8ba9STakashi Iwai 	ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
1717cda8ba9STakashi Iwai 	ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
1721da177e4SLinus Torvalds 
1737cda8ba9STakashi Iwai 	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
1747cda8ba9STakashi Iwai 	ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
1757cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
1767cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
1777cda8ba9STakashi Iwai 	ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
1781da177e4SLinus Torvalds 
1797cda8ba9STakashi Iwai 	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
1807cda8ba9STakashi Iwai 	ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
1817cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
1827cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
1837cda8ba9STakashi Iwai 	ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
1841da177e4SLinus Torvalds 
1857cda8ba9STakashi Iwai 	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
1867cda8ba9STakashi Iwai 	ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
1877cda8ba9STakashi Iwai 	ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
1887cda8ba9STakashi Iwai 	ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
1897cda8ba9STakashi Iwai 	ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	/* let's go - activate only functions in first box */
192e8a91ae1STakashi Iwai 	if (staudio)
193e8a91ae1STakashi Iwai 		spec->config = ICE1712_STDSP24_MUTE;
194e8a91ae1STakashi Iwai 	else
1957cda8ba9STakashi Iwai 		spec->config = 0;
1961da177e4SLinus Torvalds 			    /* ICE1712_STDSP24_MUTE |
1971da177e4SLinus Torvalds 			       ICE1712_STDSP24_INSEL |
1981da177e4SLinus Torvalds 			       ICE1712_STDSP24_DAREAR; */
199d043143dSAlan Horstmann 	/*  These boxconfigs have caused problems in the past.
200d043143dSAlan Horstmann 	 *  The code is not optimal, but should now enable a working config to
201d043143dSAlan Horstmann 	 *  be achieved.
202d043143dSAlan Horstmann 	 *  ** MIDI IN can only be configured on one box **
203d043143dSAlan Horstmann 	 *  ICE1712_STDSP24_BOX_MIDI1 needs to be set for that box.
204d043143dSAlan Horstmann 	 *  Tests on a ADAC2000 box suggest the box config flags do not
205d043143dSAlan Horstmann 	 *  work as would be expected, and the inputs are crossed.
206d043143dSAlan Horstmann 	 *  Setting ICE1712_STDSP24_BOX_MIDI1 and ICE1712_STDSP24_BOX_MIDI2
207d043143dSAlan Horstmann 	 *  on the same box connects MIDI-In to both 401 uarts; both outputs
208d043143dSAlan Horstmann 	 *  are then active on all boxes.
209d043143dSAlan Horstmann 	 *  The default config here sets up everything on the first box.
210d043143dSAlan Horstmann 	 *  Alan Horstmann  5.2.2008
211d043143dSAlan Horstmann 	 */
2127cda8ba9STakashi Iwai 	spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
2131da177e4SLinus Torvalds 				     ICE1712_STDSP24_BOX_CHN2 |
2141da177e4SLinus Torvalds 				     ICE1712_STDSP24_BOX_CHN3 |
2151da177e4SLinus Torvalds 				     ICE1712_STDSP24_BOX_CHN4 |
2161da177e4SLinus Torvalds 				     ICE1712_STDSP24_BOX_MIDI1 |
2171da177e4SLinus Torvalds 				     ICE1712_STDSP24_BOX_MIDI2;
218e8a91ae1STakashi Iwai 	if (staudio) {
219e8a91ae1STakashi Iwai 		spec->boxconfig[1] =
220e8a91ae1STakashi Iwai 		spec->boxconfig[2] =
221e8a91ae1STakashi Iwai 		spec->boxconfig[3] = spec->boxconfig[0];
222e8a91ae1STakashi Iwai 	} else {
2237cda8ba9STakashi Iwai 		spec->boxconfig[1] =
2247cda8ba9STakashi Iwai 		spec->boxconfig[2] =
2257cda8ba9STakashi Iwai 		spec->boxconfig[3] = 0;
226e8a91ae1STakashi Iwai 	}
227e8a91ae1STakashi Iwai 
2287cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_darear(ice,
2297cda8ba9STakashi Iwai 		(spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
2307cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_mute(ice,
2317cda8ba9STakashi Iwai 		(spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
2327cda8ba9STakashi Iwai 	snd_ice1712_stdsp24_insel(ice,
2337cda8ba9STakashi Iwai 		(spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
234d043143dSAlan Horstmann 	for (box = 0; box < 4; box++) {
2357cda8ba9STakashi Iwai 		if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
236b8c5b53eSJaroslav Kysela                         snd_ice1712_stdsp24_midi2(ice, 1);
2371da177e4SLinus Torvalds 		for (chn = 0; chn < 4; chn++)
2387cda8ba9STakashi Iwai 			snd_ice1712_stdsp24_box_channel(ice, box, chn,
2397cda8ba9STakashi Iwai 				(spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
240d043143dSAlan Horstmann 		if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1)
241d043143dSAlan Horstmann 			snd_ice1712_stdsp24_box_midi(ice, box, 1);
2421da177e4SLinus Torvalds 	}
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds 	return 0;
2451da177e4SLinus Torvalds }
2461da177e4SLinus Torvalds 
snd_ice1712_hoontech_init(struct snd_ice1712 * ice)247e8a91ae1STakashi Iwai static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
248e8a91ae1STakashi Iwai {
249e8a91ae1STakashi Iwai 	return hoontech_init(ice, false);
250e8a91ae1STakashi Iwai }
251e8a91ae1STakashi Iwai 
snd_ice1712_staudio_init(struct snd_ice1712 * ice)252e8a91ae1STakashi Iwai static int snd_ice1712_staudio_init(struct snd_ice1712 *ice)
253e8a91ae1STakashi Iwai {
254e8a91ae1STakashi Iwai 	return hoontech_init(ice, true);
255e8a91ae1STakashi Iwai }
256e8a91ae1STakashi Iwai 
2571da177e4SLinus Torvalds /*
2581da177e4SLinus Torvalds  * AK4524 access
2591da177e4SLinus Torvalds  */
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds /* start callback for STDSP24 with modified hardware */
stdsp24_ak4524_lock(struct snd_akm4xxx * ak,int chip)2626ca308d4STakashi Iwai static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
2631da177e4SLinus Torvalds {
2646ca308d4STakashi Iwai 	struct snd_ice1712 *ice = ak->private_data[0];
2651da177e4SLinus Torvalds 	unsigned char tmp;
2661da177e4SLinus Torvalds 	snd_ice1712_save_gpio_status(ice);
2671da177e4SLinus Torvalds 	tmp =	ICE1712_STDSP24_SERIAL_DATA |
2681da177e4SLinus Torvalds 		ICE1712_STDSP24_SERIAL_CLOCK |
2691da177e4SLinus Torvalds 		ICE1712_STDSP24_AK4524_CS;
2701da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
2711da177e4SLinus Torvalds 			  ice->gpio.direction | tmp);
2721da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
2731da177e4SLinus Torvalds }
2741da177e4SLinus Torvalds 
snd_ice1712_value_init(struct snd_ice1712 * ice)275e23e7a14SBill Pemberton static int snd_ice1712_value_init(struct snd_ice1712 *ice)
2761da177e4SLinus Torvalds {
2771da177e4SLinus Torvalds 	/* Hoontech STDSP24 with modified hardware */
2783135432eSBhumika Goyal 	static const struct snd_akm4xxx akm_stdsp24_mv = {
2791da177e4SLinus Torvalds 		.num_adcs = 2,
2801da177e4SLinus Torvalds 		.num_dacs = 2,
2811da177e4SLinus Torvalds 		.type = SND_AK4524,
2821da177e4SLinus Torvalds 		.ops = {
2831da177e4SLinus Torvalds 			.lock = stdsp24_ak4524_lock
2841da177e4SLinus Torvalds 		}
2851da177e4SLinus Torvalds 	};
2861da177e4SLinus Torvalds 
2874647e8d5SBhumika Goyal 	static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = {
2881da177e4SLinus Torvalds 		.caddr = 2,
2891da177e4SLinus Torvalds 		.cif = 1, /* CIF high */
2901da177e4SLinus Torvalds 		.data_mask = ICE1712_STDSP24_SERIAL_DATA,
2911da177e4SLinus Torvalds 		.clk_mask = ICE1712_STDSP24_SERIAL_CLOCK,
2921da177e4SLinus Torvalds 		.cs_mask = ICE1712_STDSP24_AK4524_CS,
2931da177e4SLinus Torvalds 		.cs_addr = ICE1712_STDSP24_AK4524_CS,
2941da177e4SLinus Torvalds 		.cs_none = 0,
2951da177e4SLinus Torvalds 		.add_flags = 0,
2961da177e4SLinus Torvalds 	};
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	int err;
2996ca308d4STakashi Iwai 	struct snd_akm4xxx *ak;
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds 	/* set the analog DACs */
3021da177e4SLinus Torvalds 	ice->num_total_dacs = 2;
3031da177e4SLinus Torvalds 
3041da177e4SLinus Torvalds 	/* set the analog ADCs */
3051da177e4SLinus Torvalds 	ice->num_total_adcs = 2;
3061da177e4SLinus Torvalds 
3071da177e4SLinus Torvalds 	/* analog section */
3086ca308d4STakashi Iwai 	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
3091da177e4SLinus Torvalds 	if (! ak)
3101da177e4SLinus Torvalds 		return -ENOMEM;
3111da177e4SLinus Torvalds 	ice->akm_codecs = 1;
3121da177e4SLinus Torvalds 
3131da177e4SLinus Torvalds 	err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice);
3141da177e4SLinus Torvalds 	if (err < 0)
3151da177e4SLinus Torvalds 		return err;
3161da177e4SLinus Torvalds 
3171da177e4SLinus Torvalds 	/* ak4524 controls */
318387417b5SSudip Mukherjee 	return snd_ice1712_akm4xxx_build_controls(ice);
3191da177e4SLinus Torvalds }
3201da177e4SLinus Torvalds 
snd_ice1712_ez8_init(struct snd_ice1712 * ice)321e23e7a14SBill Pemberton static int snd_ice1712_ez8_init(struct snd_ice1712 *ice)
3221da177e4SLinus Torvalds {
3231da177e4SLinus Torvalds 	ice->gpio.write_mask = ice->eeprom.gpiomask;
3241da177e4SLinus Torvalds 	ice->gpio.direction = ice->eeprom.gpiodir;
3251da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
3261da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
3271da177e4SLinus Torvalds 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
3281da177e4SLinus Torvalds 	return 0;
3291da177e4SLinus Torvalds }
3301da177e4SLinus Torvalds 
3311da177e4SLinus Torvalds 
3321da177e4SLinus Torvalds /* entry point */
333e23e7a14SBill Pemberton struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = {
3341da177e4SLinus Torvalds 	{
3351da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_STDSP24,
3361da177e4SLinus Torvalds 		.name = "Hoontech SoundTrack Audio DSP24",
3371da177e4SLinus Torvalds 		.model = "dsp24",
3381da177e4SLinus Torvalds 		.chip_init = snd_ice1712_hoontech_init,
339d043143dSAlan Horstmann 		.mpu401_1_name = "MIDI-1 Hoontech/STA DSP24",
340d043143dSAlan Horstmann 		.mpu401_2_name = "MIDI-2 Hoontech/STA DSP24",
3411da177e4SLinus Torvalds 	},
3421da177e4SLinus Torvalds 	{
3431da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE,	/* a dummy id */
3441da177e4SLinus Torvalds 		.name = "Hoontech SoundTrack Audio DSP24 Value",
3451da177e4SLinus Torvalds 		.model = "dsp24_value",
3461da177e4SLinus Torvalds 		.chip_init = snd_ice1712_value_init,
3471da177e4SLinus Torvalds 	},
3481da177e4SLinus Torvalds 	{
3491da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
3501da177e4SLinus Torvalds 		.name = "Hoontech STA DSP24 Media 7.1",
3511da177e4SLinus Torvalds 		.model = "dsp24_71",
3521da177e4SLinus Torvalds 		.chip_init = snd_ice1712_hoontech_init,
3531da177e4SLinus Torvalds 	},
3541da177e4SLinus Torvalds 	{
3551da177e4SLinus Torvalds 		.subvendor = ICE1712_SUBDEVICE_EVENT_EZ8,	/* a dummy id */
3561da177e4SLinus Torvalds 		.name = "Event Electronics EZ8",
3571da177e4SLinus Torvalds 		.model = "ez8",
3581da177e4SLinus Torvalds 		.chip_init = snd_ice1712_ez8_init,
3591da177e4SLinus Torvalds 	},
360e8a91ae1STakashi Iwai 	{
361e8a91ae1STakashi Iwai 		/* STAudio ADCIII has the same SSID as Hoontech StA DSP24,
362e8a91ae1STakashi Iwai 		 * thus identified only via the explicit model option
363e8a91ae1STakashi Iwai 		 */
364e8a91ae1STakashi Iwai 		.subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII,	/* a dummy id */
365e8a91ae1STakashi Iwai 		.name = "STAudio ADCIII",
366e8a91ae1STakashi Iwai 		.model = "staudio",
367e8a91ae1STakashi Iwai 		.chip_init = snd_ice1712_staudio_init,
368e8a91ae1STakashi Iwai 	},
3691da177e4SLinus Torvalds 	{ } /* terminator */
3701da177e4SLinus Torvalds };
371