patch_via.c 89 KB

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