ssp.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/arch/arm/mach-sa1100/ssp.c
  4. *
  5. * Copyright (C) 2003 Russell King.
  6. *
  7. * Generic SSP driver. This provides the generic core for simple
  8. * IO-based SSP applications.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/sched.h>
  13. #include <linux/errno.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/ioport.h>
  16. #include <linux/init.h>
  17. #include <linux/io.h>
  18. #include <mach/hardware.h>
  19. #include <mach/irqs.h>
  20. #include <asm/hardware/ssp.h>
  21. #define TIMEOUT 100000
  22. static irqreturn_t ssp_interrupt(int irq, void *dev_id)
  23. {
  24. unsigned int status = Ser4SSSR;
  25. if (status & SSSR_ROR)
  26. printk(KERN_WARNING "SSP: receiver overrun\n");
  27. Ser4SSSR = SSSR_ROR;
  28. return status ? IRQ_HANDLED : IRQ_NONE;
  29. }
  30. /**
  31. * ssp_write_word - write a word to the SSP port
  32. * @data: 16-bit, MSB justified data to write.
  33. *
  34. * Wait for a free entry in the SSP transmit FIFO, and write a data
  35. * word to the SSP port. Wait for the SSP port to start sending
  36. * the data.
  37. *
  38. * The caller is expected to perform the necessary locking.
  39. *
  40. * Returns:
  41. * %-ETIMEDOUT timeout occurred
  42. * 0 success
  43. */
  44. int ssp_write_word(u16 data)
  45. {
  46. int timeout = TIMEOUT;
  47. while (!(Ser4SSSR & SSSR_TNF)) {
  48. if (!--timeout)
  49. return -ETIMEDOUT;
  50. cpu_relax();
  51. }
  52. Ser4SSDR = data;
  53. timeout = TIMEOUT;
  54. while (!(Ser4SSSR & SSSR_BSY)) {
  55. if (!--timeout)
  56. return -ETIMEDOUT;
  57. cpu_relax();
  58. }
  59. return 0;
  60. }
  61. /**
  62. * ssp_read_word - read a word from the SSP port
  63. *
  64. * Wait for a data word in the SSP receive FIFO, and return the
  65. * received data. Data is LSB justified.
  66. *
  67. * Note: Currently, if data is not expected to be received, this
  68. * function will wait for ever.
  69. *
  70. * The caller is expected to perform the necessary locking.
  71. *
  72. * Returns:
  73. * %-ETIMEDOUT timeout occurred
  74. * 16-bit data success
  75. */
  76. int ssp_read_word(u16 *data)
  77. {
  78. int timeout = TIMEOUT;
  79. while (!(Ser4SSSR & SSSR_RNE)) {
  80. if (!--timeout)
  81. return -ETIMEDOUT;
  82. cpu_relax();
  83. }
  84. *data = (u16)Ser4SSDR;
  85. return 0;
  86. }
  87. /**
  88. * ssp_flush - flush the transmit and receive FIFOs
  89. *
  90. * Wait for the SSP to idle, and ensure that the receive FIFO
  91. * is empty.
  92. *
  93. * The caller is expected to perform the necessary locking.
  94. *
  95. * Returns:
  96. * %-ETIMEDOUT timeout occurred
  97. * 0 success
  98. */
  99. int ssp_flush(void)
  100. {
  101. int timeout = TIMEOUT * 2;
  102. do {
  103. while (Ser4SSSR & SSSR_RNE) {
  104. if (!--timeout)
  105. return -ETIMEDOUT;
  106. (void) Ser4SSDR;
  107. }
  108. if (!--timeout)
  109. return -ETIMEDOUT;
  110. } while (Ser4SSSR & SSSR_BSY);
  111. return 0;
  112. }
  113. /**
  114. * ssp_enable - enable the SSP port
  115. *
  116. * Turn on the SSP port.
  117. */
  118. void ssp_enable(void)
  119. {
  120. Ser4SSCR0 |= SSCR0_SSE;
  121. }
  122. /**
  123. * ssp_disable - shut down the SSP port
  124. *
  125. * Turn off the SSP port, optionally powering it down.
  126. */
  127. void ssp_disable(void)
  128. {
  129. Ser4SSCR0 &= ~SSCR0_SSE;
  130. }
  131. /**
  132. * ssp_save_state - save the SSP configuration
  133. * @ssp: pointer to structure to save SSP configuration
  134. *
  135. * Save the configured SSP state for suspend.
  136. */
  137. void ssp_save_state(struct ssp_state *ssp)
  138. {
  139. ssp->cr0 = Ser4SSCR0;
  140. ssp->cr1 = Ser4SSCR1;
  141. Ser4SSCR0 &= ~SSCR0_SSE;
  142. }
  143. /**
  144. * ssp_restore_state - restore a previously saved SSP configuration
  145. * @ssp: pointer to configuration saved by ssp_save_state
  146. *
  147. * Restore the SSP configuration saved previously by ssp_save_state.
  148. */
  149. void ssp_restore_state(struct ssp_state *ssp)
  150. {
  151. Ser4SSSR = SSSR_ROR;
  152. Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
  153. Ser4SSCR1 = ssp->cr1;
  154. Ser4SSCR0 = ssp->cr0;
  155. }
  156. /**
  157. * ssp_init - setup the SSP port
  158. *
  159. * initialise and claim resources for the SSP port.
  160. *
  161. * Returns:
  162. * %-ENODEV if the SSP port is unavailable
  163. * %-EBUSY if the resources are already in use
  164. * %0 on success
  165. */
  166. int ssp_init(void)
  167. {
  168. int ret;
  169. if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
  170. return -ENODEV;
  171. if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
  172. return -EBUSY;
  173. }
  174. Ser4SSSR = SSSR_ROR;
  175. ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
  176. if (ret)
  177. goto out_region;
  178. return 0;
  179. out_region:
  180. release_mem_region(__PREG(Ser4SSCR0), 0x18);
  181. return ret;
  182. }
  183. /**
  184. * ssp_exit - undo the effects of ssp_init
  185. *
  186. * release and free resources for the SSP port.
  187. */
  188. void ssp_exit(void)
  189. {
  190. Ser4SSCR0 &= ~SSCR0_SSE;
  191. free_irq(IRQ_Ser4SSP, NULL);
  192. release_mem_region(__PREG(Ser4SSCR0), 0x18);
  193. }
  194. MODULE_AUTHOR("Russell King");
  195. MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
  196. MODULE_LICENSE("GPL");
  197. EXPORT_SYMBOL(ssp_write_word);
  198. EXPORT_SYMBOL(ssp_read_word);
  199. EXPORT_SYMBOL(ssp_flush);
  200. EXPORT_SYMBOL(ssp_enable);
  201. EXPORT_SYMBOL(ssp_disable);
  202. EXPORT_SYMBOL(ssp_save_state);
  203. EXPORT_SYMBOL(ssp_restore_state);
  204. EXPORT_SYMBOL(ssp_init);
  205. EXPORT_SYMBOL(ssp_exit);