18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * ALSA driver for ICEnsemble ICE1712 (Envy24) 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Lowlevel functions for Hoontech STDSP24 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/delay.h> 118c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/slab.h> 148c2ecf20Sopenharmony_ci#include <linux/mutex.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <sound/core.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "ice1712.h" 198c2ecf20Sopenharmony_ci#include "hoontech.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* Hoontech-specific setting */ 228c2ecf20Sopenharmony_cistruct hoontech_spec { 238c2ecf20Sopenharmony_ci unsigned char boxbits[4]; 248c2ecf20Sopenharmony_ci unsigned int config; 258c2ecf20Sopenharmony_ci unsigned short boxconfig[4]; 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci byte |= ICE1712_STDSP24_CLOCK_BIT; 318c2ecf20Sopenharmony_ci udelay(100); 328c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); 338c2ecf20Sopenharmony_ci byte &= ~ICE1712_STDSP24_CLOCK_BIT; 348c2ecf20Sopenharmony_ci udelay(100); 358c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); 368c2ecf20Sopenharmony_ci byte |= ICE1712_STDSP24_CLOCK_BIT; 378c2ecf20Sopenharmony_ci udelay(100); 388c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 448c2ecf20Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 458c2ecf20Sopenharmony_ci ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate); 468c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); 478c2ecf20Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 538c2ecf20Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 548c2ecf20Sopenharmony_ci ICE1712_STDSP24_3_MUTE(spec->boxbits, activate); 558c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 568c2ecf20Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 628c2ecf20Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 638c2ecf20Sopenharmony_ci ICE1712_STDSP24_3_INSEL(spec->boxbits, activate); 648c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 658c2ecf20Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* select box */ 758c2ecf20Sopenharmony_ci ICE1712_STDSP24_0_BOX(spec->boxbits, box); 768c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* prepare for write */ 798c2ecf20Sopenharmony_ci if (chn == 3) 808c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 0); 818c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate); 828c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 838c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); 868c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); 878c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); 888c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); 898c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); 908c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 918c2ecf20Sopenharmony_ci udelay(100); 928c2ecf20Sopenharmony_ci if (chn == 3) { 938c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 0); 948c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 958c2ecf20Sopenharmony_ci } else { 968c2ecf20Sopenharmony_ci switch (chn) { 978c2ecf20Sopenharmony_ci case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break; 988c2ecf20Sopenharmony_ci case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break; 998c2ecf20Sopenharmony_ci case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci udelay(100); 1048c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); 1058c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); 1068c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); 1078c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); 1088c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]); 1098c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 1108c2ecf20Sopenharmony_ci udelay(100); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0); 1138c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) 1198c2ecf20Sopenharmony_ci{ 1208c2ecf20Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci /* select box */ 1258c2ecf20Sopenharmony_ci ICE1712_STDSP24_0_BOX(spec->boxbits, box); 1268c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); 1298c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, master); 1308c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 1318c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci udelay(100); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0); 1368c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci mdelay(10); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); 1418c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci struct hoontech_spec *spec = ice->spec; 1498c2ecf20Sopenharmony_ci mutex_lock(&ice->gpio_mutex); 1508c2ecf20Sopenharmony_ci ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate); 1518c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]); 1528c2ecf20Sopenharmony_ci mutex_unlock(&ice->gpio_mutex); 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistatic int hoontech_init(struct snd_ice1712 *ice, bool staudio) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci struct hoontech_spec *spec; 1588c2ecf20Sopenharmony_ci int box, chn; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci ice->num_total_dacs = 8; 1618c2ecf20Sopenharmony_ci ice->num_total_adcs = 8; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1648c2ecf20Sopenharmony_ci if (!spec) 1658c2ecf20Sopenharmony_ci return -ENOMEM; 1668c2ecf20Sopenharmony_ci ice->spec = spec; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0); 1698c2ecf20Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1); 1708c2ecf20Sopenharmony_ci ICE1712_STDSP24_0_BOX(spec->boxbits, 0); 1718c2ecf20Sopenharmony_ci ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1); 1748c2ecf20Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1); 1758c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN1(spec->boxbits, 1); 1768c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN2(spec->boxbits, 1); 1778c2ecf20Sopenharmony_ci ICE1712_STDSP24_1_CHN3(spec->boxbits, 1); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2); 1808c2ecf20Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1); 1818c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_CHN4(spec->boxbits, 1); 1828c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1); 1838c2ecf20Sopenharmony_ci ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3); 1868c2ecf20Sopenharmony_ci ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1); 1878c2ecf20Sopenharmony_ci ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0); 1888c2ecf20Sopenharmony_ci ICE1712_STDSP24_3_MUTE(spec->boxbits, 1); 1898c2ecf20Sopenharmony_ci ICE1712_STDSP24_3_INSEL(spec->boxbits, 0); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci /* let's go - activate only functions in first box */ 1928c2ecf20Sopenharmony_ci if (staudio) 1938c2ecf20Sopenharmony_ci spec->config = ICE1712_STDSP24_MUTE; 1948c2ecf20Sopenharmony_ci else 1958c2ecf20Sopenharmony_ci spec->config = 0; 1968c2ecf20Sopenharmony_ci /* ICE1712_STDSP24_MUTE | 1978c2ecf20Sopenharmony_ci ICE1712_STDSP24_INSEL | 1988c2ecf20Sopenharmony_ci ICE1712_STDSP24_DAREAR; */ 1998c2ecf20Sopenharmony_ci /* These boxconfigs have caused problems in the past. 2008c2ecf20Sopenharmony_ci * The code is not optimal, but should now enable a working config to 2018c2ecf20Sopenharmony_ci * be achieved. 2028c2ecf20Sopenharmony_ci * ** MIDI IN can only be configured on one box ** 2038c2ecf20Sopenharmony_ci * ICE1712_STDSP24_BOX_MIDI1 needs to be set for that box. 2048c2ecf20Sopenharmony_ci * Tests on a ADAC2000 box suggest the box config flags do not 2058c2ecf20Sopenharmony_ci * work as would be expected, and the inputs are crossed. 2068c2ecf20Sopenharmony_ci * Setting ICE1712_STDSP24_BOX_MIDI1 and ICE1712_STDSP24_BOX_MIDI2 2078c2ecf20Sopenharmony_ci * on the same box connects MIDI-In to both 401 uarts; both outputs 2088c2ecf20Sopenharmony_ci * are then active on all boxes. 2098c2ecf20Sopenharmony_ci * The default config here sets up everything on the first box. 2108c2ecf20Sopenharmony_ci * Alan Horstmann 5.2.2008 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_ci spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 | 2138c2ecf20Sopenharmony_ci ICE1712_STDSP24_BOX_CHN2 | 2148c2ecf20Sopenharmony_ci ICE1712_STDSP24_BOX_CHN3 | 2158c2ecf20Sopenharmony_ci ICE1712_STDSP24_BOX_CHN4 | 2168c2ecf20Sopenharmony_ci ICE1712_STDSP24_BOX_MIDI1 | 2178c2ecf20Sopenharmony_ci ICE1712_STDSP24_BOX_MIDI2; 2188c2ecf20Sopenharmony_ci if (staudio) { 2198c2ecf20Sopenharmony_ci spec->boxconfig[1] = 2208c2ecf20Sopenharmony_ci spec->boxconfig[2] = 2218c2ecf20Sopenharmony_ci spec->boxconfig[3] = spec->boxconfig[0]; 2228c2ecf20Sopenharmony_ci } else { 2238c2ecf20Sopenharmony_ci spec->boxconfig[1] = 2248c2ecf20Sopenharmony_ci spec->boxconfig[2] = 2258c2ecf20Sopenharmony_ci spec->boxconfig[3] = 0; 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_darear(ice, 2298c2ecf20Sopenharmony_ci (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0); 2308c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_mute(ice, 2318c2ecf20Sopenharmony_ci (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0); 2328c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_insel(ice, 2338c2ecf20Sopenharmony_ci (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0); 2348c2ecf20Sopenharmony_ci for (box = 0; box < 4; box++) { 2358c2ecf20Sopenharmony_ci if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2) 2368c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_midi2(ice, 1); 2378c2ecf20Sopenharmony_ci for (chn = 0; chn < 4; chn++) 2388c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_box_channel(ice, box, chn, 2398c2ecf20Sopenharmony_ci (spec->boxconfig[box] & (1 << chn)) ? 1 : 0); 2408c2ecf20Sopenharmony_ci if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) 2418c2ecf20Sopenharmony_ci snd_ice1712_stdsp24_box_midi(ice, box, 1); 2428c2ecf20Sopenharmony_ci } 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci return 0; 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) 2488c2ecf20Sopenharmony_ci{ 2498c2ecf20Sopenharmony_ci return hoontech_init(ice, false); 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic int snd_ice1712_staudio_init(struct snd_ice1712 *ice) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci return hoontech_init(ice, true); 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci/* 2588c2ecf20Sopenharmony_ci * AK4524 access 2598c2ecf20Sopenharmony_ci */ 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci/* start callback for STDSP24 with modified hardware */ 2628c2ecf20Sopenharmony_cistatic void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci struct snd_ice1712 *ice = ak->private_data[0]; 2658c2ecf20Sopenharmony_ci unsigned char tmp; 2668c2ecf20Sopenharmony_ci snd_ice1712_save_gpio_status(ice); 2678c2ecf20Sopenharmony_ci tmp = ICE1712_STDSP24_SERIAL_DATA | 2688c2ecf20Sopenharmony_ci ICE1712_STDSP24_SERIAL_CLOCK | 2698c2ecf20Sopenharmony_ci ICE1712_STDSP24_AK4524_CS; 2708c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 2718c2ecf20Sopenharmony_ci ice->gpio.direction | tmp); 2728c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp); 2738c2ecf20Sopenharmony_ci} 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic int snd_ice1712_value_init(struct snd_ice1712 *ice) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci /* Hoontech STDSP24 with modified hardware */ 2788c2ecf20Sopenharmony_ci static const struct snd_akm4xxx akm_stdsp24_mv = { 2798c2ecf20Sopenharmony_ci .num_adcs = 2, 2808c2ecf20Sopenharmony_ci .num_dacs = 2, 2818c2ecf20Sopenharmony_ci .type = SND_AK4524, 2828c2ecf20Sopenharmony_ci .ops = { 2838c2ecf20Sopenharmony_ci .lock = stdsp24_ak4524_lock 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci }; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = { 2888c2ecf20Sopenharmony_ci .caddr = 2, 2898c2ecf20Sopenharmony_ci .cif = 1, /* CIF high */ 2908c2ecf20Sopenharmony_ci .data_mask = ICE1712_STDSP24_SERIAL_DATA, 2918c2ecf20Sopenharmony_ci .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK, 2928c2ecf20Sopenharmony_ci .cs_mask = ICE1712_STDSP24_AK4524_CS, 2938c2ecf20Sopenharmony_ci .cs_addr = ICE1712_STDSP24_AK4524_CS, 2948c2ecf20Sopenharmony_ci .cs_none = 0, 2958c2ecf20Sopenharmony_ci .add_flags = 0, 2968c2ecf20Sopenharmony_ci }; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci int err; 2998c2ecf20Sopenharmony_ci struct snd_akm4xxx *ak; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci /* set the analog DACs */ 3028c2ecf20Sopenharmony_ci ice->num_total_dacs = 2; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci /* set the analog ADCs */ 3058c2ecf20Sopenharmony_ci ice->num_total_adcs = 2; 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci /* analog section */ 3088c2ecf20Sopenharmony_ci ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 3098c2ecf20Sopenharmony_ci if (! ak) 3108c2ecf20Sopenharmony_ci return -ENOMEM; 3118c2ecf20Sopenharmony_ci ice->akm_codecs = 1; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice); 3148c2ecf20Sopenharmony_ci if (err < 0) 3158c2ecf20Sopenharmony_ci return err; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci /* ak4524 controls */ 3188c2ecf20Sopenharmony_ci return snd_ice1712_akm4xxx_build_controls(ice); 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic int snd_ice1712_ez8_init(struct snd_ice1712 *ice) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci ice->gpio.write_mask = ice->eeprom.gpiomask; 3248c2ecf20Sopenharmony_ci ice->gpio.direction = ice->eeprom.gpiodir; 3258c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask); 3268c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir); 3278c2ecf20Sopenharmony_ci snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate); 3288c2ecf20Sopenharmony_ci return 0; 3298c2ecf20Sopenharmony_ci} 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci/* entry point */ 3338c2ecf20Sopenharmony_cistruct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = { 3348c2ecf20Sopenharmony_ci { 3358c2ecf20Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STDSP24, 3368c2ecf20Sopenharmony_ci .name = "Hoontech SoundTrack Audio DSP24", 3378c2ecf20Sopenharmony_ci .model = "dsp24", 3388c2ecf20Sopenharmony_ci .chip_init = snd_ice1712_hoontech_init, 3398c2ecf20Sopenharmony_ci .mpu401_1_name = "MIDI-1 Hoontech/STA DSP24", 3408c2ecf20Sopenharmony_ci .mpu401_2_name = "MIDI-2 Hoontech/STA DSP24", 3418c2ecf20Sopenharmony_ci }, 3428c2ecf20Sopenharmony_ci { 3438c2ecf20Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE, /* a dummy id */ 3448c2ecf20Sopenharmony_ci .name = "Hoontech SoundTrack Audio DSP24 Value", 3458c2ecf20Sopenharmony_ci .model = "dsp24_value", 3468c2ecf20Sopenharmony_ci .chip_init = snd_ice1712_value_init, 3478c2ecf20Sopenharmony_ci }, 3488c2ecf20Sopenharmony_ci { 3498c2ecf20Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1, 3508c2ecf20Sopenharmony_ci .name = "Hoontech STA DSP24 Media 7.1", 3518c2ecf20Sopenharmony_ci .model = "dsp24_71", 3528c2ecf20Sopenharmony_ci .chip_init = snd_ice1712_hoontech_init, 3538c2ecf20Sopenharmony_ci }, 3548c2ecf20Sopenharmony_ci { 3558c2ecf20Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8, /* a dummy id */ 3568c2ecf20Sopenharmony_ci .name = "Event Electronics EZ8", 3578c2ecf20Sopenharmony_ci .model = "ez8", 3588c2ecf20Sopenharmony_ci .chip_init = snd_ice1712_ez8_init, 3598c2ecf20Sopenharmony_ci }, 3608c2ecf20Sopenharmony_ci { 3618c2ecf20Sopenharmony_ci /* STAudio ADCIII has the same SSID as Hoontech StA DSP24, 3628c2ecf20Sopenharmony_ci * thus identified only via the explicit model option 3638c2ecf20Sopenharmony_ci */ 3648c2ecf20Sopenharmony_ci .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII, /* a dummy id */ 3658c2ecf20Sopenharmony_ci .name = "STAudio ADCIII", 3668c2ecf20Sopenharmony_ci .model = "staudio", 3678c2ecf20Sopenharmony_ci .chip_init = snd_ice1712_staudio_init, 3688c2ecf20Sopenharmony_ci }, 3698c2ecf20Sopenharmony_ci { } /* terminator */ 3708c2ecf20Sopenharmony_ci}; 371