arizona.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /*
  2. * arizona.c - Wolfson Arizona class device shared support
  3. *
  4. * Copyright 2012 Wolfson Microelectronics plc
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/gcd.h>
  13. #include <linux/module.h>
  14. #include <linux/pm_runtime.h>
  15. #include <sound/pcm.h>
  16. #include <sound/pcm_params.h>
  17. #include <sound/tlv.h>
  18. #include <linux/mfd/arizona/core.h>
  19. #include <linux/mfd/arizona/registers.h>
  20. #include "arizona.h"
  21. #define ARIZONA_AIF_BCLK_CTRL 0x00
  22. #define ARIZONA_AIF_TX_PIN_CTRL 0x01
  23. #define ARIZONA_AIF_RX_PIN_CTRL 0x02
  24. #define ARIZONA_AIF_RATE_CTRL 0x03
  25. #define ARIZONA_AIF_FORMAT 0x04
  26. #define ARIZONA_AIF_TX_BCLK_RATE 0x05
  27. #define ARIZONA_AIF_RX_BCLK_RATE 0x06
  28. #define ARIZONA_AIF_FRAME_CTRL_1 0x07
  29. #define ARIZONA_AIF_FRAME_CTRL_2 0x08
  30. #define ARIZONA_AIF_FRAME_CTRL_3 0x09
  31. #define ARIZONA_AIF_FRAME_CTRL_4 0x0A
  32. #define ARIZONA_AIF_FRAME_CTRL_5 0x0B
  33. #define ARIZONA_AIF_FRAME_CTRL_6 0x0C
  34. #define ARIZONA_AIF_FRAME_CTRL_7 0x0D
  35. #define ARIZONA_AIF_FRAME_CTRL_8 0x0E
  36. #define ARIZONA_AIF_FRAME_CTRL_9 0x0F
  37. #define ARIZONA_AIF_FRAME_CTRL_10 0x10
  38. #define ARIZONA_AIF_FRAME_CTRL_11 0x11
  39. #define ARIZONA_AIF_FRAME_CTRL_12 0x12
  40. #define ARIZONA_AIF_FRAME_CTRL_13 0x13
  41. #define ARIZONA_AIF_FRAME_CTRL_14 0x14
  42. #define ARIZONA_AIF_FRAME_CTRL_15 0x15
  43. #define ARIZONA_AIF_FRAME_CTRL_16 0x16
  44. #define ARIZONA_AIF_FRAME_CTRL_17 0x17
  45. #define ARIZONA_AIF_FRAME_CTRL_18 0x18
  46. #define ARIZONA_AIF_TX_ENABLES 0x19
  47. #define ARIZONA_AIF_RX_ENABLES 0x1A
  48. #define ARIZONA_AIF_FORCE_WRITE 0x1B
  49. #define arizona_fll_err(_fll, fmt, ...) \
  50. dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  51. #define arizona_fll_warn(_fll, fmt, ...) \
  52. dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  53. #define arizona_fll_dbg(_fll, fmt, ...) \
  54. dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  55. #define arizona_aif_err(_dai, fmt, ...) \
  56. dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  57. #define arizona_aif_warn(_dai, fmt, ...) \
  58. dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  59. #define arizona_aif_dbg(_dai, fmt, ...) \
  60. dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  61. const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
  62. "None",
  63. "Tone Generator 1",
  64. "Tone Generator 2",
  65. "Haptics",
  66. "AEC",
  67. "Mic Mute Mixer",
  68. "Noise Generator",
  69. "IN1L",
  70. "IN1R",
  71. "IN2L",
  72. "IN2R",
  73. "IN3L",
  74. "IN3R",
  75. "IN4L",
  76. "IN4R",
  77. "AIF1RX1",
  78. "AIF1RX2",
  79. "AIF1RX3",
  80. "AIF1RX4",
  81. "AIF1RX5",
  82. "AIF1RX6",
  83. "AIF1RX7",
  84. "AIF1RX8",
  85. "AIF2RX1",
  86. "AIF2RX2",
  87. "AIF3RX1",
  88. "AIF3RX2",
  89. "SLIMRX1",
  90. "SLIMRX2",
  91. "SLIMRX3",
  92. "SLIMRX4",
  93. "SLIMRX5",
  94. "SLIMRX6",
  95. "SLIMRX7",
  96. "SLIMRX8",
  97. "EQ1",
  98. "EQ2",
  99. "EQ3",
  100. "EQ4",
  101. "DRC1L",
  102. "DRC1R",
  103. "DRC2L",
  104. "DRC2R",
  105. "LHPF1",
  106. "LHPF2",
  107. "LHPF3",
  108. "LHPF4",
  109. "DSP1.1",
  110. "DSP1.2",
  111. "DSP1.3",
  112. "DSP1.4",
  113. "DSP1.5",
  114. "DSP1.6",
  115. "ASRC1L",
  116. "ASRC1R",
  117. "ASRC2L",
  118. "ASRC2R",
  119. };
  120. EXPORT_SYMBOL_GPL(arizona_mixer_texts);
  121. int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
  122. 0x00, /* None */
  123. 0x04, /* Tone */
  124. 0x05,
  125. 0x06, /* Haptics */
  126. 0x08, /* AEC */
  127. 0x0c, /* Noise mixer */
  128. 0x0d, /* Comfort noise */
  129. 0x10, /* IN1L */
  130. 0x11,
  131. 0x12,
  132. 0x13,
  133. 0x14,
  134. 0x15,
  135. 0x16,
  136. 0x17,
  137. 0x20, /* AIF1RX1 */
  138. 0x21,
  139. 0x22,
  140. 0x23,
  141. 0x24,
  142. 0x25,
  143. 0x26,
  144. 0x27,
  145. 0x28, /* AIF2RX1 */
  146. 0x29,
  147. 0x30, /* AIF3RX1 */
  148. 0x31,
  149. 0x38, /* SLIMRX1 */
  150. 0x39,
  151. 0x3a,
  152. 0x3b,
  153. 0x3c,
  154. 0x3d,
  155. 0x3e,
  156. 0x3f,
  157. 0x50, /* EQ1 */
  158. 0x51,
  159. 0x52,
  160. 0x53,
  161. 0x58, /* DRC1L */
  162. 0x59,
  163. 0x5a,
  164. 0x5b,
  165. 0x60, /* LHPF1 */
  166. 0x61,
  167. 0x62,
  168. 0x63,
  169. 0x68, /* DSP1.1 */
  170. 0x69,
  171. 0x6a,
  172. 0x6b,
  173. 0x6c,
  174. 0x6d,
  175. 0x90, /* ASRC1L */
  176. 0x91,
  177. 0x92,
  178. 0x93,
  179. };
  180. EXPORT_SYMBOL_GPL(arizona_mixer_values);
  181. const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
  182. EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
  183. static const char *arizona_lhpf_mode_text[] = {
  184. "Low-pass", "High-pass"
  185. };
  186. const struct soc_enum arizona_lhpf1_mode =
  187. SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
  188. arizona_lhpf_mode_text);
  189. EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
  190. const struct soc_enum arizona_lhpf2_mode =
  191. SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
  192. arizona_lhpf_mode_text);
  193. EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
  194. const struct soc_enum arizona_lhpf3_mode =
  195. SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
  196. arizona_lhpf_mode_text);
  197. EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
  198. const struct soc_enum arizona_lhpf4_mode =
  199. SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
  200. arizona_lhpf_mode_text);
  201. EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
  202. int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
  203. int event)
  204. {
  205. return 0;
  206. }
  207. EXPORT_SYMBOL_GPL(arizona_in_ev);
  208. int arizona_out_ev(struct snd_soc_dapm_widget *w,
  209. struct snd_kcontrol *kcontrol,
  210. int event)
  211. {
  212. return 0;
  213. }
  214. EXPORT_SYMBOL_GPL(arizona_out_ev);
  215. int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
  216. int source, unsigned int freq, int dir)
  217. {
  218. struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
  219. struct arizona *arizona = priv->arizona;
  220. char *name;
  221. unsigned int reg;
  222. unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
  223. unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
  224. unsigned int *clk;
  225. switch (clk_id) {
  226. case ARIZONA_CLK_SYSCLK:
  227. name = "SYSCLK";
  228. reg = ARIZONA_SYSTEM_CLOCK_1;
  229. clk = &priv->sysclk;
  230. mask |= ARIZONA_SYSCLK_FRAC;
  231. break;
  232. case ARIZONA_CLK_ASYNCCLK:
  233. name = "ASYNCCLK";
  234. reg = ARIZONA_ASYNC_CLOCK_1;
  235. clk = &priv->asyncclk;
  236. break;
  237. default:
  238. return -EINVAL;
  239. }
  240. switch (freq) {
  241. case 5644800:
  242. case 6144000:
  243. break;
  244. case 11289600:
  245. case 12288000:
  246. val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
  247. break;
  248. case 22579200:
  249. case 24576000:
  250. val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
  251. break;
  252. case 45158400:
  253. case 49152000:
  254. val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
  255. break;
  256. default:
  257. return -EINVAL;
  258. }
  259. *clk = freq;
  260. if (freq % 6144000)
  261. val |= ARIZONA_SYSCLK_FRAC;
  262. dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
  263. return regmap_update_bits(arizona->regmap, reg, mask, val);
  264. }
  265. EXPORT_SYMBOL_GPL(arizona_set_sysclk);
  266. static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  267. {
  268. struct snd_soc_codec *codec = dai->codec;
  269. int lrclk, bclk, mode, base;
  270. base = dai->driver->base;
  271. lrclk = 0;
  272. bclk = 0;
  273. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  274. case SND_SOC_DAIFMT_DSP_A:
  275. mode = 0;
  276. break;
  277. case SND_SOC_DAIFMT_DSP_B:
  278. mode = 1;
  279. break;
  280. case SND_SOC_DAIFMT_I2S:
  281. mode = 2;
  282. break;
  283. case SND_SOC_DAIFMT_LEFT_J:
  284. mode = 3;
  285. break;
  286. default:
  287. arizona_aif_err(dai, "Unsupported DAI format %d\n",
  288. fmt & SND_SOC_DAIFMT_FORMAT_MASK);
  289. return -EINVAL;
  290. }
  291. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  292. case SND_SOC_DAIFMT_CBS_CFS:
  293. break;
  294. case SND_SOC_DAIFMT_CBS_CFM:
  295. lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
  296. break;
  297. case SND_SOC_DAIFMT_CBM_CFS:
  298. bclk |= ARIZONA_AIF1_BCLK_MSTR;
  299. break;
  300. case SND_SOC_DAIFMT_CBM_CFM:
  301. bclk |= ARIZONA_AIF1_BCLK_MSTR;
  302. lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
  303. break;
  304. default:
  305. arizona_aif_err(dai, "Unsupported master mode %d\n",
  306. fmt & SND_SOC_DAIFMT_MASTER_MASK);
  307. return -EINVAL;
  308. }
  309. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  310. case SND_SOC_DAIFMT_NB_NF:
  311. break;
  312. case SND_SOC_DAIFMT_IB_IF:
  313. bclk |= ARIZONA_AIF1_BCLK_INV;
  314. lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
  315. break;
  316. case SND_SOC_DAIFMT_IB_NF:
  317. bclk |= ARIZONA_AIF1_BCLK_INV;
  318. break;
  319. case SND_SOC_DAIFMT_NB_IF:
  320. lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
  321. break;
  322. default:
  323. return -EINVAL;
  324. }
  325. snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
  326. ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
  327. bclk);
  328. snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
  329. ARIZONA_AIF1TX_LRCLK_INV |
  330. ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
  331. snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
  332. ARIZONA_AIF1RX_LRCLK_INV |
  333. ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
  334. snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
  335. ARIZONA_AIF1_FMT_MASK, mode);
  336. return 0;
  337. }
  338. static const int arizona_48k_bclk_rates[] = {
  339. -1,
  340. 48000,
  341. 64000,
  342. 96000,
  343. 128000,
  344. 192000,
  345. 256000,
  346. 384000,
  347. 512000,
  348. 768000,
  349. 1024000,
  350. 1536000,
  351. 2048000,
  352. 3072000,
  353. 4096000,
  354. 6144000,
  355. 8192000,
  356. 12288000,
  357. 24576000,
  358. };
  359. static const unsigned int arizona_48k_rates[] = {
  360. 12000,
  361. 24000,
  362. 48000,
  363. 96000,
  364. 192000,
  365. 384000,
  366. 768000,
  367. 4000,
  368. 8000,
  369. 16000,
  370. 32000,
  371. 64000,
  372. 128000,
  373. 256000,
  374. 512000,
  375. };
  376. static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
  377. .count = ARRAY_SIZE(arizona_48k_rates),
  378. .list = arizona_48k_rates,
  379. };
  380. static const int arizona_44k1_bclk_rates[] = {
  381. -1,
  382. 44100,
  383. 58800,
  384. 88200,
  385. 117600,
  386. 177640,
  387. 235200,
  388. 352800,
  389. 470400,
  390. 705600,
  391. 940800,
  392. 1411200,
  393. 1881600,
  394. 2882400,
  395. 3763200,
  396. 5644800,
  397. 7526400,
  398. 11289600,
  399. 22579200,
  400. };
  401. static const unsigned int arizona_44k1_rates[] = {
  402. 11025,
  403. 22050,
  404. 44100,
  405. 88200,
  406. 176400,
  407. 352800,
  408. 705600,
  409. };
  410. static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
  411. .count = ARRAY_SIZE(arizona_44k1_rates),
  412. .list = arizona_44k1_rates,
  413. };
  414. static int arizona_sr_vals[] = {
  415. 0,
  416. 12000,
  417. 24000,
  418. 48000,
  419. 96000,
  420. 192000,
  421. 384000,
  422. 768000,
  423. 0,
  424. 11025,
  425. 22050,
  426. 44100,
  427. 88200,
  428. 176400,
  429. 352800,
  430. 705600,
  431. 4000,
  432. 8000,
  433. 16000,
  434. 32000,
  435. 64000,
  436. 128000,
  437. 256000,
  438. 512000,
  439. };
  440. static int arizona_startup(struct snd_pcm_substream *substream,
  441. struct snd_soc_dai *dai)
  442. {
  443. struct snd_soc_codec *codec = dai->codec;
  444. struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
  445. struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
  446. const struct snd_pcm_hw_constraint_list *constraint;
  447. unsigned int base_rate;
  448. switch (dai_priv->clk) {
  449. case ARIZONA_CLK_SYSCLK:
  450. base_rate = priv->sysclk;
  451. break;
  452. case ARIZONA_CLK_ASYNCCLK:
  453. base_rate = priv->asyncclk;
  454. break;
  455. default:
  456. return 0;
  457. }
  458. if (base_rate % 8000)
  459. constraint = &arizona_44k1_constraint;
  460. else
  461. constraint = &arizona_48k_constraint;
  462. return snd_pcm_hw_constraint_list(substream->runtime, 0,
  463. SNDRV_PCM_HW_PARAM_RATE,
  464. constraint);
  465. }
  466. static int arizona_hw_params(struct snd_pcm_substream *substream,
  467. struct snd_pcm_hw_params *params,
  468. struct snd_soc_dai *dai)
  469. {
  470. struct snd_soc_codec *codec = dai->codec;
  471. struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
  472. struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
  473. int base = dai->driver->base;
  474. const int *rates;
  475. int i;
  476. int bclk, lrclk, wl, frame, sr_val;
  477. if (params_rate(params) % 8000)
  478. rates = &arizona_44k1_bclk_rates[0];
  479. else
  480. rates = &arizona_48k_bclk_rates[0];
  481. for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
  482. if (rates[i] >= snd_soc_params_to_bclk(params) &&
  483. rates[i] % params_rate(params) == 0) {
  484. bclk = i;
  485. break;
  486. }
  487. }
  488. if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
  489. arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
  490. params_rate(params));
  491. return -EINVAL;
  492. }
  493. for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
  494. if (arizona_sr_vals[i] == params_rate(params))
  495. break;
  496. if (i == ARRAY_SIZE(arizona_sr_vals)) {
  497. arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
  498. params_rate(params));
  499. return -EINVAL;
  500. }
  501. sr_val = i;
  502. lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
  503. arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
  504. rates[bclk], rates[bclk] / lrclk);
  505. wl = snd_pcm_format_width(params_format(params));
  506. frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
  507. /*
  508. * We will need to be more flexible than this in future,
  509. * currently we use a single sample rate for SYSCLK.
  510. */
  511. switch (dai_priv->clk) {
  512. case ARIZONA_CLK_SYSCLK:
  513. snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
  514. ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
  515. snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
  516. ARIZONA_AIF1_RATE_MASK, 0);
  517. break;
  518. case ARIZONA_CLK_ASYNCCLK:
  519. snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
  520. ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
  521. snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
  522. ARIZONA_AIF1_RATE_MASK, 8);
  523. break;
  524. default:
  525. arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
  526. return -EINVAL;
  527. }
  528. snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
  529. ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
  530. snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
  531. ARIZONA_AIF1TX_BCPF_MASK, lrclk);
  532. snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
  533. ARIZONA_AIF1RX_BCPF_MASK, lrclk);
  534. snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
  535. ARIZONA_AIF1TX_WL_MASK |
  536. ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
  537. snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
  538. ARIZONA_AIF1RX_WL_MASK |
  539. ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
  540. return 0;
  541. }
  542. static const char *arizona_dai_clk_str(int clk_id)
  543. {
  544. switch (clk_id) {
  545. case ARIZONA_CLK_SYSCLK:
  546. return "SYSCLK";
  547. case ARIZONA_CLK_ASYNCCLK:
  548. return "ASYNCCLK";
  549. default:
  550. return "Unknown clock";
  551. }
  552. }
  553. static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
  554. int clk_id, unsigned int freq, int dir)
  555. {
  556. struct snd_soc_codec *codec = dai->codec;
  557. struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
  558. struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
  559. struct snd_soc_dapm_route routes[2];
  560. switch (clk_id) {
  561. case ARIZONA_CLK_SYSCLK:
  562. case ARIZONA_CLK_ASYNCCLK:
  563. break;
  564. default:
  565. return -EINVAL;
  566. }
  567. if (clk_id == dai_priv->clk)
  568. return 0;
  569. if (dai->active) {
  570. dev_err(codec->dev, "Can't change clock on active DAI %d\n",
  571. dai->id);
  572. return -EBUSY;
  573. }
  574. memset(&routes, 0, sizeof(routes));
  575. routes[0].sink = dai->driver->capture.stream_name;
  576. routes[1].sink = dai->driver->playback.stream_name;
  577. routes[0].source = arizona_dai_clk_str(dai_priv->clk);
  578. routes[1].source = arizona_dai_clk_str(dai_priv->clk);
  579. snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
  580. routes[0].source = arizona_dai_clk_str(clk_id);
  581. routes[1].source = arizona_dai_clk_str(clk_id);
  582. snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
  583. return snd_soc_dapm_sync(&codec->dapm);
  584. }
  585. const struct snd_soc_dai_ops arizona_dai_ops = {
  586. .startup = arizona_startup,
  587. .set_fmt = arizona_set_fmt,
  588. .hw_params = arizona_hw_params,
  589. .set_sysclk = arizona_dai_set_sysclk,
  590. };
  591. EXPORT_SYMBOL_GPL(arizona_dai_ops);
  592. int arizona_init_dai(struct arizona_priv *priv, int id)
  593. {
  594. struct arizona_dai_priv *dai_priv = &priv->dai[id];
  595. dai_priv->clk = ARIZONA_CLK_SYSCLK;
  596. return 0;
  597. }
  598. EXPORT_SYMBOL_GPL(arizona_init_dai);
  599. static irqreturn_t arizona_fll_lock(int irq, void *data)
  600. {
  601. struct arizona_fll *fll = data;
  602. arizona_fll_dbg(fll, "Locked\n");
  603. complete(&fll->lock);
  604. return IRQ_HANDLED;
  605. }
  606. static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
  607. {
  608. struct arizona_fll *fll = data;
  609. arizona_fll_dbg(fll, "clock OK\n");
  610. complete(&fll->ok);
  611. return IRQ_HANDLED;
  612. }
  613. static struct {
  614. unsigned int min;
  615. unsigned int max;
  616. u16 fratio;
  617. int ratio;
  618. } fll_fratios[] = {
  619. { 0, 64000, 4, 16 },
  620. { 64000, 128000, 3, 8 },
  621. { 128000, 256000, 2, 4 },
  622. { 256000, 1000000, 1, 2 },
  623. { 1000000, 13500000, 0, 1 },
  624. };
  625. struct arizona_fll_cfg {
  626. int n;
  627. int theta;
  628. int lambda;
  629. int refdiv;
  630. int outdiv;
  631. int fratio;
  632. };
  633. static int arizona_calc_fll(struct arizona_fll *fll,
  634. struct arizona_fll_cfg *cfg,
  635. unsigned int Fref,
  636. unsigned int Fout)
  637. {
  638. unsigned int target, div, gcd_fll;
  639. int i, ratio;
  640. arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
  641. /* Fref must be <=13.5MHz */
  642. div = 1;
  643. cfg->refdiv = 0;
  644. while ((Fref / div) > 13500000) {
  645. div *= 2;
  646. cfg->refdiv++;
  647. if (div > 8) {
  648. arizona_fll_err(fll,
  649. "Can't scale %dMHz in to <=13.5MHz\n",
  650. Fref);
  651. return -EINVAL;
  652. }
  653. }
  654. /* Apply the division for our remaining calculations */
  655. Fref /= div;
  656. /* Fvco should be over the targt; don't check the upper bound */
  657. div = 1;
  658. while (Fout * div < 90000000 * fll->vco_mult) {
  659. div++;
  660. if (div > 7) {
  661. arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
  662. Fout);
  663. return -EINVAL;
  664. }
  665. }
  666. target = Fout * div / fll->vco_mult;
  667. cfg->outdiv = div;
  668. arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
  669. /* Find an appropraite FLL_FRATIO and factor it out of the target */
  670. for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
  671. if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
  672. cfg->fratio = fll_fratios[i].fratio;
  673. ratio = fll_fratios[i].ratio;
  674. break;
  675. }
  676. }
  677. if (i == ARRAY_SIZE(fll_fratios)) {
  678. arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
  679. Fref);
  680. return -EINVAL;
  681. }
  682. cfg->n = target / (ratio * Fref);
  683. if (target % Fref) {
  684. gcd_fll = gcd(target, ratio * Fref);
  685. arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
  686. cfg->theta = (target - (cfg->n * ratio * Fref))
  687. / gcd_fll;
  688. cfg->lambda = (ratio * Fref) / gcd_fll;
  689. } else {
  690. cfg->theta = 0;
  691. cfg->lambda = 0;
  692. }
  693. arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
  694. cfg->n, cfg->theta, cfg->lambda);
  695. arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
  696. cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
  697. return 0;
  698. }
  699. static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
  700. struct arizona_fll_cfg *cfg, int source)
  701. {
  702. regmap_update_bits(arizona->regmap, base + 3,
  703. ARIZONA_FLL1_THETA_MASK, cfg->theta);
  704. regmap_update_bits(arizona->regmap, base + 4,
  705. ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
  706. regmap_update_bits(arizona->regmap, base + 5,
  707. ARIZONA_FLL1_FRATIO_MASK,
  708. cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
  709. regmap_update_bits(arizona->regmap, base + 6,
  710. ARIZONA_FLL1_CLK_REF_DIV_MASK |
  711. ARIZONA_FLL1_CLK_REF_SRC_MASK,
  712. cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
  713. source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
  714. regmap_update_bits(arizona->regmap, base + 2,
  715. ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
  716. ARIZONA_FLL1_CTRL_UPD | cfg->n);
  717. }
  718. int arizona_set_fll(struct arizona_fll *fll, int source,
  719. unsigned int Fref, unsigned int Fout)
  720. {
  721. struct arizona *arizona = fll->arizona;
  722. struct arizona_fll_cfg cfg, sync;
  723. unsigned int reg, val;
  724. int syncsrc;
  725. bool ena;
  726. int ret;
  727. ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
  728. if (ret != 0) {
  729. arizona_fll_err(fll, "Failed to read current state: %d\n",
  730. ret);
  731. return ret;
  732. }
  733. ena = reg & ARIZONA_FLL1_ENA;
  734. if (Fout) {
  735. /* Do we have a 32kHz reference? */
  736. regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
  737. switch (val & ARIZONA_CLK_32K_SRC_MASK) {
  738. case ARIZONA_CLK_SRC_MCLK1:
  739. case ARIZONA_CLK_SRC_MCLK2:
  740. syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
  741. break;
  742. default:
  743. syncsrc = -1;
  744. }
  745. if (source == syncsrc)
  746. syncsrc = -1;
  747. if (syncsrc >= 0) {
  748. ret = arizona_calc_fll(fll, &sync, Fref, Fout);
  749. if (ret != 0)
  750. return ret;
  751. ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
  752. if (ret != 0)
  753. return ret;
  754. } else {
  755. ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
  756. if (ret != 0)
  757. return ret;
  758. }
  759. } else {
  760. regmap_update_bits(arizona->regmap, fll->base + 1,
  761. ARIZONA_FLL1_ENA, 0);
  762. regmap_update_bits(arizona->regmap, fll->base + 0x11,
  763. ARIZONA_FLL1_SYNC_ENA, 0);
  764. if (ena)
  765. pm_runtime_put_autosuspend(arizona->dev);
  766. return 0;
  767. }
  768. regmap_update_bits(arizona->regmap, fll->base + 5,
  769. ARIZONA_FLL1_OUTDIV_MASK,
  770. cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
  771. if (syncsrc >= 0) {
  772. arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
  773. arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
  774. } else {
  775. arizona_apply_fll(arizona, fll->base, &cfg, source);
  776. }
  777. if (!ena)
  778. pm_runtime_get(arizona->dev);
  779. /* Clear any pending completions */
  780. try_wait_for_completion(&fll->ok);
  781. regmap_update_bits(arizona->regmap, fll->base + 1,
  782. ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
  783. if (syncsrc >= 0)
  784. regmap_update_bits(arizona->regmap, fll->base + 0x11,
  785. ARIZONA_FLL1_SYNC_ENA,
  786. ARIZONA_FLL1_SYNC_ENA);
  787. ret = wait_for_completion_timeout(&fll->ok,
  788. msecs_to_jiffies(25));
  789. if (ret == 0)
  790. arizona_fll_warn(fll, "Timed out waiting for lock\n");
  791. return 0;
  792. }
  793. EXPORT_SYMBOL_GPL(arizona_set_fll);
  794. int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
  795. int ok_irq, struct arizona_fll *fll)
  796. {
  797. int ret;
  798. init_completion(&fll->lock);
  799. init_completion(&fll->ok);
  800. fll->id = id;
  801. fll->base = base;
  802. fll->arizona = arizona;
  803. snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
  804. snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
  805. "FLL%d clock OK", id);
  806. ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
  807. arizona_fll_lock, fll);
  808. if (ret != 0) {
  809. dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
  810. id, ret);
  811. }
  812. ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
  813. arizona_fll_clock_ok, fll);
  814. if (ret != 0) {
  815. dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
  816. id, ret);
  817. }
  818. return 0;
  819. }
  820. EXPORT_SYMBOL_GPL(arizona_init_fll);
  821. MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
  822. MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
  823. MODULE_LICENSE("GPL");