Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nj_u.c
Go to the documentation of this file.
1 /* $Id: nj_u.c,v 2.14.2.3 2004/01/13 14:31:26 keil Exp $
2  *
3  * This software may be used and distributed according to the terms
4  * of the GNU General Public License, incorporated herein by reference.
5  *
6  */
7 
8 #include <linux/init.h>
9 #include "hisax.h"
10 #include "icc.h"
11 #include "isdnl1.h"
12 #include <linux/pci.h>
13 #include <linux/interrupt.h>
14 #include <linux/ppp_defs.h>
15 #include "netjet.h"
16 
17 static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
18 
19 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
20 {
21  return (5);
22 }
23 
24 static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value)
25 {
26 }
27 
28 static irqreturn_t
29 netjet_u_interrupt(int intno, void *dev_id)
30 {
31  struct IsdnCardState *cs = dev_id;
32  u_char val, sval;
33  u_long flags;
34 
35  spin_lock_irqsave(&cs->lock, flags);
36  if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) &
37  NETJET_ISACIRQ)) {
38  val = NETjet_ReadIC(cs, ICC_ISTA);
39  if (cs->debug & L1_DEB_ISAC)
40  debugl1(cs, "tiger: i1 %x %x", sval, val);
41  if (val) {
42  icc_interrupt(cs, val);
43  NETjet_WriteIC(cs, ICC_MASK, 0xFF);
44  NETjet_WriteIC(cs, ICC_MASK, 0x0);
45  }
46  }
47  /* start new code 13/07/00 GE */
48  /* set bits in sval to indicate which page is free */
49  if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
50  inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
51  /* the 2nd write page is free */
52  sval = 0x08;
53  else /* the 1st write page is free */
54  sval = 0x04;
55  if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
56  inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
57  /* the 2nd read page is free */
58  sval = sval | 0x02;
59  else /* the 1st read page is free */
60  sval = sval | 0x01;
61  if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */
62  {
63  if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
64  spin_unlock_irqrestore(&cs->lock, flags);
65  return IRQ_HANDLED;
66  }
67  cs->hw.njet.irqstat0 = sval;
68  if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) !=
69  (cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
70  /* we have a read dma int */
71  read_tiger(cs);
72  if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
73  (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
74  /* we have a write dma int */
75  write_tiger(cs);
76  /* end new code 13/07/00 GE */
77  test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
78  }
79  spin_unlock_irqrestore(&cs->lock, flags);
80  return IRQ_HANDLED;
81 }
82 
83 static void
84 reset_netjet_u(struct IsdnCardState *cs)
85 {
86  cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
87  byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
88  mdelay(10);
89  cs->hw.njet.ctrl_reg = 0x40; /* Reset Off and status read clear */
90  /* now edge triggered for TJ320 GE 13/07/00 */
91  byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
92  mdelay(10);
93  cs->hw.njet.auxd = 0xC0;
94  cs->hw.njet.dmactrl = 0;
95  byteout(cs->hw.njet.auxa, 0);
96  byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
97  byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
98  byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
99 }
100 
101 static int
102 NETjet_U_card_msg(struct IsdnCardState *cs, int mt, void *arg)
103 {
104  u_long flags;
105 
106  switch (mt) {
107  case CARD_RESET:
108  spin_lock_irqsave(&cs->lock, flags);
109  reset_netjet_u(cs);
110  spin_unlock_irqrestore(&cs->lock, flags);
111  return (0);
112  case CARD_RELEASE:
113  release_io_netjet(cs);
114  return (0);
115  case CARD_INIT:
116  spin_lock_irqsave(&cs->lock, flags);
117  inittiger(cs);
118  reset_netjet_u(cs);
120  initicc(cs);
121  /* Reenable all IRQ */
122  cs->writeisac(cs, ICC_MASK, 0);
123  spin_unlock_irqrestore(&cs->lock, flags);
124  return (0);
125  case CARD_TEST:
126  return (0);
127  }
128  return (0);
129 }
130 
131 static int __devinit nju_pci_probe(struct pci_dev *dev_netjet,
132  struct IsdnCardState *cs)
133 {
134  if (pci_enable_device(dev_netjet))
135  return (0);
136  pci_set_master(dev_netjet);
137  cs->irq = dev_netjet->irq;
138  if (!cs->irq) {
139  printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
140  return (0);
141  }
142  cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
143  if (!cs->hw.njet.base) {
144  printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n");
145  return (0);
146  }
147 
148  return (1);
149 }
150 
151 static int __devinit nju_cs_init(struct IsdnCard *card,
152  struct IsdnCardState *cs)
153 {
154  cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
155  cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
156  mdelay(10);
157 
158  cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
159  byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
160  mdelay(10);
161 
162  cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
163  byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
164  mdelay(10);
165 
166  cs->hw.njet.auxd = 0xC0;
167  cs->hw.njet.dmactrl = 0;
168 
169  byteout(cs->hw.njet.auxa, 0);
170  byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
171  byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
172  byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
173 
174  switch (((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3))
175  {
176  case 3:
177  return 1; /* end loop */
178 
179  case 0:
180  printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n");
181  return -1; /* continue looping */
182 
183  default:
184  printk(KERN_WARNING "NETspider-U: No PCI card found\n");
185  return 0; /* end loop & function */
186  }
187  return 1; /* end loop */
188 }
189 
190 static int __devinit nju_cs_init_rest(struct IsdnCard *card,
191  struct IsdnCardState *cs)
192 {
193  const int bytecnt = 256;
194 
196  "NETspider-U: PCI card configured at %#lx IRQ %d\n",
197  cs->hw.njet.base, cs->irq);
198  if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) {
200  "HiSax: NETspider-U config port %#lx-%#lx "
201  "already in use\n",
202  cs->hw.njet.base,
203  cs->hw.njet.base + bytecnt);
204  return (0);
205  }
206  setup_icc(cs);
207  cs->readisac = &NETjet_ReadIC;
208  cs->writeisac = &NETjet_WriteIC;
209  cs->readisacfifo = &NETjet_ReadICfifo;
210  cs->writeisacfifo = &NETjet_WriteICfifo;
211  cs->BC_Read_Reg = &dummyrr;
212  cs->BC_Write_Reg = &dummywr;
213  cs->BC_Send_Data = &netjet_fill_dma;
214  cs->cardmsg = &NETjet_U_card_msg;
215  cs->irq_func = &netjet_u_interrupt;
216  cs->irq_flags |= IRQF_SHARED;
217  ICCVersion(cs, "NETspider-U:");
218 
219  return (1);
220 }
221 
222 static struct pci_dev *dev_netjet __devinitdata = NULL;
223 
224 int __devinit
226 {
227  int ret;
228  struct IsdnCardState *cs = card->cs;
229  char tmp[64];
230 
231 #ifdef __BIG_ENDIAN
232 #error "not running on big endian machines now"
233 #endif
234 
235  strcpy(tmp, NETjet_U_revision);
236  printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp));
237  if (cs->typ != ISDN_CTYPE_NETJET_U)
238  return (0);
239  test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
240 
241  for (;;)
242  {
243  if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
244  PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
245  ret = nju_pci_probe(dev_netjet, cs);
246  if (!ret)
247  return (0);
248  } else {
249  printk(KERN_WARNING "NETspider-U: No PCI card found\n");
250  return (0);
251  }
252 
253  ret = nju_cs_init(card, cs);
254  if (!ret)
255  return (0);
256  if (ret > 0)
257  break;
258  /* ret < 0 == continue looping */
259  }
260 
261  return nju_cs_init_rest(card, cs);
262 }