gen.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. * Renesas R-Car Gen1 SRU/SSI support
  3. *
  4. * Copyright (C) 2013 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 "rsnd.h"
  12. struct rsnd_gen_ops {
  13. int (*probe)(struct platform_device *pdev,
  14. struct rcar_snd_info *info,
  15. struct rsnd_priv *priv);
  16. void (*remove)(struct platform_device *pdev,
  17. struct rsnd_priv *priv);
  18. int (*path_init)(struct rsnd_priv *priv,
  19. struct rsnd_dai *rdai,
  20. struct rsnd_dai_stream *io);
  21. int (*path_exit)(struct rsnd_priv *priv,
  22. struct rsnd_dai *rdai,
  23. struct rsnd_dai_stream *io);
  24. };
  25. struct rsnd_gen {
  26. void __iomem *base[RSND_BASE_MAX];
  27. struct rsnd_gen_ops *ops;
  28. struct regmap *regmap;
  29. struct regmap_field *regs[RSND_REG_MAX];
  30. };
  31. #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
  32. #define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size) \
  33. [id] = { \
  34. .reg = (unsigned int)gen->base[reg_id] + offset, \
  35. .lsb = 0, \
  36. .msb = 31, \
  37. .id_size = _id_size, \
  38. .id_offset = _id_offset, \
  39. }
  40. /*
  41. * basic function
  42. */
  43. static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
  44. {
  45. struct rsnd_priv *priv = context;
  46. struct device *dev = rsnd_priv_to_dev(priv);
  47. u32 *data = (u32 *)_data;
  48. u32 val = data[1];
  49. void __iomem *reg = (void *)data[0];
  50. iowrite32(val, reg);
  51. dev_dbg(dev, "w %p : %08x\n", reg, val);
  52. return 0;
  53. }
  54. static int rsnd_regmap_read32(void *context,
  55. const void *_data, size_t reg_size,
  56. void *_val, size_t val_size)
  57. {
  58. struct rsnd_priv *priv = context;
  59. struct device *dev = rsnd_priv_to_dev(priv);
  60. u32 *data = (u32 *)_data;
  61. u32 *val = (u32 *)_val;
  62. void __iomem *reg = (void *)data[0];
  63. *val = ioread32(reg);
  64. dev_dbg(dev, "r %p : %08x\n", reg, *val);
  65. return 0;
  66. }
  67. static struct regmap_bus rsnd_regmap_bus = {
  68. .write = rsnd_regmap_write32,
  69. .read = rsnd_regmap_read32,
  70. .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
  71. .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
  72. };
  73. u32 rsnd_read(struct rsnd_priv *priv,
  74. struct rsnd_mod *mod, enum rsnd_reg reg)
  75. {
  76. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  77. u32 val;
  78. regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
  79. return val;
  80. }
  81. void rsnd_write(struct rsnd_priv *priv,
  82. struct rsnd_mod *mod,
  83. enum rsnd_reg reg, u32 data)
  84. {
  85. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  86. regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
  87. }
  88. void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
  89. enum rsnd_reg reg, u32 mask, u32 data)
  90. {
  91. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  92. regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
  93. mask, data);
  94. }
  95. /*
  96. * Gen2
  97. * will be filled in the future
  98. */
  99. /*
  100. * Gen1
  101. */
  102. static int rsnd_gen1_path_init(struct rsnd_priv *priv,
  103. struct rsnd_dai *rdai,
  104. struct rsnd_dai_stream *io)
  105. {
  106. struct rsnd_mod *mod;
  107. int ret;
  108. int id;
  109. /*
  110. * Gen1 is created by SRU/SSI, and this SRU is base module of
  111. * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
  112. *
  113. * Easy image is..
  114. * Gen1 SRU = Gen2 SCU + SSIU + etc
  115. *
  116. * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
  117. * using fixed path.
  118. *
  119. * Then, SSI id = SCU id here
  120. */
  121. /* get SSI's ID */
  122. mod = rsnd_ssi_mod_get_frm_dai(priv,
  123. rsnd_dai_id(priv, rdai),
  124. rsnd_dai_is_play(rdai, io));
  125. id = rsnd_mod_id(mod);
  126. /* SSI */
  127. mod = rsnd_ssi_mod_get(priv, id);
  128. ret = rsnd_dai_connect(rdai, mod, io);
  129. if (ret < 0)
  130. return ret;
  131. /* SCU */
  132. mod = rsnd_scu_mod_get(priv, id);
  133. ret = rsnd_dai_connect(rdai, mod, io);
  134. return ret;
  135. }
  136. static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
  137. struct rsnd_dai *rdai,
  138. struct rsnd_dai_stream *io)
  139. {
  140. struct rsnd_mod *mod, *n;
  141. int ret = 0;
  142. /*
  143. * remove all mod from rdai
  144. */
  145. for_each_rsnd_mod(mod, n, io)
  146. ret |= rsnd_dai_disconnect(mod);
  147. return ret;
  148. }
  149. /* single address mapping */
  150. #define RSND_GEN1_S_REG(gen, reg, id, offset) \
  151. RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9)
  152. /* multi address mapping */
  153. #define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset) \
  154. RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
  155. static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
  156. {
  157. int i;
  158. struct device *dev = rsnd_priv_to_dev(priv);
  159. struct regmap_config regc;
  160. struct reg_field regf[RSND_REG_MAX] = {
  161. RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_SEL, 0x00),
  162. RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL0, 0x08),
  163. RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL1, 0x0c),
  164. RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL2, 0x10),
  165. RSND_GEN1_S_REG(gen, SRU, SRC_CTRL, 0xc0),
  166. RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0),
  167. RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4),
  168. RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4),
  169. RSND_GEN1_M_REG(gen, SRU, BUSIF_ADINR, 0x214, 0x40),
  170. RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00),
  171. RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04),
  172. RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08),
  173. RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c),
  174. RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10),
  175. RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL3, 0x18),
  176. RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL4, 0x1c),
  177. RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL5, 0x20),
  178. RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40),
  179. RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40),
  180. RSND_GEN1_M_REG(gen, SSI, SSITDR, 0x08, 0x40),
  181. RSND_GEN1_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40),
  182. RSND_GEN1_M_REG(gen, SSI, SSIWSR, 0x20, 0x40),
  183. };
  184. memset(&regc, 0, sizeof(regc));
  185. regc.reg_bits = 32;
  186. regc.val_bits = 32;
  187. gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
  188. if (IS_ERR(gen->regmap)) {
  189. dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
  190. return PTR_ERR(gen->regmap);
  191. }
  192. for (i = 0; i < RSND_REG_MAX; i++) {
  193. gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
  194. if (IS_ERR(gen->regs[i]))
  195. return PTR_ERR(gen->regs[i]);
  196. }
  197. return 0;
  198. }
  199. static int rsnd_gen1_probe(struct platform_device *pdev,
  200. struct rcar_snd_info *info,
  201. struct rsnd_priv *priv)
  202. {
  203. struct device *dev = rsnd_priv_to_dev(priv);
  204. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  205. struct resource *sru_res;
  206. struct resource *adg_res;
  207. struct resource *ssi_res;
  208. int ret;
  209. /*
  210. * map address
  211. */
  212. sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU);
  213. adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG);
  214. ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI);
  215. gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res);
  216. gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res);
  217. gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res);
  218. if (IS_ERR(gen->base[RSND_GEN1_SRU]) ||
  219. IS_ERR(gen->base[RSND_GEN1_ADG]) ||
  220. IS_ERR(gen->base[RSND_GEN1_SSI]))
  221. return -ENODEV;
  222. ret = rsnd_gen1_regmap_init(priv, gen);
  223. if (ret < 0)
  224. return ret;
  225. dev_dbg(dev, "Gen1 device probed\n");
  226. dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start,
  227. gen->base[RSND_GEN1_SRU]);
  228. dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start,
  229. gen->base[RSND_GEN1_ADG]);
  230. dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start,
  231. gen->base[RSND_GEN1_SSI]);
  232. return 0;
  233. }
  234. static void rsnd_gen1_remove(struct platform_device *pdev,
  235. struct rsnd_priv *priv)
  236. {
  237. }
  238. static struct rsnd_gen_ops rsnd_gen1_ops = {
  239. .probe = rsnd_gen1_probe,
  240. .remove = rsnd_gen1_remove,
  241. .path_init = rsnd_gen1_path_init,
  242. .path_exit = rsnd_gen1_path_exit,
  243. };
  244. /*
  245. * Gen
  246. */
  247. int rsnd_gen_path_init(struct rsnd_priv *priv,
  248. struct rsnd_dai *rdai,
  249. struct rsnd_dai_stream *io)
  250. {
  251. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  252. return gen->ops->path_init(priv, rdai, io);
  253. }
  254. int rsnd_gen_path_exit(struct rsnd_priv *priv,
  255. struct rsnd_dai *rdai,
  256. struct rsnd_dai_stream *io)
  257. {
  258. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  259. return gen->ops->path_exit(priv, rdai, io);
  260. }
  261. int rsnd_gen_probe(struct platform_device *pdev,
  262. struct rcar_snd_info *info,
  263. struct rsnd_priv *priv)
  264. {
  265. struct device *dev = rsnd_priv_to_dev(priv);
  266. struct rsnd_gen *gen;
  267. gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
  268. if (!gen) {
  269. dev_err(dev, "GEN allocate failed\n");
  270. return -ENOMEM;
  271. }
  272. if (rsnd_is_gen1(priv))
  273. gen->ops = &rsnd_gen1_ops;
  274. if (!gen->ops) {
  275. dev_err(dev, "unknown generation R-Car sound device\n");
  276. return -ENODEV;
  277. }
  278. priv->gen = gen;
  279. return gen->ops->probe(pdev, info, priv);
  280. }
  281. void rsnd_gen_remove(struct platform_device *pdev,
  282. struct rsnd_priv *priv)
  283. {
  284. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  285. gen->ops->remove(pdev, priv);
  286. }