maya44.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. /*
  2. * ALSA driver for ICEnsemble VT1724 (Envy24HT)
  3. *
  4. * Lowlevel functions for ESI Maya44 cards
  5. *
  6. * Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
  7. * Based on the patches by Rainer Zimmermann <mail@lightshed.de>
  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 <linux/init.h>
  25. #include <linux/slab.h>
  26. #include <linux/io.h>
  27. #include <sound/core.h>
  28. #include <sound/control.h>
  29. #include <sound/pcm.h>
  30. #include <sound/tlv.h>
  31. #include "ice1712.h"
  32. #include "envy24ht.h"
  33. #include "maya44.h"
  34. /* WM8776 register indexes */
  35. #define WM8776_REG_HEADPHONE_L 0x00
  36. #define WM8776_REG_HEADPHONE_R 0x01
  37. #define WM8776_REG_HEADPHONE_MASTER 0x02
  38. #define WM8776_REG_DAC_ATTEN_L 0x03
  39. #define WM8776_REG_DAC_ATTEN_R 0x04
  40. #define WM8776_REG_DAC_ATTEN_MASTER 0x05
  41. #define WM8776_REG_DAC_PHASE 0x06
  42. #define WM8776_REG_DAC_CONTROL 0x07
  43. #define WM8776_REG_DAC_MUTE 0x08
  44. #define WM8776_REG_DAC_DEEMPH 0x09
  45. #define WM8776_REG_DAC_IF_CONTROL 0x0a
  46. #define WM8776_REG_ADC_IF_CONTROL 0x0b
  47. #define WM8776_REG_MASTER_MODE_CONTROL 0x0c
  48. #define WM8776_REG_POWERDOWN 0x0d
  49. #define WM8776_REG_ADC_ATTEN_L 0x0e
  50. #define WM8776_REG_ADC_ATTEN_R 0x0f
  51. #define WM8776_REG_ADC_ALC1 0x10
  52. #define WM8776_REG_ADC_ALC2 0x11
  53. #define WM8776_REG_ADC_ALC3 0x12
  54. #define WM8776_REG_ADC_NOISE_GATE 0x13
  55. #define WM8776_REG_ADC_LIMITER 0x14
  56. #define WM8776_REG_ADC_MUX 0x15
  57. #define WM8776_REG_OUTPUT_MUX 0x16
  58. #define WM8776_REG_RESET 0x17
  59. #define WM8776_NUM_REGS 0x18
  60. /* clock ratio identifiers for snd_wm8776_set_rate() */
  61. #define WM8776_CLOCK_RATIO_128FS 0
  62. #define WM8776_CLOCK_RATIO_192FS 1
  63. #define WM8776_CLOCK_RATIO_256FS 2
  64. #define WM8776_CLOCK_RATIO_384FS 3
  65. #define WM8776_CLOCK_RATIO_512FS 4
  66. #define WM8776_CLOCK_RATIO_768FS 5
  67. enum { WM_VOL_HP, WM_VOL_DAC, WM_VOL_ADC, WM_NUM_VOLS };
  68. enum { WM_SW_DAC, WM_SW_BYPASS, WM_NUM_SWITCHES };
  69. struct snd_wm8776 {
  70. unsigned char addr;
  71. unsigned short regs[WM8776_NUM_REGS];
  72. unsigned char volumes[WM_NUM_VOLS][2];
  73. unsigned int switch_bits;
  74. };
  75. struct snd_maya44 {
  76. struct snd_ice1712 *ice;
  77. struct snd_wm8776 wm[2];
  78. struct mutex mutex;
  79. };
  80. /* write the given register and save the data to the cache */
  81. static void wm8776_write(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
  82. unsigned char reg, unsigned short val)
  83. {
  84. /*
  85. * WM8776 registers are up to 9 bits wide, bit 8 is placed in the LSB
  86. * of the address field
  87. */
  88. snd_vt1724_write_i2c(ice, wm->addr,
  89. (reg << 1) | ((val >> 8) & 1),
  90. val & 0xff);
  91. wm->regs[reg] = val;
  92. }
  93. /*
  94. * update the given register with and/or mask and save the data to the cache
  95. */
  96. static int wm8776_write_bits(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
  97. unsigned char reg,
  98. unsigned short mask, unsigned short val)
  99. {
  100. val |= wm->regs[reg] & ~mask;
  101. if (val != wm->regs[reg]) {
  102. wm8776_write(ice, wm, reg, val);
  103. return 1;
  104. }
  105. return 0;
  106. }
  107. /*
  108. * WM8776 volume controls
  109. */
  110. struct maya_vol_info {
  111. unsigned int maxval; /* volume range: 0..maxval */
  112. unsigned char regs[2]; /* left and right registers */
  113. unsigned short mask; /* value mask */
  114. unsigned short offset; /* zero-value offset */
  115. unsigned short mute; /* mute bit */
  116. unsigned short update; /* update bits */
  117. unsigned char mux_bits[2]; /* extra bits for ADC mute */
  118. };
  119. static struct maya_vol_info vol_info[WM_NUM_VOLS] = {
  120. [WM_VOL_HP] = {
  121. .maxval = 80,
  122. .regs = { WM8776_REG_HEADPHONE_L, WM8776_REG_HEADPHONE_R },
  123. .mask = 0x7f,
  124. .offset = 0x30,
  125. .mute = 0x00,
  126. .update = 0x180, /* update and zero-cross enable */
  127. },
  128. [WM_VOL_DAC] = {
  129. .maxval = 255,
  130. .regs = { WM8776_REG_DAC_ATTEN_L, WM8776_REG_DAC_ATTEN_R },
  131. .mask = 0xff,
  132. .offset = 0x01,
  133. .mute = 0x00,
  134. .update = 0x100, /* zero-cross enable */
  135. },
  136. [WM_VOL_ADC] = {
  137. .maxval = 91,
  138. .regs = { WM8776_REG_ADC_ATTEN_L, WM8776_REG_ADC_ATTEN_R },
  139. .mask = 0xff,
  140. .offset = 0xa5,
  141. .mute = 0xa5,
  142. .update = 0x100, /* update */
  143. .mux_bits = { 0x80, 0x40 }, /* ADCMUX bits */
  144. },
  145. };
  146. /*
  147. * dB tables
  148. */
  149. /* headphone output: mute, -73..+6db (1db step) */
  150. static const DECLARE_TLV_DB_SCALE(db_scale_hp, -7400, 100, 1);
  151. /* DAC output: mute, -127..0db (0.5db step) */
  152. static const DECLARE_TLV_DB_SCALE(db_scale_dac, -12750, 50, 1);
  153. /* ADC gain: mute, -21..+24db (0.5db step) */
  154. static const DECLARE_TLV_DB_SCALE(db_scale_adc, -2100, 50, 1);
  155. static int maya_vol_info(struct snd_kcontrol *kcontrol,
  156. struct snd_ctl_elem_info *uinfo)
  157. {
  158. unsigned int idx = kcontrol->private_value;
  159. struct maya_vol_info *vol = &vol_info[idx];
  160. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  161. uinfo->count = 2;
  162. uinfo->value.integer.min = 0;
  163. uinfo->value.integer.max = vol->maxval;
  164. return 0;
  165. }
  166. static int maya_vol_get(struct snd_kcontrol *kcontrol,
  167. struct snd_ctl_elem_value *ucontrol)
  168. {
  169. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  170. struct snd_wm8776 *wm =
  171. &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
  172. unsigned int idx = kcontrol->private_value;
  173. mutex_lock(&chip->mutex);
  174. ucontrol->value.integer.value[0] = wm->volumes[idx][0];
  175. ucontrol->value.integer.value[1] = wm->volumes[idx][1];
  176. mutex_unlock(&chip->mutex);
  177. return 0;
  178. }
  179. static int maya_vol_put(struct snd_kcontrol *kcontrol,
  180. struct snd_ctl_elem_value *ucontrol)
  181. {
  182. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  183. struct snd_wm8776 *wm =
  184. &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
  185. unsigned int idx = kcontrol->private_value;
  186. struct maya_vol_info *vol = &vol_info[idx];
  187. unsigned int val, data;
  188. int ch, changed = 0;
  189. mutex_lock(&chip->mutex);
  190. for (ch = 0; ch < 2; ch++) {
  191. val = ucontrol->value.integer.value[ch];
  192. if (val > vol->maxval)
  193. val = vol->maxval;
  194. if (val == wm->volumes[idx][ch])
  195. continue;
  196. if (!val)
  197. data = vol->mute;
  198. else
  199. data = (val - 1) + vol->offset;
  200. data |= vol->update;
  201. changed |= wm8776_write_bits(chip->ice, wm, vol->regs[ch],
  202. vol->mask | vol->update, data);
  203. if (vol->mux_bits[ch])
  204. wm8776_write_bits(chip->ice, wm, WM8776_REG_ADC_MUX,
  205. vol->mux_bits[ch],
  206. val ? 0 : vol->mux_bits[ch]);
  207. wm->volumes[idx][ch] = val;
  208. }
  209. mutex_unlock(&chip->mutex);
  210. return changed;
  211. }
  212. /*
  213. * WM8776 switch controls
  214. */
  215. #define COMPOSE_SW_VAL(idx, reg, mask) ((idx) | ((reg) << 8) | ((mask) << 16))
  216. #define GET_SW_VAL_IDX(val) ((val) & 0xff)
  217. #define GET_SW_VAL_REG(val) (((val) >> 8) & 0xff)
  218. #define GET_SW_VAL_MASK(val) (((val) >> 16) & 0xff)
  219. #define maya_sw_info snd_ctl_boolean_mono_info
  220. static int maya_sw_get(struct snd_kcontrol *kcontrol,
  221. struct snd_ctl_elem_value *ucontrol)
  222. {
  223. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  224. struct snd_wm8776 *wm =
  225. &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
  226. unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
  227. ucontrol->value.integer.value[0] = (wm->switch_bits >> idx) & 1;
  228. return 0;
  229. }
  230. static int maya_sw_put(struct snd_kcontrol *kcontrol,
  231. struct snd_ctl_elem_value *ucontrol)
  232. {
  233. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  234. struct snd_wm8776 *wm =
  235. &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
  236. unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
  237. unsigned int mask, val;
  238. int changed;
  239. mutex_lock(&chip->mutex);
  240. mask = 1 << idx;
  241. wm->switch_bits &= ~mask;
  242. val = ucontrol->value.integer.value[0];
  243. if (val)
  244. wm->switch_bits |= mask;
  245. mask = GET_SW_VAL_MASK(kcontrol->private_value);
  246. changed = wm8776_write_bits(chip->ice, wm,
  247. GET_SW_VAL_REG(kcontrol->private_value),
  248. mask, val ? mask : 0);
  249. mutex_unlock(&chip->mutex);
  250. return changed;
  251. }
  252. /*
  253. * GPIO pins (known ones for maya44)
  254. */
  255. #define GPIO_PHANTOM_OFF 2
  256. #define GPIO_MIC_RELAY 4
  257. #define GPIO_SPDIF_IN_INV 5
  258. #define GPIO_MUST_BE_0 7
  259. /*
  260. * GPIO switch controls
  261. */
  262. #define COMPOSE_GPIO_VAL(shift, inv) ((shift) | ((inv) << 8))
  263. #define GET_GPIO_VAL_SHIFT(val) ((val) & 0xff)
  264. #define GET_GPIO_VAL_INV(val) (((val) >> 8) & 1)
  265. static int maya_set_gpio_bits(struct snd_ice1712 *ice, unsigned int mask,
  266. unsigned int bits)
  267. {
  268. unsigned int data;
  269. data = snd_ice1712_gpio_read(ice);
  270. if ((data & mask) == bits)
  271. return 0;
  272. snd_ice1712_gpio_write(ice, (data & ~mask) | bits);
  273. return 1;
  274. }
  275. #define maya_gpio_sw_info snd_ctl_boolean_mono_info
  276. static int maya_gpio_sw_get(struct snd_kcontrol *kcontrol,
  277. struct snd_ctl_elem_value *ucontrol)
  278. {
  279. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  280. unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
  281. unsigned int val;
  282. val = (snd_ice1712_gpio_read(chip->ice) >> shift) & 1;
  283. if (GET_GPIO_VAL_INV(kcontrol->private_value))
  284. val = !val;
  285. ucontrol->value.integer.value[0] = val;
  286. return 0;
  287. }
  288. static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
  289. struct snd_ctl_elem_value *ucontrol)
  290. {
  291. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  292. unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
  293. unsigned int val, mask;
  294. int changed;
  295. mutex_lock(&chip->mutex);
  296. mask = 1 << shift;
  297. val = ucontrol->value.integer.value[0];
  298. if (GET_GPIO_VAL_INV(kcontrol->private_value))
  299. val = !val;
  300. val = val ? mask : 0;
  301. changed = maya_set_gpio_bits(chip->ice, mask, val);
  302. mutex_unlock(&chip->mutex);
  303. return changed;
  304. }
  305. /*
  306. * capture source selection
  307. */
  308. /* known working input slots (0-4) */
  309. #define MAYA_LINE_IN 1 /* in-2 */
  310. #define MAYA_MIC_IN 3 /* in-4 */
  311. static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
  312. {
  313. wm8776_write_bits(chip->ice, &chip->wm[idx], WM8776_REG_ADC_MUX,
  314. 0x1f, 1 << line);
  315. }
  316. static int maya_rec_src_info(struct snd_kcontrol *kcontrol,
  317. struct snd_ctl_elem_info *uinfo)
  318. {
  319. static char *texts[] = { "Line", "Mic" };
  320. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  321. uinfo->count = 1;
  322. uinfo->value.enumerated.items = ARRAY_SIZE(texts);
  323. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  324. uinfo->value.enumerated.item =
  325. uinfo->value.enumerated.items - 1;
  326. strcpy(uinfo->value.enumerated.name,
  327. texts[uinfo->value.enumerated.item]);
  328. return 0;
  329. }
  330. static int maya_rec_src_get(struct snd_kcontrol *kcontrol,
  331. struct snd_ctl_elem_value *ucontrol)
  332. {
  333. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  334. int sel;
  335. if (snd_ice1712_gpio_read(chip->ice) & (1 << GPIO_MIC_RELAY))
  336. sel = 1;
  337. else
  338. sel = 0;
  339. ucontrol->value.enumerated.item[0] = sel;
  340. return 0;
  341. }
  342. static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
  343. struct snd_ctl_elem_value *ucontrol)
  344. {
  345. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  346. int sel = ucontrol->value.enumerated.item[0];
  347. int changed;
  348. mutex_lock(&chip->mutex);
  349. changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
  350. sel ? (1 << GPIO_MIC_RELAY) : 0);
  351. wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
  352. mutex_unlock(&chip->mutex);
  353. return changed;
  354. }
  355. /*
  356. * Maya44 routing switch settings have different meanings than the standard
  357. * ice1724 switches as defined in snd_vt1724_pro_route_info (ice1724.c).
  358. */
  359. static int maya_pb_route_info(struct snd_kcontrol *kcontrol,
  360. struct snd_ctl_elem_info *uinfo)
  361. {
  362. static char *texts[] = {
  363. "PCM Out", /* 0 */
  364. "Input 1", "Input 2", "Input 3", "Input 4"
  365. };
  366. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  367. uinfo->count = 1;
  368. uinfo->value.enumerated.items = ARRAY_SIZE(texts);
  369. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  370. uinfo->value.enumerated.item =
  371. uinfo->value.enumerated.items - 1;
  372. strcpy(uinfo->value.enumerated.name,
  373. texts[uinfo->value.enumerated.item]);
  374. return 0;
  375. }
  376. static int maya_pb_route_shift(int idx)
  377. {
  378. static const unsigned char shift[10] =
  379. { 8, 20, 0, 3, 11, 23, 14, 26, 17, 29 };
  380. return shift[idx % 10];
  381. }
  382. static int maya_pb_route_get(struct snd_kcontrol *kcontrol,
  383. struct snd_ctl_elem_value *ucontrol)
  384. {
  385. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  386. int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  387. ucontrol->value.enumerated.item[0] =
  388. snd_ice1724_get_route_val(chip->ice, maya_pb_route_shift(idx));
  389. return 0;
  390. }
  391. static int maya_pb_route_put(struct snd_kcontrol *kcontrol,
  392. struct snd_ctl_elem_value *ucontrol)
  393. {
  394. struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
  395. int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  396. return snd_ice1724_put_route_val(chip->ice,
  397. ucontrol->value.enumerated.item[0],
  398. maya_pb_route_shift(idx));
  399. }
  400. /*
  401. * controls to be added
  402. */
  403. static struct snd_kcontrol_new maya_controls[] __devinitdata = {
  404. {
  405. .name = "Crossmix Playback Volume",
  406. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  407. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
  408. SNDRV_CTL_ELEM_ACCESS_TLV_READ,
  409. .info = maya_vol_info,
  410. .get = maya_vol_get,
  411. .put = maya_vol_put,
  412. .tlv = { .p = db_scale_hp },
  413. .private_value = WM_VOL_HP,
  414. .count = 2,
  415. },
  416. {
  417. .name = "PCM Playback Volume",
  418. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  419. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
  420. SNDRV_CTL_ELEM_ACCESS_TLV_READ,
  421. .info = maya_vol_info,
  422. .get = maya_vol_get,
  423. .put = maya_vol_put,
  424. .tlv = { .p = db_scale_dac },
  425. .private_value = WM_VOL_DAC,
  426. .count = 2,
  427. },
  428. {
  429. .name = "Line Capture Volume",
  430. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  431. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
  432. SNDRV_CTL_ELEM_ACCESS_TLV_READ,
  433. .info = maya_vol_info,
  434. .get = maya_vol_get,
  435. .put = maya_vol_put,
  436. .tlv = { .p = db_scale_adc },
  437. .private_value = WM_VOL_ADC,
  438. .count = 2,
  439. },
  440. {
  441. .name = "PCM Playback Switch",
  442. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  443. .info = maya_sw_info,
  444. .get = maya_sw_get,
  445. .put = maya_sw_put,
  446. .private_value = COMPOSE_SW_VAL(WM_SW_DAC,
  447. WM8776_REG_OUTPUT_MUX, 0x01),
  448. .count = 2,
  449. },
  450. {
  451. .name = "Bypass Playback Switch",
  452. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  453. .info = maya_sw_info,
  454. .get = maya_sw_get,
  455. .put = maya_sw_put,
  456. .private_value = COMPOSE_SW_VAL(WM_SW_BYPASS,
  457. WM8776_REG_OUTPUT_MUX, 0x04),
  458. .count = 2,
  459. },
  460. {
  461. .name = "Capture Source",
  462. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  463. .info = maya_rec_src_info,
  464. .get = maya_rec_src_get,
  465. .put = maya_rec_src_put,
  466. },
  467. {
  468. .name = "Mic Phantom Power Switch",
  469. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  470. .info = maya_gpio_sw_info,
  471. .get = maya_gpio_sw_get,
  472. .put = maya_gpio_sw_put,
  473. .private_value = COMPOSE_GPIO_VAL(GPIO_PHANTOM_OFF, 1),
  474. },
  475. {
  476. .name = "SPDIF Capture Switch",
  477. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  478. .info = maya_gpio_sw_info,
  479. .get = maya_gpio_sw_get,
  480. .put = maya_gpio_sw_put,
  481. .private_value = COMPOSE_GPIO_VAL(GPIO_SPDIF_IN_INV, 1),
  482. },
  483. {
  484. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  485. .name = "H/W Playback Route",
  486. .info = maya_pb_route_info,
  487. .get = maya_pb_route_get,
  488. .put = maya_pb_route_put,
  489. .count = 4, /* FIXME: do controls 5-9 have any meaning? */
  490. },
  491. };
  492. static int __devinit maya44_add_controls(struct snd_ice1712 *ice)
  493. {
  494. int err, i;
  495. for (i = 0; i < ARRAY_SIZE(maya_controls); i++) {
  496. err = snd_ctl_add(ice->card, snd_ctl_new1(&maya_controls[i],
  497. ice->spec));
  498. if (err < 0)
  499. return err;
  500. }
  501. return 0;
  502. }
  503. /*
  504. * initialize a wm8776 chip
  505. */
  506. static void __devinit wm8776_init(struct snd_ice1712 *ice,
  507. struct snd_wm8776 *wm, unsigned int addr)
  508. {
  509. static const unsigned short inits_wm8776[] = {
  510. 0x02, 0x100, /* R2: headphone L+R muted + update */
  511. 0x05, 0x100, /* R5: DAC output L+R muted + update */
  512. 0x06, 0x000, /* R6: DAC output phase normal */
  513. 0x07, 0x091, /* R7: DAC enable zero cross detection,
  514. normal output */
  515. 0x08, 0x000, /* R8: DAC soft mute off */
  516. 0x09, 0x000, /* R9: no deemph, DAC zero detect disabled */
  517. 0x0a, 0x022, /* R10: DAC I2C mode, std polarities, 24bit */
  518. 0x0b, 0x022, /* R11: ADC I2C mode, std polarities, 24bit,
  519. highpass filter enabled */
  520. 0x0c, 0x042, /* R12: ADC+DAC slave, ADC+DAC 44,1kHz */
  521. 0x0d, 0x000, /* R13: all power up */
  522. 0x0e, 0x100, /* R14: ADC left muted,
  523. enable zero cross detection */
  524. 0x0f, 0x100, /* R15: ADC right muted,
  525. enable zero cross detection */
  526. /* R16: ALC...*/
  527. 0x11, 0x000, /* R17: disable ALC */
  528. /* R18: ALC...*/
  529. /* R19: noise gate...*/
  530. 0x15, 0x000, /* R21: ADC input mux init, mute all inputs */
  531. 0x16, 0x001, /* R22: output mux, select DAC */
  532. 0xff, 0xff
  533. };
  534. const unsigned short *ptr;
  535. unsigned char reg;
  536. unsigned short data;
  537. wm->addr = addr;
  538. /* enable DAC output; mute bypass, aux & all inputs */
  539. wm->switch_bits = (1 << WM_SW_DAC);
  540. ptr = inits_wm8776;
  541. while (*ptr != 0xff) {
  542. reg = *ptr++;
  543. data = *ptr++;
  544. wm8776_write(ice, wm, reg, data);
  545. }
  546. }
  547. /*
  548. * change the rate on the WM8776 codecs.
  549. * this assumes that the VT17xx's rate is changed by the calling function.
  550. * NOTE: even though the WM8776's are running in slave mode and rate
  551. * selection is automatic, we need to call snd_wm8776_set_rate() here
  552. * to make sure some flags are set correctly.
  553. */
  554. static void set_rate(struct snd_ice1712 *ice, unsigned int rate)
  555. {
  556. struct snd_maya44 *chip = ice->spec;
  557. unsigned int ratio, adc_ratio, val;
  558. int i;
  559. switch (rate) {
  560. case 192000:
  561. ratio = WM8776_CLOCK_RATIO_128FS;
  562. break;
  563. case 176400:
  564. ratio = WM8776_CLOCK_RATIO_128FS;
  565. break;
  566. case 96000:
  567. ratio = WM8776_CLOCK_RATIO_256FS;
  568. break;
  569. case 88200:
  570. ratio = WM8776_CLOCK_RATIO_384FS;
  571. break;
  572. case 48000:
  573. ratio = WM8776_CLOCK_RATIO_512FS;
  574. break;
  575. case 44100:
  576. ratio = WM8776_CLOCK_RATIO_512FS;
  577. break;
  578. case 32000:
  579. ratio = WM8776_CLOCK_RATIO_768FS;
  580. break;
  581. case 0:
  582. /* no hint - S/PDIF input is master, simply return */
  583. return;
  584. default:
  585. snd_BUG();
  586. return;
  587. }
  588. /*
  589. * this currently sets the same rate for ADC and DAC, but limits
  590. * ADC rate to 256X (96kHz). For 256X mode (96kHz), this sets ADC
  591. * oversampling to 64x, as recommended by WM8776 datasheet.
  592. * Setting the rate is not really necessary in slave mode.
  593. */
  594. adc_ratio = ratio;
  595. if (adc_ratio < WM8776_CLOCK_RATIO_256FS)
  596. adc_ratio = WM8776_CLOCK_RATIO_256FS;
  597. val = adc_ratio;
  598. if (adc_ratio == WM8776_CLOCK_RATIO_256FS)
  599. val |= 8;
  600. val |= ratio << 4;
  601. mutex_lock(&chip->mutex);
  602. for (i = 0; i < 2; i++)
  603. wm8776_write_bits(ice, &chip->wm[i],
  604. WM8776_REG_MASTER_MODE_CONTROL,
  605. 0x180, val);
  606. mutex_unlock(&chip->mutex);
  607. }
  608. /*
  609. * supported sample rates (to override the default one)
  610. */
  611. static unsigned int rates[] = {
  612. 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000
  613. };
  614. /* playback rates: 32..192 kHz */
  615. static struct snd_pcm_hw_constraint_list dac_rates = {
  616. .count = ARRAY_SIZE(rates),
  617. .list = rates,
  618. .mask = 0
  619. };
  620. /*
  621. * chip addresses on I2C bus
  622. */
  623. static unsigned char wm8776_addr[2] __devinitdata = {
  624. 0x34, 0x36, /* codec 0 & 1 */
  625. };
  626. /*
  627. * initialize the chip
  628. */
  629. static int __devinit maya44_init(struct snd_ice1712 *ice)
  630. {
  631. int i;
  632. struct snd_maya44 *chip;
  633. chip = kzalloc(sizeof(*chip), GFP_KERNEL);
  634. if (!chip)
  635. return -ENOMEM;
  636. mutex_init(&chip->mutex);
  637. chip->ice = ice;
  638. ice->spec = chip;
  639. /* initialise codecs */
  640. ice->num_total_dacs = 4;
  641. ice->num_total_adcs = 4;
  642. ice->akm_codecs = 0;
  643. for (i = 0; i < 2; i++) {
  644. wm8776_init(ice, &chip->wm[i], wm8776_addr[i]);
  645. wm8776_select_input(chip, i, MAYA_LINE_IN);
  646. }
  647. /* set card specific rates */
  648. ice->hw_rates = &dac_rates;
  649. /* register change rate notifier */
  650. ice->gpio.set_pro_rate = set_rate;
  651. /* RDMA1 (2nd input channel) is used for ADC by default */
  652. ice->force_rdma1 = 1;
  653. /* have an own routing control */
  654. ice->own_routing = 1;
  655. return 0;
  656. }
  657. /*
  658. * Maya44 boards don't provide the EEPROM data except for the vendor IDs.
  659. * hence the driver needs to sets up it properly.
  660. */
  661. static unsigned char maya44_eeprom[] __devinitdata = {
  662. [ICE_EEP2_SYSCONF] = 0x45,
  663. /* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */
  664. [ICE_EEP2_ACLINK] = 0x80,
  665. /* I2S */
  666. [ICE_EEP2_I2S] = 0xf8,
  667. /* vol, 96k, 24bit, 192k */
  668. [ICE_EEP2_SPDIF] = 0xc3,
  669. /* enable spdif out, spdif out supp, spdif-in, ext spdif out */
  670. [ICE_EEP2_GPIO_DIR] = 0xff,
  671. [ICE_EEP2_GPIO_DIR1] = 0xff,
  672. [ICE_EEP2_GPIO_DIR2] = 0xff,
  673. [ICE_EEP2_GPIO_MASK] = 0/*0x9f*/,
  674. [ICE_EEP2_GPIO_MASK1] = 0/*0xff*/,
  675. [ICE_EEP2_GPIO_MASK2] = 0/*0x7f*/,
  676. [ICE_EEP2_GPIO_STATE] = (1 << GPIO_PHANTOM_OFF) |
  677. (1 << GPIO_SPDIF_IN_INV),
  678. [ICE_EEP2_GPIO_STATE1] = 0x00,
  679. [ICE_EEP2_GPIO_STATE2] = 0x00,
  680. };
  681. /* entry point */
  682. struct snd_ice1712_card_info snd_vt1724_maya44_cards[] __devinitdata = {
  683. {
  684. .subvendor = VT1724_SUBDEVICE_MAYA44,
  685. .name = "ESI Maya44",
  686. .model = "maya44",
  687. .chip_init = maya44_init,
  688. .build_controls = maya44_add_controls,
  689. .eeprom_size = sizeof(maya44_eeprom),
  690. .eeprom_data = maya44_eeprom,
  691. },
  692. { } /* terminator */
  693. };