ssp.c 4.3 KB

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