axg-tdm-formatter.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // SPDX-License-Identifier: (GPL-2.0 OR MIT)
  2. //
  3. // Copyright (c) 2018 BayLibre, SAS.
  4. // Author: Jerome Brunet <jbrunet@baylibre.com>
  5. #include <linux/clk.h>
  6. #include <linux/module.h>
  7. #include <linux/of_platform.h>
  8. #include <linux/regmap.h>
  9. #include <sound/soc.h>
  10. #include "axg-tdm-formatter.h"
  11. struct axg_tdm_formatter {
  12. struct list_head list;
  13. struct axg_tdm_stream *stream;
  14. const struct axg_tdm_formatter_driver *drv;
  15. struct clk *pclk;
  16. struct clk *sclk;
  17. struct clk *lrclk;
  18. struct clk *sclk_sel;
  19. struct clk *lrclk_sel;
  20. bool enabled;
  21. struct regmap *map;
  22. };
  23. int axg_tdm_formatter_set_channel_masks(struct regmap *map,
  24. struct axg_tdm_stream *ts,
  25. unsigned int offset)
  26. {
  27. unsigned int val, ch = ts->channels;
  28. unsigned long mask;
  29. int i, j;
  30. /*
  31. * Distribute the channels of the stream over the available slots
  32. * of each TDM lane
  33. */
  34. for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
  35. val = 0;
  36. mask = ts->mask[i];
  37. for (j = find_first_bit(&mask, 32);
  38. (j < 32) && ch;
  39. j = find_next_bit(&mask, 32, j + 1)) {
  40. val |= 1 << j;
  41. ch -= 1;
  42. }
  43. regmap_write(map, offset, val);
  44. offset += regmap_get_reg_stride(map);
  45. }
  46. /*
  47. * If we still have channel left at the end of the process, it means
  48. * the stream has more channels than we can accommodate and we should
  49. * have caught this earlier.
  50. */
  51. if (WARN_ON(ch != 0)) {
  52. pr_err("channel mask error\n");
  53. return -EINVAL;
  54. }
  55. return 0;
  56. }
  57. EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
  58. static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
  59. {
  60. struct axg_tdm_stream *ts = formatter->stream;
  61. bool invert = formatter->drv->invert_sclk;
  62. int ret;
  63. /* Do nothing if the formatter is already enabled */
  64. if (formatter->enabled)
  65. return 0;
  66. /*
  67. * If sclk is inverted, invert it back and provide the inversion
  68. * required by the formatter
  69. */
  70. invert ^= axg_tdm_sclk_invert(ts->iface->fmt);
  71. ret = clk_set_phase(formatter->sclk, invert ? 180 : 0);
  72. if (ret)
  73. return ret;
  74. /* Setup the stream parameter in the formatter */
  75. ret = formatter->drv->ops->prepare(formatter->map, formatter->stream);
  76. if (ret)
  77. return ret;
  78. /* Enable the signal clocks feeding the formatter */
  79. ret = clk_prepare_enable(formatter->sclk);
  80. if (ret)
  81. return ret;
  82. ret = clk_prepare_enable(formatter->lrclk);
  83. if (ret) {
  84. clk_disable_unprepare(formatter->sclk);
  85. return ret;
  86. }
  87. /* Finally, actually enable the formatter */
  88. formatter->drv->ops->enable(formatter->map);
  89. formatter->enabled = true;
  90. return 0;
  91. }
  92. static void axg_tdm_formatter_disable(struct axg_tdm_formatter *formatter)
  93. {
  94. /* Do nothing if the formatter is already disabled */
  95. if (!formatter->enabled)
  96. return;
  97. formatter->drv->ops->disable(formatter->map);
  98. clk_disable_unprepare(formatter->lrclk);
  99. clk_disable_unprepare(formatter->sclk);
  100. formatter->enabled = false;
  101. }
  102. static int axg_tdm_formatter_attach(struct axg_tdm_formatter *formatter)
  103. {
  104. struct axg_tdm_stream *ts = formatter->stream;
  105. int ret = 0;
  106. mutex_lock(&ts->lock);
  107. /* Catch up if the stream is already running when we attach */
  108. if (ts->ready) {
  109. ret = axg_tdm_formatter_enable(formatter);
  110. if (ret) {
  111. pr_err("failed to enable formatter\n");
  112. goto out;
  113. }
  114. }
  115. list_add_tail(&formatter->list, &ts->formatter_list);
  116. out:
  117. mutex_unlock(&ts->lock);
  118. return ret;
  119. }
  120. static void axg_tdm_formatter_dettach(struct axg_tdm_formatter *formatter)
  121. {
  122. struct axg_tdm_stream *ts = formatter->stream;
  123. mutex_lock(&ts->lock);
  124. list_del(&formatter->list);
  125. mutex_unlock(&ts->lock);
  126. axg_tdm_formatter_disable(formatter);
  127. }
  128. static int axg_tdm_formatter_power_up(struct axg_tdm_formatter *formatter,
  129. struct snd_soc_dapm_widget *w)
  130. {
  131. struct axg_tdm_stream *ts = formatter->drv->ops->get_stream(w);
  132. int ret;
  133. /*
  134. * If we don't get a stream at this stage, it would mean that the
  135. * widget is powering up but is not attached to any backend DAI.
  136. * It should not happen, ever !
  137. */
  138. if (WARN_ON(!ts))
  139. return -ENODEV;
  140. /* Clock our device */
  141. ret = clk_prepare_enable(formatter->pclk);
  142. if (ret)
  143. return ret;
  144. /* Reparent the bit clock to the TDM interface */
  145. ret = clk_set_parent(formatter->sclk_sel, ts->iface->sclk);
  146. if (ret)
  147. goto disable_pclk;
  148. /* Reparent the sample clock to the TDM interface */
  149. ret = clk_set_parent(formatter->lrclk_sel, ts->iface->lrclk);
  150. if (ret)
  151. goto disable_pclk;
  152. formatter->stream = ts;
  153. ret = axg_tdm_formatter_attach(formatter);
  154. if (ret)
  155. goto disable_pclk;
  156. return 0;
  157. disable_pclk:
  158. clk_disable_unprepare(formatter->pclk);
  159. return ret;
  160. }
  161. static void axg_tdm_formatter_power_down(struct axg_tdm_formatter *formatter)
  162. {
  163. axg_tdm_formatter_dettach(formatter);
  164. clk_disable_unprepare(formatter->pclk);
  165. formatter->stream = NULL;
  166. }
  167. int axg_tdm_formatter_event(struct snd_soc_dapm_widget *w,
  168. struct snd_kcontrol *control,
  169. int event)
  170. {
  171. struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
  172. struct axg_tdm_formatter *formatter = snd_soc_component_get_drvdata(c);
  173. int ret = 0;
  174. switch (event) {
  175. case SND_SOC_DAPM_PRE_PMU:
  176. ret = axg_tdm_formatter_power_up(formatter, w);
  177. break;
  178. case SND_SOC_DAPM_PRE_PMD:
  179. axg_tdm_formatter_power_down(formatter);
  180. break;
  181. default:
  182. dev_err(c->dev, "Unexpected event %d\n", event);
  183. return -EINVAL;
  184. }
  185. return ret;
  186. }
  187. EXPORT_SYMBOL_GPL(axg_tdm_formatter_event);
  188. int axg_tdm_formatter_probe(struct platform_device *pdev)
  189. {
  190. struct device *dev = &pdev->dev;
  191. const struct axg_tdm_formatter_driver *drv;
  192. struct axg_tdm_formatter *formatter;
  193. struct resource *res;
  194. void __iomem *regs;
  195. int ret;
  196. drv = of_device_get_match_data(dev);
  197. if (!drv) {
  198. dev_err(dev, "failed to match device\n");
  199. return -ENODEV;
  200. }
  201. formatter = devm_kzalloc(dev, sizeof(*formatter), GFP_KERNEL);
  202. if (!formatter)
  203. return -ENOMEM;
  204. platform_set_drvdata(pdev, formatter);
  205. formatter->drv = drv;
  206. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  207. regs = devm_ioremap_resource(dev, res);
  208. if (IS_ERR(regs))
  209. return PTR_ERR(regs);
  210. formatter->map = devm_regmap_init_mmio(dev, regs, drv->regmap_cfg);
  211. if (IS_ERR(formatter->map)) {
  212. dev_err(dev, "failed to init regmap: %ld\n",
  213. PTR_ERR(formatter->map));
  214. return PTR_ERR(formatter->map);
  215. }
  216. /* Peripharal clock */
  217. formatter->pclk = devm_clk_get(dev, "pclk");
  218. if (IS_ERR(formatter->pclk)) {
  219. ret = PTR_ERR(formatter->pclk);
  220. if (ret != -EPROBE_DEFER)
  221. dev_err(dev, "failed to get pclk: %d\n", ret);
  222. return ret;
  223. }
  224. /* Formatter bit clock */
  225. formatter->sclk = devm_clk_get(dev, "sclk");
  226. if (IS_ERR(formatter->sclk)) {
  227. ret = PTR_ERR(formatter->sclk);
  228. if (ret != -EPROBE_DEFER)
  229. dev_err(dev, "failed to get sclk: %d\n", ret);
  230. return ret;
  231. }
  232. /* Formatter sample clock */
  233. formatter->lrclk = devm_clk_get(dev, "lrclk");
  234. if (IS_ERR(formatter->lrclk)) {
  235. ret = PTR_ERR(formatter->lrclk);
  236. if (ret != -EPROBE_DEFER)
  237. dev_err(dev, "failed to get lrclk: %d\n", ret);
  238. return ret;
  239. }
  240. /* Formatter bit clock input multiplexer */
  241. formatter->sclk_sel = devm_clk_get(dev, "sclk_sel");
  242. if (IS_ERR(formatter->sclk_sel)) {
  243. ret = PTR_ERR(formatter->sclk_sel);
  244. if (ret != -EPROBE_DEFER)
  245. dev_err(dev, "failed to get sclk_sel: %d\n", ret);
  246. return ret;
  247. }
  248. /* Formatter sample clock input multiplexer */
  249. formatter->lrclk_sel = devm_clk_get(dev, "lrclk_sel");
  250. if (IS_ERR(formatter->lrclk_sel)) {
  251. ret = PTR_ERR(formatter->lrclk_sel);
  252. if (ret != -EPROBE_DEFER)
  253. dev_err(dev, "failed to get lrclk_sel: %d\n", ret);
  254. return ret;
  255. }
  256. return devm_snd_soc_register_component(dev, drv->component_drv,
  257. NULL, 0);
  258. }
  259. EXPORT_SYMBOL_GPL(axg_tdm_formatter_probe);
  260. int axg_tdm_stream_start(struct axg_tdm_stream *ts)
  261. {
  262. struct axg_tdm_formatter *formatter;
  263. int ret = 0;
  264. mutex_lock(&ts->lock);
  265. ts->ready = true;
  266. /* Start all the formatters attached to the stream */
  267. list_for_each_entry(formatter, &ts->formatter_list, list) {
  268. ret = axg_tdm_formatter_enable(formatter);
  269. if (ret) {
  270. pr_err("failed to start tdm stream\n");
  271. goto out;
  272. }
  273. }
  274. out:
  275. mutex_unlock(&ts->lock);
  276. return ret;
  277. }
  278. EXPORT_SYMBOL_GPL(axg_tdm_stream_start);
  279. void axg_tdm_stream_stop(struct axg_tdm_stream *ts)
  280. {
  281. struct axg_tdm_formatter *formatter;
  282. mutex_lock(&ts->lock);
  283. ts->ready = false;
  284. /* Stop all the formatters attached to the stream */
  285. list_for_each_entry(formatter, &ts->formatter_list, list) {
  286. axg_tdm_formatter_disable(formatter);
  287. }
  288. mutex_unlock(&ts->lock);
  289. }
  290. EXPORT_SYMBOL_GPL(axg_tdm_stream_stop);
  291. struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface)
  292. {
  293. struct axg_tdm_stream *ts;
  294. ts = kzalloc(sizeof(*ts), GFP_KERNEL);
  295. if (ts) {
  296. INIT_LIST_HEAD(&ts->formatter_list);
  297. mutex_init(&ts->lock);
  298. ts->iface = iface;
  299. }
  300. return ts;
  301. }
  302. EXPORT_SYMBOL_GPL(axg_tdm_stream_alloc);
  303. void axg_tdm_stream_free(struct axg_tdm_stream *ts)
  304. {
  305. /*
  306. * If the list is not empty, it would mean that one of the formatter
  307. * widget is still powered and attached to the interface while we
  308. * we are removing the TDM DAI. It should not be possible
  309. */
  310. WARN_ON(!list_empty(&ts->formatter_list));
  311. mutex_destroy(&ts->lock);
  312. kfree(ts);
  313. }
  314. EXPORT_SYMBOL_GPL(axg_tdm_stream_free);
  315. MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver");
  316. MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
  317. MODULE_LICENSE("GPL v2");