simple-card.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. * ASoC simple sound card support
  3. *
  4. * Copyright (C) 2012 Renesas Solutions Corp.
  5. * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/clk.h>
  12. #include <linux/device.h>
  13. #include <linux/gpio.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_gpio.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/string.h>
  19. #include <sound/jack.h>
  20. #include <sound/simple_card.h>
  21. #include <sound/soc-dai.h>
  22. #include <sound/soc.h>
  23. struct simple_card_data {
  24. struct snd_soc_card snd_card;
  25. struct simple_dai_props {
  26. struct asoc_simple_dai cpu_dai;
  27. struct asoc_simple_dai codec_dai;
  28. } *dai_props;
  29. unsigned int mclk_fs;
  30. int gpio_hp_det;
  31. int gpio_mic_det;
  32. struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
  33. };
  34. #define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
  35. #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
  36. #define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
  37. static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
  38. struct snd_pcm_hw_params *params)
  39. {
  40. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  41. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  42. struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
  43. unsigned int mclk;
  44. int ret = 0;
  45. if (priv->mclk_fs) {
  46. mclk = params_rate(params) * priv->mclk_fs;
  47. ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
  48. SND_SOC_CLOCK_IN);
  49. }
  50. return ret;
  51. }
  52. static struct snd_soc_ops asoc_simple_card_ops = {
  53. .hw_params = asoc_simple_card_hw_params,
  54. };
  55. static struct snd_soc_jack simple_card_hp_jack;
  56. static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = {
  57. {
  58. .pin = "Headphones",
  59. .mask = SND_JACK_HEADPHONE,
  60. },
  61. };
  62. static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = {
  63. .name = "Headphone detection",
  64. .report = SND_JACK_HEADPHONE,
  65. .debounce_time = 150,
  66. };
  67. static struct snd_soc_jack simple_card_mic_jack;
  68. static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = {
  69. {
  70. .pin = "Mic Jack",
  71. .mask = SND_JACK_MICROPHONE,
  72. },
  73. };
  74. static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = {
  75. .name = "Mic detection",
  76. .report = SND_JACK_MICROPHONE,
  77. .debounce_time = 150,
  78. };
  79. static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
  80. struct asoc_simple_dai *set)
  81. {
  82. int ret;
  83. if (set->fmt) {
  84. ret = snd_soc_dai_set_fmt(dai, set->fmt);
  85. if (ret && ret != -ENOTSUPP) {
  86. dev_err(dai->dev, "simple-card: set_fmt error\n");
  87. goto err;
  88. }
  89. }
  90. if (set->sysclk) {
  91. ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
  92. if (ret && ret != -ENOTSUPP) {
  93. dev_err(dai->dev, "simple-card: set_sysclk error\n");
  94. goto err;
  95. }
  96. }
  97. if (set->slots) {
  98. ret = snd_soc_dai_set_tdm_slot(dai, 0, 0,
  99. set->slots,
  100. set->slot_width);
  101. if (ret && ret != -ENOTSUPP) {
  102. dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
  103. goto err;
  104. }
  105. }
  106. ret = 0;
  107. err:
  108. return ret;
  109. }
  110. static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
  111. {
  112. struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
  113. struct snd_soc_dai *codec = rtd->codec_dai;
  114. struct snd_soc_dai *cpu = rtd->cpu_dai;
  115. struct simple_dai_props *dai_props;
  116. int num, ret;
  117. num = rtd - rtd->card->rtd;
  118. dai_props = &priv->dai_props[num];
  119. ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
  120. if (ret < 0)
  121. return ret;
  122. ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai);
  123. if (ret < 0)
  124. return ret;
  125. if (gpio_is_valid(priv->gpio_hp_det)) {
  126. snd_soc_jack_new(codec->codec, "Headphones", SND_JACK_HEADPHONE,
  127. &simple_card_hp_jack);
  128. snd_soc_jack_add_pins(&simple_card_hp_jack,
  129. ARRAY_SIZE(simple_card_hp_jack_pins),
  130. simple_card_hp_jack_pins);
  131. simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det;
  132. snd_soc_jack_add_gpios(&simple_card_hp_jack, 1,
  133. &simple_card_hp_jack_gpio);
  134. }
  135. if (gpio_is_valid(priv->gpio_mic_det)) {
  136. snd_soc_jack_new(codec->codec, "Mic Jack", SND_JACK_MICROPHONE,
  137. &simple_card_mic_jack);
  138. snd_soc_jack_add_pins(&simple_card_mic_jack,
  139. ARRAY_SIZE(simple_card_mic_jack_pins),
  140. simple_card_mic_jack_pins);
  141. simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det;
  142. snd_soc_jack_add_gpios(&simple_card_mic_jack, 1,
  143. &simple_card_mic_jack_gpio);
  144. }
  145. return 0;
  146. }
  147. static int
  148. asoc_simple_card_sub_parse_of(struct device_node *np,
  149. struct asoc_simple_dai *dai,
  150. struct device_node **p_node,
  151. const char **name,
  152. int *args_count)
  153. {
  154. struct of_phandle_args args;
  155. struct clk *clk;
  156. u32 val;
  157. int ret;
  158. /*
  159. * Get node via "sound-dai = <&phandle port>"
  160. * it will be used as xxx_of_node on soc_bind_dai_link()
  161. */
  162. ret = of_parse_phandle_with_args(np, "sound-dai",
  163. "#sound-dai-cells", 0, &args);
  164. if (ret)
  165. return ret;
  166. *p_node = args.np;
  167. if (args_count)
  168. *args_count = args.args_count;
  169. /* Get dai->name */
  170. ret = snd_soc_of_get_dai_name(np, name);
  171. if (ret < 0)
  172. return ret;
  173. /* Parse TDM slot */
  174. ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
  175. if (ret)
  176. return ret;
  177. /*
  178. * Parse dai->sysclk come from "clocks = <&xxx>"
  179. * (if system has common clock)
  180. * or "system-clock-frequency = <xxx>"
  181. * or device's module clock.
  182. */
  183. if (of_property_read_bool(np, "clocks")) {
  184. clk = of_clk_get(np, 0);
  185. if (IS_ERR(clk)) {
  186. ret = PTR_ERR(clk);
  187. return ret;
  188. }
  189. dai->sysclk = clk_get_rate(clk);
  190. } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
  191. dai->sysclk = val;
  192. } else {
  193. clk = of_clk_get(args.np, 0);
  194. if (!IS_ERR(clk))
  195. dai->sysclk = clk_get_rate(clk);
  196. }
  197. return 0;
  198. }
  199. static int asoc_simple_card_dai_link_of(struct device_node *node,
  200. struct simple_card_data *priv,
  201. int idx,
  202. bool is_top_level_node)
  203. {
  204. struct device *dev = simple_priv_to_dev(priv);
  205. struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
  206. struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
  207. struct device_node *np = NULL;
  208. struct device_node *bitclkmaster = NULL;
  209. struct device_node *framemaster = NULL;
  210. unsigned int daifmt;
  211. char *name;
  212. char prop[128];
  213. char *prefix = "";
  214. int ret, cpu_args;
  215. /* For single DAI link & old style of DT node */
  216. if (is_top_level_node)
  217. prefix = "simple-audio-card,";
  218. daifmt = snd_soc_of_parse_daifmt(node, prefix,
  219. &bitclkmaster, &framemaster);
  220. daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
  221. snprintf(prop, sizeof(prop), "%scpu", prefix);
  222. np = of_get_child_by_name(node, prop);
  223. if (!np) {
  224. ret = -EINVAL;
  225. dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
  226. goto dai_link_of_err;
  227. }
  228. ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai,
  229. &dai_link->cpu_of_node,
  230. &dai_link->cpu_dai_name,
  231. &cpu_args);
  232. if (ret < 0)
  233. goto dai_link_of_err;
  234. dai_props->cpu_dai.fmt = daifmt;
  235. switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
  236. case 0x11:
  237. dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
  238. break;
  239. case 0x10:
  240. dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
  241. break;
  242. case 0x01:
  243. dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
  244. break;
  245. default:
  246. dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
  247. break;
  248. }
  249. of_node_put(np);
  250. snprintf(prop, sizeof(prop), "%scodec", prefix);
  251. np = of_get_child_by_name(node, prop);
  252. if (!np) {
  253. ret = -EINVAL;
  254. dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
  255. goto dai_link_of_err;
  256. }
  257. ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai,
  258. &dai_link->codec_of_node,
  259. &dai_link->codec_dai_name, NULL);
  260. if (ret < 0)
  261. goto dai_link_of_err;
  262. if (strlen(prefix) && !bitclkmaster && !framemaster) {
  263. /*
  264. * No DAI link level and master setting was found
  265. * from sound node level, revert back to legacy DT
  266. * parsing and take the settings from codec node.
  267. */
  268. dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n",
  269. __func__);
  270. dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt =
  271. snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) |
  272. (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
  273. } else {
  274. dai_props->codec_dai.fmt = daifmt;
  275. switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
  276. case 0x11:
  277. dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
  278. break;
  279. case 0x10:
  280. dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
  281. break;
  282. case 0x01:
  283. dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
  284. break;
  285. default:
  286. dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
  287. break;
  288. }
  289. }
  290. if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
  291. ret = -EINVAL;
  292. goto dai_link_of_err;
  293. }
  294. /* Simple Card assumes platform == cpu */
  295. dai_link->platform_of_node = dai_link->cpu_of_node;
  296. /* DAI link name is created from CPU/CODEC dai name */
  297. name = devm_kzalloc(dev,
  298. strlen(dai_link->cpu_dai_name) +
  299. strlen(dai_link->codec_dai_name) + 2,
  300. GFP_KERNEL);
  301. sprintf(name, "%s-%s", dai_link->cpu_dai_name,
  302. dai_link->codec_dai_name);
  303. dai_link->name = dai_link->stream_name = name;
  304. dai_link->ops = &asoc_simple_card_ops;
  305. dai_link->init = asoc_simple_card_dai_init;
  306. dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
  307. dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
  308. dai_link->cpu_dai_name,
  309. dai_props->cpu_dai.fmt,
  310. dai_props->cpu_dai.sysclk);
  311. dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
  312. dai_link->codec_dai_name,
  313. dai_props->codec_dai.fmt,
  314. dai_props->codec_dai.sysclk);
  315. /*
  316. * In soc_bind_dai_link() will check cpu name after
  317. * of_node matching if dai_link has cpu_dai_name.
  318. * but, it will never match if name was created by
  319. * fmt_single_name() remove cpu_dai_name if cpu_args
  320. * was 0. See:
  321. * fmt_single_name()
  322. * fmt_multiple_name()
  323. */
  324. if (!cpu_args)
  325. dai_link->cpu_dai_name = NULL;
  326. dai_link_of_err:
  327. if (np)
  328. of_node_put(np);
  329. if (bitclkmaster)
  330. of_node_put(bitclkmaster);
  331. if (framemaster)
  332. of_node_put(framemaster);
  333. return ret;
  334. }
  335. static int asoc_simple_card_parse_of(struct device_node *node,
  336. struct simple_card_data *priv)
  337. {
  338. struct device *dev = simple_priv_to_dev(priv);
  339. u32 val;
  340. int ret;
  341. if (!node)
  342. return -EINVAL;
  343. /* Parse the card name from DT */
  344. snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
  345. /* The off-codec widgets */
  346. if (of_property_read_bool(node, "simple-audio-card,widgets")) {
  347. ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
  348. "simple-audio-card,widgets");
  349. if (ret)
  350. return ret;
  351. }
  352. /* DAPM routes */
  353. if (of_property_read_bool(node, "simple-audio-card,routing")) {
  354. ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
  355. "simple-audio-card,routing");
  356. if (ret)
  357. return ret;
  358. }
  359. /* Factor to mclk, used in hw_params() */
  360. ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val);
  361. if (ret == 0)
  362. priv->mclk_fs = val;
  363. dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
  364. priv->snd_card.name : "");
  365. /* Single/Muti DAI link(s) & New style of DT node */
  366. if (of_get_child_by_name(node, "simple-audio-card,dai-link")) {
  367. struct device_node *np = NULL;
  368. int i = 0;
  369. for_each_child_of_node(node, np) {
  370. dev_dbg(dev, "\tlink %d:\n", i);
  371. ret = asoc_simple_card_dai_link_of(np, priv,
  372. i, false);
  373. if (ret < 0) {
  374. of_node_put(np);
  375. return ret;
  376. }
  377. i++;
  378. }
  379. } else {
  380. /* For single DAI link & old style of DT node */
  381. ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
  382. if (ret < 0)
  383. return ret;
  384. }
  385. priv->gpio_hp_det = of_get_named_gpio(node,
  386. "simple-audio-card,hp-det-gpio", 0);
  387. if (priv->gpio_hp_det == -EPROBE_DEFER)
  388. return -EPROBE_DEFER;
  389. priv->gpio_mic_det = of_get_named_gpio(node,
  390. "simple-audio-card,mic-det-gpio", 0);
  391. if (priv->gpio_mic_det == -EPROBE_DEFER)
  392. return -EPROBE_DEFER;
  393. if (!priv->snd_card.name)
  394. priv->snd_card.name = priv->snd_card.dai_link->name;
  395. return 0;
  396. }
  397. /* Decrease the reference count of the device nodes */
  398. static int asoc_simple_card_unref(struct snd_soc_card *card)
  399. {
  400. struct snd_soc_dai_link *dai_link;
  401. struct device_node *np;
  402. int num_links;
  403. for (num_links = 0, dai_link = card->dai_link;
  404. num_links < card->num_links;
  405. num_links++, dai_link++) {
  406. np = (struct device_node *) dai_link->cpu_of_node;
  407. if (np)
  408. of_node_put(np);
  409. np = (struct device_node *) dai_link->codec_of_node;
  410. if (np)
  411. of_node_put(np);
  412. }
  413. return 0;
  414. }
  415. static int asoc_simple_card_probe(struct platform_device *pdev)
  416. {
  417. struct simple_card_data *priv;
  418. struct snd_soc_dai_link *dai_link;
  419. struct device_node *np = pdev->dev.of_node;
  420. struct device *dev = &pdev->dev;
  421. int num_links, ret;
  422. /* Get the number of DAI links */
  423. if (np && of_get_child_by_name(np, "simple-audio-card,dai-link"))
  424. num_links = of_get_child_count(np);
  425. else
  426. num_links = 1;
  427. /* Allocate the private data and the DAI link array */
  428. priv = devm_kzalloc(dev,
  429. sizeof(*priv) + sizeof(*dai_link) * num_links,
  430. GFP_KERNEL);
  431. if (!priv)
  432. return -ENOMEM;
  433. /* Init snd_soc_card */
  434. priv->snd_card.owner = THIS_MODULE;
  435. priv->snd_card.dev = dev;
  436. dai_link = priv->dai_link;
  437. priv->snd_card.dai_link = dai_link;
  438. priv->snd_card.num_links = num_links;
  439. priv->gpio_hp_det = -ENOENT;
  440. priv->gpio_mic_det = -ENOENT;
  441. /* Get room for the other properties */
  442. priv->dai_props = devm_kzalloc(dev,
  443. sizeof(*priv->dai_props) * num_links,
  444. GFP_KERNEL);
  445. if (!priv->dai_props)
  446. return -ENOMEM;
  447. if (np && of_device_is_available(np)) {
  448. ret = asoc_simple_card_parse_of(np, priv);
  449. if (ret < 0) {
  450. if (ret != -EPROBE_DEFER)
  451. dev_err(dev, "parse error %d\n", ret);
  452. goto err;
  453. }
  454. } else {
  455. struct asoc_simple_card_info *cinfo;
  456. cinfo = dev->platform_data;
  457. if (!cinfo) {
  458. dev_err(dev, "no info for asoc-simple-card\n");
  459. return -EINVAL;
  460. }
  461. if (!cinfo->name ||
  462. !cinfo->codec_dai.name ||
  463. !cinfo->codec ||
  464. !cinfo->platform ||
  465. !cinfo->cpu_dai.name) {
  466. dev_err(dev, "insufficient asoc_simple_card_info settings\n");
  467. return -EINVAL;
  468. }
  469. priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name;
  470. dai_link->name = cinfo->name;
  471. dai_link->stream_name = cinfo->name;
  472. dai_link->platform_name = cinfo->platform;
  473. dai_link->codec_name = cinfo->codec;
  474. dai_link->cpu_dai_name = cinfo->cpu_dai.name;
  475. dai_link->codec_dai_name = cinfo->codec_dai.name;
  476. dai_link->init = asoc_simple_card_dai_init;
  477. memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
  478. sizeof(priv->dai_props->cpu_dai));
  479. memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
  480. sizeof(priv->dai_props->codec_dai));
  481. priv->dai_props->cpu_dai.fmt |= cinfo->daifmt;
  482. priv->dai_props->codec_dai.fmt |= cinfo->daifmt;
  483. }
  484. snd_soc_card_set_drvdata(&priv->snd_card, priv);
  485. ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
  486. if (ret >= 0)
  487. return ret;
  488. err:
  489. asoc_simple_card_unref(&priv->snd_card);
  490. return ret;
  491. }
  492. static int asoc_simple_card_remove(struct platform_device *pdev)
  493. {
  494. struct snd_soc_card *card = platform_get_drvdata(pdev);
  495. struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
  496. if (gpio_is_valid(priv->gpio_hp_det))
  497. snd_soc_jack_free_gpios(&simple_card_hp_jack, 1,
  498. &simple_card_hp_jack_gpio);
  499. if (gpio_is_valid(priv->gpio_mic_det))
  500. snd_soc_jack_free_gpios(&simple_card_mic_jack, 1,
  501. &simple_card_mic_jack_gpio);
  502. return asoc_simple_card_unref(card);
  503. }
  504. static const struct of_device_id asoc_simple_of_match[] = {
  505. { .compatible = "simple-audio-card", },
  506. {},
  507. };
  508. MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
  509. static struct platform_driver asoc_simple_card = {
  510. .driver = {
  511. .name = "asoc-simple-card",
  512. .owner = THIS_MODULE,
  513. .of_match_table = asoc_simple_of_match,
  514. },
  515. .probe = asoc_simple_card_probe,
  516. .remove = asoc_simple_card_remove,
  517. };
  518. module_platform_driver(asoc_simple_card);
  519. MODULE_ALIAS("platform:asoc-simple-card");
  520. MODULE_LICENSE("GPL");
  521. MODULE_DESCRIPTION("ASoC Simple Sound Card");
  522. MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");