jz4770.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Ingenic JZ4770 CODEC driver
  4. //
  5. // Copyright (C) 2012, Maarten ter Huurne <maarten@treewalker.org>
  6. // Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
  7. #include <linux/clk.h>
  8. #include <linux/delay.h>
  9. #include <linux/iopoll.h>
  10. #include <linux/module.h>
  11. #include <linux/regmap.h>
  12. #include <linux/time64.h>
  13. #include <sound/pcm_params.h>
  14. #include <sound/soc.h>
  15. #include <sound/soc-dai.h>
  16. #include <sound/soc-dapm.h>
  17. #include <sound/tlv.h>
  18. #define ICDC_RGADW_OFFSET 0x00
  19. #define ICDC_RGDATA_OFFSET 0x04
  20. /* ICDC internal register access control register(RGADW) */
  21. #define ICDC_RGADW_RGWR BIT(16)
  22. #define ICDC_RGADW_RGADDR_OFFSET 8
  23. #define ICDC_RGADW_RGADDR_MASK GENMASK(14, ICDC_RGADW_RGADDR_OFFSET)
  24. #define ICDC_RGADW_RGDIN_OFFSET 0
  25. #define ICDC_RGADW_RGDIN_MASK GENMASK(7, ICDC_RGADW_RGDIN_OFFSET)
  26. /* ICDC internal register data output register (RGDATA)*/
  27. #define ICDC_RGDATA_IRQ BIT(8)
  28. #define ICDC_RGDATA_RGDOUT_OFFSET 0
  29. #define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, ICDC_RGDATA_RGDOUT_OFFSET)
  30. /* Internal register space, accessed through regmap */
  31. enum {
  32. JZ4770_CODEC_REG_SR,
  33. JZ4770_CODEC_REG_AICR_DAC,
  34. JZ4770_CODEC_REG_AICR_ADC,
  35. JZ4770_CODEC_REG_CR_LO,
  36. JZ4770_CODEC_REG_CR_HP,
  37. JZ4770_CODEC_REG_MISSING_REG1,
  38. JZ4770_CODEC_REG_CR_DAC,
  39. JZ4770_CODEC_REG_CR_MIC,
  40. JZ4770_CODEC_REG_CR_LI,
  41. JZ4770_CODEC_REG_CR_ADC,
  42. JZ4770_CODEC_REG_CR_MIX,
  43. JZ4770_CODEC_REG_CR_VIC,
  44. JZ4770_CODEC_REG_CCR,
  45. JZ4770_CODEC_REG_FCR_DAC,
  46. JZ4770_CODEC_REG_FCR_ADC,
  47. JZ4770_CODEC_REG_ICR,
  48. JZ4770_CODEC_REG_IMR,
  49. JZ4770_CODEC_REG_IFR,
  50. JZ4770_CODEC_REG_GCR_HPL,
  51. JZ4770_CODEC_REG_GCR_HPR,
  52. JZ4770_CODEC_REG_GCR_LIBYL,
  53. JZ4770_CODEC_REG_GCR_LIBYR,
  54. JZ4770_CODEC_REG_GCR_DACL,
  55. JZ4770_CODEC_REG_GCR_DACR,
  56. JZ4770_CODEC_REG_GCR_MIC1,
  57. JZ4770_CODEC_REG_GCR_MIC2,
  58. JZ4770_CODEC_REG_GCR_ADCL,
  59. JZ4770_CODEC_REG_GCR_ADCR,
  60. JZ4770_CODEC_REG_MISSING_REG2,
  61. JZ4770_CODEC_REG_GCR_MIXADC,
  62. JZ4770_CODEC_REG_GCR_MIXDAC,
  63. JZ4770_CODEC_REG_AGC1,
  64. JZ4770_CODEC_REG_AGC2,
  65. JZ4770_CODEC_REG_AGC3,
  66. JZ4770_CODEC_REG_AGC4,
  67. JZ4770_CODEC_REG_AGC5,
  68. };
  69. #define REG_AICR_DAC_ADWL_OFFSET 6
  70. #define REG_AICR_DAC_ADWL_MASK (0x3 << REG_AICR_DAC_ADWL_OFFSET)
  71. #define REG_AICR_DAC_SERIAL BIT(1)
  72. #define REG_AICR_DAC_I2S BIT(0)
  73. #define REG_AICR_ADC_ADWL_OFFSET 6
  74. #define REG_AICR_ADC_ADWL_MASK (0x3 << REG_AICR_ADC_ADWL_OFFSET)
  75. #define REG_AICR_ADC_SERIAL BIT(1)
  76. #define REG_AICR_ADC_I2S BIT(0)
  77. #define REG_CR_LO_MUTE_OFFSET 7
  78. #define REG_CR_LO_SB_OFFSET 4
  79. #define REG_CR_LO_SEL_OFFSET 0
  80. #define REG_CR_LO_SEL_MASK (0x3 << REG_CR_LO_SEL_OFFSET)
  81. #define REG_CR_HP_MUTE BIT(7)
  82. #define REG_CR_HP_LOAD BIT(6)
  83. #define REG_CR_HP_SB_OFFSET 4
  84. #define REG_CR_HP_SB_HPCM BIT(3)
  85. #define REG_CR_HP_SEL_OFFSET 0
  86. #define REG_CR_HP_SEL_MASK (0x3 << REG_CR_HP_SEL_OFFSET)
  87. #define REG_CR_DAC_MUTE BIT(7)
  88. #define REG_CR_DAC_MONO BIT(6)
  89. #define REG_CR_DAC_LEFT_ONLY BIT(5)
  90. #define REG_CR_DAC_SB_OFFSET 4
  91. #define REG_CR_DAC_LRSWAP BIT(3)
  92. #define REG_CR_MIC_STEREO_OFFSET 7
  93. #define REG_CR_MIC_IDIFF_OFFSET 6
  94. #define REG_CR_MIC_SB_MIC2_OFFSET 5
  95. #define REG_CR_MIC_SB_MIC1_OFFSET 4
  96. #define REG_CR_MIC_BIAS_V0_OFFSET 1
  97. #define REG_CR_MIC_BIAS_SB_OFFSET 0
  98. #define REG_CR_LI_LIBY_OFFSET 4
  99. #define REG_CR_LI_SB_OFFSET 0
  100. #define REG_CR_ADC_DMIC_SEL BIT(7)
  101. #define REG_CR_ADC_MONO BIT(6)
  102. #define REG_CR_ADC_LEFT_ONLY BIT(5)
  103. #define REG_CR_ADC_SB_OFFSET 4
  104. #define REG_CR_ADC_LRSWAP BIT(3)
  105. #define REG_CR_ADC_IN_SEL_OFFSET 0
  106. #define REG_CR_ADC_IN_SEL_MASK (0x3 << REG_CR_ADC_IN_SEL_OFFSET)
  107. #define REG_CR_VIC_SB_SLEEP BIT(1)
  108. #define REG_CR_VIC_SB BIT(0)
  109. #define REG_CCR_CRYSTAL_OFFSET 0
  110. #define REG_CCR_CRYSTAL_MASK (0xf << REG_CCR_CRYSTAL_OFFSET)
  111. #define REG_FCR_DAC_FREQ_OFFSET 0
  112. #define REG_FCR_DAC_FREQ_MASK (0xf << REG_FCR_DAC_FREQ_OFFSET)
  113. #define REG_FCR_ADC_FREQ_OFFSET 0
  114. #define REG_FCR_ADC_FREQ_MASK (0xf << REG_FCR_ADC_FREQ_OFFSET)
  115. #define REG_ICR_INT_FORM_OFFSET 6
  116. #define REG_ICR_INT_FORM_MASK (0x3 << REG_ICR_INT_FORM_OFFSET)
  117. #define REG_IMR_ALL_MASK (0x7f)
  118. #define REG_IMR_SCLR_MASK BIT(6)
  119. #define REG_IMR_JACK_MASK BIT(5)
  120. #define REG_IMR_SCMC_MASK BIT(4)
  121. #define REG_IMR_RUP_MASK BIT(3)
  122. #define REG_IMR_RDO_MASK BIT(2)
  123. #define REG_IMR_GUP_MASK BIT(1)
  124. #define REG_IMR_GDO_MASK BIT(0)
  125. #define REG_IFR_ALL_MASK (0x7f)
  126. #define REG_IFR_SCLR BIT(6)
  127. #define REG_IFR_JACK BIT(5)
  128. #define REG_IFR_SCMC BIT(4)
  129. #define REG_IFR_RUP BIT(3)
  130. #define REG_IFR_RDO BIT(2)
  131. #define REG_IFR_GUP BIT(1)
  132. #define REG_IFR_GDO BIT(0)
  133. #define REG_GCR_HPL_LRGO BIT(7)
  134. #define REG_GCR_DACL_RLGOD BIT(7)
  135. #define REG_GCR_GAIN_OFFSET 0
  136. #define REG_GCR_GAIN_MAX 0x1f
  137. #define REG_GCR_MIC_GAIN_OFFSET 0
  138. #define REG_GCR_MIC_GAIN_MAX 5
  139. #define REG_GCR_ADC_GAIN_OFFSET 0
  140. #define REG_GCR_ADC_GAIN_MAX 23
  141. #define REG_AGC1_EN BIT(7)
  142. /* codec private data */
  143. struct jz_codec {
  144. struct device *dev;
  145. struct regmap *regmap;
  146. void __iomem *base;
  147. struct clk *clk;
  148. };
  149. static int jz4770_codec_set_bias_level(struct snd_soc_component *codec,
  150. enum snd_soc_bias_level level)
  151. {
  152. struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
  153. struct regmap *regmap = jz_codec->regmap;
  154. switch (level) {
  155. case SND_SOC_BIAS_PREPARE:
  156. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
  157. REG_CR_VIC_SB, 0);
  158. msleep(250);
  159. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
  160. REG_CR_VIC_SB_SLEEP, 0);
  161. msleep(400);
  162. break;
  163. case SND_SOC_BIAS_STANDBY:
  164. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
  165. REG_CR_VIC_SB_SLEEP, REG_CR_VIC_SB_SLEEP);
  166. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
  167. REG_CR_VIC_SB, REG_CR_VIC_SB);
  168. fallthrough;
  169. default:
  170. break;
  171. }
  172. return 0;
  173. }
  174. static int jz4770_codec_startup(struct snd_pcm_substream *substream,
  175. struct snd_soc_dai *dai)
  176. {
  177. struct snd_soc_component *codec = dai->component;
  178. struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
  179. /*
  180. * SYSCLK output from the codec to the AIC is required to keep the
  181. * DMA transfer going during playback when all audible outputs have
  182. * been disabled.
  183. */
  184. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  185. snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
  186. return 0;
  187. }
  188. static void jz4770_codec_shutdown(struct snd_pcm_substream *substream,
  189. struct snd_soc_dai *dai)
  190. {
  191. struct snd_soc_component *codec = dai->component;
  192. struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
  193. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  194. snd_soc_dapm_disable_pin(dapm, "SYSCLK");
  195. }
  196. static int jz4770_codec_pcm_trigger(struct snd_pcm_substream *substream,
  197. int cmd, struct snd_soc_dai *dai)
  198. {
  199. struct snd_soc_component *codec = dai->component;
  200. int ret = 0;
  201. switch (cmd) {
  202. case SNDRV_PCM_TRIGGER_START:
  203. case SNDRV_PCM_TRIGGER_RESUME:
  204. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  205. if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
  206. snd_soc_component_force_bias_level(codec,
  207. SND_SOC_BIAS_ON);
  208. break;
  209. case SNDRV_PCM_TRIGGER_STOP:
  210. case SNDRV_PCM_TRIGGER_SUSPEND:
  211. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  212. /* do nothing */
  213. break;
  214. default:
  215. ret = -EINVAL;
  216. }
  217. return ret;
  218. }
  219. static int jz4770_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
  220. {
  221. struct snd_soc_component *codec = dai->component;
  222. struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
  223. unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
  224. unsigned int val;
  225. int change, err;
  226. change = snd_soc_component_update_bits(codec, JZ4770_CODEC_REG_CR_DAC,
  227. REG_CR_DAC_MUTE,
  228. mute ? REG_CR_DAC_MUTE : 0);
  229. if (change == 1) {
  230. regmap_read(jz_codec->regmap, JZ4770_CODEC_REG_CR_DAC, &val);
  231. if (val & BIT(REG_CR_DAC_SB_OFFSET))
  232. return 1;
  233. err = regmap_read_poll_timeout(jz_codec->regmap,
  234. JZ4770_CODEC_REG_IFR,
  235. val, val & gain_bit,
  236. 1000, 100 * USEC_PER_MSEC);
  237. if (err) {
  238. dev_err(jz_codec->dev,
  239. "Timeout while setting digital mute: %d", err);
  240. return err;
  241. }
  242. /* clear GUP/GDO flag */
  243. regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
  244. gain_bit, gain_bit);
  245. }
  246. return 0;
  247. }
  248. /* unit: 0.01dB */
  249. static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 0);
  250. static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
  251. static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 600);
  252. static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
  253. /* Unconditional controls. */
  254. static const struct snd_kcontrol_new jz4770_codec_snd_controls[] = {
  255. /* record gain control */
  256. SOC_DOUBLE_R_TLV("PCM Capture Volume",
  257. JZ4770_CODEC_REG_GCR_ADCL, JZ4770_CODEC_REG_GCR_ADCR,
  258. REG_GCR_ADC_GAIN_OFFSET, REG_GCR_ADC_GAIN_MAX,
  259. 0, adc_tlv),
  260. SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
  261. JZ4770_CODEC_REG_GCR_LIBYL, JZ4770_CODEC_REG_GCR_LIBYR,
  262. REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
  263. };
  264. static const struct snd_kcontrol_new jz4770_codec_pcm_playback_controls[] = {
  265. {
  266. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  267. .name = "Volume",
  268. .info = snd_soc_info_volsw,
  269. .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
  270. | SNDRV_CTL_ELEM_ACCESS_READWRITE,
  271. .tlv.p = dac_tlv,
  272. .get = snd_soc_dapm_get_volsw,
  273. .put = snd_soc_dapm_put_volsw,
  274. /*
  275. * NOTE: DACR/DACL are inversed; the gain value written to DACR
  276. * seems to affect the left channel, and the gain value written
  277. * to DACL seems to affect the right channel.
  278. */
  279. .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_DACR,
  280. JZ4770_CODEC_REG_GCR_DACL,
  281. REG_GCR_GAIN_OFFSET,
  282. REG_GCR_GAIN_MAX, 1),
  283. },
  284. };
  285. static const struct snd_kcontrol_new jz4770_codec_hp_playback_controls[] = {
  286. {
  287. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  288. .name = "Volume",
  289. .info = snd_soc_info_volsw,
  290. .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
  291. | SNDRV_CTL_ELEM_ACCESS_READWRITE,
  292. .tlv.p = out_tlv,
  293. .get = snd_soc_dapm_get_volsw,
  294. .put = snd_soc_dapm_put_volsw,
  295. /* HPR/HPL inversed for the same reason as above */
  296. .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_HPR,
  297. JZ4770_CODEC_REG_GCR_HPL,
  298. REG_GCR_GAIN_OFFSET,
  299. REG_GCR_GAIN_MAX, 1),
  300. },
  301. };
  302. static int hpout_event(struct snd_soc_dapm_widget *w,
  303. struct snd_kcontrol *kcontrol, int event)
  304. {
  305. struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
  306. struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
  307. unsigned int val;
  308. int err;
  309. switch (event) {
  310. case SND_SOC_DAPM_PRE_PMU:
  311. /* set cap-less, unmute HP */
  312. regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
  313. REG_CR_HP_SB_HPCM | REG_CR_HP_MUTE, 0);
  314. break;
  315. case SND_SOC_DAPM_POST_PMU:
  316. /* wait for ramp-up complete (RUP) */
  317. err = regmap_read_poll_timeout(jz_codec->regmap,
  318. JZ4770_CODEC_REG_IFR,
  319. val, val & REG_IFR_RUP,
  320. 1000, 100 * USEC_PER_MSEC);
  321. if (err) {
  322. dev_err(jz_codec->dev, "RUP timeout: %d", err);
  323. return err;
  324. }
  325. /* clear RUP flag */
  326. regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
  327. REG_IFR_RUP, REG_IFR_RUP);
  328. break;
  329. case SND_SOC_DAPM_POST_PMD:
  330. /* set cap-couple, mute HP */
  331. regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
  332. REG_CR_HP_SB_HPCM | REG_CR_HP_MUTE,
  333. REG_CR_HP_SB_HPCM | REG_CR_HP_MUTE);
  334. err = regmap_read_poll_timeout(jz_codec->regmap,
  335. JZ4770_CODEC_REG_IFR,
  336. val, val & REG_IFR_RDO,
  337. 1000, 100 * USEC_PER_MSEC);
  338. if (err) {
  339. dev_err(jz_codec->dev, "RDO timeout: %d", err);
  340. return err;
  341. }
  342. /* clear RDO flag */
  343. regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
  344. REG_IFR_RDO, REG_IFR_RDO);
  345. break;
  346. }
  347. return 0;
  348. }
  349. static int adc_poweron_event(struct snd_soc_dapm_widget *w,
  350. struct snd_kcontrol *kcontrol, int event)
  351. {
  352. if (event == SND_SOC_DAPM_POST_PMU)
  353. msleep(1000);
  354. return 0;
  355. }
  356. static const char * const jz4770_codec_hp_texts[] = {
  357. "PCM", "Line In", "Mic 1", "Mic 2"
  358. };
  359. static const unsigned int jz4770_codec_hp_values[] = { 3, 2, 0, 1 };
  360. static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_hp_enum,
  361. JZ4770_CODEC_REG_CR_HP,
  362. REG_CR_HP_SEL_OFFSET,
  363. REG_CR_HP_SEL_MASK,
  364. jz4770_codec_hp_texts,
  365. jz4770_codec_hp_values);
  366. static const struct snd_kcontrol_new jz4770_codec_hp_source =
  367. SOC_DAPM_ENUM("Route", jz4770_codec_hp_enum);
  368. static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_lo_enum,
  369. JZ4770_CODEC_REG_CR_LO,
  370. REG_CR_LO_SEL_OFFSET,
  371. REG_CR_LO_SEL_MASK,
  372. jz4770_codec_hp_texts,
  373. jz4770_codec_hp_values);
  374. static const struct snd_kcontrol_new jz4770_codec_lo_source =
  375. SOC_DAPM_ENUM("Route", jz4770_codec_lo_enum);
  376. static const char * const jz4770_codec_cap_texts[] = {
  377. "Line In", "Mic 1", "Mic 2"
  378. };
  379. static const unsigned int jz4770_codec_cap_values[] = { 2, 0, 1 };
  380. static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_cap_enum,
  381. JZ4770_CODEC_REG_CR_ADC,
  382. REG_CR_ADC_IN_SEL_OFFSET,
  383. REG_CR_ADC_IN_SEL_MASK,
  384. jz4770_codec_cap_texts,
  385. jz4770_codec_cap_values);
  386. static const struct snd_kcontrol_new jz4770_codec_cap_source =
  387. SOC_DAPM_ENUM("Route", jz4770_codec_cap_enum);
  388. static const struct snd_kcontrol_new jz4770_codec_mic_controls[] = {
  389. SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4770_CODEC_REG_CR_MIC,
  390. REG_CR_MIC_STEREO_OFFSET, 1, 0),
  391. };
  392. static const struct snd_soc_dapm_widget jz4770_codec_dapm_widgets[] = {
  393. SND_SOC_DAPM_PGA_E("HP Out", JZ4770_CODEC_REG_CR_HP,
  394. REG_CR_HP_SB_OFFSET, 1, NULL, 0, hpout_event,
  395. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  396. SND_SOC_DAPM_POST_PMD),
  397. SND_SOC_DAPM_PGA("Line Out", JZ4770_CODEC_REG_CR_LO,
  398. REG_CR_LO_SB_OFFSET, 1, NULL, 0),
  399. SND_SOC_DAPM_PGA("Line Out Switch 2", JZ4770_CODEC_REG_CR_LO,
  400. REG_CR_LO_MUTE_OFFSET, 1, NULL, 0),
  401. SND_SOC_DAPM_PGA("Line In", JZ4770_CODEC_REG_CR_LI,
  402. REG_CR_LI_SB_OFFSET, 1, NULL, 0),
  403. SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
  404. &jz4770_codec_hp_source),
  405. SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
  406. &jz4770_codec_cap_source),
  407. SND_SOC_DAPM_MUX("Line Out Source", SND_SOC_NOPM, 0, 0,
  408. &jz4770_codec_lo_source),
  409. SND_SOC_DAPM_PGA("Mic 1", JZ4770_CODEC_REG_CR_MIC,
  410. REG_CR_MIC_SB_MIC1_OFFSET, 1, NULL, 0),
  411. SND_SOC_DAPM_PGA("Mic 2", JZ4770_CODEC_REG_CR_MIC,
  412. REG_CR_MIC_SB_MIC2_OFFSET, 1, NULL, 0),
  413. SND_SOC_DAPM_PGA("Mic Diff", JZ4770_CODEC_REG_CR_MIC,
  414. REG_CR_MIC_IDIFF_OFFSET, 0, NULL, 0),
  415. SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
  416. jz4770_codec_mic_controls,
  417. ARRAY_SIZE(jz4770_codec_mic_controls)),
  418. SND_SOC_DAPM_PGA("Line In Bypass", JZ4770_CODEC_REG_CR_LI,
  419. REG_CR_LI_LIBY_OFFSET, 1, NULL, 0),
  420. SND_SOC_DAPM_ADC_E("ADC", "HiFi Capture", JZ4770_CODEC_REG_CR_ADC,
  421. REG_CR_ADC_SB_OFFSET, 1, adc_poweron_event,
  422. SND_SOC_DAPM_POST_PMU),
  423. SND_SOC_DAPM_DAC("DAC", "HiFi Playback", JZ4770_CODEC_REG_CR_DAC,
  424. REG_CR_DAC_SB_OFFSET, 1),
  425. SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
  426. jz4770_codec_pcm_playback_controls,
  427. ARRAY_SIZE(jz4770_codec_pcm_playback_controls)),
  428. SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
  429. jz4770_codec_hp_playback_controls,
  430. ARRAY_SIZE(jz4770_codec_hp_playback_controls)),
  431. SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4770_CODEC_REG_CR_MIC,
  432. REG_CR_MIC_BIAS_SB_OFFSET, 1, NULL, 0),
  433. SND_SOC_DAPM_INPUT("MIC1P"),
  434. SND_SOC_DAPM_INPUT("MIC1N"),
  435. SND_SOC_DAPM_INPUT("MIC2P"),
  436. SND_SOC_DAPM_INPUT("MIC2N"),
  437. SND_SOC_DAPM_OUTPUT("LOUT"),
  438. SND_SOC_DAPM_OUTPUT("ROUT"),
  439. SND_SOC_DAPM_OUTPUT("LHPOUT"),
  440. SND_SOC_DAPM_OUTPUT("RHPOUT"),
  441. SND_SOC_DAPM_INPUT("LLINEIN"),
  442. SND_SOC_DAPM_INPUT("RLINEIN"),
  443. SND_SOC_DAPM_OUTPUT("SYSCLK"),
  444. };
  445. /* Unconditional routes. */
  446. static const struct snd_soc_dapm_route jz4770_codec_dapm_routes[] = {
  447. { "Mic 1", NULL, "MIC1P" },
  448. { "Mic Diff", NULL, "MIC1N" },
  449. { "Mic 1", NULL, "Mic Diff" },
  450. { "Mic 2", NULL, "MIC2P" },
  451. { "Mic Diff", NULL, "MIC2N" },
  452. { "Mic 2", NULL, "Mic Diff" },
  453. { "Line In", NULL, "LLINEIN" },
  454. { "Line In", NULL, "RLINEIN" },
  455. { "Mic", "Stereo Capture Switch", "Mic 1" },
  456. { "Mic", "Stereo Capture Switch", "Mic 2" },
  457. { "Headphones Source", "Mic 1", "Mic" },
  458. { "Headphones Source", "Mic 2", "Mic" },
  459. { "Capture Source", "Mic 1", "Mic" },
  460. { "Capture Source", "Mic 2", "Mic" },
  461. { "Headphones Source", "Mic 1", "Mic 1" },
  462. { "Headphones Source", "Mic 2", "Mic 2" },
  463. { "Headphones Source", "Line In", "Line In Bypass" },
  464. { "Headphones Source", "PCM", "Headphones Playback" },
  465. { "HP Out", NULL, "Headphones Source" },
  466. { "Capture Source", "Line In", "Line In" },
  467. { "Capture Source", "Mic 1", "Mic 1" },
  468. { "Capture Source", "Mic 2", "Mic 2" },
  469. { "ADC", NULL, "Capture Source" },
  470. { "Line In Bypass", NULL, "Line In" },
  471. { "Line Out Source", "Line In", "Line In Bypass" },
  472. { "Line Out Source", "PCM", "PCM Playback" },
  473. { "LHPOUT", NULL, "HP Out"},
  474. { "RHPOUT", NULL, "HP Out"},
  475. { "Line Out", NULL, "Line Out Source" },
  476. { "Line Out Switch 2", NULL, "Line Out" },
  477. { "LOUT", NULL, "Line Out Switch 2"},
  478. { "ROUT", NULL, "Line Out Switch 2"},
  479. { "PCM Playback", "Volume", "DAC" },
  480. { "Headphones Playback", "Volume", "PCM Playback" },
  481. { "SYSCLK", NULL, "DAC" },
  482. };
  483. static void jz4770_codec_codec_init_regs(struct snd_soc_component *codec)
  484. {
  485. struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
  486. struct regmap *regmap = jz_codec->regmap;
  487. /* Collect updates for later sending. */
  488. regcache_cache_only(regmap, true);
  489. /* default HP output to PCM */
  490. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_HP,
  491. REG_CR_HP_SEL_MASK, REG_CR_HP_SEL_MASK);
  492. /* default line output to PCM */
  493. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_LO,
  494. REG_CR_LO_SEL_MASK, REG_CR_LO_SEL_MASK);
  495. /* Disable stereo mic */
  496. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_MIC,
  497. BIT(REG_CR_MIC_STEREO_OFFSET), 0);
  498. /* Set mic 1 as default source for ADC */
  499. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_ADC,
  500. REG_CR_ADC_IN_SEL_MASK, 0);
  501. /* ADC/DAC: serial + i2s */
  502. regmap_update_bits(regmap, JZ4770_CODEC_REG_AICR_ADC,
  503. REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S,
  504. REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S);
  505. regmap_update_bits(regmap, JZ4770_CODEC_REG_AICR_DAC,
  506. REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S,
  507. REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
  508. /* The generated IRQ is a high level */
  509. regmap_update_bits(regmap, JZ4770_CODEC_REG_ICR,
  510. REG_ICR_INT_FORM_MASK, 0);
  511. regmap_update_bits(regmap, JZ4770_CODEC_REG_IMR, REG_IMR_ALL_MASK,
  512. REG_IMR_JACK_MASK | REG_IMR_RUP_MASK |
  513. REG_IMR_RDO_MASK | REG_IMR_GUP_MASK |
  514. REG_IMR_GDO_MASK);
  515. /* 12M oscillator */
  516. regmap_update_bits(regmap, JZ4770_CODEC_REG_CCR,
  517. REG_CCR_CRYSTAL_MASK, 0);
  518. /* 0: 16ohm/220uF, 1: 10kohm/1uF */
  519. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_HP,
  520. REG_CR_HP_LOAD, 0);
  521. /* disable automatic gain */
  522. regmap_update_bits(regmap, JZ4770_CODEC_REG_AGC1, REG_AGC1_EN, 0);
  523. /* Disable DAC lrswap */
  524. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_DAC,
  525. REG_CR_DAC_LRSWAP, REG_CR_DAC_LRSWAP);
  526. /* Independent L/R DAC gain control */
  527. regmap_update_bits(regmap, JZ4770_CODEC_REG_GCR_DACL,
  528. REG_GCR_DACL_RLGOD, 0);
  529. /* Disable ADC lrswap */
  530. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_ADC,
  531. REG_CR_ADC_LRSWAP, REG_CR_ADC_LRSWAP);
  532. /* default to cap-less mode(0) */
  533. regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_HP,
  534. REG_CR_HP_SB_HPCM, 0);
  535. /* Send collected updates. */
  536. regcache_cache_only(regmap, false);
  537. regcache_sync(regmap);
  538. /* Reset all interrupt flags. */
  539. regmap_write(regmap, JZ4770_CODEC_REG_IFR, REG_IFR_ALL_MASK);
  540. }
  541. static int jz4770_codec_codec_probe(struct snd_soc_component *codec)
  542. {
  543. struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
  544. clk_prepare_enable(jz_codec->clk);
  545. jz4770_codec_codec_init_regs(codec);
  546. return 0;
  547. }
  548. static void jz4770_codec_codec_remove(struct snd_soc_component *codec)
  549. {
  550. struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
  551. clk_disable_unprepare(jz_codec->clk);
  552. }
  553. static const struct snd_soc_component_driver jz4770_codec_soc_codec_dev = {
  554. .probe = jz4770_codec_codec_probe,
  555. .remove = jz4770_codec_codec_remove,
  556. .set_bias_level = jz4770_codec_set_bias_level,
  557. .controls = jz4770_codec_snd_controls,
  558. .num_controls = ARRAY_SIZE(jz4770_codec_snd_controls),
  559. .dapm_widgets = jz4770_codec_dapm_widgets,
  560. .num_dapm_widgets = ARRAY_SIZE(jz4770_codec_dapm_widgets),
  561. .dapm_routes = jz4770_codec_dapm_routes,
  562. .num_dapm_routes = ARRAY_SIZE(jz4770_codec_dapm_routes),
  563. .suspend_bias_off = 1,
  564. .use_pmdown_time = 1,
  565. };
  566. static const unsigned int jz4770_codec_sample_rates[] = {
  567. 96000, 48000, 44100, 32000,
  568. 24000, 22050, 16000, 12000,
  569. 11025, 9600, 8000,
  570. };
  571. static int jz4770_codec_hw_params(struct snd_pcm_substream *substream,
  572. struct snd_pcm_hw_params *params,
  573. struct snd_soc_dai *dai)
  574. {
  575. struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
  576. unsigned int rate, bit_width;
  577. switch (params_format(params)) {
  578. case SNDRV_PCM_FORMAT_S16_LE:
  579. bit_width = 0;
  580. break;
  581. case SNDRV_PCM_FORMAT_S18_3LE:
  582. bit_width = 1;
  583. break;
  584. case SNDRV_PCM_FORMAT_S20_3LE:
  585. bit_width = 2;
  586. break;
  587. case SNDRV_PCM_FORMAT_S24_3LE:
  588. bit_width = 3;
  589. break;
  590. default:
  591. return -EINVAL;
  592. }
  593. for (rate = 0; rate < ARRAY_SIZE(jz4770_codec_sample_rates); rate++) {
  594. if (jz4770_codec_sample_rates[rate] == params_rate(params))
  595. break;
  596. }
  597. if (rate == ARRAY_SIZE(jz4770_codec_sample_rates))
  598. return -EINVAL;
  599. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  600. regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_DAC,
  601. REG_AICR_DAC_ADWL_MASK,
  602. bit_width << REG_AICR_DAC_ADWL_OFFSET);
  603. regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_DAC,
  604. REG_FCR_DAC_FREQ_MASK,
  605. rate << REG_FCR_DAC_FREQ_OFFSET);
  606. } else {
  607. regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_ADC,
  608. REG_AICR_ADC_ADWL_MASK,
  609. bit_width << REG_AICR_ADC_ADWL_OFFSET);
  610. regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_ADC,
  611. REG_FCR_ADC_FREQ_MASK,
  612. rate << REG_FCR_ADC_FREQ_OFFSET);
  613. }
  614. return 0;
  615. }
  616. static const struct snd_soc_dai_ops jz4770_codec_dai_ops = {
  617. .startup = jz4770_codec_startup,
  618. .shutdown = jz4770_codec_shutdown,
  619. .hw_params = jz4770_codec_hw_params,
  620. .trigger = jz4770_codec_pcm_trigger,
  621. .mute_stream = jz4770_codec_mute_stream,
  622. .no_capture_mute = 1,
  623. };
  624. #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
  625. SNDRV_PCM_FMTBIT_S18_3LE | \
  626. SNDRV_PCM_FMTBIT_S20_3LE | \
  627. SNDRV_PCM_FMTBIT_S24_3LE)
  628. static struct snd_soc_dai_driver jz4770_codec_dai = {
  629. .name = "jz4770-hifi",
  630. .playback = {
  631. .stream_name = "Playback",
  632. .channels_min = 2,
  633. .channels_max = 2,
  634. .rates = SNDRV_PCM_RATE_8000_96000,
  635. .formats = JZ_CODEC_FORMATS,
  636. },
  637. .capture = {
  638. .stream_name = "Capture",
  639. .channels_min = 2,
  640. .channels_max = 2,
  641. .rates = SNDRV_PCM_RATE_8000_96000,
  642. .formats = JZ_CODEC_FORMATS,
  643. },
  644. .ops = &jz4770_codec_dai_ops,
  645. };
  646. static bool jz4770_codec_volatile(struct device *dev, unsigned int reg)
  647. {
  648. return reg == JZ4770_CODEC_REG_SR || reg == JZ4770_CODEC_REG_IFR;
  649. }
  650. static bool jz4770_codec_readable(struct device *dev, unsigned int reg)
  651. {
  652. switch (reg) {
  653. case JZ4770_CODEC_REG_MISSING_REG1:
  654. case JZ4770_CODEC_REG_MISSING_REG2:
  655. return false;
  656. default:
  657. return true;
  658. }
  659. }
  660. static bool jz4770_codec_writeable(struct device *dev, unsigned int reg)
  661. {
  662. switch (reg) {
  663. case JZ4770_CODEC_REG_SR:
  664. case JZ4770_CODEC_REG_MISSING_REG1:
  665. case JZ4770_CODEC_REG_MISSING_REG2:
  666. return false;
  667. default:
  668. return true;
  669. }
  670. }
  671. static int jz4770_codec_io_wait(struct jz_codec *codec)
  672. {
  673. u32 reg;
  674. return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
  675. !(reg & ICDC_RGADW_RGWR),
  676. 1000, 10 * USEC_PER_MSEC);
  677. }
  678. static int jz4770_codec_reg_read(void *context, unsigned int reg,
  679. unsigned int *val)
  680. {
  681. struct jz_codec *codec = context;
  682. unsigned int i;
  683. u32 tmp;
  684. int ret;
  685. ret = jz4770_codec_io_wait(codec);
  686. if (ret)
  687. return ret;
  688. tmp = readl(codec->base + ICDC_RGADW_OFFSET);
  689. tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
  690. | (reg << ICDC_RGADW_RGADDR_OFFSET);
  691. writel(tmp, codec->base + ICDC_RGADW_OFFSET);
  692. /* wait 6+ cycles */
  693. for (i = 0; i < 6; i++)
  694. *val = readl(codec->base + ICDC_RGDATA_OFFSET) &
  695. ICDC_RGDATA_RGDOUT_MASK;
  696. return 0;
  697. }
  698. static int jz4770_codec_reg_write(void *context, unsigned int reg,
  699. unsigned int val)
  700. {
  701. struct jz_codec *codec = context;
  702. int ret;
  703. ret = jz4770_codec_io_wait(codec);
  704. if (ret)
  705. return ret;
  706. writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
  707. codec->base + ICDC_RGADW_OFFSET);
  708. ret = jz4770_codec_io_wait(codec);
  709. if (ret)
  710. return ret;
  711. return 0;
  712. }
  713. static const u8 jz4770_codec_reg_defaults[] = {
  714. 0x00, 0xC3, 0xC3, 0x90, 0x98, 0xFF, 0x90, 0xB1,
  715. 0x11, 0x10, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00,
  716. 0xFF, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
  717. 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x34,
  718. 0x07, 0x44, 0x1F, 0x00
  719. };
  720. static struct regmap_config jz4770_codec_regmap_config = {
  721. .reg_bits = 7,
  722. .val_bits = 8,
  723. .max_register = JZ4770_CODEC_REG_AGC5,
  724. .volatile_reg = jz4770_codec_volatile,
  725. .readable_reg = jz4770_codec_readable,
  726. .writeable_reg = jz4770_codec_writeable,
  727. .reg_read = jz4770_codec_reg_read,
  728. .reg_write = jz4770_codec_reg_write,
  729. .reg_defaults_raw = jz4770_codec_reg_defaults,
  730. .num_reg_defaults_raw = ARRAY_SIZE(jz4770_codec_reg_defaults),
  731. .cache_type = REGCACHE_FLAT,
  732. };
  733. static int jz4770_codec_probe(struct platform_device *pdev)
  734. {
  735. struct device *dev = &pdev->dev;
  736. struct jz_codec *codec;
  737. int ret;
  738. codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
  739. if (!codec)
  740. return -ENOMEM;
  741. codec->dev = dev;
  742. codec->base = devm_platform_ioremap_resource(pdev, 0);
  743. if (IS_ERR(codec->base)) {
  744. ret = PTR_ERR(codec->base);
  745. dev_err(dev, "Failed to ioremap mmio memory: %d\n", ret);
  746. return ret;
  747. }
  748. codec->regmap = devm_regmap_init(dev, NULL, codec,
  749. &jz4770_codec_regmap_config);
  750. if (IS_ERR(codec->regmap))
  751. return PTR_ERR(codec->regmap);
  752. codec->clk = devm_clk_get(dev, "aic");
  753. if (IS_ERR(codec->clk))
  754. return PTR_ERR(codec->clk);
  755. platform_set_drvdata(pdev, codec);
  756. ret = devm_snd_soc_register_component(dev, &jz4770_codec_soc_codec_dev,
  757. &jz4770_codec_dai, 1);
  758. if (ret) {
  759. dev_err(dev, "Failed to register codec: %d\n", ret);
  760. return ret;
  761. }
  762. return 0;
  763. }
  764. static const struct of_device_id jz4770_codec_of_matches[] = {
  765. { .compatible = "ingenic,jz4770-codec", },
  766. { /* sentinel */ }
  767. };
  768. MODULE_DEVICE_TABLE(of, jz4770_codec_of_matches);
  769. static struct platform_driver jz4770_codec_driver = {
  770. .probe = jz4770_codec_probe,
  771. .driver = {
  772. .name = "jz4770-codec",
  773. .of_match_table = jz4770_codec_of_matches,
  774. },
  775. };
  776. module_platform_driver(jz4770_codec_driver);
  777. MODULE_DESCRIPTION("JZ4770 SoC internal codec driver");
  778. MODULE_AUTHOR("Maarten ter Huurne <maarten@treewalker.org>");
  779. MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
  780. MODULE_LICENSE("GPL v2");