revo.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * ALSA driver for ICEnsemble ICE1712 (Envy24)
  4. *
  5. * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
  6. *
  7. * Copyright (c) 2003 Takashi Iwai <[email protected]>
  8. */
  9. #include <linux/delay.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/init.h>
  12. #include <linux/slab.h>
  13. #include <sound/core.h>
  14. #include "ice1712.h"
  15. #include "envy24ht.h"
  16. #include "revo.h"
  17. /* a non-standard I2C device for revo51 */
  18. struct revo51_spec {
  19. struct snd_i2c_device *dev;
  20. struct snd_pt2258 *pt2258;
  21. struct ak4114 *ak4114;
  22. };
  23. static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
  24. {
  25. /* assert PRST# to converters; MT05 bit 7 */
  26. outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
  27. mdelay(5);
  28. /* deassert PRST# */
  29. outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
  30. }
  31. /*
  32. * change the rate of Envy24HT, AK4355 and AK4381
  33. */
  34. static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
  35. {
  36. unsigned char old, tmp, dfs;
  37. int reg, shift;
  38. if (rate == 0) /* no hint - S/PDIF input is master, simply return */
  39. return;
  40. /* adjust DFS on codecs */
  41. if (rate > 96000)
  42. dfs = 2;
  43. else if (rate > 48000)
  44. dfs = 1;
  45. else
  46. dfs = 0;
  47. if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
  48. reg = 2;
  49. shift = 4;
  50. } else {
  51. reg = 1;
  52. shift = 3;
  53. }
  54. tmp = snd_akm4xxx_get(ak, 0, reg);
  55. old = (tmp >> shift) & 0x03;
  56. if (old == dfs)
  57. return;
  58. /* reset DFS */
  59. snd_akm4xxx_reset(ak, 1);
  60. tmp = snd_akm4xxx_get(ak, 0, reg);
  61. tmp &= ~(0x03 << shift);
  62. tmp |= dfs << shift;
  63. /* snd_akm4xxx_write(ak, 0, reg, tmp); */
  64. snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
  65. snd_akm4xxx_reset(ak, 0);
  66. }
  67. /*
  68. * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
  69. */
  70. static void revo_i2c_start(struct snd_i2c_bus *bus)
  71. {
  72. struct snd_ice1712 *ice = bus->private_data;
  73. snd_ice1712_save_gpio_status(ice);
  74. }
  75. static void revo_i2c_stop(struct snd_i2c_bus *bus)
  76. {
  77. struct snd_ice1712 *ice = bus->private_data;
  78. snd_ice1712_restore_gpio_status(ice);
  79. }
  80. static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
  81. {
  82. struct snd_ice1712 *ice = bus->private_data;
  83. unsigned int mask, val;
  84. val = 0;
  85. if (clock)
  86. val |= VT1724_REVO_I2C_CLOCK; /* write SCL */
  87. if (data)
  88. val |= VT1724_REVO_I2C_DATA; /* write SDA */
  89. mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;
  90. ice->gpio.direction &= ~mask;
  91. ice->gpio.direction |= val;
  92. snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
  93. snd_ice1712_gpio_set_mask(ice, ~mask);
  94. }
  95. static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
  96. {
  97. struct snd_ice1712 *ice = bus->private_data;
  98. unsigned int val = 0;
  99. if (clk)
  100. val |= VT1724_REVO_I2C_CLOCK;
  101. if (data)
  102. val |= VT1724_REVO_I2C_DATA;
  103. snd_ice1712_gpio_write_bits(ice,
  104. VT1724_REVO_I2C_DATA |
  105. VT1724_REVO_I2C_CLOCK, val);
  106. udelay(5);
  107. }
  108. static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)
  109. {
  110. struct snd_ice1712 *ice = bus->private_data;
  111. int bit;
  112. if (ack)
  113. udelay(5);
  114. bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;
  115. return bit;
  116. }
  117. static struct snd_i2c_bit_ops revo51_bit_ops = {
  118. .start = revo_i2c_start,
  119. .stop = revo_i2c_stop,
  120. .direction = revo_i2c_direction,
  121. .setlines = revo_i2c_setlines,
  122. .getdata = revo_i2c_getdata,
  123. };
  124. static int revo51_i2c_init(struct snd_ice1712 *ice,
  125. struct snd_pt2258 *pt)
  126. {
  127. struct revo51_spec *spec;
  128. int err;
  129. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  130. if (!spec)
  131. return -ENOMEM;
  132. ice->spec = spec;
  133. /* create the I2C bus */
  134. err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
  135. if (err < 0)
  136. return err;
  137. ice->i2c->private_data = ice;
  138. ice->i2c->hw_ops.bit = &revo51_bit_ops;
  139. /* create the I2C device */
  140. err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
  141. if (err < 0)
  142. return err;
  143. pt->card = ice->card;
  144. pt->i2c_bus = ice->i2c;
  145. pt->i2c_dev = spec->dev;
  146. spec->pt2258 = pt;
  147. snd_pt2258_reset(pt);
  148. return 0;
  149. }
  150. /*
  151. * initialize the chips on M-Audio Revolution cards
  152. */
  153. #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
  154. static const struct snd_akm4xxx_dac_channel revo71_front[] = {
  155. {
  156. .name = "PCM Playback Volume",
  157. .num_channels = 2,
  158. /* front channels DAC supports muting */
  159. .switch_name = "PCM Playback Switch",
  160. },
  161. };
  162. static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
  163. AK_DAC("PCM Center Playback Volume", 1),
  164. AK_DAC("PCM LFE Playback Volume", 1),
  165. AK_DAC("PCM Side Playback Volume", 2),
  166. AK_DAC("PCM Rear Playback Volume", 2),
  167. };
  168. static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
  169. AK_DAC("PCM Playback Volume", 2),
  170. AK_DAC("PCM Center Playback Volume", 1),
  171. AK_DAC("PCM LFE Playback Volume", 1),
  172. AK_DAC("PCM Rear Playback Volume", 2),
  173. AK_DAC("PCM Headphone Volume", 2),
  174. };
  175. static const char *revo51_adc_input_names[] = {
  176. "Mic",
  177. "Line",
  178. "CD",
  179. NULL
  180. };
  181. static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
  182. {
  183. .name = "PCM Capture Volume",
  184. .switch_name = "PCM Capture Switch",
  185. .num_channels = 2,
  186. .input_names = revo51_adc_input_names
  187. },
  188. };
  189. static const struct snd_akm4xxx akm_revo_front = {
  190. .type = SND_AK4381,
  191. .num_dacs = 2,
  192. .ops = {
  193. .set_rate_val = revo_set_rate_val
  194. },
  195. .dac_info = revo71_front,
  196. };
  197. static const struct snd_ak4xxx_private akm_revo_front_priv = {
  198. .caddr = 1,
  199. .cif = 0,
  200. .data_mask = VT1724_REVO_CDOUT,
  201. .clk_mask = VT1724_REVO_CCLK,
  202. .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
  203. .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
  204. .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
  205. .add_flags = VT1724_REVO_CCLK, /* high at init */
  206. .mask_flags = 0,
  207. };
  208. static const struct snd_akm4xxx akm_revo_surround = {
  209. .type = SND_AK4355,
  210. .idx_offset = 1,
  211. .num_dacs = 6,
  212. .ops = {
  213. .set_rate_val = revo_set_rate_val
  214. },
  215. .dac_info = revo71_surround,
  216. };
  217. static const struct snd_ak4xxx_private akm_revo_surround_priv = {
  218. .caddr = 3,
  219. .cif = 0,
  220. .data_mask = VT1724_REVO_CDOUT,
  221. .clk_mask = VT1724_REVO_CCLK,
  222. .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
  223. .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
  224. .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
  225. .add_flags = VT1724_REVO_CCLK, /* high at init */
  226. .mask_flags = 0,
  227. };
  228. static const struct snd_akm4xxx akm_revo51 = {
  229. .type = SND_AK4358,
  230. .num_dacs = 8,
  231. .ops = {
  232. .set_rate_val = revo_set_rate_val
  233. },
  234. .dac_info = revo51_dac,
  235. };
  236. static const struct snd_ak4xxx_private akm_revo51_priv = {
  237. .caddr = 2,
  238. .cif = 0,
  239. .data_mask = VT1724_REVO_CDOUT,
  240. .clk_mask = VT1724_REVO_CCLK,
  241. .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
  242. .cs_addr = VT1724_REVO_CS1,
  243. .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
  244. .add_flags = VT1724_REVO_CCLK, /* high at init */
  245. .mask_flags = 0,
  246. };
  247. static const struct snd_akm4xxx akm_revo51_adc = {
  248. .type = SND_AK5365,
  249. .num_adcs = 2,
  250. .adc_info = revo51_adc,
  251. };
  252. static const struct snd_ak4xxx_private akm_revo51_adc_priv = {
  253. .caddr = 2,
  254. .cif = 0,
  255. .data_mask = VT1724_REVO_CDOUT,
  256. .clk_mask = VT1724_REVO_CCLK,
  257. .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
  258. .cs_addr = VT1724_REVO_CS0,
  259. .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
  260. .add_flags = VT1724_REVO_CCLK, /* high at init */
  261. .mask_flags = 0,
  262. };
  263. static struct snd_pt2258 ptc_revo51_volume;
  264. /* AK4358 for AP192 DAC, AK5385A for ADC */
  265. static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
  266. {
  267. struct snd_ice1712 *ice = ak->private_data[0];
  268. int dfs;
  269. revo_set_rate_val(ak, rate);
  270. /* reset CKS */
  271. snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0);
  272. /* reset DFS pins of AK5385A for ADC, too */
  273. if (rate > 96000)
  274. dfs = 2;
  275. else if (rate > 48000)
  276. dfs = 1;
  277. else
  278. dfs = 0;
  279. snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9);
  280. /* reset ADC */
  281. snd_ice1712_gpio_write_bits(ice, 1 << 11, 0);
  282. snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11);
  283. }
  284. static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
  285. AK_DAC("PCM Playback Volume", 2)
  286. };
  287. static const struct snd_akm4xxx akm_ap192 = {
  288. .type = SND_AK4358,
  289. .num_dacs = 2,
  290. .ops = {
  291. .set_rate_val = ap192_set_rate_val
  292. },
  293. .dac_info = ap192_dac,
  294. };
  295. static const struct snd_ak4xxx_private akm_ap192_priv = {
  296. .caddr = 2,
  297. .cif = 0,
  298. .data_mask = VT1724_REVO_CDOUT,
  299. .clk_mask = VT1724_REVO_CCLK,
  300. .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3,
  301. .cs_addr = VT1724_REVO_CS3,
  302. .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,
  303. .add_flags = VT1724_REVO_CCLK, /* high at init */
  304. .mask_flags = 0,
  305. };
  306. /* AK4114 support on Audiophile 192 */
  307. /* CDTO (pin 32) -- GPIO2 pin 52
  308. * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
  309. * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
  310. * CSN (pin 35) -- GPIO7 pin 59
  311. */
  312. #define AK4114_ADDR 0x00
  313. static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
  314. unsigned int data, int idx)
  315. {
  316. for (; idx >= 0; idx--) {
  317. /* drop clock */
  318. gpio &= ~VT1724_REVO_CCLK;
  319. snd_ice1712_gpio_write(ice, gpio);
  320. udelay(1);
  321. /* set data */
  322. if (data & (1 << idx))
  323. gpio |= VT1724_REVO_CDOUT;
  324. else
  325. gpio &= ~VT1724_REVO_CDOUT;
  326. snd_ice1712_gpio_write(ice, gpio);
  327. udelay(1);
  328. /* raise clock */
  329. gpio |= VT1724_REVO_CCLK;
  330. snd_ice1712_gpio_write(ice, gpio);
  331. udelay(1);
  332. }
  333. }
  334. static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
  335. int idx)
  336. {
  337. unsigned char data = 0;
  338. for (; idx >= 0; idx--) {
  339. /* drop clock */
  340. gpio &= ~VT1724_REVO_CCLK;
  341. snd_ice1712_gpio_write(ice, gpio);
  342. udelay(1);
  343. /* read data */
  344. if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)
  345. data |= (1 << idx);
  346. udelay(1);
  347. /* raise clock */
  348. gpio |= VT1724_REVO_CCLK;
  349. snd_ice1712_gpio_write(ice, gpio);
  350. udelay(1);
  351. }
  352. return data;
  353. }
  354. static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
  355. {
  356. unsigned int tmp;
  357. snd_ice1712_save_gpio_status(ice);
  358. tmp = snd_ice1712_gpio_read(ice);
  359. tmp |= VT1724_REVO_CCLK; /* high at init */
  360. tmp |= VT1724_REVO_CS0;
  361. tmp &= ~VT1724_REVO_CS3;
  362. snd_ice1712_gpio_write(ice, tmp);
  363. udelay(1);
  364. return tmp;
  365. }
  366. static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
  367. {
  368. tmp |= VT1724_REVO_CS3;
  369. tmp |= VT1724_REVO_CS0;
  370. snd_ice1712_gpio_write(ice, tmp);
  371. udelay(1);
  372. snd_ice1712_restore_gpio_status(ice);
  373. }
  374. static void ap192_ak4114_write(void *private_data, unsigned char addr,
  375. unsigned char data)
  376. {
  377. struct snd_ice1712 *ice = private_data;
  378. unsigned int tmp, addrdata;
  379. tmp = ap192_4wire_start(ice);
  380. addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
  381. addrdata = (addrdata << 8) | data;
  382. write_data(ice, tmp, addrdata, 15);
  383. ap192_4wire_finish(ice, tmp);
  384. }
  385. static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
  386. {
  387. struct snd_ice1712 *ice = private_data;
  388. unsigned int tmp;
  389. unsigned char data;
  390. tmp = ap192_4wire_start(ice);
  391. write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
  392. data = read_data(ice, tmp, 7);
  393. ap192_4wire_finish(ice, tmp);
  394. return data;
  395. }
  396. static int ap192_ak4114_init(struct snd_ice1712 *ice)
  397. {
  398. static const unsigned char ak4114_init_vals[] = {
  399. AK4114_RST | AK4114_PWN | AK4114_OCKS0,
  400. AK4114_DIF_I24I2S,
  401. AK4114_TX1E,
  402. AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0),
  403. 0,
  404. 0
  405. };
  406. static const unsigned char ak4114_init_txcsb[] = {
  407. 0x41, 0x02, 0x2c, 0x00, 0x00
  408. };
  409. int err;
  410. struct revo51_spec *spec;
  411. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  412. if (!spec)
  413. return -ENOMEM;
  414. ice->spec = spec;
  415. err = snd_ak4114_create(ice->card,
  416. ap192_ak4114_read,
  417. ap192_ak4114_write,
  418. ak4114_init_vals, ak4114_init_txcsb,
  419. ice, &spec->ak4114);
  420. if (err < 0)
  421. return err;
  422. /* AK4114 in Revo cannot detect external rate correctly.
  423. * No reason to stop capture stream due to incorrect checks */
  424. spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;
  425. return 0;
  426. }
  427. static int revo_init(struct snd_ice1712 *ice)
  428. {
  429. struct snd_akm4xxx *ak;
  430. int err;
  431. /* determine I2C, DACs and ADCs */
  432. switch (ice->eeprom.subvendor) {
  433. case VT1724_SUBDEVICE_REVOLUTION71:
  434. ice->num_total_dacs = 8;
  435. ice->num_total_adcs = 2;
  436. ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
  437. break;
  438. case VT1724_SUBDEVICE_REVOLUTION51:
  439. ice->num_total_dacs = 8;
  440. ice->num_total_adcs = 2;
  441. break;
  442. case VT1724_SUBDEVICE_AUDIOPHILE192:
  443. ice->num_total_dacs = 2;
  444. ice->num_total_adcs = 2;
  445. break;
  446. default:
  447. snd_BUG();
  448. return -EINVAL;
  449. }
  450. /* second stage of initialization, analog parts and others */
  451. ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
  452. if (! ak)
  453. return -ENOMEM;
  454. switch (ice->eeprom.subvendor) {
  455. case VT1724_SUBDEVICE_REVOLUTION71:
  456. ice->akm_codecs = 2;
  457. err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
  458. &akm_revo_front_priv, ice);
  459. if (err < 0)
  460. return err;
  461. err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
  462. &akm_revo_surround_priv, ice);
  463. if (err < 0)
  464. return err;
  465. /* unmute all codecs */
  466. snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
  467. VT1724_REVO_MUTE);
  468. break;
  469. case VT1724_SUBDEVICE_REVOLUTION51:
  470. ice->akm_codecs = 2;
  471. err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,
  472. &akm_revo51_priv, ice);
  473. if (err < 0)
  474. return err;
  475. err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,
  476. &akm_revo51_adc_priv, ice);
  477. if (err < 0)
  478. return err;
  479. err = revo51_i2c_init(ice, &ptc_revo51_volume);
  480. if (err < 0)
  481. return err;
  482. /* unmute all codecs */
  483. snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
  484. VT1724_REVO_MUTE);
  485. break;
  486. case VT1724_SUBDEVICE_AUDIOPHILE192:
  487. ice->akm_codecs = 1;
  488. err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,
  489. ice);
  490. if (err < 0)
  491. return err;
  492. err = ap192_ak4114_init(ice);
  493. if (err < 0)
  494. return err;
  495. /* unmute all codecs */
  496. snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
  497. VT1724_REVO_MUTE);
  498. break;
  499. }
  500. return 0;
  501. }
  502. static int revo_add_controls(struct snd_ice1712 *ice)
  503. {
  504. struct revo51_spec *spec = ice->spec;
  505. int err;
  506. switch (ice->eeprom.subvendor) {
  507. case VT1724_SUBDEVICE_REVOLUTION71:
  508. err = snd_ice1712_akm4xxx_build_controls(ice);
  509. if (err < 0)
  510. return err;
  511. break;
  512. case VT1724_SUBDEVICE_REVOLUTION51:
  513. err = snd_ice1712_akm4xxx_build_controls(ice);
  514. if (err < 0)
  515. return err;
  516. spec = ice->spec;
  517. err = snd_pt2258_build_controls(spec->pt2258);
  518. if (err < 0)
  519. return err;
  520. break;
  521. case VT1724_SUBDEVICE_AUDIOPHILE192:
  522. err = snd_ice1712_akm4xxx_build_controls(ice);
  523. if (err < 0)
  524. return err;
  525. /* only capture SPDIF over AK4114 */
  526. err = snd_ak4114_build(spec->ak4114, NULL,
  527. ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
  528. if (err < 0)
  529. return err;
  530. break;
  531. }
  532. return 0;
  533. }
  534. /* entry point */
  535. struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {
  536. {
  537. .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
  538. .name = "M Audio Revolution-7.1",
  539. .model = "revo71",
  540. .chip_init = revo_init,
  541. .build_controls = revo_add_controls,
  542. },
  543. {
  544. .subvendor = VT1724_SUBDEVICE_REVOLUTION51,
  545. .name = "M Audio Revolution-5.1",
  546. .model = "revo51",
  547. .chip_init = revo_init,
  548. .build_controls = revo_add_controls,
  549. },
  550. {
  551. .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,
  552. .name = "M Audio Audiophile192",
  553. .model = "ap192",
  554. .chip_init = revo_init,
  555. .build_controls = revo_add_controls,
  556. },
  557. { } /* terminator */
  558. };