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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: s0box.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * low level stuff for Creatix S0BOX
  4.  *
  5.  * Author       Enrik Berkhan
  6.  * Copyright    by Enrik Berkhan <enrik@starfleet.inka.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.  */
  12. #define __NO_VERSION__
  13. #include <linux/init.h>
  14. #include "hisax.h"
  15. #include "isac.h"
  16. #include "hscx.h"
  17. #include "isdnl1.h"
  18. extern const char *CardType[];
  19. const char *s0box_revision = "$Revision: 1.1.4.1 $";
  20. static inline void
  21. writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
  22. unsigned long flags;
  23. save_flags(flags);
  24. cli();
  25. outb_p(0x1c,padr+2);
  26. outb_p(0x14,padr+2);
  27. outb_p((addr+off)&0x7f,padr);
  28. outb_p(0x16,padr+2);
  29. outb_p(val,padr);
  30. outb_p(0x17,padr+2);
  31. outb_p(0x14,padr+2);
  32. outb_p(0x1c,padr+2);
  33. restore_flags(flags);
  34. }
  35. static u_char nibtab[] = { 1, 9, 5, 0xd, 3, 0xb, 7, 0xf,
  36.  0, 0, 0, 0, 0, 0, 0, 0,
  37.  0, 8, 4, 0xc, 2, 0xa, 6, 0xe } ;
  38. static inline u_char
  39. readreg(unsigned int padr, signed int addr, u_char off) {
  40. register u_char n1, n2;
  41. unsigned long flags;
  42. save_flags(flags);
  43. cli();
  44. outb_p(0x1c,padr+2);
  45. outb_p(0x14,padr+2);
  46. outb_p((addr+off)|0x80,padr);
  47. outb_p(0x16,padr+2);
  48. outb_p(0x17,padr+2);
  49. n1 = (inb_p(padr+1) >> 3) & 0x17;
  50. outb_p(0x16,padr+2);
  51. n2 = (inb_p(padr+1) >> 3) & 0x17;
  52. outb_p(0x14,padr+2);
  53. outb_p(0x1c,padr+2);
  54. restore_flags(flags);
  55. return nibtab[n1] | (nibtab[n2] << 4);
  56. }
  57. static inline void
  58. read_fifo(unsigned int padr, signed int adr, u_char * data, int size)
  59. {
  60. int i;
  61. register u_char n1, n2;
  62. outb_p(0x1c, padr+2);
  63. outb_p(0x14, padr+2);
  64. outb_p(adr|0x80, padr);
  65. outb_p(0x16, padr+2);
  66. for (i=0; i<size; i++) {
  67. outb_p(0x17, padr+2);
  68. n1 = (inb_p(padr+1) >> 3) & 0x17;
  69. outb_p(0x16,padr+2);
  70. n2 = (inb_p(padr+1) >> 3) & 0x17;
  71. *(data++)=nibtab[n1] | (nibtab[n2] << 4);
  72. }
  73. outb_p(0x14,padr+2);
  74. outb_p(0x1c,padr+2);
  75. return;
  76. }
  77. static inline void
  78. write_fifo(unsigned int padr, signed int adr, u_char * data, int size)
  79. {
  80. int i;
  81. outb_p(0x1c, padr+2);
  82. outb_p(0x14, padr+2);
  83. outb_p(adr&0x7f, padr);
  84. for (i=0; i<size; i++) {
  85. outb_p(0x16, padr+2);
  86. outb_p(*(data++), padr);
  87. outb_p(0x17, padr+2);
  88. }
  89. outb_p(0x14,padr+2);
  90. outb_p(0x1c,padr+2);
  91. return;
  92. }
  93. /* Interface functions */
  94. static u_char
  95. ReadISAC(struct IsdnCardState *cs, u_char offset)
  96. {
  97. return (readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, offset));
  98. }
  99. static void
  100. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  101. {
  102. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, offset, value);
  103. }
  104. static void
  105. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  106. {
  107. read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size);
  108. }
  109. static void
  110. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  111. {
  112. write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size);
  113. }
  114. static u_char
  115. ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
  116. {
  117. return (readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[hscx], offset));
  118. }
  119. static void
  120. WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  121. {
  122. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[hscx], offset, value);
  123. }
  124. /*
  125.  * fast interrupt HSCX stuff goes here
  126.  */
  127. #define READHSCX(cs, nr, reg) readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[nr], reg)
  128. #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[nr], reg, data)
  129. #define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscxfifo[nr], ptr, cnt)
  130. #define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscxfifo[nr], ptr, cnt)
  131. #include "hscx_irq.c"
  132. static void
  133. s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs)
  134. {
  135. #define MAXCOUNT 5
  136. struct IsdnCardState *cs = dev_id;
  137. u_char val;
  138. int count = 0;
  139. if (!cs) {
  140. printk(KERN_WARNING "Teles: Spurious interrupt!n");
  141. return;
  142. }
  143. val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA);
  144.       Start_HSCX:
  145. if (val)
  146. hscx_int_main(cs, val);
  147. val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA);
  148.       Start_ISAC:
  149. if (val)
  150. isac_interrupt(cs, val);
  151. count++;
  152. val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA);
  153. if (val && count < MAXCOUNT) {
  154. if (cs->debug & L1_DEB_HSCX)
  155. debugl1(cs, "HSCX IntStat after IntRoutine");
  156. goto Start_HSCX;
  157. }
  158. val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA);
  159. if (val && count < MAXCOUNT) {
  160. if (cs->debug & L1_DEB_ISAC)
  161. debugl1(cs, "ISAC IntStat after IntRoutine");
  162. goto Start_ISAC;
  163. }
  164. if (count >= MAXCOUNT)
  165. printk(KERN_WARNING "S0Box: more than %d loops in s0box_interruptn", count);
  166. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF);
  167. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF);
  168. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0xFF);
  169. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0x0);
  170. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0x0);
  171. writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0x0);
  172. }
  173. void
  174. release_io_s0box(struct IsdnCardState *cs)
  175. {
  176. release_region(cs->hw.teles3.cfg_reg, 8);
  177. }
  178. static int
  179. S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  180. {
  181. switch (mt) {
  182. case CARD_RESET:
  183. break;
  184. case CARD_RELEASE:
  185. release_io_s0box(cs);
  186. break;
  187. case CARD_INIT:
  188. inithscxisac(cs, 3);
  189. break;
  190. case CARD_TEST:
  191. break;
  192. }
  193. return(0);
  194. }
  195. int __init
  196. setup_s0box(struct IsdnCard *card)
  197. {
  198. struct IsdnCardState *cs = card->cs;
  199. char tmp[64];
  200. strcpy(tmp, s0box_revision);
  201. printk(KERN_INFO "HiSax: S0Box IO driver Rev. %sn", HiSax_getrev(tmp));
  202. if (cs->typ != ISDN_CTYPE_S0BOX)
  203. return (0);
  204. cs->hw.teles3.cfg_reg = card->para[1];
  205. cs->hw.teles3.hscx[0] = -0x20;
  206. cs->hw.teles3.hscx[1] = 0x0;
  207. cs->hw.teles3.isac = 0x20;
  208. cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e;
  209. cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
  210. cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
  211. cs->irq = card->para[0];
  212. if (check_region(cs->hw.teles3.cfg_reg,8)) {
  213. printk(KERN_WARNING
  214.        "HiSax: %s ports %x-%x already in usen",
  215.        CardType[cs->typ],
  216.                        cs->hw.teles3.cfg_reg,
  217.                        cs->hw.teles3.cfg_reg + 7);
  218. return 0;
  219. } else
  220. request_region(cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O");
  221. printk(KERN_INFO
  222.        "HiSax: %s config irq:%d isac:0x%x  cfg:0x%xn",
  223.        CardType[cs->typ], cs->irq,
  224.        cs->hw.teles3.isac, cs->hw.teles3.cfg_reg);
  225. printk(KERN_INFO
  226.        "HiSax: hscx A:0x%x  hscx B:0x%xn",
  227.        cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]);
  228. cs->readisac = &ReadISAC;
  229. cs->writeisac = &WriteISAC;
  230. cs->readisacfifo = &ReadISACfifo;
  231. cs->writeisacfifo = &WriteISACfifo;
  232. cs->BC_Read_Reg = &ReadHSCX;
  233. cs->BC_Write_Reg = &WriteHSCX;
  234. cs->BC_Send_Data = &hscx_fill_fifo;
  235. cs->cardmsg = &S0Box_card_msg;
  236. cs->irq_func = &s0box_interrupt;
  237. ISACVersion(cs, "S0Box:");
  238. if (HscxVersion(cs, "S0Box:")) {
  239. printk(KERN_WARNING
  240.        "S0Box: wrong HSCX versions check IO addressn");
  241. release_io_s0box(cs);
  242. return (0);
  243. }
  244. return (1);
  245. }