patch_via.c 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920
  1. /*
  2. * Universal Interface for Intel High Definition Audio Codec
  3. *
  4. * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec
  5. *
  6. * Copyright (c) 2006-2008 Lydia Wang <lydiawang@viatech.com>
  7. * Takashi Iwai <tiwai@suse.de>
  8. *
  9. * This driver 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 driver 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. /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
  24. /* */
  25. /* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
  26. /* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
  27. /* 2006-08-02 Lydia Wang Add support to VT1709 codec */
  28. /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
  29. /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
  30. /* 2007-09-17 Lydia Wang Add VT1708B codec support */
  31. /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
  32. /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
  33. /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
  34. /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
  35. /* */
  36. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  37. #include <linux/init.h>
  38. #include <linux/delay.h>
  39. #include <linux/slab.h>
  40. #include <sound/core.h>
  41. #include "hda_codec.h"
  42. #include "hda_local.h"
  43. #include "hda_patch.h"
  44. /* amp values */
  45. #define AMP_VAL_IDX_SHIFT 19
  46. #define AMP_VAL_IDX_MASK (0x0f<<19)
  47. #define NUM_CONTROL_ALLOC 32
  48. #define NUM_VERB_ALLOC 32
  49. /* Pin Widget NID */
  50. #define VT1708_HP_NID 0x13
  51. #define VT1708_DIGOUT_NID 0x14
  52. #define VT1708_DIGIN_NID 0x16
  53. #define VT1708_DIGIN_PIN 0x26
  54. #define VT1708_HP_PIN_NID 0x20
  55. #define VT1708_CD_PIN_NID 0x24
  56. #define VT1709_HP_DAC_NID 0x28
  57. #define VT1709_DIGOUT_NID 0x13
  58. #define VT1709_DIGIN_NID 0x17
  59. #define VT1709_DIGIN_PIN 0x25
  60. #define VT1708B_HP_NID 0x25
  61. #define VT1708B_DIGOUT_NID 0x12
  62. #define VT1708B_DIGIN_NID 0x15
  63. #define VT1708B_DIGIN_PIN 0x21
  64. #define VT1708S_HP_NID 0x25
  65. #define VT1708S_DIGOUT_NID 0x12
  66. #define VT1702_HP_NID 0x17
  67. #define VT1702_DIGOUT_NID 0x11
  68. #define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
  69. #define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
  70. #define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
  71. #define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723)
  72. #define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727)
  73. #define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397)
  74. #define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398)
  75. #define VIA_HP_EVENT 0x01
  76. #define VIA_GPIO_EVENT 0x02
  77. enum {
  78. VIA_CTL_WIDGET_VOL,
  79. VIA_CTL_WIDGET_MUTE,
  80. };
  81. enum {
  82. AUTO_SEQ_FRONT = 0,
  83. AUTO_SEQ_SURROUND,
  84. AUTO_SEQ_CENLFE,
  85. AUTO_SEQ_SIDE
  86. };
  87. static struct snd_kcontrol_new vt1708_control_templates[] = {
  88. HDA_CODEC_VOLUME(NULL, 0, 0, 0),
  89. HDA_CODEC_MUTE(NULL, 0, 0, 0),
  90. };
  91. struct via_spec {
  92. /* codec parameterization */
  93. struct snd_kcontrol_new *mixers[3];
  94. unsigned int num_mixers;
  95. struct hda_verb *init_verbs[5];
  96. unsigned int num_iverbs;
  97. char *stream_name_analog;
  98. struct hda_pcm_stream *stream_analog_playback;
  99. struct hda_pcm_stream *stream_analog_capture;
  100. char *stream_name_digital;
  101. struct hda_pcm_stream *stream_digital_playback;
  102. struct hda_pcm_stream *stream_digital_capture;
  103. /* playback */
  104. struct hda_multi_out multiout;
  105. /* capture */
  106. unsigned int num_adc_nids;
  107. hda_nid_t *adc_nids;
  108. hda_nid_t dig_in_nid;
  109. /* capture source */
  110. const struct hda_input_mux *input_mux;
  111. unsigned int cur_mux[3];
  112. /* PCM information */
  113. struct hda_pcm pcm_rec[2];
  114. /* dynamic controls, init_verbs and input_mux */
  115. struct auto_pin_cfg autocfg;
  116. unsigned int num_kctl_alloc, num_kctl_used;
  117. struct snd_kcontrol_new *kctl_alloc;
  118. struct hda_input_mux private_imux;
  119. hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  120. #ifdef CONFIG_SND_HDA_POWER_SAVE
  121. struct hda_loopback_check loopback;
  122. #endif
  123. };
  124. static hda_nid_t vt1708_adc_nids[2] = {
  125. /* ADC1-2 */
  126. 0x15, 0x27
  127. };
  128. static hda_nid_t vt1709_adc_nids[3] = {
  129. /* ADC1-2 */
  130. 0x14, 0x15, 0x16
  131. };
  132. static hda_nid_t vt1708B_adc_nids[2] = {
  133. /* ADC1-2 */
  134. 0x13, 0x14
  135. };
  136. static hda_nid_t vt1708S_adc_nids[2] = {
  137. /* ADC1-2 */
  138. 0x13, 0x14
  139. };
  140. static hda_nid_t vt1702_adc_nids[3] = {
  141. /* ADC1-2 */
  142. 0x12, 0x20, 0x1F
  143. };
  144. /* add dynamic controls */
  145. static int via_add_control(struct via_spec *spec, int type, const char *name,
  146. unsigned long val)
  147. {
  148. struct snd_kcontrol_new *knew;
  149. if (spec->num_kctl_used >= spec->num_kctl_alloc) {
  150. int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
  151. /* array + terminator */
  152. knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
  153. if (!knew)
  154. return -ENOMEM;
  155. if (spec->kctl_alloc) {
  156. memcpy(knew, spec->kctl_alloc,
  157. sizeof(*knew) * spec->num_kctl_alloc);
  158. kfree(spec->kctl_alloc);
  159. }
  160. spec->kctl_alloc = knew;
  161. spec->num_kctl_alloc = num;
  162. }
  163. knew = &spec->kctl_alloc[spec->num_kctl_used];
  164. *knew = vt1708_control_templates[type];
  165. knew->name = kstrdup(name, GFP_KERNEL);
  166. if (!knew->name)
  167. return -ENOMEM;
  168. knew->private_value = val;
  169. spec->num_kctl_used++;
  170. return 0;
  171. }
  172. /* create input playback/capture controls for the given pin */
  173. static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
  174. const char *ctlname, int idx, int mix_nid)
  175. {
  176. char name[32];
  177. int err;
  178. sprintf(name, "%s Playback Volume", ctlname);
  179. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  180. HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
  181. if (err < 0)
  182. return err;
  183. sprintf(name, "%s Playback Switch", ctlname);
  184. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  185. HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
  186. if (err < 0)
  187. return err;
  188. return 0;
  189. }
  190. static void via_auto_set_output_and_unmute(struct hda_codec *codec,
  191. hda_nid_t nid, int pin_type,
  192. int dac_idx)
  193. {
  194. /* set as output */
  195. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  196. pin_type);
  197. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  198. AMP_OUT_UNMUTE);
  199. }
  200. static void via_auto_init_multi_out(struct hda_codec *codec)
  201. {
  202. struct via_spec *spec = codec->spec;
  203. int i;
  204. for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
  205. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  206. if (nid)
  207. via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
  208. }
  209. }
  210. static void via_auto_init_hp_out(struct hda_codec *codec)
  211. {
  212. struct via_spec *spec = codec->spec;
  213. hda_nid_t pin;
  214. pin = spec->autocfg.hp_pins[0];
  215. if (pin) /* connect to front */
  216. via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  217. }
  218. static void via_auto_init_analog_input(struct hda_codec *codec)
  219. {
  220. struct via_spec *spec = codec->spec;
  221. int i;
  222. for (i = 0; i < AUTO_PIN_LAST; i++) {
  223. hda_nid_t nid = spec->autocfg.input_pins[i];
  224. snd_hda_codec_write(codec, nid, 0,
  225. AC_VERB_SET_PIN_WIDGET_CONTROL,
  226. (i <= AUTO_PIN_FRONT_MIC ?
  227. PIN_VREF50 : PIN_IN));
  228. }
  229. }
  230. /*
  231. * input MUX handling
  232. */
  233. static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
  234. struct snd_ctl_elem_info *uinfo)
  235. {
  236. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  237. struct via_spec *spec = codec->spec;
  238. return snd_hda_input_mux_info(spec->input_mux, uinfo);
  239. }
  240. static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
  241. struct snd_ctl_elem_value *ucontrol)
  242. {
  243. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  244. struct via_spec *spec = codec->spec;
  245. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  246. ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  247. return 0;
  248. }
  249. static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
  250. struct snd_ctl_elem_value *ucontrol)
  251. {
  252. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  253. struct via_spec *spec = codec->spec;
  254. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  255. unsigned int vendor_id = codec->vendor_id;
  256. /* AIW0 lydia 060801 add for correct sw0 input select */
  257. if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
  258. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  259. 0x18, &spec->cur_mux[adc_idx]);
  260. else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
  261. IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0))
  262. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  263. 0x19, &spec->cur_mux[adc_idx]);
  264. else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
  265. IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0))
  266. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  267. 0x17, &spec->cur_mux[adc_idx]);
  268. else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0))
  269. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  270. 0x13, &spec->cur_mux[adc_idx]);
  271. else
  272. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  273. spec->adc_nids[adc_idx],
  274. &spec->cur_mux[adc_idx]);
  275. }
  276. /* capture mixer elements */
  277. static struct snd_kcontrol_new vt1708_capture_mixer[] = {
  278. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
  279. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
  280. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
  281. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
  282. {
  283. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  284. /* The multiple "Capture Source" controls confuse alsamixer
  285. * So call somewhat different..
  286. */
  287. /* .name = "Capture Source", */
  288. .name = "Input Source",
  289. .count = 1,
  290. .info = via_mux_enum_info,
  291. .get = via_mux_enum_get,
  292. .put = via_mux_enum_put,
  293. },
  294. { } /* end */
  295. };
  296. /*
  297. * generic initialization of ADC, input mixers and output mixers
  298. */
  299. static struct hda_verb vt1708_volume_init_verbs[] = {
  300. /*
  301. * Unmute ADC0-1 and set the default input to mic-in
  302. */
  303. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  304. {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  305. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  306. * mixer widget
  307. */
  308. /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
  309. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  310. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  311. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  312. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  313. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  314. /*
  315. * Set up output mixers (0x19 - 0x1b)
  316. */
  317. /* set vol=0 to output mixers */
  318. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  319. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  320. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  321. /* Setup default input to PW4 */
  322. {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
  323. /* PW9 Output enable */
  324. {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  325. { }
  326. };
  327. static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
  328. struct hda_codec *codec,
  329. struct snd_pcm_substream *substream)
  330. {
  331. struct via_spec *spec = codec->spec;
  332. return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
  333. hinfo);
  334. }
  335. static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  336. struct hda_codec *codec,
  337. unsigned int stream_tag,
  338. unsigned int format,
  339. struct snd_pcm_substream *substream)
  340. {
  341. struct via_spec *spec = codec->spec;
  342. return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
  343. stream_tag, format, substream);
  344. }
  345. static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  346. struct hda_codec *codec,
  347. struct snd_pcm_substream *substream)
  348. {
  349. struct via_spec *spec = codec->spec;
  350. return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
  351. }
  352. /*
  353. * Digital out
  354. */
  355. static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
  356. struct hda_codec *codec,
  357. struct snd_pcm_substream *substream)
  358. {
  359. struct via_spec *spec = codec->spec;
  360. return snd_hda_multi_out_dig_open(codec, &spec->multiout);
  361. }
  362. static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
  363. struct hda_codec *codec,
  364. struct snd_pcm_substream *substream)
  365. {
  366. struct via_spec *spec = codec->spec;
  367. return snd_hda_multi_out_dig_close(codec, &spec->multiout);
  368. }
  369. static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  370. struct hda_codec *codec,
  371. unsigned int stream_tag,
  372. unsigned int format,
  373. struct snd_pcm_substream *substream)
  374. {
  375. struct via_spec *spec = codec->spec;
  376. return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
  377. stream_tag, format, substream);
  378. }
  379. /*
  380. * Analog capture
  381. */
  382. static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
  383. struct hda_codec *codec,
  384. unsigned int stream_tag,
  385. unsigned int format,
  386. struct snd_pcm_substream *substream)
  387. {
  388. struct via_spec *spec = codec->spec;
  389. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  390. stream_tag, 0, format);
  391. return 0;
  392. }
  393. static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
  394. struct hda_codec *codec,
  395. struct snd_pcm_substream *substream)
  396. {
  397. struct via_spec *spec = codec->spec;
  398. snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
  399. return 0;
  400. }
  401. static struct hda_pcm_stream vt1708_pcm_analog_playback = {
  402. .substreams = 1,
  403. .channels_min = 2,
  404. .channels_max = 8,
  405. .nid = 0x10, /* NID to query formats and rates */
  406. .ops = {
  407. .open = via_playback_pcm_open,
  408. .prepare = via_playback_pcm_prepare,
  409. .cleanup = via_playback_pcm_cleanup
  410. },
  411. };
  412. static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
  413. .substreams = 1,
  414. .channels_min = 2,
  415. .channels_max = 8,
  416. .nid = 0x10, /* NID to query formats and rates */
  417. /* We got noisy outputs on the right channel on VT1708 when
  418. * 24bit samples are used. Until any workaround is found,
  419. * disable the 24bit format, so far.
  420. */
  421. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  422. .ops = {
  423. .open = via_playback_pcm_open,
  424. .prepare = via_playback_pcm_prepare,
  425. .cleanup = via_playback_pcm_cleanup
  426. },
  427. };
  428. static struct hda_pcm_stream vt1708_pcm_analog_capture = {
  429. .substreams = 2,
  430. .channels_min = 2,
  431. .channels_max = 2,
  432. .nid = 0x15, /* NID to query formats and rates */
  433. .ops = {
  434. .prepare = via_capture_pcm_prepare,
  435. .cleanup = via_capture_pcm_cleanup
  436. },
  437. };
  438. static struct hda_pcm_stream vt1708_pcm_digital_playback = {
  439. .substreams = 1,
  440. .channels_min = 2,
  441. .channels_max = 2,
  442. /* NID is set in via_build_pcms */
  443. .ops = {
  444. .open = via_dig_playback_pcm_open,
  445. .close = via_dig_playback_pcm_close,
  446. .prepare = via_dig_playback_pcm_prepare
  447. },
  448. };
  449. static struct hda_pcm_stream vt1708_pcm_digital_capture = {
  450. .substreams = 1,
  451. .channels_min = 2,
  452. .channels_max = 2,
  453. };
  454. static int via_build_controls(struct hda_codec *codec)
  455. {
  456. struct via_spec *spec = codec->spec;
  457. int err;
  458. int i;
  459. for (i = 0; i < spec->num_mixers; i++) {
  460. err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  461. if (err < 0)
  462. return err;
  463. }
  464. if (spec->multiout.dig_out_nid) {
  465. err = snd_hda_create_spdif_out_ctls(codec,
  466. spec->multiout.dig_out_nid);
  467. if (err < 0)
  468. return err;
  469. err = snd_hda_create_spdif_share_sw(codec,
  470. &spec->multiout);
  471. if (err < 0)
  472. return err;
  473. spec->multiout.share_spdif = 1;
  474. }
  475. if (spec->dig_in_nid) {
  476. err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
  477. if (err < 0)
  478. return err;
  479. }
  480. return 0;
  481. }
  482. static int via_build_pcms(struct hda_codec *codec)
  483. {
  484. struct via_spec *spec = codec->spec;
  485. struct hda_pcm *info = spec->pcm_rec;
  486. codec->num_pcms = 1;
  487. codec->pcm_info = info;
  488. info->name = spec->stream_name_analog;
  489. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
  490. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
  491. info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
  492. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
  493. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
  494. spec->multiout.max_channels;
  495. if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
  496. codec->num_pcms++;
  497. info++;
  498. info->name = spec->stream_name_digital;
  499. info->pcm_type = HDA_PCM_TYPE_SPDIF;
  500. if (spec->multiout.dig_out_nid) {
  501. info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
  502. *(spec->stream_digital_playback);
  503. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
  504. spec->multiout.dig_out_nid;
  505. }
  506. if (spec->dig_in_nid) {
  507. info->stream[SNDRV_PCM_STREAM_CAPTURE] =
  508. *(spec->stream_digital_capture);
  509. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
  510. spec->dig_in_nid;
  511. }
  512. }
  513. return 0;
  514. }
  515. static void via_free(struct hda_codec *codec)
  516. {
  517. struct via_spec *spec = codec->spec;
  518. unsigned int i;
  519. if (!spec)
  520. return;
  521. if (spec->kctl_alloc) {
  522. for (i = 0; i < spec->num_kctl_used; i++)
  523. kfree(spec->kctl_alloc[i].name);
  524. kfree(spec->kctl_alloc);
  525. }
  526. kfree(codec->spec);
  527. }
  528. /* mute internal speaker if HP is plugged */
  529. static void via_hp_automute(struct hda_codec *codec)
  530. {
  531. unsigned int present;
  532. struct via_spec *spec = codec->spec;
  533. present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
  534. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  535. snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
  536. HDA_OUTPUT, 0, HDA_AMP_MUTE,
  537. present ? HDA_AMP_MUTE : 0);
  538. }
  539. static void via_gpio_control(struct hda_codec *codec)
  540. {
  541. unsigned int gpio_data;
  542. unsigned int vol_counter;
  543. unsigned int vol;
  544. unsigned int master_vol;
  545. struct via_spec *spec = codec->spec;
  546. gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
  547. AC_VERB_GET_GPIO_DATA, 0) & 0x03;
  548. vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
  549. 0xF84, 0) & 0x3F0000) >> 16;
  550. vol = vol_counter & 0x1F;
  551. master_vol = snd_hda_codec_read(codec, 0x1A, 0,
  552. AC_VERB_GET_AMP_GAIN_MUTE,
  553. AC_AMP_GET_INPUT);
  554. if (gpio_data == 0x02) {
  555. /* unmute line out */
  556. snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
  557. HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
  558. if (vol_counter & 0x20) {
  559. /* decrease volume */
  560. if (vol > master_vol)
  561. vol = master_vol;
  562. snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
  563. 0, HDA_AMP_VOLMASK,
  564. master_vol-vol);
  565. } else {
  566. /* increase volume */
  567. snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
  568. HDA_AMP_VOLMASK,
  569. ((master_vol+vol) > 0x2A) ? 0x2A :
  570. (master_vol+vol));
  571. }
  572. } else if (!(gpio_data & 0x02)) {
  573. /* mute line out */
  574. snd_hda_codec_amp_stereo(codec,
  575. spec->autocfg.line_out_pins[0],
  576. HDA_OUTPUT, 0, HDA_AMP_MUTE,
  577. HDA_AMP_MUTE);
  578. }
  579. }
  580. /* unsolicited event for jack sensing */
  581. static void via_unsol_event(struct hda_codec *codec,
  582. unsigned int res)
  583. {
  584. res >>= 26;
  585. if (res == VIA_HP_EVENT)
  586. via_hp_automute(codec);
  587. else if (res == VIA_GPIO_EVENT)
  588. via_gpio_control(codec);
  589. }
  590. static int via_init(struct hda_codec *codec)
  591. {
  592. struct via_spec *spec = codec->spec;
  593. int i;
  594. for (i = 0; i < spec->num_iverbs; i++)
  595. snd_hda_sequence_write(codec, spec->init_verbs[i]);
  596. /* Lydia Add for EAPD enable */
  597. if (!spec->dig_in_nid) { /* No Digital In connection */
  598. if (IS_VT1708_VENDORID(codec->vendor_id)) {
  599. snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
  600. AC_VERB_SET_PIN_WIDGET_CONTROL,
  601. PIN_OUT);
  602. snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
  603. AC_VERB_SET_EAPD_BTLENABLE, 0x02);
  604. } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) ||
  605. IS_VT1709_6CH_VENDORID(codec->vendor_id)) {
  606. snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
  607. AC_VERB_SET_PIN_WIDGET_CONTROL,
  608. PIN_OUT);
  609. snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
  610. AC_VERB_SET_EAPD_BTLENABLE, 0x02);
  611. } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) ||
  612. IS_VT1708B_4CH_VENDORID(codec->vendor_id)) {
  613. snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
  614. AC_VERB_SET_PIN_WIDGET_CONTROL,
  615. PIN_OUT);
  616. snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
  617. AC_VERB_SET_EAPD_BTLENABLE, 0x02);
  618. }
  619. } else /* enable SPDIF-input pin */
  620. snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
  621. AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
  622. return 0;
  623. }
  624. #ifdef CONFIG_SND_HDA_POWER_SAVE
  625. static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
  626. {
  627. struct via_spec *spec = codec->spec;
  628. return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
  629. }
  630. #endif
  631. /*
  632. */
  633. static struct hda_codec_ops via_patch_ops = {
  634. .build_controls = via_build_controls,
  635. .build_pcms = via_build_pcms,
  636. .init = via_init,
  637. .free = via_free,
  638. #ifdef CONFIG_SND_HDA_POWER_SAVE
  639. .check_power_status = via_check_power_status,
  640. #endif
  641. };
  642. /* fill in the dac_nids table from the parsed pin configuration */
  643. static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
  644. const struct auto_pin_cfg *cfg)
  645. {
  646. int i;
  647. hda_nid_t nid;
  648. spec->multiout.num_dacs = cfg->line_outs;
  649. spec->multiout.dac_nids = spec->private_dac_nids;
  650. for(i = 0; i < 4; i++) {
  651. nid = cfg->line_out_pins[i];
  652. if (nid) {
  653. /* config dac list */
  654. switch (i) {
  655. case AUTO_SEQ_FRONT:
  656. spec->multiout.dac_nids[i] = 0x10;
  657. break;
  658. case AUTO_SEQ_CENLFE:
  659. spec->multiout.dac_nids[i] = 0x12;
  660. break;
  661. case AUTO_SEQ_SURROUND:
  662. spec->multiout.dac_nids[i] = 0x11;
  663. break;
  664. case AUTO_SEQ_SIDE:
  665. spec->multiout.dac_nids[i] = 0x13;
  666. break;
  667. }
  668. }
  669. }
  670. return 0;
  671. }
  672. /* add playback controls from the parsed DAC table */
  673. static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
  674. const struct auto_pin_cfg *cfg)
  675. {
  676. char name[32];
  677. static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
  678. hda_nid_t nid, nid_vol = 0;
  679. int i, err;
  680. for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
  681. nid = cfg->line_out_pins[i];
  682. if (!nid)
  683. continue;
  684. if (i != AUTO_SEQ_FRONT)
  685. nid_vol = 0x18 + i;
  686. if (i == AUTO_SEQ_CENLFE) {
  687. /* Center/LFE */
  688. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  689. "Center Playback Volume",
  690. HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
  691. HDA_OUTPUT));
  692. if (err < 0)
  693. return err;
  694. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  695. "LFE Playback Volume",
  696. HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
  697. HDA_OUTPUT));
  698. if (err < 0)
  699. return err;
  700. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  701. "Center Playback Switch",
  702. HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
  703. HDA_OUTPUT));
  704. if (err < 0)
  705. return err;
  706. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  707. "LFE Playback Switch",
  708. HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
  709. HDA_OUTPUT));
  710. if (err < 0)
  711. return err;
  712. } else if (i == AUTO_SEQ_FRONT){
  713. /* add control to mixer index 0 */
  714. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  715. "Master Front Playback Volume",
  716. HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
  717. HDA_INPUT));
  718. if (err < 0)
  719. return err;
  720. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  721. "Master Front Playback Switch",
  722. HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
  723. HDA_INPUT));
  724. if (err < 0)
  725. return err;
  726. /* add control to PW3 */
  727. sprintf(name, "%s Playback Volume", chname[i]);
  728. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  729. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  730. HDA_OUTPUT));
  731. if (err < 0)
  732. return err;
  733. sprintf(name, "%s Playback Switch", chname[i]);
  734. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  735. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  736. HDA_OUTPUT));
  737. if (err < 0)
  738. return err;
  739. } else {
  740. sprintf(name, "%s Playback Volume", chname[i]);
  741. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  742. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  743. HDA_OUTPUT));
  744. if (err < 0)
  745. return err;
  746. sprintf(name, "%s Playback Switch", chname[i]);
  747. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  748. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  749. HDA_OUTPUT));
  750. if (err < 0)
  751. return err;
  752. }
  753. }
  754. return 0;
  755. }
  756. static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
  757. {
  758. int err;
  759. if (!pin)
  760. return 0;
  761. spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
  762. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  763. "Headphone Playback Volume",
  764. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  765. if (err < 0)
  766. return err;
  767. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  768. "Headphone Playback Switch",
  769. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  770. if (err < 0)
  771. return err;
  772. return 0;
  773. }
  774. /* create playback/capture controls for input pins */
  775. static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
  776. const struct auto_pin_cfg *cfg)
  777. {
  778. static char *labels[] = {
  779. "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
  780. };
  781. struct hda_input_mux *imux = &spec->private_imux;
  782. int i, err, idx = 0;
  783. /* for internal loopback recording select */
  784. imux->items[imux->num_items].label = "Stereo Mixer";
  785. imux->items[imux->num_items].index = idx;
  786. imux->num_items++;
  787. for (i = 0; i < AUTO_PIN_LAST; i++) {
  788. if (!cfg->input_pins[i])
  789. continue;
  790. switch (cfg->input_pins[i]) {
  791. case 0x1d: /* Mic */
  792. idx = 2;
  793. break;
  794. case 0x1e: /* Line In */
  795. idx = 3;
  796. break;
  797. case 0x21: /* Front Mic */
  798. idx = 4;
  799. break;
  800. case 0x24: /* CD */
  801. idx = 1;
  802. break;
  803. }
  804. err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
  805. idx, 0x17);
  806. if (err < 0)
  807. return err;
  808. imux->items[imux->num_items].label = labels[i];
  809. imux->items[imux->num_items].index = idx;
  810. imux->num_items++;
  811. }
  812. return 0;
  813. }
  814. #ifdef CONFIG_SND_HDA_POWER_SAVE
  815. static struct hda_amp_list vt1708_loopbacks[] = {
  816. { 0x17, HDA_INPUT, 1 },
  817. { 0x17, HDA_INPUT, 2 },
  818. { 0x17, HDA_INPUT, 3 },
  819. { 0x17, HDA_INPUT, 4 },
  820. { } /* end */
  821. };
  822. #endif
  823. static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
  824. {
  825. unsigned int def_conf;
  826. unsigned char seqassoc;
  827. def_conf = snd_hda_codec_read(codec, nid, 0,
  828. AC_VERB_GET_CONFIG_DEFAULT, 0);
  829. seqassoc = (unsigned char) get_defcfg_association(def_conf);
  830. seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
  831. if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
  832. if (seqassoc == 0xff) {
  833. def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
  834. snd_hda_codec_write(codec, nid, 0,
  835. AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
  836. def_conf >> 24);
  837. }
  838. }
  839. return;
  840. }
  841. static int vt1708_parse_auto_config(struct hda_codec *codec)
  842. {
  843. struct via_spec *spec = codec->spec;
  844. int err;
  845. /* Add HP and CD pin config connect bit re-config action */
  846. vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
  847. vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
  848. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
  849. if (err < 0)
  850. return err;
  851. err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
  852. if (err < 0)
  853. return err;
  854. if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
  855. return 0; /* can't find valid BIOS pin config */
  856. err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
  857. if (err < 0)
  858. return err;
  859. err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  860. if (err < 0)
  861. return err;
  862. err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
  863. if (err < 0)
  864. return err;
  865. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  866. if (spec->autocfg.dig_out_pin)
  867. spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
  868. if (spec->autocfg.dig_in_pin)
  869. spec->dig_in_nid = VT1708_DIGIN_NID;
  870. if (spec->kctl_alloc)
  871. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  872. spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
  873. spec->input_mux = &spec->private_imux;
  874. return 1;
  875. }
  876. /* init callback for auto-configuration model -- overriding the default init */
  877. static int via_auto_init(struct hda_codec *codec)
  878. {
  879. via_init(codec);
  880. via_auto_init_multi_out(codec);
  881. via_auto_init_hp_out(codec);
  882. via_auto_init_analog_input(codec);
  883. return 0;
  884. }
  885. static int patch_vt1708(struct hda_codec *codec)
  886. {
  887. struct via_spec *spec;
  888. int err;
  889. /* create a codec specific record */
  890. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  891. if (spec == NULL)
  892. return -ENOMEM;
  893. codec->spec = spec;
  894. /* automatic parse from the BIOS config */
  895. err = vt1708_parse_auto_config(codec);
  896. if (err < 0) {
  897. via_free(codec);
  898. return err;
  899. } else if (!err) {
  900. printk(KERN_INFO "hda_codec: Cannot set up configuration "
  901. "from BIOS. Using genenic mode...\n");
  902. }
  903. spec->stream_name_analog = "VT1708 Analog";
  904. spec->stream_analog_playback = &vt1708_pcm_analog_playback;
  905. /* disable 32bit format on VT1708 */
  906. if (codec->vendor_id == 0x11061708)
  907. spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
  908. spec->stream_analog_capture = &vt1708_pcm_analog_capture;
  909. spec->stream_name_digital = "VT1708 Digital";
  910. spec->stream_digital_playback = &vt1708_pcm_digital_playback;
  911. spec->stream_digital_capture = &vt1708_pcm_digital_capture;
  912. if (!spec->adc_nids && spec->input_mux) {
  913. spec->adc_nids = vt1708_adc_nids;
  914. spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
  915. spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
  916. spec->num_mixers++;
  917. }
  918. codec->patch_ops = via_patch_ops;
  919. codec->patch_ops.init = via_auto_init;
  920. #ifdef CONFIG_SND_HDA_POWER_SAVE
  921. spec->loopback.amplist = vt1708_loopbacks;
  922. #endif
  923. return 0;
  924. }
  925. /* capture mixer elements */
  926. static struct snd_kcontrol_new vt1709_capture_mixer[] = {
  927. HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
  928. HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
  929. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
  930. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
  931. HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
  932. HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
  933. {
  934. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  935. /* The multiple "Capture Source" controls confuse alsamixer
  936. * So call somewhat different..
  937. */
  938. /* .name = "Capture Source", */
  939. .name = "Input Source",
  940. .count = 1,
  941. .info = via_mux_enum_info,
  942. .get = via_mux_enum_get,
  943. .put = via_mux_enum_put,
  944. },
  945. { } /* end */
  946. };
  947. static struct hda_verb vt1709_uniwill_init_verbs[] = {
  948. {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
  949. { }
  950. };
  951. /*
  952. * generic initialization of ADC, input mixers and output mixers
  953. */
  954. static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
  955. /*
  956. * Unmute ADC0-2 and set the default input to mic-in
  957. */
  958. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  959. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  960. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  961. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  962. * mixer widget
  963. */
  964. /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
  965. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  966. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  967. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  968. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  969. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  970. /*
  971. * Set up output selector (0x1a, 0x1b, 0x29)
  972. */
  973. /* set vol=0 to output mixers */
  974. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  975. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  976. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  977. /*
  978. * Unmute PW3 and PW4
  979. */
  980. {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  981. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  982. /* Set input of PW4 as AOW4 */
  983. {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
  984. /* PW9 Output enable */
  985. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  986. { }
  987. };
  988. static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
  989. .substreams = 1,
  990. .channels_min = 2,
  991. .channels_max = 10,
  992. .nid = 0x10, /* NID to query formats and rates */
  993. .ops = {
  994. .open = via_playback_pcm_open,
  995. .prepare = via_playback_pcm_prepare,
  996. .cleanup = via_playback_pcm_cleanup
  997. },
  998. };
  999. static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
  1000. .substreams = 1,
  1001. .channels_min = 2,
  1002. .channels_max = 6,
  1003. .nid = 0x10, /* NID to query formats and rates */
  1004. .ops = {
  1005. .open = via_playback_pcm_open,
  1006. .prepare = via_playback_pcm_prepare,
  1007. .cleanup = via_playback_pcm_cleanup
  1008. },
  1009. };
  1010. static struct hda_pcm_stream vt1709_pcm_analog_capture = {
  1011. .substreams = 2,
  1012. .channels_min = 2,
  1013. .channels_max = 2,
  1014. .nid = 0x14, /* NID to query formats and rates */
  1015. .ops = {
  1016. .prepare = via_capture_pcm_prepare,
  1017. .cleanup = via_capture_pcm_cleanup
  1018. },
  1019. };
  1020. static struct hda_pcm_stream vt1709_pcm_digital_playback = {
  1021. .substreams = 1,
  1022. .channels_min = 2,
  1023. .channels_max = 2,
  1024. /* NID is set in via_build_pcms */
  1025. .ops = {
  1026. .open = via_dig_playback_pcm_open,
  1027. .close = via_dig_playback_pcm_close
  1028. },
  1029. };
  1030. static struct hda_pcm_stream vt1709_pcm_digital_capture = {
  1031. .substreams = 1,
  1032. .channels_min = 2,
  1033. .channels_max = 2,
  1034. };
  1035. static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
  1036. const struct auto_pin_cfg *cfg)
  1037. {
  1038. int i;
  1039. hda_nid_t nid;
  1040. if (cfg->line_outs == 4) /* 10 channels */
  1041. spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
  1042. else if (cfg->line_outs == 3) /* 6 channels */
  1043. spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
  1044. spec->multiout.dac_nids = spec->private_dac_nids;
  1045. if (cfg->line_outs == 4) { /* 10 channels */
  1046. for (i = 0; i < cfg->line_outs; i++) {
  1047. nid = cfg->line_out_pins[i];
  1048. if (nid) {
  1049. /* config dac list */
  1050. switch (i) {
  1051. case AUTO_SEQ_FRONT:
  1052. /* AOW0 */
  1053. spec->multiout.dac_nids[i] = 0x10;
  1054. break;
  1055. case AUTO_SEQ_CENLFE:
  1056. /* AOW2 */
  1057. spec->multiout.dac_nids[i] = 0x12;
  1058. break;
  1059. case AUTO_SEQ_SURROUND:
  1060. /* AOW3 */
  1061. spec->multiout.dac_nids[i] = 0x11;
  1062. break;
  1063. case AUTO_SEQ_SIDE:
  1064. /* AOW1 */
  1065. spec->multiout.dac_nids[i] = 0x27;
  1066. break;
  1067. default:
  1068. break;
  1069. }
  1070. }
  1071. }
  1072. spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
  1073. } else if (cfg->line_outs == 3) { /* 6 channels */
  1074. for(i = 0; i < cfg->line_outs; i++) {
  1075. nid = cfg->line_out_pins[i];
  1076. if (nid) {
  1077. /* config dac list */
  1078. switch(i) {
  1079. case AUTO_SEQ_FRONT:
  1080. /* AOW0 */
  1081. spec->multiout.dac_nids[i] = 0x10;
  1082. break;
  1083. case AUTO_SEQ_CENLFE:
  1084. /* AOW2 */
  1085. spec->multiout.dac_nids[i] = 0x12;
  1086. break;
  1087. case AUTO_SEQ_SURROUND:
  1088. /* AOW1 */
  1089. spec->multiout.dac_nids[i] = 0x11;
  1090. break;
  1091. default:
  1092. break;
  1093. }
  1094. }
  1095. }
  1096. }
  1097. return 0;
  1098. }
  1099. /* add playback controls from the parsed DAC table */
  1100. static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
  1101. const struct auto_pin_cfg *cfg)
  1102. {
  1103. char name[32];
  1104. static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
  1105. hda_nid_t nid = 0;
  1106. int i, err;
  1107. for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
  1108. nid = cfg->line_out_pins[i];
  1109. if (!nid)
  1110. continue;
  1111. if (i == AUTO_SEQ_CENLFE) {
  1112. /* Center/LFE */
  1113. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1114. "Center Playback Volume",
  1115. HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
  1116. HDA_OUTPUT));
  1117. if (err < 0)
  1118. return err;
  1119. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1120. "LFE Playback Volume",
  1121. HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
  1122. HDA_OUTPUT));
  1123. if (err < 0)
  1124. return err;
  1125. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1126. "Center Playback Switch",
  1127. HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
  1128. HDA_OUTPUT));
  1129. if (err < 0)
  1130. return err;
  1131. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1132. "LFE Playback Switch",
  1133. HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
  1134. HDA_OUTPUT));
  1135. if (err < 0)
  1136. return err;
  1137. } else if (i == AUTO_SEQ_FRONT){
  1138. /* add control to mixer index 0 */
  1139. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1140. "Master Front Playback Volume",
  1141. HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
  1142. HDA_INPUT));
  1143. if (err < 0)
  1144. return err;
  1145. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1146. "Master Front Playback Switch",
  1147. HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
  1148. HDA_INPUT));
  1149. if (err < 0)
  1150. return err;
  1151. /* add control to PW3 */
  1152. sprintf(name, "%s Playback Volume", chname[i]);
  1153. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  1154. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  1155. HDA_OUTPUT));
  1156. if (err < 0)
  1157. return err;
  1158. sprintf(name, "%s Playback Switch", chname[i]);
  1159. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  1160. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  1161. HDA_OUTPUT));
  1162. if (err < 0)
  1163. return err;
  1164. } else if (i == AUTO_SEQ_SURROUND) {
  1165. sprintf(name, "%s Playback Volume", chname[i]);
  1166. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  1167. HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
  1168. HDA_OUTPUT));
  1169. if (err < 0)
  1170. return err;
  1171. sprintf(name, "%s Playback Switch", chname[i]);
  1172. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  1173. HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
  1174. HDA_OUTPUT));
  1175. if (err < 0)
  1176. return err;
  1177. } else if (i == AUTO_SEQ_SIDE) {
  1178. sprintf(name, "%s Playback Volume", chname[i]);
  1179. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  1180. HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
  1181. HDA_OUTPUT));
  1182. if (err < 0)
  1183. return err;
  1184. sprintf(name, "%s Playback Switch", chname[i]);
  1185. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  1186. HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
  1187. HDA_OUTPUT));
  1188. if (err < 0)
  1189. return err;
  1190. }
  1191. }
  1192. return 0;
  1193. }
  1194. static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
  1195. {
  1196. int err;
  1197. if (!pin)
  1198. return 0;
  1199. if (spec->multiout.num_dacs == 5) /* 10 channels */
  1200. spec->multiout.hp_nid = VT1709_HP_DAC_NID;
  1201. else if (spec->multiout.num_dacs == 3) /* 6 channels */
  1202. spec->multiout.hp_nid = 0;
  1203. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1204. "Headphone Playback Volume",
  1205. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  1206. if (err < 0)
  1207. return err;
  1208. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1209. "Headphone Playback Switch",
  1210. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  1211. if (err < 0)
  1212. return err;
  1213. return 0;
  1214. }
  1215. /* create playback/capture controls for input pins */
  1216. static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
  1217. const struct auto_pin_cfg *cfg)
  1218. {
  1219. static char *labels[] = {
  1220. "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
  1221. };
  1222. struct hda_input_mux *imux = &spec->private_imux;
  1223. int i, err, idx = 0;
  1224. /* for internal loopback recording select */
  1225. imux->items[imux->num_items].label = "Stereo Mixer";
  1226. imux->items[imux->num_items].index = idx;
  1227. imux->num_items++;
  1228. for (i = 0; i < AUTO_PIN_LAST; i++) {
  1229. if (!cfg->input_pins[i])
  1230. continue;
  1231. switch (cfg->input_pins[i]) {
  1232. case 0x1d: /* Mic */
  1233. idx = 2;
  1234. break;
  1235. case 0x1e: /* Line In */
  1236. idx = 3;
  1237. break;
  1238. case 0x21: /* Front Mic */
  1239. idx = 4;
  1240. break;
  1241. case 0x23: /* CD */
  1242. idx = 1;
  1243. break;
  1244. }
  1245. err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
  1246. idx, 0x18);
  1247. if (err < 0)
  1248. return err;
  1249. imux->items[imux->num_items].label = labels[i];
  1250. imux->items[imux->num_items].index = idx;
  1251. imux->num_items++;
  1252. }
  1253. return 0;
  1254. }
  1255. static int vt1709_parse_auto_config(struct hda_codec *codec)
  1256. {
  1257. struct via_spec *spec = codec->spec;
  1258. int err;
  1259. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
  1260. if (err < 0)
  1261. return err;
  1262. err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
  1263. if (err < 0)
  1264. return err;
  1265. if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
  1266. return 0; /* can't find valid BIOS pin config */
  1267. err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
  1268. if (err < 0)
  1269. return err;
  1270. err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  1271. if (err < 0)
  1272. return err;
  1273. err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
  1274. if (err < 0)
  1275. return err;
  1276. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  1277. if (spec->autocfg.dig_out_pin)
  1278. spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
  1279. if (spec->autocfg.dig_in_pin)
  1280. spec->dig_in_nid = VT1709_DIGIN_NID;
  1281. if (spec->kctl_alloc)
  1282. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  1283. spec->input_mux = &spec->private_imux;
  1284. return 1;
  1285. }
  1286. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1287. static struct hda_amp_list vt1709_loopbacks[] = {
  1288. { 0x18, HDA_INPUT, 1 },
  1289. { 0x18, HDA_INPUT, 2 },
  1290. { 0x18, HDA_INPUT, 3 },
  1291. { 0x18, HDA_INPUT, 4 },
  1292. { } /* end */
  1293. };
  1294. #endif
  1295. static int patch_vt1709_10ch(struct hda_codec *codec)
  1296. {
  1297. struct via_spec *spec;
  1298. int err;
  1299. /* create a codec specific record */
  1300. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1301. if (spec == NULL)
  1302. return -ENOMEM;
  1303. codec->spec = spec;
  1304. err = vt1709_parse_auto_config(codec);
  1305. if (err < 0) {
  1306. via_free(codec);
  1307. return err;
  1308. } else if (!err) {
  1309. printk(KERN_INFO "hda_codec: Cannot set up configuration. "
  1310. "Using genenic mode...\n");
  1311. }
  1312. spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
  1313. spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
  1314. spec->stream_name_analog = "VT1709 Analog";
  1315. spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
  1316. spec->stream_analog_capture = &vt1709_pcm_analog_capture;
  1317. spec->stream_name_digital = "VT1709 Digital";
  1318. spec->stream_digital_playback = &vt1709_pcm_digital_playback;
  1319. spec->stream_digital_capture = &vt1709_pcm_digital_capture;
  1320. if (!spec->adc_nids && spec->input_mux) {
  1321. spec->adc_nids = vt1709_adc_nids;
  1322. spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
  1323. spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
  1324. spec->num_mixers++;
  1325. }
  1326. codec->patch_ops = via_patch_ops;
  1327. codec->patch_ops.init = via_auto_init;
  1328. codec->patch_ops.unsol_event = via_unsol_event;
  1329. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1330. spec->loopback.amplist = vt1709_loopbacks;
  1331. #endif
  1332. return 0;
  1333. }
  1334. /*
  1335. * generic initialization of ADC, input mixers and output mixers
  1336. */
  1337. static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
  1338. /*
  1339. * Unmute ADC0-2 and set the default input to mic-in
  1340. */
  1341. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1342. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1343. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1344. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  1345. * mixer widget
  1346. */
  1347. /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
  1348. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1349. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1350. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  1351. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  1352. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  1353. /*
  1354. * Set up output selector (0x1a, 0x1b, 0x29)
  1355. */
  1356. /* set vol=0 to output mixers */
  1357. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1358. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1359. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1360. /*
  1361. * Unmute PW3 and PW4
  1362. */
  1363. {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1364. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1365. /* Set input of PW4 as MW0 */
  1366. {0x20, AC_VERB_SET_CONNECT_SEL, 0},
  1367. /* PW9 Output enable */
  1368. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  1369. { }
  1370. };
  1371. static int patch_vt1709_6ch(struct hda_codec *codec)
  1372. {
  1373. struct via_spec *spec;
  1374. int err;
  1375. /* create a codec specific record */
  1376. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1377. if (spec == NULL)
  1378. return -ENOMEM;
  1379. codec->spec = spec;
  1380. err = vt1709_parse_auto_config(codec);
  1381. if (err < 0) {
  1382. via_free(codec);
  1383. return err;
  1384. } else if (!err) {
  1385. printk(KERN_INFO "hda_codec: Cannot set up configuration. "
  1386. "Using genenic mode...\n");
  1387. }
  1388. spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
  1389. spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
  1390. spec->stream_name_analog = "VT1709 Analog";
  1391. spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
  1392. spec->stream_analog_capture = &vt1709_pcm_analog_capture;
  1393. spec->stream_name_digital = "VT1709 Digital";
  1394. spec->stream_digital_playback = &vt1709_pcm_digital_playback;
  1395. spec->stream_digital_capture = &vt1709_pcm_digital_capture;
  1396. if (!spec->adc_nids && spec->input_mux) {
  1397. spec->adc_nids = vt1709_adc_nids;
  1398. spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
  1399. spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
  1400. spec->num_mixers++;
  1401. }
  1402. codec->patch_ops = via_patch_ops;
  1403. codec->patch_ops.init = via_auto_init;
  1404. codec->patch_ops.unsol_event = via_unsol_event;
  1405. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1406. spec->loopback.amplist = vt1709_loopbacks;
  1407. #endif
  1408. return 0;
  1409. }
  1410. /* capture mixer elements */
  1411. static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
  1412. HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
  1413. HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
  1414. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
  1415. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
  1416. {
  1417. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1418. /* The multiple "Capture Source" controls confuse alsamixer
  1419. * So call somewhat different..
  1420. */
  1421. /* .name = "Capture Source", */
  1422. .name = "Input Source",
  1423. .count = 1,
  1424. .info = via_mux_enum_info,
  1425. .get = via_mux_enum_get,
  1426. .put = via_mux_enum_put,
  1427. },
  1428. { } /* end */
  1429. };
  1430. /*
  1431. * generic initialization of ADC, input mixers and output mixers
  1432. */
  1433. static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
  1434. /*
  1435. * Unmute ADC0-1 and set the default input to mic-in
  1436. */
  1437. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1438. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1439. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  1440. * mixer widget
  1441. */
  1442. /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
  1443. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1444. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1445. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  1446. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  1447. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  1448. /*
  1449. * Set up output mixers
  1450. */
  1451. /* set vol=0 to output mixers */
  1452. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1453. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1454. {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1455. /* Setup default input to PW4 */
  1456. {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
  1457. /* PW9 Output enable */
  1458. {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  1459. /* PW10 Input enable */
  1460. {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  1461. { }
  1462. };
  1463. static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
  1464. /*
  1465. * Unmute ADC0-1 and set the default input to mic-in
  1466. */
  1467. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1468. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1469. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  1470. * mixer widget
  1471. */
  1472. /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
  1473. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1474. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1475. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  1476. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  1477. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  1478. /*
  1479. * Set up output mixers
  1480. */
  1481. /* set vol=0 to output mixers */
  1482. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1483. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1484. {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1485. /* Setup default input of PW4 to MW0 */
  1486. {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
  1487. /* PW9 Output enable */
  1488. {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  1489. /* PW10 Input enable */
  1490. {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  1491. { }
  1492. };
  1493. static struct hda_verb vt1708B_uniwill_init_verbs[] = {
  1494. {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
  1495. { }
  1496. };
  1497. static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
  1498. .substreams = 1,
  1499. .channels_min = 2,
  1500. .channels_max = 8,
  1501. .nid = 0x10, /* NID to query formats and rates */
  1502. .ops = {
  1503. .open = via_playback_pcm_open,
  1504. .prepare = via_playback_pcm_prepare,
  1505. .cleanup = via_playback_pcm_cleanup
  1506. },
  1507. };
  1508. static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
  1509. .substreams = 1,
  1510. .channels_min = 2,
  1511. .channels_max = 4,
  1512. .nid = 0x10, /* NID to query formats and rates */
  1513. .ops = {
  1514. .open = via_playback_pcm_open,
  1515. .prepare = via_playback_pcm_prepare,
  1516. .cleanup = via_playback_pcm_cleanup
  1517. },
  1518. };
  1519. static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
  1520. .substreams = 2,
  1521. .channels_min = 2,
  1522. .channels_max = 2,
  1523. .nid = 0x13, /* NID to query formats and rates */
  1524. .ops = {
  1525. .prepare = via_capture_pcm_prepare,
  1526. .cleanup = via_capture_pcm_cleanup
  1527. },
  1528. };
  1529. static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
  1530. .substreams = 1,
  1531. .channels_min = 2,
  1532. .channels_max = 2,
  1533. /* NID is set in via_build_pcms */
  1534. .ops = {
  1535. .open = via_dig_playback_pcm_open,
  1536. .close = via_dig_playback_pcm_close,
  1537. .prepare = via_dig_playback_pcm_prepare
  1538. },
  1539. };
  1540. static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
  1541. .substreams = 1,
  1542. .channels_min = 2,
  1543. .channels_max = 2,
  1544. };
  1545. /* fill in the dac_nids table from the parsed pin configuration */
  1546. static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
  1547. const struct auto_pin_cfg *cfg)
  1548. {
  1549. int i;
  1550. hda_nid_t nid;
  1551. spec->multiout.num_dacs = cfg->line_outs;
  1552. spec->multiout.dac_nids = spec->private_dac_nids;
  1553. for (i = 0; i < 4; i++) {
  1554. nid = cfg->line_out_pins[i];
  1555. if (nid) {
  1556. /* config dac list */
  1557. switch (i) {
  1558. case AUTO_SEQ_FRONT:
  1559. spec->multiout.dac_nids[i] = 0x10;
  1560. break;
  1561. case AUTO_SEQ_CENLFE:
  1562. spec->multiout.dac_nids[i] = 0x24;
  1563. break;
  1564. case AUTO_SEQ_SURROUND:
  1565. spec->multiout.dac_nids[i] = 0x11;
  1566. break;
  1567. case AUTO_SEQ_SIDE:
  1568. spec->multiout.dac_nids[i] = 0x25;
  1569. break;
  1570. }
  1571. }
  1572. }
  1573. return 0;
  1574. }
  1575. /* add playback controls from the parsed DAC table */
  1576. static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
  1577. const struct auto_pin_cfg *cfg)
  1578. {
  1579. char name[32];
  1580. static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
  1581. hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
  1582. hda_nid_t nid, nid_vol = 0;
  1583. int i, err;
  1584. for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
  1585. nid = cfg->line_out_pins[i];
  1586. if (!nid)
  1587. continue;
  1588. nid_vol = nid_vols[i];
  1589. if (i == AUTO_SEQ_CENLFE) {
  1590. /* Center/LFE */
  1591. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1592. "Center Playback Volume",
  1593. HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
  1594. HDA_OUTPUT));
  1595. if (err < 0)
  1596. return err;
  1597. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1598. "LFE Playback Volume",
  1599. HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
  1600. HDA_OUTPUT));
  1601. if (err < 0)
  1602. return err;
  1603. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1604. "Center Playback Switch",
  1605. HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
  1606. HDA_OUTPUT));
  1607. if (err < 0)
  1608. return err;
  1609. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1610. "LFE Playback Switch",
  1611. HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
  1612. HDA_OUTPUT));
  1613. if (err < 0)
  1614. return err;
  1615. } else if (i == AUTO_SEQ_FRONT) {
  1616. /* add control to mixer index 0 */
  1617. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1618. "Master Front Playback Volume",
  1619. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  1620. HDA_INPUT));
  1621. if (err < 0)
  1622. return err;
  1623. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1624. "Master Front Playback Switch",
  1625. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  1626. HDA_INPUT));
  1627. if (err < 0)
  1628. return err;
  1629. /* add control to PW3 */
  1630. sprintf(name, "%s Playback Volume", chname[i]);
  1631. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  1632. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  1633. HDA_OUTPUT));
  1634. if (err < 0)
  1635. return err;
  1636. sprintf(name, "%s Playback Switch", chname[i]);
  1637. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  1638. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  1639. HDA_OUTPUT));
  1640. if (err < 0)
  1641. return err;
  1642. } else {
  1643. sprintf(name, "%s Playback Volume", chname[i]);
  1644. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  1645. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  1646. HDA_OUTPUT));
  1647. if (err < 0)
  1648. return err;
  1649. sprintf(name, "%s Playback Switch", chname[i]);
  1650. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  1651. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  1652. HDA_OUTPUT));
  1653. if (err < 0)
  1654. return err;
  1655. }
  1656. }
  1657. return 0;
  1658. }
  1659. static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
  1660. {
  1661. int err;
  1662. if (!pin)
  1663. return 0;
  1664. spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
  1665. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1666. "Headphone Playback Volume",
  1667. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  1668. if (err < 0)
  1669. return err;
  1670. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1671. "Headphone Playback Switch",
  1672. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  1673. if (err < 0)
  1674. return err;
  1675. return 0;
  1676. }
  1677. /* create playback/capture controls for input pins */
  1678. static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
  1679. const struct auto_pin_cfg *cfg)
  1680. {
  1681. static char *labels[] = {
  1682. "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
  1683. };
  1684. struct hda_input_mux *imux = &spec->private_imux;
  1685. int i, err, idx = 0;
  1686. /* for internal loopback recording select */
  1687. imux->items[imux->num_items].label = "Stereo Mixer";
  1688. imux->items[imux->num_items].index = idx;
  1689. imux->num_items++;
  1690. for (i = 0; i < AUTO_PIN_LAST; i++) {
  1691. if (!cfg->input_pins[i])
  1692. continue;
  1693. switch (cfg->input_pins[i]) {
  1694. case 0x1a: /* Mic */
  1695. idx = 2;
  1696. break;
  1697. case 0x1b: /* Line In */
  1698. idx = 3;
  1699. break;
  1700. case 0x1e: /* Front Mic */
  1701. idx = 4;
  1702. break;
  1703. case 0x1f: /* CD */
  1704. idx = 1;
  1705. break;
  1706. }
  1707. err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
  1708. idx, 0x16);
  1709. if (err < 0)
  1710. return err;
  1711. imux->items[imux->num_items].label = labels[i];
  1712. imux->items[imux->num_items].index = idx;
  1713. imux->num_items++;
  1714. }
  1715. return 0;
  1716. }
  1717. static int vt1708B_parse_auto_config(struct hda_codec *codec)
  1718. {
  1719. struct via_spec *spec = codec->spec;
  1720. int err;
  1721. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
  1722. if (err < 0)
  1723. return err;
  1724. err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
  1725. if (err < 0)
  1726. return err;
  1727. if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
  1728. return 0; /* can't find valid BIOS pin config */
  1729. err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
  1730. if (err < 0)
  1731. return err;
  1732. err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  1733. if (err < 0)
  1734. return err;
  1735. err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
  1736. if (err < 0)
  1737. return err;
  1738. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  1739. if (spec->autocfg.dig_out_pin)
  1740. spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
  1741. if (spec->autocfg.dig_in_pin)
  1742. spec->dig_in_nid = VT1708B_DIGIN_NID;
  1743. if (spec->kctl_alloc)
  1744. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  1745. spec->input_mux = &spec->private_imux;
  1746. return 1;
  1747. }
  1748. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1749. static struct hda_amp_list vt1708B_loopbacks[] = {
  1750. { 0x16, HDA_INPUT, 1 },
  1751. { 0x16, HDA_INPUT, 2 },
  1752. { 0x16, HDA_INPUT, 3 },
  1753. { 0x16, HDA_INPUT, 4 },
  1754. { } /* end */
  1755. };
  1756. #endif
  1757. static int patch_vt1708B_8ch(struct hda_codec *codec)
  1758. {
  1759. struct via_spec *spec;
  1760. int err;
  1761. /* create a codec specific record */
  1762. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1763. if (spec == NULL)
  1764. return -ENOMEM;
  1765. codec->spec = spec;
  1766. /* automatic parse from the BIOS config */
  1767. err = vt1708B_parse_auto_config(codec);
  1768. if (err < 0) {
  1769. via_free(codec);
  1770. return err;
  1771. } else if (!err) {
  1772. printk(KERN_INFO "hda_codec: Cannot set up configuration "
  1773. "from BIOS. Using genenic mode...\n");
  1774. }
  1775. spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
  1776. spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
  1777. spec->stream_name_analog = "VT1708B Analog";
  1778. spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
  1779. spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
  1780. spec->stream_name_digital = "VT1708B Digital";
  1781. spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
  1782. spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
  1783. if (!spec->adc_nids && spec->input_mux) {
  1784. spec->adc_nids = vt1708B_adc_nids;
  1785. spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
  1786. spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
  1787. spec->num_mixers++;
  1788. }
  1789. codec->patch_ops = via_patch_ops;
  1790. codec->patch_ops.init = via_auto_init;
  1791. codec->patch_ops.unsol_event = via_unsol_event;
  1792. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1793. spec->loopback.amplist = vt1708B_loopbacks;
  1794. #endif
  1795. return 0;
  1796. }
  1797. static int patch_vt1708B_4ch(struct hda_codec *codec)
  1798. {
  1799. struct via_spec *spec;
  1800. int err;
  1801. /* create a codec specific record */
  1802. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1803. if (spec == NULL)
  1804. return -ENOMEM;
  1805. codec->spec = spec;
  1806. /* automatic parse from the BIOS config */
  1807. err = vt1708B_parse_auto_config(codec);
  1808. if (err < 0) {
  1809. via_free(codec);
  1810. return err;
  1811. } else if (!err) {
  1812. printk(KERN_INFO "hda_codec: Cannot set up configuration "
  1813. "from BIOS. Using genenic mode...\n");
  1814. }
  1815. spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
  1816. spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
  1817. spec->stream_name_analog = "VT1708B Analog";
  1818. spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
  1819. spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
  1820. spec->stream_name_digital = "VT1708B Digital";
  1821. spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
  1822. spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
  1823. if (!spec->adc_nids && spec->input_mux) {
  1824. spec->adc_nids = vt1708B_adc_nids;
  1825. spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
  1826. spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
  1827. spec->num_mixers++;
  1828. }
  1829. codec->patch_ops = via_patch_ops;
  1830. codec->patch_ops.init = via_auto_init;
  1831. codec->patch_ops.unsol_event = via_unsol_event;
  1832. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1833. spec->loopback.amplist = vt1708B_loopbacks;
  1834. #endif
  1835. return 0;
  1836. }
  1837. /* Patch for VT1708S */
  1838. /* capture mixer elements */
  1839. static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
  1840. HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
  1841. HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
  1842. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
  1843. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
  1844. HDA_CODEC_VOLUME("Mic Boost", 0x1A, 0x0, HDA_INPUT),
  1845. HDA_CODEC_VOLUME("Front Mic Boost", 0x1E, 0x0, HDA_INPUT),
  1846. {
  1847. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1848. /* The multiple "Capture Source" controls confuse alsamixer
  1849. * So call somewhat different..
  1850. */
  1851. /* .name = "Capture Source", */
  1852. .name = "Input Source",
  1853. .count = 1,
  1854. .info = via_mux_enum_info,
  1855. .get = via_mux_enum_get,
  1856. .put = via_mux_enum_put,
  1857. },
  1858. { } /* end */
  1859. };
  1860. static struct hda_verb vt1708S_volume_init_verbs[] = {
  1861. /* Unmute ADC0-1 and set the default input to mic-in */
  1862. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1863. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1864. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
  1865. * analog-loopback mixer widget */
  1866. /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
  1867. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1868. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1869. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  1870. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  1871. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  1872. /* Setup default input of PW4 to MW0 */
  1873. {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
  1874. /* PW9 Output enable */
  1875. {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  1876. { }
  1877. };
  1878. static struct hda_verb vt1708S_uniwill_init_verbs[] = {
  1879. {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
  1880. { }
  1881. };
  1882. static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
  1883. .substreams = 2,
  1884. .channels_min = 2,
  1885. .channels_max = 8,
  1886. .nid = 0x10, /* NID to query formats and rates */
  1887. .ops = {
  1888. .open = via_playback_pcm_open,
  1889. .prepare = via_playback_pcm_prepare,
  1890. .cleanup = via_playback_pcm_cleanup
  1891. },
  1892. };
  1893. static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
  1894. .substreams = 2,
  1895. .channels_min = 2,
  1896. .channels_max = 2,
  1897. .nid = 0x13, /* NID to query formats and rates */
  1898. .ops = {
  1899. .prepare = via_capture_pcm_prepare,
  1900. .cleanup = via_capture_pcm_cleanup
  1901. },
  1902. };
  1903. static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
  1904. .substreams = 1,
  1905. .channels_min = 2,
  1906. .channels_max = 2,
  1907. /* NID is set in via_build_pcms */
  1908. .ops = {
  1909. .open = via_dig_playback_pcm_open,
  1910. .close = via_dig_playback_pcm_close,
  1911. .prepare = via_dig_playback_pcm_prepare
  1912. },
  1913. };
  1914. /* fill in the dac_nids table from the parsed pin configuration */
  1915. static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
  1916. const struct auto_pin_cfg *cfg)
  1917. {
  1918. int i;
  1919. hda_nid_t nid;
  1920. spec->multiout.num_dacs = cfg->line_outs;
  1921. spec->multiout.dac_nids = spec->private_dac_nids;
  1922. for (i = 0; i < 4; i++) {
  1923. nid = cfg->line_out_pins[i];
  1924. if (nid) {
  1925. /* config dac list */
  1926. switch (i) {
  1927. case AUTO_SEQ_FRONT:
  1928. spec->multiout.dac_nids[i] = 0x10;
  1929. break;
  1930. case AUTO_SEQ_CENLFE:
  1931. spec->multiout.dac_nids[i] = 0x24;
  1932. break;
  1933. case AUTO_SEQ_SURROUND:
  1934. spec->multiout.dac_nids[i] = 0x11;
  1935. break;
  1936. case AUTO_SEQ_SIDE:
  1937. spec->multiout.dac_nids[i] = 0x25;
  1938. break;
  1939. }
  1940. }
  1941. }
  1942. return 0;
  1943. }
  1944. /* add playback controls from the parsed DAC table */
  1945. static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
  1946. const struct auto_pin_cfg *cfg)
  1947. {
  1948. char name[32];
  1949. static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
  1950. hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
  1951. hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
  1952. hda_nid_t nid, nid_vol, nid_mute;
  1953. int i, err;
  1954. for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
  1955. nid = cfg->line_out_pins[i];
  1956. if (!nid)
  1957. continue;
  1958. nid_vol = nid_vols[i];
  1959. nid_mute = nid_mutes[i];
  1960. if (i == AUTO_SEQ_CENLFE) {
  1961. /* Center/LFE */
  1962. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1963. "Center Playback Volume",
  1964. HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
  1965. HDA_OUTPUT));
  1966. if (err < 0)
  1967. return err;
  1968. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1969. "LFE Playback Volume",
  1970. HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
  1971. HDA_OUTPUT));
  1972. if (err < 0)
  1973. return err;
  1974. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1975. "Center Playback Switch",
  1976. HDA_COMPOSE_AMP_VAL(nid_mute,
  1977. 1, 0,
  1978. HDA_OUTPUT));
  1979. if (err < 0)
  1980. return err;
  1981. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1982. "LFE Playback Switch",
  1983. HDA_COMPOSE_AMP_VAL(nid_mute,
  1984. 2, 0,
  1985. HDA_OUTPUT));
  1986. if (err < 0)
  1987. return err;
  1988. } else if (i == AUTO_SEQ_FRONT) {
  1989. /* add control to mixer index 0 */
  1990. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  1991. "Master Front Playback Volume",
  1992. HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
  1993. HDA_INPUT));
  1994. if (err < 0)
  1995. return err;
  1996. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  1997. "Master Front Playback Switch",
  1998. HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
  1999. HDA_INPUT));
  2000. if (err < 0)
  2001. return err;
  2002. /* Front */
  2003. sprintf(name, "%s Playback Volume", chname[i]);
  2004. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  2005. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  2006. HDA_OUTPUT));
  2007. if (err < 0)
  2008. return err;
  2009. sprintf(name, "%s Playback Switch", chname[i]);
  2010. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  2011. HDA_COMPOSE_AMP_VAL(nid_mute,
  2012. 3, 0,
  2013. HDA_OUTPUT));
  2014. if (err < 0)
  2015. return err;
  2016. } else {
  2017. sprintf(name, "%s Playback Volume", chname[i]);
  2018. err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
  2019. HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
  2020. HDA_OUTPUT));
  2021. if (err < 0)
  2022. return err;
  2023. sprintf(name, "%s Playback Switch", chname[i]);
  2024. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
  2025. HDA_COMPOSE_AMP_VAL(nid_mute,
  2026. 3, 0,
  2027. HDA_OUTPUT));
  2028. if (err < 0)
  2029. return err;
  2030. }
  2031. }
  2032. return 0;
  2033. }
  2034. static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
  2035. {
  2036. int err;
  2037. if (!pin)
  2038. return 0;
  2039. spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
  2040. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  2041. "Headphone Playback Volume",
  2042. HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
  2043. if (err < 0)
  2044. return err;
  2045. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  2046. "Headphone Playback Switch",
  2047. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  2048. if (err < 0)
  2049. return err;
  2050. return 0;
  2051. }
  2052. /* create playback/capture controls for input pins */
  2053. static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
  2054. const struct auto_pin_cfg *cfg)
  2055. {
  2056. static char *labels[] = {
  2057. "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
  2058. };
  2059. struct hda_input_mux *imux = &spec->private_imux;
  2060. int i, err, idx = 0;
  2061. /* for internal loopback recording select */
  2062. imux->items[imux->num_items].label = "Stereo Mixer";
  2063. imux->items[imux->num_items].index = 5;
  2064. imux->num_items++;
  2065. for (i = 0; i < AUTO_PIN_LAST; i++) {
  2066. if (!cfg->input_pins[i])
  2067. continue;
  2068. switch (cfg->input_pins[i]) {
  2069. case 0x1a: /* Mic */
  2070. idx = 2;
  2071. break;
  2072. case 0x1b: /* Line In */
  2073. idx = 3;
  2074. break;
  2075. case 0x1e: /* Front Mic */
  2076. idx = 4;
  2077. break;
  2078. case 0x1f: /* CD */
  2079. idx = 1;
  2080. break;
  2081. }
  2082. err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
  2083. idx, 0x16);
  2084. if (err < 0)
  2085. return err;
  2086. imux->items[imux->num_items].label = labels[i];
  2087. imux->items[imux->num_items].index = idx-1;
  2088. imux->num_items++;
  2089. }
  2090. return 0;
  2091. }
  2092. static int vt1708S_parse_auto_config(struct hda_codec *codec)
  2093. {
  2094. struct via_spec *spec = codec->spec;
  2095. int err;
  2096. static hda_nid_t vt1708s_ignore[] = {0x21, 0};
  2097. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  2098. vt1708s_ignore);
  2099. if (err < 0)
  2100. return err;
  2101. err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
  2102. if (err < 0)
  2103. return err;
  2104. if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
  2105. return 0; /* can't find valid BIOS pin config */
  2106. err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
  2107. if (err < 0)
  2108. return err;
  2109. err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  2110. if (err < 0)
  2111. return err;
  2112. err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
  2113. if (err < 0)
  2114. return err;
  2115. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  2116. if (spec->autocfg.dig_out_pin)
  2117. spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID;
  2118. if (spec->kctl_alloc)
  2119. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  2120. spec->input_mux = &spec->private_imux;
  2121. return 1;
  2122. }
  2123. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2124. static struct hda_amp_list vt1708S_loopbacks[] = {
  2125. { 0x16, HDA_INPUT, 1 },
  2126. { 0x16, HDA_INPUT, 2 },
  2127. { 0x16, HDA_INPUT, 3 },
  2128. { 0x16, HDA_INPUT, 4 },
  2129. { } /* end */
  2130. };
  2131. #endif
  2132. static int patch_vt1708S(struct hda_codec *codec)
  2133. {
  2134. struct via_spec *spec;
  2135. int err;
  2136. /* create a codec specific record */
  2137. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  2138. if (spec == NULL)
  2139. return -ENOMEM;
  2140. codec->spec = spec;
  2141. /* automatic parse from the BIOS config */
  2142. err = vt1708S_parse_auto_config(codec);
  2143. if (err < 0) {
  2144. via_free(codec);
  2145. return err;
  2146. } else if (!err) {
  2147. printk(KERN_INFO "hda_codec: Cannot set up configuration "
  2148. "from BIOS. Using genenic mode...\n");
  2149. }
  2150. spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
  2151. spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
  2152. spec->stream_name_analog = "VT1708S Analog";
  2153. spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
  2154. spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
  2155. spec->stream_name_digital = "VT1708S Digital";
  2156. spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
  2157. if (!spec->adc_nids && spec->input_mux) {
  2158. spec->adc_nids = vt1708S_adc_nids;
  2159. spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
  2160. spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
  2161. spec->num_mixers++;
  2162. }
  2163. codec->patch_ops = via_patch_ops;
  2164. codec->patch_ops.init = via_auto_init;
  2165. codec->patch_ops.unsol_event = via_unsol_event;
  2166. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2167. spec->loopback.amplist = vt1708S_loopbacks;
  2168. #endif
  2169. return 0;
  2170. }
  2171. /* Patch for VT1702 */
  2172. /* capture mixer elements */
  2173. static struct snd_kcontrol_new vt1702_capture_mixer[] = {
  2174. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
  2175. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
  2176. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
  2177. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
  2178. HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
  2179. HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
  2180. HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
  2181. HDA_INPUT),
  2182. {
  2183. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  2184. /* The multiple "Capture Source" controls confuse alsamixer
  2185. * So call somewhat different..
  2186. */
  2187. /* .name = "Capture Source", */
  2188. .name = "Input Source",
  2189. .count = 1,
  2190. .info = via_mux_enum_info,
  2191. .get = via_mux_enum_get,
  2192. .put = via_mux_enum_put,
  2193. },
  2194. { } /* end */
  2195. };
  2196. static struct hda_verb vt1702_volume_init_verbs[] = {
  2197. /*
  2198. * Unmute ADC0-1 and set the default input to mic-in
  2199. */
  2200. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2201. {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2202. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2203. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  2204. * mixer widget
  2205. */
  2206. /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
  2207. {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2208. {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2209. {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  2210. {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  2211. {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  2212. /* Setup default input of PW4 to MW0 */
  2213. {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
  2214. /* PW6 PW7 Output enable */
  2215. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  2216. {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  2217. { }
  2218. };
  2219. static struct hda_verb vt1702_uniwill_init_verbs[] = {
  2220. {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT},
  2221. {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
  2222. { }
  2223. };
  2224. static struct hda_pcm_stream vt1702_pcm_analog_playback = {
  2225. .substreams = 1,
  2226. .channels_min = 2,
  2227. .channels_max = 2,
  2228. .nid = 0x10, /* NID to query formats and rates */
  2229. .ops = {
  2230. .open = via_playback_pcm_open,
  2231. .prepare = via_playback_pcm_prepare,
  2232. .cleanup = via_playback_pcm_cleanup
  2233. },
  2234. };
  2235. static struct hda_pcm_stream vt1702_pcm_analog_capture = {
  2236. .substreams = 3,
  2237. .channels_min = 2,
  2238. .channels_max = 2,
  2239. .nid = 0x12, /* NID to query formats and rates */
  2240. .ops = {
  2241. .prepare = via_capture_pcm_prepare,
  2242. .cleanup = via_capture_pcm_cleanup
  2243. },
  2244. };
  2245. static struct hda_pcm_stream vt1702_pcm_digital_playback = {
  2246. .substreams = 1,
  2247. .channels_min = 2,
  2248. .channels_max = 2,
  2249. /* NID is set in via_build_pcms */
  2250. .ops = {
  2251. .open = via_dig_playback_pcm_open,
  2252. .close = via_dig_playback_pcm_close,
  2253. .prepare = via_dig_playback_pcm_prepare
  2254. },
  2255. };
  2256. /* fill in the dac_nids table from the parsed pin configuration */
  2257. static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
  2258. const struct auto_pin_cfg *cfg)
  2259. {
  2260. spec->multiout.num_dacs = 1;
  2261. spec->multiout.dac_nids = spec->private_dac_nids;
  2262. if (cfg->line_out_pins[0]) {
  2263. /* config dac list */
  2264. spec->multiout.dac_nids[0] = 0x10;
  2265. }
  2266. return 0;
  2267. }
  2268. /* add playback controls from the parsed DAC table */
  2269. static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
  2270. const struct auto_pin_cfg *cfg)
  2271. {
  2272. int err;
  2273. if (!cfg->line_out_pins[0])
  2274. return -1;
  2275. /* add control to mixer index 0 */
  2276. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  2277. "Master Front Playback Volume",
  2278. HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
  2279. if (err < 0)
  2280. return err;
  2281. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  2282. "Master Front Playback Switch",
  2283. HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
  2284. if (err < 0)
  2285. return err;
  2286. /* Front */
  2287. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  2288. "Front Playback Volume",
  2289. HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
  2290. if (err < 0)
  2291. return err;
  2292. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  2293. "Front Playback Switch",
  2294. HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
  2295. if (err < 0)
  2296. return err;
  2297. return 0;
  2298. }
  2299. static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
  2300. {
  2301. int err;
  2302. if (!pin)
  2303. return 0;
  2304. spec->multiout.hp_nid = 0x1D;
  2305. err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
  2306. "Headphone Playback Volume",
  2307. HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
  2308. if (err < 0)
  2309. return err;
  2310. err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
  2311. "Headphone Playback Switch",
  2312. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  2313. if (err < 0)
  2314. return err;
  2315. return 0;
  2316. }
  2317. /* create playback/capture controls for input pins */
  2318. static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
  2319. const struct auto_pin_cfg *cfg)
  2320. {
  2321. static char *labels[] = {
  2322. "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
  2323. };
  2324. struct hda_input_mux *imux = &spec->private_imux;
  2325. int i, err, idx = 0;
  2326. /* for internal loopback recording select */
  2327. imux->items[imux->num_items].label = "Stereo Mixer";
  2328. imux->items[imux->num_items].index = 3;
  2329. imux->num_items++;
  2330. for (i = 0; i < AUTO_PIN_LAST; i++) {
  2331. if (!cfg->input_pins[i])
  2332. continue;
  2333. switch (cfg->input_pins[i]) {
  2334. case 0x14: /* Mic */
  2335. idx = 1;
  2336. break;
  2337. case 0x15: /* Line In */
  2338. idx = 2;
  2339. break;
  2340. case 0x18: /* Front Mic */
  2341. idx = 3;
  2342. break;
  2343. }
  2344. err = via_new_analog_input(spec, cfg->input_pins[i],
  2345. labels[i], idx, 0x1A);
  2346. if (err < 0)
  2347. return err;
  2348. imux->items[imux->num_items].label = labels[i];
  2349. imux->items[imux->num_items].index = idx-1;
  2350. imux->num_items++;
  2351. }
  2352. return 0;
  2353. }
  2354. static int vt1702_parse_auto_config(struct hda_codec *codec)
  2355. {
  2356. struct via_spec *spec = codec->spec;
  2357. int err;
  2358. static hda_nid_t vt1702_ignore[] = {0x1C, 0};
  2359. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  2360. vt1702_ignore);
  2361. if (err < 0)
  2362. return err;
  2363. err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
  2364. if (err < 0)
  2365. return err;
  2366. if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
  2367. return 0; /* can't find valid BIOS pin config */
  2368. err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
  2369. if (err < 0)
  2370. return err;
  2371. err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  2372. if (err < 0)
  2373. return err;
  2374. err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
  2375. if (err < 0)
  2376. return err;
  2377. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  2378. if (spec->autocfg.dig_out_pin)
  2379. spec->multiout.dig_out_nid = VT1702_DIGOUT_NID;
  2380. if (spec->kctl_alloc)
  2381. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  2382. spec->input_mux = &spec->private_imux;
  2383. return 1;
  2384. }
  2385. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2386. static struct hda_amp_list vt1702_loopbacks[] = {
  2387. { 0x1A, HDA_INPUT, 1 },
  2388. { 0x1A, HDA_INPUT, 2 },
  2389. { 0x1A, HDA_INPUT, 3 },
  2390. { 0x1A, HDA_INPUT, 4 },
  2391. { } /* end */
  2392. };
  2393. #endif
  2394. static int patch_vt1702(struct hda_codec *codec)
  2395. {
  2396. struct via_spec *spec;
  2397. int err;
  2398. unsigned int response;
  2399. unsigned char control;
  2400. /* create a codec specific record */
  2401. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  2402. if (spec == NULL)
  2403. return -ENOMEM;
  2404. codec->spec = spec;
  2405. /* automatic parse from the BIOS config */
  2406. err = vt1702_parse_auto_config(codec);
  2407. if (err < 0) {
  2408. via_free(codec);
  2409. return err;
  2410. } else if (!err) {
  2411. printk(KERN_INFO "hda_codec: Cannot set up configuration "
  2412. "from BIOS. Using genenic mode...\n");
  2413. }
  2414. spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
  2415. spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
  2416. spec->stream_name_analog = "VT1702 Analog";
  2417. spec->stream_analog_playback = &vt1702_pcm_analog_playback;
  2418. spec->stream_analog_capture = &vt1702_pcm_analog_capture;
  2419. spec->stream_name_digital = "VT1702 Digital";
  2420. spec->stream_digital_playback = &vt1702_pcm_digital_playback;
  2421. if (!spec->adc_nids && spec->input_mux) {
  2422. spec->adc_nids = vt1702_adc_nids;
  2423. spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
  2424. spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
  2425. spec->num_mixers++;
  2426. }
  2427. codec->patch_ops = via_patch_ops;
  2428. codec->patch_ops.init = via_auto_init;
  2429. codec->patch_ops.unsol_event = via_unsol_event;
  2430. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2431. spec->loopback.amplist = vt1702_loopbacks;
  2432. #endif
  2433. /* Open backdoor */
  2434. response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0);
  2435. control = (unsigned char)(response & 0xff);
  2436. control |= 0x3;
  2437. snd_hda_codec_write(codec, codec->afg, 0, 0xF88, control);
  2438. /* Enable GPIO 0&1 for volume&mute control */
  2439. /* Enable GPIO 2 for DMIC-DATA */
  2440. response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0);
  2441. control = (unsigned char)((response >> 16) & 0x3f);
  2442. snd_hda_codec_write(codec, codec->afg, 0, 0xF82, control);
  2443. return 0;
  2444. }
  2445. /*
  2446. * patch entries
  2447. */
  2448. struct hda_codec_preset snd_hda_preset_via[] = {
  2449. { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
  2450. { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
  2451. { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
  2452. { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
  2453. { .id = 0x1106E710, .name = "VIA VT1709 10-Ch",
  2454. .patch = patch_vt1709_10ch},
  2455. { .id = 0x1106E711, .name = "VIA VT1709 10-Ch",
  2456. .patch = patch_vt1709_10ch},
  2457. { .id = 0x1106E712, .name = "VIA VT1709 10-Ch",
  2458. .patch = patch_vt1709_10ch},
  2459. { .id = 0x1106E713, .name = "VIA VT1709 10-Ch",
  2460. .patch = patch_vt1709_10ch},
  2461. { .id = 0x1106E714, .name = "VIA VT1709 6-Ch",
  2462. .patch = patch_vt1709_6ch},
  2463. { .id = 0x1106E715, .name = "VIA VT1709 6-Ch",
  2464. .patch = patch_vt1709_6ch},
  2465. { .id = 0x1106E716, .name = "VIA VT1709 6-Ch",
  2466. .patch = patch_vt1709_6ch},
  2467. { .id = 0x1106E717, .name = "VIA VT1709 6-Ch",
  2468. .patch = patch_vt1709_6ch},
  2469. { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch",
  2470. .patch = patch_vt1708B_8ch},
  2471. { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch",
  2472. .patch = patch_vt1708B_8ch},
  2473. { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch",
  2474. .patch = patch_vt1708B_8ch},
  2475. { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch",
  2476. .patch = patch_vt1708B_8ch},
  2477. { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch",
  2478. .patch = patch_vt1708B_4ch},
  2479. { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch",
  2480. .patch = patch_vt1708B_4ch},
  2481. { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch",
  2482. .patch = patch_vt1708B_4ch},
  2483. { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch",
  2484. .patch = patch_vt1708B_4ch},
  2485. { .id = 0x11060397, .name = "VIA VT1708S",
  2486. .patch = patch_vt1708S},
  2487. { .id = 0x11061397, .name = "VIA VT1708S",
  2488. .patch = patch_vt1708S},
  2489. { .id = 0x11062397, .name = "VIA VT1708S",
  2490. .patch = patch_vt1708S},
  2491. { .id = 0x11063397, .name = "VIA VT1708S",
  2492. .patch = patch_vt1708S},
  2493. { .id = 0x11064397, .name = "VIA VT1708S",
  2494. .patch = patch_vt1708S},
  2495. { .id = 0x11065397, .name = "VIA VT1708S",
  2496. .patch = patch_vt1708S},
  2497. { .id = 0x11066397, .name = "VIA VT1708S",
  2498. .patch = patch_vt1708S},
  2499. { .id = 0x11067397, .name = "VIA VT1708S",
  2500. .patch = patch_vt1708S},
  2501. { .id = 0x11060398, .name = "VIA VT1702",
  2502. .patch = patch_vt1702},
  2503. { .id = 0x11061398, .name = "VIA VT1702",
  2504. .patch = patch_vt1702},
  2505. { .id = 0x11062398, .name = "VIA VT1702",
  2506. .patch = patch_vt1702},
  2507. { .id = 0x11063398, .name = "VIA VT1702",
  2508. .patch = patch_vt1702},
  2509. { .id = 0x11064398, .name = "VIA VT1702",
  2510. .patch = patch_vt1702},
  2511. { .id = 0x11065398, .name = "VIA VT1702",
  2512. .patch = patch_vt1702},
  2513. { .id = 0x11066398, .name = "VIA VT1702",
  2514. .patch = patch_vt1702},
  2515. { .id = 0x11067398, .name = "VIA VT1702",
  2516. .patch = patch_vt1702},
  2517. {} /* terminator */
  2518. };