ews.c 30 KB

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