control.c 4.5 KB

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