ix1_micro.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: ix1_micro.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * low level stuff for ITK ix1-micro Rev.2 isdn cards
  4.  * derived from the original file teles3.c from Karsten Keil
  5.  *
  6.  * Author       Klaus-Peter Nischke
  7.  * Copyright    by Klaus-Peter Nischke, ITK AG
  8.  *                                   <klaus@nischke.do.eunet.de>
  9.  *              by Karsten Keil      <keil@isdn4linux.de>
  10.  * 
  11.  * This software may be used and distributed according to the terms
  12.  * of the GNU General Public License, incorporated herein by reference.
  13.  *
  14.  * Klaus-Peter Nischke
  15.  * Deusener Str. 287
  16.  * 44369 Dortmund
  17.  * Germany
  18.  */
  19. #define __NO_VERSION__
  20. #include <linux/init.h>
  21. #include "hisax.h"
  22. #include "isac.h"
  23. #include "hscx.h"
  24. #include "isdnl1.h"
  25. extern const char *CardType[];
  26. const char *ix1_revision = "$Revision: 1.1.4.1 $";
  27. #define byteout(addr,val) outb(val,addr)
  28. #define bytein(addr) inb(addr)
  29. #define SPECIAL_PORT_OFFSET 3
  30. #define ISAC_COMMAND_OFFSET 2
  31. #define ISAC_DATA_OFFSET 0
  32. #define HSCX_COMMAND_OFFSET 2
  33. #define HSCX_DATA_OFFSET 1
  34. #define TIMEOUT 50
  35. static inline u_char
  36. readreg(unsigned int ale, unsigned int adr, u_char off)
  37. {
  38. register u_char ret;
  39. long flags;
  40. save_flags(flags);
  41. cli();
  42. byteout(ale, off);
  43. ret = bytein(adr);
  44. restore_flags(flags);
  45. return (ret);
  46. }
  47. static inline void
  48. readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  49. {
  50. /* fifo read without cli because it's allready done  */
  51. byteout(ale, off);
  52. insb(adr, data, size);
  53. }
  54. static inline void
  55. writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
  56. {
  57. long flags;
  58. save_flags(flags);
  59. cli();
  60. byteout(ale, off);
  61. byteout(adr, data);
  62. restore_flags(flags);
  63. }
  64. static inline void
  65. writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  66. {
  67. /* fifo write without cli because it's allready done  */
  68. byteout(ale, off);
  69. outsb(adr, data, size);
  70. }
  71. /* Interface functions */
  72. static u_char
  73. ReadISAC(struct IsdnCardState *cs, u_char offset)
  74. {
  75. return (readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, offset));
  76. }
  77. static void
  78. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  79. {
  80. writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, offset, value);
  81. }
  82. static void
  83. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  84. {
  85. readfifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size);
  86. }
  87. static void
  88. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  89. {
  90. writefifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size);
  91. }
  92. static u_char
  93. ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
  94. {
  95. return (readreg(cs->hw.ix1.hscx_ale,
  96. cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0)));
  97. }
  98. static void
  99. WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  100. {
  101. writereg(cs->hw.ix1.hscx_ale,
  102.  cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0), value);
  103. }
  104. #define READHSCX(cs, nr, reg) readreg(cs->hw.ix1.hscx_ale, 
  105. cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0))
  106. #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ix1.hscx_ale, 
  107. cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0), data)
  108. #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ix1.hscx_ale, 
  109. cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
  110. #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ix1.hscx_ale, 
  111. cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
  112. #include "hscx_irq.c"
  113. static void
  114. ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs)
  115. {
  116. struct IsdnCardState *cs = dev_id;
  117. u_char val;
  118. if (!cs) {
  119. printk(KERN_WARNING "IX1: Spurious interrupt!n");
  120. return;
  121. }
  122. val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40);
  123.       Start_HSCX:
  124. if (val)
  125. hscx_int_main(cs, val);
  126. val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA);
  127.       Start_ISAC:
  128. if (val)
  129. isac_interrupt(cs, val);
  130. val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40);
  131. if (val) {
  132. if (cs->debug & L1_DEB_HSCX)
  133. debugl1(cs, "HSCX IntStat after IntRoutine");
  134. goto Start_HSCX;
  135. }
  136. val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA);
  137. if (val) {
  138. if (cs->debug & L1_DEB_ISAC)
  139. debugl1(cs, "ISAC IntStat after IntRoutine");
  140. goto Start_ISAC;
  141. }
  142. writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0xFF);
  143. writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0xFF);
  144. writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0xFF);
  145. writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0);
  146. writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0);
  147. writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0);
  148. }
  149. void
  150. release_io_ix1micro(struct IsdnCardState *cs)
  151. {
  152. if (cs->hw.ix1.cfg_reg)
  153. release_region(cs->hw.ix1.cfg_reg, 4);
  154. }
  155. static void
  156. ix1_reset(struct IsdnCardState *cs)
  157. {
  158. long flags;
  159. int cnt;
  160. /* reset isac */
  161. save_flags(flags);
  162. cnt = 3 * (HZ / 10) + 1;
  163. sti();
  164. while (cnt--) {
  165. byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 1);
  166. HZDELAY(1); /* wait >=10 ms */
  167. }
  168. byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 0);
  169. restore_flags(flags);
  170. }
  171. static int
  172. ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  173. {
  174. switch (mt) {
  175. case CARD_RESET:
  176. ix1_reset(cs);
  177. return(0);
  178. case CARD_RELEASE:
  179. release_io_ix1micro(cs);
  180. return(0);
  181. case CARD_INIT:
  182. inithscxisac(cs, 3);
  183. return(0);
  184. case CARD_TEST:
  185. return(0);
  186. }
  187. return(0);
  188. }
  189. int __init
  190. setup_ix1micro(struct IsdnCard *card)
  191. {
  192. struct IsdnCardState *cs = card->cs;
  193. char tmp[64];
  194. strcpy(tmp, ix1_revision);
  195. printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %sn", HiSax_getrev(tmp));
  196. if (cs->typ != ISDN_CTYPE_IX1MICROR2)
  197. return (0);
  198. /* IO-Ports */
  199. cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET;
  200. cs->hw.ix1.hscx_ale = card->para[1] + HSCX_COMMAND_OFFSET;
  201. cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET;
  202. cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
  203. cs->hw.ix1.cfg_reg = card->para[1];
  204. cs->irq = card->para[0];
  205. if (cs->hw.ix1.cfg_reg) {
  206. if (check_region((cs->hw.ix1.cfg_reg), 4)) {
  207. printk(KERN_WARNING
  208.   "HiSax: %s config port %x-%x already in usen",
  209.        CardType[card->typ],
  210.        cs->hw.ix1.cfg_reg,
  211.        cs->hw.ix1.cfg_reg + 4);
  212. return (0);
  213. } else
  214. request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg");
  215. }
  216. printk(KERN_INFO
  217.        "HiSax: %s config irq:%d io:0x%Xn",
  218.        CardType[cs->typ], cs->irq,
  219.        cs->hw.ix1.cfg_reg);
  220. ix1_reset(cs);
  221. cs->readisac = &ReadISAC;
  222. cs->writeisac = &WriteISAC;
  223. cs->readisacfifo = &ReadISACfifo;
  224. cs->writeisacfifo = &WriteISACfifo;
  225. cs->BC_Read_Reg = &ReadHSCX;
  226. cs->BC_Write_Reg = &WriteHSCX;
  227. cs->BC_Send_Data = &hscx_fill_fifo;
  228. cs->cardmsg = &ix1_card_msg;
  229. cs->irq_func = &ix1micro_interrupt;
  230. ISACVersion(cs, "ix1-Micro:");
  231. if (HscxVersion(cs, "ix1-Micro:")) {
  232. printk(KERN_WARNING
  233.     "ix1-Micro: wrong HSCX versions check IO addressn");
  234. release_io_ix1micro(cs);
  235. return (0);
  236. }
  237. return (1);
  238. }