162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ALSA driver for ICEnsemble ICE1712 (Envy24) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Lowlevel functions for Hoontech STDSP24 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/delay.h> 1162306a36Sopenharmony_ci#include <linux/interrupt.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/slab.h> 1462306a36Sopenharmony_ci#include <linux/mutex.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <sound/core.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "ice1712.h" 1962306a36Sopenharmony_ci#include "hoontech.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* Hoontech-specific setting */ 2262306a36Sopenharmony_cistruct hoontech_spec { 2362306a36Sopenharmony_ci unsigned char boxbits[4]; 2462306a36Sopenharmony_ci unsigned int config; 2562306a36Sopenharmony_ci unsigned short boxconfig[4]; 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci byte |= ICE1712_STDSP24_CLOCK_BIT; 3162306a36Sopenharmony_ci udelay(100); 3262306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); 3362306a36Sopenharmony_ci byte &= ~ICE1712_STDSP24_CLOCK_BIT; 3462306a36Sopenharmony_ci udelay(100); 3562306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); 3662306a36Sopenharmony_ci byte |= ICE1712_STDSP24_CLOCK_BIT; 3762306a36Sopenharmony_ci udelay(100); 3862306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 4462306a36Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 4562306a36Sopenharmony_ci ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate); 4662306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); 4762306a36Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 5362306a36Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 5462306a36Sopenharmony_ci ICE1712_STDSP24_3_MUTE(spec->boxbits, activate); 5562306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 5662306a36Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 6262306a36Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 6362306a36Sopenharmony_ci ICE1712_STDSP24_3_INSEL(spec->boxbits, activate); 6462306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 6562306a36Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /* select box */ 7562306a36Sopenharmony_ci ICE1712_STDSP24_0_BOX(spec->boxbits, box); 7662306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci /* prepare for write */ 7962306a36Sopenharmony_ci if (chn == 3) 8062306a36Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 0); 8162306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate); 8262306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 8362306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); 8662306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); 8762306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); 8862306a36Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); 8962306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); 9062306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 9162306a36Sopenharmony_ci udelay(100); 9262306a36Sopenharmony_ci if (chn == 3) { 9362306a36Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 0); 9462306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 9562306a36Sopenharmony_ci } else { 9662306a36Sopenharmony_ci switch (chn) { 9762306a36Sopenharmony_ci case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break; 9862306a36Sopenharmony_ci case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break; 9962306a36Sopenharmony_ci case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break; 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci udelay(100); 10462306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); 10562306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); 10662306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); 10762306a36Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); 10862306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); 10962306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 11062306a36Sopenharmony_ci udelay(100); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0); 11362306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) 11962306a36Sopenharmony_ci{ 12062306a36Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci /* select box */ 12562306a36Sopenharmony_ci ICE1712_STDSP24_0_BOX(spec->boxbits, box); 12662306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); 12962306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, master); 13062306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 13162306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci udelay(100); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0); 13662306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci mdelay(10); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); 14162306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) 14762306a36Sopenharmony_ci{ 14862306a36Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 14962306a36Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 15062306a36Sopenharmony_ci ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate); 15162306a36Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 15262306a36Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic int hoontech_init(struct snd_ice1712 *ice, bool staudio) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci struct hoontech_spec *spec; 15862306a36Sopenharmony_ci int box, chn; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci ice->num_total_dacs = 8; 16162306a36Sopenharmony_ci ice->num_total_adcs = 8; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16462306a36Sopenharmony_ci if (!spec) 16562306a36Sopenharmony_ci return -ENOMEM; 16662306a36Sopenharmony_ci ice->spec = spec; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0); 16962306a36Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1); 17062306a36Sopenharmony_ci ICE1712_STDSP24_0_BOX(spec->boxbits, 0); 17162306a36Sopenharmony_ci ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1); 17462306a36Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1); 17562306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); 17662306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); 17762306a36Sopenharmony_ci ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2); 18062306a36Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1); 18162306a36Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); 18262306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); 18362306a36Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3); 18662306a36Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1); 18762306a36Sopenharmony_ci ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0); 18862306a36Sopenharmony_ci ICE1712_STDSP24_3_MUTE(spec->boxbits, 1); 18962306a36Sopenharmony_ci ICE1712_STDSP24_3_INSEL(spec->boxbits, 0); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci /* let's go - activate only functions in first box */ 19262306a36Sopenharmony_ci if (staudio) 19362306a36Sopenharmony_ci spec->config = ICE1712_STDSP24_MUTE; 19462306a36Sopenharmony_ci else 19562306a36Sopenharmony_ci spec->config = 0; 19662306a36Sopenharmony_ci /* ICE1712_STDSP24_MUTE | 19762306a36Sopenharmony_ci ICE1712_STDSP24_INSEL | 19862306a36Sopenharmony_ci ICE1712_STDSP24_DAREAR; */ 19962306a36Sopenharmony_ci /* These boxconfigs have caused problems in the past. 20062306a36Sopenharmony_ci * The code is not optimal, but should now enable a working config to 20162306a36Sopenharmony_ci * be achieved. 20262306a36Sopenharmony_ci * ** MIDI IN can only be configured on one box ** 20362306a36Sopenharmony_ci * ICE1712_STDSP24_BOX_MIDI1 needs to be set for that box. 20462306a36Sopenharmony_ci * Tests on a ADAC2000 box suggest the box config flags do not 20562306a36Sopenharmony_ci * work as would be expected, and the inputs are crossed. 20662306a36Sopenharmony_ci * Setting ICE1712_STDSP24_BOX_MIDI1 and ICE1712_STDSP24_BOX_MIDI2 20762306a36Sopenharmony_ci * on the same box connects MIDI-In to both 401 uarts; both outputs 20862306a36Sopenharmony_ci * are then active on all boxes. 20962306a36Sopenharmony_ci * The default config here sets up everything on the first box. 21062306a36Sopenharmony_ci * Alan Horstmann 5.2.2008 21162306a36Sopenharmony_ci */ 21262306a36Sopenharmony_ci spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 | 21362306a36Sopenharmony_ci ICE1712_STDSP24_BOX_CHN2 | 21462306a36Sopenharmony_ci ICE1712_STDSP24_BOX_CHN3 | 21562306a36Sopenharmony_ci ICE1712_STDSP24_BOX_CHN4 | 21662306a36Sopenharmony_ci ICE1712_STDSP24_BOX_MIDI1 | 21762306a36Sopenharmony_ci ICE1712_STDSP24_BOX_MIDI2; 21862306a36Sopenharmony_ci if (staudio) { 21962306a36Sopenharmony_ci spec->boxconfig[1] = 22062306a36Sopenharmony_ci spec->boxconfig[2] = 22162306a36Sopenharmony_ci spec->boxconfig[3] = spec->boxconfig[0]; 22262306a36Sopenharmony_ci } else { 22362306a36Sopenharmony_ci spec->boxconfig[1] = 22462306a36Sopenharmony_ci spec->boxconfig[2] = 22562306a36Sopenharmony_ci spec->boxconfig[3] = 0; 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci snd_ice1712_stdsp24_darear(ice, 22962306a36Sopenharmony_ci (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0); 23062306a36Sopenharmony_ci snd_ice1712_stdsp24_mute(ice, 23162306a36Sopenharmony_ci (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0); 23262306a36Sopenharmony_ci snd_ice1712_stdsp24_insel(ice, 23362306a36Sopenharmony_ci (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0); 23462306a36Sopenharmony_ci for (box = 0; box < 4; box++) { 23562306a36Sopenharmony_ci if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2) 23662306a36Sopenharmony_ci snd_ice1712_stdsp24_midi2(ice, 1); 23762306a36Sopenharmony_ci for (chn = 0; chn < 4; chn++) 23862306a36Sopenharmony_ci snd_ice1712_stdsp24_box_channel(ice, box, chn, 23962306a36Sopenharmony_ci (spec->boxconfig[box] & (1 << chn)) ? 1 : 0); 24062306a36Sopenharmony_ci if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) 24162306a36Sopenharmony_ci snd_ice1712_stdsp24_box_midi(ice, box, 1); 24262306a36Sopenharmony_ci } 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci return 0; 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci return hoontech_init(ice, false); 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic int snd_ice1712_staudio_init(struct snd_ice1712 *ice) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci return hoontech_init(ice, true); 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/* 25862306a36Sopenharmony_ci * AK4524 access 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci/* start callback for STDSP24 with modified hardware */ 26262306a36Sopenharmony_cistatic void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) 26362306a36Sopenharmony_ci{ 26462306a36Sopenharmony_ci struct snd_ice1712 *ice = ak->private_data[0]; 26562306a36Sopenharmony_ci unsigned char tmp; 26662306a36Sopenharmony_ci snd_ice1712_save_gpio_status(ice); 26762306a36Sopenharmony_ci tmp = ICE1712_STDSP24_SERIAL_DATA | 26862306a36Sopenharmony_ci ICE1712_STDSP24_SERIAL_CLOCK | 26962306a36Sopenharmony_ci ICE1712_STDSP24_AK4524_CS; 27062306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 27162306a36Sopenharmony_ci ice->gpio.direction | tmp); 27262306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp); 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_cistatic int snd_ice1712_value_init(struct snd_ice1712 *ice) 27662306a36Sopenharmony_ci{ 27762306a36Sopenharmony_ci /* Hoontech STDSP24 with modified hardware */ 27862306a36Sopenharmony_ci static const struct snd_akm4xxx akm_stdsp24_mv = { 27962306a36Sopenharmony_ci .num_adcs = 2, 28062306a36Sopenharmony_ci .num_dacs = 2, 28162306a36Sopenharmony_ci .type = SND_AK4524, 28262306a36Sopenharmony_ci .ops = { 28362306a36Sopenharmony_ci .lock = stdsp24_ak4524_lock 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci }; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = { 28862306a36Sopenharmony_ci .caddr = 2, 28962306a36Sopenharmony_ci .cif = 1, /* CIF high */ 29062306a36Sopenharmony_ci .data_mask = ICE1712_STDSP24_SERIAL_DATA, 29162306a36Sopenharmony_ci .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK, 29262306a36Sopenharmony_ci .cs_mask = ICE1712_STDSP24_AK4524_CS, 29362306a36Sopenharmony_ci .cs_addr = ICE1712_STDSP24_AK4524_CS, 29462306a36Sopenharmony_ci .cs_none = 0, 29562306a36Sopenharmony_ci .add_flags = 0, 29662306a36Sopenharmony_ci }; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci int err; 29962306a36Sopenharmony_ci struct snd_akm4xxx *ak; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci /* set the analog DACs */ 30262306a36Sopenharmony_ci ice->num_total_dacs = 2; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* set the analog ADCs */ 30562306a36Sopenharmony_ci ice->num_total_adcs = 2; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci /* analog section */ 30862306a36Sopenharmony_ci ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 30962306a36Sopenharmony_ci if (! ak) 31062306a36Sopenharmony_ci return -ENOMEM; 31162306a36Sopenharmony_ci ice->akm_codecs = 1; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice); 31462306a36Sopenharmony_ci if (err < 0) 31562306a36Sopenharmony_ci return err; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* ak4524 controls */ 31862306a36Sopenharmony_ci return snd_ice1712_akm4xxx_build_controls(ice); 31962306a36Sopenharmony_ci} 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_cistatic int snd_ice1712_ez8_init(struct snd_ice1712 *ice) 32262306a36Sopenharmony_ci{ 32362306a36Sopenharmony_ci ice->gpio.write_mask = ice->eeprom.gpiomask; 32462306a36Sopenharmony_ci ice->gpio.direction = ice->eeprom.gpiodir; 32562306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask); 32662306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir); 32762306a36Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate); 32862306a36Sopenharmony_ci return 0; 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci/* entry point */ 33362306a36Sopenharmony_cistruct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = { 33462306a36Sopenharmony_ci { 33562306a36Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STDSP24, 33662306a36Sopenharmony_ci .name = "Hoontech SoundTrack Audio DSP24", 33762306a36Sopenharmony_ci .model = "dsp24", 33862306a36Sopenharmony_ci .chip_init = snd_ice1712_hoontech_init, 33962306a36Sopenharmony_ci .mpu401_1_name = "MIDI-1 Hoontech/STA DSP24", 34062306a36Sopenharmony_ci .mpu401_2_name = "MIDI-2 Hoontech/STA DSP24", 34162306a36Sopenharmony_ci }, 34262306a36Sopenharmony_ci { 34362306a36Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE, /* a dummy id */ 34462306a36Sopenharmony_ci .name = "Hoontech SoundTrack Audio DSP24 Value", 34562306a36Sopenharmony_ci .model = "dsp24_value", 34662306a36Sopenharmony_ci .chip_init = snd_ice1712_value_init, 34762306a36Sopenharmony_ci }, 34862306a36Sopenharmony_ci { 34962306a36Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1, 35062306a36Sopenharmony_ci .name = "Hoontech STA DSP24 Media 7.1", 35162306a36Sopenharmony_ci .model = "dsp24_71", 35262306a36Sopenharmony_ci .chip_init = snd_ice1712_hoontech_init, 35362306a36Sopenharmony_ci }, 35462306a36Sopenharmony_ci { 35562306a36Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8, /* a dummy id */ 35662306a36Sopenharmony_ci .name = "Event Electronics EZ8", 35762306a36Sopenharmony_ci .model = "ez8", 35862306a36Sopenharmony_ci .chip_init = snd_ice1712_ez8_init, 35962306a36Sopenharmony_ci }, 36062306a36Sopenharmony_ci { 36162306a36Sopenharmony_ci /* STAudio ADCIII has the same SSID as Hoontech StA DSP24, 36262306a36Sopenharmony_ci * thus identified only via the explicit model option 36362306a36Sopenharmony_ci */ 36462306a36Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII, /* a dummy id */ 36562306a36Sopenharmony_ci .name = "STAudio ADCIII", 36662306a36Sopenharmony_ci .model = "staudio", 36762306a36Sopenharmony_ci .chip_init = snd_ice1712_staudio_init, 36862306a36Sopenharmony_ci }, 36962306a36Sopenharmony_ci { } /* terminator */ 37062306a36Sopenharmony_ci}; 371