[PATCH] DVB: Update documentation and credits
[linux-2.6/history.git] / drivers / isdn / hisax / ix1_micro.c
blobfd770f72161e822ec6dd18302afb42a0e01cea60
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.
14 * Klaus-Peter Nischke
15 * Deusener Str. 287
16 * 44369 Dortmund
17 * Germany
20 #include <linux/init.h>
21 #include <linux/isapnp.h>
22 #include "hisax.h"
23 #include "isac.h"
24 #include "hscx.h"
25 #include "isdnl1.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
41 #define TIMEOUT 50
43 static inline u8
44 readreg(struct IsdnCardState *cs, unsigned int adr, u8 off)
46 u8 ret;
47 unsigned long flags;
49 spin_lock_irqsave(&ix1_micro_lock, flags);
50 byteout(cs->hw.ix1.isac_ale, off);
51 ret = bytein(adr);
52 spin_unlock_irqrestore(&ix1_micro_lock, flags);
53 return (ret);
56 static inline void
57 writereg(struct IsdnCardState *cs, unsigned int adr, u8 off, u8 data)
59 unsigned long flags;
61 spin_lock_irqsave(&ix1_micro_lock, flags);
62 byteout(cs->hw.ix1.isac_ale, off);
63 byteout(adr, data);
64 spin_unlock_irqrestore(&ix1_micro_lock, flags);
67 static inline void
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);
74 static inline void
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);
81 static u8
82 isac_read(struct IsdnCardState *cs, u8 offset)
84 return readreg(cs, cs->hw.ix1.isac, offset);
87 static void
88 isac_write(struct IsdnCardState *cs, u8 offset, u8 value)
90 writereg(cs, cs->hw.ix1.isac, offset, value);
93 static void
94 isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
96 readfifo(cs, cs->hw.ix1.isac, 0, data, size);
99 static void
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,
112 static u8
113 hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
115 return readreg(cs, cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0));
118 static void
119 hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
121 writereg(cs, cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0), value);
124 static void
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);
130 static void
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,
143 static int
144 ix1_reset(struct IsdnCardState *cs)
146 int cnt;
148 /* reset isac */
149 cnt = 3 * (HZ / 10) + 1;
150 while (cnt--) {
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);
155 return 0;
158 static struct card_ops ix1_ops = {
159 .init = inithscxisac,
160 .reset = ix1_reset,
161 .release = hisax_release_resources,
162 .irq_func = hscxisac_irq,
165 static int __init
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"))
174 goto err;
176 printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n",
177 CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg);
178 ix1_reset(cs);
179 cs->card_ops = &ix1_ops;
180 if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
181 goto err;
182 return 0;
183 err:
184 hisax_release_resources(cs);
185 return -EBUSY;
188 #ifdef __ISAPNP__
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." },
196 { 0, }
199 static struct isapnp_device_id *idev = &itk_ids[0];
200 static struct pnp_card *pnp_c __devinitdata = NULL;
201 #endif
204 int __init
205 setup_ix1micro(struct IsdnCard *card)
207 char tmp[64];
209 strcpy(tmp, ix1_revision);
210 printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp));
212 if (card->para[1]) {
213 if (ix1_probe(card->cs, card))
214 return 0;
215 return 1;
217 #ifdef __ISAPNP__
218 if (isapnp_present()) {
219 struct pnp_card *pb;
220 struct pnp_dev *pd;
222 while(idev->card_vendor) {
223 if ((pb = pnp_find_card(idev->card_vendor,
224 idev->card_device,
225 pnp_c))) {
226 pnp_c = pb;
227 pd = NULL;
228 if ((pd = pnp_find_dev(pnp_c,
229 idev->vendor,
230 idev->function,
231 pd))) {
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");
236 return 0;
238 if (pnp_activate_dev(pd) < 0) {
239 printk(KERN_ERR "ITK PnP: activate failed\n");
240 pnp_device_detach(pd);
241 return 0;
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);
247 return(0);
249 card->para[1] = pnp_port_start(pd, 0);
250 card->para[0] = pnp_irq(pd, 0);
251 if (ix1_probe(card->cs, card))
252 return 0;
253 return 1;
254 } else {
255 printk(KERN_ERR "ITK PnP: PnP error card found, no device\n");
258 idev++;
259 pnp_c=NULL;
261 if (!idev->card_vendor) {
262 printk(KERN_INFO "ITK PnP: no ISAPnP card found\n");
265 #endif
266 return 0;