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