]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/nsi_canpci.c
97ce2b43ba09c6cd49ad9ccd8d67099daa3ca1db
[lincan.git] / lincan / src / nsi_canpci.c
1 /* nsi.c
2  * Linux CAN-bus device driver.
3  * nsi_canpci.c - support for NSI CAN PCI card
4  * The card support added by Eric Pennamen <pennamen@gmail.com>
5  * Based on code from Arnaud Westenberg email:arnaud@wanadoo.nl
6  * Ake Hedman, eurosource, akhe@eurosource.se ,
7  * and Pavel Pisa - OCERA team member email:pisa@cmp.felk.cvut.cz
8  * This software is released under the GPL-License.
9  * Version lincan-0.3  17 Jun 2004
10  */ 
11
12 #include "../include/can.h"
13 #include "../include/can_sysdep.h"
14 #include "../include/main.h"
15 #include "../include/nsi_canpci.h"
16 #include "../include/i82527.h"
17
18 extern int stdmask;
19 extern int extmask;
20 extern int mo15mask;
21
22 #define __NO_VERSION__
23 #include <linux/module.h>
24
25 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10))
26         #define ioread32        can_readl
27         #define iowrite32       can_writel
28         #define ioread8         can_readb
29         #define iowrite8        can_writeb
30 #else
31 #endif
32
33
34
35 #define INT_CONF 0x00000040     /* value for register INTCSR of PLX */
36 #define NSI_VENDOR_ID           0x1637
37 #define NSI_CANPCI_DEVICE_ID    0x0001
38
39 enum PORT2 { P2_0=1, P2_1=1<<1, P2_2=1<<2, P2_3=1<<3, P2_4=1<<4, P2_5=1<<5, P2_6=1<<6, P2_7=1<<7 };
40
41 /*PLX register definition */
42 #define PLX_CNTRL       0x50    /* Controle register */
43 #define PLX_INTCSR      0x4C    /* Interruption controle register */
44
45 /* This value define the i82527 clock frequency */
46 #define iCLOCK          16000000
47
48
49 /* Il faut reserver 4 zones:
50  *              BAR0: 128 octets memoire (32bits) pour les registres du PLX9052
51  *              BAR1: 128 octets I/O pour les registres du PLX9052
52  *              BAR2: 256 octets memoire(8bits) pour les registres du PLX9052
53  *              BAR3: 256 octets memoire(8bits) pour les registres du PLX9052
54  */
55 /* Variables globales contenant les @ des IO-Memory apres remap */
56 #define NB_VALID_BAR    4
57
58 typedef struct {
59         void* addr_BAR_remap[NB_VALID_BAR];
60 }t_CardArray;
61
62 void nsi_canpci_connect_irq(struct candevice_t *candev)
63 {
64 //Not used
65 }
66 void nsi_canpci_disconnect_irq(struct candevice_t *candev)
67 {
68 //on disconnecting interrupt we need to disable interruption form PLX
69         iowrite32(0x0,(void*)(candev->io_addr+PLX_INTCSR));
70         DEBUGMSG("PLX interrupt disabled\n");
71 }
72
73 int nsi_canpci_config_irqs(struct canchip_t *chip, short irqs)
74 {
75         
76         unsigned long it_mask,it_reg;
77         struct candevice_t *candev;
78         it_mask=0;
79         DEBUGMSG("Configuring NSI CANPCI interrupt\n");
80         can_write_reg(chip,irqs,iCTL);
81         if( (irqs&0x0E)!=0)
82         {//At least one interrupt source requested
83                 if(chip->chip_idx==0)
84                 {
85                         DEBUGMSG("starting interrupt on chip 0\n");
86                         it_mask=1;
87                 }
88                 else
89                 {
90                         DEBUGMSG("starting interrupt on chip 1\n");
91                         it_mask=8;
92                 }
93                 candev=chip->hostdevice;
94                 it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
95                 it_reg|=it_mask|0x40;
96                 iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
97         }
98         else
99         {//No more interrupt source
100                 if(chip->chip_idx==0)
101                 {
102                         DEBUGMSG("stoping interrupt on chip 0\n");
103                         it_mask=1;
104                 }
105                 else
106                 {
107                         DEBUGMSG("stoping interrupt on chip 1\n");
108                         it_mask=8;
109                 }
110                 candev=chip->hostdevice;
111                 it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
112                 it_reg&=~it_mask;
113                 iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
114         }
115         return 0;
116 }
117
118 int nsi_canpci_i82527_chip_config(struct canchip_t *chip)
119 {
120         can_write_reg(chip,chip->int_cpu_reg,iCPU); // Configure cpu interface
121         can_write_reg(chip,(iCTL_CCE|iCTL_INI),iCTL); // Enable configuration
122         i82527_seg_write_reg(chip,chip->int_clk_reg,iCLK); // Set clock out slew rates 
123         i82527_seg_write_reg(chip,chip->int_bus_reg,iBUS); /* Bus configuration */
124         
125         can_write_reg(chip,P2_2|P2_1,iP2C); // The pin P2_2,P2_1 of the 527 must be set as output
126         can_write_reg(chip,P2_2|P2_1,iP2O); // and P2_2 must be set to 1
127         
128         can_write_reg(chip,0x00,iSTAT); /* Clear error status register */
129
130         /* Check if we can at least read back some arbitrary data from the 
131          * card. If we can not, the card is not properly configured!
132          */
133         canobj_write_reg(chip,chip->msgobj[1],0x25,iMSGDAT1);
134         canobj_write_reg(chip,chip->msgobj[2],0x52,iMSGDAT3);
135         canobj_write_reg(chip,chip->msgobj[10],0xc3,iMSGDAT6);
136         if ( (canobj_read_reg(chip,chip->msgobj[1],iMSGDAT1) != 0x25) ||
137               (canobj_read_reg(chip,chip->msgobj[2],iMSGDAT3) != 0x52) ||
138               (canobj_read_reg(chip,chip->msgobj[10],iMSGDAT6) != 0xc3) ) {
139                 CANMSG("Could not read back from the hardware.\n");
140                 CANMSG("This probably means that your hardware is not correctly configured!\n");
141                 return -1;
142         }
143         else
144                 DEBUGMSG("Could read back, hardware is probably configured correctly\n");
145
146         if (chip->baudrate == 0)
147                 chip->baudrate=1600000;
148
149         if (i82527_baud_rate(chip,chip->baudrate,chip->clock,0,75,0)) {
150                 CANMSG("Error configuring baud rate\n");
151                 return -ENODEV;
152         }
153         if (i82527_standard_mask(chip,0x0000,stdmask)) {
154                 CANMSG("Error configuring standard mask\n");
155                 return -ENODEV;
156         }
157         if (i82527_extended_mask(chip,0x00000000,extmask)) {
158                 CANMSG("Error configuring extended mask\n");
159                 return -ENODEV;
160         }
161         if (i82527_message15_mask(chip,0x00000000,mo15mask)) {
162                 CANMSG("Error configuring message 15 mask\n");
163                 return -ENODEV;
164         }
165         if (i82527_clear_objects(chip)) {
166                 CANMSG("Error clearing message objects\n");
167                 return -ENODEV;
168         }
169         
170         if (nsi_canpci_config_irqs(chip,iCTL_IE|iCTL_EIE)) { /* has been 0x0a */
171                 CANMSG("Error configuring interrupts\n");
172                 return -ENODEV;
173         }       
174         return 0;
175 }
176
177
178 int nsi_canpci_start_chip(struct canchip_t *chip)
179 {
180         unsigned long it_mask,it_reg;
181         struct candevice_t *candev;
182         it_mask=0;
183         if(chip->chip_idx==0)
184         {
185                 DEBUGMSG("starting chip 0\n");
186                 it_mask=1;
187         }
188         else
189         {
190                 DEBUGMSG("starting chip 1\n");
191                 it_mask=8;
192         }
193         candev=chip->hostdevice;
194         it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
195         rmb();
196         it_reg|=it_mask|0x40;
197         iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
198         wmb();  
199         i82527_start_chip(chip);
200         return 0;
201 }
202
203 int nsi_canpci_stop_chip(struct canchip_t *chip)
204 {
205         unsigned long it_mask,it_reg;
206         struct candevice_t *candev;
207         it_mask=0;
208         if(chip->chip_idx==0)
209         {
210                 DEBUGMSG("stoping chip 0\n");
211                 it_mask=1;
212         }
213         else
214         {
215                 DEBUGMSG("stoping chip 1\n");
216                 it_mask=8;
217         }
218         candev=chip->hostdevice;
219         it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
220         rmb();
221         it_reg&=~it_mask;
222         iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
223         wmb();  
224         i82527_stop_chip(chip);
225         return 0;
226 }
227
228 int nsi_canpci_irq_handler(int irq, struct canchip_t *chip)
229 {
230         int retcode;
231         unsigned long it_reg;
232         struct candevice_t *candev;
233         candev=chip->hostdevice;
234         retcode = CANCHIP_IRQ_NONE;
235         it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
236         rmb();
237         if(chip->chip_idx==0)
238         {
239                 if((it_reg &0x4)!=0) //interrupt active
240                 {
241                         if(i82527_irq_handler(irq,chip)==CANCHIP_IRQ_NONE)
242                         {//some trouble with IT
243                                 it_reg&=~(0x01);
244                                 CANMSG("Unexcepted interruption from canal0, interruption is canceled\n");
245
246                         }else
247                         {
248                                 retcode=CANCHIP_IRQ_HANDLED;
249                         }
250                 
251                 }
252         }
253         else
254         {
255                 if((it_reg &0x20)!=0) //interrupt is set
256                 {
257                         if(i82527_irq_handler(irq,chip)==CANCHIP_IRQ_NONE)
258                         {//soucis avec les IT
259                                 it_reg&=~(0x08);
260                                 CANMSG("Unexcepted interruption from canal1, interruption is canceled\n");
261                         }else
262                         {
263                                 retcode=CANCHIP_IRQ_HANDLED;
264                         }       
265                 }
266         }
267         return retcode;
268 }
269
270 /* The function template_request_io is used to reserve the io-memory. If your
271  * hardware uses a dedicated memory range as hardware control registers you
272  * will have to add the code to reserve this memory as well.
273  * The reserved memory starts at candev->io_addr, wich is the module parameter io.
274  */
275 int nsi_canpci_request_io(struct candevice_t *candev)
276 {
277   (void)candev;
278   if(candev->dev_base_addr==0)
279         return -EIO;  
280   return 0;
281 }
282
283 /* The function template_release_io is used to free the previously reserved 
284  * io-memory. In case you reserved more memory, don't forget to free it here.
285  */
286 int nsi_canpci_release_io(struct candevice_t *candev)
287 {
288         unsigned long reg_reset;
289         struct pci_dev *pcidev = candev->sysdevptr.pcidev;
290         DEBUGMSG("Releasing board io\n");
291         
292         nsi_canpci_disconnect_irq(candev);
293         // First, set RESET signal to 0
294         reg_reset = ioread32( (void*)(candev->io_addr+PLX_CNTRL));
295         reg_reset&=(~(0x40000000));
296         rmb();
297         //Then set it to '1' for reseting the board
298         iowrite32( (reg_reset | 0x40000000 ),(void*)(candev->io_addr+PLX_CNTRL));
299         wmb();
300         udelay(2500); /* This delay must be greater than 1ms for i82527 */
301         iowrite32( (reg_reset ),(void*)(candev->io_addr+PLX_CNTRL)); //Releasing RESET signal
302         wmb();
303         udelay(2500); // Waiting for some additionnal time before writing in the 82527
304         iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]);
305         iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[1]);
306         iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[2]);
307         iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[3]);
308         kfree((void*)(candev->dev_base_addr));
309         pci_release_region(pcidev,0);
310         pci_release_region(pcidev,1);
311         pci_release_region(pcidev,2);                   
312         pci_release_region(pcidev,3);                   
313         return 0;
314 }
315
316 /* The function template_reset is used to give a hardware reset. This is rather
317  * hardware specific so I haven't included example code. Don't forget to check
318  * the reset status of the chip before returning.
319  */
320 int nsi_canpci_reset(struct candevice_t *candev)
321 {
322         unsigned long reg_reset;
323         
324         DEBUGMSG("Board reset !!!\n");
325         // Before reset disconnet interrupt to avoir freeze     
326         nsi_canpci_disconnect_irq(candev);
327         // First, set RESET signal to 0
328         reg_reset = ioread32( (void*)(candev->io_addr+PLX_CNTRL));
329         reg_reset&=(~(0x40000000));
330         //Then set it to '1' for reseting the board
331         iowrite32( (reg_reset | 0x40000000 ),(void*)(candev->io_addr+PLX_CNTRL));
332         wmb();
333         udelay(2500); /* This delay must be greater than 1ms for i82527 */
334         iowrite32(reg_reset,(void*)(candev->io_addr+PLX_CNTRL)); //Releasing RESET signal
335         wmb();
336         udelay(2500); // Waiting for some additionnal time before writing in the 82527
337         DEBUGMSG("Reset done !!!\n");
338         
339         nsi_canpci_connect_irq(candev);
340         return 0;       
341 }
342
343 /* The function template_init_hw_data is used to initialize the hardware
344  * structure containing information about the installed CAN-board.
345  * RESET_ADDR represents the io-address of the hardware reset register.
346  * NR_82527 represents the number of intel 82527 chips on the board.
347  * NR_SJA1000 represents the number of philips sja1000 chips on the board.
348  * The flags entry can currently only be CANDEV_PROGRAMMABLE_IRQ to indicate that
349  * the hardware uses programmable interrupts.
350  */
351
352 int nsi_canpci_init_hw_data(struct candevice_t *candev) 
353      {
354   struct pci_dev *pcidev = NULL;
355
356   /* looking for NSI CANPCI ident on the pci bus*/
357   do
358   {
359     pcidev = pci_find_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID, pcidev);
360   }
361   while(can_check_dev_taken(pcidev));
362   
363   if(pcidev == NULL) 
364   {
365         do
366         {
367         pcidev = pci_find_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID+1, pcidev);
368         }
369         while(can_check_dev_taken(pcidev));
370         if(pcidev == NULL) 
371         {
372                 CANMSG ("Error : NSI CAN PCI device not found\n");
373                 return -ENODEV;
374         }
375         else
376         {
377                 CANMSG ("NSI CANPCI OPTO device found\n");
378         }
379   }
380   else
381   {
382         CANMSG ("NSI CANPCI device found\n");  
383   }
384     
385   /* enable it */
386   if (pci_enable_device (pcidev))
387   {
388     CANMSG ("Cannot enable PCI device\n");
389     return -EIO;
390   }
391   CANMSG ("NSI CANPCI device started\n");
392   candev->sysdevptr.pcidev = pcidev;
393   candev->res_addr=0;
394   candev->nr_82527_chips=2;
395   candev->nr_sja1000_chips=0;
396   candev->nr_all_chips=2; 
397   /* initialize device spinlock */
398   can_spin_lock_init(&candev->device_lock);
399
400   if(pci_request_region(pcidev,0,"nsi_canpci bar0")==0)
401   {
402         if(pci_request_region(pcidev,1,"nsi_canpci bar1")==0)
403         {
404                 if(pci_request_region(pcidev,2,"nsi_canpci bar2")==0)
405                 {
406                         if(pci_request_region(pcidev,3,"nsi_canpci bar3")==0)
407                         {
408                         }
409                         else
410                         {
411                         pci_release_region(pcidev,0);
412                         pci_release_region(pcidev,1);
413                         pci_release_region(pcidev,2);                   
414                         return -EIO;
415                         }
416                 }
417                 else
418                 {
419                 pci_release_region(pcidev,0);
420                 pci_release_region(pcidev,1);
421                 return -EIO;
422                 }
423         }
424         else
425         {
426         pci_release_region(pcidev,0);
427         return -EIO;
428         }
429   }  
430   else
431   {
432         return -EIO;
433   }
434   candev->dev_base_addr=(unsigned long)(kmalloc(sizeof(t_CardArray),GFP_ATOMIC));  
435   
436   if((unsigned long)candev->dev_base_addr==0)
437         return -EIO;
438   //PLX register 
439   ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]=ioremap(pci_resource_start(pcidev,0),pci_resource_len(pcidev,0) );
440   //PLX IO
441   ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[1]=ioremap(pci_resource_start(pcidev,1),pci_resource_len(pcidev,1) );
442   //Chip 0
443   ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[2]=ioremap(pci_resource_start(pcidev,2),pci_resource_len(pcidev,2) );
444   //Chip 1
445   ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[3]=ioremap(pci_resource_start(pcidev,3),pci_resource_len(pcidev,3) );
446   
447   //Short acces to plx register
448   candev->io_addr=(unsigned long)(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]);
449   return 0;  
450 }
451
452 /* The function template_init_chip_data is used to initialize the hardware
453  * structure containing information about the CAN chips.
454  * CHIP_TYPE represents the type of CAN chip. CHIP_TYPE can be "i82527" or
455  * "sja1000".
456  * The chip_base_addr entry represents the start of the 'official' memory map
457  * of the installed chip. It's likely that this is the same as the candev->io_addr
458  * argument supplied at module loading time.
459  * The clock argument holds the chip clock value in Hz.
460  */
461
462 int nsi_canpci_init_chip_data(struct candevice_t *candev, int chipnr)
463 {
464         //u8 irq_line;
465         CANMSG ("NSI chip data init %d\n",chipnr);
466         i82527_fill_chipspecops(candev->chip[chipnr]);
467         
468         candev->chip[chipnr]->chipspecops->chip_config =nsi_canpci_i82527_chip_config;
469         candev->chip[chipnr]->chipspecops->start_chip=nsi_canpci_start_chip;
470         candev->chip[chipnr]->chipspecops->stop_chip=nsi_canpci_stop_chip;
471         candev->chip[chipnr]->chipspecops->config_irqs=nsi_canpci_config_irqs;
472         candev->chip[chipnr]->chipspecops->irq_handler=nsi_canpci_irq_handler;
473         /*candev->chip[chipnr]->chip_data = NULL;*/
474         
475         candev->chip[chipnr]->chip_base_addr= (unsigned long) (((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[chipnr+2]);
476         candev->chip[chipnr]->clock = iCLOCK;
477         candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
478         candev->chip[chipnr]->flags=CHIP_IRQ_PCI;
479         candev->chip[chipnr]->int_cpu_reg = iCPU_DSC+iCPU_CEN;
480         candev->chip[chipnr]->int_clk_reg = iCLK_SL1+iCLK_CD0;
481         candev->chip[chipnr]->int_bus_reg = iBUS_CBY;
482         return 0;
483 }
484
485  /* The function template_init_obj_data is used to initialize the hardware
486  * structure containing information about the different message objects on the
487  * CAN chip. In case of the sja1000 there's only one message object but on the
488  * i82527 chip there are 15.
489  * The code below is for a i82527 chip and initializes the object base addresses
490  * The entry obj_base_addr represents the first memory address of the message 
491  * object. In case of the sja1000 obj_base_addr is taken the same as the chips
492  * base address.
493  * Unless the hardware uses a segmented memory map, flags can be set zero.
494  */
495 int nsi_canpci_init_obj_data(struct canchip_t *chip, int objnr)
496 {
497
498         
499         chip->msgobj[objnr]->obj_base_addr=
500             chip->chip_base_addr+(objnr+1)*0x10;
501         
502         return 0;
503 }
504
505 /* The function template_program_irq is used for hardware that uses programmable
506  * interrupts. If your hardware doesn't use programmable interrupts you should
507  * not set the candevices_t->flags entry to CANDEV_PROGRAMMABLE_IRQ and leave this
508  * function unedited. Again this function is hardware specific so there's no
509  * example code.
510  */
511 int nsi_canpci_program_irq(struct candevice_t *candev)
512 {
513         return 0;
514 }
515
516 /* The function template_write_register is used to write to hardware registers
517  * on the CAN chip. You should only have to edit this function if your hardware
518  * uses some specific write process.
519  */
520 void nsi_canpci_write_register(unsigned data, can_ioptr_t address)
521 {
522         iowrite8((u8)data,(void*)address);
523 }
524
525 /* The function template_read_register is used to read from hardware registers
526  * on the CAN chip. You should only have to edit this function if your hardware
527  * uses some specific read process.
528  */
529 unsigned nsi_canpci_read_register(can_ioptr_t address)
530 {
531         return ioread8((void*)address);
532 }
533
534
535  /* !!! Don't change this function !!! */
536 int nsi_canpci_register(struct hwspecops_t *hwspecops)
537 {
538         hwspecops->request_io = nsi_canpci_request_io;
539         hwspecops->release_io = nsi_canpci_release_io;
540         hwspecops->reset = nsi_canpci_reset;
541         hwspecops->init_hw_data = nsi_canpci_init_hw_data;
542         hwspecops->init_chip_data = nsi_canpci_init_chip_data;
543         hwspecops->init_obj_data = nsi_canpci_init_obj_data;
544         hwspecops->write_register = nsi_canpci_write_register;
545         hwspecops->read_register = nsi_canpci_read_register;
546         hwspecops->program_irq = nsi_canpci_program_irq;
547         return 0;
548 }