kernel_003_audio.patch 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868
  1. diff --git a/drivers/mfd/ac200.c b/drivers/mfd/ac200.c
  2. index 570573790..5d759eb1e 100644
  3. --- a/drivers/mfd/ac200.c
  4. +++ b/drivers/mfd/ac200.c
  5. @@ -41,6 +41,7 @@ static const struct regmap_range_cfg ac200_range_cfg[] = {
  6. };
  7. static const struct regmap_config ac200_regmap_config = {
  8. + .name = "ac200",
  9. .reg_bits = 8,
  10. .val_bits = 16,
  11. .ranges = ac200_range_cfg,
  12. @@ -75,6 +76,10 @@ static const struct mfd_cell ac200_cells[] = {
  13. .resources = ephy_resource,
  14. .of_compatible = "x-powers,ac200-ephy",
  15. },
  16. + {
  17. + .name = "acx00-codec",
  18. + .of_compatible = "x-powers,ac200-codec",
  19. + },
  20. };
  21. static int ac200_i2c_probe(struct i2c_client *i2c,
  22. diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
  23. index 0ad261ffa..7a654de46 100644
  24. --- a/drivers/pwm/pwm-sun4i.c
  25. +++ b/drivers/pwm/pwm-sun4i.c
  26. @@ -175,7 +175,7 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
  27. clk_rate = clk_get_rate(sun4i_pwm->clk);
  28. *bypass = sun4i_pwm->data->has_direct_mod_clk_output &&
  29. - state->enabled &&
  30. +// state->enabled &&
  31. (state->period * clk_rate >= NSEC_PER_SEC) &&
  32. (state->period * clk_rate < 2 * NSEC_PER_SEC) &&
  33. (state->duty_cycle * clk_rate * 2 >= NSEC_PER_SEC);
  34. diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
  35. index 20d99b44d..09ac9c747 100644
  36. --- a/sound/soc/codecs/Kconfig
  37. +++ b/sound/soc/codecs/Kconfig
  38. @@ -1787,4 +1787,12 @@ config SND_SOC_TPA6130A2
  39. tristate "Texas Instruments TPA6130A2 headphone amplifier"
  40. depends on I2C
  41. +config SND_SOC_ACX00
  42. + tristate "ACX00 Codec"
  43. + select MFD_ACX00
  44. + default n
  45. + help
  46. + ACX00 now used as SUN50IW6 internal Codec, Connect Through I2S0.
  47. + Say Y or M if you want to add support internal audio codec.
  48. +
  49. endmenu
  50. diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
  51. index cfdeed716..e6c378f71 100644
  52. --- a/sound/soc/codecs/Makefile
  53. +++ b/sound/soc/codecs/Makefile
  54. @@ -306,6 +306,7 @@ snd-soc-tpa6130a2-objs := tpa6130a2.o
  55. snd-soc-tas2552-objs := tas2552.o
  56. snd-soc-tas2562-objs := tas2562.o
  57. snd-soc-tas2764-objs := tas2764.o
  58. +snd-soc-acx00-objs := acx00.o
  59. obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
  60. obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
  61. @@ -615,3 +616,4 @@ obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
  62. obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
  63. obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o
  64. obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
  65. +obj-$(CONFIG_SND_SOC_ACX00) += snd-soc-acx00.o
  66. \ No newline at end of file
  67. diff --git a/sound/soc/codecs/acx00.c b/sound/soc/codecs/acx00.c
  68. new file mode 100644
  69. index 000000000..afa072353
  70. --- /dev/null
  71. +++ b/sound/soc/codecs/acx00.c
  72. @@ -0,0 +1,1372 @@
  73. +/*
  74. + * acx00.c -- ACX00 ALSA Soc Audio Codec driver
  75. + *
  76. + * (C) Copyright 2010-2016 Allwinnertech Technology., Ltd.
  77. + *
  78. + * Author: Wolfgang Huang <huangjinhui@allwinner.com>
  79. + *
  80. + * This program is free software; you can redistribute it and/or modify
  81. + * it under the terms of the GNU General Public License version 2 as
  82. + * published by the Free Software Foundation.
  83. + *
  84. + */
  85. +
  86. +#include <linux/module.h>
  87. +#include <linux/moduleparam.h>
  88. +#include <linux/kernel.h>
  89. +#include <linux/init.h>
  90. +#include <linux/firmware.h>
  91. +#include <linux/delay.h>
  92. +#include <linux/pm.h>
  93. +#include <linux/i2c.h>
  94. +#include <linux/clk.h>
  95. +#include <linux/of_gpio.h>
  96. +#include <linux/of_device.h>
  97. +#include <linux/of_platform.h>
  98. +#include <linux/debugfs.h>
  99. +#include <linux/slab.h>
  100. +#include <linux/mfd/ac200.h>
  101. +#include <sound/core.h>
  102. +#include <sound/pcm.h>
  103. +#include <sound/pcm_params.h>
  104. +#include <sound/soc.h>
  105. +#include <sound/initval.h>
  106. +#include <sound/tlv.h>
  107. +#include <linux/workqueue.h>
  108. +
  109. +#include "acx00.h"
  110. +
  111. +
  112. +#define ACX00_DEF_VOL 0x9F9F
  113. +#undef ACX00_DAPM_LINEOUT
  114. +
  115. +struct acx00_priv {
  116. + struct ac200_dev *acx00; /* parent mfd device struct */
  117. + struct snd_soc_component *component;
  118. + struct clk *clk;
  119. + unsigned int sample_rate;
  120. + unsigned int fmt;
  121. + unsigned int enable;
  122. + unsigned int spk_gpio;
  123. + unsigned int switch_gpio;
  124. + bool spk_gpio_used;
  125. + struct mutex mutex;
  126. + struct delayed_work spk_work;
  127. + struct delayed_work resume_work;
  128. +};
  129. +
  130. +struct sample_rate {
  131. + unsigned int samplerate;
  132. + unsigned int rate_bit;
  133. +};
  134. +
  135. +static const struct sample_rate sample_rate_conv[] = {
  136. + {44100, 7},
  137. + {48000, 8},
  138. + {8000, 0},
  139. + {32000, 6},
  140. + {22050, 4},
  141. + {24000, 5},
  142. + {16000, 3},
  143. + {11025, 1},
  144. + {12000, 2},
  145. + {192000, 10},
  146. + {96000, 9},
  147. +};
  148. +
  149. +void __iomem *io_stat_addr;
  150. +
  151. +static const DECLARE_TLV_DB_SCALE(i2s_mixer_adc_tlv, -600, 600, 1);
  152. +static const DECLARE_TLV_DB_SCALE(i2s_mixer_dac_tlv, -600, 600, 1);
  153. +static const DECLARE_TLV_DB_SCALE(dac_mixer_adc_tlv, -600, 600, 1);
  154. +static const DECLARE_TLV_DB_SCALE(dac_mixer_dac_tlv, -600, 600, 1);
  155. +static const DECLARE_TLV_DB_SCALE(line_out_tlv, -450, 150, 0);
  156. +static const DECLARE_TLV_DB_SCALE(mic_out_tlv, -450, 150, 0);
  157. +static const DECLARE_TLV_DB_SCALE(phoneout_tlv, -450, 150, 0);
  158. +static const DECLARE_TLV_DB_SCALE(adc_input_tlv, -450, 150, 0);
  159. +static const DECLARE_TLV_DB_SCALE(lineout_tlv, -4800, 150, 1);
  160. +static const unsigned int mic_boost_tlv[] = {
  161. + TLV_DB_RANGE_HEAD(2),
  162. + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
  163. + 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
  164. +};
  165. +
  166. +static const struct snd_kcontrol_new acx00_codec_controls[] = {
  167. + SOC_DOUBLE_TLV("I2S Mixer ADC Volume", AC_I2S_MIXER_GAIN,
  168. + I2S_MIXERL_GAIN_ADC, I2S_MIXERR_GAIN_ADC,
  169. + 0x1, 0, i2s_mixer_adc_tlv),
  170. + SOC_DOUBLE_TLV("I2S Mixer DAC Volume", AC_I2S_MIXER_GAIN,
  171. + I2S_MIXERL_GAIN_DAC, I2S_MIXERR_GAIN_DAC,
  172. + 0x1, 0, i2s_mixer_dac_tlv),
  173. + SOC_DOUBLE_TLV("DAC Mixer ADC Volume", AC_DAC_MIXER_GAIN,
  174. + DAC_MIXERL_GAIN_ADC, DAC_MIXERR_GAIN_ADC,
  175. + 0x1, 0, dac_mixer_adc_tlv),
  176. + SOC_DOUBLE_TLV("DAC Mxier DAC Volume", AC_DAC_MIXER_GAIN,
  177. + DAC_MIXERL_GAIN_DAC, DAC_MIXERR_GAIN_DAC,
  178. + 0x1, 0, dac_mixer_dac_tlv),
  179. + SOC_SINGLE_TLV("Line Out Mixer Volume", AC_OUT_MIXER_CTL,
  180. + OUT_MIXER_LINE_VOL, 0x7, 0, line_out_tlv),
  181. + SOC_DOUBLE_TLV("MIC Out Mixer Volume", AC_OUT_MIXER_CTL,
  182. + OUT_MIXER_MIC1_VOL, OUT_MIXER_MIC2_VOL,
  183. + 0x7, 0, mic_out_tlv),
  184. + SOC_SINGLE_TLV("ADC Input Volume", AC_ADC_MIC_CTL,
  185. + ADC_GAIN, 0x07, 0, adc_input_tlv),
  186. + SOC_SINGLE_TLV("Master Volume", AC_LINEOUT_CTL,
  187. + LINEOUT_VOL, 0x1f, 0, lineout_tlv),
  188. + SOC_SINGLE_TLV("MIC1 Boost Volume", AC_ADC_MIC_CTL,
  189. + MIC1_BOOST, 0x07, 0, mic_boost_tlv),
  190. + SOC_SINGLE_TLV("MIC2 Boost Volume", AC_ADC_MIC_CTL,
  191. + MIC2_BOOST, 0x07, 0, mic_boost_tlv),
  192. +};
  193. +
  194. +/* Enable I2S & DAC clk, then enable the DAC digital part */
  195. +static int acx00_playback_event(struct snd_soc_dapm_widget *w,
  196. + struct snd_kcontrol *k, int event)
  197. +{
  198. + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  199. +
  200. + switch (event) {
  201. + case SND_SOC_DAPM_POST_PMU:
  202. + snd_soc_component_update_bits(component, AC_SYS_CLK_CTL,
  203. + (0x1<<SYS_CLK_DAC), (0x1<<SYS_CLK_DAC));
  204. + snd_soc_component_update_bits(component, AC_SYS_MOD_RST,
  205. + (0x1<<MOD_RST_DAC), (0x1<<MOD_RST_DAC));
  206. + snd_soc_component_update_bits(component, AC_DAC_CTL,
  207. + (0x1<<DAC_CTL_DAC_EN), (0x1<<DAC_CTL_DAC_EN));
  208. + break;
  209. + case SND_SOC_DAPM_POST_PMD:
  210. + snd_soc_component_update_bits(component, AC_SYS_CLK_CTL,
  211. + (0x1<<SYS_CLK_DAC), (0x0<<SYS_CLK_DAC));
  212. + snd_soc_component_update_bits(component, AC_SYS_MOD_RST,
  213. + (0x1<<MOD_RST_DAC), (0x0<<MOD_RST_DAC));
  214. + snd_soc_component_update_bits(component, AC_DAC_CTL,
  215. + (0x1<<DAC_CTL_DAC_EN), (0x0<<DAC_CTL_DAC_EN));
  216. + break;
  217. + default:
  218. + break;
  219. + }
  220. + return 0;
  221. +}
  222. +
  223. +/* Enable I2S & ADC clk, then enable the ADC digital part */
  224. +static int acx00_capture_event(struct snd_soc_dapm_widget *w,
  225. + struct snd_kcontrol *k, int event)
  226. +{
  227. + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  228. +
  229. + switch (event) {
  230. + case SND_SOC_DAPM_POST_PMU:
  231. + snd_soc_component_update_bits(component, AC_SYS_CLK_CTL,
  232. + (0x1<<SYS_CLK_ADC), (0x1<<SYS_CLK_ADC));
  233. + snd_soc_component_update_bits(component, AC_SYS_MOD_RST,
  234. + (0x1<<MOD_RST_ADC), (0x1<<MOD_RST_ADC));
  235. + snd_soc_component_update_bits(component, AC_ADC_CTL,
  236. + (0x1<<ADC_EN), (0x1<<ADC_EN));
  237. + break;
  238. + case SND_SOC_DAPM_POST_PMD:
  239. + snd_soc_component_update_bits(component, AC_SYS_CLK_CTL,
  240. + (0x1<<SYS_CLK_ADC), (0x0<<SYS_CLK_ADC));
  241. + snd_soc_component_update_bits(component, AC_SYS_MOD_RST,
  242. + (0x1<<MOD_RST_ADC), (0x0<<MOD_RST_ADC));
  243. + snd_soc_component_update_bits(component, AC_ADC_CTL,
  244. + (0x1<<ADC_EN), (0x0<<ADC_EN));
  245. + break;
  246. + default:
  247. + break;
  248. + }
  249. + return 0;
  250. +}
  251. +
  252. +/*
  253. + * we used for three scene:
  254. + * 1. No external Spker & DAPM LINEOUT used, we just enable the LINEOUT in the
  255. + * ALSA codec probe(acx00_codec_probe) and resume, and we shutdown the LINEOUT
  256. + * in device shutdown or suspend.
  257. + * 2. No external Spker, but DAPM LINEOUT used, we just using the LINEOUT
  258. + * enable or disable throught the DAPM control.
  259. + * 3. External Spker & DAPM LINEOUT used, we just using the LINEOUT and
  260. + * External Spker control GPIO enable or disable through DAPM control.
  261. + */
  262. +static unsigned int spk_delay = 100;
  263. +module_param(spk_delay, int, 0644);
  264. +MODULE_PARM_DESC(spk_delay, "ACX00-Codec spk mute delay time");
  265. +
  266. +static void acx00_spk_enable(struct work_struct *work)
  267. +{
  268. + struct acx00_priv *priv = container_of(work,
  269. + struct acx00_priv, spk_work.work);
  270. + gpio_set_value(priv->spk_gpio, 1);
  271. +}
  272. +
  273. +static int acx00_lineout_event(struct snd_soc_dapm_widget *w,
  274. + struct snd_kcontrol *k, int event)
  275. +{
  276. + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  277. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  278. +
  279. + switch (event) {
  280. + case SND_SOC_DAPM_POST_PMU:
  281. + if (!priv->enable) {
  282. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  283. + (1<<LINEL_SRC_EN), (1<<LINEL_SRC_EN));
  284. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  285. + (1<<LINER_SRC_EN), (1<<LINER_SRC_EN));
  286. + msleep(100);
  287. + priv->enable = 1;
  288. + }
  289. +#ifdef ACX00_DAPM_LINEOUT
  290. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL,
  291. + (1<<LINEOUT_EN), (1<<LINEOUT_EN));
  292. + mdelay(50);
  293. +#endif
  294. + if (priv->spk_gpio_used) {
  295. + if (spk_delay == 0) {
  296. + gpio_set_value(priv->spk_gpio, 1);
  297. + /*
  298. + * time delay to wait spk pa work fine,
  299. + * general setting 50ms
  300. + */
  301. + mdelay(50);
  302. + } else
  303. + schedule_delayed_work(&priv->spk_work,
  304. + msecs_to_jiffies(spk_delay));
  305. + }
  306. + break;
  307. + case SND_SOC_DAPM_PRE_PMD:
  308. + mdelay(50);
  309. + if (priv->spk_gpio_used) {
  310. + gpio_set_value(priv->spk_gpio, 0);
  311. + msleep(50);
  312. + }
  313. +#ifdef ACX00_DAPM_LINEOUT
  314. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL,
  315. + (1<<LINEOUT_EN), (0<<LINEOUT_EN));
  316. +#endif
  317. + break;
  318. + default:
  319. + break;
  320. + }
  321. + return 0;
  322. +}
  323. +
  324. +/* AC_I2S_MIXER_SRC : 0x2114 */
  325. +static const struct snd_kcontrol_new i2sl_mixer_src[] = {
  326. + SOC_DAPM_SINGLE("I2SDACL Switch", AC_I2S_MIXER_SRC,
  327. + I2S_MIXERL_SRC_DAC, 1, 0),
  328. + SOC_DAPM_SINGLE("ADCL Switch", AC_I2S_MIXER_SRC,
  329. + I2S_MIXERL_SRC_ADC, 1, 0),
  330. +};
  331. +
  332. +static const struct snd_kcontrol_new i2sr_mixer_src[] = {
  333. + SOC_DAPM_SINGLE("I2SDACR Switch", AC_I2S_MIXER_SRC,
  334. + I2S_MIXERR_SRC_DAC, 1, 0),
  335. + SOC_DAPM_SINGLE("ADCR Switch", AC_I2S_MIXER_SRC,
  336. + I2S_MIXERR_SRC_ADC, 1, 0),
  337. +};
  338. +
  339. +/* AC_DAC_MIXER_SRC : 0x2202 */
  340. +static const struct snd_kcontrol_new dacl_mixer_src[] = {
  341. + SOC_DAPM_SINGLE("I2SDACL Switch", AC_DAC_MIXER_SRC,
  342. + DAC_MIXERL_SRC_DAC, 1, 0),
  343. + SOC_DAPM_SINGLE("ADCL Switch", AC_DAC_MIXER_SRC,
  344. + DAC_MIXERL_SRC_ADC, 1, 0),
  345. +};
  346. +
  347. +static const struct snd_kcontrol_new dacr_mixer_src[] = {
  348. + SOC_DAPM_SINGLE("I2SDACR Switch", AC_DAC_MIXER_SRC,
  349. + DAC_MIXERR_SRC_DAC, 1, 0),
  350. + SOC_DAPM_SINGLE("ADCR Switch", AC_DAC_MIXER_SRC,
  351. + DAC_MIXERR_SRC_ADC, 1, 0),
  352. +};
  353. +
  354. +/* AC_OUT_MIXER_SRC : 0x2222 */
  355. +static const struct snd_kcontrol_new left_output_mixer[] = {
  356. + SOC_DAPM_SINGLE("MIC1 Switch", AC_OUT_MIXER_SRC,
  357. + OUT_MIXERL_SRC_MIC1, 1, 0),
  358. + SOC_DAPM_SINGLE("MIC2 Switch", AC_OUT_MIXER_SRC,
  359. + OUT_MIXERL_SRC_MIC2, 1, 0),
  360. + SOC_DAPM_SINGLE("PhonePN Switch", AC_OUT_MIXER_SRC,
  361. + OUT_MIXERL_SRC_PHPN, 1, 0),
  362. + SOC_DAPM_SINGLE("PhoneN Switch", AC_OUT_MIXER_SRC,
  363. + OUT_MIXERL_SRC_PHN, 1, 0),
  364. + SOC_DAPM_SINGLE("LINEINL Switch", AC_OUT_MIXER_SRC,
  365. + OUT_MIXERL_SRC_LINEL, 1, 0),
  366. + SOC_DAPM_SINGLE("DACL Switch", AC_OUT_MIXER_SRC,
  367. + OUT_MIXERL_SRC_DACL, 1, 0),
  368. + SOC_DAPM_SINGLE("DACR Switch", AC_OUT_MIXER_SRC,
  369. + OUT_MIXERL_SRC_DACR, 1, 0),
  370. +};
  371. +
  372. +static const struct snd_kcontrol_new right_output_mixer[] = {
  373. + SOC_DAPM_SINGLE("MIC1 Switch", AC_OUT_MIXER_SRC,
  374. + OUT_MIXERR_SRC_MIC1, 1, 0),
  375. + SOC_DAPM_SINGLE("MIC2 Switch", AC_OUT_MIXER_SRC,
  376. + OUT_MIXERR_SRC_MIC2, 1, 0),
  377. + SOC_DAPM_SINGLE("PhonePN Switch", AC_OUT_MIXER_SRC,
  378. + OUT_MIXERR_SRC_PHPN, 1, 0),
  379. + SOC_DAPM_SINGLE("PhoneP Switch", AC_OUT_MIXER_SRC,
  380. + OUT_MIXERR_SRC_PHP, 1, 0),
  381. + SOC_DAPM_SINGLE("LINEINR Switch", AC_OUT_MIXER_SRC,
  382. + OUT_MIXERR_SRC_LINER, 1, 0),
  383. + SOC_DAPM_SINGLE("DACR Switch", AC_OUT_MIXER_SRC,
  384. + OUT_MIXERR_SRC_DACR, 1, 0),
  385. + SOC_DAPM_SINGLE("DACL Switch", AC_OUT_MIXER_SRC,
  386. + OUT_MIXERR_SRC_DACL, 1, 0),
  387. +};
  388. +
  389. +/* AC_LINEOUT_CTL : 0x2224 */
  390. +const char * const left_lineout_text[] = {
  391. + "Left OMixer", "LR OMixer",
  392. +};
  393. +
  394. +static const struct soc_enum left_lineout_enum =
  395. + SOC_ENUM_SINGLE(AC_LINEOUT_CTL, LINEL_SRC,
  396. + ARRAY_SIZE(left_lineout_text), left_lineout_text);
  397. +
  398. +static const struct snd_kcontrol_new left_lineout_mux =
  399. + SOC_DAPM_ENUM("Left LINEOUT Mux", left_lineout_enum);
  400. +
  401. +const char * const right_lineout_text[] = {
  402. + "Right OMixer", "LR OMixer",
  403. +};
  404. +
  405. +static const struct soc_enum right_lineout_enum =
  406. + SOC_ENUM_SINGLE(AC_LINEOUT_CTL, LINER_SRC,
  407. + ARRAY_SIZE(right_lineout_text), right_lineout_text);
  408. +
  409. +static const struct snd_kcontrol_new right_lineout_mux =
  410. + SOC_DAPM_ENUM("Right LINEOUT Mux", right_lineout_enum);
  411. +
  412. +/* AC_ADC_MIXER_SRC : 0x2322 */
  413. +static const struct snd_kcontrol_new left_input_mixer[] = {
  414. + SOC_DAPM_SINGLE("MIC1 Switch", AC_ADC_MIXER_SRC,
  415. + ADC_MIXERL_MIC1, 1, 0),
  416. + SOC_DAPM_SINGLE("MIC2 Switch", AC_ADC_MIXER_SRC,
  417. + ADC_MIXERL_MIC2, 1, 0),
  418. + SOC_DAPM_SINGLE("PhonePN Switch", AC_ADC_MIXER_SRC,
  419. + ADC_MIXERL_PHPN, 1, 0),
  420. + SOC_DAPM_SINGLE("PhoneN Switch", AC_ADC_MIXER_SRC,
  421. + ADC_MIXERL_PHN, 1, 0),
  422. + SOC_DAPM_SINGLE("LINEINL Switch", AC_ADC_MIXER_SRC,
  423. + ADC_MIXERL_LINEL, 1, 0),
  424. + SOC_DAPM_SINGLE("OMixerL Switch", AC_ADC_MIXER_SRC,
  425. + ADC_MIXERL_MIXL, 1, 0),
  426. + SOC_DAPM_SINGLE("OMixerR Switch", AC_ADC_MIXER_SRC,
  427. + ADC_MIXERL_MIXR, 1, 0),
  428. +};
  429. +
  430. +static const struct snd_kcontrol_new right_input_mixer[] = {
  431. + SOC_DAPM_SINGLE("MIC1 Switch", AC_ADC_MIXER_SRC,
  432. + ADC_MIXERR_MIC1, 1, 0),
  433. + SOC_DAPM_SINGLE("MIC2 Switch", AC_ADC_MIXER_SRC,
  434. + ADC_MIXERR_MIC2, 1, 0),
  435. + SOC_DAPM_SINGLE("PhonePN Switch", AC_ADC_MIXER_SRC,
  436. + ADC_MIXERR_PHPN, 1, 0),
  437. + SOC_DAPM_SINGLE("PhoneP Switch", AC_ADC_MIXER_SRC,
  438. + ADC_MIXERR_PHP, 1, 0),
  439. + SOC_DAPM_SINGLE("LINEINR Switch", AC_ADC_MIXER_SRC,
  440. + ADC_MIXERR_LINER, 1, 0),
  441. + SOC_DAPM_SINGLE("OMixerR Switch", AC_ADC_MIXER_SRC,
  442. + ADC_MIXERR_MIXR, 1, 0),
  443. + SOC_DAPM_SINGLE("OMixerL Switch", AC_ADC_MIXER_SRC,
  444. + ADC_MIXERR_MIXL, 1, 0),
  445. +};
  446. +
  447. +static const struct snd_soc_dapm_widget acx00_codec_dapm_widgets[] = {
  448. + SND_SOC_DAPM_AIF_IN_E("DACL", "Playback", 0, AC_DAC_CTL,
  449. + OUT_MIXER_DACL_EN, 0,
  450. + acx00_playback_event,
  451. + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  452. + SND_SOC_DAPM_AIF_IN_E("DACR", "Playback", 0,
  453. + AC_DAC_CTL, OUT_MIXER_DACR_EN, 0,
  454. + acx00_playback_event,
  455. + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  456. +
  457. + SND_SOC_DAPM_AIF_OUT_E("ADCL", "Capture", 0,
  458. + AC_ADC_MIC_CTL, ADCL_EN, 0,
  459. + acx00_capture_event,
  460. + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  461. + SND_SOC_DAPM_AIF_OUT_E("ADCR", "Capture", 0,
  462. + AC_ADC_MIC_CTL, ADCR_EN, 0,
  463. + acx00_capture_event,
  464. + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  465. +
  466. + SND_SOC_DAPM_MIXER("Left Output Mixer", AC_OUT_MIXER_CTL,
  467. + OUT_MIXER_LMIX_EN, 0,
  468. + left_output_mixer, ARRAY_SIZE(left_output_mixer)),
  469. +
  470. + SND_SOC_DAPM_MIXER("Right Output Mixer", AC_OUT_MIXER_CTL,
  471. + OUT_MIXER_RMIX_EN, 0, right_output_mixer,
  472. + ARRAY_SIZE(right_output_mixer)),
  473. +
  474. + SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
  475. + left_input_mixer, ARRAY_SIZE(left_input_mixer)),
  476. + SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
  477. + right_input_mixer, ARRAY_SIZE(right_input_mixer)),
  478. +
  479. + SND_SOC_DAPM_MIXER("Left DAC Mixer", AC_OUT_MIXER_CTL,
  480. + OUT_MIXER_DACL_EN, 0, dacl_mixer_src,
  481. + ARRAY_SIZE(dacl_mixer_src)),
  482. + SND_SOC_DAPM_MIXER("Right DAC Mixer", AC_OUT_MIXER_CTL,
  483. + OUT_MIXER_DACR_EN, 0, dacr_mixer_src,
  484. + ARRAY_SIZE(dacr_mixer_src)),
  485. +
  486. + SND_SOC_DAPM_MIXER("Left I2S Mixer", SND_SOC_NOPM,
  487. + 0, 0, i2sl_mixer_src, ARRAY_SIZE(i2sl_mixer_src)),
  488. + SND_SOC_DAPM_MIXER("Right I2S Mixer", SND_SOC_NOPM,
  489. + 0, 0, i2sr_mixer_src, ARRAY_SIZE(i2sr_mixer_src)),
  490. +
  491. + SND_SOC_DAPM_MUX("Left LINEOUT Mux", SND_SOC_NOPM,
  492. + 0, 0, &left_lineout_mux),
  493. + SND_SOC_DAPM_MUX("Right LINEOUT Mux", SND_SOC_NOPM,
  494. + 0, 0, &right_lineout_mux),
  495. +
  496. + SND_SOC_DAPM_PGA("MIC1 PGA", AC_ADC_MIC_CTL,
  497. + MIC1_GAIN_EN, 0, NULL, 0),
  498. + SND_SOC_DAPM_PGA("MIC2 PGA", AC_ADC_MIC_CTL,
  499. + MIC2_GAIN_EN, 0, NULL, 0),
  500. +
  501. + SND_SOC_DAPM_MICBIAS("MIC Bias", AC_MICBIAS_CTL,
  502. + MMBIAS_EN, 0),
  503. +
  504. + /* PHONEIN & PHONEOUT not enable in pin assign */
  505. + SND_SOC_DAPM_INPUT("PHONEINP"),
  506. + SND_SOC_DAPM_INPUT("PHONEINN"),
  507. + SND_SOC_DAPM_INPUT("PHONEINPN"),
  508. +
  509. + /* endpoint define */
  510. + SND_SOC_DAPM_LINE("LINEIN", NULL),
  511. + SND_SOC_DAPM_LINE("LINEOUT", acx00_lineout_event),
  512. + SND_SOC_DAPM_MIC("MIC1", NULL),
  513. + SND_SOC_DAPM_MIC("MIC2", NULL),
  514. +};
  515. +
  516. +static const struct snd_soc_dapm_route acx00_codec_dapm_routes[] = {
  517. + {"Left Output Mixer", "MIC1 Switch", "MIC1 PGA"},
  518. + {"Left Output Mixer", "MIC2 Switch", "MIC2 PGA"},
  519. + {"Left Output Mixer", "PhonePN Switch", "PHONEINPN"},
  520. + {"Left Output Mixer", "PhoneN Switch", "PHONEINN"},
  521. + {"Left Output Mixer", "LINEINL Switch", "LINEIN"},
  522. + {"Left Output Mixer", "DACR Switch", "Right DAC Mixer"},
  523. + {"Left Output Mixer", "DACL Switch", "Left DAC Mixer"},
  524. +
  525. + {"Right Output Mixer", "MIC1 Switch", "MIC1 PGA"},
  526. + {"Right Output Mixer", "MIC2 Switch", "MIC2 PGA"},
  527. + {"Right Output Mixer", "PhonePN Switch", "PHONEINPN"},
  528. + {"Right Output Mixer", "PhoneP Switch", "PHONEINP"},
  529. + {"Right Output Mixer", "LINEINR Switch", "LINEIN"},
  530. + {"Right Output Mixer", "DACR Switch", "Right DAC Mixer"},
  531. + {"Right Output Mixer", "DACL Switch", "Left DAC Mixer"},
  532. +
  533. + {"Left LINEOUT Mux", NULL, "Left Output Mixer"},
  534. + {"Left LINEOUT Mux", "LR OMixer", "Right Output Mixer"},
  535. + {"Right LINEOUT Mux", NULL, "Right Output Mixer"},
  536. + {"Right LINEOUT Mux", "LR OMixer", "Left Output Mixer"},
  537. +
  538. + {"Left Input Mixer", "MIC1 Switch", "MIC1 PGA"},
  539. + {"Left Input Mixer", "MIC2 Switch", "MIC2 PGA"},
  540. + {"Left Input Mixer", "PhonePN Switch", "PHONEINPN"},
  541. + {"Left Input Mixer", "PhoneN Switch", "PHONEINN"},
  542. + {"Left Input Mixer", "LINEINL Switch", "LINEIN"},
  543. + {"Left Input Mixer", "OMixerL Switch", "Left Output Mixer"},
  544. + {"Left Input Mixer", "OMixerR Switch", "Right Output Mixer"},
  545. +
  546. + {"Right Input Mixer", "MIC1 Switch", "MIC1 PGA"},
  547. + {"Right Input Mixer", "MIC2 Switch", "MIC2 PGA"},
  548. + {"Right Input Mixer", "PhonePN Switch", "PHONEINPN"},
  549. + {"Right Input Mixer", "PhoneP Switch", "PHONEINP"},
  550. + {"Right Input Mixer", "LINEINR Switch", "LINEIN"},
  551. + {"Right Input Mixer", "OMixerR Switch", "Right Output Mixer"},
  552. + {"Right Input Mixer", "OMixerL Switch", "Left Output Mixer"},
  553. +
  554. + {"Left I2S Mixer", "I2SDACL Switch", "DACL"},
  555. + {"Left I2S Mixer", "ADCL Switch", "Left Input Mixer"},
  556. +
  557. + {"Right I2S Mixer", "I2SDACR Switch", "DACR"},
  558. + {"Right I2S Mixer", "ADCR Switch", "Right Input Mixer"},
  559. +
  560. + {"Left DAC Mixer", "I2SDACL Switch", "DACL"},
  561. + {"Left DAC Mixer", "ADCL Switch", "Left Input Mixer"},
  562. +
  563. + {"Right DAC Mixer", "I2SDACR Switch", "DACR"},
  564. + {"Right DAC Mixer", "ADCR Switch", "Right Input Mixer"},
  565. +
  566. + {"ADCL", NULL, "Left I2S Mixer"},
  567. + {"ADCR", NULL, "Right I2S Mixer"},
  568. +
  569. + {"LINEOUT", NULL, "Left LINEOUT Mux"},
  570. + {"LINEOUT", NULL, "Right LINEOUT Mux"},
  571. +
  572. + {"MIC Bias", NULL, "MIC1"},
  573. + {"MIC Bias", NULL, "MIC2"},
  574. + {"MIC1 PGA", NULL, "MIC Bias"},
  575. + {"MIC2 PGA", NULL, "MIC Bias"},
  576. +};
  577. +
  578. +static void acx00_codec_txctrl_enable(struct snd_soc_component *component,
  579. + int enable)
  580. +{
  581. + pr_debug("Enter %s, enable %d\n", __func__, enable);
  582. + if (enable) {
  583. + snd_soc_component_update_bits(component, AC_I2S_CTL,
  584. + (1<<I2S_RX_EN), (1<<I2S_RX_EN));
  585. + } else {
  586. + snd_soc_component_update_bits(component, AC_I2S_CTL,
  587. + (1<<I2S_RX_EN), (0<<I2S_RX_EN));
  588. + }
  589. + pr_debug("End %s, enable %d\n", __func__, enable);
  590. +}
  591. +
  592. +static void acx00_codec_rxctrl_enable(struct snd_soc_component *component,
  593. + int enable)
  594. +{
  595. + pr_debug("Enter %s, enable %d\n", __func__, enable);
  596. + if (enable) {
  597. + snd_soc_component_update_bits(component, AC_I2S_CTL,
  598. + (1<<I2S_TX_EN), (1<<I2S_TX_EN));
  599. + } else {
  600. + snd_soc_component_update_bits(component, AC_I2S_CTL,
  601. + (1<<I2S_TX_EN), (0<<I2S_TX_EN));
  602. + }
  603. + pr_debug("End %s, enable %d\n", __func__, enable);
  604. +}
  605. +
  606. +int acx00_reg_read(struct ac200_dev *acx00, unsigned short reg)
  607. +{
  608. + unsigned int val;
  609. + int ret;
  610. +
  611. + ret = regmap_read(acx00->regmap, reg, &val);
  612. +
  613. + if (ret < 0)
  614. + return ret;
  615. + else
  616. + return val;
  617. +}
  618. +
  619. +int acx00_reg_write(struct ac200_dev *acx00, unsigned short reg, unsigned short val)
  620. +{
  621. + return regmap_write(acx00->regmap, reg, val);
  622. +}
  623. +
  624. +static void acx00_codec_init(struct snd_soc_component *component)
  625. +{
  626. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  627. +
  628. + acx00_reg_write(priv->acx00, 0x50, 0x82b1);
  629. + acx00_reg_write(priv->acx00, 0xc, 0xce01);
  630. +
  631. + /* acx00_codec sysctl init */
  632. + acx00_reg_write(priv->acx00, 0x0010, 0x03);
  633. + acx00_reg_write(priv->acx00, 0x0012, 0x01);
  634. +
  635. + /* The bit3 need to setup to 1 for bias current. */
  636. + snd_soc_component_update_bits(component, AC_MICBIAS_CTL,
  637. + (0x1 << ADDA_BIAS_CUR), (0x1 << ADDA_BIAS_CUR));
  638. +
  639. + /* enable the output & global enable bit */
  640. + snd_soc_component_update_bits(component, AC_I2S_CTL,
  641. + (1<<I2S_SDO0_EN), (1<<I2S_SDO0_EN));
  642. + snd_soc_component_update_bits(component, AC_I2S_CTL, (1<<I2S_GEN), (1<<I2S_GEN));
  643. +
  644. + /* Default setting slot width as 32 bit for I2S */
  645. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  646. + (7<<I2S_FMT_SLOT_WIDTH), (7<<I2S_FMT_SLOT_WIDTH));
  647. +
  648. + /* default setting 0xA0A0 for ADC & DAC Volume */
  649. + snd_soc_component_write(component, AC_I2S_DAC_VOL, ACX00_DEF_VOL);
  650. + snd_soc_component_write(component, AC_I2S_ADC_VOL, ACX00_DEF_VOL);
  651. +
  652. + /* Enable HPF for high pass filter */
  653. + snd_soc_component_update_bits(component, AC_DAC_CTL,
  654. + (1<<DAC_CTL_HPF_EN), (1<<DAC_CTL_HPF_EN));
  655. +
  656. + /* LINEOUT ANTI POP & Click noise */
  657. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL,
  658. + (0x7<<LINE_ANTI_TIME), (0x3<<LINE_ANTI_TIME));
  659. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL,
  660. + (0x3<<LINE_SLOPE_SEL), (0x3<<LINE_SLOPE_SEL));
  661. +
  662. + /* enable & setting adc convert delay time */
  663. + snd_soc_component_update_bits(component, AC_ADC_CTL, (0x3<<ADC_DELAY_TIME),
  664. + (0x3<<ADC_DELAY_TIME));
  665. + snd_soc_component_update_bits(component, AC_ADC_CTL, (1<<ADC_DELAY_EN),
  666. + (1<<ADC_DELAY_EN));
  667. +
  668. + if (priv->spk_gpio_used) {
  669. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  670. + (1<<LINEL_SRC_EN), (1<<LINEL_SRC_EN));
  671. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  672. + (1<<LINER_SRC_EN), (1<<LINER_SRC_EN));
  673. + priv->enable = 1;
  674. + }
  675. +#ifndef ACX00_DAPM_LINEOUT
  676. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL, (1<<LINEOUT_EN),
  677. + (1<<LINEOUT_EN));
  678. +#endif
  679. +
  680. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL, 0x1f, 0x0f);
  681. + snd_soc_component_write(component, AC_DAC_MIXER_SRC, 0x2200);
  682. + snd_soc_component_write(component, AC_OUT_MIXER_SRC, 0x0202);
  683. +}
  684. +
  685. +static int acx00_codec_hw_params(struct snd_pcm_substream *substream,
  686. + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
  687. +{
  688. + struct snd_soc_component *component = dai->component;
  689. + int i;
  690. +
  691. + switch (params_format(params)) {
  692. + case SNDRV_PCM_FORMAT_S16_LE:
  693. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  694. + (7<<I2S_FMT_SAMPLE), (3<<I2S_FMT_SAMPLE));
  695. + break;
  696. + case SNDRV_PCM_FORMAT_S24_LE:
  697. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  698. + (7<<I2S_FMT_SAMPLE), (5<<I2S_FMT_SAMPLE));
  699. + break;
  700. + case SNDRV_PCM_FORMAT_S32_LE:
  701. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  702. + (7<<I2S_FMT_SAMPLE), (7<<I2S_FMT_SAMPLE));
  703. + break;
  704. + default:
  705. + dev_err(component->dev, "unrecognized format support\n");
  706. + break;
  707. + }
  708. + for (i = 0; i < ARRAY_SIZE(sample_rate_conv); i++) {
  709. + if (sample_rate_conv[i].samplerate == params_rate(params)) {
  710. + snd_soc_component_update_bits(component, AC_SYS_SR_CTL,
  711. + (SYS_SR_MASK<<SYS_SR_BIT),
  712. + (sample_rate_conv[i].rate_bit<<SYS_SR_BIT));
  713. + }
  714. + }
  715. +
  716. + return 0;
  717. +}
  718. +
  719. +static int acx00_codec_dai_set_sysclk(struct snd_soc_dai *codec_dai,
  720. + int clk_id, unsigned int freq, int dir)
  721. +{
  722. + return 0;
  723. +}
  724. +
  725. +static int acx00_codec_dai_set_fmt(struct snd_soc_dai *codec_dai,
  726. + unsigned int fmt)
  727. +{
  728. + struct acx00_priv *priv = snd_soc_dai_get_drvdata(codec_dai);
  729. + struct snd_soc_component *component = priv->component;
  730. +
  731. + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  732. + /* codec clk & FRM master */
  733. + case SND_SOC_DAIFMT_CBM_CFM:
  734. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  735. + (0x1<<I2S_BCLK_OUT), (0x1<<I2S_BCLK_OUT));
  736. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  737. + (0x1<<I2S_LRCK_OUT), (0x1<<I2S_LRCK_OUT));
  738. + break;
  739. + /* codec clk & FRM slave */
  740. + case SND_SOC_DAIFMT_CBS_CFS:
  741. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  742. + (0x1<<I2S_BCLK_OUT), 0x0<<I2S_BCLK_OUT);
  743. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  744. + (0x1<<I2S_LRCK_OUT), 0x0<<I2S_LRCK_OUT);
  745. + break;
  746. + }
  747. +
  748. + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  749. + case SND_SOC_DAIFMT_I2S:
  750. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  751. + (0x3FF<<I2S_LRCK_PERIOD),
  752. + (0x1F<<I2S_LRCK_PERIOD));
  753. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  754. + (0x3<<I2S_FMT_MODE), (0x1<<I2S_FMT_MODE));
  755. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  756. + (0x1<<I2S_FMT_TX_OFFSET),
  757. + (0x1<<I2S_FMT_TX_OFFSET));
  758. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  759. + (0x1<<I2S_FMT_RX_OFFSET),
  760. + (0x1<<I2S_FMT_RX_OFFSET));
  761. + break;
  762. + case SND_SOC_DAIFMT_RIGHT_J:
  763. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  764. + (0x3FF<<I2S_LRCK_PERIOD),
  765. + (0x1F<<I2S_LRCK_PERIOD));
  766. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  767. + (0x3<<I2S_FMT_MODE), (0x2<<I2S_FMT_MODE));
  768. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  769. + (0x1<<I2S_FMT_TX_OFFSET),
  770. + (0x0<<I2S_FMT_TX_OFFSET));
  771. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  772. + (0x1<<I2S_FMT_TX_OFFSET),
  773. + (0x0<<I2S_FMT_RX_OFFSET));
  774. + break;
  775. + case SND_SOC_DAIFMT_LEFT_J:
  776. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  777. + (0x3FF<<I2S_LRCK_PERIOD),
  778. + (0x1F<<I2S_LRCK_PERIOD));
  779. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  780. + (0x3<<I2S_FMT_MODE), (0x1<<I2S_FMT_MODE));
  781. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  782. + (0x1<<I2S_FMT_TX_OFFSET),
  783. + (0x0<<I2S_FMT_TX_OFFSET));
  784. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  785. + (0x1<<I2S_FMT_RX_OFFSET),
  786. + (0x0<<I2S_FMT_RX_OFFSET));
  787. + break;
  788. + case SND_SOC_DAIFMT_DSP_A:
  789. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  790. + (0x3FF<<I2S_LRCK_PERIOD),
  791. + (0x3F<<I2S_LRCK_PERIOD));
  792. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  793. + (0x3<<I2S_FMT_MODE), (0x0<<I2S_FMT_MODE));
  794. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  795. + (0x1<<I2S_FMT_TX_OFFSET),
  796. + (0x1<<I2S_FMT_TX_OFFSET));
  797. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  798. + (0x1<<I2S_FMT_RX_OFFSET),
  799. + (0x1<<I2S_FMT_RX_OFFSET));
  800. + break;
  801. + case SND_SOC_DAIFMT_DSP_B:
  802. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  803. + (0x3FF<<I2S_LRCK_PERIOD),
  804. + (0x3F<<I2S_LRCK_PERIOD));
  805. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  806. + (0x3<<I2S_FMT_MODE), (0x0<<I2S_FMT_MODE));
  807. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  808. + (0x1<<I2S_FMT_TX_OFFSET),
  809. + (0x0<<I2S_FMT_TX_OFFSET));
  810. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  811. + (0x1<<I2S_FMT_RX_OFFSET),
  812. + (0x0<<I2S_FMT_RX_OFFSET));
  813. + break;
  814. + default:
  815. + dev_err(component->dev, "format setting failed\n");
  816. + break;
  817. + }
  818. +
  819. + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  820. + case SND_SOC_DAIFMT_NB_NF:
  821. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  822. + (0x1<<I2S_FMT_BCLK_POLAR),
  823. + (0x0<<I2S_FMT_BCLK_POLAR));
  824. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  825. + (0x1<<I2S_FMT_LRCK_POLAR),
  826. + (0x0<<I2S_FMT_LRCK_POLAR));
  827. + break;
  828. + case SND_SOC_DAIFMT_NB_IF:
  829. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  830. + (0x1<<I2S_FMT_BCLK_POLAR),
  831. + (0x0<<I2S_FMT_BCLK_POLAR));
  832. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  833. + (0x1<<I2S_FMT_LRCK_POLAR),
  834. + (0x1<<I2S_FMT_LRCK_POLAR));
  835. + break;
  836. + case SND_SOC_DAIFMT_IB_NF:
  837. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  838. + (0x1<<I2S_FMT_BCLK_POLAR),
  839. + (0x1<<I2S_FMT_BCLK_POLAR));
  840. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  841. + (0x1<<I2S_FMT_LRCK_POLAR),
  842. + (0x0<<I2S_FMT_LRCK_POLAR));
  843. + break;
  844. + case SND_SOC_DAIFMT_IB_IF:
  845. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  846. + (0x1<<I2S_FMT_BCLK_POLAR),
  847. + (0x1<<I2S_FMT_BCLK_POLAR));
  848. + snd_soc_component_update_bits(component, AC_I2S_FMT1,
  849. + (0x1<<I2S_FMT_LRCK_POLAR),
  850. + (0x1<<I2S_FMT_LRCK_POLAR));
  851. + break;
  852. + default:
  853. + dev_err(component->dev, "invert clk setting failed\n");
  854. + return -EINVAL;
  855. + }
  856. + return 0;
  857. +}
  858. +
  859. +static int acx00_codec_dai_set_clkdiv(struct snd_soc_dai *codec_dai,
  860. + int clk_id, int clk_div)
  861. +{
  862. + struct acx00_priv *priv = snd_soc_dai_get_drvdata(codec_dai);
  863. + struct snd_soc_component *component = priv->component;
  864. + unsigned int bclk_div;
  865. + /*
  866. + * when PCM mode, setting as 64fs, when I2S mode as 32fs,
  867. + * then two channel, then just as 64fs
  868. + */
  869. + unsigned int div_ratio = clk_div / 64;
  870. +
  871. + switch (div_ratio) {
  872. + case 1:
  873. + bclk_div = I2S_BCLK_DIV_1;
  874. + break;
  875. + case 2:
  876. + bclk_div = I2S_BCLK_DIV_2;
  877. + break;
  878. + case 4:
  879. + bclk_div = I2S_BCLK_DIV_3;
  880. + break;
  881. + case 6:
  882. + bclk_div = I2S_BCLK_DIV_4;
  883. + break;
  884. + case 8:
  885. + bclk_div = I2S_BCLK_DIV_5;
  886. + break;
  887. + case 12:
  888. + bclk_div = I2S_BCLK_DIV_6;
  889. + break;
  890. + case 16:
  891. + bclk_div = I2S_BCLK_DIV_7;
  892. + break;
  893. + case 24:
  894. + bclk_div = I2S_BCLK_DIV_8;
  895. + break;
  896. + case 32:
  897. + bclk_div = I2S_BCLK_DIV_9;
  898. + break;
  899. + case 48:
  900. + bclk_div = I2S_BCLK_DIV_10;
  901. + break;
  902. + case 64:
  903. + bclk_div = I2S_BCLK_DIV_11;
  904. + break;
  905. + case 96:
  906. + bclk_div = I2S_BCLK_DIV_12;
  907. + break;
  908. + case 128:
  909. + bclk_div = I2S_BCLK_DIV_13;
  910. + break;
  911. + case 176:
  912. + bclk_div = I2S_BCLK_DIV_14;
  913. + break;
  914. + case 192:
  915. + bclk_div = I2S_BCLK_DIV_15;
  916. + break;
  917. + default:
  918. + dev_err(component->dev, "setting blck div failed\n");
  919. + break;
  920. + }
  921. +
  922. + snd_soc_component_update_bits(component, AC_I2S_CLK,
  923. + (I2S_BCLK_DIV_MASK<<I2S_BLCK_DIV),
  924. + (bclk_div<<I2S_BLCK_DIV));
  925. + return 0;
  926. +}
  927. +
  928. +static int acx00_codec_startup(struct snd_pcm_substream *substream,
  929. + struct snd_soc_dai *codec_dai)
  930. +{
  931. + return 0;
  932. +}
  933. +
  934. +static bool acx00_loop_en;
  935. +module_param(acx00_loop_en, bool, 0644);
  936. +MODULE_PARM_DESC(acx00_loop_en, "ACX00-Codec audio loopback debug(Y=enable, N=disable)");
  937. +
  938. +static int acx00_codec_trigger(struct snd_pcm_substream *substream,
  939. + int cmd, struct snd_soc_dai *codec_dai)
  940. +{
  941. + struct snd_soc_component *component = codec_dai->component;
  942. + return 0;
  943. +}
  944. +
  945. +static int acx00_codec_prepare(struct snd_pcm_substream *substream,
  946. + struct snd_soc_dai *codec_dai)
  947. +{
  948. + struct snd_soc_component *component = codec_dai->component;
  949. +
  950. + snd_soc_component_update_bits(component, AC_SYS_CLK_CTL,
  951. + (0x1<<SYS_CLK_I2S), (0x1<<SYS_CLK_I2S));
  952. + snd_soc_component_update_bits(component, AC_SYS_MOD_RST,
  953. + (0x1<<MOD_RST_I2S), (0x1<<MOD_RST_I2S));
  954. +
  955. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  956. + if (acx00_loop_en)
  957. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  958. + (0x1<<I2S_FMT_LOOP),
  959. + (0x1<<I2S_FMT_LOOP));
  960. + else
  961. + snd_soc_component_update_bits(component, AC_I2S_FMT0,
  962. + (0x1<<I2S_FMT_LOOP),
  963. + (0x0<<I2S_FMT_LOOP));
  964. + acx00_codec_txctrl_enable(component, 1);
  965. + } else
  966. + acx00_codec_rxctrl_enable(component, 1);
  967. + return 0;
  968. +}
  969. +
  970. +static int acx00_codec_digital_mute(struct snd_soc_dai *codec_dai,
  971. + int mute)
  972. +{
  973. + struct snd_soc_component *component = codec_dai->component;
  974. +
  975. + if (mute)
  976. + snd_soc_component_write(component, AC_I2S_DAC_VOL, 0);
  977. + else
  978. + snd_soc_component_write(component, AC_I2S_DAC_VOL, ACX00_DEF_VOL);
  979. + return 0;
  980. +}
  981. +
  982. +static void acx00_codec_shutdown(struct snd_pcm_substream *substream,
  983. + struct snd_soc_dai *dai)
  984. +{
  985. + struct snd_soc_component *component = dai->component;
  986. +
  987. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  988. + acx00_codec_txctrl_enable(component, 0);
  989. + else
  990. + acx00_codec_rxctrl_enable(component, 0);
  991. +}
  992. +
  993. +static const struct snd_soc_dai_ops acx00_codec_dai_ops = {
  994. + .hw_params = acx00_codec_hw_params,
  995. + .shutdown = acx00_codec_shutdown,
  996. +// .digital_mute = acx00_codec_digital_mute,
  997. + .set_sysclk = acx00_codec_dai_set_sysclk,
  998. + .set_fmt = acx00_codec_dai_set_fmt,
  999. + .set_clkdiv = acx00_codec_dai_set_clkdiv,
  1000. + .startup = acx00_codec_startup,
  1001. + .trigger = acx00_codec_trigger,
  1002. + .prepare = acx00_codec_prepare,
  1003. +};
  1004. +
  1005. +static struct snd_soc_dai_driver acx00_codec_dai[] = {
  1006. + {
  1007. + .name = "acx00-dai",
  1008. + .playback = {
  1009. + .stream_name = "Playback",
  1010. + .channels_min = 1,
  1011. + .channels_max = 2,
  1012. + .rates = SNDRV_PCM_RATE_8000_192000
  1013. + | SNDRV_PCM_RATE_KNOT,
  1014. + .formats = SNDRV_PCM_FMTBIT_S16_LE
  1015. + | SNDRV_PCM_FMTBIT_S24_LE
  1016. + | SNDRV_PCM_FMTBIT_S32_LE,
  1017. + },
  1018. +
  1019. + .capture = {
  1020. + .stream_name = "Capture",
  1021. + .channels_min = 1,
  1022. + .channels_max = 2,
  1023. + .rates = SNDRV_PCM_RATE_8000_192000
  1024. + | SNDRV_PCM_RATE_KNOT,
  1025. + .formats = SNDRV_PCM_FMTBIT_S16_LE
  1026. + | SNDRV_PCM_FMTBIT_S24_LE
  1027. + | SNDRV_PCM_FMTBIT_S32_LE,
  1028. + },
  1029. +
  1030. + .ops = &acx00_codec_dai_ops,
  1031. + },
  1032. +};
  1033. +
  1034. +static void acx00_codec_resume_work(struct work_struct *work)
  1035. +{
  1036. + struct acx00_priv *priv = container_of(work,
  1037. + struct acx00_priv, resume_work.work);
  1038. +
  1039. + acx00_codec_init(priv->component);
  1040. +}
  1041. +
  1042. +static int acx00_codec_probe(struct snd_soc_component *component)
  1043. +{
  1044. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  1045. + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  1046. + int ret = 0;
  1047. +
  1048. + mutex_init(&priv->mutex);
  1049. +
  1050. + priv->component = component;
  1051. +#if 0
  1052. + /* Add virtual switch */
  1053. + ret = snd_soc_add_component_controls(component, acx00_codec_controls,
  1054. + ARRAY_SIZE(acx00_codec_controls));
  1055. + if (ret) {
  1056. + pr_err("[audio-codec] Failed to register audio mode control, will continue without it.\n");
  1057. + }
  1058. + snd_soc_dapm_new_controls(dapm, acx00_codec_dapm_widgets, ARRAY_SIZE(acx00_codec_dapm_widgets));
  1059. + snd_soc_dapm_add_routes(dapm, acx00_codec_dapm_routes, ARRAY_SIZE(acx00_codec_dapm_routes));
  1060. +#endif
  1061. + /* using late_initcall to wait 120ms acx00-core to make chip reset */
  1062. + acx00_codec_init(component);
  1063. + INIT_DELAYED_WORK(&priv->spk_work, acx00_spk_enable);
  1064. + INIT_DELAYED_WORK(&priv->resume_work, acx00_codec_resume_work);
  1065. + return 0;
  1066. +}
  1067. +
  1068. +static void acx00_codec_remove(struct snd_soc_component *component)
  1069. +{
  1070. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  1071. +
  1072. + cancel_delayed_work_sync(&priv->spk_work);
  1073. + cancel_delayed_work_sync(&priv->resume_work);
  1074. +}
  1075. +
  1076. +static unsigned int acx00_codec_read(struct snd_soc_component *component,
  1077. + unsigned int reg)
  1078. +{
  1079. + unsigned int data;
  1080. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  1081. +
  1082. + /* Device I/O API */
  1083. + data = acx00_reg_read(priv->acx00, reg);
  1084. + return data;
  1085. +}
  1086. +
  1087. +static int acx00_codec_write(struct snd_soc_component *component,
  1088. + unsigned int reg, unsigned int value)
  1089. +{
  1090. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  1091. +
  1092. + return acx00_reg_write(priv->acx00, reg, value);
  1093. +}
  1094. +
  1095. +static int sunxi_gpio_iodisable(u32 gpio)
  1096. +{
  1097. + char pin_name[8];
  1098. + u32 config, ret;
  1099. +#if 0
  1100. + sunxi_gpio_to_name(gpio, pin_name);
  1101. + config = 7 << 16;
  1102. + ret = pin_config_set(SUNXI_PINCTRL, pin_name, config);
  1103. +#endif
  1104. + return ret;
  1105. +}
  1106. +
  1107. +static int acx00_codec_suspend(struct snd_soc_component *component)
  1108. +{
  1109. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  1110. +
  1111. + pr_debug("Enter %s\n", __func__);
  1112. +
  1113. + clk_disable_unprepare(priv->clk);
  1114. +
  1115. + /* PA_CTRL first setting low state, then make it iodisabled */
  1116. + if (priv->spk_gpio_used) {
  1117. + sunxi_gpio_iodisable(priv->spk_gpio);
  1118. + msleep(30);
  1119. + }
  1120. +
  1121. + /*
  1122. + * when codec suspend, then the register reset, if auto reset produce
  1123. + * Pop & Click noise, then we should cut down the LINEOUT in this town.
  1124. + */
  1125. + if (priv->enable) {
  1126. + snd_soc_component_update_bits(component, AC_LINEOUT_CTL,
  1127. + (1<<LINEOUT_EN), (0<<LINEOUT_EN));
  1128. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  1129. + (1<<LINEL_SRC_EN), (0<<LINEL_SRC_EN));
  1130. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  1131. + (1<<LINER_SRC_EN), (0<<LINER_SRC_EN));
  1132. + priv->enable = 0;
  1133. + }
  1134. +
  1135. + pr_debug("Exit %s\n", __func__);
  1136. +
  1137. + return 0;
  1138. +}
  1139. +
  1140. +static int acx00_codec_resume(struct snd_soc_component *component)
  1141. +{
  1142. + struct acx00_priv *priv = snd_soc_component_get_drvdata(component);
  1143. +
  1144. + pr_debug("Enter %s\n", __func__);
  1145. +
  1146. + if (clk_prepare_enable(priv->clk)) {
  1147. + dev_err(component->dev, "codec resume clk failed\n");
  1148. + return -EBUSY;
  1149. + }
  1150. +
  1151. + schedule_delayed_work(&priv->resume_work, msecs_to_jiffies(300));
  1152. +
  1153. + if (priv->spk_gpio_used) {
  1154. + gpio_direction_output(priv->spk_gpio, 1);
  1155. + gpio_set_value(priv->spk_gpio, 0);
  1156. + }
  1157. +
  1158. + pr_debug("Exit %s\n", __func__);
  1159. +
  1160. + return 0;
  1161. +}
  1162. +
  1163. +
  1164. +static int acx00_codec_set_bias_level(struct snd_soc_component *component,
  1165. + enum snd_soc_bias_level level)
  1166. +{
  1167. + component->dapm.bias_level = level;
  1168. + return 0;
  1169. +}
  1170. +
  1171. +struct label {
  1172. + const char *name;
  1173. + int value;
  1174. +};
  1175. +
  1176. +#define LABEL(constant) { #constant, constant }
  1177. +#define LABEL_END { NULL, -1 }
  1178. +
  1179. +static struct label reg_labels[] = {
  1180. + LABEL(AC_SYS_CLK_CTL),
  1181. + LABEL(AC_SYS_MOD_RST),
  1182. + LABEL(AC_SYS_SR_CTL),
  1183. + LABEL(AC_I2S_CTL),
  1184. + LABEL(AC_I2S_CLK),
  1185. + LABEL(AC_I2S_FMT0),
  1186. + LABEL(AC_I2S_FMT1),
  1187. + LABEL(AC_I2S_MIXER_SRC),
  1188. + LABEL(AC_I2S_MIXER_GAIN),
  1189. + LABEL(AC_I2S_DAC_VOL),
  1190. + LABEL(AC_I2S_ADC_VOL),
  1191. + LABEL(AC_DAC_CTL),
  1192. + LABEL(AC_DAC_MIXER_SRC),
  1193. + LABEL(AC_DAC_MIXER_GAIN),
  1194. + LABEL(AC_OUT_MIXER_CTL),
  1195. + LABEL(AC_OUT_MIXER_SRC),
  1196. + LABEL(AC_LINEOUT_CTL),
  1197. + LABEL(AC_ADC_CTL),
  1198. + LABEL(AC_MICBIAS_CTL),
  1199. + LABEL(AC_ADC_MIC_CTL),
  1200. + LABEL(AC_ADC_MIXER_SRC),
  1201. + LABEL(AC_BIAS_CTL),
  1202. + LABEL(AC_ANALOG_PROF_CTL),
  1203. + LABEL_END,
  1204. +};
  1205. +
  1206. +static ssize_t show_audio_reg(struct device *dev,
  1207. + struct device_attribute *attr, char *buf)
  1208. +{
  1209. + struct acx00_priv *priv = dev_get_drvdata(dev);
  1210. + int count = 0, i = 0;
  1211. + unsigned int reg_val;
  1212. +
  1213. + count += sprintf(buf, "dump audio reg:\n");
  1214. +
  1215. + while (reg_labels[i].name != NULL) {
  1216. + reg_val = acx00_reg_read(priv->acx00, reg_labels[i].value);
  1217. + count += sprintf(buf + count, "%s 0x%x: 0x%x\n",
  1218. + reg_labels[i].name, (reg_labels[i].value), reg_val);
  1219. + i++;
  1220. + }
  1221. +
  1222. + return count;
  1223. +}
  1224. +
  1225. +/*
  1226. + * param 1: 0 read;1 write
  1227. + * param 2: 1 digital reg; 2 analog reg
  1228. + * param 3: reg value;
  1229. + * param 4: write value;
  1230. + * read:
  1231. + * echo 0,1,0x00> audio_reg
  1232. + * echo 0,2,0x00> audio_reg
  1233. + * write:
  1234. + * echo 1,1,0x00,0xa > audio_reg
  1235. + * echo 1,2,0x00,0xff > audio_reg
  1236. +*/
  1237. +static ssize_t store_audio_reg(struct device *dev,
  1238. + struct device_attribute *attr, const char *buf, size_t count)
  1239. +{
  1240. + int ret;
  1241. + int rw_flag;
  1242. + unsigned int input_reg_val = 0;
  1243. + int input_reg_group = 0;
  1244. + unsigned int input_reg_offset = 0;
  1245. + struct acx00_priv *priv = dev_get_drvdata(dev);
  1246. +
  1247. + ret = sscanf(buf, "%d,%d,0x%x,0x%x", &rw_flag, &input_reg_group,
  1248. + &input_reg_offset, &input_reg_val);
  1249. + dev_info(dev, "ret:%d, reg_group:%d, reg_offset:%d, reg_val:0x%x\n",
  1250. + ret, input_reg_group, input_reg_offset, input_reg_val);
  1251. +
  1252. + if (input_reg_group != 1) {
  1253. + pr_err("not exist reg group\n");
  1254. + ret = count;
  1255. + goto out;
  1256. + }
  1257. + if (!(rw_flag == 1 || rw_flag == 0)) {
  1258. + pr_err("not rw_flag\n");
  1259. + ret = count;
  1260. + goto out;
  1261. + }
  1262. +
  1263. + if (rw_flag) {
  1264. + acx00_reg_write(priv->acx00, input_reg_offset, input_reg_val);
  1265. + } else {
  1266. + input_reg_val = acx00_reg_read(priv->acx00, input_reg_offset);
  1267. + dev_info(dev, "\n\n Reg[0x%x] : 0x%04x\n\n",
  1268. + input_reg_offset, input_reg_val);
  1269. + }
  1270. + ret = count;
  1271. +
  1272. +out:
  1273. + return ret;
  1274. +}
  1275. +
  1276. +static DEVICE_ATTR(audio_reg, 0644, show_audio_reg, store_audio_reg);
  1277. +
  1278. +static struct attribute *audio_debug_attrs[] = {
  1279. + &dev_attr_audio_reg.attr,
  1280. + NULL,
  1281. +};
  1282. +
  1283. +static struct attribute_group audio_debug_attr_group = {
  1284. + .name = "audio_reg_debug",
  1285. + .attrs = audio_debug_attrs,
  1286. +};
  1287. +
  1288. +static struct snd_soc_component_driver soc_codec_driver_acx00 = {
  1289. + .probe = acx00_codec_probe,
  1290. + .remove = acx00_codec_remove,
  1291. + .suspend = acx00_codec_suspend,
  1292. + .resume = acx00_codec_resume,
  1293. + .read = acx00_codec_read,
  1294. + .write = acx00_codec_write,
  1295. +// .ignore_pmdown_time = 1,
  1296. + .set_bias_level = acx00_codec_set_bias_level,
  1297. + .controls = acx00_codec_controls,
  1298. + .num_controls = ARRAY_SIZE(acx00_codec_controls),
  1299. + .dapm_widgets = acx00_codec_dapm_widgets,
  1300. + .num_dapm_widgets = ARRAY_SIZE(acx00_codec_dapm_widgets),
  1301. + .dapm_routes = acx00_codec_dapm_routes,
  1302. + .num_dapm_routes = ARRAY_SIZE(acx00_codec_dapm_routes),
  1303. +};
  1304. +
  1305. +/* through acx00 is part of mfd devices, after the mfd */
  1306. +static int acx00_codec_dev_probe(struct platform_device *pdev)
  1307. +{
  1308. + struct acx00_priv *priv;
  1309. + int ret;
  1310. + struct device_node *np = of_find_compatible_node(NULL, NULL, "allwinner,ac200_codec");
  1311. +
  1312. + priv = devm_kzalloc(&pdev->dev, sizeof(struct acx00_priv), GFP_KERNEL);
  1313. + if (!priv) {
  1314. + dev_err(&pdev->dev, "acx00 codec priv mem alloc failed\n");
  1315. + return -ENOMEM;
  1316. + }
  1317. +
  1318. + platform_set_drvdata(pdev, priv);
  1319. + priv->acx00 = dev_get_drvdata(pdev->dev.parent);
  1320. +
  1321. + if (np) {
  1322. + ret = of_get_named_gpio(np, "gpio-spk", 0);
  1323. + if (ret >= 0) {
  1324. + priv->spk_gpio_used = 1;
  1325. + priv->spk_gpio = ret;
  1326. + if (!gpio_is_valid(priv->spk_gpio)) {
  1327. + dev_err(&pdev->dev, "gpio-spk is valid\n");
  1328. + ret = -EINVAL;
  1329. + goto err_devm_kfree;
  1330. + } else {
  1331. + ret = devm_gpio_request(&pdev->dev,
  1332. + priv->spk_gpio, "SPK");
  1333. + if (ret) {
  1334. + dev_err(&pdev->dev,
  1335. + "failed request gpio-spk\n");
  1336. + ret = -EBUSY;
  1337. + goto err_devm_kfree;
  1338. + } else {
  1339. + gpio_direction_output(priv->spk_gpio,
  1340. + 1);
  1341. + gpio_set_value(priv->spk_gpio, 0);
  1342. + }
  1343. + }
  1344. + } else {
  1345. + priv->spk_gpio_used = 0;
  1346. + }
  1347. +
  1348. + ret = of_get_named_gpio(np, "gpio-switch", 0);
  1349. + if (ret >= 0) {
  1350. + priv->switch_gpio = ret;
  1351. + if (!gpio_is_valid(priv->switch_gpio)) {
  1352. + dev_err(&pdev->dev, "gpio-switch is valid\n");
  1353. + ret = -EINVAL;
  1354. + goto err_devm_kfree;
  1355. + } else {
  1356. + ret = devm_gpio_request(&pdev->dev, priv->switch_gpio, "SWITCH");
  1357. + if (ret) {
  1358. + dev_err(&pdev->dev,
  1359. + "failed request gpio-switch\n");
  1360. + ret = -EBUSY;
  1361. + goto err_devm_kfree;
  1362. + } else {
  1363. + gpio_direction_output(priv->switch_gpio, 1);
  1364. + gpio_set_value(priv->switch_gpio, 1);
  1365. + }
  1366. + }
  1367. + }
  1368. + }
  1369. +
  1370. + ret = snd_soc_register_component(&pdev->dev, &soc_codec_driver_acx00,
  1371. + acx00_codec_dai, ARRAY_SIZE(acx00_codec_dai));
  1372. +
  1373. + if (ret < 0)
  1374. + dev_err(&pdev->dev, "Failed register acx00: %d\n", ret);
  1375. +
  1376. + ret = sysfs_create_group(&pdev->dev.kobj, &audio_debug_attr_group);
  1377. + if (ret)
  1378. + dev_warn(&pdev->dev, "failed to create attr group\n");
  1379. +
  1380. + return 0;
  1381. +
  1382. +err_devm_kfree:
  1383. + devm_kfree(&pdev->dev, priv);
  1384. + return ret;
  1385. +}
  1386. +
  1387. +/* Mark this space to clear the LINEOUT & gpio */
  1388. +static void acx00_codec_dev_shutdown(struct platform_device *pdev)
  1389. +{
  1390. + struct acx00_priv *priv = platform_get_drvdata(pdev);
  1391. +
  1392. + if (priv->spk_gpio_used)
  1393. + gpio_set_value(priv->spk_gpio, 0);
  1394. +}
  1395. +
  1396. +static int acx00_codec_dev_remove(struct platform_device *pdev)
  1397. +{
  1398. + struct acx00_priv *priv = platform_get_drvdata(pdev);
  1399. +
  1400. +#ifndef ACX00_DAPM_LINEOUT
  1401. + /*
  1402. + snd_soc_component_update_bits(priv->component, AC_LINEOUT_CTL,
  1403. + (1<<LINEOUT_EN), (0<<LINEOUT_EN));
  1404. + */
  1405. +#endif
  1406. + snd_soc_unregister_component(&pdev->dev);
  1407. + clk_disable_unprepare(priv->clk);
  1408. + devm_kfree(&pdev->dev, priv);
  1409. + return 0;
  1410. +}
  1411. +
  1412. +static const struct of_device_id acx00_codec_match[] = {
  1413. + { .compatible = "x-powers,ac200-codec" },
  1414. + { }
  1415. +};
  1416. +MODULE_DEVICE_TABLE(of, acx00_codec_match);
  1417. +
  1418. +static struct platform_driver acx00_codec_driver = {
  1419. + .driver = {
  1420. + .name = "acx00-codec",
  1421. + .of_match_table = acx00_codec_match,
  1422. + },
  1423. + .probe = acx00_codec_dev_probe,
  1424. + .remove = acx00_codec_dev_remove,
  1425. + .shutdown = acx00_codec_dev_shutdown,
  1426. +};
  1427. +
  1428. +static int __init acx00_codec_driver_init(void)
  1429. +{
  1430. + return platform_driver_register(&acx00_codec_driver);
  1431. +}
  1432. +
  1433. +static void __exit acx00_codec_driver_exit(void)
  1434. +{
  1435. + platform_driver_unregister(&acx00_codec_driver);
  1436. +}
  1437. +late_initcall(acx00_codec_driver_init);
  1438. +module_exit(acx00_codec_driver_exit);
  1439. +
  1440. +MODULE_LICENSE("GPL");
  1441. +MODULE_DESCRIPTION("SUNXI ASoC ACX00 Codec Driver");
  1442. +MODULE_AUTHOR("wolfgang huang");
  1443. +MODULE_ALIAS("platform:acx00-codec");
  1444. +
  1445. diff --git a/sound/soc/codecs/acx00.h b/sound/soc/codecs/acx00.h
  1446. new file mode 100644
  1447. index 000000000..4d53184fc
  1448. --- /dev/null
  1449. +++ b/sound/soc/codecs/acx00.h
  1450. @@ -0,0 +1,357 @@
  1451. +/*
  1452. + * sound\soc\codecs\acx00.h
  1453. + * (C) Copyright 2012-2016
  1454. + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  1455. + * Wolfgang Huang <huangjinhui@allwinnertech.com>
  1456. + *
  1457. + * some simple description for this code
  1458. + *
  1459. + * This program is free software; you can redistribute it and/or
  1460. + * modify it under the terms of the GNU General Public License as
  1461. + * published by the Free Software Foundation; either version 2 of
  1462. + * the License, or (at your option) any later version.
  1463. + *
  1464. + */
  1465. +
  1466. +#ifndef __ACX00_H_
  1467. +#define __ACX00_H_
  1468. +
  1469. +/* ACX00 register offset list */
  1470. +#define AC_SYS_CLK_CTL 0x2000
  1471. +#define AC_SYS_MOD_RST 0x2002
  1472. +#define AC_SYS_SR_CTL 0x2004
  1473. +/* Left blank */
  1474. +#define AC_I2S_CTL 0x2100
  1475. +#define AC_I2S_CLK 0x2102
  1476. +#define AC_I2S_FMT0 0x2104
  1477. +/* Left blank */
  1478. +#define AC_I2S_FMT1 0x2108
  1479. +/* Left blank */
  1480. +#define AC_I2S_MIXER_SRC 0x2114
  1481. +#define AC_I2S_MIXER_GAIN 0x2116
  1482. +#define AC_I2S_DAC_VOL 0x2118
  1483. +#define AC_I2S_ADC_VOL 0x211A
  1484. +/* Left blank */
  1485. +#define AC_DAC_CTL 0x2200
  1486. +#define AC_DAC_MIXER_SRC 0x2202
  1487. +#define AC_DAC_MIXER_GAIN 0x2204
  1488. +/* Left blank */
  1489. +#define AC_OUT_MIXER_CTL 0x2220
  1490. +#define AC_OUT_MIXER_SRC 0x2222
  1491. +#define AC_LINEOUT_CTL 0x2224
  1492. +/* Left blank */
  1493. +#define AC_ADC_CTL 0x2300
  1494. +/* Left blank */
  1495. +#define AC_MICBIAS_CTL 0x2310
  1496. +/* Left blank */
  1497. +#define AC_ADC_MIC_CTL 0x2320
  1498. +#define AC_ADC_MIXER_SRC 0x2322
  1499. +/* Left blank */
  1500. +#define AC_BIAS_CTL 0x232A
  1501. +#define AC_ANALOG_PROF_CTL 0x232C
  1502. +/* Left blank */
  1503. +#define AC_ADC_DAPL_CTRL 0x2500
  1504. +#define AC_ADC_DAPR_CTRL 0x2502
  1505. +#define AC_ADC_DAPLSTA 0x2504
  1506. +#define AC_ADC_DAPRSTA 0x2506
  1507. +#define AC_ADC_DAP_LTL 0x2508
  1508. +#define AC_ADC_DAP_RTL 0x250A
  1509. +#define AC_ADC_DAP_LHAC 0x250C
  1510. +#define AC_ADC_DAP_LLAC 0x250E
  1511. +#define AC_ADC_DAP_RHAC 0x2510
  1512. +#define AC_ADC_DAP_RLAC 0x2512
  1513. +#define AC_ADC_DAP_LDT 0x2514
  1514. +#define AC_ADC_DAP_LAT 0x2516
  1515. +#define AC_ADC_DAP_RDT 0x2518
  1516. +#define AC_ADC_DAP_RAT 0x251A
  1517. +#define AC_ADC_DAP_NTH 0x251C
  1518. +#define AC_ADC_DAP_LHNAC 0x251E
  1519. +#define AC_ADC_DAP_LLNAC 0x2520
  1520. +#define AC_ADC_DAP_RHNAC 0x2522
  1521. +#define AC_ADC_DAP_RLNAC 0x2524
  1522. +#define AC_ADC_DAP_HHPFC 0x2526
  1523. +#define AC_ADC_DAP_LHPFC 0x2528
  1524. +#define AC_ADC_DAP_OPT 0x252A
  1525. +/* Left blank */
  1526. +#define AC_AGC_SEL 0x2480
  1527. +/* Left blank */
  1528. +#define AC_ADC_DAPL_CTRL 0x2500
  1529. +#define AC_ADC_DAPR_CTRL 0x2502
  1530. +#define AC_ADC_DAPLSTA 0x2504
  1531. +#define AC_ADC_DAPRSTA 0x2506
  1532. +#define AC_ADC_DAP_LTL 0x2508
  1533. +#define AC_ADC_DAP_RTL 0x250A
  1534. +#define AC_ADC_DAP_LHAC 0x250C
  1535. +#define AC_ADC_DAP_LLAC 0x250E
  1536. +#define AC_ADC_DAP_RHAC 0x2510
  1537. +#define AC_ADC_DAP_RLAC 0x2512
  1538. +#define AC_ADC_DAP_LDT 0x2514
  1539. +#define AC_ADC_DAP_LAT 0x2516
  1540. +#define AC_ADC_DAP_RDT 0x2518
  1541. +#define AC_ADC_DAP_RAT 0x251A
  1542. +#define AC_ADC_DAP_NTH 0x251C
  1543. +#define AC_ADC_DAP_LHNAC 0x251E
  1544. +#define AC_ADC_DAP_LLNAC 0x2520
  1545. +#define AC_ADC_DAP_RHNAC 0x2522
  1546. +#define AC_ADC_DAP_RLNAC 0x2524
  1547. +#define AC_ADC_DAP_HHPFC 0x2526
  1548. +#define AC_ADC_DAP_LHPFC 0x2528
  1549. +#define AC_ADC_DAP_OPT 0x252A
  1550. +/* Left blank */
  1551. +#define AC_DRC_SEL 0x2f80
  1552. +/* Left blank */
  1553. +#define AC_DRC_CHAN_CTRL 0x3000
  1554. +#define AC_DRC_HHPFC 0x3002
  1555. +#define AC_DRC_LHPFC 0x3004
  1556. +#define AC_DRC_CTRL 0x3006
  1557. +#define AC_DRC_LPFHAT 0x3008
  1558. +#define AC_DRC_LPFLAT 0x300A
  1559. +#define AC_DRC_RPFHAT 0x300C
  1560. +#define AC_DRC_RPFLAT 0x300E
  1561. +#define AC_DRC_LPFHRT 0x3010
  1562. +#define AC_DRC_LPFLRT 0x3012
  1563. +#define AC_DRC_RPFHRT 0x3014
  1564. +#define AC_DRC_RPFLRT 0x3016
  1565. +#define AC_DRC_LRMSHAT 0x3018
  1566. +#define AC_DRC_LRMSLAT 0x301A
  1567. +#define AC_DRC_RRMSHAT 0x301C
  1568. +#define AC_DRC_RRMSLAT 0x301E
  1569. +#define AC_DRC_HCT 0x3020
  1570. +#define AC_DRC_LCT 0x3022
  1571. +#define AC_DRC_HKC 0x3024
  1572. +#define AC_DRC_LKC 0x3026
  1573. +#define AC_DRC_HOPC 0x3028
  1574. +#define AC_DRC_LOPC 0x302A
  1575. +#define AC_DRC_HLT 0x302C
  1576. +#define AC_DRC_LLT 0x302E
  1577. +#define AC_DRC_HKI 0x3030
  1578. +#define AC_DRC_LKI 0x3032
  1579. +#define AC_DRC_HOPL 0x3034
  1580. +#define AC_DRC_LOPL 0x3036
  1581. +#define AC_DRC_HET 0x3038
  1582. +#define AC_DRC_LET 0x303A
  1583. +#define AC_DRC_HKE 0x303C
  1584. +#define AC_DRC_LKE 0x303E
  1585. +#define AC_DRC_HOPE 0x3040
  1586. +#define AC_DRC_LOPE 0x3042
  1587. +#define AC_DRC_HKN 0x3044
  1588. +#define AC_DRC_LKN 0x3046
  1589. +#define AC_DRC_SFHAT 0x3048
  1590. +#define AC_DRC_SFLAT 0x304A
  1591. +#define AC_DRC_SFHRT 0x304C
  1592. +#define AC_DRC_SFLRT 0x304E
  1593. +#define AC_DRC_MXGHS 0x3050
  1594. +#define AC_DRC_MXGLS 0x3052
  1595. +#define AC_DRC_MNGHS 0x3054
  1596. +#define AC_DRC_MNGLS 0x3056
  1597. +#define AC_DRC_EPSHC 0x3058
  1598. +#define AC_DRC_EPSLC 0x305A
  1599. +#define AC_DRC_OPT 0x305C
  1600. +#define AC_DRC_HPFHGAIN 0x305E
  1601. +#define AC_DRC_HPFLGAIN 0x3060
  1602. +#define AC_DRC_BISTCR 0x3100
  1603. +#define AC_DRC_BISTST 0x3102
  1604. +
  1605. +/* AC_SYS_CLK_CTL : 0x2000 */
  1606. +#define SYS_CLK_I2S 15
  1607. +#define SYS_CLK_AGC 7
  1608. +#define SYS_CLK_DRC 6
  1609. +#define SYS_CLK_ADC 3
  1610. +#define SYS_CLK_DAC 2
  1611. +
  1612. +/* AC_SYS_MOD_RST : 0x2002 */
  1613. +#define MOD_RST_I2S 15
  1614. +#define MOD_RST_AGC 7
  1615. +#define MOD_RST_DRC 6
  1616. +#define MOD_RST_ADC 3
  1617. +#define MOD_RST_DAC 2
  1618. +
  1619. +/* AC_SYS_SR_CTL : 0x2004 */
  1620. +#define SYS_SR_BIT 0
  1621. +#define SYS_SR_MASK 0xF
  1622. +#define SYS_SR_BIT_0 0 /* 8000 */
  1623. +#define SYS_SR_BIT_1 1 /* 11025 */
  1624. +#define SYS_SR_BIT_2 2 /* 12000 */
  1625. +#define SYS_SR_BIT_3 3 /* 16000 */
  1626. +#define SYS_SR_BIT_4 4 /* 22050 */
  1627. +#define SYS_SR_BIT_5 5 /* 24000 */
  1628. +#define SYS_SR_BIT_6 6 /* 32000 */
  1629. +#define SYS_SR_BIT_7 7 /* 44100 */
  1630. +#define SYS_SR_BIT_8 8 /* 48000 */
  1631. +#define SYS_SR_BIT_9 9 /* 96000 */
  1632. +#define SYS_SR_BIT_10 10 /* 192000 */
  1633. +
  1634. +/* AC_I2S_CTL : 0x2100 */
  1635. +#define I2S_SDO0_EN 3
  1636. +#define I2S_TX_EN 2
  1637. +#define I2S_RX_EN 1
  1638. +#define I2S_GEN 0
  1639. +
  1640. +/* AC_I2S_CLK : 0x2102 */
  1641. +#define I2S_BCLK_OUT 15
  1642. +#define I2S_LRCK_OUT 14
  1643. +#define I2S_BLCK_DIV 10
  1644. +#define I2S_LRCK_PERIOD 0
  1645. +/* BCLK DIV Define */
  1646. +#define I2S_BCLK_DIV_MASK 0xF
  1647. +#define I2S_BCLK_DIV_1 1
  1648. +#define I2S_BCLK_DIV_2 2
  1649. +#define I2S_BCLK_DIV_3 3
  1650. +#define I2S_BCLK_DIV_4 4
  1651. +#define I2S_BCLK_DIV_5 5
  1652. +#define I2S_BCLK_DIV_6 6
  1653. +#define I2S_BCLK_DIV_7 7
  1654. +#define I2S_BCLK_DIV_8 8
  1655. +#define I2S_BCLK_DIV_9 9
  1656. +#define I2S_BCLK_DIV_10 10
  1657. +#define I2S_BCLK_DIV_11 11
  1658. +#define I2S_BCLK_DIV_12 12
  1659. +#define I2S_BCLK_DIV_13 13
  1660. +#define I2S_BCLK_DIV_14 14
  1661. +#define I2S_BCLK_DIV_15 15
  1662. +#define I2S_LRCK_PERIOD_MASK 0x3FF
  1663. +
  1664. +/* AC_I2S_FMT0 : 0x2104 */
  1665. +#define I2S_FMT_MODE 14
  1666. +#define I2S_FMT_TX_OFFSET 10
  1667. +#define I2S_FMT_RX_OFFSET 8
  1668. +#define I2S_FMT_SAMPLE 4
  1669. +#define I2S_FMT_SLOT_WIDTH 1
  1670. +#define I2S_FMT_LOOP 0
  1671. +
  1672. +/* AC_I2S_FMT1 : 0x2108 */
  1673. +#define I2S_FMT_BCLK_POLAR 15
  1674. +#define I2S_FMT_LRCK_POLAR 14
  1675. +#define I2S_FMT_EDGE_TRANSFER 13
  1676. +#define I2S_FMT_RX_MLS 11
  1677. +#define I2S_FMT_TX_MLS 10
  1678. +#define I2S_FMT_EXTEND 9
  1679. +#define I2S_FMT_LRCK_WIDTH 4 /* PCM long/short Frame */
  1680. +#define I2S_MFT_RX_PDM 2
  1681. +#define I2S_FMT_TX_PDM 0
  1682. +
  1683. +/* AC_I2S_MIXER_SRC : 0x2114 */
  1684. +#define I2S_MIXERL_SRC_DAC 13
  1685. +#define I2S_MIXERL_SRC_ADC 12
  1686. +#define I2S_MIXERR_SRC_DAC 9
  1687. +#define I2S_MIXERR_SRC_ADC 8
  1688. +
  1689. +/* AC_I2S_MIXER_GAIN : 0x2116 */
  1690. +#define I2S_MIXERL_GAIN_DAC 13
  1691. +#define I2S_MIXERL_GAIN_ADC 12
  1692. +#define I2S_MIXERR_GAIN_DAC 9
  1693. +#define I2S_MIXERR_GAIN_ADC 8
  1694. +
  1695. +
  1696. +/* AC_I2S_DAC_VOL : 0x2118 */
  1697. +#define I2S_DACL_VOL 8
  1698. +#define I2S_DACR_VOL 0
  1699. +
  1700. +/* AC_I2S_ADC_VOL : 0x211A */
  1701. +#define I2S_ADCL_VOL 8
  1702. +#define I2S_ADCR_VOL 0
  1703. +
  1704. +/* AC_DAC_CTL : 0x2200 */
  1705. +#define DAC_CTL_DAC_EN 15
  1706. +#define DAC_CTL_HPF_EN 14
  1707. +#define DAC_CTL_FIR 13
  1708. +#define DAC_CTL_MODQU 8
  1709. +
  1710. +/* AC_DAC_MIXER_SRC : 0x2202 */
  1711. +#define DAC_MIXERL_SRC_DAC 13
  1712. +#define DAC_MIXERL_SRC_ADC 12
  1713. +#define DAC_MIXERR_SRC_DAC 9
  1714. +#define DAC_MIXERR_SRC_ADC 8
  1715. +
  1716. +/* AC_DAC_MIXER_GAIN : 0x2204 */
  1717. +#define DAC_MIXERL_GAIN_DAC 13
  1718. +#define DAC_MIXERL_GAIN_ADC 12
  1719. +#define DAC_MIXERR_GAIN_DAC 9
  1720. +#define DAC_MIXERR_GAIN_ADC 8
  1721. +
  1722. +/* AC_OUT_MIXER_CTL : 0x2220 */
  1723. +#define OUT_MIXER_DACR_EN 15
  1724. +#define OUT_MIXER_DACL_EN 14
  1725. +#define OUT_MIXER_RMIX_EN 13
  1726. +#define OUT_MIXER_LMIX_EN 12
  1727. +#define OUT_MIXER_LINE_VOL 8
  1728. +#define OUT_MIXER_MIC1_VOL 4
  1729. +#define OUT_MIXER_MIC2_VOL 0
  1730. +
  1731. +/* AC_OUT_MIXER_SRC : 0x2222 */
  1732. +#define OUT_MIXERR_SRC_MIC1 14
  1733. +#define OUT_MIXERR_SRC_MIC2 13
  1734. +#define OUT_MIXERR_SRC_PHPN 12
  1735. +#define OUT_MIXERR_SRC_PHP 11
  1736. +#define OUT_MIXERR_SRC_LINER 10
  1737. +#define OUT_MIXERR_SRC_DACR 9
  1738. +#define OUT_MIXERR_SRC_DACL 8
  1739. +#define OUT_MIXERL_SRC_MIC1 6
  1740. +#define OUT_MIXERL_SRC_MIC2 5
  1741. +#define OUT_MIXERL_SRC_PHPN 4
  1742. +#define OUT_MIXERL_SRC_PHN 3
  1743. +#define OUT_MIXERL_SRC_LINEL 2
  1744. +#define OUT_MIXERL_SRC_DACL 1
  1745. +#define OUT_MIXERL_SRC_DACR 0
  1746. +
  1747. +/* AC_LINEOUT_CTL : 0x2224 */
  1748. +#define LINEOUT_EN 15
  1749. +#define LINEL_SRC_EN 14
  1750. +#define LINER_SRC_EN 13
  1751. +#define LINEL_SRC 12
  1752. +#define LINER_SRC 11
  1753. +/* ramp just skip */
  1754. +#define LINE_SLOPE_SEL 8
  1755. +#define LINE_ANTI_TIME 5
  1756. +#define LINEOUT_VOL 0
  1757. +
  1758. +/* AC_ADC_CTL : 0x2300 */
  1759. +#define ADC_EN 15
  1760. +#define ADC_ENDM 14
  1761. +#define ADC_FIR 13
  1762. +#define ADC_DELAY_TIME 2
  1763. +#define ADC_DELAY_EN 1
  1764. +
  1765. +/* AC_MICBIAS_CTL : 0x2310 */
  1766. +#define MMBIAS_EN 15
  1767. +#define MMBIAS_CHOPPER 14
  1768. +#define MMBIAS_CHOP_CLK 12
  1769. +#define MMBIAS_SEL 8
  1770. +#define ADDA_BIAS_CUR 3
  1771. +
  1772. +/* AC_ADC_MIC_CTL : 0x2320 */
  1773. +#define ADCR_EN 15
  1774. +#define ADCL_EN 14
  1775. +#define ADC_GAIN 8
  1776. +#define MIC1_GAIN_EN 7
  1777. +#define MIC1_BOOST 4
  1778. +#define MIC2_GAIN_EN 3
  1779. +#define MIC2_BOOST 0
  1780. +
  1781. +/* AC_ADC_MIXER_SRC : 0x2322 */
  1782. +#define ADC_MIXERR_MIC1 14
  1783. +#define ADC_MIXERR_MIC2 13
  1784. +#define ADC_MIXERR_PHPN 12
  1785. +#define ADC_MIXERR_PHP 11
  1786. +#define ADC_MIXERR_LINER 10
  1787. +#define ADC_MIXERR_MIXR 9
  1788. +#define ADC_MIXERR_MIXL 8
  1789. +#define ADC_MIXERL_MIC1 6
  1790. +#define ADC_MIXERL_MIC2 5
  1791. +#define ADC_MIXERL_PHPN 4
  1792. +#define ADC_MIXERL_PHN 3
  1793. +#define ADC_MIXERL_LINEL 2
  1794. +#define ADC_MIXERL_MIXL 1
  1795. +#define ADC_MIXERL_MIXR 0
  1796. +
  1797. +/* AC_BIAS_CTL : 0x232A */
  1798. +
  1799. +/* AC_ANALOG_PROF_CTL : 0x232C */
  1800. +/* used for current performance measure */
  1801. +
  1802. +/* AC_DLDO_OSC_CTL : 0x2340 */
  1803. +/* AC_ALDO_CTL : 0x2342 */
  1804. +/* used for digital & analog LDO test... etc */
  1805. +
  1806. +#endif
  1807. +
  1808. diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
  1809. index 9f8e868b9..f2ef01aae 100644
  1810. --- a/sound/soc/sunxi/sun4i-i2s.c
  1811. +++ b/sound/soc/sunxi/sun4i-i2s.c
  1812. @@ -724,7 +724,8 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
  1813. val = 0;
  1814. break;
  1815. case SND_SOC_DAIFMT_NB_NF:
  1816. - val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
  1817. + //val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
  1818. + val = SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
  1819. break;
  1820. default:
  1821. return -EINVAL;
  1822. @@ -796,9 +797,9 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
  1823. val);
  1824. /* Set sign extension to pad out LSB with 0 */
  1825. - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
  1826. + /* regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
  1827. SUN8I_I2S_FMT1_REG_SEXT_MASK,
  1828. - SUN8I_I2S_FMT1_REG_SEXT(0));
  1829. + SUN8I_I2S_FMT1_REG_SEXT(0)); */
  1830. return 0;
  1831. }
  1832. @@ -831,7 +832,8 @@ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
  1833. val = 0;
  1834. break;
  1835. case SND_SOC_DAIFMT_NB_NF:
  1836. - val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
  1837. + //val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
  1838. + val = SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
  1839. break;
  1840. default:
  1841. return -EINVAL;
  1842. @@ -903,9 +905,9 @@ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
  1843. val);
  1844. /* Set sign extension to pad out LSB with 0 */
  1845. - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
  1846. + /* regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
  1847. SUN8I_I2S_FMT1_REG_SEXT_MASK,
  1848. - SUN8I_I2S_FMT1_REG_SEXT(0));
  1849. + SUN8I_I2S_FMT1_REG_SEXT(0)); */
  1850. return 0;
  1851. }
  1852. @@ -1238,6 +1240,7 @@ static const struct regmap_config sun8i_i2s_regmap_config = {
  1853. };
  1854. static const struct regmap_config sun50i_h6_i2s_regmap_config = {
  1855. + .name = "h6_i2s",
  1856. .reg_bits = 32,
  1857. .reg_stride = 4,
  1858. .val_bits = 32,