1 /**************************************************************************/
2 /* File: pcan_pci.c - support for PEAK System PCAN-PCI cards */
4 /* LinCAN - (Not only) Linux CAN bus driver */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
7 /* Funded by OCERA and FRESCOR IST projects */
8 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
10 /* LinCAN is free software; you can redistribute it and/or modify it */
11 /* under terms of the GNU General Public License as published by the */
12 /* Free Software Foundation; either version 2, or (at your option) any */
13 /* later version. LinCAN is distributed in the hope that it will be */
14 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
15 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* General Public License for more details. You should have received a */
17 /* copy of the GNU General Public License along with LinCAN; see file */
18 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
19 /* Cambridge, MA 02139, USA. */
21 /* To allow use of LinCAN in the compact embedded systems firmware */
22 /* and RT-executives (RTEMS for example), main authors agree with next */
23 /* special exception: */
25 /* Including LinCAN header files in a file, instantiating LinCAN generics */
26 /* or templates, or linking other files with LinCAN objects to produce */
27 /* an application image/executable, does not by itself cause the */
28 /* resulting application image/executable to be covered by */
29 /* the GNU General Public License. */
30 /* This exception does not however invalidate any other reasons */
31 /* why the executable file might be covered by the GNU Public License. */
32 /* Publication of enhanced or derived LinCAN files is required although. */
33 /**************************************************************************/
35 #include "../include/can.h"
36 #include "../include/can_sysdep.h"
37 #include "../include/main.h"
38 #include "../include/sja1000p.h"
40 #ifdef CAN_ENABLE_PCI_SUPPORT
42 /* This card is based on Infineon's PSB 4600 PITA bridge */
44 #define PITA_ICR 0x00 /* interrupt control register */
45 #define PITA_ICR_STAT 0x00 /* - status/IRQ pending bits */
46 #define PITA_ICR_IEN 0x02 /* - IRQ enable bits */
47 #define PITA_GPIOICR 0x18 /* general purpose IO interface control register */
48 #define PITA_MISC 0x1C /* misc register */
50 #define PCAN_PCI_CONFIG_PORT_SIZE 0x1000 /* size of the config io-memory */
51 #define PCAN_PCI_PORT_SIZE 0x0400 /* size of a channel io-memory */
53 #define PCAN_PCI_VENDOR_ID 0x001C /* PCAN-PCI and clones vednor id */
54 #define PCAN_PCI_PRODUCT_ID 0x0001 /* PCAN-PCI and clones device ID */
56 /* Standard value: Pushpull (OCTP1|OCTN1|OCPOL1|OCTP0|OCTN0|OCM1) */
57 #define PCAN_PCI_OCR_DEFAULT_STD 0xFA
59 #define PCAN_PCI_BYTES_PER_CIRCUIT 0x400
60 #define PCAN_PCI_BYTES_PER_REG 4
62 /* Conversion of the chip index to IRQ register mask */
63 static unsigned int pcan_pci_idx2mask[4]={
70 void pcan_pci_disconnect_irq(struct candevice_t *candev)
74 /* disable interrupts sources */
75 w = can_readw(candev->aux_base_addr + PITA_ICR_IEN);
76 can_writew(w & ~0xC3, candev->aux_base_addr + PITA_ICR_IEN);
79 void pcan_pci_connect_irq(struct candevice_t *candev)
84 /* clear previous accumulated status */
85 can_writew(0xC3, candev->aux_base_addr + PITA_ICR_STAT);
87 /* enable interrupts sources */
88 w = can_readw(candev->aux_base_addr + PITA_ICR_IEN);
89 for(i = 0; i < candev->nr_all_chips; i++)
90 w |= pcan_pci_idx2mask[i];
91 can_writew(w, candev->aux_base_addr + PITA_ICR_IEN);
95 int pcan_pci_request_io(struct candevice_t *candev)
97 unsigned long ctrl_addr;
98 unsigned long io_addr;
101 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
102 if(pci_request_region(candev->sysdevptr.pcidev, 0, "pcan_pci_ctrl") != 0){
103 CANMSG("Request of pcan_pci_ctrl range failed\n");
105 }else if(pci_request_region(candev->sysdevptr.pcidev, 1, "pcan_pci_io") != 0){
106 CANMSG("Request of pcan_pci_io range failed\n");
109 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
110 if(pci_request_regions(candev->sysdevptr.pcidev, "pcan_pci") != 0){
111 CANMSG("Request of pcan_pci_bridge regions failed\n");
114 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
116 ctrl_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
117 if (!(candev->aux_base_addr = ioremap(ctrl_addr,
118 pci_resource_len(candev->sysdevptr.pcidev,0)))) {
119 CANMSG("Unable to access I/O memory at: 0x%lx\n", ctrl_addr);
120 goto error_ioremap_ctrl;
123 io_addr=pci_resource_start(candev->sysdevptr.pcidev,1);;
124 if (!(candev->dev_base_addr = ioremap(io_addr,
125 pci_resource_len(candev->sysdevptr.pcidev,1)))) {
126 CANMSG("Unable to access I/O memory at: 0x%lx\n", io_addr);
127 goto error_ioremap_io;
130 candev->io_addr=io_addr;
131 candev->res_addr=ctrl_addr;
134 * this is redundant with chip initialization, but remap address
135 * can change when resources are temporarily released
137 for(i=0;i<candev->nr_all_chips;i++) {
138 struct canchip_t *chip=candev->chip[i];
140 chip->chip_base_addr = candev->dev_base_addr +
141 i * PCAN_PCI_BYTES_PER_CIRCUIT;
142 if(!chip->msgobj[0]) continue;
143 chip->msgobj[0]->obj_base_addr=chip->chip_base_addr;
146 pcan_pci_disconnect_irq(candev);
149 can_writew(0x0005, candev->aux_base_addr + PITA_GPIOICR + 2); /* set GPIO control register */
151 can_writeb(0x00, candev->aux_base_addr + PITA_GPIOICR); /* enable all channels */
153 can_writeb(0x05, candev->aux_base_addr + PITA_MISC + 3); /* toggle reset */
155 writeb(0x04, candev->aux_base_addr + PITA_MISC + 3); /* leave parport mux mode */
161 iounmap(candev->aux_base_addr);
163 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
164 pci_release_region(candev->sysdevptr.pcidev, 1);
166 pci_release_region(candev->sysdevptr.pcidev, 0);
167 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
168 pci_release_regions(candev->sysdevptr.pcidev);
169 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
174 int pcan_pci_release_io(struct candevice_t *candev)
176 pcan_pci_disconnect_irq(candev);
178 iounmap(candev->dev_base_addr);
179 iounmap(candev->aux_base_addr);
180 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
181 pci_release_region(candev->sysdevptr.pcidev, 1);
182 pci_release_region(candev->sysdevptr.pcidev, 0);
183 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
184 pci_release_regions(candev->sysdevptr.pcidev);
185 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
190 void pcan_pci_write_register(unsigned data, can_ioptr_t address)
192 address += ((can_ioptr2ulong(address)&(PCAN_PCI_BYTES_PER_CIRCUIT-1))
193 *(PCAN_PCI_BYTES_PER_REG-1));
194 can_writeb(data,address);
197 unsigned pcan_pci_read_register(can_ioptr_t address)
199 address += ((can_ioptr2ulong(address)&(PCAN_PCI_BYTES_PER_CIRCUIT-1))
200 *(PCAN_PCI_BYTES_PER_REG-1));
201 return can_readb(address);
204 int pcan_pci_irq_handler(int irq, struct canchip_t *chip)
206 struct candevice_t *candev=chip->hostdevice;
208 unsigned int icr_stat;
209 unsigned int chip_mask = pcan_pci_idx2mask[chip->chip_idx];
211 icr_stat = can_readw(candev->aux_base_addr + PITA_ICR_STAT);
213 if(!(icr_stat & chip_mask)) return CANCHIP_IRQ_NONE;
215 ret = sja1000p_irq_handler(irq, chip);
217 can_writew(chip_mask, candev->aux_base_addr + PITA_ICR_STAT);
222 int pcan_pci_reset(struct candevice_t *candev)
225 struct canchip_t *chip;
228 DEBUGMSG("Resetting pcan_pci hardware ...\n");
230 pcan_pci_disconnect_irq(candev);
232 for(chip_nr=0;chip_nr<candev->nr_all_chips;chip_nr++){
233 if(!candev->chip[chip_nr]) continue;
234 chip=candev->chip[chip_nr];
236 pcan_pci_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
239 cdr=pcan_pci_read_register(chip->chip_base_addr+SJACDR);
240 pcan_pci_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
242 pcan_pci_write_register(0, chip->chip_base_addr+SJAIER);
245 pcan_pci_write_register(0, chip->chip_base_addr+SJAMOD);
246 while (pcan_pci_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
247 if(!i--) return -ENODEV;
249 pcan_pci_write_register(0, chip->chip_base_addr+SJAMOD);
252 cdr=pcan_pci_read_register(chip->chip_base_addr+SJACDR);
253 pcan_pci_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
255 pcan_pci_write_register(0, chip->chip_base_addr+SJAIER);
257 pcan_pci_read_register(chip->chip_base_addr+SJAIR);
261 pcan_pci_connect_irq(candev);
266 int pcan_pci_init_hw_data(struct candevice_t *candev)
268 struct pci_dev *pcidev = NULL;
275 pcidev = pci_find_device(PCAN_PCI_VENDOR_ID, PCAN_PCI_PRODUCT_ID, pcidev);
277 printk(KERN_ERR "No unused PCAN_PCI #%d card found\n", i);
281 } while(can_check_dev_taken(pcidev));
283 if (pci_enable_device (pcidev)){
284 printk(KERN_ERR "Enable PCAN_PCI failed\n");
287 candev->sysdevptr.pcidev=pcidev;
289 if(pci_read_config_word(pcidev, 0x2E, &subsysid))
292 if(pci_write_config_word(pcidev, 0x04, 2))
295 if(pci_write_config_word(pcidev, 0x44, 0))
301 if(!(pci_resource_flags(pcidev,0)&IORESOURCE_MEM)){
302 printk(KERN_ERR "PCAN_PCI region %d is not memory\n",i);
307 candev->res_addr=pci_resource_start(pcidev,0); /* Control registers */
308 candev->io_addr=pci_resource_start(pcidev,1); /* SJA1000 chips are mapped here */
309 candev->dev_base_addr=pci_resource_start(pcidev,1);
311 /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
315 else if(subsysid >= 10)
317 else if(subsysid >= 4)
322 candev->nr_82527_chips=0;
323 candev->nr_sja1000_chips=nr_chips;
324 candev->nr_all_chips=nr_chips;
326 printk(KERN_INFO "Found PCAN_PCI device with %d chip(s)\n", nr_chips);
332 printk(KERN_CRIT "Setup of PCAN_PCI failed\n");
333 pci_disable_device (pcidev);
337 int pcan_pci_init_chip_data(struct candevice_t *candev, int chipnr)
340 if(candev->sysdevptr.pcidev==NULL)
343 sja1000p_fill_chipspecops(candev->chip[chipnr]);
345 /* special version of the IRQ handler is required for PCAN_PCI board */
346 candev->chip[chipnr]->chipspecops->irq_handler=pcan_pci_irq_handler;
348 candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
350 candev->chip[chipnr]->chip_base_addr=
351 can_ioport2ioptr(candev->io_addr+chipnr*PCAN_PCI_BYTES_PER_CIRCUIT);
352 candev->chip[chipnr]->flags = 0;
353 candev->chip[chipnr]->int_cpu_reg = 0;
354 candev->chip[chipnr]->int_clk_reg = 0;
355 candev->chip[chipnr]->int_bus_reg = 0;
356 candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
357 candev->chip[chipnr]->sja_ocr_reg = PCAN_PCI_OCR_DEFAULT_STD;
358 candev->chip[chipnr]->clock = 16000000;
359 candev->chip[chipnr]->flags |= CHIP_IRQ_PCI;
364 int pcan_pci_init_obj_data(struct canchip_t *chip, int objnr)
366 chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
370 int pcan_pci_program_irq(struct candevice_t *candev)
376 int pcan_pci_register(struct hwspecops_t *hwspecops)
378 hwspecops->request_io = pcan_pci_request_io;
379 hwspecops->release_io = pcan_pci_release_io;
380 hwspecops->reset = pcan_pci_reset;
381 hwspecops->init_hw_data = pcan_pci_init_hw_data;
382 hwspecops->init_chip_data = pcan_pci_init_chip_data;
383 hwspecops->init_obj_data = pcan_pci_init_obj_data;
384 hwspecops->write_register = pcan_pci_write_register;
385 hwspecops->read_register = pcan_pci_read_register;
386 hwspecops->program_irq = pcan_pci_program_irq;
391 #endif /*CAN_ENABLE_PCI_SUPPORT*/