control.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * i2sbus driver -- bus control routines
  4. *
  5. * Copyright 2006 Johannes Berg <[email protected]>
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/delay.h>
  9. #include <linux/slab.h>
  10. #include <linux/io.h>
  11. #include <asm/prom.h>
  12. #include <asm/macio.h>
  13. #include <asm/pmac_feature.h>
  14. #include <asm/pmac_pfunc.h>
  15. #include <asm/keylargo.h>
  16. #include "i2sbus.h"
  17. int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
  18. {
  19. *c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
  20. if (!*c)
  21. return -ENOMEM;
  22. INIT_LIST_HEAD(&(*c)->list);
  23. (*c)->macio = dev->bus->chip;
  24. return 0;
  25. }
  26. void i2sbus_control_destroy(struct i2sbus_control *c)
  27. {
  28. kfree(c);
  29. }
  30. /* this is serialised externally */
  31. int i2sbus_control_add_dev(struct i2sbus_control *c,
  32. struct i2sbus_dev *i2sdev)
  33. {
  34. struct device_node *np;
  35. np = i2sdev->sound.ofdev.dev.of_node;
  36. i2sdev->enable = pmf_find_function(np, "enable");
  37. i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
  38. i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
  39. i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
  40. i2sdev->clock_disable = pmf_find_function(np, "clock-disable");
  41. /* if the bus number is not 0 or 1 we absolutely need to use
  42. * the platform functions -- there's nothing in Darwin that
  43. * would allow seeing a system behind what the FCRs are then,
  44. * and I don't want to go parsing a bunch of platform functions
  45. * by hand to try finding a system... */
  46. if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
  47. (!i2sdev->enable ||
  48. !i2sdev->cell_enable || !i2sdev->clock_enable ||
  49. !i2sdev->cell_disable || !i2sdev->clock_disable)) {
  50. pmf_put_function(i2sdev->enable);
  51. pmf_put_function(i2sdev->cell_enable);
  52. pmf_put_function(i2sdev->clock_enable);
  53. pmf_put_function(i2sdev->cell_disable);
  54. pmf_put_function(i2sdev->clock_disable);
  55. return -ENODEV;
  56. }
  57. list_add(&i2sdev->item, &c->list);
  58. return 0;
  59. }
  60. void i2sbus_control_remove_dev(struct i2sbus_control *c,
  61. struct i2sbus_dev *i2sdev)
  62. {
  63. /* this is serialised externally */
  64. list_del(&i2sdev->item);
  65. if (list_empty(&c->list))
  66. i2sbus_control_destroy(c);
  67. }
  68. int i2sbus_control_enable(struct i2sbus_control *c,
  69. struct i2sbus_dev *i2sdev)
  70. {
  71. struct pmf_args args = { .count = 0 };
  72. struct macio_chip *macio = c->macio;
  73. if (i2sdev->enable)
  74. return pmf_call_one(i2sdev->enable, &args);
  75. if (macio == NULL || macio->base == NULL)
  76. return -ENODEV;
  77. switch (i2sdev->bus_number) {
  78. case 0:
  79. /* these need to be locked or done through
  80. * newly created feature calls! */
  81. MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
  82. break;
  83. case 1:
  84. MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
  85. break;
  86. default:
  87. return -ENODEV;
  88. }
  89. return 0;
  90. }
  91. int i2sbus_control_cell(struct i2sbus_control *c,
  92. struct i2sbus_dev *i2sdev,
  93. int enable)
  94. {
  95. struct pmf_args args = { .count = 0 };
  96. struct macio_chip *macio = c->macio;
  97. switch (enable) {
  98. case 0:
  99. if (i2sdev->cell_disable)
  100. return pmf_call_one(i2sdev->cell_disable, &args);
  101. break;
  102. case 1:
  103. if (i2sdev->cell_enable)
  104. return pmf_call_one(i2sdev->cell_enable, &args);
  105. break;
  106. default:
  107. printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
  108. return -ENODEV;
  109. }
  110. if (macio == NULL || macio->base == NULL)
  111. return -ENODEV;
  112. switch (i2sdev->bus_number) {
  113. case 0:
  114. if (enable)
  115. MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
  116. else
  117. MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
  118. break;
  119. case 1:
  120. if (enable)
  121. MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
  122. else
  123. MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
  124. break;
  125. default:
  126. return -ENODEV;
  127. }
  128. return 0;
  129. }
  130. int i2sbus_control_clock(struct i2sbus_control *c,
  131. struct i2sbus_dev *i2sdev,
  132. int enable)
  133. {
  134. struct pmf_args args = { .count = 0 };
  135. struct macio_chip *macio = c->macio;
  136. switch (enable) {
  137. case 0:
  138. if (i2sdev->clock_disable)
  139. return pmf_call_one(i2sdev->clock_disable, &args);
  140. break;
  141. case 1:
  142. if (i2sdev->clock_enable)
  143. return pmf_call_one(i2sdev->clock_enable, &args);
  144. break;
  145. default:
  146. printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
  147. return -ENODEV;
  148. }
  149. if (macio == NULL || macio->base == NULL)
  150. return -ENODEV;
  151. switch (i2sdev->bus_number) {
  152. case 0:
  153. if (enable)
  154. MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
  155. else
  156. MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
  157. break;
  158. case 1:
  159. if (enable)
  160. MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
  161. else
  162. MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
  163. break;
  164. default:
  165. return -ENODEV;
  166. }
  167. return 0;
  168. }