1 /* adlink7841.c - support for ADLINK 7841 cards
2 * Linux CAN-bus device driver.
3 * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4 * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
5 * email:pisa@cmp.felk.cvut.cz
6 * This software is released under the GPL-License.
7 * Version lincan-0.3 17 Jun 2004
10 #include "../include/can.h"
11 #include "../include/can_sysdep.h"
12 #include "../include/main.h"
13 #include "../include/sja1000p.h"
15 #ifdef CAN_ENABLE_PCI_SUPPORT
17 #define ADLINK7841_PCI_VENDOR_ID 0x144A /* ADLINK vednor id */
18 #define ADLINK7841_PCI_PRODUCT_ID 0x7841 /* PCI 7841 device ID */
20 /* PCI to local bus bridge PLX9050 */
22 #define PLX9050_INTCSR 0x4c /* interrupt control register */
24 #define ADLINK7841_BYTES_PER_CIRCUIT 0x80
26 // Standard value: Pushpull (OCTP1|OCTN1|OCPOL1|OCTP0|OCTN0|OCM1)
27 #define ADLINK7841_OCR_DEFAULT_STD 0xFA
31 You need to know the following:
32 " RX1 is connected to ground.
33 " TX1 is not connected.
34 " CLKO is not connected.
35 " Setting the OCR register to 0xFA is a good idea.
36 This means normal output mode , push-pull and the correct polarity.
37 " In the CDR register, you should set CBP to 1.
38 You will probably also want to set the clock divider value to 0 (meaning divide-by-2),
39 the Pelican bit, and the clock-off bit (you have no need for CLKOUT anyway.)
45 void adlink7841_disconnect_irq(struct candevice_t *candev)
49 void adlink7841_connect_irq(struct candevice_t *candev)
54 int adlink7841_request_io(struct candevice_t *candev)
56 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
57 if(pci_request_region(candev->sysdevptr.pcidev, 1, "adlink7841_plx9050") != 0){
58 CANMSG("Request of adlink7841_plx9050 range failed\n");
60 }else if(pci_request_region(candev->sysdevptr.pcidev, 2, "adlink7841_io") != 0){
61 CANMSG("Request of adlink7841_io range failed\n");
64 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
65 if(pci_request_regions(candev->sysdevptr.pcidev, "adlink7841") != 0){
66 CANMSG("Request of adlink7841_plx9050 regions failed\n");
69 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
71 adlink7841_disconnect_irq(candev);
75 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
77 pci_release_region(candev->sysdevptr.pcidev, 1);
78 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
83 int adlink7841_release_io(struct candevice_t *candev)
85 adlink7841_disconnect_irq(candev);
87 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
88 pci_release_region(candev->sysdevptr.pcidev, 2);
89 pci_release_region(candev->sysdevptr.pcidev, 1);
90 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
91 pci_release_regions(candev->sysdevptr.pcidev);
92 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
98 void adlink7841_write_register(unsigned data, unsigned long address)
103 unsigned adlink7841_read_register(unsigned long address)
108 int adlink7841_reset(struct candevice_t *candev)
111 struct canchip_t *chip;
114 DEBUGMSG("Resetting adlink7841 hardware ...\n");
116 adlink7841_disconnect_irq(candev);
118 for(chip_nr=0;chip_nr<candev->nr_all_chips;chip_nr++){
119 if(!candev->chip[chip_nr]) continue;
120 chip=candev->chip[chip_nr];
122 adlink7841_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
125 cdr=adlink7841_read_register(chip->chip_base_addr+SJACDR);
126 adlink7841_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
128 adlink7841_write_register(0, chip->chip_base_addr+SJAIER);
131 adlink7841_write_register(0, chip->chip_base_addr+SJAMOD);
132 while (adlink7841_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
133 if(!i--) return -ENODEV;
135 adlink7841_write_register(0, chip->chip_base_addr+SJAMOD);
138 cdr=adlink7841_read_register(chip->chip_base_addr+SJACDR);
139 adlink7841_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
141 adlink7841_write_register(0, chip->chip_base_addr+SJAIER);
143 adlink7841_read_register(chip->chip_base_addr+SJAIR);
147 adlink7841_connect_irq(candev);
152 int adlink7841_init_hw_data(struct candevice_t *candev)
154 struct pci_dev *pcidev = NULL;
158 pcidev = pci_find_device(ADLINK7841_PCI_VENDOR_ID, ADLINK7841_PCI_PRODUCT_ID, pcidev);
159 if(pcidev == NULL) return -ENODEV;
160 } while(can_check_dev_taken(pcidev));
162 if (pci_enable_device (pcidev)){
163 printk(KERN_CRIT "Setup of ADLINK7841 failed\n");
166 candev->sysdevptr.pcidev=pcidev;
169 if(!(pci_resource_flags(pcidev,i)&IORESOURCE_IO)){
170 printk(KERN_CRIT "ADLINK7841 region %d is not IO\n",i);
174 candev->dev_base_addr=pci_resource_start(pcidev,1); /* PLX 9050 BASE*/
175 candev->io_addr=pci_resource_start(pcidev,2); /*IO window for SJA1000 chips*/
176 candev->res_addr=pci_resource_start(pcidev,1); /*reserved*/
178 /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
180 candev->nr_82527_chips=0;
181 candev->nr_sja1000_chips=2;
182 candev->nr_all_chips=2;
187 int adlink7841_init_chip_data(struct candevice_t *candev, int chipnr)
190 if(candev->sysdevptr.pcidev==NULL)
193 candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
195 sja1000p_fill_chipspecops(candev->chip[chipnr]);
196 candev->chip[chipnr]->chip_base_addr=
197 candev->io_addr+chipnr*ADLINK7841_BYTES_PER_CIRCUIT;
198 candev->chip[chipnr]->flags = 0;
199 candev->chip[chipnr]->int_cpu_reg = 0;
200 candev->chip[chipnr]->int_clk_reg = 0;
201 candev->chip[chipnr]->int_bus_reg = 0;
202 candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
203 candev->chip[chipnr]->sja_ocr_reg = ADLINK7841_OCR_DEFAULT_STD;
204 candev->chip[chipnr]->clock = 16000000;
205 candev->chip[chipnr]->flags |= CHIP_IRQ_PCI;
210 int adlink7841_init_obj_data(struct canchip_t *chip, int objnr)
212 chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
216 int adlink7841_program_irq(struct candevice_t *candev)
222 int adlink7841_register(struct hwspecops_t *hwspecops)
224 hwspecops->request_io = adlink7841_request_io;
225 hwspecops->release_io = adlink7841_release_io;
226 hwspecops->reset = adlink7841_reset;
227 hwspecops->init_hw_data = adlink7841_init_hw_data;
228 hwspecops->init_chip_data = adlink7841_init_chip_data;
229 hwspecops->init_obj_data = adlink7841_init_obj_data;
230 hwspecops->write_register = adlink7841_write_register;
231 hwspecops->read_register = adlink7841_read_register;
232 hwspecops->program_irq = adlink7841_program_irq;
237 #endif /*CAN_ENABLE_PCI_SUPPORT*/