saphir.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: saphir.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * low level stuff for HST Saphir 1
  4.  *
  5.  * Author       Karsten Keil
  6.  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  7.  * 
  8.  * This software may be used and distributed according to the terms
  9.  * of the GNU General Public License, incorporated herein by reference.
  10.  *
  11.  * Thanks to    HST High Soft Tech GmbH
  12.  *
  13.  */
  14. #define __NO_VERSION__
  15. #include <linux/init.h>
  16. #include "hisax.h"
  17. #include "isac.h"
  18. #include "hscx.h"
  19. #include "isdnl1.h"
  20. extern const char *CardType[];
  21. static char *saphir_rev = "$Revision: 1.1.4.1 $";
  22. #define byteout(addr,val) outb(val,addr)
  23. #define bytein(addr) inb(addr)
  24. #define ISAC_DATA 0
  25. #define HSCX_DATA 1
  26. #define ADDRESS_REG 2
  27. #define IRQ_REG 3
  28. #define SPARE_REG 4
  29. #define RESET_REG 5
  30. static inline u_char
  31. readreg(unsigned int ale, unsigned int adr, u_char off)
  32. {
  33. register u_char ret;
  34. long flags;
  35. save_flags(flags);
  36. cli();
  37. byteout(ale, off);
  38. ret = bytein(adr);
  39. restore_flags(flags);
  40. return (ret);
  41. }
  42. static inline void
  43. readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  44. {
  45. /* fifo read without cli because it's allready done  */
  46. byteout(ale, off);
  47. insb(adr, data, size);
  48. }
  49. static inline void
  50. writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
  51. {
  52. long flags;
  53. save_flags(flags);
  54. cli();
  55. byteout(ale, off);
  56. byteout(adr, data);
  57. restore_flags(flags);
  58. }
  59. static inline void
  60. writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  61. {
  62. /* fifo write without cli because it's allready done  */
  63. byteout(ale, off);
  64. outsb(adr, data, size);
  65. }
  66. /* Interface functions */
  67. static u_char
  68. ReadISAC(struct IsdnCardState *cs, u_char offset)
  69. {
  70. return (readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset));
  71. }
  72. static void
  73. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  74. {
  75. writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset, value);
  76. }
  77. static void
  78. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  79. {
  80. readfifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
  81. }
  82. static void
  83. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  84. {
  85. writefifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
  86. }
  87. static u_char
  88. ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
  89. {
  90. return (readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
  91. offset + (hscx ? 0x40 : 0)));
  92. }
  93. static void
  94. WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  95. {
  96. writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
  97. offset + (hscx ? 0x40 : 0), value);
  98. }
  99. #define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, 
  100. cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
  101. #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, 
  102. cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
  103. #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, 
  104. cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
  105. #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, 
  106. cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
  107. #include "hscx_irq.c"
  108. static void
  109. saphir_interrupt(int intno, void *dev_id, struct pt_regs *regs)
  110. {
  111. struct IsdnCardState *cs = dev_id;
  112. u_char val;
  113. if (!cs) {
  114. printk(KERN_WARNING "saphir: Spurious interrupt!n");
  115. return;
  116. }
  117. val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
  118.       Start_HSCX:
  119. if (val)
  120. hscx_int_main(cs, val);
  121. val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
  122.       Start_ISAC:
  123. if (val)
  124. isac_interrupt(cs, val);
  125. val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
  126. if (val) {
  127. if (cs->debug & L1_DEB_HSCX)
  128. debugl1(cs, "HSCX IntStat after IntRoutine");
  129. goto Start_HSCX;
  130. }
  131. val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
  132. if (val) {
  133. if (cs->debug & L1_DEB_ISAC)
  134. debugl1(cs, "ISAC IntStat after IntRoutine");
  135. goto Start_ISAC;
  136. }
  137. /* Watchdog */
  138. if (cs->hw.saphir.timer.function) 
  139. mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
  140. else
  141. printk(KERN_WARNING "saphir: Spurious timer!n");
  142. writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0xFF);
  143. writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0xFF);
  144. writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0xFF);
  145. writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0);
  146. writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0);
  147. writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0);
  148. }
  149. static void
  150. SaphirWatchDog(struct IsdnCardState *cs)
  151. {
  152.         /* 5 sec WatchDog, so read at least every 4 sec */
  153. cs->readisac(cs, ISAC_RBCH);
  154. mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
  155. }
  156. void
  157. release_io_saphir(struct IsdnCardState *cs)
  158. {
  159. long flags;
  160. save_flags(flags);
  161. cli();
  162. byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
  163. del_timer(&cs->hw.saphir.timer);
  164. cs->hw.saphir.timer.function = NULL;
  165. restore_flags(flags);
  166. if (cs->hw.saphir.cfg_reg)
  167. release_region(cs->hw.saphir.cfg_reg, 6);
  168. }
  169. static int
  170. saphir_reset(struct IsdnCardState *cs)
  171. {
  172. long flags;
  173. u_char irq_val;
  174. switch(cs->irq) {
  175. case 5: irq_val = 0;
  176. break;
  177. case 3: irq_val = 1;
  178. break;
  179. case 11:
  180. irq_val = 2;
  181. break;
  182. case 12:
  183. irq_val = 3;
  184. break;
  185. case 15:
  186. irq_val = 4;
  187. break;
  188. default:
  189. printk(KERN_WARNING "HiSax: saphir wrong IRQ %dn",
  190. cs->irq);
  191. return (1);
  192. }
  193. byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
  194. save_flags(flags);
  195. sti();
  196. byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1);
  197. set_current_state(TASK_UNINTERRUPTIBLE);
  198. schedule_timeout((30*HZ)/1000); /* Timeout 30ms */
  199. byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0);
  200. set_current_state(TASK_UNINTERRUPTIBLE);
  201. schedule_timeout((30*HZ)/1000); /* Timeout 30ms */
  202. restore_flags(flags);
  203. byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
  204. byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02);
  205. return (0);
  206. }
  207. static int
  208. saphir_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  209. {
  210. switch (mt) {
  211. case CARD_RESET:
  212. saphir_reset(cs);
  213. return(0);
  214. case CARD_RELEASE:
  215. release_io_saphir(cs);
  216. return(0);
  217. case CARD_INIT:
  218. inithscxisac(cs, 3);
  219. return(0);
  220. case CARD_TEST:
  221. return(0);
  222. }
  223. return(0);
  224. }
  225. int __init
  226. setup_saphir(struct IsdnCard *card)
  227. {
  228. struct IsdnCardState *cs = card->cs;
  229. char tmp[64];
  230. strcpy(tmp, saphir_rev);
  231. printk(KERN_INFO "HiSax: HST Saphir driver Rev. %sn", HiSax_getrev(tmp));
  232. if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
  233. return (0);
  234. /* IO-Ports */
  235. cs->hw.saphir.cfg_reg = card->para[1];
  236. cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
  237. cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
  238. cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
  239. cs->irq = card->para[0];
  240. if (check_region((cs->hw.saphir.cfg_reg), 6)) {
  241. printk(KERN_WARNING
  242. "HiSax: %s config port %x-%x already in usen",
  243. CardType[card->typ],
  244. cs->hw.saphir.cfg_reg,
  245. cs->hw.saphir.cfg_reg + 5);
  246. return (0);
  247. } else
  248. request_region(cs->hw.saphir.cfg_reg,6, "saphir");
  249. printk(KERN_INFO
  250.        "HiSax: %s config irq:%d io:0x%Xn",
  251.        CardType[cs->typ], cs->irq,
  252.        cs->hw.saphir.cfg_reg);
  253. cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
  254. cs->hw.saphir.timer.data = (long) cs;
  255. init_timer(&cs->hw.saphir.timer);
  256. cs->hw.saphir.timer.expires = jiffies + 4*HZ;
  257. add_timer(&cs->hw.saphir.timer);
  258. if (saphir_reset(cs)) {
  259. release_io_saphir(cs);
  260. return (0);
  261. }
  262. cs->readisac = &ReadISAC;
  263. cs->writeisac = &WriteISAC;
  264. cs->readisacfifo = &ReadISACfifo;
  265. cs->writeisacfifo = &WriteISACfifo;
  266. cs->BC_Read_Reg = &ReadHSCX;
  267. cs->BC_Write_Reg = &WriteHSCX;
  268. cs->BC_Send_Data = &hscx_fill_fifo;
  269. cs->cardmsg = &saphir_card_msg;
  270. cs->irq_func = &saphir_interrupt;
  271. ISACVersion(cs, "saphir:");
  272. if (HscxVersion(cs, "saphir:")) {
  273. printk(KERN_WARNING
  274.     "saphir: wrong HSCX versions check IO addressn");
  275. release_io_saphir(cs);
  276. return (0);
  277. }
  278. return (1);
  279. }