ssiu.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Renesas R-Car SSIU support
  4. //
  5. // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6. #include "rsnd.h"
  7. #define SSIU_NAME "ssiu"
  8. struct rsnd_ssiu {
  9. struct rsnd_mod mod;
  10. };
  11. #define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
  12. #define for_each_rsnd_ssiu(pos, priv, i) \
  13. for (i = 0; \
  14. (i < rsnd_ssiu_nr(priv)) && \
  15. ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \
  16. i++)
  17. static int rsnd_ssiu_init(struct rsnd_mod *mod,
  18. struct rsnd_dai_stream *io,
  19. struct rsnd_priv *priv)
  20. {
  21. struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
  22. u32 multi_ssi_slaves = rsnd_ssi_multi_slaves_runtime(io);
  23. int use_busif = rsnd_ssi_use_busif(io);
  24. int id = rsnd_mod_id(mod);
  25. u32 mask1, val1;
  26. u32 mask2, val2;
  27. /* clear status */
  28. switch (id) {
  29. case 0:
  30. case 1:
  31. case 2:
  32. case 3:
  33. case 4:
  34. rsnd_mod_write(mod, SSI_SYS_STATUS0, 0xf << (id * 4));
  35. rsnd_mod_write(mod, SSI_SYS_STATUS2, 0xf << (id * 4));
  36. rsnd_mod_write(mod, SSI_SYS_STATUS4, 0xf << (id * 4));
  37. rsnd_mod_write(mod, SSI_SYS_STATUS6, 0xf << (id * 4));
  38. break;
  39. case 9:
  40. rsnd_mod_write(mod, SSI_SYS_STATUS1, 0xf << 4);
  41. rsnd_mod_write(mod, SSI_SYS_STATUS3, 0xf << 4);
  42. rsnd_mod_write(mod, SSI_SYS_STATUS5, 0xf << 4);
  43. rsnd_mod_write(mod, SSI_SYS_STATUS7, 0xf << 4);
  44. break;
  45. }
  46. /*
  47. * SSI_MODE0
  48. */
  49. rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
  50. /*
  51. * SSI_MODE1
  52. */
  53. mask1 = (1 << 4) | (1 << 20); /* mask sync bit */
  54. mask2 = (1 << 4); /* mask sync bit */
  55. val1 = val2 = 0;
  56. if (id == 8) {
  57. /*
  58. * SSI8 pin is sharing with SSI7, nothing to do.
  59. */
  60. } else if (rsnd_ssi_is_pin_sharing(io)) {
  61. int shift = -1;
  62. switch (id) {
  63. case 1:
  64. shift = 0;
  65. break;
  66. case 2:
  67. shift = 2;
  68. break;
  69. case 4:
  70. shift = 16;
  71. break;
  72. default:
  73. return -EINVAL;
  74. }
  75. mask1 |= 0x3 << shift;
  76. val1 = rsnd_rdai_is_clk_master(rdai) ?
  77. 0x2 << shift : 0x1 << shift;
  78. } else if (multi_ssi_slaves) {
  79. mask2 |= 0x00000007;
  80. mask1 |= 0x0000000f;
  81. switch (multi_ssi_slaves) {
  82. case 0x0206: /* SSI0/1/2/9 */
  83. val2 = (1 << 4) | /* SSI0129 sync */
  84. (rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1);
  85. /* fall through */
  86. case 0x0006: /* SSI0/1/2 */
  87. val1 = rsnd_rdai_is_clk_master(rdai) ?
  88. 0xa : 0x5;
  89. if (!val2) /* SSI012 sync */
  90. val1 |= (1 << 4);
  91. }
  92. }
  93. rsnd_mod_bset(mod, SSI_MODE1, mask1, val1);
  94. rsnd_mod_bset(mod, SSI_MODE2, mask2, val2);
  95. return 0;
  96. }
  97. static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
  98. .name = SSIU_NAME,
  99. .init = rsnd_ssiu_init,
  100. };
  101. static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
  102. struct rsnd_dai_stream *io,
  103. struct rsnd_priv *priv)
  104. {
  105. int hdmi = rsnd_ssi_hdmi_port(io);
  106. int ret;
  107. u32 mode = 0;
  108. ret = rsnd_ssiu_init(mod, io, priv);
  109. if (ret < 0)
  110. return ret;
  111. if (rsnd_runtime_is_ssi_tdm(io)) {
  112. /*
  113. * TDM Extend Mode
  114. * see
  115. * rsnd_ssi_config_init()
  116. */
  117. mode = 0x1;
  118. }
  119. rsnd_mod_write(mod, SSI_MODE, mode);
  120. if (rsnd_ssi_use_busif(io)) {
  121. rsnd_mod_write(mod, SSI_BUSIF_ADINR,
  122. rsnd_get_adinr_bit(mod, io) |
  123. (rsnd_io_is_play(io) ?
  124. rsnd_runtime_channel_after_ctu(io) :
  125. rsnd_runtime_channel_original(io)));
  126. rsnd_mod_write(mod, SSI_BUSIF_MODE,
  127. rsnd_get_busif_shift(io, mod) | 1);
  128. rsnd_mod_write(mod, SSI_BUSIF_DALIGN,
  129. rsnd_get_dalign(mod, io));
  130. }
  131. if (hdmi) {
  132. enum rsnd_mod_type rsnd_ssi_array[] = {
  133. RSND_MOD_SSIM1,
  134. RSND_MOD_SSIM2,
  135. RSND_MOD_SSIM3,
  136. };
  137. struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
  138. struct rsnd_mod *pos;
  139. u32 val;
  140. int i, shift;
  141. i = rsnd_mod_id(ssi_mod);
  142. /* output all same SSI as default */
  143. val = i << 16 |
  144. i << 20 |
  145. i << 24 |
  146. i << 28 |
  147. i;
  148. for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
  149. shift = (i * 4) + 20;
  150. val = (val & ~(0xF << shift)) |
  151. rsnd_mod_id(pos) << shift;
  152. }
  153. switch (hdmi) {
  154. case RSND_SSI_HDMI_PORT0:
  155. rsnd_mod_write(mod, HDMI0_SEL, val);
  156. break;
  157. case RSND_SSI_HDMI_PORT1:
  158. rsnd_mod_write(mod, HDMI1_SEL, val);
  159. break;
  160. }
  161. }
  162. return 0;
  163. }
  164. static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
  165. struct rsnd_dai_stream *io,
  166. struct rsnd_priv *priv)
  167. {
  168. if (!rsnd_ssi_use_busif(io))
  169. return 0;
  170. rsnd_mod_write(mod, SSI_CTRL, 0x1);
  171. if (rsnd_ssi_multi_slaves_runtime(io))
  172. rsnd_mod_write(mod, SSI_CONTROL, 0x1);
  173. return 0;
  174. }
  175. static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
  176. struct rsnd_dai_stream *io,
  177. struct rsnd_priv *priv)
  178. {
  179. if (!rsnd_ssi_use_busif(io))
  180. return 0;
  181. rsnd_mod_write(mod, SSI_CTRL, 0);
  182. if (rsnd_ssi_multi_slaves_runtime(io))
  183. rsnd_mod_write(mod, SSI_CONTROL, 0);
  184. return 0;
  185. }
  186. static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
  187. .name = SSIU_NAME,
  188. .init = rsnd_ssiu_init_gen2,
  189. .start = rsnd_ssiu_start_gen2,
  190. .stop = rsnd_ssiu_stop_gen2,
  191. };
  192. static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
  193. {
  194. if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
  195. id = 0;
  196. return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
  197. }
  198. int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
  199. struct rsnd_mod *ssi_mod)
  200. {
  201. struct rsnd_priv *priv = rsnd_io_to_priv(io);
  202. struct rsnd_mod *mod = rsnd_ssiu_mod_get(priv, rsnd_mod_id(ssi_mod));
  203. rsnd_mod_confirm_ssi(ssi_mod);
  204. return rsnd_dai_connect(mod, io, mod->type);
  205. }
  206. int rsnd_ssiu_probe(struct rsnd_priv *priv)
  207. {
  208. struct device *dev = rsnd_priv_to_dev(priv);
  209. struct rsnd_ssiu *ssiu;
  210. struct rsnd_mod_ops *ops;
  211. int i, nr, ret;
  212. /* same number to SSI */
  213. nr = priv->ssi_nr;
  214. ssiu = devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
  215. if (!ssiu)
  216. return -ENOMEM;
  217. priv->ssiu = ssiu;
  218. priv->ssiu_nr = nr;
  219. if (rsnd_is_gen1(priv))
  220. ops = &rsnd_ssiu_ops_gen1;
  221. else
  222. ops = &rsnd_ssiu_ops_gen2;
  223. for_each_rsnd_ssiu(ssiu, priv, i) {
  224. ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
  225. ops, NULL, rsnd_mod_get_status,
  226. RSND_MOD_SSIU, i);
  227. if (ret)
  228. return ret;
  229. }
  230. return 0;
  231. }
  232. void rsnd_ssiu_remove(struct rsnd_priv *priv)
  233. {
  234. struct rsnd_ssiu *ssiu;
  235. int i;
  236. for_each_rsnd_ssiu(ssiu, priv, i) {
  237. rsnd_mod_quit(rsnd_mod_get(ssiu));
  238. }
  239. }