adau17x1.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /*
  2. * Common code for ADAU1X61 and ADAU1X81 codecs
  3. *
  4. * Copyright 2011-2014 Analog Devices Inc.
  5. * Author: Lars-Peter Clausen <lars@metafoo.de>
  6. *
  7. * Licensed under the GPL-2 or later.
  8. */
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/delay.h>
  12. #include <linux/slab.h>
  13. #include <sound/core.h>
  14. #include <sound/pcm.h>
  15. #include <sound/pcm_params.h>
  16. #include <sound/soc.h>
  17. #include <sound/tlv.h>
  18. #include <linux/gcd.h>
  19. #include <linux/i2c.h>
  20. #include <linux/spi/spi.h>
  21. #include <linux/regmap.h>
  22. #include "sigmadsp.h"
  23. #include "adau17x1.h"
  24. static const char * const adau17x1_capture_mixer_boost_text[] = {
  25. "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3",
  26. };
  27. static SOC_ENUM_SINGLE_DECL(adau17x1_capture_boost_enum,
  28. ADAU17X1_REC_POWER_MGMT, 5, adau17x1_capture_mixer_boost_text);
  29. static const char * const adau17x1_mic_bias_mode_text[] = {
  30. "Normal operation", "High performance",
  31. };
  32. static SOC_ENUM_SINGLE_DECL(adau17x1_mic_bias_mode_enum,
  33. ADAU17X1_MICBIAS, 3, adau17x1_mic_bias_mode_text);
  34. static const DECLARE_TLV_DB_MINMAX(adau17x1_digital_tlv, -9563, 0);
  35. static const struct snd_kcontrol_new adau17x1_controls[] = {
  36. SOC_DOUBLE_R_TLV("Digital Capture Volume",
  37. ADAU17X1_LEFT_INPUT_DIGITAL_VOL,
  38. ADAU17X1_RIGHT_INPUT_DIGITAL_VOL,
  39. 0, 0xff, 1, adau17x1_digital_tlv),
  40. SOC_DOUBLE_R_TLV("Digital Playback Volume", ADAU17X1_DAC_CONTROL1,
  41. ADAU17X1_DAC_CONTROL2, 0, 0xff, 1, adau17x1_digital_tlv),
  42. SOC_SINGLE("ADC High Pass Filter Switch", ADAU17X1_ADC_CONTROL,
  43. 5, 1, 0),
  44. SOC_SINGLE("Playback De-emphasis Switch", ADAU17X1_DAC_CONTROL0,
  45. 2, 1, 0),
  46. SOC_ENUM("Capture Boost", adau17x1_capture_boost_enum),
  47. SOC_ENUM("Mic Bias Mode", adau17x1_mic_bias_mode_enum),
  48. };
  49. static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
  50. struct snd_kcontrol *kcontrol, int event)
  51. {
  52. struct adau *adau = snd_soc_codec_get_drvdata(w->codec);
  53. int ret;
  54. if (SND_SOC_DAPM_EVENT_ON(event)) {
  55. adau->pll_regs[5] = 1;
  56. } else {
  57. adau->pll_regs[5] = 0;
  58. /* Bypass the PLL when disabled, otherwise registers will become
  59. * inaccessible. */
  60. regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
  61. ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, 0);
  62. }
  63. /* The PLL register is 6 bytes long and can only be written at once. */
  64. ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
  65. adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
  66. if (SND_SOC_DAPM_EVENT_ON(event)) {
  67. mdelay(5);
  68. regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
  69. ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL,
  70. ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL);
  71. }
  72. return 0;
  73. }
  74. static const char * const adau17x1_mono_stereo_text[] = {
  75. "Stereo",
  76. "Mono Left Channel (L+R)",
  77. "Mono Right Channel (L+R)",
  78. "Mono (L+R)",
  79. };
  80. static SOC_ENUM_SINGLE_DECL(adau17x1_dac_mode_enum,
  81. ADAU17X1_DAC_CONTROL0, 6, adau17x1_mono_stereo_text);
  82. static const struct snd_kcontrol_new adau17x1_dac_mode_mux =
  83. SOC_DAPM_ENUM("DAC Mono-Stereo-Mode", adau17x1_dac_mode_enum);
  84. static const struct snd_soc_dapm_widget adau17x1_dapm_widgets[] = {
  85. SND_SOC_DAPM_SUPPLY_S("PLL", 3, SND_SOC_NOPM, 0, 0, adau17x1_pll_event,
  86. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  87. SND_SOC_DAPM_SUPPLY("AIFCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
  88. SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU17X1_MICBIAS, 0, 0, NULL, 0),
  89. SND_SOC_DAPM_SUPPLY("Left Playback Enable", ADAU17X1_PLAY_POWER_MGMT,
  90. 0, 0, NULL, 0),
  91. SND_SOC_DAPM_SUPPLY("Right Playback Enable", ADAU17X1_PLAY_POWER_MGMT,
  92. 1, 0, NULL, 0),
  93. SND_SOC_DAPM_MUX("Left DAC Mode Mux", SND_SOC_NOPM, 0, 0,
  94. &adau17x1_dac_mode_mux),
  95. SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0,
  96. &adau17x1_dac_mode_mux),
  97. SND_SOC_DAPM_ADC("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0),
  98. SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0),
  99. SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0),
  100. SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0),
  101. };
  102. static const struct snd_soc_dapm_route adau17x1_dapm_routes[] = {
  103. { "Left Decimator", NULL, "SYSCLK" },
  104. { "Right Decimator", NULL, "SYSCLK" },
  105. { "Left DAC", NULL, "SYSCLK" },
  106. { "Right DAC", NULL, "SYSCLK" },
  107. { "Capture", NULL, "SYSCLK" },
  108. { "Playback", NULL, "SYSCLK" },
  109. { "Left DAC", NULL, "Left DAC Mode Mux" },
  110. { "Right DAC", NULL, "Right DAC Mode Mux" },
  111. { "Capture", NULL, "AIFCLK" },
  112. { "Playback", NULL, "AIFCLK" },
  113. };
  114. static const struct snd_soc_dapm_route adau17x1_dapm_pll_route = {
  115. "SYSCLK", NULL, "PLL",
  116. };
  117. /*
  118. * The MUX register for the Capture and Playback MUXs selects either DSP as
  119. * source/destination or one of the TDM slots. The TDM slot is selected via
  120. * snd_soc_dai_set_tdm_slot(), so we only expose whether to go to the DSP or
  121. * directly to the DAI interface with this control.
  122. */
  123. static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
  124. struct snd_ctl_elem_value *ucontrol)
  125. {
  126. struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
  127. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  128. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  129. struct snd_soc_dapm_update update;
  130. unsigned int stream = e->shift_l;
  131. unsigned int val, change;
  132. int reg;
  133. if (ucontrol->value.enumerated.item[0] >= e->items)
  134. return -EINVAL;
  135. switch (ucontrol->value.enumerated.item[0]) {
  136. case 0:
  137. val = 0;
  138. adau->dsp_bypass[stream] = false;
  139. break;
  140. default:
  141. val = (adau->tdm_slot[stream] * 2) + 1;
  142. adau->dsp_bypass[stream] = true;
  143. break;
  144. }
  145. if (stream == SNDRV_PCM_STREAM_PLAYBACK)
  146. reg = ADAU17X1_SERIAL_INPUT_ROUTE;
  147. else
  148. reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;
  149. change = snd_soc_test_bits(codec, reg, 0xff, val);
  150. if (change) {
  151. update.kcontrol = kcontrol;
  152. update.mask = 0xff;
  153. update.reg = reg;
  154. update.val = val;
  155. snd_soc_dapm_mux_update_power(&codec->dapm, kcontrol,
  156. ucontrol->value.enumerated.item[0], e, &update);
  157. }
  158. return change;
  159. }
  160. static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,
  161. struct snd_ctl_elem_value *ucontrol)
  162. {
  163. struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
  164. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  165. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  166. unsigned int stream = e->shift_l;
  167. unsigned int reg, val;
  168. int ret;
  169. if (stream == SNDRV_PCM_STREAM_PLAYBACK)
  170. reg = ADAU17X1_SERIAL_INPUT_ROUTE;
  171. else
  172. reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;
  173. ret = regmap_read(adau->regmap, reg, &val);
  174. if (ret)
  175. return ret;
  176. if (val != 0)
  177. val = 1;
  178. ucontrol->value.enumerated.item[0] = val;
  179. return 0;
  180. }
  181. #define DECLARE_ADAU17X1_DSP_MUX_CTRL(_name, _label, _stream, _text) \
  182. const struct snd_kcontrol_new _name = \
  183. SOC_DAPM_ENUM_EXT(_label, (const struct soc_enum)\
  184. SOC_ENUM_SINGLE(SND_SOC_NOPM, _stream, \
  185. ARRAY_SIZE(_text), _text), \
  186. adau17x1_dsp_mux_enum_get, adau17x1_dsp_mux_enum_put)
  187. static const char * const adau17x1_dac_mux_text[] = {
  188. "DSP",
  189. "AIFIN",
  190. };
  191. static const char * const adau17x1_capture_mux_text[] = {
  192. "DSP",
  193. "Decimator",
  194. };
  195. static DECLARE_ADAU17X1_DSP_MUX_CTRL(adau17x1_dac_mux, "DAC Playback Mux",
  196. SNDRV_PCM_STREAM_PLAYBACK, adau17x1_dac_mux_text);
  197. static DECLARE_ADAU17X1_DSP_MUX_CTRL(adau17x1_capture_mux, "Capture Mux",
  198. SNDRV_PCM_STREAM_CAPTURE, adau17x1_capture_mux_text);
  199. static const struct snd_soc_dapm_widget adau17x1_dsp_dapm_widgets[] = {
  200. SND_SOC_DAPM_PGA("DSP", ADAU17X1_DSP_RUN, 0, 0, NULL, 0),
  201. SND_SOC_DAPM_SIGGEN("DSP Siggen"),
  202. SND_SOC_DAPM_MUX("DAC Playback Mux", SND_SOC_NOPM, 0, 0,
  203. &adau17x1_dac_mux),
  204. SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
  205. &adau17x1_capture_mux),
  206. };
  207. static const struct snd_soc_dapm_route adau17x1_dsp_dapm_routes[] = {
  208. { "DAC Playback Mux", "DSP", "DSP" },
  209. { "DAC Playback Mux", "AIFIN", "Playback" },
  210. { "Left DAC Mode Mux", "Stereo", "DAC Playback Mux" },
  211. { "Left DAC Mode Mux", "Mono (L+R)", "DAC Playback Mux" },
  212. { "Left DAC Mode Mux", "Mono Left Channel (L+R)", "DAC Playback Mux" },
  213. { "Right DAC Mode Mux", "Stereo", "DAC Playback Mux" },
  214. { "Right DAC Mode Mux", "Mono (L+R)", "DAC Playback Mux" },
  215. { "Right DAC Mode Mux", "Mono Right Channel (L+R)", "DAC Playback Mux" },
  216. { "Capture Mux", "DSP", "DSP" },
  217. { "Capture Mux", "Decimator", "Left Decimator" },
  218. { "Capture Mux", "Decimator", "Right Decimator" },
  219. { "Capture", NULL, "Capture Mux" },
  220. { "DSP", NULL, "DSP Siggen" },
  221. { "DSP", NULL, "Left Decimator" },
  222. { "DSP", NULL, "Right Decimator" },
  223. };
  224. static const struct snd_soc_dapm_route adau17x1_no_dsp_dapm_routes[] = {
  225. { "Left DAC Mode Mux", "Stereo", "Playback" },
  226. { "Left DAC Mode Mux", "Mono (L+R)", "Playback" },
  227. { "Left DAC Mode Mux", "Mono Left Channel (L+R)", "Playback" },
  228. { "Right DAC Mode Mux", "Stereo", "Playback" },
  229. { "Right DAC Mode Mux", "Mono (L+R)", "Playback" },
  230. { "Right DAC Mode Mux", "Mono Right Channel (L+R)", "Playback" },
  231. { "Capture", NULL, "Left Decimator" },
  232. { "Capture", NULL, "Right Decimator" },
  233. };
  234. bool adau17x1_has_dsp(struct adau *adau)
  235. {
  236. switch (adau->type) {
  237. case ADAU1761:
  238. case ADAU1381:
  239. case ADAU1781:
  240. return true;
  241. default:
  242. return false;
  243. }
  244. }
  245. EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
  246. static int adau17x1_hw_params(struct snd_pcm_substream *substream,
  247. struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
  248. {
  249. struct snd_soc_codec *codec = dai->codec;
  250. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  251. unsigned int val, div, dsp_div;
  252. unsigned int freq;
  253. if (adau->clk_src == ADAU17X1_CLK_SRC_PLL)
  254. freq = adau->pll_freq;
  255. else
  256. freq = adau->sysclk;
  257. if (freq % params_rate(params) != 0)
  258. return -EINVAL;
  259. switch (freq / params_rate(params)) {
  260. case 1024: /* fs */
  261. div = 0;
  262. dsp_div = 1;
  263. break;
  264. case 6144: /* fs / 6 */
  265. div = 1;
  266. dsp_div = 6;
  267. break;
  268. case 4096: /* fs / 4 */
  269. div = 2;
  270. dsp_div = 5;
  271. break;
  272. case 3072: /* fs / 3 */
  273. div = 3;
  274. dsp_div = 4;
  275. break;
  276. case 2048: /* fs / 2 */
  277. div = 4;
  278. dsp_div = 3;
  279. break;
  280. case 1536: /* fs / 1.5 */
  281. div = 5;
  282. dsp_div = 2;
  283. break;
  284. case 512: /* fs / 0.5 */
  285. div = 6;
  286. dsp_div = 0;
  287. break;
  288. default:
  289. return -EINVAL;
  290. }
  291. regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
  292. ADAU17X1_CONVERTER0_CONVSR_MASK, div);
  293. if (adau17x1_has_dsp(adau)) {
  294. regmap_write(adau->regmap, ADAU17X1_SERIAL_SAMPLING_RATE, div);
  295. regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dsp_div);
  296. }
  297. if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
  298. return 0;
  299. switch (params_width(params)) {
  300. case 16:
  301. val = ADAU17X1_SERIAL_PORT1_DELAY16;
  302. break;
  303. case 24:
  304. val = ADAU17X1_SERIAL_PORT1_DELAY8;
  305. break;
  306. case 32:
  307. val = ADAU17X1_SERIAL_PORT1_DELAY0;
  308. break;
  309. default:
  310. return -EINVAL;
  311. }
  312. return regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,
  313. ADAU17X1_SERIAL_PORT1_DELAY_MASK, val);
  314. }
  315. static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
  316. int source, unsigned int freq_in, unsigned int freq_out)
  317. {
  318. struct snd_soc_codec *codec = dai->codec;
  319. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  320. unsigned int r, n, m, i, j;
  321. unsigned int div;
  322. int ret;
  323. if (freq_in < 8000000 || freq_in > 27000000)
  324. return -EINVAL;
  325. if (!freq_out) {
  326. r = 0;
  327. n = 0;
  328. m = 0;
  329. div = 0;
  330. } else {
  331. if (freq_out % freq_in != 0) {
  332. div = DIV_ROUND_UP(freq_in, 13500000);
  333. freq_in /= div;
  334. r = freq_out / freq_in;
  335. i = freq_out % freq_in;
  336. j = gcd(i, freq_in);
  337. n = i / j;
  338. m = freq_in / j;
  339. div--;
  340. } else {
  341. r = freq_out / freq_in;
  342. n = 0;
  343. m = 0;
  344. div = 0;
  345. }
  346. if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
  347. return -EINVAL;
  348. }
  349. adau->pll_regs[0] = m >> 8;
  350. adau->pll_regs[1] = m & 0xff;
  351. adau->pll_regs[2] = n >> 8;
  352. adau->pll_regs[3] = n & 0xff;
  353. adau->pll_regs[4] = (r << 3) | (div << 1);
  354. if (m != 0)
  355. adau->pll_regs[4] |= 1; /* Fractional mode */
  356. /* The PLL register is 6 bytes long and can only be written at once. */
  357. ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
  358. adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
  359. if (ret)
  360. return ret;
  361. adau->pll_freq = freq_out;
  362. return 0;
  363. }
  364. static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
  365. int clk_id, unsigned int freq, int dir)
  366. {
  367. struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
  368. struct snd_soc_dapm_context *dapm = &dai->codec->dapm;
  369. switch (clk_id) {
  370. case ADAU17X1_CLK_SRC_MCLK:
  371. case ADAU17X1_CLK_SRC_PLL:
  372. break;
  373. default:
  374. return -EINVAL;
  375. }
  376. adau->sysclk = freq;
  377. if (adau->clk_src != clk_id) {
  378. if (clk_id == ADAU17X1_CLK_SRC_PLL) {
  379. snd_soc_dapm_add_routes(dapm,
  380. &adau17x1_dapm_pll_route, 1);
  381. } else {
  382. snd_soc_dapm_del_routes(dapm,
  383. &adau17x1_dapm_pll_route, 1);
  384. }
  385. }
  386. adau->clk_src = clk_id;
  387. return 0;
  388. }
  389. static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
  390. unsigned int fmt)
  391. {
  392. struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
  393. unsigned int ctrl0, ctrl1;
  394. int lrclk_pol;
  395. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  396. case SND_SOC_DAIFMT_CBM_CFM:
  397. ctrl0 = ADAU17X1_SERIAL_PORT0_MASTER;
  398. adau->master = true;
  399. break;
  400. case SND_SOC_DAIFMT_CBS_CFS:
  401. ctrl0 = 0;
  402. adau->master = false;
  403. break;
  404. default:
  405. return -EINVAL;
  406. }
  407. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  408. case SND_SOC_DAIFMT_I2S:
  409. lrclk_pol = 0;
  410. ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1;
  411. break;
  412. case SND_SOC_DAIFMT_LEFT_J:
  413. case SND_SOC_DAIFMT_RIGHT_J:
  414. lrclk_pol = 1;
  415. ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0;
  416. break;
  417. case SND_SOC_DAIFMT_DSP_A:
  418. lrclk_pol = 1;
  419. ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE;
  420. ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1;
  421. break;
  422. case SND_SOC_DAIFMT_DSP_B:
  423. lrclk_pol = 1;
  424. ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE;
  425. ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0;
  426. break;
  427. default:
  428. return -EINVAL;
  429. }
  430. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  431. case SND_SOC_DAIFMT_NB_NF:
  432. break;
  433. case SND_SOC_DAIFMT_IB_NF:
  434. ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL;
  435. break;
  436. case SND_SOC_DAIFMT_NB_IF:
  437. lrclk_pol = !lrclk_pol;
  438. break;
  439. case SND_SOC_DAIFMT_IB_IF:
  440. ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL;
  441. lrclk_pol = !lrclk_pol;
  442. break;
  443. default:
  444. return -EINVAL;
  445. }
  446. if (lrclk_pol)
  447. ctrl0 |= ADAU17X1_SERIAL_PORT0_LRCLK_POL;
  448. regmap_write(adau->regmap, ADAU17X1_SERIAL_PORT0, ctrl0);
  449. regmap_write(adau->regmap, ADAU17X1_SERIAL_PORT1, ctrl1);
  450. adau->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
  451. return 0;
  452. }
  453. static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,
  454. unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
  455. {
  456. struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
  457. unsigned int ser_ctrl0, ser_ctrl1;
  458. unsigned int conv_ctrl0, conv_ctrl1;
  459. /* I2S mode */
  460. if (slots == 0) {
  461. slots = 2;
  462. rx_mask = 3;
  463. tx_mask = 3;
  464. slot_width = 32;
  465. }
  466. switch (slots) {
  467. case 2:
  468. ser_ctrl0 = ADAU17X1_SERIAL_PORT0_STEREO;
  469. break;
  470. case 4:
  471. ser_ctrl0 = ADAU17X1_SERIAL_PORT0_TDM4;
  472. break;
  473. case 8:
  474. if (adau->type == ADAU1361)
  475. return -EINVAL;
  476. ser_ctrl0 = ADAU17X1_SERIAL_PORT0_TDM8;
  477. break;
  478. default:
  479. return -EINVAL;
  480. }
  481. switch (slot_width * slots) {
  482. case 32:
  483. if (adau->type == ADAU1761)
  484. return -EINVAL;
  485. ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK32;
  486. break;
  487. case 64:
  488. ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK64;
  489. break;
  490. case 48:
  491. ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK48;
  492. break;
  493. case 128:
  494. ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK128;
  495. break;
  496. case 256:
  497. if (adau->type == ADAU1361)
  498. return -EINVAL;
  499. ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK256;
  500. break;
  501. default:
  502. return -EINVAL;
  503. }
  504. switch (rx_mask) {
  505. case 0x03:
  506. conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(1);
  507. adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 0;
  508. break;
  509. case 0x0c:
  510. conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(2);
  511. adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 1;
  512. break;
  513. case 0x30:
  514. conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(3);
  515. adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 2;
  516. break;
  517. case 0xc0:
  518. conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(4);
  519. adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 3;
  520. break;
  521. default:
  522. return -EINVAL;
  523. }
  524. switch (tx_mask) {
  525. case 0x03:
  526. conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(1);
  527. adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 0;
  528. break;
  529. case 0x0c:
  530. conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(2);
  531. adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 1;
  532. break;
  533. case 0x30:
  534. conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(3);
  535. adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 2;
  536. break;
  537. case 0xc0:
  538. conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(4);
  539. adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 3;
  540. break;
  541. default:
  542. return -EINVAL;
  543. }
  544. regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
  545. ADAU17X1_CONVERTER0_DAC_PAIR_MASK, conv_ctrl0);
  546. regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER1,
  547. ADAU17X1_CONVERTER1_ADC_PAIR_MASK, conv_ctrl1);
  548. regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT0,
  549. ADAU17X1_SERIAL_PORT0_TDM_MASK, ser_ctrl0);
  550. regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,
  551. ADAU17X1_SERIAL_PORT1_BCLK_MASK, ser_ctrl1);
  552. if (!adau17x1_has_dsp(adau))
  553. return 0;
  554. if (adau->dsp_bypass[SNDRV_PCM_STREAM_PLAYBACK]) {
  555. regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE,
  556. (adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] * 2) + 1);
  557. }
  558. if (adau->dsp_bypass[SNDRV_PCM_STREAM_CAPTURE]) {
  559. regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE,
  560. (adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] * 2) + 1);
  561. }
  562. return 0;
  563. }
  564. const struct snd_soc_dai_ops adau17x1_dai_ops = {
  565. .hw_params = adau17x1_hw_params,
  566. .set_sysclk = adau17x1_set_dai_sysclk,
  567. .set_fmt = adau17x1_set_dai_fmt,
  568. .set_pll = adau17x1_set_dai_pll,
  569. .set_tdm_slot = adau17x1_set_dai_tdm_slot,
  570. };
  571. EXPORT_SYMBOL_GPL(adau17x1_dai_ops);
  572. int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
  573. enum adau17x1_micbias_voltage micbias)
  574. {
  575. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  576. switch (micbias) {
  577. case ADAU17X1_MICBIAS_0_90_AVDD:
  578. case ADAU17X1_MICBIAS_0_65_AVDD:
  579. break;
  580. default:
  581. return -EINVAL;
  582. }
  583. return regmap_write(adau->regmap, ADAU17X1_MICBIAS, micbias << 2);
  584. }
  585. EXPORT_SYMBOL_GPL(adau17x1_set_micbias_voltage);
  586. bool adau17x1_readable_register(struct device *dev, unsigned int reg)
  587. {
  588. switch (reg) {
  589. case ADAU17X1_CLOCK_CONTROL:
  590. case ADAU17X1_PLL_CONTROL:
  591. case ADAU17X1_REC_POWER_MGMT:
  592. case ADAU17X1_MICBIAS:
  593. case ADAU17X1_SERIAL_PORT0:
  594. case ADAU17X1_SERIAL_PORT1:
  595. case ADAU17X1_CONVERTER0:
  596. case ADAU17X1_CONVERTER1:
  597. case ADAU17X1_LEFT_INPUT_DIGITAL_VOL:
  598. case ADAU17X1_RIGHT_INPUT_DIGITAL_VOL:
  599. case ADAU17X1_ADC_CONTROL:
  600. case ADAU17X1_PLAY_POWER_MGMT:
  601. case ADAU17X1_DAC_CONTROL0:
  602. case ADAU17X1_DAC_CONTROL1:
  603. case ADAU17X1_DAC_CONTROL2:
  604. case ADAU17X1_SERIAL_PORT_PAD:
  605. case ADAU17X1_CONTROL_PORT_PAD0:
  606. case ADAU17X1_CONTROL_PORT_PAD1:
  607. case ADAU17X1_DSP_SAMPLING_RATE:
  608. case ADAU17X1_SERIAL_INPUT_ROUTE:
  609. case ADAU17X1_SERIAL_OUTPUT_ROUTE:
  610. case ADAU17X1_DSP_ENABLE:
  611. case ADAU17X1_DSP_RUN:
  612. case ADAU17X1_SERIAL_SAMPLING_RATE:
  613. return true;
  614. default:
  615. break;
  616. }
  617. return false;
  618. }
  619. EXPORT_SYMBOL_GPL(adau17x1_readable_register);
  620. bool adau17x1_volatile_register(struct device *dev, unsigned int reg)
  621. {
  622. /* SigmaDSP parameter and program memory */
  623. if (reg < 0x4000)
  624. return true;
  625. switch (reg) {
  626. /* The PLL register is 6 bytes long */
  627. case ADAU17X1_PLL_CONTROL:
  628. case ADAU17X1_PLL_CONTROL + 1:
  629. case ADAU17X1_PLL_CONTROL + 2:
  630. case ADAU17X1_PLL_CONTROL + 3:
  631. case ADAU17X1_PLL_CONTROL + 4:
  632. case ADAU17X1_PLL_CONTROL + 5:
  633. return true;
  634. default:
  635. break;
  636. }
  637. return false;
  638. }
  639. EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
  640. int adau17x1_load_firmware(struct adau *adau, struct device *dev,
  641. const char *firmware)
  642. {
  643. int ret;
  644. int dspsr;
  645. ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
  646. if (ret)
  647. return ret;
  648. regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);
  649. regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);
  650. ret = process_sigma_firmware_regmap(dev, adau->regmap, firmware);
  651. if (ret) {
  652. regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);
  653. return ret;
  654. }
  655. regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);
  656. return 0;
  657. }
  658. EXPORT_SYMBOL_GPL(adau17x1_load_firmware);
  659. int adau17x1_add_widgets(struct snd_soc_codec *codec)
  660. {
  661. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  662. int ret;
  663. ret = snd_soc_add_codec_controls(codec, adau17x1_controls,
  664. ARRAY_SIZE(adau17x1_controls));
  665. if (ret)
  666. return ret;
  667. ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dapm_widgets,
  668. ARRAY_SIZE(adau17x1_dapm_widgets));
  669. if (ret)
  670. return ret;
  671. if (adau17x1_has_dsp(adau)) {
  672. ret = snd_soc_dapm_new_controls(&codec->dapm,
  673. adau17x1_dsp_dapm_widgets,
  674. ARRAY_SIZE(adau17x1_dsp_dapm_widgets));
  675. }
  676. return ret;
  677. }
  678. EXPORT_SYMBOL_GPL(adau17x1_add_widgets);
  679. int adau17x1_add_routes(struct snd_soc_codec *codec)
  680. {
  681. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  682. int ret;
  683. ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dapm_routes,
  684. ARRAY_SIZE(adau17x1_dapm_routes));
  685. if (ret)
  686. return ret;
  687. if (adau17x1_has_dsp(adau)) {
  688. ret = snd_soc_dapm_add_routes(&codec->dapm,
  689. adau17x1_dsp_dapm_routes,
  690. ARRAY_SIZE(adau17x1_dsp_dapm_routes));
  691. } else {
  692. ret = snd_soc_dapm_add_routes(&codec->dapm,
  693. adau17x1_no_dsp_dapm_routes,
  694. ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));
  695. }
  696. return ret;
  697. }
  698. EXPORT_SYMBOL_GPL(adau17x1_add_routes);
  699. int adau17x1_resume(struct snd_soc_codec *codec)
  700. {
  701. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  702. if (adau->switch_mode)
  703. adau->switch_mode(codec->dev);
  704. regcache_sync(adau->regmap);
  705. return 0;
  706. }
  707. EXPORT_SYMBOL_GPL(adau17x1_resume);
  708. int adau17x1_probe(struct device *dev, struct regmap *regmap,
  709. enum adau17x1_type type, void (*switch_mode)(struct device *dev))
  710. {
  711. struct adau *adau;
  712. if (IS_ERR(regmap))
  713. return PTR_ERR(regmap);
  714. adau = devm_kzalloc(dev, sizeof(*adau), GFP_KERNEL);
  715. if (!adau)
  716. return -ENOMEM;
  717. adau->regmap = regmap;
  718. adau->switch_mode = switch_mode;
  719. adau->type = type;
  720. dev_set_drvdata(dev, adau);
  721. if (switch_mode)
  722. switch_mode(dev);
  723. return 0;
  724. }
  725. EXPORT_SYMBOL_GPL(adau17x1_probe);
  726. MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code");
  727. MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
  728. MODULE_LICENSE("GPL");