aureon.c 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284
  1. /*
  2. * ALSA driver for ICEnsemble VT1724 (Envy24HT)
  3. *
  4. * Lowlevel functions for Terratec Aureon cards
  5. *
  6. * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. *
  23. * NOTES:
  24. *
  25. * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
  26. * both wm and akm codecs are pretty similar, so we can integrate
  27. * both controls in the future, once if wm codecs are reused in
  28. * many boards.
  29. *
  30. * - DAC digital volumes are not implemented in the mixer.
  31. * if they show better response than DAC analog volumes, we can use them
  32. * instead.
  33. *
  34. * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
  35. * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
  36. *
  37. * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
  38. * added 64x/128x oversampling switch (should be 64x only for 96khz)
  39. * fixed some recording labels (still need to check the rest)
  40. * recording is working probably thanks to correct wm8770 initialization
  41. *
  42. * version 0.5: Initial release:
  43. * working: analog output, mixer, headphone amplifier switch
  44. * not working: prety much everything else, at least i could verify that
  45. * we have no digital output, no capture, pretty bad clicks and poops
  46. * on mixer switch and other coll stuff.
  47. */
  48. #include <linux/io.h>
  49. #include <linux/delay.h>
  50. #include <linux/interrupt.h>
  51. #include <linux/init.h>
  52. #include <linux/slab.h>
  53. #include <linux/mutex.h>
  54. #include <sound/core.h>
  55. #include "ice1712.h"
  56. #include "envy24ht.h"
  57. #include "aureon.h"
  58. #include <sound/tlv.h>
  59. /* AC97 register cache for Aureon */
  60. struct aureon_spec {
  61. unsigned short stac9744[64];
  62. unsigned int cs8415_mux;
  63. unsigned short master[2];
  64. unsigned short vol[8];
  65. unsigned char pca9554_out;
  66. };
  67. /* WM8770 registers */
  68. #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
  69. #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
  70. #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
  71. #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
  72. #define WM_PHASE_SWAP 0x12 /* DAC phase */
  73. #define WM_DAC_CTRL1 0x13 /* DAC control bits */
  74. #define WM_MUTE 0x14 /* mute controls */
  75. #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
  76. #define WM_INT_CTRL 0x16 /* interface control */
  77. #define WM_MASTER 0x17 /* master clock and mode */
  78. #define WM_POWERDOWN 0x18 /* power-down controls */
  79. #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
  80. #define WM_ADC_MUX 0x1b /* input MUX */
  81. #define WM_OUT_MUX1 0x1c /* output MUX */
  82. #define WM_OUT_MUX2 0x1e /* output MUX */
  83. #define WM_RESET 0x1f /* software reset */
  84. /* CS8415A registers */
  85. #define CS8415_CTRL1 0x01
  86. #define CS8415_CTRL2 0x02
  87. #define CS8415_QSUB 0x14
  88. #define CS8415_RATIO 0x1E
  89. #define CS8415_C_BUFFER 0x20
  90. #define CS8415_ID 0x7F
  91. /* PCA9554 registers */
  92. #define PCA9554_DEV 0x40 /* I2C device address */
  93. #define PCA9554_IN 0x00 /* input port */
  94. #define PCA9554_OUT 0x01 /* output port */
  95. #define PCA9554_INVERT 0x02 /* input invert */
  96. #define PCA9554_DIR 0x03 /* port directions */
  97. /*
  98. * Aureon Universe additional controls using PCA9554
  99. */
  100. /*
  101. * Send data to pca9554
  102. */
  103. static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
  104. unsigned char data)
  105. {
  106. unsigned int tmp;
  107. int i, j;
  108. unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
  109. unsigned char val = 0;
  110. tmp = snd_ice1712_gpio_read(ice);
  111. snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
  112. AUREON_WM_RW|AUREON_WM_CS|
  113. AUREON_CS8415_CS));
  114. tmp |= AUREON_WM_RW;
  115. tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
  116. tmp &= ~AUREON_SPI_MOSI;
  117. tmp &= ~AUREON_SPI_CLK;
  118. snd_ice1712_gpio_write(ice, tmp);
  119. udelay(50);
  120. /*
  121. * send i2c stop condition and start condition
  122. * to obtain sane state
  123. */
  124. tmp |= AUREON_SPI_CLK;
  125. snd_ice1712_gpio_write(ice, tmp);
  126. udelay(50);
  127. tmp |= AUREON_SPI_MOSI;
  128. snd_ice1712_gpio_write(ice, tmp);
  129. udelay(100);
  130. tmp &= ~AUREON_SPI_MOSI;
  131. snd_ice1712_gpio_write(ice, tmp);
  132. udelay(50);
  133. tmp &= ~AUREON_SPI_CLK;
  134. snd_ice1712_gpio_write(ice, tmp);
  135. udelay(100);
  136. /*
  137. * send device address, command and value,
  138. * skipping ack cycles inbetween
  139. */
  140. for (j = 0; j < 3; j++) {
  141. switch (j) {
  142. case 0:
  143. val = dev;
  144. break;
  145. case 1:
  146. val = reg;
  147. break;
  148. case 2:
  149. val = data;
  150. break;
  151. }
  152. for (i = 7; i >= 0; i--) {
  153. tmp &= ~AUREON_SPI_CLK;
  154. snd_ice1712_gpio_write(ice, tmp);
  155. udelay(40);
  156. if (val & (1 << i))
  157. tmp |= AUREON_SPI_MOSI;
  158. else
  159. tmp &= ~AUREON_SPI_MOSI;
  160. snd_ice1712_gpio_write(ice, tmp);
  161. udelay(40);
  162. tmp |= AUREON_SPI_CLK;
  163. snd_ice1712_gpio_write(ice, tmp);
  164. udelay(40);
  165. }
  166. tmp &= ~AUREON_SPI_CLK;
  167. snd_ice1712_gpio_write(ice, tmp);
  168. udelay(40);
  169. tmp |= AUREON_SPI_CLK;
  170. snd_ice1712_gpio_write(ice, tmp);
  171. udelay(40);
  172. tmp &= ~AUREON_SPI_CLK;
  173. snd_ice1712_gpio_write(ice, tmp);
  174. udelay(40);
  175. }
  176. tmp &= ~AUREON_SPI_CLK;
  177. snd_ice1712_gpio_write(ice, tmp);
  178. udelay(40);
  179. tmp &= ~AUREON_SPI_MOSI;
  180. snd_ice1712_gpio_write(ice, tmp);
  181. udelay(40);
  182. tmp |= AUREON_SPI_CLK;
  183. snd_ice1712_gpio_write(ice, tmp);
  184. udelay(50);
  185. tmp |= AUREON_SPI_MOSI;
  186. snd_ice1712_gpio_write(ice, tmp);
  187. udelay(100);
  188. }
  189. static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
  190. struct snd_ctl_elem_info *uinfo)
  191. {
  192. char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
  193. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  194. uinfo->count = 1;
  195. uinfo->value.enumerated.items = 3;
  196. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  197. uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
  198. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  199. return 0;
  200. }
  201. static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
  202. struct snd_ctl_elem_value *ucontrol)
  203. {
  204. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  205. struct aureon_spec *spec = ice->spec;
  206. ucontrol->value.enumerated.item[0] = spec->pca9554_out;
  207. return 0;
  208. }
  209. static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
  210. struct snd_ctl_elem_value *ucontrol)
  211. {
  212. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  213. struct aureon_spec *spec = ice->spec;
  214. unsigned char oval, nval;
  215. int change;
  216. nval = ucontrol->value.enumerated.item[0];
  217. if (nval >= 3)
  218. return -EINVAL;
  219. snd_ice1712_save_gpio_status(ice);
  220. oval = spec->pca9554_out;
  221. change = (oval != nval);
  222. if (change) {
  223. aureon_pca9554_write(ice, PCA9554_OUT, nval);
  224. spec->pca9554_out = nval;
  225. }
  226. snd_ice1712_restore_gpio_status(ice);
  227. return change;
  228. }
  229. static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
  230. unsigned short val)
  231. {
  232. struct aureon_spec *spec = ice->spec;
  233. unsigned int tmp;
  234. /* Send address to XILINX chip */
  235. tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
  236. snd_ice1712_gpio_write(ice, tmp);
  237. udelay(10);
  238. tmp |= AUREON_AC97_ADDR;
  239. snd_ice1712_gpio_write(ice, tmp);
  240. udelay(10);
  241. tmp &= ~AUREON_AC97_ADDR;
  242. snd_ice1712_gpio_write(ice, tmp);
  243. udelay(10);
  244. /* Send low-order byte to XILINX chip */
  245. tmp &= ~AUREON_AC97_DATA_MASK;
  246. tmp |= val & AUREON_AC97_DATA_MASK;
  247. snd_ice1712_gpio_write(ice, tmp);
  248. udelay(10);
  249. tmp |= AUREON_AC97_DATA_LOW;
  250. snd_ice1712_gpio_write(ice, tmp);
  251. udelay(10);
  252. tmp &= ~AUREON_AC97_DATA_LOW;
  253. snd_ice1712_gpio_write(ice, tmp);
  254. udelay(10);
  255. /* Send high-order byte to XILINX chip */
  256. tmp &= ~AUREON_AC97_DATA_MASK;
  257. tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
  258. snd_ice1712_gpio_write(ice, tmp);
  259. udelay(10);
  260. tmp |= AUREON_AC97_DATA_HIGH;
  261. snd_ice1712_gpio_write(ice, tmp);
  262. udelay(10);
  263. tmp &= ~AUREON_AC97_DATA_HIGH;
  264. snd_ice1712_gpio_write(ice, tmp);
  265. udelay(10);
  266. /* Instruct XILINX chip to parse the data to the STAC9744 chip */
  267. tmp |= AUREON_AC97_COMMIT;
  268. snd_ice1712_gpio_write(ice, tmp);
  269. udelay(10);
  270. tmp &= ~AUREON_AC97_COMMIT;
  271. snd_ice1712_gpio_write(ice, tmp);
  272. udelay(10);
  273. /* Store the data in out private buffer */
  274. spec->stac9744[(reg & 0x7F) >> 1] = val;
  275. }
  276. static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
  277. {
  278. struct aureon_spec *spec = ice->spec;
  279. return spec->stac9744[(reg & 0x7F) >> 1];
  280. }
  281. /*
  282. * Initialize STAC9744 chip
  283. */
  284. static int aureon_ac97_init(struct snd_ice1712 *ice)
  285. {
  286. struct aureon_spec *spec = ice->spec;
  287. int i;
  288. static const unsigned short ac97_defaults[] = {
  289. 0x00, 0x9640,
  290. 0x02, 0x8000,
  291. 0x04, 0x8000,
  292. 0x06, 0x8000,
  293. 0x0C, 0x8008,
  294. 0x0E, 0x8008,
  295. 0x10, 0x8808,
  296. 0x12, 0x8808,
  297. 0x14, 0x8808,
  298. 0x16, 0x8808,
  299. 0x18, 0x8808,
  300. 0x1C, 0x8000,
  301. 0x26, 0x000F,
  302. 0x28, 0x0201,
  303. 0x2C, 0xBB80,
  304. 0x32, 0xBB80,
  305. 0x7C, 0x8384,
  306. 0x7E, 0x7644,
  307. (unsigned short)-1
  308. };
  309. unsigned int tmp;
  310. /* Cold reset */
  311. tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
  312. snd_ice1712_gpio_write(ice, tmp);
  313. udelay(3);
  314. tmp &= ~AUREON_AC97_RESET;
  315. snd_ice1712_gpio_write(ice, tmp);
  316. udelay(3);
  317. tmp |= AUREON_AC97_RESET;
  318. snd_ice1712_gpio_write(ice, tmp);
  319. udelay(3);
  320. memset(&spec->stac9744, 0, sizeof(spec->stac9744));
  321. for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
  322. spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
  323. /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
  324. aureon_ac97_write(ice, AC97_MASTER, 0x0000);
  325. return 0;
  326. }
  327. #define AUREON_AC97_STEREO 0x80
  328. /*
  329. * AC'97 volume controls
  330. */
  331. static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  332. {
  333. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  334. uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
  335. uinfo->value.integer.min = 0;
  336. uinfo->value.integer.max = 31;
  337. return 0;
  338. }
  339. static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  340. {
  341. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  342. unsigned short vol;
  343. mutex_lock(&ice->gpio_mutex);
  344. vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
  345. ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
  346. if (kcontrol->private_value & AUREON_AC97_STEREO)
  347. ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
  348. mutex_unlock(&ice->gpio_mutex);
  349. return 0;
  350. }
  351. static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  352. {
  353. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  354. unsigned short ovol, nvol;
  355. int change;
  356. snd_ice1712_save_gpio_status(ice);
  357. ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
  358. nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
  359. if (kcontrol->private_value & AUREON_AC97_STEREO)
  360. nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
  361. nvol |= ovol & ~0x1F1F;
  362. change = (ovol != nvol);
  363. if (change)
  364. aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
  365. snd_ice1712_restore_gpio_status(ice);
  366. return change;
  367. }
  368. /*
  369. * AC'97 mute controls
  370. */
  371. #define aureon_ac97_mute_info snd_ctl_boolean_mono_info
  372. static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  373. {
  374. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  375. mutex_lock(&ice->gpio_mutex);
  376. ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
  377. kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
  378. mutex_unlock(&ice->gpio_mutex);
  379. return 0;
  380. }
  381. static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  382. {
  383. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  384. unsigned short ovol, nvol;
  385. int change;
  386. snd_ice1712_save_gpio_status(ice);
  387. ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
  388. nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
  389. change = (ovol != nvol);
  390. if (change)
  391. aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
  392. snd_ice1712_restore_gpio_status(ice);
  393. return change;
  394. }
  395. /*
  396. * AC'97 mute controls
  397. */
  398. #define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
  399. static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  400. {
  401. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  402. mutex_lock(&ice->gpio_mutex);
  403. ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
  404. mutex_unlock(&ice->gpio_mutex);
  405. return 0;
  406. }
  407. static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  408. {
  409. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  410. unsigned short ovol, nvol;
  411. int change;
  412. snd_ice1712_save_gpio_status(ice);
  413. ovol = aureon_ac97_read(ice, AC97_MIC);
  414. nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
  415. change = (ovol != nvol);
  416. if (change)
  417. aureon_ac97_write(ice, AC97_MIC, nvol);
  418. snd_ice1712_restore_gpio_status(ice);
  419. return change;
  420. }
  421. /*
  422. * write data in the SPI mode
  423. */
  424. static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
  425. {
  426. unsigned int tmp;
  427. int i;
  428. unsigned int mosi, clk;
  429. tmp = snd_ice1712_gpio_read(ice);
  430. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
  431. ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
  432. snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
  433. mosi = PRODIGY_SPI_MOSI;
  434. clk = PRODIGY_SPI_CLK;
  435. } else {
  436. snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
  437. AUREON_WM_CS|AUREON_CS8415_CS));
  438. mosi = AUREON_SPI_MOSI;
  439. clk = AUREON_SPI_CLK;
  440. tmp |= AUREON_WM_RW;
  441. }
  442. tmp &= ~cs;
  443. snd_ice1712_gpio_write(ice, tmp);
  444. udelay(1);
  445. for (i = bits - 1; i >= 0; i--) {
  446. tmp &= ~clk;
  447. snd_ice1712_gpio_write(ice, tmp);
  448. udelay(1);
  449. if (data & (1 << i))
  450. tmp |= mosi;
  451. else
  452. tmp &= ~mosi;
  453. snd_ice1712_gpio_write(ice, tmp);
  454. udelay(1);
  455. tmp |= clk;
  456. snd_ice1712_gpio_write(ice, tmp);
  457. udelay(1);
  458. }
  459. tmp &= ~clk;
  460. tmp |= cs;
  461. snd_ice1712_gpio_write(ice, tmp);
  462. udelay(1);
  463. tmp |= clk;
  464. snd_ice1712_gpio_write(ice, tmp);
  465. udelay(1);
  466. }
  467. /*
  468. * Read data in SPI mode
  469. */
  470. static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
  471. unsigned int data, int bits, unsigned char *buffer, int size)
  472. {
  473. int i, j;
  474. unsigned int tmp;
  475. tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
  476. snd_ice1712_gpio_write(ice, tmp);
  477. tmp &= ~cs;
  478. snd_ice1712_gpio_write(ice, tmp);
  479. udelay(1);
  480. for (i = bits-1; i >= 0; i--) {
  481. if (data & (1 << i))
  482. tmp |= AUREON_SPI_MOSI;
  483. else
  484. tmp &= ~AUREON_SPI_MOSI;
  485. snd_ice1712_gpio_write(ice, tmp);
  486. udelay(1);
  487. tmp |= AUREON_SPI_CLK;
  488. snd_ice1712_gpio_write(ice, tmp);
  489. udelay(1);
  490. tmp &= ~AUREON_SPI_CLK;
  491. snd_ice1712_gpio_write(ice, tmp);
  492. udelay(1);
  493. }
  494. for (j = 0; j < size; j++) {
  495. unsigned char outdata = 0;
  496. for (i = 7; i >= 0; i--) {
  497. tmp = snd_ice1712_gpio_read(ice);
  498. outdata <<= 1;
  499. outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
  500. udelay(1);
  501. tmp |= AUREON_SPI_CLK;
  502. snd_ice1712_gpio_write(ice, tmp);
  503. udelay(1);
  504. tmp &= ~AUREON_SPI_CLK;
  505. snd_ice1712_gpio_write(ice, tmp);
  506. udelay(1);
  507. }
  508. buffer[j] = outdata;
  509. }
  510. tmp |= cs;
  511. snd_ice1712_gpio_write(ice, tmp);
  512. }
  513. static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
  514. {
  515. unsigned char val;
  516. aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
  517. aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
  518. return val;
  519. }
  520. static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
  521. unsigned char *buffer, int size)
  522. {
  523. aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
  524. aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
  525. }
  526. static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
  527. unsigned char val)
  528. {
  529. aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
  530. }
  531. /*
  532. * get the current register value of WM codec
  533. */
  534. static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
  535. {
  536. reg <<= 1;
  537. return ((unsigned short)ice->akm[0].images[reg] << 8) |
  538. ice->akm[0].images[reg + 1];
  539. }
  540. /*
  541. * set the register value of WM codec
  542. */
  543. static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
  544. {
  545. aureon_spi_write(ice,
  546. ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
  547. ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
  548. PRODIGY_WM_CS : AUREON_WM_CS),
  549. (reg << 9) | (val & 0x1ff), 16);
  550. }
  551. /*
  552. * set the register value of WM codec and remember it
  553. */
  554. static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
  555. {
  556. wm_put_nocache(ice, reg, val);
  557. reg <<= 1;
  558. ice->akm[0].images[reg] = val >> 8;
  559. ice->akm[0].images[reg + 1] = val;
  560. }
  561. /*
  562. */
  563. #define aureon_mono_bool_info snd_ctl_boolean_mono_info
  564. /*
  565. * AC'97 master playback mute controls (Mute on WM8770 chip)
  566. */
  567. #define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
  568. static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  569. {
  570. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  571. mutex_lock(&ice->gpio_mutex);
  572. ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
  573. mutex_unlock(&ice->gpio_mutex);
  574. return 0;
  575. }
  576. static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  577. {
  578. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  579. unsigned short ovol, nvol;
  580. int change;
  581. snd_ice1712_save_gpio_status(ice);
  582. ovol = wm_get(ice, WM_OUT_MUX1);
  583. nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
  584. change = (ovol != nvol);
  585. if (change)
  586. wm_put(ice, WM_OUT_MUX1, nvol);
  587. snd_ice1712_restore_gpio_status(ice);
  588. return change;
  589. }
  590. static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
  591. static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
  592. static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
  593. static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
  594. static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
  595. /*
  596. * Logarithmic volume values for WM8770
  597. * Computed as 20 * Log10(255 / x)
  598. */
  599. static const unsigned char wm_vol[256] = {
  600. 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
  601. 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
  602. 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
  603. 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
  604. 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
  605. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
  606. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  607. 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
  608. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  609. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  610. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  611. 0, 0
  612. };
  613. #define WM_VOL_MAX (sizeof(wm_vol) - 1)
  614. #define WM_VOL_MUTE 0x8000
  615. static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
  616. {
  617. unsigned char nvol;
  618. if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
  619. nvol = 0;
  620. else
  621. nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
  622. wm_put(ice, index, nvol);
  623. wm_put_nocache(ice, index, 0x180 | nvol);
  624. }
  625. /*
  626. * DAC mute control
  627. */
  628. #define wm_pcm_mute_info snd_ctl_boolean_mono_info
  629. static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  630. {
  631. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  632. mutex_lock(&ice->gpio_mutex);
  633. ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
  634. mutex_unlock(&ice->gpio_mutex);
  635. return 0;
  636. }
  637. static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  638. {
  639. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  640. unsigned short nval, oval;
  641. int change;
  642. snd_ice1712_save_gpio_status(ice);
  643. oval = wm_get(ice, WM_MUTE);
  644. nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
  645. change = (oval != nval);
  646. if (change)
  647. wm_put(ice, WM_MUTE, nval);
  648. snd_ice1712_restore_gpio_status(ice);
  649. return change;
  650. }
  651. /*
  652. * Master volume attenuation mixer control
  653. */
  654. static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  655. {
  656. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  657. uinfo->count = 2;
  658. uinfo->value.integer.min = 0;
  659. uinfo->value.integer.max = WM_VOL_MAX;
  660. return 0;
  661. }
  662. static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  663. {
  664. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  665. struct aureon_spec *spec = ice->spec;
  666. int i;
  667. for (i = 0; i < 2; i++)
  668. ucontrol->value.integer.value[i] =
  669. spec->master[i] & ~WM_VOL_MUTE;
  670. return 0;
  671. }
  672. static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  673. {
  674. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  675. struct aureon_spec *spec = ice->spec;
  676. int ch, change = 0;
  677. snd_ice1712_save_gpio_status(ice);
  678. for (ch = 0; ch < 2; ch++) {
  679. unsigned int vol = ucontrol->value.integer.value[ch];
  680. if (vol > WM_VOL_MAX)
  681. continue;
  682. vol |= spec->master[ch] & WM_VOL_MUTE;
  683. if (vol != spec->master[ch]) {
  684. int dac;
  685. spec->master[ch] = vol;
  686. for (dac = 0; dac < ice->num_total_dacs; dac += 2)
  687. wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
  688. spec->vol[dac + ch],
  689. spec->master[ch]);
  690. change = 1;
  691. }
  692. }
  693. snd_ice1712_restore_gpio_status(ice);
  694. return change;
  695. }
  696. /*
  697. * DAC volume attenuation mixer control
  698. */
  699. static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  700. {
  701. int voices = kcontrol->private_value >> 8;
  702. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  703. uinfo->count = voices;
  704. uinfo->value.integer.min = 0; /* mute (-101dB) */
  705. uinfo->value.integer.max = 0x7F; /* 0dB */
  706. return 0;
  707. }
  708. static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  709. {
  710. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  711. struct aureon_spec *spec = ice->spec;
  712. int i, ofs, voices;
  713. voices = kcontrol->private_value >> 8;
  714. ofs = kcontrol->private_value & 0xff;
  715. for (i = 0; i < voices; i++)
  716. ucontrol->value.integer.value[i] =
  717. spec->vol[ofs+i] & ~WM_VOL_MUTE;
  718. return 0;
  719. }
  720. static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  721. {
  722. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  723. struct aureon_spec *spec = ice->spec;
  724. int i, idx, ofs, voices;
  725. int change = 0;
  726. voices = kcontrol->private_value >> 8;
  727. ofs = kcontrol->private_value & 0xff;
  728. snd_ice1712_save_gpio_status(ice);
  729. for (i = 0; i < voices; i++) {
  730. unsigned int vol = ucontrol->value.integer.value[i];
  731. if (vol > 0x7f)
  732. continue;
  733. vol |= spec->vol[ofs+i];
  734. if (vol != spec->vol[ofs+i]) {
  735. spec->vol[ofs+i] = vol;
  736. idx = WM_DAC_ATTEN + ofs + i;
  737. wm_set_vol(ice, idx, spec->vol[ofs + i],
  738. spec->master[i]);
  739. change = 1;
  740. }
  741. }
  742. snd_ice1712_restore_gpio_status(ice);
  743. return change;
  744. }
  745. /*
  746. * WM8770 mute control
  747. */
  748. static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  749. {
  750. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  751. uinfo->count = kcontrol->private_value >> 8;
  752. uinfo->value.integer.min = 0;
  753. uinfo->value.integer.max = 1;
  754. return 0;
  755. }
  756. static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  757. {
  758. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  759. struct aureon_spec *spec = ice->spec;
  760. int voices, ofs, i;
  761. voices = kcontrol->private_value >> 8;
  762. ofs = kcontrol->private_value & 0xFF;
  763. for (i = 0; i < voices; i++)
  764. ucontrol->value.integer.value[i] =
  765. (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
  766. return 0;
  767. }
  768. static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  769. {
  770. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  771. struct aureon_spec *spec = ice->spec;
  772. int change = 0, voices, ofs, i;
  773. voices = kcontrol->private_value >> 8;
  774. ofs = kcontrol->private_value & 0xFF;
  775. snd_ice1712_save_gpio_status(ice);
  776. for (i = 0; i < voices; i++) {
  777. int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
  778. if (ucontrol->value.integer.value[i] != val) {
  779. spec->vol[ofs + i] &= ~WM_VOL_MUTE;
  780. spec->vol[ofs + i] |=
  781. ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
  782. wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
  783. spec->master[i]);
  784. change = 1;
  785. }
  786. }
  787. snd_ice1712_restore_gpio_status(ice);
  788. return change;
  789. }
  790. /*
  791. * WM8770 master mute control
  792. */
  793. #define wm_master_mute_info snd_ctl_boolean_stereo_info
  794. static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  795. {
  796. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  797. struct aureon_spec *spec = ice->spec;
  798. ucontrol->value.integer.value[0] =
  799. (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
  800. ucontrol->value.integer.value[1] =
  801. (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
  802. return 0;
  803. }
  804. static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  805. {
  806. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  807. struct aureon_spec *spec = ice->spec;
  808. int change = 0, i;
  809. snd_ice1712_save_gpio_status(ice);
  810. for (i = 0; i < 2; i++) {
  811. int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
  812. if (ucontrol->value.integer.value[i] != val) {
  813. int dac;
  814. spec->master[i] &= ~WM_VOL_MUTE;
  815. spec->master[i] |=
  816. ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
  817. for (dac = 0; dac < ice->num_total_dacs; dac += 2)
  818. wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
  819. spec->vol[dac + i],
  820. spec->master[i]);
  821. change = 1;
  822. }
  823. }
  824. snd_ice1712_restore_gpio_status(ice);
  825. return change;
  826. }
  827. /* digital master volume */
  828. #define PCM_0dB 0xff
  829. #define PCM_RES 128 /* -64dB */
  830. #define PCM_MIN (PCM_0dB - PCM_RES)
  831. static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  832. {
  833. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  834. uinfo->count = 1;
  835. uinfo->value.integer.min = 0; /* mute (-64dB) */
  836. uinfo->value.integer.max = PCM_RES; /* 0dB */
  837. return 0;
  838. }
  839. static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  840. {
  841. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  842. unsigned short val;
  843. mutex_lock(&ice->gpio_mutex);
  844. val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
  845. val = val > PCM_MIN ? (val - PCM_MIN) : 0;
  846. ucontrol->value.integer.value[0] = val;
  847. mutex_unlock(&ice->gpio_mutex);
  848. return 0;
  849. }
  850. static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  851. {
  852. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  853. unsigned short ovol, nvol;
  854. int change = 0;
  855. nvol = ucontrol->value.integer.value[0];
  856. if (nvol > PCM_RES)
  857. return -EINVAL;
  858. snd_ice1712_save_gpio_status(ice);
  859. nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
  860. ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
  861. if (ovol != nvol) {
  862. wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
  863. wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
  864. change = 1;
  865. }
  866. snd_ice1712_restore_gpio_status(ice);
  867. return change;
  868. }
  869. /*
  870. * ADC mute control
  871. */
  872. #define wm_adc_mute_info snd_ctl_boolean_stereo_info
  873. static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  874. {
  875. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  876. unsigned short val;
  877. int i;
  878. mutex_lock(&ice->gpio_mutex);
  879. for (i = 0; i < 2; i++) {
  880. val = wm_get(ice, WM_ADC_GAIN + i);
  881. ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
  882. }
  883. mutex_unlock(&ice->gpio_mutex);
  884. return 0;
  885. }
  886. static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  887. {
  888. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  889. unsigned short new, old;
  890. int i, change = 0;
  891. snd_ice1712_save_gpio_status(ice);
  892. for (i = 0; i < 2; i++) {
  893. old = wm_get(ice, WM_ADC_GAIN + i);
  894. new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
  895. if (new != old) {
  896. wm_put(ice, WM_ADC_GAIN + i, new);
  897. change = 1;
  898. }
  899. }
  900. snd_ice1712_restore_gpio_status(ice);
  901. return change;
  902. }
  903. /*
  904. * ADC gain mixer control
  905. */
  906. static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  907. {
  908. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  909. uinfo->count = 2;
  910. uinfo->value.integer.min = 0; /* -12dB */
  911. uinfo->value.integer.max = 0x1f; /* 19dB */
  912. return 0;
  913. }
  914. static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  915. {
  916. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  917. int i, idx;
  918. unsigned short vol;
  919. mutex_lock(&ice->gpio_mutex);
  920. for (i = 0; i < 2; i++) {
  921. idx = WM_ADC_GAIN + i;
  922. vol = wm_get(ice, idx) & 0x1f;
  923. ucontrol->value.integer.value[i] = vol;
  924. }
  925. mutex_unlock(&ice->gpio_mutex);
  926. return 0;
  927. }
  928. static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  929. {
  930. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  931. int i, idx;
  932. unsigned short ovol, nvol;
  933. int change = 0;
  934. snd_ice1712_save_gpio_status(ice);
  935. for (i = 0; i < 2; i++) {
  936. idx = WM_ADC_GAIN + i;
  937. nvol = ucontrol->value.integer.value[i] & 0x1f;
  938. ovol = wm_get(ice, idx);
  939. if ((ovol & 0x1f) != nvol) {
  940. wm_put(ice, idx, nvol | (ovol & ~0x1f));
  941. change = 1;
  942. }
  943. }
  944. snd_ice1712_restore_gpio_status(ice);
  945. return change;
  946. }
  947. /*
  948. * ADC input mux mixer control
  949. */
  950. static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  951. {
  952. static const char * const texts[] = {
  953. "CD", /* AIN1 */
  954. "Aux", /* AIN2 */
  955. "Line", /* AIN3 */
  956. "Mic", /* AIN4 */
  957. "AC97" /* AIN5 */
  958. };
  959. static const char * const universe_texts[] = {
  960. "Aux1", /* AIN1 */
  961. "CD", /* AIN2 */
  962. "Phono", /* AIN3 */
  963. "Line", /* AIN4 */
  964. "Aux2", /* AIN5 */
  965. "Mic", /* AIN6 */
  966. "Aux3", /* AIN7 */
  967. "AC97" /* AIN8 */
  968. };
  969. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  970. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  971. uinfo->count = 2;
  972. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
  973. uinfo->value.enumerated.items = 8;
  974. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  975. uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
  976. strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
  977. } else {
  978. uinfo->value.enumerated.items = 5;
  979. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  980. uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
  981. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  982. }
  983. return 0;
  984. }
  985. static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  986. {
  987. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  988. unsigned short val;
  989. mutex_lock(&ice->gpio_mutex);
  990. val = wm_get(ice, WM_ADC_MUX);
  991. ucontrol->value.enumerated.item[0] = val & 7;
  992. ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
  993. mutex_unlock(&ice->gpio_mutex);
  994. return 0;
  995. }
  996. static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  997. {
  998. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  999. unsigned short oval, nval;
  1000. int change;
  1001. snd_ice1712_save_gpio_status(ice);
  1002. oval = wm_get(ice, WM_ADC_MUX);
  1003. nval = oval & ~0x77;
  1004. nval |= ucontrol->value.enumerated.item[0] & 7;
  1005. nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
  1006. change = (oval != nval);
  1007. if (change)
  1008. wm_put(ice, WM_ADC_MUX, nval);
  1009. snd_ice1712_restore_gpio_status(ice);
  1010. return change;
  1011. }
  1012. /*
  1013. * CS8415 Input mux
  1014. */
  1015. static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  1016. {
  1017. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1018. static const char * const aureon_texts[] = {
  1019. "CD", /* RXP0 */
  1020. "Optical" /* RXP1 */
  1021. };
  1022. static const char * const prodigy_texts[] = {
  1023. "CD",
  1024. "Coax"
  1025. };
  1026. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1027. uinfo->count = 1;
  1028. uinfo->value.enumerated.items = 2;
  1029. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  1030. uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
  1031. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
  1032. strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
  1033. else
  1034. strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
  1035. return 0;
  1036. }
  1037. static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1038. {
  1039. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1040. struct aureon_spec *spec = ice->spec;
  1041. /* snd_ice1712_save_gpio_status(ice); */
  1042. /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
  1043. ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
  1044. /* snd_ice1712_restore_gpio_status(ice); */
  1045. return 0;
  1046. }
  1047. static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1048. {
  1049. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1050. struct aureon_spec *spec = ice->spec;
  1051. unsigned short oval, nval;
  1052. int change;
  1053. snd_ice1712_save_gpio_status(ice);
  1054. oval = aureon_cs8415_get(ice, CS8415_CTRL2);
  1055. nval = oval & ~0x07;
  1056. nval |= ucontrol->value.enumerated.item[0] & 7;
  1057. change = (oval != nval);
  1058. if (change)
  1059. aureon_cs8415_put(ice, CS8415_CTRL2, nval);
  1060. snd_ice1712_restore_gpio_status(ice);
  1061. spec->cs8415_mux = ucontrol->value.enumerated.item[0];
  1062. return change;
  1063. }
  1064. static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  1065. {
  1066. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  1067. uinfo->count = 1;
  1068. uinfo->value.integer.min = 0;
  1069. uinfo->value.integer.max = 192000;
  1070. return 0;
  1071. }
  1072. static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1073. {
  1074. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1075. unsigned char ratio;
  1076. ratio = aureon_cs8415_get(ice, CS8415_RATIO);
  1077. ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
  1078. return 0;
  1079. }
  1080. /*
  1081. * CS8415A Mute
  1082. */
  1083. #define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
  1084. static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1085. {
  1086. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1087. snd_ice1712_save_gpio_status(ice);
  1088. ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
  1089. snd_ice1712_restore_gpio_status(ice);
  1090. return 0;
  1091. }
  1092. static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1093. {
  1094. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1095. unsigned char oval, nval;
  1096. int change;
  1097. snd_ice1712_save_gpio_status(ice);
  1098. oval = aureon_cs8415_get(ice, CS8415_CTRL1);
  1099. if (ucontrol->value.integer.value[0])
  1100. nval = oval & ~0x20;
  1101. else
  1102. nval = oval | 0x20;
  1103. change = (oval != nval);
  1104. if (change)
  1105. aureon_cs8415_put(ice, CS8415_CTRL1, nval);
  1106. snd_ice1712_restore_gpio_status(ice);
  1107. return change;
  1108. }
  1109. /*
  1110. * CS8415A Q-Sub info
  1111. */
  1112. static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  1113. {
  1114. uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
  1115. uinfo->count = 10;
  1116. return 0;
  1117. }
  1118. static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1119. {
  1120. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1121. snd_ice1712_save_gpio_status(ice);
  1122. aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
  1123. snd_ice1712_restore_gpio_status(ice);
  1124. return 0;
  1125. }
  1126. static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  1127. {
  1128. uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
  1129. uinfo->count = 1;
  1130. return 0;
  1131. }
  1132. static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1133. {
  1134. memset(ucontrol->value.iec958.status, 0xFF, 24);
  1135. return 0;
  1136. }
  1137. static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1138. {
  1139. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1140. snd_ice1712_save_gpio_status(ice);
  1141. aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
  1142. snd_ice1712_restore_gpio_status(ice);
  1143. return 0;
  1144. }
  1145. /*
  1146. * Headphone Amplifier
  1147. */
  1148. static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
  1149. {
  1150. unsigned int tmp, tmp2;
  1151. tmp2 = tmp = snd_ice1712_gpio_read(ice);
  1152. if (enable)
  1153. if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
  1154. ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
  1155. tmp |= AUREON_HP_SEL;
  1156. else
  1157. tmp |= PRODIGY_HP_SEL;
  1158. else
  1159. if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
  1160. ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
  1161. tmp &= ~AUREON_HP_SEL;
  1162. else
  1163. tmp &= ~PRODIGY_HP_SEL;
  1164. if (tmp != tmp2) {
  1165. snd_ice1712_gpio_write(ice, tmp);
  1166. return 1;
  1167. }
  1168. return 0;
  1169. }
  1170. static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
  1171. {
  1172. unsigned int tmp = snd_ice1712_gpio_read(ice);
  1173. return (tmp & AUREON_HP_SEL) != 0;
  1174. }
  1175. #define aureon_hpamp_info snd_ctl_boolean_mono_info
  1176. static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1177. {
  1178. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1179. ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
  1180. return 0;
  1181. }
  1182. static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1183. {
  1184. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1185. return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
  1186. }
  1187. /*
  1188. * Deemphasis
  1189. */
  1190. #define aureon_deemp_info snd_ctl_boolean_mono_info
  1191. static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1192. {
  1193. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1194. ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
  1195. return 0;
  1196. }
  1197. static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1198. {
  1199. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1200. int temp, temp2;
  1201. temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
  1202. if (ucontrol->value.integer.value[0])
  1203. temp |= 0xf;
  1204. else
  1205. temp &= ~0xf;
  1206. if (temp != temp2) {
  1207. wm_put(ice, WM_DAC_CTRL2, temp);
  1208. return 1;
  1209. }
  1210. return 0;
  1211. }
  1212. /*
  1213. * ADC Oversampling
  1214. */
  1215. static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
  1216. {
  1217. static const char * const texts[2] = { "128x", "64x" };
  1218. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1219. uinfo->count = 1;
  1220. uinfo->value.enumerated.items = 2;
  1221. if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  1222. uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
  1223. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  1224. return 0;
  1225. }
  1226. static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1227. {
  1228. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1229. ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
  1230. return 0;
  1231. }
  1232. static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1233. {
  1234. int temp, temp2;
  1235. struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
  1236. temp2 = temp = wm_get(ice, WM_MASTER);
  1237. if (ucontrol->value.enumerated.item[0])
  1238. temp |= 0x8;
  1239. else
  1240. temp &= ~0x8;
  1241. if (temp != temp2) {
  1242. wm_put(ice, WM_MASTER, temp);
  1243. return 1;
  1244. }
  1245. return 0;
  1246. }
  1247. /*
  1248. * mixers
  1249. */
  1250. static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
  1251. {
  1252. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1253. .name = "Master Playback Switch",
  1254. .info = wm_master_mute_info,
  1255. .get = wm_master_mute_get,
  1256. .put = wm_master_mute_put
  1257. },
  1258. {
  1259. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1260. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1261. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1262. .name = "Master Playback Volume",
  1263. .info = wm_master_vol_info,
  1264. .get = wm_master_vol_get,
  1265. .put = wm_master_vol_put,
  1266. .tlv = { .p = db_scale_wm_dac }
  1267. },
  1268. {
  1269. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1270. .name = "Front Playback Switch",
  1271. .info = wm_mute_info,
  1272. .get = wm_mute_get,
  1273. .put = wm_mute_put,
  1274. .private_value = (2 << 8) | 0
  1275. },
  1276. {
  1277. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1278. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1279. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1280. .name = "Front Playback Volume",
  1281. .info = wm_vol_info,
  1282. .get = wm_vol_get,
  1283. .put = wm_vol_put,
  1284. .private_value = (2 << 8) | 0,
  1285. .tlv = { .p = db_scale_wm_dac }
  1286. },
  1287. {
  1288. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1289. .name = "Rear Playback Switch",
  1290. .info = wm_mute_info,
  1291. .get = wm_mute_get,
  1292. .put = wm_mute_put,
  1293. .private_value = (2 << 8) | 2
  1294. },
  1295. {
  1296. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1297. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1298. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1299. .name = "Rear Playback Volume",
  1300. .info = wm_vol_info,
  1301. .get = wm_vol_get,
  1302. .put = wm_vol_put,
  1303. .private_value = (2 << 8) | 2,
  1304. .tlv = { .p = db_scale_wm_dac }
  1305. },
  1306. {
  1307. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1308. .name = "Center Playback Switch",
  1309. .info = wm_mute_info,
  1310. .get = wm_mute_get,
  1311. .put = wm_mute_put,
  1312. .private_value = (1 << 8) | 4
  1313. },
  1314. {
  1315. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1316. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1317. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1318. .name = "Center Playback Volume",
  1319. .info = wm_vol_info,
  1320. .get = wm_vol_get,
  1321. .put = wm_vol_put,
  1322. .private_value = (1 << 8) | 4,
  1323. .tlv = { .p = db_scale_wm_dac }
  1324. },
  1325. {
  1326. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1327. .name = "LFE Playback Switch",
  1328. .info = wm_mute_info,
  1329. .get = wm_mute_get,
  1330. .put = wm_mute_put,
  1331. .private_value = (1 << 8) | 5
  1332. },
  1333. {
  1334. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1335. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1336. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1337. .name = "LFE Playback Volume",
  1338. .info = wm_vol_info,
  1339. .get = wm_vol_get,
  1340. .put = wm_vol_put,
  1341. .private_value = (1 << 8) | 5,
  1342. .tlv = { .p = db_scale_wm_dac }
  1343. },
  1344. {
  1345. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1346. .name = "Side Playback Switch",
  1347. .info = wm_mute_info,
  1348. .get = wm_mute_get,
  1349. .put = wm_mute_put,
  1350. .private_value = (2 << 8) | 6
  1351. },
  1352. {
  1353. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1354. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1355. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1356. .name = "Side Playback Volume",
  1357. .info = wm_vol_info,
  1358. .get = wm_vol_get,
  1359. .put = wm_vol_put,
  1360. .private_value = (2 << 8) | 6,
  1361. .tlv = { .p = db_scale_wm_dac }
  1362. }
  1363. };
  1364. static struct snd_kcontrol_new wm_controls[] __devinitdata = {
  1365. {
  1366. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1367. .name = "PCM Playback Switch",
  1368. .info = wm_pcm_mute_info,
  1369. .get = wm_pcm_mute_get,
  1370. .put = wm_pcm_mute_put
  1371. },
  1372. {
  1373. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1374. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1375. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1376. .name = "PCM Playback Volume",
  1377. .info = wm_pcm_vol_info,
  1378. .get = wm_pcm_vol_get,
  1379. .put = wm_pcm_vol_put,
  1380. .tlv = { .p = db_scale_wm_pcm }
  1381. },
  1382. {
  1383. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1384. .name = "Capture Switch",
  1385. .info = wm_adc_mute_info,
  1386. .get = wm_adc_mute_get,
  1387. .put = wm_adc_mute_put,
  1388. },
  1389. {
  1390. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1391. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1392. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1393. .name = "Capture Volume",
  1394. .info = wm_adc_vol_info,
  1395. .get = wm_adc_vol_get,
  1396. .put = wm_adc_vol_put,
  1397. .tlv = { .p = db_scale_wm_adc }
  1398. },
  1399. {
  1400. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1401. .name = "Capture Source",
  1402. .info = wm_adc_mux_info,
  1403. .get = wm_adc_mux_get,
  1404. .put = wm_adc_mux_put,
  1405. .private_value = 5
  1406. },
  1407. {
  1408. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1409. .name = "External Amplifier",
  1410. .info = aureon_hpamp_info,
  1411. .get = aureon_hpamp_get,
  1412. .put = aureon_hpamp_put
  1413. },
  1414. {
  1415. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1416. .name = "DAC Deemphasis Switch",
  1417. .info = aureon_deemp_info,
  1418. .get = aureon_deemp_get,
  1419. .put = aureon_deemp_put
  1420. },
  1421. {
  1422. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1423. .name = "ADC Oversampling",
  1424. .info = aureon_oversampling_info,
  1425. .get = aureon_oversampling_get,
  1426. .put = aureon_oversampling_put
  1427. }
  1428. };
  1429. static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
  1430. {
  1431. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1432. .name = "AC97 Playback Switch",
  1433. .info = aureon_ac97_mmute_info,
  1434. .get = aureon_ac97_mmute_get,
  1435. .put = aureon_ac97_mmute_put,
  1436. .private_value = AC97_MASTER
  1437. },
  1438. {
  1439. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1440. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1441. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1442. .name = "AC97 Playback Volume",
  1443. .info = aureon_ac97_vol_info,
  1444. .get = aureon_ac97_vol_get,
  1445. .put = aureon_ac97_vol_put,
  1446. .private_value = AC97_MASTER|AUREON_AC97_STEREO,
  1447. .tlv = { .p = db_scale_ac97_master }
  1448. },
  1449. {
  1450. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1451. .name = "CD Playback Switch",
  1452. .info = aureon_ac97_mute_info,
  1453. .get = aureon_ac97_mute_get,
  1454. .put = aureon_ac97_mute_put,
  1455. .private_value = AC97_CD
  1456. },
  1457. {
  1458. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1459. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1460. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1461. .name = "CD Playback Volume",
  1462. .info = aureon_ac97_vol_info,
  1463. .get = aureon_ac97_vol_get,
  1464. .put = aureon_ac97_vol_put,
  1465. .private_value = AC97_CD|AUREON_AC97_STEREO,
  1466. .tlv = { .p = db_scale_ac97_gain }
  1467. },
  1468. {
  1469. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1470. .name = "Aux Playback Switch",
  1471. .info = aureon_ac97_mute_info,
  1472. .get = aureon_ac97_mute_get,
  1473. .put = aureon_ac97_mute_put,
  1474. .private_value = AC97_AUX,
  1475. },
  1476. {
  1477. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1478. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1479. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1480. .name = "Aux Playback Volume",
  1481. .info = aureon_ac97_vol_info,
  1482. .get = aureon_ac97_vol_get,
  1483. .put = aureon_ac97_vol_put,
  1484. .private_value = AC97_AUX|AUREON_AC97_STEREO,
  1485. .tlv = { .p = db_scale_ac97_gain }
  1486. },
  1487. {
  1488. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1489. .name = "Line Playback Switch",
  1490. .info = aureon_ac97_mute_info,
  1491. .get = aureon_ac97_mute_get,
  1492. .put = aureon_ac97_mute_put,
  1493. .private_value = AC97_LINE
  1494. },
  1495. {
  1496. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1497. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1498. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1499. .name = "Line Playback Volume",
  1500. .info = aureon_ac97_vol_info,
  1501. .get = aureon_ac97_vol_get,
  1502. .put = aureon_ac97_vol_put,
  1503. .private_value = AC97_LINE|AUREON_AC97_STEREO,
  1504. .tlv = { .p = db_scale_ac97_gain }
  1505. },
  1506. {
  1507. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1508. .name = "Mic Playback Switch",
  1509. .info = aureon_ac97_mute_info,
  1510. .get = aureon_ac97_mute_get,
  1511. .put = aureon_ac97_mute_put,
  1512. .private_value = AC97_MIC
  1513. },
  1514. {
  1515. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1516. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1517. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1518. .name = "Mic Playback Volume",
  1519. .info = aureon_ac97_vol_info,
  1520. .get = aureon_ac97_vol_get,
  1521. .put = aureon_ac97_vol_put,
  1522. .private_value = AC97_MIC,
  1523. .tlv = { .p = db_scale_ac97_gain }
  1524. },
  1525. {
  1526. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1527. .name = "Mic Boost (+20dB)",
  1528. .info = aureon_ac97_micboost_info,
  1529. .get = aureon_ac97_micboost_get,
  1530. .put = aureon_ac97_micboost_put
  1531. }
  1532. };
  1533. static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
  1534. {
  1535. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1536. .name = "AC97 Playback Switch",
  1537. .info = aureon_ac97_mmute_info,
  1538. .get = aureon_ac97_mmute_get,
  1539. .put = aureon_ac97_mmute_put,
  1540. .private_value = AC97_MASTER
  1541. },
  1542. {
  1543. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1544. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1545. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1546. .name = "AC97 Playback Volume",
  1547. .info = aureon_ac97_vol_info,
  1548. .get = aureon_ac97_vol_get,
  1549. .put = aureon_ac97_vol_put,
  1550. .private_value = AC97_MASTER|AUREON_AC97_STEREO,
  1551. .tlv = { .p = db_scale_ac97_master }
  1552. },
  1553. {
  1554. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1555. .name = "CD Playback Switch",
  1556. .info = aureon_ac97_mute_info,
  1557. .get = aureon_ac97_mute_get,
  1558. .put = aureon_ac97_mute_put,
  1559. .private_value = AC97_AUX
  1560. },
  1561. {
  1562. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1563. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1564. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1565. .name = "CD Playback Volume",
  1566. .info = aureon_ac97_vol_info,
  1567. .get = aureon_ac97_vol_get,
  1568. .put = aureon_ac97_vol_put,
  1569. .private_value = AC97_AUX|AUREON_AC97_STEREO,
  1570. .tlv = { .p = db_scale_ac97_gain }
  1571. },
  1572. {
  1573. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1574. .name = "Phono Playback Switch",
  1575. .info = aureon_ac97_mute_info,
  1576. .get = aureon_ac97_mute_get,
  1577. .put = aureon_ac97_mute_put,
  1578. .private_value = AC97_CD
  1579. },
  1580. {
  1581. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1582. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1583. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1584. .name = "Phono Playback Volume",
  1585. .info = aureon_ac97_vol_info,
  1586. .get = aureon_ac97_vol_get,
  1587. .put = aureon_ac97_vol_put,
  1588. .private_value = AC97_CD|AUREON_AC97_STEREO,
  1589. .tlv = { .p = db_scale_ac97_gain }
  1590. },
  1591. {
  1592. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1593. .name = "Line Playback Switch",
  1594. .info = aureon_ac97_mute_info,
  1595. .get = aureon_ac97_mute_get,
  1596. .put = aureon_ac97_mute_put,
  1597. .private_value = AC97_LINE
  1598. },
  1599. {
  1600. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1601. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1602. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1603. .name = "Line Playback Volume",
  1604. .info = aureon_ac97_vol_info,
  1605. .get = aureon_ac97_vol_get,
  1606. .put = aureon_ac97_vol_put,
  1607. .private_value = AC97_LINE|AUREON_AC97_STEREO,
  1608. .tlv = { .p = db_scale_ac97_gain }
  1609. },
  1610. {
  1611. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1612. .name = "Mic Playback Switch",
  1613. .info = aureon_ac97_mute_info,
  1614. .get = aureon_ac97_mute_get,
  1615. .put = aureon_ac97_mute_put,
  1616. .private_value = AC97_MIC
  1617. },
  1618. {
  1619. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1620. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1621. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1622. .name = "Mic Playback Volume",
  1623. .info = aureon_ac97_vol_info,
  1624. .get = aureon_ac97_vol_get,
  1625. .put = aureon_ac97_vol_put,
  1626. .private_value = AC97_MIC,
  1627. .tlv = { .p = db_scale_ac97_gain }
  1628. },
  1629. {
  1630. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1631. .name = "Mic Boost (+20dB)",
  1632. .info = aureon_ac97_micboost_info,
  1633. .get = aureon_ac97_micboost_get,
  1634. .put = aureon_ac97_micboost_put
  1635. },
  1636. {
  1637. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1638. .name = "Aux Playback Switch",
  1639. .info = aureon_ac97_mute_info,
  1640. .get = aureon_ac97_mute_get,
  1641. .put = aureon_ac97_mute_put,
  1642. .private_value = AC97_VIDEO,
  1643. },
  1644. {
  1645. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1646. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  1647. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  1648. .name = "Aux Playback Volume",
  1649. .info = aureon_ac97_vol_info,
  1650. .get = aureon_ac97_vol_get,
  1651. .put = aureon_ac97_vol_put,
  1652. .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
  1653. .tlv = { .p = db_scale_ac97_gain }
  1654. },
  1655. {
  1656. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1657. .name = "Aux Source",
  1658. .info = aureon_universe_inmux_info,
  1659. .get = aureon_universe_inmux_get,
  1660. .put = aureon_universe_inmux_put
  1661. }
  1662. };
  1663. static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
  1664. {
  1665. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1666. .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
  1667. .info = aureon_cs8415_mute_info,
  1668. .get = aureon_cs8415_mute_get,
  1669. .put = aureon_cs8415_mute_put
  1670. },
  1671. {
  1672. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1673. .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
  1674. .info = aureon_cs8415_mux_info,
  1675. .get = aureon_cs8415_mux_get,
  1676. .put = aureon_cs8415_mux_put,
  1677. },
  1678. {
  1679. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  1680. .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
  1681. .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  1682. .info = aureon_cs8415_qsub_info,
  1683. .get = aureon_cs8415_qsub_get,
  1684. },
  1685. {
  1686. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  1687. .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
  1688. .access = SNDRV_CTL_ELEM_ACCESS_READ,
  1689. .info = aureon_cs8415_spdif_info,
  1690. .get = aureon_cs8415_mask_get
  1691. },
  1692. {
  1693. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  1694. .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
  1695. .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  1696. .info = aureon_cs8415_spdif_info,
  1697. .get = aureon_cs8415_spdif_get
  1698. },
  1699. {
  1700. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  1701. .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
  1702. .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  1703. .info = aureon_cs8415_rate_info,
  1704. .get = aureon_cs8415_rate_get
  1705. }
  1706. };
  1707. static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
  1708. {
  1709. unsigned int i, counts;
  1710. int err;
  1711. counts = ARRAY_SIZE(aureon_dac_controls);
  1712. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
  1713. counts -= 2; /* no side */
  1714. for (i = 0; i < counts; i++) {
  1715. err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
  1716. if (err < 0)
  1717. return err;
  1718. }
  1719. for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
  1720. err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
  1721. if (err < 0)
  1722. return err;
  1723. }
  1724. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
  1725. for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
  1726. err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
  1727. if (err < 0)
  1728. return err;
  1729. }
  1730. } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
  1731. ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
  1732. for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
  1733. err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
  1734. if (err < 0)
  1735. return err;
  1736. }
  1737. }
  1738. if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
  1739. ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
  1740. unsigned char id;
  1741. snd_ice1712_save_gpio_status(ice);
  1742. id = aureon_cs8415_get(ice, CS8415_ID);
  1743. if (id != 0x41)
  1744. snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
  1745. else if ((id & 0x0F) != 0x01)
  1746. snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
  1747. else {
  1748. for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
  1749. struct snd_kcontrol *kctl;
  1750. err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
  1751. if (err < 0)
  1752. return err;
  1753. if (i > 1)
  1754. kctl->id.device = ice->pcm->device;
  1755. }
  1756. }
  1757. snd_ice1712_restore_gpio_status(ice);
  1758. }
  1759. return 0;
  1760. }
  1761. /*
  1762. * initialize the chip
  1763. */
  1764. static int __devinit aureon_init(struct snd_ice1712 *ice)
  1765. {
  1766. static const unsigned short wm_inits_aureon[] = {
  1767. /* These come first to reduce init pop noise */
  1768. 0x1b, 0x044, /* ADC Mux (AC'97 source) */
  1769. 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
  1770. 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
  1771. 0x18, 0x000, /* All power-up */
  1772. 0x16, 0x122, /* I2S, normal polarity, 24bit */
  1773. 0x17, 0x022, /* 256fs, slave mode */
  1774. 0x00, 0, /* DAC1 analog mute */
  1775. 0x01, 0, /* DAC2 analog mute */
  1776. 0x02, 0, /* DAC3 analog mute */
  1777. 0x03, 0, /* DAC4 analog mute */
  1778. 0x04, 0, /* DAC5 analog mute */
  1779. 0x05, 0, /* DAC6 analog mute */
  1780. 0x06, 0, /* DAC7 analog mute */
  1781. 0x07, 0, /* DAC8 analog mute */
  1782. 0x08, 0x100, /* master analog mute */
  1783. 0x09, 0xff, /* DAC1 digital full */
  1784. 0x0a, 0xff, /* DAC2 digital full */
  1785. 0x0b, 0xff, /* DAC3 digital full */
  1786. 0x0c, 0xff, /* DAC4 digital full */
  1787. 0x0d, 0xff, /* DAC5 digital full */
  1788. 0x0e, 0xff, /* DAC6 digital full */
  1789. 0x0f, 0xff, /* DAC7 digital full */
  1790. 0x10, 0xff, /* DAC8 digital full */
  1791. 0x11, 0x1ff, /* master digital full */
  1792. 0x12, 0x000, /* phase normal */
  1793. 0x13, 0x090, /* unmute DAC L/R */
  1794. 0x14, 0x000, /* all unmute */
  1795. 0x15, 0x000, /* no deemphasis, no ZFLG */
  1796. 0x19, 0x000, /* -12dB ADC/L */
  1797. 0x1a, 0x000, /* -12dB ADC/R */
  1798. (unsigned short)-1
  1799. };
  1800. static const unsigned short wm_inits_prodigy[] = {
  1801. /* These come first to reduce init pop noise */
  1802. 0x1b, 0x000, /* ADC Mux */
  1803. 0x1c, 0x009, /* Out Mux1 */
  1804. 0x1d, 0x009, /* Out Mux2 */
  1805. 0x18, 0x000, /* All power-up */
  1806. 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
  1807. 0x17, 0x006, /* 128fs, slave mode */
  1808. 0x00, 0, /* DAC1 analog mute */
  1809. 0x01, 0, /* DAC2 analog mute */
  1810. 0x02, 0, /* DAC3 analog mute */
  1811. 0x03, 0, /* DAC4 analog mute */
  1812. 0x04, 0, /* DAC5 analog mute */
  1813. 0x05, 0, /* DAC6 analog mute */
  1814. 0x06, 0, /* DAC7 analog mute */
  1815. 0x07, 0, /* DAC8 analog mute */
  1816. 0x08, 0x100, /* master analog mute */
  1817. 0x09, 0x7f, /* DAC1 digital full */
  1818. 0x0a, 0x7f, /* DAC2 digital full */
  1819. 0x0b, 0x7f, /* DAC3 digital full */
  1820. 0x0c, 0x7f, /* DAC4 digital full */
  1821. 0x0d, 0x7f, /* DAC5 digital full */
  1822. 0x0e, 0x7f, /* DAC6 digital full */
  1823. 0x0f, 0x7f, /* DAC7 digital full */
  1824. 0x10, 0x7f, /* DAC8 digital full */
  1825. 0x11, 0x1FF, /* master digital full */
  1826. 0x12, 0x000, /* phase normal */
  1827. 0x13, 0x090, /* unmute DAC L/R */
  1828. 0x14, 0x000, /* all unmute */
  1829. 0x15, 0x000, /* no deemphasis, no ZFLG */
  1830. 0x19, 0x000, /* -12dB ADC/L */
  1831. 0x1a, 0x000, /* -12dB ADC/R */
  1832. (unsigned short)-1
  1833. };
  1834. static const unsigned short cs_inits[] = {
  1835. 0x0441, /* RUN */
  1836. 0x0180, /* no mute, OMCK output on RMCK pin */
  1837. 0x0201, /* S/PDIF source on RXP1 */
  1838. 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
  1839. (unsigned short)-1
  1840. };
  1841. struct aureon_spec *spec;
  1842. unsigned int tmp;
  1843. const unsigned short *p;
  1844. int err, i;
  1845. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1846. if (!spec)
  1847. return -ENOMEM;
  1848. ice->spec = spec;
  1849. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
  1850. ice->num_total_dacs = 6;
  1851. ice->num_total_adcs = 2;
  1852. } else {
  1853. /* aureon 7.1 and prodigy 7.1 */
  1854. ice->num_total_dacs = 8;
  1855. ice->num_total_adcs = 2;
  1856. }
  1857. /* to remeber the register values of CS8415 */
  1858. ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
  1859. if (!ice->akm)
  1860. return -ENOMEM;
  1861. ice->akm_codecs = 1;
  1862. err = aureon_ac97_init(ice);
  1863. if (err != 0)
  1864. return err;
  1865. snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
  1866. /* reset the wm codec as the SPI mode */
  1867. snd_ice1712_save_gpio_status(ice);
  1868. snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
  1869. tmp = snd_ice1712_gpio_read(ice);
  1870. tmp &= ~AUREON_WM_RESET;
  1871. snd_ice1712_gpio_write(ice, tmp);
  1872. udelay(1);
  1873. tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
  1874. snd_ice1712_gpio_write(ice, tmp);
  1875. udelay(1);
  1876. tmp |= AUREON_WM_RESET;
  1877. snd_ice1712_gpio_write(ice, tmp);
  1878. udelay(1);
  1879. /* initialize WM8770 codec */
  1880. if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
  1881. ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
  1882. ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
  1883. p = wm_inits_prodigy;
  1884. else
  1885. p = wm_inits_aureon;
  1886. for (; *p != (unsigned short)-1; p += 2)
  1887. wm_put(ice, p[0], p[1]);
  1888. /* initialize CS8415A codec */
  1889. if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
  1890. ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
  1891. for (p = cs_inits; *p != (unsigned short)-1; p++)
  1892. aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
  1893. spec->cs8415_mux = 1;
  1894. aureon_set_headphone_amp(ice, 1);
  1895. }
  1896. snd_ice1712_restore_gpio_status(ice);
  1897. /* initialize PCA9554 pin directions & set default input */
  1898. aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
  1899. aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
  1900. spec->master[0] = WM_VOL_MUTE;
  1901. spec->master[1] = WM_VOL_MUTE;
  1902. for (i = 0; i < ice->num_total_dacs; i++) {
  1903. spec->vol[i] = WM_VOL_MUTE;
  1904. wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
  1905. }
  1906. return 0;
  1907. }
  1908. /*
  1909. * Aureon boards don't provide the EEPROM data except for the vendor IDs.
  1910. * hence the driver needs to sets up it properly.
  1911. */
  1912. static unsigned char aureon51_eeprom[] __devinitdata = {
  1913. [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
  1914. [ICE_EEP2_ACLINK] = 0x80, /* I2S */
  1915. [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
  1916. [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
  1917. [ICE_EEP2_GPIO_DIR] = 0xff,
  1918. [ICE_EEP2_GPIO_DIR1] = 0xff,
  1919. [ICE_EEP2_GPIO_DIR2] = 0x5f,
  1920. [ICE_EEP2_GPIO_MASK] = 0x00,
  1921. [ICE_EEP2_GPIO_MASK1] = 0x00,
  1922. [ICE_EEP2_GPIO_MASK2] = 0x00,
  1923. [ICE_EEP2_GPIO_STATE] = 0x00,
  1924. [ICE_EEP2_GPIO_STATE1] = 0x00,
  1925. [ICE_EEP2_GPIO_STATE2] = 0x00,
  1926. };
  1927. static unsigned char aureon71_eeprom[] __devinitdata = {
  1928. [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
  1929. [ICE_EEP2_ACLINK] = 0x80, /* I2S */
  1930. [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
  1931. [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
  1932. [ICE_EEP2_GPIO_DIR] = 0xff,
  1933. [ICE_EEP2_GPIO_DIR1] = 0xff,
  1934. [ICE_EEP2_GPIO_DIR2] = 0x5f,
  1935. [ICE_EEP2_GPIO_MASK] = 0x00,
  1936. [ICE_EEP2_GPIO_MASK1] = 0x00,
  1937. [ICE_EEP2_GPIO_MASK2] = 0x00,
  1938. [ICE_EEP2_GPIO_STATE] = 0x00,
  1939. [ICE_EEP2_GPIO_STATE1] = 0x00,
  1940. [ICE_EEP2_GPIO_STATE2] = 0x00,
  1941. };
  1942. #define prodigy71_eeprom aureon71_eeprom
  1943. static unsigned char aureon71_universe_eeprom[] __devinitdata = {
  1944. [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
  1945. * 4DACs
  1946. */
  1947. [ICE_EEP2_ACLINK] = 0x80, /* I2S */
  1948. [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
  1949. [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
  1950. [ICE_EEP2_GPIO_DIR] = 0xff,
  1951. [ICE_EEP2_GPIO_DIR1] = 0xff,
  1952. [ICE_EEP2_GPIO_DIR2] = 0x5f,
  1953. [ICE_EEP2_GPIO_MASK] = 0x00,
  1954. [ICE_EEP2_GPIO_MASK1] = 0x00,
  1955. [ICE_EEP2_GPIO_MASK2] = 0x00,
  1956. [ICE_EEP2_GPIO_STATE] = 0x00,
  1957. [ICE_EEP2_GPIO_STATE1] = 0x00,
  1958. [ICE_EEP2_GPIO_STATE2] = 0x00,
  1959. };
  1960. static unsigned char prodigy71lt_eeprom[] __devinitdata = {
  1961. [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
  1962. [ICE_EEP2_ACLINK] = 0x80, /* I2S */
  1963. [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
  1964. [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
  1965. [ICE_EEP2_GPIO_DIR] = 0xff,
  1966. [ICE_EEP2_GPIO_DIR1] = 0xff,
  1967. [ICE_EEP2_GPIO_DIR2] = 0x5f,
  1968. [ICE_EEP2_GPIO_MASK] = 0x00,
  1969. [ICE_EEP2_GPIO_MASK1] = 0x00,
  1970. [ICE_EEP2_GPIO_MASK2] = 0x00,
  1971. [ICE_EEP2_GPIO_STATE] = 0x00,
  1972. [ICE_EEP2_GPIO_STATE1] = 0x00,
  1973. [ICE_EEP2_GPIO_STATE2] = 0x00,
  1974. };
  1975. #define prodigy71xt_eeprom prodigy71lt_eeprom
  1976. /* entry point */
  1977. struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
  1978. {
  1979. .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
  1980. .name = "Terratec Aureon 5.1-Sky",
  1981. .model = "aureon51",
  1982. .chip_init = aureon_init,
  1983. .build_controls = aureon_add_controls,
  1984. .eeprom_size = sizeof(aureon51_eeprom),
  1985. .eeprom_data = aureon51_eeprom,
  1986. .driver = "Aureon51",
  1987. },
  1988. {
  1989. .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
  1990. .name = "Terratec Aureon 7.1-Space",
  1991. .model = "aureon71",
  1992. .chip_init = aureon_init,
  1993. .build_controls = aureon_add_controls,
  1994. .eeprom_size = sizeof(aureon71_eeprom),
  1995. .eeprom_data = aureon71_eeprom,
  1996. .driver = "Aureon71",
  1997. },
  1998. {
  1999. .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
  2000. .name = "Terratec Aureon 7.1-Universe",
  2001. .model = "universe",
  2002. .chip_init = aureon_init,
  2003. .build_controls = aureon_add_controls,
  2004. .eeprom_size = sizeof(aureon71_universe_eeprom),
  2005. .eeprom_data = aureon71_universe_eeprom,
  2006. .driver = "Aureon71Univ", /* keep in 15 letters */
  2007. },
  2008. {
  2009. .subvendor = VT1724_SUBDEVICE_PRODIGY71,
  2010. .name = "Audiotrak Prodigy 7.1",
  2011. .model = "prodigy71",
  2012. .chip_init = aureon_init,
  2013. .build_controls = aureon_add_controls,
  2014. .eeprom_size = sizeof(prodigy71_eeprom),
  2015. .eeprom_data = prodigy71_eeprom,
  2016. .driver = "Prodigy71", /* should be identical with Aureon71 */
  2017. },
  2018. {
  2019. .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
  2020. .name = "Audiotrak Prodigy 7.1 LT",
  2021. .model = "prodigy71lt",
  2022. .chip_init = aureon_init,
  2023. .build_controls = aureon_add_controls,
  2024. .eeprom_size = sizeof(prodigy71lt_eeprom),
  2025. .eeprom_data = prodigy71lt_eeprom,
  2026. .driver = "Prodigy71LT",
  2027. },
  2028. {
  2029. .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
  2030. .name = "Audiotrak Prodigy 7.1 XT",
  2031. .model = "prodigy71xt",
  2032. .chip_init = aureon_init,
  2033. .build_controls = aureon_add_controls,
  2034. .eeprom_size = sizeof(prodigy71xt_eeprom),
  2035. .eeprom_data = prodigy71xt_eeprom,
  2036. .driver = "Prodigy71LT",
  2037. },
  2038. { } /* terminator */
  2039. };