ctu.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * ctu.c
  3. *
  4. * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include "rsnd.h"
  11. #define CTU_NAME_SIZE 16
  12. #define CTU_NAME "ctu"
  13. struct rsnd_ctu {
  14. struct rsnd_ctu_platform_info *info; /* rcar_snd.h */
  15. struct rsnd_mod mod;
  16. };
  17. #define rsnd_ctu_nr(priv) ((priv)->ctu_nr)
  18. #define for_each_rsnd_ctu(pos, priv, i) \
  19. for ((i) = 0; \
  20. ((i) < rsnd_ctu_nr(priv)) && \
  21. ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \
  22. i++)
  23. #define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1)
  24. #define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0)
  25. static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable)
  26. {
  27. rsnd_mod_write(mod, CTU_CTUIR, enable);
  28. }
  29. static int rsnd_ctu_init(struct rsnd_mod *mod,
  30. struct rsnd_dai_stream *io,
  31. struct rsnd_priv *priv)
  32. {
  33. rsnd_mod_hw_start(mod);
  34. rsnd_ctu_initialize_lock(mod);
  35. rsnd_mod_write(mod, CTU_ADINR, rsnd_get_adinr_chan(mod, io));
  36. rsnd_ctu_initialize_unlock(mod);
  37. return 0;
  38. }
  39. static int rsnd_ctu_quit(struct rsnd_mod *mod,
  40. struct rsnd_dai_stream *io,
  41. struct rsnd_priv *priv)
  42. {
  43. rsnd_mod_hw_stop(mod);
  44. return 0;
  45. }
  46. static struct rsnd_mod_ops rsnd_ctu_ops = {
  47. .name = CTU_NAME,
  48. .init = rsnd_ctu_init,
  49. .quit = rsnd_ctu_quit,
  50. };
  51. struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
  52. {
  53. if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
  54. id = 0;
  55. return &((struct rsnd_ctu *)(priv->ctu) + id)->mod;
  56. }
  57. static void rsnd_of_parse_ctu(struct platform_device *pdev,
  58. const struct rsnd_of_data *of_data,
  59. struct rsnd_priv *priv)
  60. {
  61. struct device_node *node;
  62. struct rsnd_ctu_platform_info *ctu_info;
  63. struct rcar_snd_info *info = rsnd_priv_to_info(priv);
  64. struct device *dev = &pdev->dev;
  65. int nr;
  66. if (!of_data)
  67. return;
  68. node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
  69. if (!node)
  70. return;
  71. nr = of_get_child_count(node);
  72. if (!nr)
  73. goto rsnd_of_parse_ctu_end;
  74. ctu_info = devm_kzalloc(dev,
  75. sizeof(struct rsnd_ctu_platform_info) * nr,
  76. GFP_KERNEL);
  77. if (!ctu_info) {
  78. dev_err(dev, "ctu info allocation error\n");
  79. goto rsnd_of_parse_ctu_end;
  80. }
  81. info->ctu_info = ctu_info;
  82. info->ctu_info_nr = nr;
  83. rsnd_of_parse_ctu_end:
  84. of_node_put(node);
  85. }
  86. int rsnd_ctu_probe(struct platform_device *pdev,
  87. const struct rsnd_of_data *of_data,
  88. struct rsnd_priv *priv)
  89. {
  90. struct rcar_snd_info *info = rsnd_priv_to_info(priv);
  91. struct device *dev = rsnd_priv_to_dev(priv);
  92. struct rsnd_ctu *ctu;
  93. struct clk *clk;
  94. char name[CTU_NAME_SIZE];
  95. int i, nr, ret;
  96. /* This driver doesn't support Gen1 at this point */
  97. if (rsnd_is_gen1(priv)) {
  98. dev_warn(dev, "CTU is not supported on Gen1\n");
  99. return -EINVAL;
  100. }
  101. rsnd_of_parse_ctu(pdev, of_data, priv);
  102. nr = info->ctu_info_nr;
  103. if (!nr)
  104. return 0;
  105. ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL);
  106. if (!ctu)
  107. return -ENOMEM;
  108. priv->ctu_nr = nr;
  109. priv->ctu = ctu;
  110. for_each_rsnd_ctu(ctu, priv, i) {
  111. /*
  112. * CTU00, CTU01, CTU02, CTU03 => CTU0
  113. * CTU10, CTU11, CTU12, CTU13 => CTU1
  114. */
  115. snprintf(name, CTU_NAME_SIZE, "%s.%d",
  116. CTU_NAME, i / 4);
  117. clk = devm_clk_get(dev, name);
  118. if (IS_ERR(clk))
  119. return PTR_ERR(clk);
  120. ctu->info = &info->ctu_info[i];
  121. ret = rsnd_mod_init(priv, &ctu->mod, &rsnd_ctu_ops,
  122. clk, RSND_MOD_CTU, i);
  123. if (ret)
  124. return ret;
  125. }
  126. return 0;
  127. }
  128. void rsnd_ctu_remove(struct platform_device *pdev,
  129. struct rsnd_priv *priv)
  130. {
  131. struct rsnd_ctu *ctu;
  132. int i;
  133. for_each_rsnd_ctu(ctu, priv, i) {
  134. rsnd_mod_quit(&ctu->mod);
  135. }
  136. }