001-soc-audio-support.patch 92 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866
  1. From ef05a3ce8340c7156610b173324ab793b06e0ae2 Mon Sep 17 00:00:00 2001
  2. From: Michal Ulianko <info@itserve.cz>
  3. Date: Mon, 29 Jul 2013 20:14:38 +0200
  4. Subject: [PATCH 1/2] Added ASoC driver for i.MX233's builtin ADC/DAC codec.
  5. ---
  6. sound/soc/codecs/Kconfig | 4 +
  7. sound/soc/codecs/Makefile | 2 +
  8. sound/soc/codecs/mxs-builtin-codec.c | 1128 ++++++++++++++++++++++++++++++++++
  9. sound/soc/codecs/mxs-builtin-codec.h | 825 +++++++++++++++++++++++++
  10. sound/soc/mxs/Kconfig | 10 +
  11. sound/soc/mxs/Makefile | 9 +
  12. sound/soc/mxs/mxs-builtin-audio.c | 120 ++++
  13. sound/soc/mxs/mxs-builtin-dai.c | 588 ++++++++++++++++++
  14. sound/soc/mxs/mxs-builtin-pcm.c | 69 +++
  15. sound/soc/mxs/mxs-builtin-pcm.h | 25 +
  16. 10 files changed, 2780 insertions(+)
  17. create mode 100644 sound/soc/codecs/mxs-builtin-codec.c
  18. create mode 100644 sound/soc/codecs/mxs-builtin-codec.h
  19. create mode 100644 sound/soc/mxs/mxs-builtin-audio.c
  20. create mode 100644 sound/soc/mxs/mxs-builtin-dai.c
  21. create mode 100644 sound/soc/mxs/mxs-builtin-pcm.c
  22. create mode 100644 sound/soc/mxs/mxs-builtin-pcm.h
  23. --- a/sound/soc/codecs/Kconfig
  24. +++ b/sound/soc/codecs/Kconfig
  25. @@ -164,6 +164,7 @@ config SND_SOC_ALL_CODECS
  26. select SND_SOC_WM9705 if SND_SOC_AC97_BUS
  27. select SND_SOC_WM9712 if SND_SOC_AC97_BUS
  28. select SND_SOC_WM9713 if SND_SOC_AC97_BUS
  29. + select SND_SOC_MXS_BUILTIN_CODEC
  30. help
  31. Normally ASoC codec drivers are only built if a machine driver which
  32. uses them is also built since they are only usable with a machine
  33. @@ -789,6 +790,9 @@ config SND_SOC_WM9712
  34. config SND_SOC_WM9713
  35. tristate
  36. +config SND_SOC_MXS_BUILTIN_CODEC
  37. + tristate
  38. +
  39. # Amp
  40. config SND_SOC_LM4857
  41. tristate
  42. --- a/sound/soc/codecs/Makefile
  43. +++ b/sound/soc/codecs/Makefile
  44. @@ -166,6 +166,7 @@ snd-soc-wm9705-objs := wm9705.o
  45. snd-soc-wm9712-objs := wm9712.o
  46. snd-soc-wm9713-objs := wm9713.o
  47. snd-soc-wm-hubs-objs := wm_hubs.o
  48. +snd-soc-mxs-builtin-codec-objs := mxs-builtin-codec.o
  49. # Amp
  50. snd-soc-max9877-objs := max9877.o
  51. @@ -339,6 +340,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-
  52. obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
  53. obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
  54. obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
  55. +obj-$(CONFIG_SND_SOC_MXS_BUILTIN_CODEC) += snd-soc-mxs-builtin-codec.o
  56. # Amp
  57. obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
  58. --- /dev/null
  59. +++ b/sound/soc/codecs/mxs-builtin-codec.c
  60. @@ -0,0 +1,1128 @@
  61. +/*
  62. + * mxs-builtin-codec.c -- i.MX233 built-in codec ALSA Soc Audio driver
  63. + *
  64. + * Author: Michal Ulianko <michal.ulianko@gmail.com>
  65. + *
  66. + * Based on sound/soc/codecs/mxs-adc-codec.c for kernel 2.6.35
  67. + * by Vladislav Buzov <vbuzov@embeddedalley.com>
  68. + *
  69. + * This program is free software; you can redistribute it and/or modify
  70. + * it under the terms of the GNU General Public License version 2 as
  71. + * published by the Free Software Foundation.
  72. + */
  73. +
  74. +#include <linux/clk.h>
  75. +#include <linux/delay.h>
  76. +#include <linux/module.h>
  77. +#include <linux/platform_device.h>
  78. +#include <sound/pcm.h>
  79. +#include <sound/pcm_params.h>
  80. +#include <sound/soc.h>
  81. +
  82. +#include "mxs-builtin-codec.h"
  83. +
  84. +#ifndef BF
  85. +#define BF(value, field) (((value) << BP_##field) & BM_##field)
  86. +#endif
  87. +
  88. +/* TODO Delete this and use BM_RTC_PERSISTENT0_RELEASE_GND from header file
  89. + * if it works. */
  90. +#define BP_RTC_PERSISTENT0_SPARE_ANALOG 18
  91. +#define BM_RTC_PERSISTENT0_SPARE_ANALOG 0xFFFC0000
  92. +#define BM_RTC_PERSISTENT0_RELEASE_GND BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG)
  93. +
  94. +/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */
  95. +
  96. +struct mxs_adc_priv {
  97. + void __iomem *ain_base;
  98. + void __iomem *aout_base;
  99. + void __iomem *rtc_base;
  100. + struct clk *clk;
  101. +};
  102. +
  103. +static unsigned int mxs_regmap[] = {
  104. + HW_AUDIOOUT_CTRL,
  105. + HW_AUDIOOUT_STAT,
  106. + HW_AUDIOOUT_DACSRR,
  107. + HW_AUDIOOUT_DACVOLUME,
  108. + HW_AUDIOOUT_DACDEBUG,
  109. + HW_AUDIOOUT_HPVOL,
  110. + HW_AUDIOOUT_PWRDN,
  111. + HW_AUDIOOUT_REFCTRL,
  112. + HW_AUDIOOUT_ANACTRL,
  113. + HW_AUDIOOUT_TEST,
  114. + HW_AUDIOOUT_BISTCTRL,
  115. + HW_AUDIOOUT_BISTSTAT0,
  116. + HW_AUDIOOUT_BISTSTAT1,
  117. + HW_AUDIOOUT_ANACLKCTRL,
  118. + HW_AUDIOOUT_DATA,
  119. + HW_AUDIOOUT_SPEAKERCTRL,
  120. + HW_AUDIOOUT_VERSION,
  121. + HW_AUDIOIN_CTRL,
  122. + HW_AUDIOIN_STAT,
  123. + HW_AUDIOIN_ADCSRR,
  124. + HW_AUDIOIN_ADCVOLUME,
  125. + HW_AUDIOIN_ADCDEBUG,
  126. + HW_AUDIOIN_ADCVOL,
  127. + HW_AUDIOIN_MICLINE,
  128. + HW_AUDIOIN_ANACLKCTRL,
  129. + HW_AUDIOIN_DATA,
  130. +};
  131. +
  132. +static void __iomem *mxs_getreg(struct mxs_adc_priv *mxs_adc, int i)
  133. +{
  134. + if (i <= 16)
  135. + return mxs_adc->aout_base + mxs_regmap[i];
  136. + else if (i < ADC_REGNUM)
  137. + return mxs_adc->ain_base + mxs_regmap[i];
  138. + else
  139. + return NULL;
  140. +}
  141. +
  142. +static u8 dac_volumn_control_word[] = {
  143. + 0x37, 0x5e, 0x7e, 0x8e,
  144. + 0x9e, 0xae, 0xb6, 0xbe,
  145. + 0xc6, 0xce, 0xd6, 0xde,
  146. + 0xe6, 0xee, 0xf6, 0xfe,
  147. +};
  148. +
  149. +struct dac_srr {
  150. + u32 rate;
  151. + u32 basemult;
  152. + u32 src_hold;
  153. + u32 src_int;
  154. + u32 src_frac;
  155. +};
  156. +
  157. +static struct dac_srr srr_values[] = {
  158. + {192000, 0x4, 0x0, 0x0F, 0x13FF},
  159. + {176400, 0x4, 0x0, 0x11, 0x0037},
  160. + {128000, 0x4, 0x0, 0x17, 0x0E00},
  161. + {96000, 0x2, 0x0, 0x0F, 0x13FF},
  162. + {88200, 0x2, 0x0, 0x11, 0x0037},
  163. + {64000, 0x2, 0x0, 0x17, 0x0E00},
  164. + {48000, 0x1, 0x0, 0x0F, 0x13FF},
  165. + {44100, 0x1, 0x0, 0x11, 0x0037},
  166. + {32000, 0x1, 0x0, 0x17, 0x0E00},
  167. + {24000, 0x1, 0x1, 0x0F, 0x13FF},
  168. + {22050, 0x1, 0x1, 0x11, 0x0037},
  169. + {16000, 0x1, 0x1, 0x17, 0x0E00},
  170. + {12000, 0x1, 0x3, 0x0F, 0x13FF},
  171. + {11025, 0x1, 0x3, 0x11, 0x0037},
  172. + {8000, 0x1, 0x3, 0x17, 0x0E00}
  173. +};
  174. +
  175. +static inline int get_srr_values(int rate)
  176. +{
  177. + int i;
  178. +
  179. + for (i = 0; i < ARRAY_SIZE(srr_values); i++)
  180. + if (srr_values[i].rate == rate)
  181. + return i;
  182. +
  183. + return -1;
  184. +}
  185. +
  186. +/* SoC IO functions */
  187. +static void mxs_codec_write_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
  188. +{
  189. + u16 *cache = codec->reg_cache;
  190. + if (reg < ADC_REGNUM)
  191. + cache[reg] = value;
  192. +}
  193. +
  194. +static int mxs_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
  195. +{
  196. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  197. + unsigned int reg_val;
  198. + unsigned int mask = 0xffff;
  199. +
  200. + if (reg >= ADC_REGNUM)
  201. + return -EIO;
  202. +
  203. + mxs_codec_write_cache(codec, reg, value);
  204. +
  205. + if (reg & 0x1) {
  206. + mask <<= 16;
  207. + value <<= 16;
  208. + }
  209. +
  210. + reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1));
  211. + reg_val = (reg_val & ~mask) | value;
  212. + __raw_writel(reg_val, mxs_getreg(mxs_adc, reg >> 1));
  213. +
  214. + return 0;
  215. +}
  216. +
  217. +static unsigned int mxs_codec_read(struct snd_soc_codec *codec, unsigned int reg)
  218. +{
  219. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  220. + unsigned int reg_val;
  221. +
  222. + if (reg >= ADC_REGNUM)
  223. + return -1;
  224. +
  225. + reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1));
  226. + if (reg & 1)
  227. + reg_val >>= 16;
  228. +
  229. + return reg_val & 0xffff;
  230. +}
  231. +
  232. +// static unsigned int mxs_codec_read_cache(struct snd_soc_codec *codec, unsigned int reg)
  233. +// {
  234. +// u16 *cache = codec->reg_cache;
  235. +// if (reg >= ADC_REGNUM)
  236. +// return -EINVAL;
  237. +// return cache[reg];
  238. +// }
  239. +
  240. +static void mxs_codec_sync_reg_cache(struct snd_soc_codec *codec)
  241. +{
  242. + int reg;
  243. + for (reg = 0; reg < ADC_REGNUM; reg += 1)
  244. + mxs_codec_write_cache(codec, reg,
  245. + mxs_codec_read(codec, reg));
  246. +}
  247. +
  248. +// static int mxs_codec_restore_reg(struct snd_soc_codec *codec, unsigned int reg)
  249. +// {
  250. +// unsigned int cached_val, hw_val;
  251. +//
  252. +// cached_val = mxs_codec_read_cache(codec, reg);
  253. +// hw_val = mxs_codec_read(codec, reg);
  254. +//
  255. +// if (hw_val != cached_val)
  256. +// return mxs_codec_write(codec, reg, cached_val);
  257. +//
  258. +// return 0;
  259. +// }
  260. +/* END SoC IO functions */
  261. +
  262. +/* Codec routines */
  263. +#define VAG_BASE_VALUE ((1400/2 - 625)/25)
  264. +
  265. +static void mxs_codec_dac_set_vag(struct mxs_adc_priv *mxs_adc)
  266. +{
  267. + u32 refctrl_val = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL);
  268. +
  269. + refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VAG_VAL);
  270. + refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VBG_ADJ);
  271. + refctrl_val |= BF(VAG_BASE_VALUE, AUDIOOUT_REFCTRL_VAG_VAL) |
  272. + BM_AUDIOOUT_REFCTRL_ADJ_VAG |
  273. + BF(0xF, AUDIOOUT_REFCTRL_ADC_REFVAL) |
  274. + BM_AUDIOOUT_REFCTRL_ADJ_ADC |
  275. + BF(0x3, AUDIOOUT_REFCTRL_VBG_ADJ) | BM_AUDIOOUT_REFCTRL_RAISE_REF;
  276. +
  277. + __raw_writel(refctrl_val, mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL);
  278. +}
  279. +
  280. +static bool mxs_codec_dac_is_capless(struct mxs_adc_priv *mxs_adc)
  281. +{
  282. + if ((__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_PWRDN)
  283. + & BM_AUDIOOUT_PWRDN_CAPLESS) == 0)
  284. + return false;
  285. + else
  286. + return true;
  287. +}
  288. +
  289. +static void mxs_codec_dac_arm_short_cm(struct mxs_adc_priv *mxs_adc, bool bShort)
  290. +{
  291. + __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_CM),
  292. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
  293. + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_CM_STS,
  294. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
  295. + if (bShort)
  296. + __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_CM),
  297. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
  298. +}
  299. +
  300. +static void mxs_codec_dac_arm_short_lr(struct mxs_adc_priv *mxs_adc, bool bShort)
  301. +{
  302. + __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_LR),
  303. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
  304. + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
  305. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
  306. + if (bShort)
  307. + __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_LR),
  308. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
  309. +}
  310. +
  311. +static void mxs_codec_dac_set_short_trip_level(struct mxs_adc_priv *mxs_adc, u8 u8level)
  312. +{
  313. + __raw_writel(__raw_readl(mxs_adc->aout_base +
  314. + HW_AUDIOOUT_ANACTRL)
  315. + & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL)
  316. + & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR)
  317. + | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJL)
  318. + | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJR),
  319. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL);
  320. +}
  321. +
  322. +static void mxs_codec_dac_arm_short(struct mxs_adc_priv *mxs_adc, bool bLatchCM, bool bLatchLR)
  323. +{
  324. + if (bLatchCM) {
  325. + if (mxs_codec_dac_is_capless(mxs_adc))
  326. + mxs_codec_dac_arm_short_cm(mxs_adc, true);
  327. + } else
  328. + mxs_codec_dac_arm_short_cm(mxs_adc, false);
  329. +
  330. + if (bLatchLR)
  331. + mxs_codec_dac_arm_short_lr(mxs_adc, true);
  332. + else
  333. + mxs_codec_dac_arm_short_lr(mxs_adc, false);
  334. +}
  335. +
  336. +static void
  337. +mxs_codec_dac_power_on(struct mxs_adc_priv *mxs_adc)
  338. +{
  339. + /* Ungate DAC clocks */
  340. + __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
  341. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
  342. + __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
  343. + mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_CLR);
  344. +
  345. + /* 16 bit word length */
  346. + __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
  347. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
  348. +
  349. + /* Arm headphone LR short protect */
  350. + mxs_codec_dac_set_short_trip_level(mxs_adc, 0);
  351. + mxs_codec_dac_arm_short(mxs_adc, false, true);
  352. +
  353. + /* Update DAC volume over zero crossings */
  354. + __raw_writel(BM_AUDIOOUT_DACVOLUME_EN_ZCD,
  355. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
  356. + /* Mute DAC */
  357. + __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
  358. + BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
  359. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
  360. +
  361. + /* Update HP volume over zero crossings */
  362. + __raw_writel(BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD,
  363. + mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
  364. +
  365. + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
  366. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
  367. +
  368. + /* Mute HP output */
  369. + __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
  370. + mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
  371. + /* Mute speaker amp */
  372. + __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
  373. + mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
  374. + /* Enable the audioout */
  375. + __raw_writel(BM_AUDIOOUT_CTRL_RUN,
  376. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
  377. +}
  378. +
  379. +static void
  380. +mxs_codec_dac_power_down(struct mxs_adc_priv *mxs_adc)
  381. +{
  382. + /* Disable the audioout */
  383. + __raw_writel(BM_AUDIOOUT_CTRL_RUN,
  384. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
  385. + /* Disable class AB */
  386. + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
  387. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
  388. +
  389. + /* Set hold to ground */
  390. + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
  391. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
  392. +
  393. + /* Mute HP output */
  394. + __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
  395. + mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
  396. + /* Power down HP output */
  397. + __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
  398. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
  399. +
  400. + /* Mute speaker amp */
  401. + __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
  402. + mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
  403. + /* Power down speaker amp */
  404. + __raw_writel(BM_AUDIOOUT_PWRDN_SPEAKER,
  405. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
  406. +
  407. + /* Mute DAC */
  408. + __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
  409. + BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
  410. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
  411. + /* Power down DAC */
  412. + __raw_writel(BM_AUDIOOUT_PWRDN_DAC,
  413. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
  414. +
  415. + /* Gate DAC clocks */
  416. + __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
  417. + mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_SET);
  418. + __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
  419. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
  420. +}
  421. +
  422. +static void
  423. +mxs_codec_adc_power_on(struct mxs_adc_priv *mxs_adc)
  424. +{
  425. + u32 reg;
  426. +
  427. + /* Ungate ADC clocks */
  428. + __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
  429. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
  430. + __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
  431. + mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_CLR);
  432. +
  433. + /* 16 bit word length */
  434. + __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
  435. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
  436. +
  437. + /* Unmute ADC channels */
  438. + __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
  439. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
  440. +
  441. + /*
  442. + * The MUTE_LEFT and MUTE_RIGHT fields need to be cleared.
  443. + * They aren't presented in the datasheet, so this is hardcode.
  444. + */
  445. + __raw_writel(0x01000100, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME_CLR);
  446. +
  447. + /* Set the Input channel gain 3dB */
  448. + __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_LEFT,
  449. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
  450. + __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_RIGHT,
  451. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
  452. + __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_LEFT),
  453. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
  454. + __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_RIGHT),
  455. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
  456. +
  457. + /* Select default input - Microphone */
  458. + __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_LEFT,
  459. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
  460. + __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_RIGHT,
  461. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
  462. + __raw_writel(BF
  463. + (BV_AUDIOIN_ADCVOL_SELECT__MIC,
  464. + AUDIOIN_ADCVOL_SELECT_LEFT),
  465. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
  466. + __raw_writel(BF
  467. + (BV_AUDIOIN_ADCVOL_SELECT__MIC,
  468. + AUDIOIN_ADCVOL_SELECT_RIGHT),
  469. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
  470. +
  471. + /* Supply bias voltage to microphone */
  472. + __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_RESISTOR),
  473. + mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
  474. + __raw_writel(BM_AUDIOIN_MICLINE_MIC_SELECT,
  475. + mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
  476. + __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_GAIN),
  477. + mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
  478. + __raw_writel(BF(7, AUDIOIN_MICLINE_MIC_BIAS),
  479. + mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
  480. +
  481. + /* Set max ADC volume */
  482. + reg = __raw_readl(mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME);
  483. + reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
  484. + reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
  485. + reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_LEFT);
  486. + reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_RIGHT);
  487. + __raw_writel(reg, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME);
  488. +}
  489. +
  490. +static void
  491. +mxs_codec_adc_power_down(struct mxs_adc_priv *mxs_adc)
  492. +{
  493. + /* Mute ADC channels */
  494. + __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
  495. + mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
  496. +
  497. + /* Power Down ADC */
  498. + __raw_writel(BM_AUDIOOUT_PWRDN_ADC | BM_AUDIOOUT_PWRDN_RIGHT_ADC,
  499. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
  500. +
  501. + /* Gate ADC clocks */
  502. + __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
  503. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
  504. + __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
  505. + mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_SET);
  506. +
  507. + /* Disable bias voltage to microphone */
  508. + __raw_writel(BF(0, AUDIOIN_MICLINE_MIC_RESISTOR),
  509. + mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
  510. +}
  511. +
  512. +static void mxs_codec_dac_enable(struct mxs_adc_priv *mxs_adc)
  513. +{
  514. + /* Move DAC codec out of reset */
  515. + __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
  516. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
  517. +
  518. + /* Reduce analog power */
  519. + __raw_writel(BM_AUDIOOUT_TEST_HP_I1_ADJ,
  520. + mxs_adc->aout_base + HW_AUDIOOUT_TEST_CLR);
  521. + __raw_writel(BF(0x1, AUDIOOUT_TEST_HP_I1_ADJ),
  522. + mxs_adc->aout_base + HW_AUDIOOUT_TEST_SET);
  523. + __raw_writel(BM_AUDIOOUT_REFCTRL_LOW_PWR,
  524. + mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET);
  525. + __raw_writel(BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS,
  526. + mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET);
  527. + __raw_writel(BM_AUDIOOUT_REFCTRL_BIAS_CTRL,
  528. + mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR);
  529. + __raw_writel(BF(0x1, AUDIOOUT_REFCTRL_BIAS_CTRL),
  530. + mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR);
  531. +
  532. + /* Set Vag value */
  533. + mxs_codec_dac_set_vag(mxs_adc);
  534. +
  535. + /* Power on DAC codec */
  536. + mxs_codec_dac_power_on(mxs_adc);
  537. +}
  538. +
  539. +static void mxs_codec_dac_disable(struct mxs_adc_priv *mxs_adc)
  540. +{
  541. + mxs_codec_dac_power_down(mxs_adc);
  542. +}
  543. +
  544. +static void mxs_codec_adc_enable(struct mxs_adc_priv *mxs_adc)
  545. +{
  546. + /* Move ADC codec out of reset */
  547. + __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
  548. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
  549. +
  550. + /* Power on ADC codec */
  551. + mxs_codec_adc_power_on(mxs_adc);
  552. +}
  553. +
  554. +static void mxs_codec_adc_disable(struct mxs_adc_priv *mxs_adc)
  555. +{
  556. + mxs_codec_adc_power_down(mxs_adc);
  557. +}
  558. +
  559. +static void mxs_codec_startup(struct snd_soc_codec *codec)
  560. +{
  561. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  562. +
  563. + /* Soft reset DAC block */
  564. + __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
  565. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
  566. + while (!(__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_CTRL)
  567. + & BM_AUDIOOUT_CTRL_CLKGATE)){
  568. + }
  569. +
  570. + /* Soft reset ADC block */
  571. + __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
  572. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
  573. + while (!(__raw_readl(mxs_adc->ain_base + HW_AUDIOIN_CTRL)
  574. + & BM_AUDIOIN_CTRL_CLKGATE)){
  575. + }
  576. +
  577. + mxs_codec_dac_enable(mxs_adc);
  578. + mxs_codec_adc_enable(mxs_adc);
  579. +
  580. + /* Sync regs and cache */
  581. + mxs_codec_sync_reg_cache(codec);
  582. +}
  583. +
  584. +static void mxs_codec_stop(struct snd_soc_codec *codec)
  585. +{
  586. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  587. +
  588. + mxs_codec_dac_disable(mxs_adc);
  589. + mxs_codec_adc_disable(mxs_adc);
  590. +}
  591. +/* END Codec routines */
  592. +
  593. +/* kcontrol */
  594. +static int dac_info_volsw(struct snd_kcontrol *kcontrol,
  595. + struct snd_ctl_elem_info *uinfo)
  596. +{
  597. + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  598. + uinfo->count = 2;
  599. + uinfo->value.integer.min = 0;
  600. + uinfo->value.integer.max = 0xf;
  601. + return 0;
  602. +}
  603. +
  604. +static int dac_get_volsw(struct snd_kcontrol *kcontrol,
  605. + struct snd_ctl_elem_value *ucontrol)
  606. +{
  607. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  608. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  609. + int reg, l, r;
  610. + int i;
  611. +
  612. + reg = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
  613. +
  614. + l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >>
  615. + BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
  616. + r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >>
  617. + BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
  618. + /*Left channel */
  619. + i = 0;
  620. + while (i < 16) {
  621. + if (l == dac_volumn_control_word[i]) {
  622. + ucontrol->value.integer.value[0] = i;
  623. + break;
  624. + }
  625. + i++;
  626. + }
  627. + if (i == 16)
  628. + ucontrol->value.integer.value[0] = i;
  629. + /*Right channel */
  630. + i = 0;
  631. + while (i < 16) {
  632. + if (r == dac_volumn_control_word[i]) {
  633. + ucontrol->value.integer.value[1] = i;
  634. + break;
  635. + }
  636. + i++;
  637. + }
  638. + if (i == 16)
  639. + ucontrol->value.integer.value[1] = i;
  640. +
  641. + return 0;
  642. +}
  643. +
  644. +static int dac_put_volsw(struct snd_kcontrol *kcontrol,
  645. + struct snd_ctl_elem_value *ucontrol)
  646. +{
  647. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  648. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  649. + int reg, l, r;
  650. + int i;
  651. +
  652. + i = ucontrol->value.integer.value[0];
  653. + l = dac_volumn_control_word[i];
  654. + /*Get dac volume for left channel */
  655. + reg = BF(l, AUDIOOUT_DACVOLUME_VOLUME_LEFT);
  656. +
  657. + i = ucontrol->value.integer.value[1];
  658. + r = dac_volumn_control_word[i];
  659. + /*Get dac volume for right channel */
  660. + reg = reg | BF(r, AUDIOOUT_DACVOLUME_VOLUME_RIGHT);
  661. +
  662. + /*Clear left/right dac volume */
  663. + __raw_writel(BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT |
  664. + BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT,
  665. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR);
  666. + __raw_writel(reg, mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
  667. +
  668. + return 0;
  669. +}
  670. +
  671. +static const char *mxs_codec_adc_input_sel[] = {
  672. + "Mic", "Line In 1", "Head Phone", "Line In 2" };
  673. +
  674. +static const char *mxs_codec_hp_output_sel[] = { "DAC Out", "Line In 1" };
  675. +
  676. +static const char *mxs_codec_adc_3d_sel[] = {
  677. + "Off", "Low", "Medium", "High" };
  678. +
  679. +static const struct soc_enum mxs_codec_enum[] = {
  680. + SOC_ENUM_SINGLE(ADC_ADCVOL_L, 12, 4, mxs_codec_adc_input_sel),
  681. + SOC_ENUM_SINGLE(ADC_ADCVOL_L, 4, 4, mxs_codec_adc_input_sel),
  682. + SOC_ENUM_SINGLE(DAC_HPVOL_H, 0, 2, mxs_codec_hp_output_sel),
  683. + SOC_ENUM_SINGLE(DAC_CTRL_L, 8, 4, mxs_codec_adc_3d_sel),
  684. +};
  685. +
  686. +static const struct snd_kcontrol_new mxs_snd_controls[] = {
  687. + /* Playback Volume */
  688. + {
  689. + .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  690. + .name = "DAC Playback Volume",
  691. + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
  692. + SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  693. + .info = dac_info_volsw,
  694. + .get = dac_get_volsw,
  695. + .put = dac_put_volsw,
  696. + },
  697. +
  698. + SOC_DOUBLE_R("DAC Playback Switch",
  699. + DAC_VOLUME_H, DAC_VOLUME_L, 8, 0x01, 1),
  700. + SOC_DOUBLE("HP Playback Volume", DAC_HPVOL_L, 8, 0, 0x7F, 1),
  701. +
  702. + /* Capture Volume */
  703. + SOC_DOUBLE_R("ADC Capture Volume",
  704. + ADC_VOLUME_H, ADC_VOLUME_L, 0, 0xFF, 0),
  705. + SOC_DOUBLE("ADC PGA Capture Volume", ADC_ADCVOL_L, 8, 0, 0x0F, 0),
  706. + SOC_SINGLE("ADC PGA Capture Switch", ADC_ADCVOL_H, 8, 0x1, 1),
  707. + SOC_SINGLE("Mic PGA Capture Volume", ADC_MICLINE_L, 0, 0x03, 0),
  708. +
  709. + /* Virtual 3D effect */
  710. + SOC_ENUM("3D effect", mxs_codec_enum[3]),
  711. +};
  712. +/* END kcontrol */
  713. +
  714. +/* DAPM */
  715. +static int pga_event(struct snd_soc_dapm_widget *w,
  716. + struct snd_kcontrol *kcontrol, int event)
  717. +{
  718. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec);
  719. +
  720. + switch (event) {
  721. + case SND_SOC_DAPM_PRE_PMU:
  722. + /* Prepare powering up HP and SPEAKER output */
  723. + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
  724. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
  725. + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
  726. + mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET);
  727. + msleep(100);
  728. + break;
  729. + case SND_SOC_DAPM_POST_PMU:
  730. + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
  731. + mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
  732. + break;
  733. + case SND_SOC_DAPM_POST_PMD:
  734. + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
  735. + mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR);
  736. + break;
  737. + }
  738. + return 0;
  739. +}
  740. +
  741. +static int adc_event(struct snd_soc_dapm_widget *w,
  742. + struct snd_kcontrol *kcontrol, int event)
  743. +{
  744. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec);
  745. +
  746. + switch (event) {
  747. + case SND_SOC_DAPM_PRE_PMU:
  748. + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
  749. + mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET);
  750. + msleep(100);
  751. + break;
  752. + case SND_SOC_DAPM_POST_PMD:
  753. + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
  754. + mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR);
  755. + break;
  756. + }
  757. + return 0;
  758. +}
  759. +
  760. +/* Left ADC Mux */
  761. +static const struct snd_kcontrol_new mxs_left_adc_controls =
  762. +SOC_DAPM_ENUM("Route", mxs_codec_enum[0]);
  763. +
  764. +/* Right ADC Mux */
  765. +static const struct snd_kcontrol_new mxs_right_adc_controls =
  766. +SOC_DAPM_ENUM("Route", mxs_codec_enum[1]);
  767. +
  768. +/* Head Phone Mux */
  769. +static const struct snd_kcontrol_new mxs_hp_controls =
  770. +SOC_DAPM_ENUM("Route", mxs_codec_enum[2]);
  771. +
  772. +static const struct snd_soc_dapm_widget mxs_dapm_widgets[] = {
  773. + SND_SOC_DAPM_ADC_E("ADC", "Capture", DAC_PWRDN_L, 8, 1, adc_event,
  774. + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  775. +
  776. + SND_SOC_DAPM_DAC("DAC", "Playback", DAC_PWRDN_L, 12, 1),
  777. +
  778. + SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
  779. + &mxs_left_adc_controls),
  780. + SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
  781. + &mxs_right_adc_controls),
  782. + SND_SOC_DAPM_MUX("HP Mux", SND_SOC_NOPM, 0, 0,
  783. + &mxs_hp_controls),
  784. + SND_SOC_DAPM_PGA_E("HP AMP", DAC_PWRDN_L, 0, 1, NULL, 0, pga_event,
  785. + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  786. + SND_SOC_DAPM_POST_PMD),
  787. + SND_SOC_DAPM_PGA("SPEAKER AMP", DAC_PWRDN_H, 8, 1, NULL, 0),
  788. + SND_SOC_DAPM_INPUT("LINE1L"),
  789. + SND_SOC_DAPM_INPUT("LINE1R"),
  790. + SND_SOC_DAPM_INPUT("LINE2L"),
  791. + SND_SOC_DAPM_INPUT("LINE2R"),
  792. + SND_SOC_DAPM_INPUT("MIC"),
  793. +
  794. + SND_SOC_DAPM_OUTPUT("SPEAKER"),
  795. + SND_SOC_DAPM_OUTPUT("HPL"),
  796. + SND_SOC_DAPM_OUTPUT("HPR"),
  797. +};
  798. +
  799. +/* routes for sgtl5000 */
  800. +static const struct snd_soc_dapm_route mxs_dapm_routes[] = {
  801. + /* Left ADC Mux */
  802. + {"Left ADC Mux", "Mic", "MIC"},
  803. + {"Left ADC Mux", "Line In 1", "LINE1L"},
  804. + {"Left ADC Mux", "Line In 2", "LINE2L"},
  805. + {"Left ADC Mux", "Head Phone", "HPL"},
  806. +
  807. + /* Right ADC Mux */
  808. + {"Right ADC Mux", "Mic", "MIC"},
  809. + {"Right ADC Mux", "Line In 1", "LINE1R"},
  810. + {"Right ADC Mux", "Line In 2", "LINE2R"},
  811. + {"Right ADC Mux", "Head Phone", "HPR"},
  812. +
  813. + /* ADC */
  814. + {"ADC", NULL, "Left ADC Mux"},
  815. + {"ADC", NULL, "Right ADC Mux"},
  816. +
  817. + /* HP Mux */
  818. + {"HP Mux", "DAC Out", "DAC"},
  819. + {"HP Mux", "Line In 1", "LINE1L"},
  820. + {"HP Mux", "Line In 1", "LINE1R"},
  821. +
  822. + /* HP amp */
  823. + {"HP AMP", NULL, "HP Mux"},
  824. + /* HP output */
  825. + {"HPR", NULL, "HP AMP"},
  826. + {"HPL", NULL, "HP AMP"},
  827. +
  828. + /* Speaker amp */
  829. + {"SPEAKER AMP", NULL, "DAC"},
  830. + {"SPEAKER", NULL, "SPEAKER AMP"},
  831. +};
  832. +/* END DAPM */
  833. +
  834. +static int mxs_set_bias_level(struct snd_soc_codec *codec,
  835. + enum snd_soc_bias_level level)
  836. +{
  837. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  838. +
  839. + pr_debug("dapm level %d\n", level);
  840. + switch (level) {
  841. + case SND_SOC_BIAS_ON: /* full On */
  842. + if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
  843. + break;
  844. + break;
  845. +
  846. + case SND_SOC_BIAS_PREPARE: /* partial On */
  847. + if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
  848. + break;
  849. + /* Set Capless mode */
  850. + __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
  851. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_CLR);
  852. + break;
  853. +
  854. + case SND_SOC_BIAS_STANDBY: /* Off, with power */
  855. + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
  856. + break;
  857. + /* Unset Capless mode */
  858. + __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
  859. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
  860. + break;
  861. +
  862. + case SND_SOC_BIAS_OFF: /* Off, without power */
  863. + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
  864. + break;
  865. + /* Unset Capless mode */
  866. + __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
  867. + mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
  868. + break;
  869. + }
  870. +
  871. + codec->dapm.bias_level = level;
  872. + return 0;
  873. +}
  874. +
  875. +/* MXS-ADC Codec DAI driver */
  876. +static int mxs_pcm_hw_params(struct snd_pcm_substream *substream,
  877. + struct snd_pcm_hw_params *params,
  878. + struct snd_soc_dai *dai)
  879. +{
  880. + struct snd_soc_codec *codec = dai->codec;
  881. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
  882. + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
  883. + int i;
  884. + u32 srr_value = 0;
  885. + u32 src_hold = 0;
  886. +
  887. + i = get_srr_values(params_rate(params));
  888. + if (i < 0)
  889. + dev_warn(codec->dev, "codec doesn't support rate %d\n",
  890. + params_rate(params));
  891. + else {
  892. + src_hold = srr_values[i].src_hold;
  893. +
  894. + srr_value =
  895. + BF(srr_values[i].basemult, AUDIOOUT_DACSRR_BASEMULT) |
  896. + BF(srr_values[i].src_int, AUDIOOUT_DACSRR_SRC_INT) |
  897. + BF(srr_values[i].src_frac, AUDIOOUT_DACSRR_SRC_FRAC) |
  898. + BF(src_hold, AUDIOOUT_DACSRR_SRC_HOLD);
  899. +
  900. + if (playback)
  901. + __raw_writel(srr_value,
  902. + mxs_adc->aout_base + HW_AUDIOOUT_DACSRR);
  903. + else
  904. + __raw_writel(srr_value,
  905. + mxs_adc->ain_base + HW_AUDIOIN_ADCSRR);
  906. + }
  907. +
  908. + switch (params_format(params)) {
  909. + case SNDRV_PCM_FORMAT_S16_LE:
  910. + if (playback)
  911. + __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
  912. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
  913. + else
  914. + __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
  915. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
  916. +
  917. + break;
  918. +
  919. + case SNDRV_PCM_FORMAT_S32_LE:
  920. + if (playback)
  921. + __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
  922. + mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
  923. + else
  924. + __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
  925. + mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
  926. +
  927. + break;
  928. +
  929. + default:
  930. + dev_warn(codec->dev, "codec doesn't support format %d\n",
  931. + params_format(params));
  932. +
  933. + }
  934. +
  935. + return 0;
  936. +}
  937. +
  938. +/* mute the codec used by alsa core */
  939. +static int mxs_codec_dig_mute(struct snd_soc_dai *codec_dai, int mute)
  940. +{
  941. + struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec_dai->codec);
  942. + int l, r;
  943. + int ll, rr;
  944. + u32 reg, reg1, reg2;
  945. + u32 dac_mask = BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
  946. + BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT;
  947. +
  948. + if (mute) {
  949. + reg = __raw_readl(mxs_adc->aout_base + \
  950. + HW_AUDIOOUT_DACVOLUME);
  951. +
  952. + reg1 = reg & ~BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
  953. + reg1 = reg1 & ~BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
  954. +
  955. + l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >>
  956. + BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
  957. + r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >>
  958. + BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
  959. +
  960. + /* fade out dac vol */
  961. + while ((l > DAC_VOLUME_MIN) || (r > DAC_VOLUME_MIN)) {
  962. + l -= 0x8;
  963. + r -= 0x8;
  964. + ll = l > DAC_VOLUME_MIN ? l : DAC_VOLUME_MIN;
  965. + rr = r > DAC_VOLUME_MIN ? r : DAC_VOLUME_MIN;
  966. + reg2 = reg1 | BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(ll)
  967. + | BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(rr);
  968. + __raw_writel(reg2,
  969. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
  970. + msleep(1);
  971. + }
  972. +
  973. + __raw_writel(dac_mask,
  974. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
  975. + reg = reg | dac_mask;
  976. + __raw_writel(reg,
  977. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
  978. + } else
  979. + __raw_writel(dac_mask,
  980. + mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR);
  981. +
  982. + return 0;
  983. +}
  984. +
  985. +#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
  986. +#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
  987. +
  988. +static const struct snd_soc_dai_ops mxs_codec_dai_ops = {
  989. + .hw_params = mxs_pcm_hw_params,
  990. + .digital_mute = mxs_codec_dig_mute,
  991. +};
  992. +
  993. +static struct snd_soc_dai_driver mxs_codec_dai_driver = {
  994. + .name = "mxs-builtin-codec-dai",
  995. + .playback = {
  996. + .stream_name = "Playback",
  997. + .channels_min = 2,
  998. + .channels_max = 2,
  999. + .rates = MXS_ADC_RATES,
  1000. + .formats = MXS_ADC_FORMATS,
  1001. + },
  1002. + .capture = {
  1003. + .stream_name = "Capture",
  1004. + .channels_min = 2,
  1005. + .channels_max = 2,
  1006. + .rates = MXS_ADC_RATES,
  1007. + .formats = MXS_ADC_FORMATS,
  1008. + },
  1009. + .ops = &mxs_codec_dai_ops,
  1010. +};
  1011. +/* END MXS-ADC Codec DAI driver */
  1012. +
  1013. +/* MXS-ADC Codec driver */
  1014. +static int mxs_codec_driver_probe(struct snd_soc_codec *codec)
  1015. +{
  1016. + int ret = 0;
  1017. + /* We don't use snd_soc_codec_set_cache_io because we are using
  1018. + * our own IO functions: write, read. */
  1019. +
  1020. + mxs_codec_startup(codec);
  1021. +
  1022. + /* leading to standby state */
  1023. + ret = mxs_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
  1024. + if (ret)
  1025. + goto err;
  1026. +
  1027. + return 0;
  1028. +
  1029. +err:
  1030. + mxs_codec_stop(codec);
  1031. +
  1032. + return ret;
  1033. +}
  1034. +
  1035. +static int mxs_codec_driver_remove(struct snd_soc_codec *codec)
  1036. +{
  1037. + mxs_codec_stop(codec);
  1038. +
  1039. + return 0;
  1040. +}
  1041. +
  1042. +// static int mxs_codec_driver_suspend(struct snd_soc_codec *codec)
  1043. +// {
  1044. +// /* TODO Enable power management. */
  1045. +// return 0;
  1046. +// }
  1047. +
  1048. +// static int mxs_codec_driver_resume(struct snd_soc_codec *codec)
  1049. +// {
  1050. +// /* TODO Enable power management. */
  1051. +// return 0;
  1052. +// }
  1053. +
  1054. +static struct snd_soc_codec_driver mxs_codec_driver = {
  1055. + .probe = mxs_codec_driver_probe,
  1056. + .remove = mxs_codec_driver_remove,
  1057. +// .suspend = mxs_codec_driver_suspend,
  1058. +// .resume = mxs_codec_driver_resume,
  1059. + .set_bias_level = mxs_set_bias_level,
  1060. + .reg_cache_size = ADC_REGNUM,
  1061. + .reg_word_size = sizeof(u16),
  1062. + .reg_cache_step = 1,
  1063. +// .reg_cache_default = mxsadc_regs,
  1064. +// .volatile_register = sgtl5000_volatile_register,
  1065. + .controls = mxs_snd_controls,
  1066. + .num_controls = ARRAY_SIZE(mxs_snd_controls),
  1067. + .dapm_widgets = mxs_dapm_widgets,
  1068. + .num_dapm_widgets = ARRAY_SIZE(mxs_dapm_widgets),
  1069. + .dapm_routes = mxs_dapm_routes,
  1070. + .num_dapm_routes = ARRAY_SIZE(mxs_dapm_routes),
  1071. + .write = mxs_codec_write,
  1072. + .read = mxs_codec_read,
  1073. +};
  1074. +/* END MXS-ADC Codec driver */
  1075. +
  1076. +/* Underlying platform device that registers codec */
  1077. +static int mxs_adc_probe(struct platform_device *pdev)
  1078. +{
  1079. + struct mxs_adc_priv *mxs_adc;
  1080. + struct resource *r;
  1081. + int ret;
  1082. +
  1083. + mxs_adc = devm_kzalloc(&pdev->dev, sizeof(struct mxs_adc_priv), GFP_KERNEL);
  1084. + if (!mxs_adc)
  1085. + return -ENOMEM;
  1086. +
  1087. + platform_set_drvdata(pdev, mxs_adc);
  1088. +
  1089. + /* audio-in IO memory */
  1090. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioin");
  1091. + if (IS_ERR(r)) {
  1092. + dev_err(&pdev->dev, "failed to get resource\n");
  1093. + return PTR_ERR(r);
  1094. + }
  1095. +
  1096. + mxs_adc->ain_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
  1097. + if (IS_ERR(mxs_adc->ain_base)) {
  1098. + dev_err(&pdev->dev, "ioremap failed\n");
  1099. + return PTR_ERR(mxs_adc->ain_base);
  1100. + }
  1101. +
  1102. + /* audio-out IO memory */
  1103. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioout");
  1104. + if (IS_ERR(r)) {
  1105. + dev_err(&pdev->dev, "failed to get resource\n");
  1106. + return PTR_ERR(r);
  1107. + }
  1108. +
  1109. + mxs_adc->aout_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
  1110. + if (IS_ERR(mxs_adc->aout_base)) {
  1111. + dev_err(&pdev->dev, "ioremap failed\n");
  1112. + return PTR_ERR(mxs_adc->aout_base);
  1113. + }
  1114. +
  1115. + /* rtc IO memory */
  1116. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
  1117. + if (IS_ERR(r)) {
  1118. + dev_err(&pdev->dev, "failed to get resource\n");
  1119. + return PTR_ERR(r);
  1120. + }
  1121. +
  1122. + mxs_adc->rtc_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
  1123. + if (IS_ERR(mxs_adc->rtc_base)) {
  1124. + dev_err(&pdev->dev, "ioremap failed\n");
  1125. + return PTR_ERR(mxs_adc->rtc_base);
  1126. + }
  1127. +
  1128. + /* Get audio clock */
  1129. + mxs_adc->clk = devm_clk_get(&pdev->dev, "filt");
  1130. + if (IS_ERR(mxs_adc->clk)) {
  1131. + ret = PTR_ERR(mxs_adc->clk);
  1132. + dev_err(&pdev->dev, "%s: Clock initialization failed\n", __func__);
  1133. + return ret;
  1134. + }
  1135. +
  1136. + /* Turn on audio clock */
  1137. + ret = clk_prepare_enable(mxs_adc->clk);
  1138. + if (unlikely(ret != 0)) {
  1139. + dev_err(&pdev->dev, "%s: Clock prepare or enable failed\n", __func__);
  1140. + return ret;
  1141. + }
  1142. +
  1143. + ret = snd_soc_register_codec(&pdev->dev,
  1144. + &mxs_codec_driver,&mxs_codec_dai_driver, 1);
  1145. + if (unlikely(ret != 0)) {
  1146. + dev_err(&pdev->dev, "Codec registration failed\n");
  1147. + goto disable_clk;
  1148. + }
  1149. +
  1150. + return 0;
  1151. +
  1152. +disable_clk:
  1153. + clk_disable_unprepare(mxs_adc->clk);
  1154. + return ret;
  1155. +}
  1156. +
  1157. +static int mxs_adc_remove(struct platform_device *pdev)
  1158. +{
  1159. + struct mxs_adc_priv *mxs_adc = platform_get_drvdata(pdev);
  1160. +
  1161. + clk_disable_unprepare(mxs_adc->clk);
  1162. + snd_soc_unregister_codec(&pdev->dev);
  1163. +
  1164. + return 0;
  1165. +}
  1166. +
  1167. +static const struct of_device_id mxs_adc_dt_ids[] = {
  1168. + { .compatible = "fsl,mxs-builtin-codec", },
  1169. + { /* sentinel */ }
  1170. +};
  1171. +MODULE_DEVICE_TABLE(of, mxs_adc_dt_ids);
  1172. +
  1173. +static struct platform_driver mxs_adc_driver = {
  1174. + .driver = {
  1175. + .name = "mxs-builtin-codec",
  1176. + .owner = THIS_MODULE,
  1177. + .of_match_table = mxs_adc_dt_ids,
  1178. + },
  1179. + .probe = mxs_adc_probe,
  1180. + .remove = mxs_adc_remove,
  1181. +};
  1182. +
  1183. +module_platform_driver(mxs_adc_driver);
  1184. +/* END Underlying platform device that registers codec */
  1185. +
  1186. +MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec Driver");
  1187. +MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
  1188. +MODULE_LICENSE("GPL");
  1189. --- /dev/null
  1190. +++ b/sound/soc/codecs/mxs-builtin-codec.h
  1191. @@ -0,0 +1,825 @@
  1192. +#ifndef __MXS_ADC_CODEC_H
  1193. +
  1194. +#include <linux/io.h>
  1195. +
  1196. +/* MXS ADC/DAC registers */
  1197. +#define DAC_CTRL_L 0
  1198. +#define DAC_CTRL_H 1
  1199. +#define DAC_STAT_L 2
  1200. +#define DAC_STAT_H 3
  1201. +#define DAC_SRR_L 4
  1202. +#define DAC_VOLUME_L 6
  1203. +#define DAC_VOLUME_H 7
  1204. +#define DAC_DEBUG_L 8
  1205. +#define DAC_DEBUG_H 9
  1206. +#define DAC_HPVOL_L 10
  1207. +#define DAC_HPVOL_H 11
  1208. +#define DAC_PWRDN_L 12
  1209. +#define DAC_PWRDN_H 13
  1210. +#define DAC_REFCTRL_L 14
  1211. +#define DAC_REFCTRL_H 15
  1212. +#define DAC_ANACTRL_L 16
  1213. +#define DAC_ANACTRL_H 17
  1214. +#define DAC_TEST_L 18
  1215. +#define DAC_TEST_H 19
  1216. +#define DAC_BISTCTRL_L 20
  1217. +#define DAC_BISTCTRL_H 21
  1218. +#define DAC_BISTSTAT0_L 22
  1219. +#define DAC_BISTSTAT0_H 23
  1220. +#define DAC_BISTSTAT1_L 24
  1221. +#define DAC_BISTSTAT1_H 25
  1222. +#define DAC_ANACLKCTRL_L 26
  1223. +#define DAC_ANACLKCTRL_H 27
  1224. +#define DAC_DATA_L 28
  1225. +#define DAC_DATA_H 29
  1226. +#define DAC_SPEAKERCTRL_L 30
  1227. +#define DAC_SPEAKERCTRL_H 31
  1228. +#define DAC_VERSION_L 32
  1229. +#define DAC_VERSION_H 33
  1230. +#define ADC_CTRL_L 34
  1231. +#define ADC_CTRL_H 35
  1232. +#define ADC_STAT_L 36
  1233. +#define ADC_STAT_H 37
  1234. +#define ADC_SRR_L 38
  1235. +#define ADC_SRR_H 39
  1236. +#define ADC_VOLUME_L 40
  1237. +#define ADC_VOLUME_H 41
  1238. +#define ADC_DEBUG_L 42
  1239. +#define ADC_DEBUG_H 43
  1240. +#define ADC_ADCVOL_L 44
  1241. +#define ADC_ADCVOL_H 45
  1242. +#define ADC_MICLINE_L 46
  1243. +#define ADC_MICLINE_H 47
  1244. +#define ADC_ANACLKCTRL_L 48
  1245. +#define ADC_ANACLKCTRL_H 49
  1246. +#define ADC_DATA_L 50
  1247. +#define ADC_DATA_H 51
  1248. +
  1249. +#define ADC_REGNUM 52
  1250. +
  1251. +#define DAC_VOLUME_MIN 0x37
  1252. +#define DAC_VOLUME_MAX 0xFE
  1253. +#define ADC_VOLUME_MIN 0x37
  1254. +#define ADC_VOLUME_MAX 0xFE
  1255. +#define HP_VOLUME_MAX 0x0
  1256. +#define HP_VOLUME_MIN 0x7F
  1257. +#define LO_VOLUME_MAX 0x0
  1258. +#define LO_VOLUME_MIN 0x1F
  1259. +
  1260. +/* RTC */
  1261. +#define HW_RTC_PERSISTENT0 (0x00000060)
  1262. +#define HW_RTC_PERSISTENT0_SET (0x00000064)
  1263. +#define HW_RTC_PERSISTENT0_CLR (0x00000068)
  1264. +#define HW_RTC_PERSISTENT0_TOG (0x0000006c)
  1265. +
  1266. +// TODO
  1267. +//#define BM_RTC_PERSISTENT0_RELEASE_GND 0x00080000
  1268. +
  1269. +/* AUDIOOUT */
  1270. +#define HW_AUDIOOUT_CTRL (0x00000000)
  1271. +#define HW_AUDIOOUT_CTRL_SET (0x00000004)
  1272. +#define HW_AUDIOOUT_CTRL_CLR (0x00000008)
  1273. +#define HW_AUDIOOUT_CTRL_TOG (0x0000000c)
  1274. +
  1275. +#define BM_AUDIOOUT_CTRL_SFTRST 0x80000000
  1276. +#define BM_AUDIOOUT_CTRL_CLKGATE 0x40000000
  1277. +#define BP_AUDIOOUT_CTRL_RSRVD4 21
  1278. +#define BM_AUDIOOUT_CTRL_RSRVD4 0x3FE00000
  1279. +#define BF_AUDIOOUT_CTRL_RSRVD4(v) \
  1280. + (((v) << 21) & BM_AUDIOOUT_CTRL_RSRVD4)
  1281. +#define BP_AUDIOOUT_CTRL_DMAWAIT_COUNT 16
  1282. +#define BM_AUDIOOUT_CTRL_DMAWAIT_COUNT 0x001F0000
  1283. +#define BF_AUDIOOUT_CTRL_DMAWAIT_COUNT(v) \
  1284. + (((v) << 16) & BM_AUDIOOUT_CTRL_DMAWAIT_COUNT)
  1285. +#define BM_AUDIOOUT_CTRL_RSRVD3 0x00008000
  1286. +#define BM_AUDIOOUT_CTRL_LR_SWAP 0x00004000
  1287. +#define BM_AUDIOOUT_CTRL_EDGE_SYNC 0x00002000
  1288. +#define BM_AUDIOOUT_CTRL_INVERT_1BIT 0x00001000
  1289. +#define BP_AUDIOOUT_CTRL_RSRVD2 10
  1290. +#define BM_AUDIOOUT_CTRL_RSRVD2 0x00000C00
  1291. +#define BF_AUDIOOUT_CTRL_RSRVD2(v) \
  1292. + (((v) << 10) & BM_AUDIOOUT_CTRL_RSRVD2)
  1293. +#define BP_AUDIOOUT_CTRL_SS3D_EFFECT 8
  1294. +#define BM_AUDIOOUT_CTRL_SS3D_EFFECT 0x00000300
  1295. +#define BF_AUDIOOUT_CTRL_SS3D_EFFECT(v) \
  1296. + (((v) << 8) & BM_AUDIOOUT_CTRL_SS3D_EFFECT)
  1297. +#define BM_AUDIOOUT_CTRL_RSRVD1 0x00000080
  1298. +#define BM_AUDIOOUT_CTRL_WORD_LENGTH 0x00000040
  1299. +#define BM_AUDIOOUT_CTRL_DAC_ZERO_ENABLE 0x00000020
  1300. +#define BM_AUDIOOUT_CTRL_LOOPBACK 0x00000010
  1301. +#define BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008
  1302. +#define BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ 0x00000004
  1303. +#define BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN 0x00000002
  1304. +#define BM_AUDIOOUT_CTRL_RUN 0x00000001
  1305. +
  1306. +#define HW_AUDIOOUT_STAT (0x00000010)
  1307. +#define HW_AUDIOOUT_STAT_SET (0x00000014)
  1308. +#define HW_AUDIOOUT_STAT_CLR (0x00000018)
  1309. +#define HW_AUDIOOUT_STAT_TOG (0x0000001c)
  1310. +
  1311. +#define BM_AUDIOOUT_STAT_DAC_PRESENT 0x80000000
  1312. +#define BP_AUDIOOUT_STAT_RSRVD1 0
  1313. +#define BM_AUDIOOUT_STAT_RSRVD1 0x7FFFFFFF
  1314. +#define BF_AUDIOOUT_STAT_RSRVD1(v) \
  1315. + (((v) << 0) & BM_AUDIOOUT_STAT_RSRVD1)
  1316. +
  1317. +#define HW_AUDIOOUT_DACSRR (0x00000020)
  1318. +#define HW_AUDIOOUT_DACSRR_SET (0x00000024)
  1319. +#define HW_AUDIOOUT_DACSRR_CLR (0x00000028)
  1320. +#define HW_AUDIOOUT_DACSRR_TOG (0x0000002c)
  1321. +
  1322. +#define BM_AUDIOOUT_DACSRR_OSR 0x80000000
  1323. +#define BV_AUDIOOUT_DACSRR_OSR__OSR6 0x0
  1324. +#define BV_AUDIOOUT_DACSRR_OSR__OSR12 0x1
  1325. +#define BP_AUDIOOUT_DACSRR_BASEMULT 28
  1326. +#define BM_AUDIOOUT_DACSRR_BASEMULT 0x70000000
  1327. +#define BF_AUDIOOUT_DACSRR_BASEMULT(v) \
  1328. + (((v) << 28) & BM_AUDIOOUT_DACSRR_BASEMULT)
  1329. +#define BV_AUDIOOUT_DACSRR_BASEMULT__SINGLE_RATE 0x1
  1330. +#define BV_AUDIOOUT_DACSRR_BASEMULT__DOUBLE_RATE 0x2
  1331. +#define BV_AUDIOOUT_DACSRR_BASEMULT__QUAD_RATE 0x4
  1332. +#define BM_AUDIOOUT_DACSRR_RSRVD2 0x08000000
  1333. +#define BP_AUDIOOUT_DACSRR_SRC_HOLD 24
  1334. +#define BM_AUDIOOUT_DACSRR_SRC_HOLD 0x07000000
  1335. +#define BF_AUDIOOUT_DACSRR_SRC_HOLD(v) \
  1336. + (((v) << 24) & BM_AUDIOOUT_DACSRR_SRC_HOLD)
  1337. +#define BP_AUDIOOUT_DACSRR_RSRVD1 21
  1338. +#define BM_AUDIOOUT_DACSRR_RSRVD1 0x00E00000
  1339. +#define BF_AUDIOOUT_DACSRR_RSRVD1(v) \
  1340. + (((v) << 21) & BM_AUDIOOUT_DACSRR_RSRVD1)
  1341. +#define BP_AUDIOOUT_DACSRR_SRC_INT 16
  1342. +#define BM_AUDIOOUT_DACSRR_SRC_INT 0x001F0000
  1343. +#define BF_AUDIOOUT_DACSRR_SRC_INT(v) \
  1344. + (((v) << 16) & BM_AUDIOOUT_DACSRR_SRC_INT)
  1345. +#define BP_AUDIOOUT_DACSRR_RSRVD0 13
  1346. +#define BM_AUDIOOUT_DACSRR_RSRVD0 0x0000E000
  1347. +#define BF_AUDIOOUT_DACSRR_RSRVD0(v) \
  1348. + (((v) << 13) & BM_AUDIOOUT_DACSRR_RSRVD0)
  1349. +#define BP_AUDIOOUT_DACSRR_SRC_FRAC 0
  1350. +#define BM_AUDIOOUT_DACSRR_SRC_FRAC 0x00001FFF
  1351. +#define BF_AUDIOOUT_DACSRR_SRC_FRAC(v) \
  1352. + (((v) << 0) & BM_AUDIOOUT_DACSRR_SRC_FRAC)
  1353. +
  1354. +#define HW_AUDIOOUT_DACVOLUME (0x00000030)
  1355. +#define HW_AUDIOOUT_DACVOLUME_SET (0x00000034)
  1356. +#define HW_AUDIOOUT_DACVOLUME_CLR (0x00000038)
  1357. +#define HW_AUDIOOUT_DACVOLUME_TOG (0x0000003c)
  1358. +
  1359. +#define BP_AUDIOOUT_DACVOLUME_RSRVD4 29
  1360. +#define BM_AUDIOOUT_DACVOLUME_RSRVD4 0xE0000000
  1361. +#define BF_AUDIOOUT_DACVOLUME_RSRVD4(v) \
  1362. + (((v) << 29) & BM_AUDIOOUT_DACVOLUME_RSRVD4)
  1363. +#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_LEFT 0x10000000
  1364. +#define BP_AUDIOOUT_DACVOLUME_RSRVD3 26
  1365. +#define BM_AUDIOOUT_DACVOLUME_RSRVD3 0x0C000000
  1366. +#define BF_AUDIOOUT_DACVOLUME_RSRVD3(v) \
  1367. + (((v) << 26) & BM_AUDIOOUT_DACVOLUME_RSRVD3)
  1368. +#define BM_AUDIOOUT_DACVOLUME_EN_ZCD 0x02000000
  1369. +#define BM_AUDIOOUT_DACVOLUME_MUTE_LEFT 0x01000000
  1370. +#define BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT 16
  1371. +#define BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT 0x00FF0000
  1372. +#define BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(v) \
  1373. + (((v) << 16) & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT)
  1374. +#define BP_AUDIOOUT_DACVOLUME_RSRVD2 13
  1375. +#define BM_AUDIOOUT_DACVOLUME_RSRVD2 0x0000E000
  1376. +#define BF_AUDIOOUT_DACVOLUME_RSRVD2(v) \
  1377. + (((v) << 13) & BM_AUDIOOUT_DACVOLUME_RSRVD2)
  1378. +#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_RIGHT 0x00001000
  1379. +#define BP_AUDIOOUT_DACVOLUME_RSRVD1 9
  1380. +#define BM_AUDIOOUT_DACVOLUME_RSRVD1 0x00000E00
  1381. +#define BF_AUDIOOUT_DACVOLUME_RSRVD1(v) \
  1382. + (((v) << 9) & BM_AUDIOOUT_DACVOLUME_RSRVD1)
  1383. +#define BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT 0x00000100
  1384. +#define BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0
  1385. +#define BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0x000000FF
  1386. +#define BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(v) \
  1387. + (((v) << 0) & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT)
  1388. +
  1389. +#define HW_AUDIOOUT_DACDEBUG (0x00000040)
  1390. +#define HW_AUDIOOUT_DACDEBUG_SET (0x00000044)
  1391. +#define HW_AUDIOOUT_DACDEBUG_CLR (0x00000048)
  1392. +#define HW_AUDIOOUT_DACDEBUG_TOG (0x0000004c)
  1393. +
  1394. +#define BM_AUDIOOUT_DACDEBUG_ENABLE_DACDMA 0x80000000
  1395. +#define BP_AUDIOOUT_DACDEBUG_RSRVD2 12
  1396. +#define BM_AUDIOOUT_DACDEBUG_RSRVD2 0x7FFFF000
  1397. +#define BF_AUDIOOUT_DACDEBUG_RSRVD2(v) \
  1398. + (((v) << 12) & BM_AUDIOOUT_DACDEBUG_RSRVD2)
  1399. +#define BP_AUDIOOUT_DACDEBUG_RAM_SS 8
  1400. +#define BM_AUDIOOUT_DACDEBUG_RAM_SS 0x00000F00
  1401. +#define BF_AUDIOOUT_DACDEBUG_RAM_SS(v) \
  1402. + (((v) << 8) & BM_AUDIOOUT_DACDEBUG_RAM_SS)
  1403. +#define BP_AUDIOOUT_DACDEBUG_RSRVD1 6
  1404. +#define BM_AUDIOOUT_DACDEBUG_RSRVD1 0x000000C0
  1405. +#define BF_AUDIOOUT_DACDEBUG_RSRVD1(v) \
  1406. + (((v) << 6) & BM_AUDIOOUT_DACDEBUG_RSRVD1)
  1407. +#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_CLK_CROSS 0x00000020
  1408. +#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_CLK_CROSS 0x00000010
  1409. +#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_HAND_SHAKE 0x00000008
  1410. +#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_HAND_SHAKE 0x00000004
  1411. +#define BM_AUDIOOUT_DACDEBUG_DMA_PREQ 0x00000002
  1412. +#define BM_AUDIOOUT_DACDEBUG_FIFO_STATUS 0x00000001
  1413. +
  1414. +#define HW_AUDIOOUT_HPVOL (0x00000050)
  1415. +#define HW_AUDIOOUT_HPVOL_SET (0x00000054)
  1416. +#define HW_AUDIOOUT_HPVOL_CLR (0x00000058)
  1417. +#define HW_AUDIOOUT_HPVOL_TOG (0x0000005c)
  1418. +
  1419. +#define BP_AUDIOOUT_HPVOL_RSRVD5 29
  1420. +#define BM_AUDIOOUT_HPVOL_RSRVD5 0xE0000000
  1421. +#define BF_AUDIOOUT_HPVOL_RSRVD5(v) \
  1422. + (((v) << 29) & BM_AUDIOOUT_HPVOL_RSRVD5)
  1423. +#define BM_AUDIOOUT_HPVOL_VOLUME_UPDATE_PENDING 0x10000000
  1424. +#define BP_AUDIOOUT_HPVOL_RSRVD4 26
  1425. +#define BM_AUDIOOUT_HPVOL_RSRVD4 0x0C000000
  1426. +#define BF_AUDIOOUT_HPVOL_RSRVD4(v) \
  1427. + (((v) << 26) & BM_AUDIOOUT_HPVOL_RSRVD4)
  1428. +#define BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD 0x02000000
  1429. +#define BM_AUDIOOUT_HPVOL_MUTE 0x01000000
  1430. +#define BP_AUDIOOUT_HPVOL_RSRVD3 17
  1431. +#define BM_AUDIOOUT_HPVOL_RSRVD3 0x00FE0000
  1432. +#define BF_AUDIOOUT_HPVOL_RSRVD3(v) \
  1433. + (((v) << 17) & BM_AUDIOOUT_HPVOL_RSRVD3)
  1434. +#define BM_AUDIOOUT_HPVOL_SELECT 0x00010000
  1435. +#define BM_AUDIOOUT_HPVOL_RSRVD2 0x00008000
  1436. +#define BP_AUDIOOUT_HPVOL_VOL_LEFT 8
  1437. +#define BM_AUDIOOUT_HPVOL_VOL_LEFT 0x00007F00
  1438. +#define BF_AUDIOOUT_HPVOL_VOL_LEFT(v) \
  1439. + (((v) << 8) & BM_AUDIOOUT_HPVOL_VOL_LEFT)
  1440. +#define BM_AUDIOOUT_HPVOL_RSRVD1 0x00000080
  1441. +#define BP_AUDIOOUT_HPVOL_VOL_RIGHT 0
  1442. +#define BM_AUDIOOUT_HPVOL_VOL_RIGHT 0x0000007F
  1443. +#define BF_AUDIOOUT_HPVOL_VOL_RIGHT(v) \
  1444. + (((v) << 0) & BM_AUDIOOUT_HPVOL_VOL_RIGHT)
  1445. +
  1446. +#define HW_AUDIOOUT_RESERVED (0x00000060)
  1447. +#define HW_AUDIOOUT_RESERVED_SET (0x00000064)
  1448. +#define HW_AUDIOOUT_RESERVED_CLR (0x00000068)
  1449. +#define HW_AUDIOOUT_RESERVED_TOG (0x0000006c)
  1450. +
  1451. +#define BP_AUDIOOUT_RESERVED_RSRVD1 0
  1452. +#define BM_AUDIOOUT_RESERVED_RSRVD1 0xFFFFFFFF
  1453. +#define BF_AUDIOOUT_RESERVED_RSRVD1(v) (v)
  1454. +
  1455. +#define HW_AUDIOOUT_PWRDN (0x00000070)
  1456. +#define HW_AUDIOOUT_PWRDN_SET (0x00000074)
  1457. +#define HW_AUDIOOUT_PWRDN_CLR (0x00000078)
  1458. +#define HW_AUDIOOUT_PWRDN_TOG (0x0000007c)
  1459. +
  1460. +#define BP_AUDIOOUT_PWRDN_RSRVD7 25
  1461. +#define BM_AUDIOOUT_PWRDN_RSRVD7 0xFE000000
  1462. +#define BF_AUDIOOUT_PWRDN_RSRVD7(v) \
  1463. + (((v) << 25) & BM_AUDIOOUT_PWRDN_RSRVD7)
  1464. +#define BM_AUDIOOUT_PWRDN_SPEAKER 0x01000000
  1465. +#define BP_AUDIOOUT_PWRDN_RSRVD6 21
  1466. +#define BM_AUDIOOUT_PWRDN_RSRVD6 0x00E00000
  1467. +#define BF_AUDIOOUT_PWRDN_RSRVD6(v) \
  1468. + (((v) << 21) & BM_AUDIOOUT_PWRDN_RSRVD6)
  1469. +#define BM_AUDIOOUT_PWRDN_SELFBIAS 0x00100000
  1470. +#define BP_AUDIOOUT_PWRDN_RSRVD5 17
  1471. +#define BM_AUDIOOUT_PWRDN_RSRVD5 0x000E0000
  1472. +#define BF_AUDIOOUT_PWRDN_RSRVD5(v) \
  1473. + (((v) << 17) & BM_AUDIOOUT_PWRDN_RSRVD5)
  1474. +#define BM_AUDIOOUT_PWRDN_RIGHT_ADC 0x00010000
  1475. +#define BP_AUDIOOUT_PWRDN_RSRVD4 13
  1476. +#define BM_AUDIOOUT_PWRDN_RSRVD4 0x0000E000
  1477. +#define BF_AUDIOOUT_PWRDN_RSRVD4(v) \
  1478. + (((v) << 13) & BM_AUDIOOUT_PWRDN_RSRVD4)
  1479. +#define BM_AUDIOOUT_PWRDN_DAC 0x00001000
  1480. +#define BP_AUDIOOUT_PWRDN_RSRVD3 9
  1481. +#define BM_AUDIOOUT_PWRDN_RSRVD3 0x00000E00
  1482. +#define BF_AUDIOOUT_PWRDN_RSRVD3(v) \
  1483. + (((v) << 9) & BM_AUDIOOUT_PWRDN_RSRVD3)
  1484. +#define BM_AUDIOOUT_PWRDN_ADC 0x00000100
  1485. +#define BP_AUDIOOUT_PWRDN_RSRVD2 5
  1486. +#define BM_AUDIOOUT_PWRDN_RSRVD2 0x000000E0
  1487. +#define BF_AUDIOOUT_PWRDN_RSRVD2(v) \
  1488. + (((v) << 5) & BM_AUDIOOUT_PWRDN_RSRVD2)
  1489. +#define BM_AUDIOOUT_PWRDN_CAPLESS 0x00000010
  1490. +#define BP_AUDIOOUT_PWRDN_RSRVD1 1
  1491. +#define BM_AUDIOOUT_PWRDN_RSRVD1 0x0000000E
  1492. +#define BF_AUDIOOUT_PWRDN_RSRVD1(v) \
  1493. + (((v) << 1) & BM_AUDIOOUT_PWRDN_RSRVD1)
  1494. +#define BM_AUDIOOUT_PWRDN_HEADPHONE 0x00000001
  1495. +
  1496. +#define HW_AUDIOOUT_REFCTRL (0x00000080)
  1497. +#define HW_AUDIOOUT_REFCTRL_SET (0x00000084)
  1498. +#define HW_AUDIOOUT_REFCTRL_CLR (0x00000088)
  1499. +#define HW_AUDIOOUT_REFCTRL_TOG (0x0000008c)
  1500. +
  1501. +#define BP_AUDIOOUT_REFCTRL_RSRVD4 27
  1502. +#define BM_AUDIOOUT_REFCTRL_RSRVD4 0xF8000000
  1503. +#define BF_AUDIOOUT_REFCTRL_RSRVD4(v) \
  1504. + (((v) << 27) & BM_AUDIOOUT_REFCTRL_RSRVD4)
  1505. +#define BM_AUDIOOUT_REFCTRL_FASTSETTLING 0x04000000
  1506. +#define BM_AUDIOOUT_REFCTRL_RAISE_REF 0x02000000
  1507. +#define BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS 0x01000000
  1508. +#define BM_AUDIOOUT_REFCTRL_RSRVD3 0x00800000
  1509. +#define BP_AUDIOOUT_REFCTRL_VBG_ADJ 20
  1510. +#define BM_AUDIOOUT_REFCTRL_VBG_ADJ 0x00700000
  1511. +#define BF_AUDIOOUT_REFCTRL_VBG_ADJ(v) \
  1512. + (((v) << 20) & BM_AUDIOOUT_REFCTRL_VBG_ADJ)
  1513. +#define BM_AUDIOOUT_REFCTRL_LOW_PWR 0x00080000
  1514. +#define BM_AUDIOOUT_REFCTRL_LW_REF 0x00040000
  1515. +#define BP_AUDIOOUT_REFCTRL_BIAS_CTRL 16
  1516. +#define BM_AUDIOOUT_REFCTRL_BIAS_CTRL 0x00030000
  1517. +#define BF_AUDIOOUT_REFCTRL_BIAS_CTRL(v) \
  1518. + (((v) << 16) & BM_AUDIOOUT_REFCTRL_BIAS_CTRL)
  1519. +#define BM_AUDIOOUT_REFCTRL_RSRVD2 0x00008000
  1520. +#define BM_AUDIOOUT_REFCTRL_VDDXTAL_TO_VDDD 0x00004000
  1521. +#define BM_AUDIOOUT_REFCTRL_ADJ_ADC 0x00002000
  1522. +#define BM_AUDIOOUT_REFCTRL_ADJ_VAG 0x00001000
  1523. +#define BP_AUDIOOUT_REFCTRL_ADC_REFVAL 8
  1524. +#define BM_AUDIOOUT_REFCTRL_ADC_REFVAL 0x00000F00
  1525. +#define BF_AUDIOOUT_REFCTRL_ADC_REFVAL(v) \
  1526. + (((v) << 8) & BM_AUDIOOUT_REFCTRL_ADC_REFVAL)
  1527. +#define BP_AUDIOOUT_REFCTRL_VAG_VAL 4
  1528. +#define BM_AUDIOOUT_REFCTRL_VAG_VAL 0x000000F0
  1529. +#define BF_AUDIOOUT_REFCTRL_VAG_VAL(v) \
  1530. + (((v) << 4) & BM_AUDIOOUT_REFCTRL_VAG_VAL)
  1531. +#define BM_AUDIOOUT_REFCTRL_RSRVD1 0x00000008
  1532. +#define BP_AUDIOOUT_REFCTRL_DAC_ADJ 0
  1533. +#define BM_AUDIOOUT_REFCTRL_DAC_ADJ 0x00000007
  1534. +#define BF_AUDIOOUT_REFCTRL_DAC_ADJ(v) \
  1535. + (((v) << 0) & BM_AUDIOOUT_REFCTRL_DAC_ADJ)
  1536. +
  1537. +#define HW_AUDIOOUT_ANACTRL (0x00000090)
  1538. +#define HW_AUDIOOUT_ANACTRL_SET (0x00000094)
  1539. +#define HW_AUDIOOUT_ANACTRL_CLR (0x00000098)
  1540. +#define HW_AUDIOOUT_ANACTRL_TOG (0x0000009c)
  1541. +
  1542. +#define BP_AUDIOOUT_ANACTRL_RSRVD8 29
  1543. +#define BM_AUDIOOUT_ANACTRL_RSRVD8 0xE0000000
  1544. +#define BF_AUDIOOUT_ANACTRL_RSRVD8(v) \
  1545. + (((v) << 29) & BM_AUDIOOUT_ANACTRL_RSRVD8)
  1546. +#define BM_AUDIOOUT_ANACTRL_SHORT_CM_STS 0x10000000
  1547. +#define BP_AUDIOOUT_ANACTRL_RSRVD7 25
  1548. +#define BM_AUDIOOUT_ANACTRL_RSRVD7 0x0E000000
  1549. +#define BF_AUDIOOUT_ANACTRL_RSRVD7(v) \
  1550. + (((v) << 25) & BM_AUDIOOUT_ANACTRL_RSRVD7)
  1551. +#define BM_AUDIOOUT_ANACTRL_SHORT_LR_STS 0x01000000
  1552. +#define BP_AUDIOOUT_ANACTRL_RSRVD6 22
  1553. +#define BM_AUDIOOUT_ANACTRL_RSRVD6 0x00C00000
  1554. +#define BF_AUDIOOUT_ANACTRL_RSRVD6(v) \
  1555. + (((v) << 22) & BM_AUDIOOUT_ANACTRL_RSRVD6)
  1556. +#define BP_AUDIOOUT_ANACTRL_SHORTMODE_CM 20
  1557. +#define BM_AUDIOOUT_ANACTRL_SHORTMODE_CM 0x00300000
  1558. +#define BF_AUDIOOUT_ANACTRL_SHORTMODE_CM(v) \
  1559. + (((v) << 20) & BM_AUDIOOUT_ANACTRL_SHORTMODE_CM)
  1560. +#define BM_AUDIOOUT_ANACTRL_RSRVD5 0x00080000
  1561. +#define BP_AUDIOOUT_ANACTRL_SHORTMODE_LR 17
  1562. +#define BM_AUDIOOUT_ANACTRL_SHORTMODE_LR 0x00060000
  1563. +#define BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(v) \
  1564. + (((v) << 17) & BM_AUDIOOUT_ANACTRL_SHORTMODE_LR)
  1565. +#define BP_AUDIOOUT_ANACTRL_RSRVD4 15
  1566. +#define BM_AUDIOOUT_ANACTRL_RSRVD4 0x00018000
  1567. +#define BF_AUDIOOUT_ANACTRL_RSRVD4(v) \
  1568. + (((v) << 15) & BM_AUDIOOUT_ANACTRL_RSRVD4)
  1569. +#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJL 12
  1570. +#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL 0x00007000
  1571. +#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJL(v) \
  1572. + (((v) << 12) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL)
  1573. +#define BM_AUDIOOUT_ANACTRL_RSRVD3 0x00000800
  1574. +#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJR 8
  1575. +#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR 0x00000700
  1576. +#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJR(v) \
  1577. + (((v) << 8) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR)
  1578. +#define BP_AUDIOOUT_ANACTRL_RSRVD2 6
  1579. +#define BM_AUDIOOUT_ANACTRL_RSRVD2 0x000000C0
  1580. +#define BF_AUDIOOUT_ANACTRL_RSRVD2(v) \
  1581. + (((v) << 6) & BM_AUDIOOUT_ANACTRL_RSRVD2)
  1582. +#define BM_AUDIOOUT_ANACTRL_HP_HOLD_GND 0x00000020
  1583. +#define BM_AUDIOOUT_ANACTRL_HP_CLASSAB 0x00000010
  1584. +#define BP_AUDIOOUT_ANACTRL_RSRVD1 0
  1585. +#define BM_AUDIOOUT_ANACTRL_RSRVD1 0x0000000F
  1586. +#define BF_AUDIOOUT_ANACTRL_RSRVD1(v) \
  1587. + (((v) << 0) & BM_AUDIOOUT_ANACTRL_RSRVD1)
  1588. +
  1589. +#define HW_AUDIOOUT_TEST (0x000000a0)
  1590. +#define HW_AUDIOOUT_TEST_SET (0x000000a4)
  1591. +#define HW_AUDIOOUT_TEST_CLR (0x000000a8)
  1592. +#define HW_AUDIOOUT_TEST_TOG (0x000000ac)
  1593. +
  1594. +#define BM_AUDIOOUT_TEST_RSRVD4 0x80000000
  1595. +#define BP_AUDIOOUT_TEST_HP_ANTIPOP 28
  1596. +#define BM_AUDIOOUT_TEST_HP_ANTIPOP 0x70000000
  1597. +#define BF_AUDIOOUT_TEST_HP_ANTIPOP(v) \
  1598. + (((v) << 28) & BM_AUDIOOUT_TEST_HP_ANTIPOP)
  1599. +#define BM_AUDIOOUT_TEST_RSRVD3 0x08000000
  1600. +#define BM_AUDIOOUT_TEST_TM_ADCIN_TOHP 0x04000000
  1601. +#define BM_AUDIOOUT_TEST_TM_LOOP 0x02000000
  1602. +#define BM_AUDIOOUT_TEST_TM_HPCOMMON 0x01000000
  1603. +#define BP_AUDIOOUT_TEST_HP_I1_ADJ 22
  1604. +#define BM_AUDIOOUT_TEST_HP_I1_ADJ 0x00C00000
  1605. +#define BF_AUDIOOUT_TEST_HP_I1_ADJ(v) \
  1606. + (((v) << 22) & BM_AUDIOOUT_TEST_HP_I1_ADJ)
  1607. +#define BP_AUDIOOUT_TEST_HP_IALL_ADJ 20
  1608. +#define BM_AUDIOOUT_TEST_HP_IALL_ADJ 0x00300000
  1609. +#define BF_AUDIOOUT_TEST_HP_IALL_ADJ(v) \
  1610. + (((v) << 20) & BM_AUDIOOUT_TEST_HP_IALL_ADJ)
  1611. +#define BP_AUDIOOUT_TEST_RSRVD2 14
  1612. +#define BM_AUDIOOUT_TEST_RSRVD2 0x000FC000
  1613. +#define BF_AUDIOOUT_TEST_RSRVD2(v) \
  1614. + (((v) << 14) & BM_AUDIOOUT_TEST_RSRVD2)
  1615. +#define BM_AUDIOOUT_TEST_VAG_CLASSA 0x00002000
  1616. +#define BM_AUDIOOUT_TEST_VAG_DOUBLE_I 0x00001000
  1617. +#define BP_AUDIOOUT_TEST_RSRVD1 4
  1618. +#define BM_AUDIOOUT_TEST_RSRVD1 0x00000FF0
  1619. +#define BF_AUDIOOUT_TEST_RSRVD1(v) \
  1620. + (((v) << 4) & BM_AUDIOOUT_TEST_RSRVD1)
  1621. +#define BM_AUDIOOUT_TEST_ADCTODAC_LOOP 0x00000008
  1622. +#define BM_AUDIOOUT_TEST_DAC_CLASSA 0x00000004
  1623. +#define BM_AUDIOOUT_TEST_DAC_DOUBLE_I 0x00000002
  1624. +#define BM_AUDIOOUT_TEST_DAC_DIS_RTZ 0x00000001
  1625. +
  1626. +#define HW_AUDIOOUT_BISTCTRL (0x000000b0)
  1627. +#define HW_AUDIOOUT_BISTCTRL_SET (0x000000b4)
  1628. +#define HW_AUDIOOUT_BISTCTRL_CLR (0x000000b8)
  1629. +#define HW_AUDIOOUT_BISTCTRL_TOG (0x000000bc)
  1630. +
  1631. +#define BP_AUDIOOUT_BISTCTRL_RSVD0 4
  1632. +#define BM_AUDIOOUT_BISTCTRL_RSVD0 0xFFFFFFF0
  1633. +#define BF_AUDIOOUT_BISTCTRL_RSVD0(v) \
  1634. + (((v) << 4) & BM_AUDIOOUT_BISTCTRL_RSVD0)
  1635. +#define BM_AUDIOOUT_BISTCTRL_FAIL 0x00000008
  1636. +#define BM_AUDIOOUT_BISTCTRL_PASS 0x00000004
  1637. +#define BM_AUDIOOUT_BISTCTRL_DONE 0x00000002
  1638. +#define BM_AUDIOOUT_BISTCTRL_START 0x00000001
  1639. +
  1640. +#define HW_AUDIOOUT_BISTSTAT0 (0x000000c0)
  1641. +#define HW_AUDIOOUT_BISTSTAT0_SET (0x000000c4)
  1642. +#define HW_AUDIOOUT_BISTSTAT0_CLR (0x000000c8)
  1643. +#define HW_AUDIOOUT_BISTSTAT0_TOG (0x000000cc)
  1644. +
  1645. +#define BP_AUDIOOUT_BISTSTAT0_RSVD0 24
  1646. +#define BM_AUDIOOUT_BISTSTAT0_RSVD0 0xFF000000
  1647. +#define BF_AUDIOOUT_BISTSTAT0_RSVD0(v) \
  1648. + (((v) << 24) & BM_AUDIOOUT_BISTSTAT0_RSVD0)
  1649. +#define BP_AUDIOOUT_BISTSTAT0_DATA 0
  1650. +#define BM_AUDIOOUT_BISTSTAT0_DATA 0x00FFFFFF
  1651. +#define BF_AUDIOOUT_BISTSTAT0_DATA(v) \
  1652. + (((v) << 0) & BM_AUDIOOUT_BISTSTAT0_DATA)
  1653. +
  1654. +#define HW_AUDIOOUT_BISTSTAT1 (0x000000d0)
  1655. +#define HW_AUDIOOUT_BISTSTAT1_SET (0x000000d4)
  1656. +#define HW_AUDIOOUT_BISTSTAT1_CLR (0x000000d8)
  1657. +#define HW_AUDIOOUT_BISTSTAT1_TOG (0x000000dc)
  1658. +
  1659. +#define BP_AUDIOOUT_BISTSTAT1_RSVD1 29
  1660. +#define BM_AUDIOOUT_BISTSTAT1_RSVD1 0xE0000000
  1661. +#define BF_AUDIOOUT_BISTSTAT1_RSVD1(v) \
  1662. + (((v) << 29) & BM_AUDIOOUT_BISTSTAT1_RSVD1)
  1663. +#define BP_AUDIOOUT_BISTSTAT1_STATE 24
  1664. +#define BM_AUDIOOUT_BISTSTAT1_STATE 0x1F000000
  1665. +#define BF_AUDIOOUT_BISTSTAT1_STATE(v) \
  1666. + (((v) << 24) & BM_AUDIOOUT_BISTSTAT1_STATE)
  1667. +#define BP_AUDIOOUT_BISTSTAT1_RSVD0 8
  1668. +#define BM_AUDIOOUT_BISTSTAT1_RSVD0 0x00FFFF00
  1669. +#define BF_AUDIOOUT_BISTSTAT1_RSVD0(v) \
  1670. + (((v) << 8) & BM_AUDIOOUT_BISTSTAT1_RSVD0)
  1671. +#define BP_AUDIOOUT_BISTSTAT1_ADDR 0
  1672. +#define BM_AUDIOOUT_BISTSTAT1_ADDR 0x000000FF
  1673. +#define BF_AUDIOOUT_BISTSTAT1_ADDR(v) \
  1674. + (((v) << 0) & BM_AUDIOOUT_BISTSTAT1_ADDR)
  1675. +
  1676. +#define HW_AUDIOOUT_ANACLKCTRL (0x000000e0)
  1677. +#define HW_AUDIOOUT_ANACLKCTRL_SET (0x000000e4)
  1678. +#define HW_AUDIOOUT_ANACLKCTRL_CLR (0x000000e8)
  1679. +#define HW_AUDIOOUT_ANACLKCTRL_TOG (0x000000ec)
  1680. +
  1681. +#define BM_AUDIOOUT_ANACLKCTRL_CLKGATE 0x80000000
  1682. +#define BP_AUDIOOUT_ANACLKCTRL_RSRVD3 5
  1683. +#define BM_AUDIOOUT_ANACLKCTRL_RSRVD3 0x7FFFFFE0
  1684. +#define BF_AUDIOOUT_ANACLKCTRL_RSRVD3(v) \
  1685. + (((v) << 5) & BM_AUDIOOUT_ANACLKCTRL_RSRVD3)
  1686. +#define BM_AUDIOOUT_ANACLKCTRL_INVERT_DACCLK 0x00000010
  1687. +#define BM_AUDIOOUT_ANACLKCTRL_RSRVD2 0x00000008
  1688. +#define BP_AUDIOOUT_ANACLKCTRL_DACDIV 0
  1689. +#define BM_AUDIOOUT_ANACLKCTRL_DACDIV 0x00000007
  1690. +#define BF_AUDIOOUT_ANACLKCTRL_DACDIV(v) \
  1691. + (((v) << 0) & BM_AUDIOOUT_ANACLKCTRL_DACDIV)
  1692. +
  1693. +#define HW_AUDIOOUT_DATA (0x000000f0)
  1694. +#define HW_AUDIOOUT_DATA_SET (0x000000f4)
  1695. +#define HW_AUDIOOUT_DATA_CLR (0x000000f8)
  1696. +#define HW_AUDIOOUT_DATA_TOG (0x000000fc)
  1697. +
  1698. +#define BP_AUDIOOUT_DATA_HIGH 16
  1699. +#define BM_AUDIOOUT_DATA_HIGH 0xFFFF0000
  1700. +#define BF_AUDIOOUT_DATA_HIGH(v) \
  1701. + (((v) << 16) & BM_AUDIOOUT_DATA_HIGH)
  1702. +#define BP_AUDIOOUT_DATA_LOW 0
  1703. +#define BM_AUDIOOUT_DATA_LOW 0x0000FFFF
  1704. +#define BF_AUDIOOUT_DATA_LOW(v) \
  1705. + (((v) << 0) & BM_AUDIOOUT_DATA_LOW)
  1706. +
  1707. +#define HW_AUDIOOUT_SPEAKERCTRL (0x00000100)
  1708. +#define HW_AUDIOOUT_SPEAKERCTRL_SET (0x00000104)
  1709. +#define HW_AUDIOOUT_SPEAKERCTRL_CLR (0x00000108)
  1710. +#define HW_AUDIOOUT_SPEAKERCTRL_TOG (0x0000010c)
  1711. +
  1712. +#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD2 25
  1713. +#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD2 0xFE000000
  1714. +#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD2(v) \
  1715. + (((v) << 25) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD2)
  1716. +#define BM_AUDIOOUT_SPEAKERCTRL_MUTE 0x01000000
  1717. +#define BP_AUDIOOUT_SPEAKERCTRL_I1_ADJ 22
  1718. +#define BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ 0x00C00000
  1719. +#define BF_AUDIOOUT_SPEAKERCTRL_I1_ADJ(v) \
  1720. + (((v) << 22) & BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ)
  1721. +#define BP_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 20
  1722. +#define BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 0x00300000
  1723. +#define BF_AUDIOOUT_SPEAKERCTRL_IALL_ADJ(v) \
  1724. + (((v) << 20) & BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ)
  1725. +#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD1 16
  1726. +#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD1 0x000F0000
  1727. +#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD1(v) \
  1728. + (((v) << 16) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD1)
  1729. +#define BP_AUDIOOUT_SPEAKERCTRL_POSDRIVER 14
  1730. +#define BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER 0x0000C000
  1731. +#define BF_AUDIOOUT_SPEAKERCTRL_POSDRIVER(v) \
  1732. + (((v) << 14) & BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER)
  1733. +#define BP_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 12
  1734. +#define BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 0x00003000
  1735. +#define BF_AUDIOOUT_SPEAKERCTRL_NEGDRIVER(v) \
  1736. + (((v) << 12) & BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER)
  1737. +#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD0 0
  1738. +#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD0 0x00000FFF
  1739. +#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD0(v) \
  1740. + (((v) << 0) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD0)
  1741. +
  1742. +#define HW_AUDIOOUT_VERSION (0x00000200)
  1743. +
  1744. +#define BP_AUDIOOUT_VERSION_MAJOR 24
  1745. +#define BM_AUDIOOUT_VERSION_MAJOR 0xFF000000
  1746. +#define BF_AUDIOOUT_VERSION_MAJOR(v) \
  1747. + (((v) << 24) & BM_AUDIOOUT_VERSION_MAJOR)
  1748. +#define BP_AUDIOOUT_VERSION_MINOR 16
  1749. +#define BM_AUDIOOUT_VERSION_MINOR 0x00FF0000
  1750. +#define BF_AUDIOOUT_VERSION_MINOR(v) \
  1751. + (((v) << 16) & BM_AUDIOOUT_VERSION_MINOR)
  1752. +#define BP_AUDIOOUT_VERSION_STEP 0
  1753. +#define BM_AUDIOOUT_VERSION_STEP 0x0000FFFF
  1754. +#define BF_AUDIOOUT_VERSION_STEP(v) \
  1755. + (((v) << 0) & BM_AUDIOOUT_VERSION_STEP)
  1756. +
  1757. +/* AUDIOIN */
  1758. +#define HW_AUDIOIN_CTRL (0x00000000)
  1759. +#define HW_AUDIOIN_CTRL_SET (0x00000004)
  1760. +#define HW_AUDIOIN_CTRL_CLR (0x00000008)
  1761. +#define HW_AUDIOIN_CTRL_TOG (0x0000000c)
  1762. +
  1763. +#define BM_AUDIOIN_CTRL_SFTRST 0x80000000
  1764. +#define BM_AUDIOIN_CTRL_CLKGATE 0x40000000
  1765. +#define BP_AUDIOIN_CTRL_RSRVD3 21
  1766. +#define BM_AUDIOIN_CTRL_RSRVD3 0x3FE00000
  1767. +#define BF_AUDIOIN_CTRL_RSRVD3(v) \
  1768. + (((v) << 21) & BM_AUDIOIN_CTRL_RSRVD3)
  1769. +#define BP_AUDIOIN_CTRL_DMAWAIT_COUNT 16
  1770. +#define BM_AUDIOIN_CTRL_DMAWAIT_COUNT 0x001F0000
  1771. +#define BF_AUDIOIN_CTRL_DMAWAIT_COUNT(v) \
  1772. + (((v) << 16) & BM_AUDIOIN_CTRL_DMAWAIT_COUNT)
  1773. +#define BP_AUDIOIN_CTRL_RSRVD1 11
  1774. +#define BM_AUDIOIN_CTRL_RSRVD1 0x0000F800
  1775. +#define BF_AUDIOIN_CTRL_RSRVD1(v) \
  1776. + (((v) << 11) & BM_AUDIOIN_CTRL_RSRVD1)
  1777. +#define BM_AUDIOIN_CTRL_LR_SWAP 0x00000400
  1778. +#define BM_AUDIOIN_CTRL_EDGE_SYNC 0x00000200
  1779. +#define BM_AUDIOIN_CTRL_INVERT_1BIT 0x00000100
  1780. +#define BM_AUDIOIN_CTRL_OFFSET_ENABLE 0x00000080
  1781. +#define BM_AUDIOIN_CTRL_HPF_ENABLE 0x00000040
  1782. +#define BM_AUDIOIN_CTRL_WORD_LENGTH 0x00000020
  1783. +#define BM_AUDIOIN_CTRL_LOOPBACK 0x00000010
  1784. +#define BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008
  1785. +#define BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ 0x00000004
  1786. +#define BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN 0x00000002
  1787. +#define BM_AUDIOIN_CTRL_RUN 0x00000001
  1788. +
  1789. +#define HW_AUDIOIN_STAT (0x00000010)
  1790. +#define HW_AUDIOIN_STAT_SET (0x00000014)
  1791. +#define HW_AUDIOIN_STAT_CLR (0x00000018)
  1792. +#define HW_AUDIOIN_STAT_TOG (0x0000001c)
  1793. +
  1794. +#define BM_AUDIOIN_STAT_ADC_PRESENT 0x80000000
  1795. +#define BP_AUDIOIN_STAT_RSRVD3 0
  1796. +#define BM_AUDIOIN_STAT_RSRVD3 0x7FFFFFFF
  1797. +#define BF_AUDIOIN_STAT_RSRVD3(v) \
  1798. + (((v) << 0) & BM_AUDIOIN_STAT_RSRVD3)
  1799. +
  1800. +#define HW_AUDIOIN_ADCSRR (0x00000020)
  1801. +#define HW_AUDIOIN_ADCSRR_SET (0x00000024)
  1802. +#define HW_AUDIOIN_ADCSRR_CLR (0x00000028)
  1803. +#define HW_AUDIOIN_ADCSRR_TOG (0x0000002c)
  1804. +
  1805. +#define BM_AUDIOIN_ADCSRR_OSR 0x80000000
  1806. +#define BV_AUDIOIN_ADCSRR_OSR__OSR6 0x0
  1807. +#define BV_AUDIOIN_ADCSRR_OSR__OSR12 0x1
  1808. +#define BP_AUDIOIN_ADCSRR_BASEMULT 28
  1809. +#define BM_AUDIOIN_ADCSRR_BASEMULT 0x70000000
  1810. +#define BF_AUDIOIN_ADCSRR_BASEMULT(v) \
  1811. + (((v) << 28) & BM_AUDIOIN_ADCSRR_BASEMULT)
  1812. +#define BV_AUDIOIN_ADCSRR_BASEMULT__SINGLE_RATE 0x1
  1813. +#define BV_AUDIOIN_ADCSRR_BASEMULT__DOUBLE_RATE 0x2
  1814. +#define BV_AUDIOIN_ADCSRR_BASEMULT__QUAD_RATE 0x4
  1815. +#define BM_AUDIOIN_ADCSRR_RSRVD2 0x08000000
  1816. +#define BP_AUDIOIN_ADCSRR_SRC_HOLD 24
  1817. +#define BM_AUDIOIN_ADCSRR_SRC_HOLD 0x07000000
  1818. +#define BF_AUDIOIN_ADCSRR_SRC_HOLD(v) \
  1819. + (((v) << 24) & BM_AUDIOIN_ADCSRR_SRC_HOLD)
  1820. +#define BP_AUDIOIN_ADCSRR_RSRVD1 21
  1821. +#define BM_AUDIOIN_ADCSRR_RSRVD1 0x00E00000
  1822. +#define BF_AUDIOIN_ADCSRR_RSRVD1(v) \
  1823. + (((v) << 21) & BM_AUDIOIN_ADCSRR_RSRVD1)
  1824. +#define BP_AUDIOIN_ADCSRR_SRC_INT 16
  1825. +#define BM_AUDIOIN_ADCSRR_SRC_INT 0x001F0000
  1826. +#define BF_AUDIOIN_ADCSRR_SRC_INT(v) \
  1827. + (((v) << 16) & BM_AUDIOIN_ADCSRR_SRC_INT)
  1828. +#define BP_AUDIOIN_ADCSRR_RSRVD0 13
  1829. +#define BM_AUDIOIN_ADCSRR_RSRVD0 0x0000E000
  1830. +#define BF_AUDIOIN_ADCSRR_RSRVD0(v) \
  1831. + (((v) << 13) & BM_AUDIOIN_ADCSRR_RSRVD0)
  1832. +#define BP_AUDIOIN_ADCSRR_SRC_FRAC 0
  1833. +#define BM_AUDIOIN_ADCSRR_SRC_FRAC 0x00001FFF
  1834. +#define BF_AUDIOIN_ADCSRR_SRC_FRAC(v) \
  1835. + (((v) << 0) & BM_AUDIOIN_ADCSRR_SRC_FRAC)
  1836. +
  1837. +#define HW_AUDIOIN_ADCVOLUME (0x00000030)
  1838. +#define HW_AUDIOIN_ADCVOLUME_SET (0x00000034)
  1839. +#define HW_AUDIOIN_ADCVOLUME_CLR (0x00000038)
  1840. +#define HW_AUDIOIN_ADCVOLUME_TOG (0x0000003c)
  1841. +
  1842. +#define BP_AUDIOIN_ADCVOLUME_RSRVD5 29
  1843. +#define BM_AUDIOIN_ADCVOLUME_RSRVD5 0xE0000000
  1844. +#define BF_AUDIOIN_ADCVOLUME_RSRVD5(v) \
  1845. + (((v) << 29) & BM_AUDIOIN_ADCVOLUME_RSRVD5)
  1846. +#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_LEFT 0x10000000
  1847. +#define BP_AUDIOIN_ADCVOLUME_RSRVD4 26
  1848. +#define BM_AUDIOIN_ADCVOLUME_RSRVD4 0x0C000000
  1849. +#define BF_AUDIOIN_ADCVOLUME_RSRVD4(v) \
  1850. + (((v) << 26) & BM_AUDIOIN_ADCVOLUME_RSRVD4)
  1851. +#define BM_AUDIOIN_ADCVOLUME_EN_ZCD 0x02000000
  1852. +#define BM_AUDIOIN_ADCVOLUME_RSRVD3 0x01000000
  1853. +#define BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT 16
  1854. +#define BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT 0x00FF0000
  1855. +#define BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(v) \
  1856. + (((v) << 16) & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT)
  1857. +#define BP_AUDIOIN_ADCVOLUME_RSRVD2 13
  1858. +#define BM_AUDIOIN_ADCVOLUME_RSRVD2 0x0000E000
  1859. +#define BF_AUDIOIN_ADCVOLUME_RSRVD2(v) \
  1860. + (((v) << 13) & BM_AUDIOIN_ADCVOLUME_RSRVD2)
  1861. +#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_RIGHT 0x00001000
  1862. +#define BP_AUDIOIN_ADCVOLUME_RSRVD1 8
  1863. +#define BM_AUDIOIN_ADCVOLUME_RSRVD1 0x00000F00
  1864. +#define BF_AUDIOIN_ADCVOLUME_RSRVD1(v) \
  1865. + (((v) << 8) & BM_AUDIOIN_ADCVOLUME_RSRVD1)
  1866. +#define BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0
  1867. +#define BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0x000000FF
  1868. +#define BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(v) \
  1869. + (((v) << 0) & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT)
  1870. +
  1871. +#define HW_AUDIOIN_ADCDEBUG (0x00000040)
  1872. +#define HW_AUDIOIN_ADCDEBUG_SET (0x00000044)
  1873. +#define HW_AUDIOIN_ADCDEBUG_CLR (0x00000048)
  1874. +#define HW_AUDIOIN_ADCDEBUG_TOG (0x0000004c)
  1875. +
  1876. +#define BM_AUDIOIN_ADCDEBUG_ENABLE_ADCDMA 0x80000000
  1877. +#define BP_AUDIOIN_ADCDEBUG_RSRVD1 4
  1878. +#define BM_AUDIOIN_ADCDEBUG_RSRVD1 0x7FFFFFF0
  1879. +#define BF_AUDIOIN_ADCDEBUG_RSRVD1(v) \
  1880. + (((v) << 4) & BM_AUDIOIN_ADCDEBUG_RSRVD1)
  1881. +#define BM_AUDIOIN_ADCDEBUG_ADC_DMA_REQ_HAND_SHAKE_CLK_CROSS 0x00000008
  1882. +#define BM_AUDIOIN_ADCDEBUG_SET_INTERRUPT3_HAND_SHAKE 0x00000004
  1883. +#define BM_AUDIOIN_ADCDEBUG_DMA_PREQ 0x00000002
  1884. +#define BM_AUDIOIN_ADCDEBUG_FIFO_STATUS 0x00000001
  1885. +
  1886. +#define HW_AUDIOIN_ADCVOL (0x00000050)
  1887. +#define HW_AUDIOIN_ADCVOL_SET (0x00000054)
  1888. +#define HW_AUDIOIN_ADCVOL_CLR (0x00000058)
  1889. +#define HW_AUDIOIN_ADCVOL_TOG (0x0000005c)
  1890. +
  1891. +#define BP_AUDIOIN_ADCVOL_RSRVD4 29
  1892. +#define BM_AUDIOIN_ADCVOL_RSRVD4 0xE0000000
  1893. +#define BF_AUDIOIN_ADCVOL_RSRVD4(v) \
  1894. + (((v) << 29) & BM_AUDIOIN_ADCVOL_RSRVD4)
  1895. +#define BM_AUDIOIN_ADCVOL_VOLUME_UPDATE_PENDING 0x10000000
  1896. +#define BP_AUDIOIN_ADCVOL_RSRVD3 26
  1897. +#define BM_AUDIOIN_ADCVOL_RSRVD3 0x0C000000
  1898. +#define BF_AUDIOIN_ADCVOL_RSRVD3(v) \
  1899. + (((v) << 26) & BM_AUDIOIN_ADCVOL_RSRVD3)
  1900. +#define BM_AUDIOIN_ADCVOL_EN_ADC_ZCD 0x02000000
  1901. +#define BM_AUDIOIN_ADCVOL_MUTE 0x01000000
  1902. +#define BP_AUDIOIN_ADCVOL_RSRVD2 14
  1903. +#define BM_AUDIOIN_ADCVOL_RSRVD2 0x00FFC000
  1904. +#define BF_AUDIOIN_ADCVOL_RSRVD2(v) \
  1905. + (((v) << 14) & BM_AUDIOIN_ADCVOL_RSRVD2)
  1906. +#define BP_AUDIOIN_ADCVOL_SELECT_LEFT 12
  1907. +#define BM_AUDIOIN_ADCVOL_SELECT_LEFT 0x00003000
  1908. +#define BF_AUDIOIN_ADCVOL_SELECT_LEFT(v) \
  1909. + (((v) << 12) & BM_AUDIOIN_ADCVOL_SELECT_LEFT)
  1910. +#define BP_AUDIOIN_ADCVOL_GAIN_LEFT 8
  1911. +#define BM_AUDIOIN_ADCVOL_GAIN_LEFT 0x00000F00
  1912. +#define BF_AUDIOIN_ADCVOL_GAIN_LEFT(v) \
  1913. + (((v) << 8) & BM_AUDIOIN_ADCVOL_GAIN_LEFT)
  1914. +#define BP_AUDIOIN_ADCVOL_RSRVD1 6
  1915. +#define BM_AUDIOIN_ADCVOL_RSRVD1 0x000000C0
  1916. +#define BF_AUDIOIN_ADCVOL_RSRVD1(v) \
  1917. + (((v) << 6) & BM_AUDIOIN_ADCVOL_RSRVD1)
  1918. +#define BP_AUDIOIN_ADCVOL_SELECT_RIGHT 4
  1919. +#define BM_AUDIOIN_ADCVOL_SELECT_RIGHT 0x00000030
  1920. +#define BF_AUDIOIN_ADCVOL_SELECT_RIGHT(v) \
  1921. + (((v) << 4) & BM_AUDIOIN_ADCVOL_SELECT_RIGHT)
  1922. +#define BP_AUDIOIN_ADCVOL_GAIN_RIGHT 0
  1923. +#define BM_AUDIOIN_ADCVOL_GAIN_RIGHT 0x0000000F
  1924. +#define BF_AUDIOIN_ADCVOL_GAIN_RIGHT(v) \
  1925. + (((v) << 0) & BM_AUDIOIN_ADCVOL_GAIN_RIGHT)
  1926. +
  1927. +#define HW_AUDIOIN_MICLINE (0x00000060)
  1928. +#define HW_AUDIOIN_MICLINE_SET (0x00000064)
  1929. +#define HW_AUDIOIN_MICLINE_CLR (0x00000068)
  1930. +#define HW_AUDIOIN_MICLINE_TOG (0x0000006c)
  1931. +
  1932. +#define BP_AUDIOIN_MICLINE_RSRVD6 30
  1933. +#define BM_AUDIOIN_MICLINE_RSRVD6 0xC0000000
  1934. +#define BF_AUDIOIN_MICLINE_RSRVD6(v) \
  1935. + (((v) << 30) & BM_AUDIOIN_MICLINE_RSRVD6)
  1936. +#define BM_AUDIOIN_MICLINE_DIVIDE_LINE1 0x20000000
  1937. +#define BM_AUDIOIN_MICLINE_DIVIDE_LINE2 0x10000000
  1938. +#define BP_AUDIOIN_MICLINE_RSRVD5 25
  1939. +#define BM_AUDIOIN_MICLINE_RSRVD5 0x0E000000
  1940. +#define BF_AUDIOIN_MICLINE_RSRVD5(v) \
  1941. + (((v) << 25) & BM_AUDIOIN_MICLINE_RSRVD5)
  1942. +#define BM_AUDIOIN_MICLINE_MIC_SELECT 0x01000000
  1943. +#define BP_AUDIOIN_MICLINE_RSRVD4 22
  1944. +#define BM_AUDIOIN_MICLINE_RSRVD4 0x00C00000
  1945. +#define BF_AUDIOIN_MICLINE_RSRVD4(v) \
  1946. + (((v) << 22) & BM_AUDIOIN_MICLINE_RSRVD4)
  1947. +#define BP_AUDIOIN_MICLINE_MIC_RESISTOR 20
  1948. +#define BM_AUDIOIN_MICLINE_MIC_RESISTOR 0x00300000
  1949. +#define BF_AUDIOIN_MICLINE_MIC_RESISTOR(v) \
  1950. + (((v) << 20) & BM_AUDIOIN_MICLINE_MIC_RESISTOR)
  1951. +#define BM_AUDIOIN_MICLINE_RSRVD3 0x00080000
  1952. +#define BP_AUDIOIN_MICLINE_MIC_BIAS 16
  1953. +#define BM_AUDIOIN_MICLINE_MIC_BIAS 0x00070000
  1954. +#define BF_AUDIOIN_MICLINE_MIC_BIAS(v) \
  1955. + (((v) << 16) & BM_AUDIOIN_MICLINE_MIC_BIAS)
  1956. +#define BP_AUDIOIN_MICLINE_RSRVD2 6
  1957. +#define BM_AUDIOIN_MICLINE_RSRVD2 0x0000FFC0
  1958. +#define BF_AUDIOIN_MICLINE_RSRVD2(v) \
  1959. + (((v) << 6) & BM_AUDIOIN_MICLINE_RSRVD2)
  1960. +#define BP_AUDIOIN_MICLINE_MIC_CHOPCLK 4
  1961. +#define BM_AUDIOIN_MICLINE_MIC_CHOPCLK 0x00000030
  1962. +#define BF_AUDIOIN_MICLINE_MIC_CHOPCLK(v) \
  1963. + (((v) << 4) & BM_AUDIOIN_MICLINE_MIC_CHOPCLK)
  1964. +#define BP_AUDIOIN_MICLINE_RSRVD1 2
  1965. +#define BM_AUDIOIN_MICLINE_RSRVD1 0x0000000C
  1966. +#define BF_AUDIOIN_MICLINE_RSRVD1(v) \
  1967. + (((v) << 2) & BM_AUDIOIN_MICLINE_RSRVD1)
  1968. +#define BP_AUDIOIN_MICLINE_MIC_GAIN 0
  1969. +#define BM_AUDIOIN_MICLINE_MIC_GAIN 0x00000003
  1970. +#define BF_AUDIOIN_MICLINE_MIC_GAIN(v) \
  1971. + (((v) << 0) & BM_AUDIOIN_MICLINE_MIC_GAIN)
  1972. +
  1973. +#define HW_AUDIOIN_ANACLKCTRL (0x00000070)
  1974. +#define HW_AUDIOIN_ANACLKCTRL_SET (0x00000074)
  1975. +#define HW_AUDIOIN_ANACLKCTRL_CLR (0x00000078)
  1976. +#define HW_AUDIOIN_ANACLKCTRL_TOG (0x0000007c)
  1977. +
  1978. +#define BM_AUDIOIN_ANACLKCTRL_CLKGATE 0x80000000
  1979. +#define BP_AUDIOIN_ANACLKCTRL_RSRVD4 11
  1980. +#define BM_AUDIOIN_ANACLKCTRL_RSRVD4 0x7FFFF800
  1981. +#define BF_AUDIOIN_ANACLKCTRL_RSRVD4(v) \
  1982. + (((v) << 11) & BM_AUDIOIN_ANACLKCTRL_RSRVD4)
  1983. +#define BM_AUDIOIN_ANACLKCTRL_DITHER_OFF 0x00000400
  1984. +#define BM_AUDIOIN_ANACLKCTRL_SLOW_DITHER 0x00000200
  1985. +#define BM_AUDIOIN_ANACLKCTRL_INVERT_ADCCLK 0x00000100
  1986. +#define BP_AUDIOIN_ANACLKCTRL_RSRVD3 6
  1987. +#define BM_AUDIOIN_ANACLKCTRL_RSRVD3 0x000000C0
  1988. +#define BF_AUDIOIN_ANACLKCTRL_RSRVD3(v) \
  1989. + (((v) << 6) & BM_AUDIOIN_ANACLKCTRL_RSRVD3)
  1990. +#define BP_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 4
  1991. +#define BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 0x00000030
  1992. +#define BF_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT(v) \
  1993. + (((v) << 4) & BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT)
  1994. +#define BM_AUDIOIN_ANACLKCTRL_RSRVD2 0x00000008
  1995. +#define BP_AUDIOIN_ANACLKCTRL_ADCDIV 0
  1996. +#define BM_AUDIOIN_ANACLKCTRL_ADCDIV 0x00000007
  1997. +#define BF_AUDIOIN_ANACLKCTRL_ADCDIV(v) \
  1998. + (((v) << 0) & BM_AUDIOIN_ANACLKCTRL_ADCDIV)
  1999. +
  2000. +#define HW_AUDIOIN_DATA (0x00000080)
  2001. +#define HW_AUDIOIN_DATA_SET (0x00000084)
  2002. +#define HW_AUDIOIN_DATA_CLR (0x00000088)
  2003. +#define HW_AUDIOIN_DATA_TOG (0x0000008c)
  2004. +
  2005. +#define BP_AUDIOIN_DATA_HIGH 16
  2006. +#define BM_AUDIOIN_DATA_HIGH 0xFFFF0000
  2007. +#define BF_AUDIOIN_DATA_HIGH(v) \
  2008. + (((v) << 16) & BM_AUDIOIN_DATA_HIGH)
  2009. +#define BP_AUDIOIN_DATA_LOW 0
  2010. +#define BM_AUDIOIN_DATA_LOW 0x0000FFFF
  2011. +#define BF_AUDIOIN_DATA_LOW(v) \
  2012. + (((v) << 0) & BM_AUDIOIN_DATA_LOW)
  2013. +
  2014. +#define BV_AUDIOIN_ADCVOL_SELECT__MIC 0x00
  2015. +
  2016. +#endif /* __MXS_ADC_CODEC_H */
  2017. --- a/sound/soc/mxs/Kconfig
  2018. +++ b/sound/soc/mxs/Kconfig
  2019. @@ -19,3 +19,13 @@ config SND_SOC_MXS_SGTL5000
  2020. a sgtl5000 codec.
  2021. endif # SND_MXS_SOC
  2022. +
  2023. +
  2024. +config SND_MXS_SOC_BUILTIN
  2025. + tristate "SoC Audio for Freescale i.MX23 built-in codec"
  2026. + depends on ARCH_MXS
  2027. + select SND_SOC_GENERIC_DMAENGINE_PCM
  2028. + select SND_SOC_MXS_BUILTIN_CODEC
  2029. + help
  2030. + Say Y or M if you want to add support for codecs attached to
  2031. + the MXS SAIF interface.
  2032. --- a/sound/soc/mxs/Makefile
  2033. +++ b/sound/soc/mxs/Makefile
  2034. @@ -8,3 +8,12 @@ obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs
  2035. snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
  2036. obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
  2037. +
  2038. +# i.MX23 built-in audio Machine and Platform support
  2039. +snd-soc-mxs-builtin-pcm-objs := mxs-builtin-pcm.o
  2040. +snd-soc-mxs-builtin-dai-objs := mxs-builtin-dai.o
  2041. +snd-soc-mxs-builtin-audio-objs := mxs-builtin-audio.o
  2042. +
  2043. +obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-pcm.o
  2044. +obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-dai.o
  2045. +obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-audio.o
  2046. --- /dev/null
  2047. +++ b/sound/soc/mxs/mxs-builtin-audio.c
  2048. @@ -0,0 +1,120 @@
  2049. +/*
  2050. + * mxs-builtin-audio.c -- i.MX233 built-in codec ALSA Soc Audio driver
  2051. + *
  2052. + * Author: Michal Ulianko <michal.ulianko@gmail.com>
  2053. + *
  2054. + * This program is free software; you can redistribute it and/or modify
  2055. + * it under the terms of the GNU General Public License version 2 as
  2056. + * published by the Free Software Foundation.
  2057. + */
  2058. +
  2059. +#include <linux/module.h>
  2060. +#include <linux/device.h>
  2061. +#include <linux/of.h>
  2062. +#include <linux/of_device.h>
  2063. +#include <sound/core.h>
  2064. +#include <sound/pcm.h>
  2065. +#include <sound/soc.h>
  2066. +#include <sound/jack.h>
  2067. +#include <sound/soc-dapm.h>
  2068. +#include <asm/mach-types.h>
  2069. +
  2070. +static struct snd_soc_dai_link mxs_adc_dai_link[] = {
  2071. + {
  2072. + .name = "MXS ADC/DAC",
  2073. + .stream_name = "MXS ADC/DAC",
  2074. + .codec_dai_name = "mxs-builtin-codec-dai",
  2075. +// .codec_name = "mxs-builtin-codec",
  2076. +// .cpu_dai_name = "mxs-builtin-cpu-dai",
  2077. +// .platform_name = "mxs-builtin-cpu-dai",
  2078. +// .ops = &mxs_sgtl5000_hifi_ops,
  2079. + },
  2080. +};
  2081. +
  2082. +static struct snd_soc_card mxs_adc_audio = {
  2083. + .name = "mxs-builtin-audio",
  2084. + .owner = THIS_MODULE,
  2085. + .dai_link = mxs_adc_dai_link,
  2086. + .num_links = ARRAY_SIZE(mxs_adc_dai_link),
  2087. +};
  2088. +
  2089. +static int mxsadc_audio_probe_dt(struct platform_device *pdev)
  2090. +{
  2091. + struct device_node *np = pdev->dev.of_node;
  2092. + struct device_node *cpu_dai_np, *codec_np;
  2093. + int ret = 0;
  2094. +
  2095. + if (!np)
  2096. + return 1; /* no device tree */
  2097. +
  2098. + cpu_dai_np = of_parse_phandle(np, "cpu-dai", 0);
  2099. + codec_np = of_parse_phandle(np, "audio-codec", 0);
  2100. + if (!cpu_dai_np || !codec_np) {
  2101. + dev_err(&pdev->dev, "phandle missing or invalid\n");
  2102. + return -EINVAL;
  2103. + }
  2104. +
  2105. + mxs_adc_dai_link[0].codec_name = NULL;
  2106. + mxs_adc_dai_link[0].codec_of_node = codec_np;
  2107. + mxs_adc_dai_link[0].cpu_dai_name = NULL;
  2108. + mxs_adc_dai_link[0].cpu_of_node = cpu_dai_np;
  2109. + mxs_adc_dai_link[0].platform_name = NULL;
  2110. + mxs_adc_dai_link[0].platform_of_node = cpu_dai_np;
  2111. +
  2112. +// of_node_put(codec_np);
  2113. +// of_node_put(cpu_dai_np);
  2114. +
  2115. + return ret;
  2116. +}
  2117. +
  2118. +static int mxsadc_audio_probe(struct platform_device *pdev)
  2119. +{
  2120. + struct snd_soc_card *card = &mxs_adc_audio;
  2121. + int ret;
  2122. +
  2123. + ret = mxsadc_audio_probe_dt(pdev);
  2124. + if (ret < 0)
  2125. + return ret;
  2126. +
  2127. + card->dev = &pdev->dev;
  2128. + platform_set_drvdata(pdev, card);
  2129. +
  2130. + ret = snd_soc_register_card(card);
  2131. + if (ret) {
  2132. + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  2133. + return ret;
  2134. + }
  2135. +
  2136. + return 0;
  2137. +}
  2138. +
  2139. +static int mxsadc_audio_remove(struct platform_device *pdev)
  2140. +{
  2141. + struct snd_soc_card *card = platform_get_drvdata(pdev);
  2142. +
  2143. + snd_soc_unregister_card(card);
  2144. +
  2145. + return 0;
  2146. +}
  2147. +
  2148. +static const struct of_device_id mxs_adc_audio_dt_ids[] = {
  2149. + { .compatible = "fsl,mxs-builtin-audio", },
  2150. + { /* sentinel */ }
  2151. +};
  2152. +MODULE_DEVICE_TABLE(of, mxs_adc_audio_dt_ids);
  2153. +
  2154. +static struct platform_driver mxs_adc_audio_driver = {
  2155. + .driver = {
  2156. + .name = "mxs-builtin-audio",
  2157. + .owner = THIS_MODULE,
  2158. + .of_match_table = mxs_adc_audio_dt_ids,
  2159. + },
  2160. + .probe = mxsadc_audio_probe,
  2161. + .remove = mxsadc_audio_remove,
  2162. +};
  2163. +
  2164. +module_platform_driver(mxs_adc_audio_driver);
  2165. +
  2166. +MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Machine Driver");
  2167. +MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
  2168. +MODULE_LICENSE("GPL");
  2169. --- /dev/null
  2170. +++ b/sound/soc/mxs/mxs-builtin-dai.c
  2171. @@ -0,0 +1,588 @@
  2172. +/*
  2173. + * mxs-builtin-dai.c -- i.MX233 built-in codec ALSA Soc Audio driver
  2174. + *
  2175. + * Author: Michal Ulianko <michal.ulianko@gmail.com>
  2176. + *
  2177. + * Based on sound/soc/mxs/mxs-adc.c for kernel 2.6.35
  2178. + * by Vladislav Buzov <vbuzov@embeddedalley.com>
  2179. + *
  2180. + * This program is free software; you can redistribute it and/or modify
  2181. + * it under the terms of the GNU General Public License version 2 as
  2182. + * published by the Free Software Foundation.
  2183. + */
  2184. +
  2185. +#include <linux/module.h>
  2186. +#include <linux/init.h>
  2187. +#include <linux/interrupt.h>
  2188. +#include <linux/delay.h>
  2189. +#include <linux/dma-mapping.h>
  2190. +#include <linux/platform_device.h>
  2191. +#include <sound/pcm.h>
  2192. +#include <sound/pcm_params.h>
  2193. +#include <sound/soc.h>
  2194. +
  2195. +#include "../codecs/mxs-builtin-codec.h"
  2196. +#include "mxs-builtin-pcm.h"
  2197. +
  2198. +#define ADC_VOLUME_MIN 0x37
  2199. +
  2200. +/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */
  2201. +
  2202. +// TODO use container_of
  2203. +struct mxs_irq_data {
  2204. + struct snd_pcm_substream *substream;
  2205. + struct mxs_adc_priv *mxs_adc;
  2206. +};
  2207. +
  2208. +struct mxs_adc_priv {
  2209. + struct mxs_irq_data irq_data;
  2210. + int dma_adc_err_irq;
  2211. + int dma_dac_err_irq;
  2212. + int hp_short_irq;
  2213. + void __iomem *audioin_base;
  2214. + void __iomem *audioout_base;
  2215. + void __iomem *rtc_base;
  2216. +};
  2217. +
  2218. +typedef struct {
  2219. + struct work_struct work;
  2220. + struct timer_list timer;
  2221. +
  2222. + /* target workqueue and CPU ->timer uses to queue ->work */
  2223. + struct workqueue_struct *wq;
  2224. + int cpu;
  2225. +
  2226. + struct mxs_adc_priv *mxs_adc;
  2227. +} my_delayed_work_t;
  2228. +
  2229. +// static struct delayed_work work;
  2230. +// static struct delayed_work adc_ramp_work;
  2231. +// static struct delayed_work dac_ramp_work;
  2232. +// static struct delayed_work test;
  2233. +static my_delayed_work_t work;
  2234. +static my_delayed_work_t adc_ramp_work;
  2235. +static my_delayed_work_t dac_ramp_work;
  2236. +static my_delayed_work_t test;
  2237. +static bool adc_ramp_done = 1;
  2238. +static bool dac_ramp_done = 1;
  2239. +
  2240. +static inline void mxs_adc_schedule_work(struct delayed_work *work)
  2241. +{
  2242. + schedule_delayed_work(work, HZ / 10);
  2243. +}
  2244. +
  2245. +static void mxs_adc_work(struct work_struct *work)
  2246. +{
  2247. + struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
  2248. + /* disable irq */
  2249. + disable_irq(mxs_adc->hp_short_irq);
  2250. +
  2251. + while (true) {
  2252. + __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
  2253. + mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR);
  2254. + msleep(10);
  2255. + if ((__raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL)
  2256. + & BM_AUDIOOUT_ANACTRL_SHORT_LR_STS) != 0) {
  2257. + /* rearm the short protection */
  2258. + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR,
  2259. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
  2260. + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
  2261. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
  2262. + __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1),
  2263. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
  2264. +
  2265. + __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
  2266. + mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET);
  2267. + printk(KERN_WARNING "WARNING : Headphone LR short!\r\n");
  2268. + } else {
  2269. + printk(KERN_WARNING "INFO : Headphone LR no longer short!\r\n");
  2270. + break;
  2271. + }
  2272. + msleep(1000);
  2273. + }
  2274. +
  2275. + /* power up the HEADPHONE and un-mute the HPVOL */
  2276. + __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
  2277. + mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR);
  2278. + __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
  2279. + mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR);
  2280. +
  2281. + /* enable irq for next short detect*/
  2282. + enable_irq(mxs_adc->hp_short_irq);
  2283. +}
  2284. +
  2285. +static void mxs_adc_schedule_ramp_work(struct delayed_work *work)
  2286. +{
  2287. + schedule_delayed_work(work, msecs_to_jiffies(2));
  2288. + adc_ramp_done = 0;
  2289. +}
  2290. +
  2291. +static void mxs_adc_ramp_work(struct work_struct *work)
  2292. +{
  2293. + struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
  2294. + u32 reg = 0;
  2295. + u32 reg1 = 0;
  2296. + u32 reg2 = 0;
  2297. + u32 l, r;
  2298. + u32 ll, rr;
  2299. + int i;
  2300. +
  2301. + reg = __raw_readl(mxs_adc->audioin_base + \
  2302. + HW_AUDIOIN_ADCVOLUME);
  2303. +
  2304. + reg1 = reg & ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
  2305. + reg1 = reg1 & ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
  2306. + /* minimize adc volume */
  2307. + reg2 = reg1 |
  2308. + BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ADC_VOLUME_MIN) |
  2309. + BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(ADC_VOLUME_MIN);
  2310. + __raw_writel(reg2,
  2311. + mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME);
  2312. + msleep(1);
  2313. +
  2314. + l = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT) >>
  2315. + BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
  2316. + r = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT) >>
  2317. + BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
  2318. +
  2319. + /* fade in adc vol */
  2320. + for (i = ADC_VOLUME_MIN; (i < l) || (i < r);) {
  2321. + i += 0x8;
  2322. + ll = i < l ? i : l;
  2323. + rr = i < r ? i : r;
  2324. + reg2 = reg1 |
  2325. + BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ll) |
  2326. + BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(rr);
  2327. + __raw_writel(reg2,
  2328. + mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME);
  2329. + msleep(1);
  2330. + }
  2331. + adc_ramp_done = 1;
  2332. +}
  2333. +
  2334. +static void mxs_dac_schedule_ramp_work(struct delayed_work *work)
  2335. +{
  2336. + schedule_delayed_work(work, msecs_to_jiffies(2));
  2337. + dac_ramp_done = 0;
  2338. +}
  2339. +
  2340. +static void mxs_dac_ramp_work(struct work_struct *work)
  2341. +{
  2342. + struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
  2343. + u32 reg = 0;
  2344. + u32 reg1 = 0;
  2345. + u32 l, r;
  2346. + u32 ll, rr;
  2347. + int i;
  2348. +
  2349. + /* unmute hp and speaker */
  2350. + __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
  2351. + mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR);
  2352. + __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
  2353. + mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_CLR);
  2354. +
  2355. + reg = __raw_readl(mxs_adc->audioout_base + \
  2356. + HW_AUDIOOUT_HPVOL);
  2357. +
  2358. + reg1 = reg & ~BM_AUDIOOUT_HPVOL_VOL_LEFT;
  2359. + reg1 = reg1 & ~BM_AUDIOOUT_HPVOL_VOL_RIGHT;
  2360. +
  2361. + l = (reg & BM_AUDIOOUT_HPVOL_VOL_LEFT) >>
  2362. + BP_AUDIOOUT_HPVOL_VOL_LEFT;
  2363. + r = (reg & BM_AUDIOOUT_HPVOL_VOL_RIGHT) >>
  2364. + BP_AUDIOOUT_HPVOL_VOL_RIGHT;
  2365. + /* fade in hp vol */
  2366. + for (i = 0x7f; i > 0 ;) {
  2367. + i -= 0x8;
  2368. + ll = i > (int)l ? i : l;
  2369. + rr = i > (int)r ? i : r;
  2370. + reg = reg1 | BF_AUDIOOUT_HPVOL_VOL_LEFT(ll)
  2371. + | BF_AUDIOOUT_HPVOL_VOL_RIGHT(rr);
  2372. + __raw_writel(reg,
  2373. + mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL);
  2374. + msleep(1);
  2375. + }
  2376. + dac_ramp_done = 1;
  2377. +}
  2378. +
  2379. +/* IRQs */
  2380. +static irqreturn_t mxs_short_irq(int irq, void *dev_id)
  2381. +{
  2382. + struct mxs_adc_priv *mxs_adc = dev_id;
  2383. + //struct snd_pcm_substream *substream = mxs_adc->irq_data.substream;
  2384. +
  2385. + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR,
  2386. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
  2387. + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
  2388. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
  2389. + __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1),
  2390. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
  2391. +
  2392. + __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
  2393. + mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET);
  2394. + __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
  2395. + mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET);
  2396. + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
  2397. + mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
  2398. +
  2399. + mxs_adc_schedule_work((struct delayed_work *) &work);
  2400. + return IRQ_HANDLED;
  2401. +}
  2402. +
  2403. +static irqreturn_t mxs_err_irq(int irq, void *dev_id)
  2404. +{
  2405. + struct mxs_adc_priv *mxs_adc = dev_id;
  2406. + struct snd_pcm_substream *substream = mxs_adc->irq_data.substream;
  2407. + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
  2408. + u32 ctrl_reg;
  2409. + u32 overflow_mask;
  2410. + u32 underflow_mask;
  2411. +
  2412. + if (playback) {
  2413. + ctrl_reg = __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL);
  2414. + underflow_mask = BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ;
  2415. + overflow_mask = BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ;
  2416. + } else {
  2417. + ctrl_reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_CTRL);
  2418. + underflow_mask = BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ;
  2419. + overflow_mask = BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ;
  2420. + }
  2421. +
  2422. + if (ctrl_reg & underflow_mask) {
  2423. + printk(KERN_DEBUG "%s underflow detected\n",
  2424. + playback ? "DAC" : "ADC");
  2425. +
  2426. + if (playback)
  2427. + __raw_writel(
  2428. + BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
  2429. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
  2430. + else
  2431. + __raw_writel(
  2432. + BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
  2433. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
  2434. +
  2435. + } else if (ctrl_reg & overflow_mask) {
  2436. + printk(KERN_DEBUG "%s overflow detected\n",
  2437. + playback ? "DAC" : "ADC");
  2438. +
  2439. + if (playback)
  2440. + __raw_writel(
  2441. + BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
  2442. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
  2443. + else
  2444. + __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
  2445. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
  2446. + } else
  2447. + printk(KERN_WARNING "Unknown DAC error interrupt\n");
  2448. +
  2449. + return IRQ_HANDLED;
  2450. +}
  2451. +/* END IRQs */
  2452. +
  2453. +static int mxs_trigger(struct snd_pcm_substream *substream,
  2454. + int cmd,
  2455. + struct snd_soc_dai *cpu_dai)
  2456. +{
  2457. + struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
  2458. + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
  2459. + int ret = 0;
  2460. +
  2461. + switch (cmd) {
  2462. + case SNDRV_PCM_TRIGGER_START:
  2463. + case SNDRV_PCM_TRIGGER_RESUME:
  2464. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  2465. +
  2466. + if (playback) {
  2467. + /* enable the fifo error interrupt */
  2468. + __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
  2469. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_SET);
  2470. + /* write a data to data reg to trigger the transfer */
  2471. + __raw_writel(0x0,
  2472. + mxs_adc->audioout_base + HW_AUDIOOUT_DATA);
  2473. + mxs_dac_schedule_ramp_work((struct delayed_work *) &dac_ramp_work);
  2474. + } else {
  2475. +// mxs_dma_get_info(prtd->dma_ch, &dma_info);
  2476. +// cur_bar1 = dma_info.buf_addr;
  2477. +// xfer_count1 = dma_info.xfer_count;
  2478. +
  2479. + __raw_writel(BM_AUDIOIN_CTRL_RUN,
  2480. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET);
  2481. + udelay(100);
  2482. +
  2483. +// mxs_dma_get_info(prtd->dma_ch, &dma_info);
  2484. +// cur_bar2 = dma_info.buf_addr;
  2485. +// xfer_count2 = dma_info.xfer_count;
  2486. +//
  2487. +// /* check if DMA getting stuck */
  2488. +// if ((xfer_count1 == xfer_count2) && (cur_bar1 == cur_bar2))
  2489. +// /* read a data from data reg to trigger the receive */
  2490. +// reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_DATA);
  2491. +
  2492. + mxs_adc_schedule_ramp_work((struct delayed_work *) &adc_ramp_work);
  2493. + }
  2494. + break;
  2495. +
  2496. + case SNDRV_PCM_TRIGGER_SUSPEND:
  2497. + case SNDRV_PCM_TRIGGER_STOP:
  2498. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  2499. +
  2500. + if (playback) {
  2501. +// printk(KERN_INFO "SNDRV_PCM_TRIGGER_START\n");
  2502. +// printk(KERN_INFO "ctrl:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL));
  2503. +// printk(KERN_INFO "stat:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_STAT));
  2504. +// printk(KERN_INFO "srr:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACSRR));
  2505. +// printk(KERN_INFO "vol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACVOLUME));
  2506. +// printk(KERN_INFO "debug:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACDEBUG));
  2507. +// printk(KERN_INFO "hpvol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL));
  2508. +// printk(KERN_INFO "pwrdn:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN));
  2509. +// printk(KERN_INFO "refc:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_REFCTRL));
  2510. +// printk(KERN_INFO "anac:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL));
  2511. +// printk(KERN_INFO "test:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_TEST));
  2512. +// printk(KERN_INFO "bist:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_BISTCTRL));
  2513. +// printk(KERN_INFO "anaclk:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACLKCTRL));
  2514. +
  2515. + if (dac_ramp_done == 0) {
  2516. + cancel_delayed_work((struct delayed_work *) &dac_ramp_work);
  2517. + dac_ramp_done = 1;
  2518. + }
  2519. + __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
  2520. + mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET);
  2521. + __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
  2522. + mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
  2523. + /* disable the fifo error interrupt */
  2524. + __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
  2525. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
  2526. + mdelay(50);
  2527. + } else {
  2528. + if (adc_ramp_done == 0) {
  2529. + cancel_delayed_work((struct delayed_work *) &adc_ramp_work);
  2530. + adc_ramp_done = 1;
  2531. + }
  2532. + __raw_writel(BM_AUDIOIN_CTRL_RUN,
  2533. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
  2534. + }
  2535. + break;
  2536. +
  2537. + default:
  2538. + printk(KERN_ERR "TRIGGER ERROR\n");
  2539. + ret = -EINVAL;
  2540. + }
  2541. +
  2542. + return ret;
  2543. +}
  2544. +
  2545. +static int mxs_startup(struct snd_pcm_substream *substream,
  2546. + struct snd_soc_dai *cpu_dai)
  2547. +{
  2548. + struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
  2549. + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
  2550. + mxs_adc->irq_data.mxs_adc = mxs_adc;
  2551. + mxs_adc->irq_data.substream = substream;
  2552. +
  2553. + work.mxs_adc = mxs_adc;
  2554. + adc_ramp_work.mxs_adc = mxs_adc;
  2555. + dac_ramp_work.mxs_adc = mxs_adc;
  2556. + test.mxs_adc = mxs_adc;
  2557. + INIT_DELAYED_WORK(&work, mxs_adc_work);
  2558. + INIT_DELAYED_WORK(&adc_ramp_work, mxs_adc_ramp_work);
  2559. + INIT_DELAYED_WORK(&dac_ramp_work, mxs_dac_ramp_work);
  2560. +
  2561. + /* Enable error interrupt */
  2562. + if (playback) {
  2563. + __raw_writel(BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
  2564. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
  2565. + __raw_writel(BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
  2566. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
  2567. + } else {
  2568. + __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
  2569. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
  2570. + __raw_writel(BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
  2571. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
  2572. + __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
  2573. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET);
  2574. + }
  2575. +
  2576. + return 0;
  2577. +}
  2578. +
  2579. +static void mxs_shutdown(struct snd_pcm_substream *substream,
  2580. + struct snd_soc_dai *cpu_dai)
  2581. +{
  2582. + struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
  2583. + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
  2584. +
  2585. + /* Disable error interrupt */
  2586. + if (playback) {
  2587. + __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
  2588. + mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
  2589. + } else {
  2590. + __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
  2591. + mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
  2592. + }
  2593. +}
  2594. +
  2595. +#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
  2596. +#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
  2597. +
  2598. +static const struct snd_soc_dai_ops mxs_adc_dai_ops = {
  2599. + .startup = mxs_startup,
  2600. + .trigger = mxs_trigger,
  2601. + .shutdown = mxs_shutdown,
  2602. +};
  2603. +
  2604. +static int mxs_dai_probe(struct snd_soc_dai *dai)
  2605. +{
  2606. + // TODO This does not make any sense.
  2607. + struct mxs_adc_priv *mxs_adc = dev_get_drvdata(dai->dev);
  2608. +
  2609. + snd_soc_dai_set_drvdata(dai, mxs_adc);
  2610. +
  2611. + return 0;
  2612. +}
  2613. +
  2614. +static struct snd_soc_dai_driver mxs_adc_dai = {
  2615. + .name = "mxs-builtin-cpu-dai",
  2616. + .probe = mxs_dai_probe,
  2617. + .playback = {
  2618. + .channels_min = 2,
  2619. + .channels_max = 2,
  2620. + .rates = MXS_ADC_RATES,
  2621. + .formats = MXS_ADC_FORMATS,
  2622. + },
  2623. + .capture = {
  2624. + .channels_min = 2,
  2625. + .channels_max = 2,
  2626. + .rates = MXS_ADC_RATES,
  2627. + .formats = MXS_ADC_FORMATS,
  2628. + },
  2629. + .ops = &mxs_adc_dai_ops,
  2630. +};
  2631. +
  2632. +static const struct snd_soc_component_driver mxs_adc_component = {
  2633. + .name = "mxs-xxx", //TODO change this name
  2634. +};
  2635. +
  2636. +static int mxs_adc_probe(struct platform_device *pdev)
  2637. +{
  2638. + struct device_node *np = pdev->dev.of_node;
  2639. + struct mxs_adc_priv *mxs_adc;
  2640. + int ret = 0;
  2641. +
  2642. + if (!np)
  2643. + return -EINVAL;
  2644. +
  2645. + mxs_adc = devm_kzalloc(&pdev->dev, sizeof(*mxs_adc), GFP_KERNEL);
  2646. + if (!mxs_adc)
  2647. + return -ENOMEM;
  2648. +
  2649. + mxs_adc->audioout_base = devm_ioremap(&pdev->dev, 0x80048000, 0x2000);
  2650. + if (IS_ERR(mxs_adc->audioout_base))
  2651. + return PTR_ERR(mxs_adc->audioout_base);
  2652. +
  2653. + mxs_adc->audioin_base = devm_ioremap(&pdev->dev, 0x8004c000, 0x2000);
  2654. + if (IS_ERR(mxs_adc->audioin_base))
  2655. + return PTR_ERR(mxs_adc->audioin_base);
  2656. +
  2657. + mxs_adc->rtc_base = devm_ioremap(&pdev->dev, 0x8005c000, 0x2000);
  2658. + if (IS_ERR(mxs_adc->rtc_base))
  2659. + return PTR_ERR(mxs_adc->rtc_base);
  2660. +
  2661. + /* Get IRQ numbers */
  2662. + mxs_adc->dma_adc_err_irq = platform_get_irq(pdev, 0);
  2663. + if (mxs_adc->dma_adc_err_irq < 0) {
  2664. + ret = mxs_adc->dma_adc_err_irq;
  2665. + dev_err(&pdev->dev, "failed to get ADC DMA ERR irq resource: %d\n", ret);
  2666. + return ret;
  2667. + }
  2668. +
  2669. + mxs_adc->dma_dac_err_irq = platform_get_irq(pdev, 1);
  2670. + if (mxs_adc->dma_dac_err_irq < 0) {
  2671. + ret = mxs_adc->dma_dac_err_irq;
  2672. + dev_err(&pdev->dev, "failed to get DAC DMA ERR irq resource: %d\n", ret);
  2673. + return ret;
  2674. + }
  2675. +
  2676. + mxs_adc->hp_short_irq = platform_get_irq(pdev, 2);
  2677. + if (mxs_adc->hp_short_irq < 0) {
  2678. + ret = mxs_adc->hp_short_irq;
  2679. + dev_err(&pdev->dev, "failed to get HP_SHORT irq resource: %d\n", ret);
  2680. + return ret;
  2681. + }
  2682. +
  2683. + /* Request IRQs */
  2684. + ret = devm_request_irq(&pdev->dev, mxs_adc->dma_adc_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error",
  2685. + mxs_adc);
  2686. + if (ret) {
  2687. + printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
  2688. + __func__, mxs_adc->dma_adc_err_irq);
  2689. + return ret;
  2690. + }
  2691. +
  2692. + ret = devm_request_irq(&pdev->dev, mxs_adc->dma_dac_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error",
  2693. + mxs_adc);
  2694. + if (ret) {
  2695. + printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
  2696. + __func__, mxs_adc->dma_dac_err_irq);
  2697. + return ret;
  2698. + }
  2699. +
  2700. + ret = devm_request_irq(&pdev->dev, mxs_adc->hp_short_irq, mxs_short_irq,
  2701. + IRQF_DISABLED | IRQF_SHARED, "MXS DAC and ADC HP SHORT", mxs_adc);
  2702. + if (ret) {
  2703. + printk(KERN_ERR "%s: Unable to request ADC/DAC HP SHORT irq %d\n",
  2704. + __func__, mxs_adc->hp_short_irq);
  2705. + return ret;
  2706. + }
  2707. +
  2708. + platform_set_drvdata(pdev, mxs_adc);
  2709. +
  2710. + ret = snd_soc_register_component(&pdev->dev, &mxs_adc_component, &mxs_adc_dai, 1);
  2711. + if (ret) {
  2712. + dev_err(&pdev->dev, "register DAI failed\n");
  2713. + return ret;
  2714. + }
  2715. +
  2716. + ret = mxs_adc_pcm_platform_register(&pdev->dev);
  2717. + if (ret) {
  2718. + dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
  2719. + goto failed_pdev_alloc;
  2720. + }
  2721. +
  2722. + return 0;
  2723. +
  2724. +failed_pdev_alloc:
  2725. + snd_soc_unregister_component(&pdev->dev);
  2726. +
  2727. + return ret;
  2728. +}
  2729. +
  2730. +static int mxs_adc_remove(struct platform_device *pdev)
  2731. +{
  2732. + mxs_adc_pcm_platform_unregister(&pdev->dev);
  2733. + snd_soc_unregister_component(&pdev->dev);
  2734. +
  2735. + return 0;
  2736. +}
  2737. +
  2738. +static const struct of_device_id mxs_adc_dai_dt_ids[] = {
  2739. + { .compatible = "fsl,mxs-builtin-cpu-dai", },
  2740. + { /* sentinel */ }
  2741. +};
  2742. +MODULE_DEVICE_TABLE(of, mxs_adc_dai_dt_ids);
  2743. +
  2744. +static struct platform_driver mxs_adc_dai_driver = {
  2745. + .probe = mxs_adc_probe,
  2746. + .remove = mxs_adc_remove,
  2747. +
  2748. + .driver = {
  2749. + .name = "mxs-builtin-cpu-dai",
  2750. + .owner = THIS_MODULE,
  2751. + .of_match_table = mxs_adc_dai_dt_ids,
  2752. + },
  2753. +};
  2754. +
  2755. +module_platform_driver(mxs_adc_dai_driver);
  2756. +
  2757. +MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec DAI Driver");
  2758. +MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
  2759. +MODULE_LICENSE("GPL");
  2760. --- /dev/null
  2761. +++ b/sound/soc/mxs/mxs-builtin-pcm.c
  2762. @@ -0,0 +1,69 @@
  2763. +/*
  2764. + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  2765. + *
  2766. + * Based on sound/soc/imx/imx-pcm-dma-mx2.c
  2767. + *
  2768. + * This program is free software; you can redistribute it and/or modify
  2769. + * it under the terms of the GNU General Public License as published by
  2770. + * the Free Software Foundation; either version 2 of the License, or
  2771. + * (at your option) any later version.
  2772. + *
  2773. + * This program is distributed in the hope that it will be useful,
  2774. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2775. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2776. + * GNU General Public License for more details.
  2777. + *
  2778. + * You should have received a copy of the GNU General Public License along
  2779. + * with this program; if not, write to the Free Software Foundation, Inc.,
  2780. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  2781. + */
  2782. +
  2783. +#include <linux/device.h>
  2784. +#include <linux/init.h>
  2785. +#include <linux/module.h>
  2786. +
  2787. +#include <sound/core.h>
  2788. +#include <sound/pcm.h>
  2789. +#include <sound/soc.h>
  2790. +#include <sound/dmaengine_pcm.h>
  2791. +
  2792. +#include "mxs-builtin-pcm.h"
  2793. +
  2794. +static const struct snd_pcm_hardware snd_mxs_hardware = {
  2795. + .info = SNDRV_PCM_INFO_MMAP |
  2796. + SNDRV_PCM_INFO_MMAP_VALID |
  2797. + SNDRV_PCM_INFO_PAUSE |
  2798. + SNDRV_PCM_INFO_RESUME |
  2799. + SNDRV_PCM_INFO_INTERLEAVED,
  2800. + .formats = SNDRV_PCM_FMTBIT_S16_LE |
  2801. + SNDRV_PCM_FMTBIT_S20_3LE |
  2802. + SNDRV_PCM_FMTBIT_S24_LE,
  2803. + .channels_min = 2,
  2804. + .channels_max = 2,
  2805. + .period_bytes_min = 32,
  2806. + .period_bytes_max = 8192,
  2807. + .periods_min = 1,
  2808. + .periods_max = 52,
  2809. + .buffer_bytes_max = 64 * 1024,
  2810. + .fifo_size = 32,
  2811. +};
  2812. +
  2813. +static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
  2814. + .pcm_hardware = &snd_mxs_hardware,
  2815. + .prealloc_buffer_size = 64 * 1024,
  2816. +};
  2817. +
  2818. +int mxs_adc_pcm_platform_register(struct device *dev)
  2819. +{
  2820. + return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
  2821. + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
  2822. +}
  2823. +EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_register);
  2824. +
  2825. +void mxs_adc_pcm_platform_unregister(struct device *dev)
  2826. +{
  2827. + snd_dmaengine_pcm_unregister(dev);
  2828. +}
  2829. +EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_unregister);
  2830. +
  2831. +MODULE_LICENSE("GPL");
  2832. --- /dev/null
  2833. +++ b/sound/soc/mxs/mxs-builtin-pcm.h
  2834. @@ -0,0 +1,25 @@
  2835. +/*
  2836. + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  2837. + *
  2838. + * This program is free software; you can redistribute it and/or modify
  2839. + * it under the terms of the GNU General Public License as published by
  2840. + * the Free Software Foundation; either version 2 of the License, or
  2841. + * (at your option) any later version.
  2842. + *
  2843. + * This program is distributed in the hope that it will be useful,
  2844. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2845. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2846. + * GNU General Public License for more details.
  2847. + *
  2848. + * You should have received a copy of the GNU General Public License along
  2849. + * with this program; if not, write to the Free Software Foundation, Inc.,
  2850. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  2851. + */
  2852. +
  2853. +#ifndef _MXS_PCM_H
  2854. +#define _MXS_PCM_H
  2855. +
  2856. +int mxs_adc_pcm_platform_register(struct device *dev);
  2857. +void mxs_adc_pcm_platform_unregister(struct device *dev);
  2858. +
  2859. +#endif