wcxb.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * wcxb SPI library
  3. *
  4. * Copyright (C) 2013 Digium, Inc.
  5. *
  6. * All rights reserved.
  7. *
  8. */
  9. /*
  10. * See http://www.asterisk.org for more information about
  11. * the Asterisk project. Please do not directly contact
  12. * any of the maintainers of this project for assistance;
  13. * the project provides a web site, mailing lists and IRC
  14. * channels for your use.
  15. *
  16. * This program is free software, distributed under the terms of
  17. * the GNU General Public License Version 2 as published by the
  18. * Free Software Foundation. See the LICENSE file included with
  19. * this program for more details.
  20. */
  21. #ifndef __WCXB_H__
  22. #define __WCXB_H__
  23. #define WCXB_DEFAULT_LATENCY 3U
  24. #define WCXB_DEFAULT_MAXLATENCY 12U
  25. #define WCXB_DMA_CHAN_SIZE 128
  26. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
  27. /* The is_pcie member was backported but I'm not sure in which version. */
  28. # ifndef RHEL_RELEASE_VERSION
  29. #define WCXB_PCI_DEV_DOES_NOT_HAVE_IS_PCIE
  30. # endif
  31. #else
  32. #endif
  33. struct wcxb;
  34. struct wcxb_operations {
  35. void (*handle_receive)(struct wcxb *xb, void *frame);
  36. void (*handle_transmit)(struct wcxb *xb, void *frame);
  37. void (*handle_error)(struct wcxb *xb);
  38. void (*handle_interrupt)(struct wcxb *xb, u32 pending);
  39. };
  40. struct wcxb_meta_desc;
  41. struct wcxb_hw_desc;
  42. /**
  43. * struct wcxb - Interface to wcxb firmware.
  44. * @last_retry_count: Running count of times firmware had to retry host DMA
  45. * transaction. Debugging aide.
  46. */
  47. struct wcxb {
  48. struct pci_dev *pdev;
  49. spinlock_t lock;
  50. const struct wcxb_operations *ops;
  51. unsigned int *debug;
  52. unsigned int max_latency;
  53. unsigned int latency;
  54. struct {
  55. u32 have_msi:1;
  56. u32 latency_locked:1;
  57. u32 drive_timing_cable:1;
  58. #ifdef WCXB_PCI_DEV_DOES_NOT_HAVE_IS_PCIE
  59. u32 is_pcie:1;
  60. #endif
  61. u32 dma_ins:1;
  62. } flags;
  63. void __iomem *membase;
  64. struct wcxb_meta_desc *meta_dring;
  65. struct wcxb_hw_desc *hw_dring;
  66. unsigned int dma_head;
  67. unsigned int dma_tail;
  68. dma_addr_t hw_dring_phys;
  69. struct dma_pool *pool;
  70. unsigned long framecount;
  71. #ifdef DEBUG
  72. u8 last_retry_count;
  73. u8 max_retry_count;
  74. u32 last_dma_time;
  75. u32 max_dma_time;
  76. #endif
  77. };
  78. extern int wcxb_init(struct wcxb *xb, const char *board_name, u32 int_mode);
  79. extern void wcxb_release(struct wcxb *xb);
  80. extern int wcxb_start(struct wcxb *xb);
  81. extern void wcxb_stop(struct wcxb *xb);
  82. extern int wcxb_wait_for_stop(struct wcxb *xb, unsigned long timeout_ms);
  83. extern bool wcxb_is_stopped(struct wcxb *xb);
  84. enum wcxb_clock_sources {
  85. WCXB_CLOCK_SELF, /* Use the internal oscillator for timing. */
  86. WCXB_CLOCK_RECOVER, /* Recover the clock from a framer. */
  87. #ifdef RPC_RCLK
  88. WCXB_CLOCK_RECOVER_ALT, /* Recover the clock from a framer. */
  89. #endif
  90. WCXB_CLOCK_SLAVE /* Recover clock from any timing header. */
  91. };
  92. extern enum wcxb_clock_sources wcxb_get_clksrc(struct wcxb *xb);
  93. extern void wcxb_set_clksrc(struct wcxb *xb, enum wcxb_clock_sources clksrc);
  94. static inline void wcxb_enable_timing_header_driver(struct wcxb *xb)
  95. {
  96. xb->flags.drive_timing_cable = 1;
  97. }
  98. static inline bool wcxb_is_timing_header_driver_enabled(struct wcxb *xb)
  99. {
  100. return 1 == xb->flags.drive_timing_cable;
  101. }
  102. static inline void wcxb_disable_timing_header_driver(struct wcxb *xb)
  103. {
  104. xb->flags.drive_timing_cable = 0;
  105. }
  106. enum wcxb_reset_option {
  107. WCXB_RESET_NOW,
  108. WCXB_RESET_LATER
  109. };
  110. extern u32 wcxb_get_firmware_version(struct wcxb *xb);
  111. extern int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
  112. const char *firmware_filename,
  113. bool force_firmware,
  114. enum wcxb_reset_option reset);
  115. extern void wcxb_stop_dma(struct wcxb *xb);
  116. extern void wcxb_disable_interrupts(struct wcxb *xb);
  117. static inline void wcxb_gpio_set(struct wcxb *xb, u32 bits)
  118. {
  119. u32 reg;
  120. unsigned long flags;
  121. spin_lock_irqsave(&xb->lock, flags);
  122. reg = ioread32be(xb->membase);
  123. iowrite32be(reg | bits, xb->membase);
  124. spin_unlock_irqrestore(&xb->lock, flags);
  125. }
  126. static inline void wcxb_gpio_clear(struct wcxb *xb, u32 bits)
  127. {
  128. u32 reg;
  129. unsigned long flags;
  130. spin_lock_irqsave(&xb->lock, flags);
  131. reg = ioread32be(xb->membase);
  132. iowrite32be(reg & (~bits), xb->membase);
  133. spin_unlock_irqrestore(&xb->lock, flags);
  134. }
  135. static inline void
  136. wcxb_set_maxlatency(struct wcxb *xb, unsigned int max_latency)
  137. {
  138. unsigned long flags;
  139. spin_lock_irqsave(&xb->lock, flags);
  140. xb->max_latency = clamp(max_latency,
  141. xb->latency,
  142. WCXB_DEFAULT_MAXLATENCY);
  143. spin_unlock_irqrestore(&xb->lock, flags);
  144. }
  145. static inline void
  146. wcxb_set_minlatency(struct wcxb *xb, unsigned int min_latency)
  147. {
  148. unsigned long flags;
  149. spin_lock_irqsave(&xb->lock, flags);
  150. xb->latency = clamp(min_latency, WCXB_DEFAULT_LATENCY,
  151. WCXB_DEFAULT_MAXLATENCY);
  152. spin_unlock_irqrestore(&xb->lock, flags);
  153. }
  154. static inline void
  155. wcxb_lock_latency(struct wcxb *xb)
  156. {
  157. unsigned long flags;
  158. spin_lock_irqsave(&xb->lock, flags);
  159. xb->flags.latency_locked = 1;
  160. spin_unlock_irqrestore(&xb->lock, flags);
  161. return;
  162. }
  163. static inline void
  164. wcxb_unlock_latency(struct wcxb *xb)
  165. {
  166. unsigned long flags;
  167. spin_lock_irqsave(&xb->lock, flags);
  168. xb->flags.latency_locked = 0;
  169. spin_unlock_irqrestore(&xb->lock, flags);
  170. return;
  171. }
  172. /* Interface for the echocan block */
  173. extern void wcxb_enable_echocan(struct wcxb *xb);
  174. extern void wcxb_disable_echocan(struct wcxb *xb);
  175. extern void wcxb_reset_echocan(struct wcxb *xb);
  176. extern void wcxb_enable_echocan_dram(struct wcxb *xb);
  177. extern bool wcxb_is_echocan_present(struct wcxb *xb);
  178. extern u16 wcxb_get_echocan_reg(struct wcxb *xb, u32 address);
  179. extern void wcxb_set_echocan_reg(struct wcxb *xb, u32 address, u16 val);
  180. #endif