1 /* $Id: ix1_micro.c,v 2.10.6.2 2001/09/23 22:24:49 kai Exp $
3 * low level stuff for ITK ix1-micro Rev.2 isdn cards
4 * derived from the original file teles3.c from Karsten Keil
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>
11 * This software may be used and distributed according to the terms
12 * of the GNU General Public License, incorporated herein by reference.
20 #include <linux/init.h>
21 #include <linux/isapnp.h>
27 extern const char *CardType
[];
28 const char *ix1_revision
= "$Revision: 2.10.6.2 $";
29 static spinlock_t ix1_micro_lock
= SPIN_LOCK_UNLOCKED
;
31 #define byteout(addr,val) outb(val,addr)
32 #define bytein(addr) inb(addr)
34 #define SPECIAL_PORT_OFFSET 3
36 #define ISAC_COMMAND_OFFSET 2
37 #define ISAC_DATA_OFFSET 0
38 #define HSCX_COMMAND_OFFSET 2
39 #define HSCX_DATA_OFFSET 1
44 readreg(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
)
49 spin_lock_irqsave(&ix1_micro_lock
, flags
);
50 byteout(cs
->hw
.ix1
.isac_ale
, off
);
52 spin_unlock_irqrestore(&ix1_micro_lock
, flags
);
57 writereg(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
, u8 data
)
61 spin_lock_irqsave(&ix1_micro_lock
, flags
);
62 byteout(cs
->hw
.ix1
.isac_ale
, off
);
64 spin_unlock_irqrestore(&ix1_micro_lock
, flags
);
68 readfifo(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
, u8
* data
, int size
)
70 byteout(cs
->hw
.ix1
.isac_ale
, off
);
71 insb(adr
, data
, size
);
75 writefifo(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
, u8
* data
, int size
)
77 byteout(cs
->hw
.ix1
.isac_ale
, off
);
78 outsb(adr
, data
, size
);
82 isac_read(struct IsdnCardState
*cs
, u8 offset
)
84 return readreg(cs
, cs
->hw
.ix1
.isac
, offset
);
88 isac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
90 writereg(cs
, cs
->hw
.ix1
.isac
, offset
, value
);
94 isac_read_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
96 readfifo(cs
, cs
->hw
.ix1
.isac
, 0, data
, size
);
100 isac_write_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
102 writefifo(cs
, cs
->hw
.ix1
.isac
, 0, data
, size
);
105 static struct dc_hw_ops isac_ops
= {
106 .read_reg
= isac_read
,
107 .write_reg
= isac_write
,
108 .read_fifo
= isac_read_fifo
,
109 .write_fifo
= isac_write_fifo
,
113 hscx_read(struct IsdnCardState
*cs
, int hscx
, u8 offset
)
115 return readreg(cs
, cs
->hw
.ix1
.hscx
, offset
+ (hscx
? 0x40 : 0));
119 hscx_write(struct IsdnCardState
*cs
, int hscx
, u8 offset
, u8 value
)
121 writereg(cs
, cs
->hw
.ix1
.hscx
, offset
+ (hscx
? 0x40 : 0), value
);
125 hscx_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
127 readfifo(cs
, cs
->hw
.ix1
.hscx
, hscx
? 0x40 : 0, data
, size
);
131 hscx_write_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
133 writefifo(cs
, cs
->hw
.ix1
.hscx
, hscx
? 0x40 : 0, data
, size
);
136 static struct bc_hw_ops hscx_ops
= {
137 .read_reg
= hscx_read
,
138 .write_reg
= hscx_write
,
139 .read_fifo
= hscx_read_fifo
,
140 .write_fifo
= hscx_write_fifo
,
144 ix1_reset(struct IsdnCardState
*cs
)
149 cnt
= 3 * (HZ
/ 10) + 1;
151 byteout(cs
->hw
.ix1
.cfg_reg
+ SPECIAL_PORT_OFFSET
, 1);
152 HZDELAY(1); /* wait >=10 ms */
154 byteout(cs
->hw
.ix1
.cfg_reg
+ SPECIAL_PORT_OFFSET
, 0);
158 static struct card_ops ix1_ops
= {
159 .init
= inithscxisac
,
161 .release
= hisax_release_resources
,
162 .irq_func
= hscxisac_irq
,
166 ix1_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
168 cs
->irq
= card
->para
[0];
169 cs
->hw
.ix1
.isac_ale
= card
->para
[1] + ISAC_COMMAND_OFFSET
;
170 cs
->hw
.ix1
.isac
= card
->para
[1] + ISAC_DATA_OFFSET
;
171 cs
->hw
.ix1
.hscx
= card
->para
[1] + HSCX_DATA_OFFSET
;
172 cs
->hw
.ix1
.cfg_reg
= card
->para
[1];
173 if (!request_io(&cs
->rs
, cs
->hw
.ix1
.cfg_reg
, 4, "ix1micro cfg"))
176 printk(KERN_INFO
"HiSax: %s config irq:%d io:0x%X\n",
177 CardType
[cs
->typ
], cs
->irq
, cs
->hw
.ix1
.cfg_reg
);
179 cs
->card_ops
= &ix1_ops
;
180 if (hscxisac_setup(cs
, &isac_ops
, &hscx_ops
))
184 hisax_release_resources(cs
);
189 static struct isapnp_device_id itk_ids
[] __initdata
= {
190 { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
191 ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
192 (unsigned long) "ITK micro 2" },
193 { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
194 ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
195 (unsigned long) "ITK micro 2." },
199 static struct isapnp_device_id
*idev
= &itk_ids
[0];
200 static struct pnp_card
*pnp_c __devinitdata
= NULL
;
205 setup_ix1micro(struct IsdnCard
*card
)
209 strcpy(tmp
, ix1_revision
);
210 printk(KERN_INFO
"HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp
));
213 if (ix1_probe(card
->cs
, card
))
218 if (isapnp_present()) {
222 while(idev
->card_vendor
) {
223 if ((pb
= pnp_find_card(idev
->card_vendor
,
228 if ((pd
= pnp_find_dev(pnp_c
,
232 printk(KERN_INFO
"HiSax: %s detected\n",
233 (char *)idev
->driver_data
);
234 if (pnp_device_attach(pd
) < 0) {
235 printk(KERN_ERR
"ITK PnP: attach failed\n");
238 if (pnp_activate_dev(pd
) < 0) {
239 printk(KERN_ERR
"ITK PnP: activate failed\n");
240 pnp_device_detach(pd
);
243 if (!pnp_port_valid(pd
, 0) || !pnp_irq_valid(pd
, 0)) {
244 printk(KERN_ERR
"ITK PnP:some resources are missing %ld/%lx\n",
245 pnp_irq(pd
, 0), pnp_port_start(pd
, 0));
246 pnp_device_detach(pd
);
249 card
->para
[1] = pnp_port_start(pd
, 0);
250 card
->para
[0] = pnp_irq(pd
, 0);
251 if (ix1_probe(card
->cs
, card
))
255 printk(KERN_ERR
"ITK PnP: PnP error card found, no device\n");
261 if (!idev
->card_vendor
) {
262 printk(KERN_INFO
"ITK PnP: no ISAPnP card found\n");