util.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /***************************************************************************
  2. nec7210/util.c
  3. -------------------
  4. begin : Dec 2001
  5. copyright : (C) 2001, 2002 by Frank Mori Hess
  6. email : fmhess@users.sourceforge.net
  7. ***************************************************************************/
  8. /***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************/
  16. #include "board.h"
  17. #include <linux/delay.h>
  18. int nec7210_enable_eos(gpib_board_t *board, nec7210_private_t *priv, uint8_t eos_byte, int compare_8_bits)
  19. {
  20. write_byte(priv, eos_byte, EOSR);
  21. priv->auxa_bits |= HR_REOS;
  22. if(compare_8_bits)
  23. priv->auxa_bits |= HR_BIN;
  24. else
  25. priv->auxa_bits &= ~HR_BIN;
  26. write_byte(priv, priv->auxa_bits, AUXMR);
  27. return 0;
  28. }
  29. void nec7210_disable_eos(gpib_board_t *board, nec7210_private_t *priv)
  30. {
  31. priv->auxa_bits &= ~HR_REOS;
  32. write_byte(priv, priv->auxa_bits, AUXMR);
  33. }
  34. int nec7210_parallel_poll(gpib_board_t *board, nec7210_private_t *priv, uint8_t *result)
  35. {
  36. int ret;
  37. clear_bit(COMMAND_READY_BN, &priv->state);
  38. // execute parallel poll
  39. write_byte(priv, AUX_EPP, AUXMR);
  40. // wait for result FIXME: support timeouts
  41. ret = wait_event_interruptible(board->wait, test_bit(COMMAND_READY_BN, &priv->state));
  42. if(ret)
  43. {
  44. printk("gpib: parallel poll interrupted\n");
  45. return -ERESTARTSYS;
  46. }
  47. *result = read_byte(priv, CPTR);
  48. return 0;
  49. }
  50. void nec7210_parallel_poll_configure( gpib_board_t *board,
  51. nec7210_private_t *priv, unsigned int configuration )
  52. {
  53. write_byte( priv, PPR | configuration , AUXMR );
  54. }
  55. void nec7210_parallel_poll_response( gpib_board_t *board, nec7210_private_t *priv, int ist )
  56. {
  57. if( ist )
  58. write_byte( priv, AUX_SPPF , AUXMR );
  59. else
  60. write_byte( priv, AUX_CPPF , AUXMR );
  61. }
  62. void nec7210_serial_poll_response(gpib_board_t *board, nec7210_private_t *priv, uint8_t status)
  63. {
  64. unsigned long flags;
  65. spin_lock_irqsave( &board->spinlock, flags );
  66. if(status & request_service_bit)
  67. priv->srq_pending = 1;
  68. else
  69. priv->srq_pending = 0;
  70. clear_bit(SPOLL_NUM, &board->status);
  71. write_byte(priv, status, SPMR);
  72. spin_unlock_irqrestore( &board->spinlock, flags );
  73. }
  74. uint8_t nec7210_serial_poll_status( gpib_board_t *board, nec7210_private_t *priv )
  75. {
  76. return read_byte(priv, SPSR);
  77. }
  78. void nec7210_primary_address(const gpib_board_t *board, nec7210_private_t *priv, unsigned int address)
  79. {
  80. // put primary address in address0
  81. write_byte(priv, address & ADDRESS_MASK, ADR);
  82. }
  83. void nec7210_secondary_address(const gpib_board_t *board, nec7210_private_t *priv, unsigned int address, int enable)
  84. {
  85. if(enable)
  86. {
  87. // put secondary address in address1
  88. write_byte(priv, HR_ARS | (address & ADDRESS_MASK), ADR);
  89. // go to address mode 2
  90. priv->reg_bits[ ADMR ] &= ~HR_ADM0;
  91. priv->reg_bits[ ADMR ] |= HR_ADM1;
  92. }else
  93. {
  94. // disable address1 register
  95. write_byte(priv, HR_ARS | HR_DT | HR_DL, ADR);
  96. // go to address mode 1
  97. priv->reg_bits[ ADMR ] |= HR_ADM0;
  98. priv->reg_bits[ ADMR ] &= ~HR_ADM1;
  99. }
  100. write_byte( priv, priv->reg_bits[ ADMR ], ADMR );
  101. }
  102. static void update_talker_state(nec7210_private_t *priv, unsigned address_status_bits)
  103. {
  104. if((address_status_bits & HR_TA))
  105. {
  106. if((address_status_bits & HR_NATN))
  107. {
  108. if(address_status_bits & HR_SPMS)
  109. {
  110. priv->talker_state = serial_poll_active;
  111. }else
  112. {
  113. priv->talker_state = talker_active;
  114. }
  115. }else
  116. {
  117. priv->talker_state = talker_addressed;
  118. }
  119. }else
  120. {
  121. priv->talker_state = talker_idle;
  122. }
  123. }
  124. static void update_listener_state(nec7210_private_t *priv, unsigned address_status_bits)
  125. {
  126. if(address_status_bits & HR_LA)
  127. {
  128. if((address_status_bits & HR_NATN))
  129. {
  130. priv->listener_state = listener_active;
  131. }else
  132. {
  133. priv->listener_state = listener_addressed;
  134. }
  135. }else
  136. {
  137. priv->listener_state = listener_idle;
  138. }
  139. }
  140. unsigned int update_status_nolock( gpib_board_t *board, nec7210_private_t *priv )
  141. {
  142. int address_status_bits;
  143. uint8_t spoll_status;
  144. if(priv == NULL) return 0;
  145. address_status_bits = read_byte(priv, ADSR);
  146. if(address_status_bits & HR_CIC)
  147. set_bit(CIC_NUM, &board->status);
  148. else
  149. clear_bit(CIC_NUM, &board->status);
  150. // check for talker/listener addressed
  151. update_talker_state(priv, address_status_bits);
  152. if(priv->talker_state == talker_active)
  153. {
  154. set_bit(TACS_NUM, &board->status);
  155. }else
  156. clear_bit(TACS_NUM, &board->status);
  157. update_listener_state(priv, address_status_bits);
  158. if(priv->listener_state == listener_active)
  159. {
  160. set_bit(LACS_NUM, &board->status);
  161. }else
  162. clear_bit(LACS_NUM, &board->status);
  163. if(address_status_bits & HR_NATN)
  164. {
  165. clear_bit(ATN_NUM, &board->status);
  166. }else
  167. {
  168. set_bit(ATN_NUM, &board->status);
  169. }
  170. spoll_status = nec7210_serial_poll_status(board, priv);
  171. if(priv->srq_pending && (spoll_status & request_service_bit) == 0)
  172. {
  173. priv->srq_pending = 0;
  174. set_bit(SPOLL_NUM, &board->status);
  175. }
  176. // GPIB_DPRINTK( "status 0x%x, state 0x%x\n", board->status, priv->state );
  177. /* we rely on the interrupt handler to set the
  178. * rest of the status bits */
  179. return board->status;
  180. }
  181. unsigned int nec7210_update_status(gpib_board_t *board, nec7210_private_t *priv,
  182. unsigned int clear_mask )
  183. {
  184. unsigned long flags;
  185. unsigned int retval;
  186. spin_lock_irqsave( &board->spinlock, flags );
  187. board->status &= ~clear_mask;
  188. retval = update_status_nolock( board, priv );
  189. spin_unlock_irqrestore( &board->spinlock, flags );
  190. return retval;
  191. }
  192. unsigned int nec7210_set_reg_bits( nec7210_private_t *priv, unsigned int reg,
  193. unsigned int mask, unsigned int bits )
  194. {
  195. priv->reg_bits[ reg ] &= ~mask;
  196. priv->reg_bits[ reg ] |= mask & bits;
  197. write_byte( priv, priv->reg_bits[ reg ], reg );
  198. return priv->reg_bits[ reg ];
  199. }
  200. void nec7210_set_handshake_mode( gpib_board_t *board, nec7210_private_t *priv, int mode )
  201. {
  202. unsigned long flags;
  203. spin_lock_irqsave( &board->spinlock, flags );
  204. priv->auxa_bits &= ~HR_HANDSHAKE_MASK;
  205. priv->auxa_bits |= ( mode & HR_HANDSHAKE_MASK );
  206. write_byte( priv, priv->auxa_bits, AUXMR );
  207. spin_unlock_irqrestore( &board->spinlock, flags );
  208. }
  209. uint8_t nec7210_read_data_in( gpib_board_t *board, nec7210_private_t *priv, int *end )
  210. {
  211. unsigned long flags;
  212. uint8_t data;
  213. spin_lock_irqsave( &board->spinlock, flags );
  214. data = read_byte( priv, DIR );
  215. clear_bit( READ_READY_BN, &priv->state );
  216. if( test_and_clear_bit( RECEIVED_END_BN, &priv->state ) )
  217. *end = 1;
  218. else
  219. *end = 0;
  220. spin_unlock_irqrestore( &board->spinlock, flags );
  221. return data;
  222. }
  223. EXPORT_SYMBOL( nec7210_enable_eos );
  224. EXPORT_SYMBOL( nec7210_disable_eos );
  225. EXPORT_SYMBOL( nec7210_serial_poll_response );
  226. EXPORT_SYMBOL( nec7210_serial_poll_status );
  227. EXPORT_SYMBOL( nec7210_parallel_poll_configure );
  228. EXPORT_SYMBOL( nec7210_parallel_poll_response );
  229. EXPORT_SYMBOL( nec7210_parallel_poll );
  230. EXPORT_SYMBOL( nec7210_primary_address );
  231. EXPORT_SYMBOL( nec7210_secondary_address );
  232. EXPORT_SYMBOL( nec7210_update_status );
  233. EXPORT_SYMBOL( nec7210_set_reg_bits );
  234. EXPORT_SYMBOL( nec7210_set_handshake_mode );
  235. EXPORT_SYMBOL( nec7210_read_data_in );