wtm.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /*
  2. * ALSA driver for ICEnsemble VT1724 (Envy24HT)
  3. *
  4. * Lowlevel functions for Ego Sys Waveterminal 192M
  5. *
  6. * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
  7. * Some functions are taken from the Prodigy192 driver
  8. * source
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. */
  25. #include <linux/delay.h>
  26. #include <linux/interrupt.h>
  27. #include <linux/init.h>
  28. #include <sound/core.h>
  29. #include <sound/tlv.h>
  30. #include <linux/slab.h>
  31. #include "ice1712.h"
  32. #include "envy24ht.h"
  33. #include "wtm.h"
  34. #include "stac946x.h"
  35. struct wtm_spec {
  36. /* rate change needs atomic mute/unmute of all dacs*/
  37. struct mutex mute_mutex;
  38. };
  39. /*
  40. * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
  41. */
  42. static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
  43. unsigned char val)
  44. {
  45. snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
  46. }
  47. static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
  48. {
  49. return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
  50. }
  51. /*
  52. * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
  53. */
  54. static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
  55. unsigned char val)
  56. {
  57. snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val);
  58. }
  59. static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
  60. {
  61. return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
  62. }
  63. /*
  64. * DAC mute control
  65. */
  66. static void stac9460_dac_mute_all(struct snd_ice1712 *ice, unsigned char mute,
  67. unsigned short int *change_mask)
  68. {
  69. unsigned char new, old;
  70. int id, idx, change;
  71. /*stac9460 1*/
  72. for (id = 0; id < 7; id++) {
  73. if (*change_mask & (0x01 << id)) {
  74. if (id == 0)
  75. idx = STAC946X_MASTER_VOLUME;
  76. else
  77. idx = STAC946X_LF_VOLUME - 1 + id;
  78. old = stac9460_get(ice, idx);
  79. new = (~mute << 7 & 0x80) | (old & ~0x80);
  80. change = (new != old);
  81. if (change) {
  82. stac9460_put(ice, idx, new);
  83. *change_mask = *change_mask | (0x01 << id);
  84. } else {
  85. *change_mask = *change_mask & ~(0x01 << id);
  86. }
  87. }
  88. }
  89. /*stac9460 2*/
  90. for (id = 0; id < 3; id++) {
  91. if (*change_mask & (0x01 << (id + 7))) {
  92. if (id == 0)
  93. idx = STAC946X_MASTER_VOLUME;
  94. else
  95. idx = STAC946X_LF_VOLUME - 1 + id;
  96. old = stac9460_2_get(ice, idx);
  97. new = (~mute << 7 & 0x80) | (old & ~0x80);
  98. change = (new != old);
  99. if (change) {
  100. stac9460_2_put(ice, idx, new);
  101. *change_mask = *change_mask | (0x01 << id);
  102. } else {
  103. *change_mask = *change_mask & ~(0x01 << id);
  104. }
  105. }
  106. }
  107. }
  108. #define stac9460_dac_mute_info snd_ctl_boolean_mono_info
  109. static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
  110. struct snd_ctl_elem_value *ucontrol)
  111. {
  112. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  113. struct wtm_spec *spec = ice->spec;
  114. unsigned char val;
  115. int idx, id;
  116. mutex_lock(&spec->mute_mutex);
  117. if (kcontrol->private_value) {
  118. idx = STAC946X_MASTER_VOLUME;
  119. id = 0;
  120. } else {
  121. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  122. idx = id + STAC946X_LF_VOLUME;
  123. }
  124. if (id < 6)
  125. val = stac9460_get(ice, idx);
  126. else
  127. val = stac9460_2_get(ice, idx - 6);
  128. ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
  129. mutex_unlock(&spec->mute_mutex);
  130. return 0;
  131. }
  132. static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
  133. struct snd_ctl_elem_value *ucontrol)
  134. {
  135. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  136. unsigned char new, old;
  137. int id, idx;
  138. int change;
  139. if (kcontrol->private_value) {
  140. idx = STAC946X_MASTER_VOLUME;
  141. old = stac9460_get(ice, idx);
  142. new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
  143. (old & ~0x80);
  144. change = (new != old);
  145. if (change) {
  146. stac9460_put(ice, idx, new);
  147. stac9460_2_put(ice, idx, new);
  148. }
  149. } else {
  150. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  151. idx = id + STAC946X_LF_VOLUME;
  152. if (id < 6)
  153. old = stac9460_get(ice, idx);
  154. else
  155. old = stac9460_2_get(ice, idx - 6);
  156. new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
  157. (old & ~0x80);
  158. change = (new != old);
  159. if (change) {
  160. if (id < 6)
  161. stac9460_put(ice, idx, new);
  162. else
  163. stac9460_2_put(ice, idx - 6, new);
  164. }
  165. }
  166. return change;
  167. }
  168. /*
  169. * DAC volume attenuation mixer control
  170. */
  171. static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
  172. struct snd_ctl_elem_info *uinfo)
  173. {
  174. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  175. uinfo->count = 1;
  176. uinfo->value.integer.min = 0; /* mute */
  177. uinfo->value.integer.max = 0x7f; /* 0dB */
  178. return 0;
  179. }
  180. static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
  181. struct snd_ctl_elem_value *ucontrol)
  182. {
  183. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  184. int idx, id;
  185. unsigned char vol;
  186. if (kcontrol->private_value) {
  187. idx = STAC946X_MASTER_VOLUME;
  188. id = 0;
  189. } else {
  190. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  191. idx = id + STAC946X_LF_VOLUME;
  192. }
  193. if (id < 6)
  194. vol = stac9460_get(ice, idx) & 0x7f;
  195. else
  196. vol = stac9460_2_get(ice, idx - 6) & 0x7f;
  197. ucontrol->value.integer.value[0] = 0x7f - vol;
  198. return 0;
  199. }
  200. static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
  201. struct snd_ctl_elem_value *ucontrol)
  202. {
  203. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  204. int idx, id;
  205. unsigned char tmp, ovol, nvol;
  206. int change;
  207. if (kcontrol->private_value) {
  208. idx = STAC946X_MASTER_VOLUME;
  209. nvol = ucontrol->value.integer.value[0] & 0x7f;
  210. tmp = stac9460_get(ice, idx);
  211. ovol = 0x7f - (tmp & 0x7f);
  212. change = (ovol != nvol);
  213. if (change) {
  214. stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
  215. stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
  216. }
  217. } else {
  218. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  219. idx = id + STAC946X_LF_VOLUME;
  220. nvol = ucontrol->value.integer.value[0] & 0x7f;
  221. if (id < 6)
  222. tmp = stac9460_get(ice, idx);
  223. else
  224. tmp = stac9460_2_get(ice, idx - 6);
  225. ovol = 0x7f - (tmp & 0x7f);
  226. change = (ovol != nvol);
  227. if (change) {
  228. if (id < 6)
  229. stac9460_put(ice, idx, (0x7f - nvol) |
  230. (tmp & 0x80));
  231. else
  232. stac9460_2_put(ice, idx-6, (0x7f - nvol) |
  233. (tmp & 0x80));
  234. }
  235. }
  236. return change;
  237. }
  238. /*
  239. * ADC mute control
  240. */
  241. #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
  242. static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
  243. struct snd_ctl_elem_value *ucontrol)
  244. {
  245. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  246. unsigned char val;
  247. int i, id;
  248. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  249. if (id == 0) {
  250. for (i = 0; i < 2; ++i) {
  251. val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
  252. ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
  253. }
  254. } else {
  255. for (i = 0; i < 2; ++i) {
  256. val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
  257. ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
  258. }
  259. }
  260. return 0;
  261. }
  262. static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
  263. struct snd_ctl_elem_value *ucontrol)
  264. {
  265. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  266. unsigned char new, old;
  267. int i, reg, id;
  268. int change;
  269. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  270. if (id == 0) {
  271. for (i = 0; i < 2; ++i) {
  272. reg = STAC946X_MIC_L_VOLUME + i;
  273. old = stac9460_get(ice, reg);
  274. new = (~ucontrol->value.integer.value[i]<<7&0x80) |
  275. (old&~0x80);
  276. change = (new != old);
  277. if (change)
  278. stac9460_put(ice, reg, new);
  279. }
  280. } else {
  281. for (i = 0; i < 2; ++i) {
  282. reg = STAC946X_MIC_L_VOLUME + i;
  283. old = stac9460_2_get(ice, reg);
  284. new = (~ucontrol->value.integer.value[i]<<7&0x80) |
  285. (old&~0x80);
  286. change = (new != old);
  287. if (change)
  288. stac9460_2_put(ice, reg, new);
  289. }
  290. }
  291. return change;
  292. }
  293. /*
  294. *ADC gain mixer control
  295. */
  296. static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
  297. struct snd_ctl_elem_info *uinfo)
  298. {
  299. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  300. uinfo->count = 2;
  301. uinfo->value.integer.min = 0; /* 0dB */
  302. uinfo->value.integer.max = 0x0f; /* 22.5dB */
  303. return 0;
  304. }
  305. static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
  306. struct snd_ctl_elem_value *ucontrol)
  307. {
  308. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  309. int i, reg, id;
  310. unsigned char vol;
  311. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  312. if (id == 0) {
  313. for (i = 0; i < 2; ++i) {
  314. reg = STAC946X_MIC_L_VOLUME + i;
  315. vol = stac9460_get(ice, reg) & 0x0f;
  316. ucontrol->value.integer.value[i] = 0x0f - vol;
  317. }
  318. } else {
  319. for (i = 0; i < 2; ++i) {
  320. reg = STAC946X_MIC_L_VOLUME + i;
  321. vol = stac9460_2_get(ice, reg) & 0x0f;
  322. ucontrol->value.integer.value[i] = 0x0f - vol;
  323. }
  324. }
  325. return 0;
  326. }
  327. static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
  328. struct snd_ctl_elem_value *ucontrol)
  329. {
  330. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  331. int i, reg, id;
  332. unsigned char ovol, nvol;
  333. int change;
  334. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  335. if (id == 0) {
  336. for (i = 0; i < 2; ++i) {
  337. reg = STAC946X_MIC_L_VOLUME + i;
  338. nvol = ucontrol->value.integer.value[i] & 0x0f;
  339. ovol = 0x0f - stac9460_get(ice, reg);
  340. change = ((ovol & 0x0f) != nvol);
  341. if (change)
  342. stac9460_put(ice, reg, (0x0f - nvol) |
  343. (ovol & ~0x0f));
  344. }
  345. } else {
  346. for (i = 0; i < 2; ++i) {
  347. reg = STAC946X_MIC_L_VOLUME + i;
  348. nvol = ucontrol->value.integer.value[i] & 0x0f;
  349. ovol = 0x0f - stac9460_2_get(ice, reg);
  350. change = ((ovol & 0x0f) != nvol);
  351. if (change)
  352. stac9460_2_put(ice, reg, (0x0f - nvol) |
  353. (ovol & ~0x0f));
  354. }
  355. }
  356. return change;
  357. }
  358. /*
  359. * MIC / LINE switch fonction
  360. */
  361. static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
  362. struct snd_ctl_elem_info *uinfo)
  363. {
  364. static const char * const texts[2] = { "Line In", "Mic" };
  365. return snd_ctl_enum_info(uinfo, 1, 2, texts);
  366. }
  367. static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
  368. struct snd_ctl_elem_value *ucontrol)
  369. {
  370. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  371. unsigned char val;
  372. int id;
  373. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  374. if (id == 0)
  375. val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
  376. else
  377. val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
  378. ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
  379. return 0;
  380. }
  381. static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
  382. struct snd_ctl_elem_value *ucontrol)
  383. {
  384. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  385. unsigned char new, old;
  386. int change, id;
  387. id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  388. if (id == 0)
  389. old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
  390. else
  391. old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
  392. new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
  393. change = (new != old);
  394. if (change) {
  395. if (id == 0)
  396. stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
  397. else
  398. stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
  399. }
  400. return change;
  401. }
  402. /*
  403. * Handler for setting correct codec rate - called when rate change is detected
  404. */
  405. static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
  406. {
  407. unsigned char old, new;
  408. unsigned short int changed;
  409. struct wtm_spec *spec = ice->spec;
  410. if (rate == 0) /* no hint - S/PDIF input is master, simply return */
  411. return;
  412. else if (rate <= 48000)
  413. new = 0x08; /* 256x, base rate mode */
  414. else if (rate <= 96000)
  415. new = 0x11; /* 256x, mid rate mode */
  416. else
  417. new = 0x12; /* 128x, high rate mode */
  418. old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
  419. if (old == new)
  420. return;
  421. /* change detected, setting master clock, muting first */
  422. /* due to possible conflicts with mute controls - mutexing */
  423. mutex_lock(&spec->mute_mutex);
  424. /* we have to remember current mute status for each DAC */
  425. changed = 0xFFFF;
  426. stac9460_dac_mute_all(ice, 0, &changed);
  427. /*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
  428. stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
  429. stac9460_2_put(ice, STAC946X_MASTER_CLOCKING, new);
  430. udelay(10);
  431. /* unmuting - only originally unmuted dacs -
  432. * i.e. those changed when muting */
  433. stac9460_dac_mute_all(ice, 1, &changed);
  434. mutex_unlock(&spec->mute_mutex);
  435. }
  436. /*Limits value in dB for fader*/
  437. static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
  438. static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
  439. /*
  440. * Control tabs
  441. */
  442. static struct snd_kcontrol_new stac9640_controls[] = {
  443. {
  444. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  445. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  446. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  447. .name = "Master Playback Switch",
  448. .info = stac9460_dac_mute_info,
  449. .get = stac9460_dac_mute_get,
  450. .put = stac9460_dac_mute_put,
  451. .private_value = 1,
  452. .tlv = { .p = db_scale_dac }
  453. },
  454. {
  455. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  456. .name = "Master Playback Volume",
  457. .info = stac9460_dac_vol_info,
  458. .get = stac9460_dac_vol_get,
  459. .put = stac9460_dac_vol_put,
  460. .private_value = 1,
  461. },
  462. {
  463. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  464. .name = "MIC/Line Input Enum",
  465. .count = 2,
  466. .info = stac9460_mic_sw_info,
  467. .get = stac9460_mic_sw_get,
  468. .put = stac9460_mic_sw_put,
  469. },
  470. {
  471. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  472. .name = "DAC Switch",
  473. .count = 8,
  474. .info = stac9460_dac_mute_info,
  475. .get = stac9460_dac_mute_get,
  476. .put = stac9460_dac_mute_put,
  477. },
  478. {
  479. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  480. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  481. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  482. .name = "DAC Volume",
  483. .count = 8,
  484. .info = stac9460_dac_vol_info,
  485. .get = stac9460_dac_vol_get,
  486. .put = stac9460_dac_vol_put,
  487. .tlv = { .p = db_scale_dac }
  488. },
  489. {
  490. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  491. .name = "ADC Switch",
  492. .count = 2,
  493. .info = stac9460_adc_mute_info,
  494. .get = stac9460_adc_mute_get,
  495. .put = stac9460_adc_mute_put,
  496. },
  497. {
  498. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  499. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  500. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  501. .name = "ADC Volume",
  502. .count = 2,
  503. .info = stac9460_adc_vol_info,
  504. .get = stac9460_adc_vol_get,
  505. .put = stac9460_adc_vol_put,
  506. .tlv = { .p = db_scale_adc }
  507. }
  508. };
  509. /*INIT*/
  510. static int wtm_add_controls(struct snd_ice1712 *ice)
  511. {
  512. unsigned int i;
  513. int err;
  514. for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
  515. err = snd_ctl_add(ice->card,
  516. snd_ctl_new1(&stac9640_controls[i], ice));
  517. if (err < 0)
  518. return err;
  519. }
  520. return 0;
  521. }
  522. static int wtm_init(struct snd_ice1712 *ice)
  523. {
  524. static unsigned short stac_inits_wtm[] = {
  525. STAC946X_RESET, 0,
  526. STAC946X_MASTER_CLOCKING, 0x11,
  527. (unsigned short)-1
  528. };
  529. unsigned short *p;
  530. struct wtm_spec *spec;
  531. /*WTM 192M*/
  532. ice->num_total_dacs = 8;
  533. ice->num_total_adcs = 4;
  534. ice->force_rdma1 = 1;
  535. /*init mutex for dac mute conflict*/
  536. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  537. if (!spec)
  538. return -ENOMEM;
  539. ice->spec = spec;
  540. mutex_init(&spec->mute_mutex);
  541. /*initialize codec*/
  542. p = stac_inits_wtm;
  543. for (; *p != (unsigned short)-1; p += 2) {
  544. stac9460_put(ice, p[0], p[1]);
  545. stac9460_2_put(ice, p[0], p[1]);
  546. }
  547. ice->gpio.set_pro_rate = stac9460_set_rate_val;
  548. return 0;
  549. }
  550. static unsigned char wtm_eeprom[] = {
  551. [ICE_EEP2_SYSCONF] = 0x67, /*SYSCONF: clock 192KHz, mpu401,
  552. 4ADC, 8DAC */
  553. [ICE_EEP2_ACLINK] = 0x80, /* ACLINK : I2S */
  554. [ICE_EEP2_I2S] = 0xf8, /* I2S: vol; 96k, 24bit, 192k */
  555. [ICE_EEP2_SPDIF] = 0xc1, /*SPDIF: out-en, spidf ext out*/
  556. [ICE_EEP2_GPIO_DIR] = 0x9f,
  557. [ICE_EEP2_GPIO_DIR1] = 0xff,
  558. [ICE_EEP2_GPIO_DIR2] = 0x7f,
  559. [ICE_EEP2_GPIO_MASK] = 0x9f,
  560. [ICE_EEP2_GPIO_MASK1] = 0xff,
  561. [ICE_EEP2_GPIO_MASK2] = 0x7f,
  562. [ICE_EEP2_GPIO_STATE] = 0x16,
  563. [ICE_EEP2_GPIO_STATE1] = 0x80,
  564. [ICE_EEP2_GPIO_STATE2] = 0x00,
  565. };
  566. /*entry point*/
  567. struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = {
  568. {
  569. .subvendor = VT1724_SUBDEVICE_WTM,
  570. .name = "ESI Waveterminal 192M",
  571. .model = "WT192M",
  572. .chip_init = wtm_init,
  573. .build_controls = wtm_add_controls,
  574. .eeprom_size = sizeof(wtm_eeprom),
  575. .eeprom_data = wtm_eeprom,
  576. },
  577. {} /*terminator*/
  578. };