gen.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 (*path_init)(struct rsnd_priv *priv,
  14. struct rsnd_dai *rdai,
  15. struct rsnd_dai_stream *io);
  16. int (*path_exit)(struct rsnd_priv *priv,
  17. struct rsnd_dai *rdai,
  18. struct rsnd_dai_stream *io);
  19. };
  20. struct rsnd_gen_reg_map {
  21. int index; /* -1 : not supported */
  22. u32 offset_id; /* offset of ssi0, ssi1, ssi2... */
  23. u32 offset_adr; /* offset of SSICR, SSISR, ... */
  24. };
  25. struct rsnd_gen {
  26. void __iomem *base[RSND_BASE_MAX];
  27. struct rsnd_gen_reg_map reg_map[RSND_REG_MAX];
  28. struct rsnd_gen_ops *ops;
  29. };
  30. #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
  31. #define rsnd_is_gen1(s) ((s)->info->flags & RSND_GEN1)
  32. #define rsnd_is_gen2(s) ((s)->info->flags & RSND_GEN2)
  33. /*
  34. * Gen2
  35. * will be filled in the future
  36. */
  37. /*
  38. * Gen1
  39. */
  40. static int rsnd_gen1_probe(struct platform_device *pdev,
  41. struct rcar_snd_info *info,
  42. struct rsnd_priv *priv)
  43. {
  44. return 0;
  45. }
  46. static void rsnd_gen1_remove(struct platform_device *pdev,
  47. struct rsnd_priv *priv)
  48. {
  49. }
  50. /*
  51. * Gen
  52. */
  53. int rsnd_gen_path_init(struct rsnd_priv *priv,
  54. struct rsnd_dai *rdai,
  55. struct rsnd_dai_stream *io)
  56. {
  57. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  58. return gen->ops->path_init(priv, rdai, io);
  59. }
  60. int rsnd_gen_path_exit(struct rsnd_priv *priv,
  61. struct rsnd_dai *rdai,
  62. struct rsnd_dai_stream *io)
  63. {
  64. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  65. return gen->ops->path_exit(priv, rdai, io);
  66. }
  67. void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
  68. struct rsnd_mod *mod,
  69. enum rsnd_reg reg)
  70. {
  71. struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
  72. struct device *dev = rsnd_priv_to_dev(priv);
  73. int index;
  74. u32 offset_id, offset_adr;
  75. if (reg >= RSND_REG_MAX) {
  76. dev_err(dev, "rsnd_reg reg error\n");
  77. return NULL;
  78. }
  79. index = gen->reg_map[reg].index;
  80. offset_id = gen->reg_map[reg].offset_id;
  81. offset_adr = gen->reg_map[reg].offset_adr;
  82. if (index < 0) {
  83. dev_err(dev, "unsupported reg access %d\n", reg);
  84. return NULL;
  85. }
  86. if (offset_id && mod)
  87. offset_id *= rsnd_mod_id(mod);
  88. /*
  89. * index/offset were set on gen1/gen2
  90. */
  91. return gen->base[index] + offset_id + offset_adr;
  92. }
  93. int rsnd_gen_probe(struct platform_device *pdev,
  94. struct rcar_snd_info *info,
  95. struct rsnd_priv *priv)
  96. {
  97. struct device *dev = rsnd_priv_to_dev(priv);
  98. struct rsnd_gen *gen;
  99. int i;
  100. gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
  101. if (!gen) {
  102. dev_err(dev, "GEN allocate failed\n");
  103. return -ENOMEM;
  104. }
  105. priv->gen = gen;
  106. /*
  107. * see
  108. * rsnd_reg_get()
  109. * rsnd_gen_probe()
  110. */
  111. for (i = 0; i < RSND_REG_MAX; i++)
  112. gen->reg_map[i].index = -1;
  113. /*
  114. * init each module
  115. */
  116. if (rsnd_is_gen1(priv))
  117. return rsnd_gen1_probe(pdev, info, priv);
  118. dev_err(dev, "unknown generation R-Car sound device\n");
  119. return -ENODEV;
  120. }
  121. void rsnd_gen_remove(struct platform_device *pdev,
  122. struct rsnd_priv *priv)
  123. {
  124. if (rsnd_is_gen1(priv))
  125. rsnd_gen1_remove(pdev, priv);
  126. }