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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: mic.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * low level stuff for mic cards
  4.  *
  5.  * Author       Stephan von Krawczynski
  6.  * Copyright    by Stephan von Krawczynski <skraw@ithnet.com>
  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 *mic_revision = "$Revision: 1.1.4.1 $";
  20. #define byteout(addr,val) outb(val,addr)
  21. #define bytein(addr) inb(addr)
  22. #define MIC_ISAC 2
  23. #define MIC_HSCX 1
  24. #define MIC_ADR 7
  25. /* CARD_ADR (Write) */
  26. #define MIC_RESET      0x3 /* same as DOS driver */
  27. static inline u_char
  28. readreg(unsigned int ale, unsigned int adr, u_char off)
  29. {
  30. register u_char ret;
  31. long flags;
  32. save_flags(flags);
  33. cli();
  34. byteout(ale, off);
  35. ret = bytein(adr);
  36. restore_flags(flags);
  37. return (ret);
  38. }
  39. static inline void
  40. readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  41. {
  42. /* fifo read without cli because it's allready done  */
  43. byteout(ale, off);
  44. insb(adr, data, size);
  45. }
  46. static inline void
  47. writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
  48. {
  49. long flags;
  50. save_flags(flags);
  51. cli();
  52. byteout(ale, off);
  53. byteout(adr, data);
  54. restore_flags(flags);
  55. }
  56. static inline void
  57. writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  58. {
  59. /* fifo write without cli because it's allready done  */
  60. byteout(ale, off);
  61. outsb(adr, data, size);
  62. }
  63. /* Interface functions */
  64. static u_char
  65. ReadISAC(struct IsdnCardState *cs, u_char offset)
  66. {
  67. return (readreg(cs->hw.mic.adr, cs->hw.mic.isac, offset));
  68. }
  69. static void
  70. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  71. {
  72. writereg(cs->hw.mic.adr, cs->hw.mic.isac, offset, value);
  73. }
  74. static void
  75. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  76. {
  77. readfifo(cs->hw.mic.adr, cs->hw.mic.isac, 0, data, size);
  78. }
  79. static void
  80. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  81. {
  82. writefifo(cs->hw.mic.adr, cs->hw.mic.isac, 0, data, size);
  83. }
  84. static u_char
  85. ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
  86. {
  87. return (readreg(cs->hw.mic.adr,
  88. cs->hw.mic.hscx, offset + (hscx ? 0x40 : 0)));
  89. }
  90. static void
  91. WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  92. {
  93. writereg(cs->hw.mic.adr,
  94.  cs->hw.mic.hscx, offset + (hscx ? 0x40 : 0), value);
  95. }
  96. /*
  97.  * fast interrupt HSCX stuff goes here
  98.  */
  99. #define READHSCX(cs, nr, reg) readreg(cs->hw.mic.adr, 
  100. cs->hw.mic.hscx, reg + (nr ? 0x40 : 0))
  101. #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.mic.adr, 
  102. cs->hw.mic.hscx, reg + (nr ? 0x40 : 0), data)
  103. #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.mic.adr, 
  104. cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
  105. #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.mic.adr, 
  106. cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
  107. #include "hscx_irq.c"
  108. static void
  109. mic_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 "mic: Spurious interrupt!n");
  115. return;
  116. }
  117. val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40);
  118.       Start_HSCX:
  119. if (val)
  120. hscx_int_main(cs, val);
  121. val = readreg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_ISTA);
  122.       Start_ISAC:
  123. if (val)
  124. isac_interrupt(cs, val);
  125. val = readreg(cs->hw.mic.adr, cs->hw.mic.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.mic.adr, cs->hw.mic.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. writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0xFF);
  138. writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0xFF);
  139. writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0xFF);
  140. writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0x0);
  141. writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0x0);
  142. writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0x0);
  143. }
  144. void
  145. release_io_mic(struct IsdnCardState *cs)
  146. {
  147. int bytecnt = 8;
  148. if (cs->hw.mic.cfg_reg)
  149. release_region(cs->hw.mic.cfg_reg, bytecnt);
  150. }
  151. static int
  152. mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  153. {
  154. switch (mt) {
  155. case CARD_RESET:
  156. return(0);
  157. case CARD_RELEASE:
  158. release_io_mic(cs);
  159. return(0);
  160. case CARD_INIT:
  161. inithscx(cs); /* /RTSA := ISAC RST */
  162. inithscxisac(cs, 3);
  163. return(0);
  164. case CARD_TEST:
  165. return(0);
  166. }
  167. return(0);
  168. }
  169. int __init
  170. setup_mic(struct IsdnCard *card)
  171. {
  172. int bytecnt;
  173. struct IsdnCardState *cs = card->cs;
  174. char tmp[64];
  175. strcpy(tmp, mic_revision);
  176. printk(KERN_INFO "HiSax: mic driver Rev. %sn", HiSax_getrev(tmp));
  177. if (cs->typ != ISDN_CTYPE_MIC)
  178. return (0);
  179. bytecnt = 8;
  180. cs->hw.mic.cfg_reg = card->para[1];
  181. cs->irq = card->para[0];
  182. cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR;
  183. cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC;
  184. cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX;
  185. if (check_region((cs->hw.mic.cfg_reg), bytecnt)) {
  186. printk(KERN_WARNING
  187.        "HiSax: %s config port %x-%x already in usen",
  188.        CardType[card->typ],
  189.        cs->hw.mic.cfg_reg,
  190.        cs->hw.mic.cfg_reg + bytecnt);
  191. return (0);
  192. } else {
  193. request_region(cs->hw.mic.cfg_reg, bytecnt, "mic isdn");
  194. }
  195. printk(KERN_INFO
  196.        "mic: defined at 0x%x IRQ %dn",
  197.        cs->hw.mic.cfg_reg,
  198.        cs->irq);
  199. cs->readisac = &ReadISAC;
  200. cs->writeisac = &WriteISAC;
  201. cs->readisacfifo = &ReadISACfifo;
  202. cs->writeisacfifo = &WriteISACfifo;
  203. cs->BC_Read_Reg = &ReadHSCX;
  204. cs->BC_Write_Reg = &WriteHSCX;
  205. cs->BC_Send_Data = &hscx_fill_fifo;
  206. cs->cardmsg = &mic_card_msg;
  207. cs->irq_func = &mic_interrupt;
  208. ISACVersion(cs, "mic:");
  209. if (HscxVersion(cs, "mic:")) {
  210. printk(KERN_WARNING
  211.     "mic: wrong HSCX versions check IO addressn");
  212. release_io_mic(cs);
  213. return (0);
  214. }
  215. return (1);
  216. }