se.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /*
  2. * ALSA driver for ICEnsemble VT1724 (Envy24HT)
  3. *
  4. * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI
  5. *
  6. * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp
  7. * (at) -> @
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. *
  23. */
  24. #include <sound/driver.h>
  25. #include <asm/io.h>
  26. #include <linux/delay.h>
  27. #include <linux/interrupt.h>
  28. #include <linux/init.h>
  29. #include <linux/slab.h>
  30. #include <sound/core.h>
  31. #include <sound/tlv.h>
  32. #include "ice1712.h"
  33. #include "envy24ht.h"
  34. #include "se.h"
  35. /****************************************************************************/
  36. /* ONKYO WAVIO SE-200PCI */
  37. /****************************************************************************/
  38. /*
  39. * system configuration ICE_EEP2_SYSCONF=0x4b
  40. * XIN1 49.152MHz
  41. * not have UART
  42. * one stereo ADC and a S/PDIF receiver connected
  43. * four stereo DACs connected
  44. *
  45. * AC-Link configuration ICE_EEP2_ACLINK=0x80
  46. * use I2C, not use AC97
  47. *
  48. * I2S converters feature ICE_EEP2_I2S=0x78
  49. * I2S codec has no volume/mute control feature
  50. * I2S codec supports 96KHz and 192KHz
  51. * I2S codec 24bits
  52. *
  53. * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
  54. * Enable integrated S/PDIF transmitter
  55. * internal S/PDIF out implemented
  56. * S/PDIF is stereo
  57. * External S/PDIF out implemented
  58. *
  59. *
  60. * ** connected chips **
  61. *
  62. * WM8740
  63. * A 2ch-DAC of main outputs.
  64. * It setuped as I2S mode by wire, so no way to setup from software.
  65. * The sample-rate are automatically changed.
  66. * ML/I2S (28pin) --------+
  67. * MC/DM1 (27pin) -- 5V |
  68. * MD/DM0 (26pin) -- GND |
  69. * MUTEB (25pin) -- NC |
  70. * MODE (24pin) -- GND |
  71. * CSBIW (23pin) --------+
  72. * |
  73. * RSTB (22pin) --R(1K)-+
  74. * Probably it reduce the noise from the control line.
  75. *
  76. * WM8766
  77. * A 6ch-DAC for surrounds.
  78. * It's control wire was connected to GPIOxx (3-wire serial interface)
  79. * ML/I2S (11pin) -- GPIO18
  80. * MC/IWL (12pin) -- GPIO17
  81. * MD/DM (13pin) -- GPIO16
  82. * MUTE (14pin) -- GPIO01
  83. *
  84. * WM8776
  85. * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC.
  86. * It's control wire was connected to SDA/SCLK (2-wire serial interface)
  87. * MODE (16pin) -- R(1K) -- GND
  88. * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34)
  89. * DI (18pin) -- SDA
  90. * CL (19pin) -- SCLK
  91. *
  92. *
  93. * ** output pins and device names **
  94. *
  95. * 7.1ch name -- output connector color -- device (-D option)
  96. *
  97. * FRONT 2ch -- green -- plughw:0,0
  98. * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0
  99. * SURROUND 2ch -- orange -- plughw:0,2,1
  100. * SURROUND BACK 2ch -- white -- plughw:0,2,2
  101. *
  102. */
  103. /****************************************************************************/
  104. /* WM8740 interface */
  105. /****************************************************************************/
  106. static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice)
  107. {
  108. /* nothing to do */
  109. }
  110. static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice,
  111. unsigned int rate)
  112. {
  113. /* nothing to do */
  114. }
  115. /****************************************************************************/
  116. /* WM8766 interface */
  117. /****************************************************************************/
  118. static void se200pci_WM8766_write(struct snd_ice1712 *ice,
  119. unsigned int addr, unsigned int data)
  120. {
  121. unsigned int st;
  122. unsigned int bits;
  123. int i;
  124. const unsigned int DATA = 0x010000;
  125. const unsigned int CLOCK = 0x020000;
  126. const unsigned int LOAD = 0x040000;
  127. const unsigned int ALL_MASK = (DATA | CLOCK | LOAD);
  128. snd_ice1712_save_gpio_status(ice);
  129. st = ((addr & 0x7f) << 9) | (data & 0x1ff);
  130. snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK);
  131. snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK);
  132. bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK;
  133. snd_ice1712_gpio_write(ice, bits);
  134. for (i = 0; i < 16; i++) {
  135. udelay(1);
  136. bits &= ~CLOCK;
  137. st = (st << 1);
  138. if (st & 0x10000)
  139. bits |= DATA;
  140. else
  141. bits &= ~DATA;
  142. snd_ice1712_gpio_write(ice, bits);
  143. udelay(1);
  144. bits |= CLOCK;
  145. snd_ice1712_gpio_write(ice, bits);
  146. }
  147. udelay(1);
  148. bits |= LOAD;
  149. snd_ice1712_gpio_write(ice, bits);
  150. udelay(1);
  151. bits |= (DATA | CLOCK);
  152. snd_ice1712_gpio_write(ice, bits);
  153. snd_ice1712_restore_gpio_status(ice);
  154. }
  155. static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,
  156. unsigned int vol1, unsigned int vol2)
  157. {
  158. switch (ch) {
  159. case 0:
  160. se200pci_WM8766_write(ice, 0x000, vol1);
  161. se200pci_WM8766_write(ice, 0x001, vol2 | 0x100);
  162. break;
  163. case 1:
  164. se200pci_WM8766_write(ice, 0x004, vol1);
  165. se200pci_WM8766_write(ice, 0x005, vol2 | 0x100);
  166. break;
  167. case 2:
  168. se200pci_WM8766_write(ice, 0x006, vol1);
  169. se200pci_WM8766_write(ice, 0x007, vol2 | 0x100);
  170. break;
  171. }
  172. }
  173. static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice)
  174. {
  175. se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
  176. udelay(10);
  177. se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */
  178. se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */
  179. se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */
  180. se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */
  181. se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
  182. se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */
  183. se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */
  184. se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */
  185. se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */
  186. se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */
  187. }
  188. static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice,
  189. unsigned int rate)
  190. {
  191. if (rate > 96000)
  192. se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */
  193. else
  194. se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
  195. }
  196. /****************************************************************************/
  197. /* WM8776 interface */
  198. /****************************************************************************/
  199. static void se200pci_WM8776_write(struct snd_ice1712 *ice,
  200. unsigned int addr, unsigned int data)
  201. {
  202. unsigned int val;
  203. val = (addr << 9) | data;
  204. snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff);
  205. }
  206. static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice,
  207. unsigned int vol1, unsigned int vol2)
  208. {
  209. se200pci_WM8776_write(ice, 0x03, vol1);
  210. se200pci_WM8776_write(ice, 0x04, vol2 | 0x100);
  211. }
  212. static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,
  213. unsigned int vol1, unsigned int vol2)
  214. {
  215. se200pci_WM8776_write(ice, 0x0e, vol1);
  216. se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
  217. }
  218. static const char *se200pci_sel[] = {
  219. "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
  220. };
  221. static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice,
  222. unsigned int sel)
  223. {
  224. static unsigned char vals[] = {
  225. /* LINE, CD, MIC, ALL, GND */
  226. 0x10, 0x04, 0x08, 0x1c, 0x03
  227. };
  228. if (sel > 4)
  229. sel = 4;
  230. se200pci_WM8776_write(ice, 0x15, vals[sel]);
  231. }
  232. static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)
  233. {
  234. /* AFL -- After Fader Listening */
  235. if (afl)
  236. se200pci_WM8776_write(ice, 0x16, 0x005);
  237. else
  238. se200pci_WM8776_write(ice, 0x16, 0x001);
  239. }
  240. static const char *se200pci_agc[] = {
  241. "Off", "LimiterMode", "ALCMode", NULL
  242. };
  243. static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)
  244. {
  245. /* AGC -- Auto Gain Control of the input */
  246. switch (agc) {
  247. case 0:
  248. se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */
  249. break;
  250. case 1:
  251. se200pci_WM8776_write(ice, 0x10, 0x07b);
  252. se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */
  253. break;
  254. case 2:
  255. se200pci_WM8776_write(ice, 0x10, 0x1fb);
  256. se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */
  257. break;
  258. }
  259. }
  260. static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice)
  261. {
  262. int i;
  263. static unsigned short __devinitdata default_values[] = {
  264. 0x100, 0x100, 0x100,
  265. 0x100, 0x100, 0x100,
  266. 0x000, 0x090, 0x000, 0x000,
  267. 0x022, 0x022, 0x022,
  268. 0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
  269. 0x032, 0x000, 0x0a6, 0x001, 0x001
  270. };
  271. se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */
  272. /* ADC and DAC interface is I2S 24bits mode */
  273. /* The sample-rate are automatically changed */
  274. udelay(10);
  275. /* BUT my board can not do reset all, so I load all by manually. */
  276. for (i = 0; i < ARRAY_SIZE(default_values); i++)
  277. se200pci_WM8776_write(ice, i, default_values[i]);
  278. se200pci_WM8776_set_input_selector(ice, 0);
  279. se200pci_WM8776_set_afl(ice, 0);
  280. se200pci_WM8776_set_agc(ice, 0);
  281. se200pci_WM8776_set_input_volume(ice, 0, 0);
  282. se200pci_WM8776_set_output_volume(ice, 0, 0);
  283. /* head phone mute and power down */
  284. se200pci_WM8776_write(ice, 0x00, 0);
  285. se200pci_WM8776_write(ice, 0x01, 0);
  286. se200pci_WM8776_write(ice, 0x02, 0x100);
  287. se200pci_WM8776_write(ice, 0x0d, 0x080);
  288. }
  289. static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice,
  290. unsigned int rate)
  291. {
  292. /* nothing to do */
  293. }
  294. /****************************************************************************/
  295. /* runtime interface */
  296. /****************************************************************************/
  297. static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
  298. {
  299. se200pci_WM8740_set_pro_rate(ice, rate);
  300. se200pci_WM8766_set_pro_rate(ice, rate);
  301. se200pci_WM8776_set_pro_rate(ice, rate);
  302. }
  303. struct se200pci_control {
  304. char *name;
  305. enum {
  306. WM8766,
  307. WM8776in,
  308. WM8776out,
  309. WM8776sel,
  310. WM8776agc,
  311. WM8776afl
  312. } target;
  313. enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
  314. int ch;
  315. const char **member;
  316. const char *comment;
  317. };
  318. static const struct se200pci_control se200pci_cont[] = {
  319. {
  320. .name = "Front Playback Volume",
  321. .target = WM8776out,
  322. .type = VOLUME1,
  323. .comment = "Front(green)"
  324. },
  325. {
  326. .name = "Side Playback Volume",
  327. .target = WM8766,
  328. .type = VOLUME1,
  329. .ch = 1,
  330. .comment = "Surround(orange)"
  331. },
  332. {
  333. .name = "Surround Playback Volume",
  334. .target = WM8766,
  335. .type = VOLUME1,
  336. .ch = 2,
  337. .comment = "SurroundBack(white)"
  338. },
  339. {
  340. .name = "CLFE Playback Volume",
  341. .target = WM8766,
  342. .type = VOLUME1,
  343. .ch = 0,
  344. .comment = "Center(Lch)&SubWoofer(Rch)(black)"
  345. },
  346. {
  347. .name = "Capture Volume",
  348. .target = WM8776in,
  349. .type = VOLUME2
  350. },
  351. {
  352. .name = "Capture Select",
  353. .target = WM8776sel,
  354. .type = ENUM,
  355. .member = se200pci_sel
  356. },
  357. {
  358. .name = "AGC Capture Mode",
  359. .target = WM8776agc,
  360. .type = ENUM,
  361. .member = se200pci_agc
  362. },
  363. {
  364. .name = "AFL Bypass Playback Switch",
  365. .target = WM8776afl,
  366. .type = BOOLEAN
  367. }
  368. };
  369. static int se200pci_get_enum_count(int n)
  370. {
  371. const char **member;
  372. int c;
  373. member = se200pci_cont[n].member;
  374. if (!member)
  375. return 0;
  376. for (c = 0; member[c]; c++)
  377. ;
  378. return c;
  379. }
  380. static int se200pci_cont_volume_info(struct snd_kcontrol *kc,
  381. struct snd_ctl_elem_info *uinfo)
  382. {
  383. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  384. uinfo->count = 2;
  385. uinfo->value.integer.min = 0; /* mute */
  386. uinfo->value.integer.max = 0xff; /* 0dB */
  387. return 0;
  388. }
  389. #define se200pci_cont_boolean_info snd_ctl_boolean_mono_info
  390. static int se200pci_cont_enum_info(struct snd_kcontrol *kc,
  391. struct snd_ctl_elem_info *uinfo)
  392. {
  393. int n, c;
  394. n = kc->private_value;
  395. c = se200pci_get_enum_count(n);
  396. if (!c)
  397. return -EINVAL;
  398. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  399. uinfo->count = 1;
  400. uinfo->value.enumerated.items = c;
  401. if (uinfo->value.enumerated.item >= c)
  402. uinfo->value.enumerated.item = c - 1;
  403. strcpy(uinfo->value.enumerated.name,
  404. se200pci_cont[n].member[uinfo->value.enumerated.item]);
  405. return 0;
  406. }
  407. static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
  408. struct snd_ctl_elem_value *uc)
  409. {
  410. struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
  411. int n = kc->private_value;
  412. uc->value.integer.value[0] = ice->spec.se.vol[n].ch1;
  413. uc->value.integer.value[1] = ice->spec.se.vol[n].ch2;
  414. return 0;
  415. }
  416. static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
  417. struct snd_ctl_elem_value *uc)
  418. {
  419. struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
  420. int n = kc->private_value;
  421. uc->value.integer.value[0] = ice->spec.se.vol[n].ch1;
  422. return 0;
  423. }
  424. static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
  425. struct snd_ctl_elem_value *uc)
  426. {
  427. struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
  428. int n = kc->private_value;
  429. uc->value.enumerated.item[0] = ice->spec.se.vol[n].ch1;
  430. return 0;
  431. }
  432. static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
  433. {
  434. switch (se200pci_cont[n].target) {
  435. case WM8766:
  436. se200pci_WM8766_set_volume(ice,
  437. se200pci_cont[n].ch,
  438. ice->spec.se.vol[n].ch1,
  439. ice->spec.se.vol[n].ch2);
  440. break;
  441. case WM8776in:
  442. se200pci_WM8776_set_input_volume(ice,
  443. ice->spec.se.vol[n].ch1,
  444. ice->spec.se.vol[n].ch2);
  445. break;
  446. case WM8776out:
  447. se200pci_WM8776_set_output_volume(ice,
  448. ice->spec.se.vol[n].ch1,
  449. ice->spec.se.vol[n].ch2);
  450. break;
  451. case WM8776sel:
  452. se200pci_WM8776_set_input_selector(ice,
  453. ice->spec.se.vol[n].ch1);
  454. break;
  455. case WM8776agc:
  456. se200pci_WM8776_set_agc(ice, ice->spec.se.vol[n].ch1);
  457. break;
  458. case WM8776afl:
  459. se200pci_WM8776_set_afl(ice, ice->spec.se.vol[n].ch1);
  460. break;
  461. default:
  462. break;
  463. }
  464. }
  465. static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
  466. struct snd_ctl_elem_value *uc)
  467. {
  468. struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
  469. int n = kc->private_value;
  470. unsigned int vol1, vol2;
  471. int changed;
  472. changed = 0;
  473. vol1 = uc->value.integer.value[0] & 0xff;
  474. vol2 = uc->value.integer.value[1] & 0xff;
  475. if (ice->spec.se.vol[n].ch1 != vol1) {
  476. ice->spec.se.vol[n].ch1 = vol1;
  477. changed = 1;
  478. }
  479. if (ice->spec.se.vol[n].ch2 != vol2) {
  480. ice->spec.se.vol[n].ch2 = vol2;
  481. changed = 1;
  482. }
  483. if (changed)
  484. se200pci_cont_update(ice, n);
  485. return changed;
  486. }
  487. static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
  488. struct snd_ctl_elem_value *uc)
  489. {
  490. struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
  491. int n = kc->private_value;
  492. unsigned int vol1;
  493. vol1 = !!uc->value.integer.value[0];
  494. if (ice->spec.se.vol[n].ch1 != vol1) {
  495. ice->spec.se.vol[n].ch1 = vol1;
  496. se200pci_cont_update(ice, n);
  497. return 1;
  498. }
  499. return 0;
  500. }
  501. static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
  502. struct snd_ctl_elem_value *uc)
  503. {
  504. struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
  505. int n = kc->private_value;
  506. unsigned int vol1;
  507. vol1 = uc->value.enumerated.item[0];
  508. if (vol1 >= se200pci_get_enum_count(n))
  509. return -EINVAL;
  510. if (ice->spec.se.vol[n].ch1 != vol1) {
  511. ice->spec.se.vol[n].ch1 = vol1;
  512. se200pci_cont_update(ice, n);
  513. return 1;
  514. }
  515. return 0;
  516. }
  517. static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
  518. static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
  519. static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)
  520. {
  521. int i;
  522. struct snd_kcontrol_new cont;
  523. int err;
  524. memset(&cont, 0, sizeof(cont));
  525. cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
  526. for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) {
  527. cont.private_value = i;
  528. cont.name = se200pci_cont[i].name;
  529. cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
  530. cont.tlv.p = NULL;
  531. switch (se200pci_cont[i].type) {
  532. case VOLUME1:
  533. case VOLUME2:
  534. cont.info = se200pci_cont_volume_info;
  535. cont.get = se200pci_cont_volume_get;
  536. cont.put = se200pci_cont_volume_put;
  537. cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
  538. if (se200pci_cont[i].type == VOLUME1)
  539. cont.tlv.p = db_scale_gain1;
  540. else
  541. cont.tlv.p = db_scale_gain2;
  542. break;
  543. case BOOLEAN:
  544. cont.info = se200pci_cont_boolean_info;
  545. cont.get = se200pci_cont_boolean_get;
  546. cont.put = se200pci_cont_boolean_put;
  547. break;
  548. case ENUM:
  549. cont.info = se200pci_cont_enum_info;
  550. cont.get = se200pci_cont_enum_get;
  551. cont.put = se200pci_cont_enum_put;
  552. break;
  553. default:
  554. snd_BUG();
  555. return -EINVAL;
  556. }
  557. err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice));
  558. if (err < 0)
  559. return err;
  560. }
  561. return 0;
  562. }
  563. /****************************************************************************/
  564. /* ONKYO WAVIO SE-90PCI */
  565. /****************************************************************************/
  566. /*
  567. * system configuration ICE_EEP2_SYSCONF=0x4b
  568. * AC-Link configuration ICE_EEP2_ACLINK=0x80
  569. * I2S converters feature ICE_EEP2_I2S=0x78
  570. * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
  571. *
  572. * ** connected chip **
  573. *
  574. * WM8716
  575. * A 2ch-DAC of main outputs.
  576. * It setuped as I2S mode by wire, so no way to setup from software.
  577. * ML/I2S (28pin) -- +5V
  578. * MC/DM1 (27pin) -- GND
  579. * MC/DM0 (26pin) -- GND
  580. * MUTEB (25pin) -- open (internal pull-up)
  581. * MODE (24pin) -- GND
  582. * CSBIWO (23pin) -- +5V
  583. *
  584. */
  585. /* Nothing to do for this chip. */
  586. /****************************************************************************/
  587. /* probe/initialize/setup */
  588. /****************************************************************************/
  589. static int __devinit se_init(struct snd_ice1712 *ice)
  590. {
  591. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
  592. ice->num_total_dacs = 2;
  593. ice->num_total_adcs = 0;
  594. ice->vt1720 = 1;
  595. return 0;
  596. } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) {
  597. ice->num_total_dacs = 8;
  598. ice->num_total_adcs = 2;
  599. se200pci_WM8740_init(ice);
  600. se200pci_WM8766_init(ice);
  601. se200pci_WM8776_init(ice);
  602. ice->gpio.set_pro_rate = se200pci_set_pro_rate;
  603. return 0;
  604. }
  605. return -ENOENT;
  606. }
  607. static int __devinit se_add_controls(struct snd_ice1712 *ice)
  608. {
  609. int err;
  610. err = 0;
  611. /* nothing to do for VT1724_SUBDEVICE_SE90PCI */
  612. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI)
  613. err = se200pci_add_controls(ice);
  614. return err;
  615. }
  616. /****************************************************************************/
  617. /* entry point */
  618. /****************************************************************************/
  619. static unsigned char se200pci_eeprom[] __devinitdata = {
  620. [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
  621. [ICE_EEP2_ACLINK] = 0x80, /* I2S */
  622. [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
  623. [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
  624. [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */
  625. [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */
  626. [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */
  627. [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */
  628. [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */
  629. [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */
  630. [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */
  631. [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */
  632. [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */
  633. };
  634. static unsigned char se90pci_eeprom[] __devinitdata = {
  635. [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
  636. [ICE_EEP2_ACLINK] = 0x80, /* I2S */
  637. [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
  638. [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
  639. /* ALL GPIO bits are in input mode */
  640. };
  641. struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = {
  642. {
  643. .subvendor = VT1724_SUBDEVICE_SE200PCI,
  644. .name = "ONKYO SE200PCI",
  645. .model = "se200pci",
  646. .chip_init = se_init,
  647. .build_controls = se_add_controls,
  648. .eeprom_size = sizeof(se200pci_eeprom),
  649. .eeprom_data = se200pci_eeprom,
  650. },
  651. {
  652. .subvendor = VT1724_SUBDEVICE_SE90PCI,
  653. .name = "ONKYO SE90PCI",
  654. .model = "se90pci",
  655. .chip_init = se_init,
  656. .build_controls = se_add_controls,
  657. .eeprom_size = sizeof(se90pci_eeprom),
  658. .eeprom_data = se90pci_eeprom,
  659. },
  660. {} /*terminator*/
  661. };