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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: sedlbauer.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * low level stuff for Sedlbauer cards
  4.  * includes support for the Sedlbauer speed star (speed star II),
  5.  * support for the Sedlbauer speed fax+,
  6.  * support for the Sedlbauer ISDN-Controller PC/104 and
  7.  * support for the Sedlbauer speed pci
  8.  * derived from the original file asuscom.c from Karsten Keil
  9.  *
  10.  * Author       Marcus Niemann
  11.  * Copyright    by Marcus Niemann    <niemann@www-bib.fh-bielefeld.de>
  12.  * 
  13.  * This software may be used and distributed according to the terms
  14.  * of the GNU General Public License, incorporated herein by reference.
  15.  *
  16.  * Thanks to  Karsten Keil
  17.  *            Sedlbauer AG for informations
  18.  *            Edgar Toernig
  19.  *
  20.  */
  21. /* Supported cards:
  22.  * Card: Chip: Configuration: Comment:
  23.  * ---------------------------------------------------------------------
  24.  * Speed Card ISAC_HSCX DIP-SWITCH
  25.  * Speed Win ISAC_HSCX ISAPNP
  26.  * Speed Fax+ ISAC_ISAR ISAPNP Full analog support
  27.  * Speed Star ISAC_HSCX CARDMGR
  28.  * Speed Win2 IPAC ISAPNP
  29.  * ISDN PC/104 IPAC DIP-SWITCH
  30.  * Speed Star2 IPAC CARDMGR
  31.  * Speed PCI IPAC PCI PNP
  32.  * Speed Fax+  ISAC_ISAR PCI PNP Full analog support
  33.  *
  34.  * Important:
  35.  * For the sedlbauer speed fax+ to work properly you have to download
  36.  * the firmware onto the card.
  37.  * For example: hisaxctrl <DriverID> 9 ISAR.BIN
  38. */
  39. #define __NO_VERSION__
  40. #include <linux/init.h>
  41. #include <linux/config.h>
  42. #include "hisax.h"
  43. #include "isac.h"
  44. #include "ipac.h"
  45. #include "hscx.h"
  46. #include "isar.h"
  47. #include "isdnl1.h"
  48. #include <linux/pci.h>
  49. extern const char *CardType[];
  50. const char *Sedlbauer_revision = "$Revision: 1.1.4.1 $";
  51. const char *Sedlbauer_Types[] =
  52. {"None", "speed card/win", "speed star", "speed fax+",
  53. "speed win II / ISDN PC/104", "speed star II", "speed pci",
  54. "speed fax+ pyramid", "speed fax+ pci"};
  55. #define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51
  56. #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
  57. #define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54
  58. #define PCI_SUB_ID_SEDLBAUER 0x01
  59. #define SEDL_SPEED_CARD_WIN 1
  60. #define SEDL_SPEED_STAR  2
  61. #define SEDL_SPEED_FAX 3
  62. #define SEDL_SPEED_WIN2_PC104  4
  63. #define SEDL_SPEED_STAR2  5
  64. #define SEDL_SPEED_PCI    6
  65. #define SEDL_SPEEDFAX_PYRAMID 7
  66. #define SEDL_SPEEDFAX_PCI 8
  67. #define SEDL_CHIP_TEST 0
  68. #define SEDL_CHIP_ISAC_HSCX 1
  69. #define SEDL_CHIP_ISAC_ISAR 2
  70. #define SEDL_CHIP_IPAC 3
  71. #define SEDL_BUS_ISA 1
  72. #define SEDL_BUS_PCI 2
  73. #define SEDL_BUS_PCMCIA 3
  74. #define byteout(addr,val) outb(val,addr)
  75. #define bytein(addr) inb(addr)
  76. #define SEDL_HSCX_ISA_RESET_ON 0
  77. #define SEDL_HSCX_ISA_RESET_OFF 1
  78. #define SEDL_HSCX_ISA_ISAC 2
  79. #define SEDL_HSCX_ISA_HSCX 3
  80. #define SEDL_HSCX_ISA_ADR 4
  81. #define SEDL_HSCX_PCMCIA_RESET 0
  82. #define SEDL_HSCX_PCMCIA_ISAC 1
  83. #define SEDL_HSCX_PCMCIA_HSCX 2
  84. #define SEDL_HSCX_PCMCIA_ADR 4
  85. #define SEDL_ISAR_ISA_ISAC 4
  86. #define SEDL_ISAR_ISA_ISAR 6
  87. #define SEDL_ISAR_ISA_ADR 8
  88. #define SEDL_ISAR_ISA_ISAR_RESET_ON 10
  89. #define SEDL_ISAR_ISA_ISAR_RESET_OFF 12
  90. #define SEDL_IPAC_ANY_ADR 0
  91. #define SEDL_IPAC_ANY_IPAC 2
  92. #define SEDL_IPAC_PCI_BASE 0
  93. #define SEDL_IPAC_PCI_ADR 0xc0
  94. #define SEDL_IPAC_PCI_IPAC 0xc8
  95. #define SEDL_ISAR_PCI_ADR 0xc8
  96. #define SEDL_ISAR_PCI_ISAC 0xd0
  97. #define SEDL_ISAR_PCI_ISAR 0xe0
  98. #define SEDL_ISAR_PCI_ISAR_RESET_ON 0x01
  99. #define SEDL_ISAR_PCI_ISAR_RESET_OFF 0x18
  100. #define SEDL_ISAR_PCI_LED1 0x08
  101. #define SEDL_ISAR_PCI_LED2 0x10
  102. #define SEDL_RESET      0x3 /* same as DOS driver */
  103. static inline u_char
  104. readreg(unsigned int ale, unsigned int adr, u_char off)
  105. {
  106. register u_char ret;
  107. long flags;
  108. save_flags(flags);
  109. cli();
  110. byteout(ale, off);
  111. ret = bytein(adr);
  112. restore_flags(flags);
  113. return (ret);
  114. }
  115. static inline void
  116. readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  117. {
  118. /* fifo read without cli because it's allready done  */
  119. byteout(ale, off);
  120. insb(adr, data, size);
  121. }
  122. static inline void
  123. writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
  124. {
  125. long flags;
  126. save_flags(flags);
  127. cli();
  128. byteout(ale, off);
  129. byteout(adr, data);
  130. restore_flags(flags);
  131. }
  132. static inline void
  133. writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
  134. {
  135. /* fifo write without cli because it's allready done  */
  136. byteout(ale, off);
  137. outsb(adr, data, size);
  138. }
  139. /* Interface functions */
  140. static u_char
  141. ReadISAC(struct IsdnCardState *cs, u_char offset)
  142. {
  143. return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset));
  144. }
  145. static void
  146. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  147. {
  148. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset, value);
  149. }
  150. static void
  151. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  152. {
  153. readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
  154. }
  155. static void
  156. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  157. {
  158. writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
  159. }
  160. static u_char
  161. ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
  162. {
  163. return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80));
  164. }
  165. static void
  166. WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
  167. {
  168. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80, value);
  169. }
  170. static void
  171. ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
  172. {
  173. readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
  174. }
  175. static void
  176. WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
  177. {
  178. writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
  179. }
  180. static u_char
  181. ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
  182. {
  183. return (readreg(cs->hw.sedl.adr,
  184. cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0)));
  185. }
  186. static void
  187. WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  188. {
  189. writereg(cs->hw.sedl.adr,
  190.  cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0), value);
  191. }
  192. /* ISAR access routines
  193.  * mode = 0 access with IRQ on
  194.  * mode = 1 access with IRQ off
  195.  * mode = 2 access with IRQ off and using last offset
  196.  */
  197. static u_char
  198. ReadISAR(struct IsdnCardState *cs, int mode, u_char offset)
  199. {
  200. if (mode == 0)
  201. return (readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset));
  202. else if (mode == 1)
  203. byteout(cs->hw.sedl.adr, offset);
  204. return(bytein(cs->hw.sedl.hscx));
  205. }
  206. static void
  207. WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
  208. {
  209. if (mode == 0)
  210. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset, value);
  211. else {
  212. if (mode == 1)
  213. byteout(cs->hw.sedl.adr, offset);
  214. byteout(cs->hw.sedl.hscx, value);
  215. }
  216. }
  217. /*
  218.  * fast interrupt HSCX stuff goes here
  219.  */
  220. #define READHSCX(cs, nr, reg) readreg(cs->hw.sedl.adr, 
  221. cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0))
  222. #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.sedl.adr, 
  223. cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0), data)
  224. #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.sedl.adr, 
  225. cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
  226. #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.sedl.adr, 
  227. cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
  228. #include "hscx_irq.c"
  229. static void
  230. sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
  231. {
  232. struct IsdnCardState *cs = dev_id;
  233. u_char val;
  234. if (!cs) {
  235. printk(KERN_WARNING "Sedlbauer: Spurious interrupt!n");
  236. return;
  237. }
  238. if ((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && (*cs->busy_flag == 1)) {
  239. /* The card tends to generate interrupts while being removed
  240.    causing us to just crash the kernel. bad. */
  241. printk(KERN_WARNING "Sedlbauer: card not available!n");
  242. return;
  243. }
  244. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
  245.       Start_HSCX:
  246. if (val)
  247. hscx_int_main(cs, val);
  248. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
  249.       Start_ISAC:
  250. if (val)
  251. isac_interrupt(cs, val);
  252. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
  253. if (val) {
  254. if (cs->debug & L1_DEB_HSCX)
  255. debugl1(cs, "HSCX IntStat after IntRoutine");
  256. goto Start_HSCX;
  257. }
  258. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
  259. if (val) {
  260. if (cs->debug & L1_DEB_ISAC)
  261. debugl1(cs, "ISAC IntStat after IntRoutine");
  262. goto Start_ISAC;
  263. }
  264. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0xFF);
  265. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0xFF);
  266. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF);
  267. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0);
  268. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0x0);
  269. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0x0);
  270. }
  271. static void
  272. sedlbauer_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
  273. {
  274. struct IsdnCardState *cs = dev_id;
  275. u_char ista, val, icnt = 5;
  276. if (!cs) {
  277. printk(KERN_WARNING "Sedlbauer: Spurious interrupt!n");
  278. return;
  279. }
  280. ista = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
  281. Start_IPAC:
  282. if (cs->debug & L1_DEB_IPAC)
  283. debugl1(cs, "IPAC ISTA %02X", ista);
  284. if (ista & 0x0f) {
  285. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
  286. if (ista & 0x01)
  287. val |= 0x01;
  288. if (ista & 0x04)
  289. val |= 0x02;
  290. if (ista & 0x08)
  291. val |= 0x04;
  292. if (val)
  293. hscx_int_main(cs, val);
  294. }
  295. if (ista & 0x20) {
  296. val = 0xfe & readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA | 0x80);
  297. if (val) {
  298. isac_interrupt(cs, val);
  299. }
  300. }
  301. if (ista & 0x10) {
  302. val = 0x01;
  303. isac_interrupt(cs, val);
  304. }
  305. ista  = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
  306. if ((ista & 0x3f) && icnt) {
  307. icnt--;
  308. goto Start_IPAC;
  309. }
  310. if (!icnt)
  311. if (cs->debug & L1_DEB_ISAC)
  312. debugl1(cs, "Sedlbauer IRQ LOOP");
  313. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xFF);
  314. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xC0);
  315. }
  316. static void
  317. sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs)
  318. {
  319. struct IsdnCardState *cs = dev_id;
  320. u_char val;
  321. int cnt = 5;
  322. if (!cs) {
  323. printk(KERN_WARNING "Sedlbauer: Spurious interrupt!n");
  324. return;
  325. }
  326. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
  327.       Start_ISAR:
  328. if (val & ISAR_IRQSTA)
  329. isar_int_main(cs);
  330. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
  331.       Start_ISAC:
  332. if (val)
  333. isac_interrupt(cs, val);
  334. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
  335. if ((val & ISAR_IRQSTA) && --cnt) {
  336. if (cs->debug & L1_DEB_HSCX)
  337. debugl1(cs, "ISAR IntStat after IntRoutine");
  338. goto Start_ISAR;
  339. }
  340. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
  341. if (val && --cnt) {
  342. if (cs->debug & L1_DEB_ISAC)
  343. debugl1(cs, "ISAC IntStat after IntRoutine");
  344. goto Start_ISAC;
  345. }
  346. if (!cnt)
  347. if (cs->debug & L1_DEB_ISAC)
  348. debugl1(cs, "Sedlbauer IRQ LOOP");
  349. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, 0);
  350. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF);
  351. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0);
  352. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, ISAR_IRQMSK);
  353. }
  354. void
  355. release_io_sedlbauer(struct IsdnCardState *cs)
  356. {
  357. int bytecnt = 8;
  358. if (cs->subtyp == SEDL_SPEED_FAX) {
  359. bytecnt = 16;
  360. } else if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
  361. bytecnt = 256;
  362. }
  363. if (cs->hw.sedl.cfg_reg)
  364. release_region(cs->hw.sedl.cfg_reg, bytecnt);
  365. }
  366. static void
  367. reset_sedlbauer(struct IsdnCardState *cs)
  368. {
  369. long flags;
  370. printk(KERN_INFO "Sedlbauer: resetting cardn");
  371. if (!((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) &&
  372.    (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) {
  373. if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
  374. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20);
  375. save_flags(flags);
  376. sti();
  377. set_current_state(TASK_UNINTERRUPTIBLE);
  378. schedule_timeout((10*HZ)/1000);
  379. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0);
  380. set_current_state(TASK_UNINTERRUPTIBLE);
  381. schedule_timeout((10*HZ)/1000);
  382. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0);
  383. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff);
  384. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0);
  385. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0);
  386. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12);
  387. restore_flags(flags);
  388. } else if ((cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) &&
  389. (cs->hw.sedl.bus == SEDL_BUS_PCI)) {
  390. byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
  391. save_flags(flags);
  392. sti();
  393. current->state = TASK_UNINTERRUPTIBLE;
  394. schedule_timeout((20*HZ)/1000);
  395. byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
  396. current->state = TASK_UNINTERRUPTIBLE;
  397. schedule_timeout((20*HZ)/1000);
  398. restore_flags(flags);
  399. } else {
  400. byteout(cs->hw.sedl.reset_on, SEDL_RESET); /* Reset On */
  401. save_flags(flags);
  402. sti();
  403. set_current_state(TASK_UNINTERRUPTIBLE);
  404. schedule_timeout((10*HZ)/1000);
  405. byteout(cs->hw.sedl.reset_off, 0); /* Reset Off */
  406. set_current_state(TASK_UNINTERRUPTIBLE);
  407. schedule_timeout((10*HZ)/1000);
  408. restore_flags(flags);
  409. }
  410. }
  411. }
  412. static int
  413. Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  414. {
  415. switch (mt) {
  416. case CARD_RESET:
  417. reset_sedlbauer(cs);
  418. return(0);
  419. case CARD_RELEASE:
  420. if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
  421. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
  422. ISAR_IRQBIT, 0);
  423. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
  424. ISAC_MASK, 0xFF);
  425. reset_sedlbauer(cs);
  426. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
  427. ISAR_IRQBIT, 0);
  428. writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
  429. ISAC_MASK, 0xFF);
  430. }
  431. release_io_sedlbauer(cs);
  432. return(0);
  433. case CARD_INIT:
  434. if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
  435. clear_pending_isac_ints(cs);
  436. writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
  437. ISAR_IRQBIT, 0);
  438. initisac(cs);
  439. initisar(cs);
  440. /* Reenable all IRQ */
  441. cs->writeisac(cs, ISAC_MASK, 0);
  442. /* RESET Receiver and Transmitter */
  443. cs->writeisac(cs, ISAC_CMDR, 0x41);
  444. } else {
  445. inithscxisac(cs, 3);
  446. }
  447. return(0);
  448. case CARD_TEST:
  449. return(0);
  450. case MDL_INFO_CONN:
  451. if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
  452. return(0);
  453. if ((long) arg)
  454. cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2;
  455. else
  456. cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1;
  457. byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
  458. break;
  459. case MDL_INFO_REL:
  460. if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
  461. return(0);
  462. if ((long) arg)
  463. cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2;
  464. else
  465. cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1;
  466. byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
  467. break;
  468. }
  469. return(0);
  470. }
  471. static struct pci_dev *dev_sedl __devinitdata = NULL;
  472. int __devinit
  473. setup_sedlbauer(struct IsdnCard *card)
  474. {
  475. int bytecnt, ver, val;
  476. struct IsdnCardState *cs = card->cs;
  477. char tmp[64];
  478. u16 sub_vendor_id, sub_id;
  479. long flags;
  480. strcpy(tmp, Sedlbauer_revision);
  481. printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %sn", HiSax_getrev(tmp));
  482.   if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
  483.   cs->subtyp = SEDL_SPEED_CARD_WIN;
  484. cs->hw.sedl.bus = SEDL_BUS_ISA;
  485. cs->hw.sedl.chip = SEDL_CHIP_TEST;
  486.   } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
  487.   cs->subtyp = SEDL_SPEED_STAR;
  488. cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
  489. cs->hw.sedl.chip = SEDL_CHIP_TEST;
  490.   } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
  491.   cs->subtyp = SEDL_SPEED_FAX;
  492. cs->hw.sedl.bus = SEDL_BUS_ISA;
  493. cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
  494.   } else
  495. return (0);
  496. bytecnt = 8;
  497. if (card->para[1]) {
  498. cs->hw.sedl.cfg_reg = card->para[1];
  499. cs->irq = card->para[0];
  500. if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
  501. bytecnt = 16;
  502. }
  503. } else {
  504. /* Probe for Sedlbauer speed pci */
  505. #if CONFIG_PCI
  506. if (!pci_present()) {
  507. printk(KERN_ERR "Sedlbauer: no PCI bus presentn");
  508. return(0);
  509. }
  510. if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
  511. PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
  512. if (pci_enable_device(dev_sedl))
  513. return(0);
  514. cs->irq = dev_sedl->irq;
  515. if (!cs->irq) {
  516. printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card foundn");
  517. return(0);
  518. }
  519. cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
  520. } else {
  521. printk(KERN_WARNING "Sedlbauer: No PCI card foundn");
  522. return(0);
  523. }
  524. cs->irq_flags |= SA_SHIRQ;
  525. cs->hw.sedl.bus = SEDL_BUS_PCI;
  526. sub_vendor_id = dev_sedl->subsystem_vendor;
  527. sub_id = dev_sedl->subsystem_device;
  528. printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %xn",
  529. sub_vendor_id, sub_id);
  530. printk(KERN_INFO "Sedlbauer: PCI base adr %#xn",
  531. cs->hw.sedl.cfg_reg);
  532. if (sub_id != PCI_SUB_ID_SEDLBAUER) {
  533. printk(KERN_ERR "Sedlbauer: unknown sub id %#xn", sub_id);
  534. return(0);
  535. }
  536. if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
  537. cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
  538. cs->subtyp = SEDL_SPEEDFAX_PYRAMID;
  539. } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) {
  540. cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
  541. cs->subtyp = SEDL_SPEEDFAX_PCI;
  542. } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) {
  543. cs->hw.sedl.chip = SEDL_CHIP_IPAC;
  544. cs->subtyp = SEDL_SPEED_PCI;
  545. } else {
  546. printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#xn",
  547. sub_vendor_id);
  548. return(0);
  549. }
  550. bytecnt = 256;
  551. cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
  552. cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
  553. byteout(cs->hw.sedl.cfg_reg, 0xff);
  554. byteout(cs->hw.sedl.cfg_reg, 0x00);
  555. byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
  556. byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
  557. byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
  558. save_flags(flags);
  559. sti();
  560. current->state = TASK_UNINTERRUPTIBLE;
  561. schedule_timeout((10*HZ)/1000);
  562. byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
  563. restore_flags(flags);
  564. #else
  565. printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOSn");
  566. return (0);
  567. #endif /* CONFIG_PCI */
  568. }
  569. /* In case of the sedlbauer pcmcia card, this region is in use,
  570.  * reserved for us by the card manager. So we do not check it
  571.  * here, it would fail.
  572.  */
  573. if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
  574. check_region((cs->hw.sedl.cfg_reg), bytecnt)) {
  575. printk(KERN_WARNING
  576. "HiSax: %s config port %x-%x already in usen",
  577. CardType[card->typ],
  578. cs->hw.sedl.cfg_reg,
  579. cs->hw.sedl.cfg_reg + bytecnt);
  580. return (0);
  581. } else {
  582. request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn");
  583. }
  584. printk(KERN_INFO
  585.        "Sedlbauer: defined at 0x%x-0x%x IRQ %dn",
  586.        cs->hw.sedl.cfg_reg,
  587.        cs->hw.sedl.cfg_reg + bytecnt,
  588.        cs->irq);
  589. cs->BC_Read_Reg = &ReadHSCX;
  590. cs->BC_Write_Reg = &WriteHSCX;
  591. cs->BC_Send_Data = &hscx_fill_fifo;
  592. cs->cardmsg = &Sedl_card_msg;
  593. /*
  594.  * testing ISA and PCMCIA Cards for IPAC, default is ISAC
  595.  * do not test for PCI card, because ports are different
  596.  * and PCI card uses only IPAC (for the moment)
  597.  */
  598. if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
  599. val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
  600. cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
  601. printk(KERN_DEBUG "Sedlbauer: testing IPAC version %xn", val);
  602.         if ((val == 1) || (val == 2)) {
  603. /* IPAC */
  604. cs->subtyp = SEDL_SPEED_WIN2_PC104;
  605. if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
  606. cs->subtyp = SEDL_SPEED_STAR2;
  607. }
  608. cs->hw.sedl.chip = SEDL_CHIP_IPAC;
  609. } else {
  610. /* ISAC_HSCX oder ISAC_ISAR */
  611. if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
  612. cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
  613. }
  614. }
  615. }
  616. /*
  617.  * hw.sedl.chip is now properly set
  618.  */
  619. printk(KERN_INFO "Sedlbauer: %s detectedn",
  620. Sedlbauer_Types[cs->subtyp]);
  621. if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
  622. if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
  623.                 cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
  624. cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
  625. cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
  626. } else {
  627.                 cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
  628. cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
  629. cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
  630. }
  631. test_and_set_bit(HW_IPAC, &cs->HW_Flags);
  632. cs->readisac = &ReadISAC_IPAC;
  633. cs->writeisac = &WriteISAC_IPAC;
  634. cs->readisacfifo = &ReadISACfifo_IPAC;
  635. cs->writeisacfifo = &WriteISACfifo_IPAC;
  636. cs->irq_func = &sedlbauer_interrupt_ipac;
  637. val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID);
  638. printk(KERN_INFO "Sedlbauer: IPAC version %xn", val);
  639. reset_sedlbauer(cs);
  640. } else {
  641. /* ISAC_HSCX oder ISAC_ISAR */
  642. cs->readisac = &ReadISAC;
  643. cs->writeisac = &WriteISAC;
  644. cs->readisacfifo = &ReadISACfifo;
  645. cs->writeisacfifo = &WriteISACfifo;
  646. if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
  647. if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
  648. cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
  649. SEDL_ISAR_PCI_ADR;
  650. cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
  651. SEDL_ISAR_PCI_ISAC;
  652. cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
  653. SEDL_ISAR_PCI_ISAR;
  654. } else {
  655. cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
  656. SEDL_ISAR_ISA_ADR;
  657. cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
  658. SEDL_ISAR_ISA_ISAC;
  659. cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
  660. SEDL_ISAR_ISA_ISAR;
  661. cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
  662. SEDL_ISAR_ISA_ISAR_RESET_ON;
  663. cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
  664. SEDL_ISAR_ISA_ISAR_RESET_OFF;
  665. }
  666. cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
  667. cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
  668. test_and_set_bit(HW_ISAR, &cs->HW_Flags);
  669. cs->irq_func = &sedlbauer_interrupt_isar;
  670. cs->auxcmd = &isar_auxcmd;
  671. ISACVersion(cs, "Sedlbauer:");
  672. cs->BC_Read_Reg = &ReadISAR;
  673. cs->BC_Write_Reg = &WriteISAR;
  674. cs->BC_Send_Data = &isar_fill_fifo;
  675. ver = ISARVersion(cs, "Sedlbauer:");
  676. if (ver < 0) {
  677. printk(KERN_WARNING
  678. "Sedlbauer: wrong ISAR version (ret = %d)n", ver);
  679. release_io_sedlbauer(cs);
  680. return (0);
  681. }
  682. } else {
  683. if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
  684. cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
  685. cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
  686. cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
  687. cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
  688. cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
  689. } else {
  690. cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
  691. cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
  692. cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
  693. cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
  694. cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
  695. }
  696. cs->irq_func = &sedlbauer_interrupt;
  697. ISACVersion(cs, "Sedlbauer:");
  698. if (HscxVersion(cs, "Sedlbauer:")) {
  699. printk(KERN_WARNING
  700. "Sedlbauer: wrong HSCX versions check IO addressn");
  701. release_io_sedlbauer(cs);
  702. return (0);
  703. }
  704. reset_sedlbauer(cs);
  705. }
  706. }
  707. return (1);
  708. }