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
9 * The support for TS-CAN1 and TS-7KV provided by Ronald Gomes
10 * from Technologic Systems <http://www.embeddedarm.com/>
13 #include "../include/can.h"
14 #include "../include/can_sysdep.h"
15 #include "../include/main.h"
16 #include "../include/pcm3680.h"
17 #include "../include/sja1000p.h"
19 #include <linux/module.h>
20 #include "../include/modparms.h"
21 #include "../include/devcommon.h"
23 #include "../include/tscan1.h"
25 static CAN_DEFINE_SPINLOCK(ts7kv_win_lock);
27 long clock[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
28 MODULE_PARM(clock, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
29 MODULE_PARM_DESC(clock,"clock frequency for each board in step of 1kHz");
31 long tscanio[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
32 MODULE_PARM(tscanio, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
33 MODULE_PARM_DESC(tscanio,"TSCAN CAN controller IO address for each board");
35 #if defined(TS7XXX_IO8_BASE)&&defined(TSXXX_BASE_IO)
36 int tsxxx_base=TS7XXX_IO8_BASE+TSXXX_BASE_IO;
37 #elif defined(TS7XXX_IO8_BASE)
38 int tsxxx_base=TS7XXX_IO8_BASE;
39 #else /*TS7XXX_IO8_BASE*/
40 unsigned long tsxxx_base=0;
41 #endif /*TS7XXX_IO8_BASE*/
42 MODULE_PARM(tsxxx_base, "1i");
43 MODULE_PARM_DESC(tsxxx_base,"The base of the ISA/8-bit IO space for TSxxx CAN peripherals in the system");
45 unsigned short ts7kv_isused = 0x0;
48 * tscan1_request_io: - reserve io or memory range for can board
49 * @candev: pointer to candevice/board which asks for io. Field @io_addr
50 * of @candev is used in most cases to define start of the range
52 * The function tscan1_request_io() is used to reserve the io-memory. If your
53 * hardware uses a dedicated memory range as hardware control registers you
54 * will have to add the code to reserve this memory as well.
55 * %IO_RANGE is the io-memory range that gets reserved, please adjust according
56 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
57 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
58 * Return Value: The function returns zero on success or %-ENODEV on failure
61 int tscan1_request_io(struct candevice_t *candev)
63 unsigned long can_io_addr;
64 unsigned long remap_can_io_addr = 0;
69 if (!can_request_io_region(candev->io_addr, TSXXX_IO_RANGE, "tscan1-base")) {
70 CANMSG("Unable to request base IO port: 0x%lx\n", candev->io_addr);
73 DEBUGMSG("Registered base IO port: 0x%lx - 0x%lx\n",
74 candev->io_addr, candev->io_addr+TSXXX_IO_RANGE-1);
77 can_io_addr = tscanio[candev->candev_idx];
79 if(can_io_addr && (can_io_addr != (unsigned long)-1)) {
80 remap_can_io_addr = tsxxx_base + can_io_addr;
82 if (!can_request_io_region(remap_can_io_addr, TSXXX_CAN_RANGE, "tscan1-can")) {
83 CANMSG("Unable to request CAN IO port: 0x%lx\n", remap_can_io_addr);
84 can_release_io_region(candev->io_addr, TSXXX_IO_RANGE);
87 DEBUGMSG("Registered CAN IO port: 0x%lx - 0x%lx\n",
88 remap_can_io_addr, remap_can_io_addr+TSXXX_CAN_RANGE-1);
94 CANMSG("Unable find range for CAN IO port\n");
95 can_release_io_region(candev->io_addr, TSXXX_IO_RANGE);
99 can_io_addr = 0x100 + i * TSXXX_CAN_RANGE;
100 for (j = 0; j < MAX_HW_CARDS; j++) {
101 if(tscanio[j] == can_io_addr) {
109 remap_can_io_addr = tsxxx_base + can_io_addr;
111 if (can_request_io_region(remap_can_io_addr, TSXXX_CAN_RANGE, "tscan1-can"))
115 tscanio[candev->candev_idx] = can_io_addr;
117 DEBUGMSG("Found free range and registered CAN IO port: 0x%lx - 0x%lx\n",
118 remap_can_io_addr, remap_can_io_addr+TSXXX_CAN_RANGE-1);
121 candev->chip[0]->chip_base_addr = remap_can_io_addr;
122 candev->chip[0]->msgobj[0]->obj_base_addr = remap_can_io_addr;
124 switch(can_io_addr) {
125 case 0x100: mode=0x60; break;
126 case 0x120: mode=0x61; break;
127 case 0x180: mode=0x62; break;
128 case 0x1A0: mode=0x63; break;
129 case 0x200: mode=0x64; break;
130 case 0x240: mode=0x65; break;
131 case 0x280: mode=0x66; break;
132 case 0x320: mode=0x67; break;
133 default: mode=0x60; break;
136 outb(0x00, candev->io_addr+TSCAN1_WIN_REG);
137 outb(mode, candev->io_addr+TSCAN1_MOD_REG);
142 int ts7kv_request_io(struct candevice_t *candev)
144 if (!can_request_io_region(candev->io_addr, TSXXX_CAN_RANGE, "ts7kv-can")) {
145 CANMSG("Unable to request CAN IO port: 0x%lx\n", candev->io_addr);
148 DEBUGMSG("Registered CAN IO port: 0x%lx - 0x%lx\n",
149 candev->io_addr, candev->io_addr+TSXXX_CAN_RANGE-1);
156 * tscan1_release_io - free reserved io memory range
157 * @candev: pointer to candevice/board which releases io
159 * The function tscan1_release_io() is used to free reserved io-memory.
160 * In case you have reserved more io memory, don't forget to free it here.
161 * IO_RANGE is the io-memory range that gets released, please adjust according
162 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
163 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
164 * Return Value: The function always returns zero
167 int tscan1_release_io(struct candevice_t *candev)
169 unsigned long remap_can_io_addr;
172 remap_can_io_addr = candev->chip[0]->chip_base_addr;
173 if(remap_can_io_addr != (unsigned long)-1)
174 can_release_io_region(remap_can_io_addr, TSXXX_CAN_RANGE);
177 outb(0x20, candev->io_addr+TSCAN1_MOD_REG);
179 can_release_io_region(candev->io_addr, TSXXX_IO_RANGE);
183 int ts7kv_release_io(struct candevice_t *candev)
185 can_release_io_region(candev->io_addr, TSXXX_CAN_RANGE);
190 * tscan1_reset - hardware reset routine
191 * @candev: Pointer to candevice/board structure
193 * The function tscan1_reset() is used to give a hardware reset. This is
194 * rather hardware specific so I haven't included example code. Don't forget to
195 * check the reset status of the chip before returning.
196 * Return Value: The function returns zero on success or %-ENODEV on failure
199 int tscan1_reset(struct candevice_t *candev)
201 unsigned short i=0, chipnr;
202 struct canchip_t *chip;
204 DEBUGMSG("Resetting %s hardware ...\n", candev->hwname);
206 for(chipnr=0;chipnr<candev->nr_sja1000_chips;chipnr++) {
207 chip=candev->chip[chipnr];
208 can_write_reg(chip, sjaMOD_RM, SJAMOD);
210 can_write_reg(chip, 0x00, SJAIER);
213 while (can_read_reg(chip, SJAMOD)&sjaMOD_RM){
214 if(!i--) return -ENODEV;
216 can_write_reg(chip, 0, SJAMOD);
219 can_write_reg(chip, sjaCDR_PELICAN, SJACDR);
220 can_write_reg(chip, 0x00, SJAIER);
226 #define RESET_ADDR 0x100
230 int tscan1_check_presence(unsigned long remap_io_addr, int *pjmp)
232 int result = -ENODEV;
234 if (!can_request_io_region(remap_io_addr, TSXXX_IO_RANGE, "tscan1-probe"))
238 if (inb(remap_io_addr+TSXXX_ID0_REG)!=TSCAN1_ID0 ||
239 inb(remap_io_addr+TSXXX_ID1_REG)!=TSCAN1_ID1)
242 outb(0x00, remap_io_addr+TSCAN1_WIN_REG);
243 outb(0x20, remap_io_addr+TSCAN1_MOD_REG);
246 *pjmp = inb(remap_io_addr+TSCAN1_JMP_REG);
251 can_release_io_region(remap_io_addr, TSXXX_IO_RANGE);
258 * tscan1_init_hw_data - Initialize hardware cards
259 * @candev: Pointer to candevice/board structure
261 * The function tscan1_init_hw_data() is used to initialize the hardware
262 * structure containing information about the installed CAN-board.
263 * %RESET_ADDR represents the io-address of the hardware reset register.
264 * %NR_82527 represents the number of intel 82527 chips on the board.
265 * %NR_SJA1000 represents the number of philips sja1000 chips on the board.
266 * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
267 * the hardware uses programmable interrupts.
268 * Return Value: The function always returns zero
272 int tscan1_init_hw_data(struct candevice_t *candev)
275 unsigned long io_addr;
276 unsigned long remap_io_addr;
278 io_addr = candev->io_addr;
280 if(io_addr && (io_addr != (unsigned long)-1)) {
281 remap_io_addr = io_addr = tsxxx_base;
283 if(tscan1_check_presence(remap_io_addr, &jmp)){
284 CANMSG("No TSCAN1 card found at address 0xlx\n");
288 DEBUGMSG("Scanning bus for TS-CAN1 boards...\n");
293 CANMSG("No TS-CAN1 boards found for slot %d\n", candev->candev_idx);
297 io_addr = TSCAN1_BASE_IO + i*TSXXX_IO_RANGE;
298 remap_io_addr = io_addr = tsxxx_base;
300 for (j = 0; j < MAX_HW_CARDS; j++) {
301 if(io[j] == io_addr){
309 if(!tscan1_check_presence(remap_io_addr, &jmp))
313 DEBUGMSG("TS-CAN1 board was found at 0x%lx for driver slot %d\n",
314 io_addr, candev->candev_idx);
316 io[candev->candev_idx] = io_addr;
319 candev->io_addr = remap_io_addr;
320 /* unused reset address is used to store jumper setting */
321 candev->res_addr = jmp;
323 candev->nr_82527_chips=NR_82527;
324 candev->nr_sja1000_chips=NR_SJA1000;
325 candev->nr_all_chips=NR_82527+NR_SJA1000;
326 candev->flags &= ~CANDEV_PROGRAMMABLE_IRQ;
328 DEBUGMSG("Memory region at 0x%lx assigned to sja1000 of driver %d/%s\n",
329 candev->io_addr, candev->candev_idx, candev->hwname);
335 int ts7kv_check_presence(unsigned long remap_io_addr, int *pjmp)
337 int result = -ENODEV;
339 if (!can_request_io_region(remap_io_addr, TSXXX_IO_RANGE, "ts7kv-probe"))
343 if (inb(remap_io_addr+TSXXX_ID0_REG)!=TS7KV_ID0 ||
344 inb(remap_io_addr+TSXXX_ID1_REG)!=TS7KV_ID1)
348 *pjmp = inb(remap_io_addr+TS7KV_JMP_REG);
353 can_release_io_region(remap_io_addr, TSXXX_IO_RANGE);
358 int ts7kv_init_hw_data(struct candevice_t *candev)
361 unsigned long io_addr;
362 unsigned long remap_io_addr;
363 unsigned long can_io_addr;
365 io_addr = candev->io_addr;
367 if(io_addr && (io_addr != (unsigned long)-1)) {
368 remap_io_addr = io_addr = tsxxx_base;
370 if(ts7kv_check_presence(remap_io_addr, &jmp)){
371 CANMSG("No TS7KV card found at address 0xlx\n");
375 DEBUGMSG("Scanning bus for TS7KV boards...\n");
380 CANMSG("No TS7KV boards found for slot %d\n", candev->candev_idx);
384 io_addr = TS7KV_BASE_IO + i*TSXXX_IO_RANGE;
385 remap_io_addr = io_addr = tsxxx_base;
387 for (j = 0; j < MAX_HW_CARDS; j++) {
388 if(io[j] == io_addr){
396 if(!ts7kv_check_presence(remap_io_addr, &jmp))
400 DEBUGMSG("TS7KV board was found at 0x%lx for driver slot %d\n",
401 io_addr, candev->candev_idx);
403 io[candev->candev_idx] = io_addr;
406 can_io_addr = ((io_addr>>3)&0x03)*0x20;
407 tscanio[candev->candev_idx] = can_io_addr;
409 /* dev_base_addr address is used to store remapped PLD base address */
410 candev->dev_base_addr = remap_io_addr;
412 /* dev_base_addr address is used to store remapped slave window address */
413 candev->io_addr = can_io_addr+tsxxx_base;
415 /* unused reset address is used to store jumper setting */
416 candev->res_addr = jmp;
418 candev->nr_82527_chips=NR_82527;
419 candev->nr_sja1000_chips=NR_SJA1000;
420 candev->nr_all_chips=NR_82527+NR_SJA1000;
421 candev->flags &= ~CANDEV_PROGRAMMABLE_IRQ;
423 DEBUGMSG("Memory region at 0x%lx assigned to sja1000 of driver %d/%s\n",
424 candev->io_addr, candev->candev_idx, candev->hwname);
430 * tscan1_init_chip_data - Initialize chips
431 * @candev: Pointer to candevice/board structure
432 * @chipnr: Number of the CAN chip on the hardware card
434 * The function tscan1_init_chip_data() is used to initialize the hardware
435 * structure containing information about the CAN chips.
436 * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
438 * The @chip_base_addr entry represents the start of the 'official' memory map
439 * of the installed chip. It's likely that this is the same as the @io_addr
440 * argument supplied at module loading time.
441 * The @clock entry holds the chip clock value in Hz.
442 * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
443 * register. Options defined in the %sja1000.h file:
444 * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN
445 * The entry @sja_ocr_reg holds hardware specific options for the Output Control
446 * register. Options defined in the %sja1000.h file:
447 * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK,
448 * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ.
449 * The entry @int_clk_reg holds hardware specific options for the Clock Out
450 * register. Options defined in the %i82527.h file:
451 * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
452 * The entry @int_bus_reg holds hardware specific options for the Bus
453 * Configuration register. Options defined in the %i82527.h file:
454 * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
455 * Return Value: The function always returns zero
458 int tscan1_init_chip_data(struct candevice_t *candev, int chipnr)
464 clk = clock[candev->candev_idx];
465 if(!clk || (clk == -1))
470 /* unused reset address is used to store jumper setting */
471 jmp = candev->res_addr;
473 if (jmp&0x10 && jmp&0x20) irq=TSXXX_IRQ5;
474 else if (jmp&0x10) irq=TSXXX_IRQ6;
475 else if (jmp&0x20) irq=TSXXX_IRQ7;
478 CANMSG("Jumpers select no IRQ for TSCAN1 at 0x%lx of driver %d/%s\n",
479 candev->io_addr, candev->candev_idx, candev->hwname);
482 candev->chip[chipnr]->chip_irq = irq;
484 sja1000p_fill_chipspecops(candev->chip[chipnr]);
486 candev->chip[chipnr]->clock = clk;
487 candev->chip[chipnr]->int_clk_reg = 0x0;
488 candev->chip[chipnr]->int_bus_reg = 0x0;
489 candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
490 candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
492 * The address is assigned during tscan1_request_io()
493 * according to found free ranges or tscanio option
495 candev->chip[chipnr]->chip_base_addr = (unsigned long)-1;
500 int ts7kv_init_chip_data(struct candevice_t *candev, int chipnr)
506 clk = clock[candev->candev_idx];
507 if(!clk || (clk == -1))
512 /* unused reset address is used to store jumper setting */
513 jmp = candev->res_addr;
515 if (jmp&0x10 && jmp&0x20) irq=TSXXX_IRQ5;
516 else if (jmp&0x10) irq=TSXXX_IRQ6;
517 else if (jmp&0x20) irq=TSXXX_IRQ7;
520 CANMSG("Jumpers select no IRQ for TS7KV CAN at 0x%lx of driver %d/%s\n",
521 candev->io_addr, candev->candev_idx, candev->hwname);
525 candev->chip[chipnr]->chip_irq = irq;
527 sja1000p_fill_chipspecops(candev->chip[chipnr]);
529 candev->chip[chipnr]->clock = clk;
530 candev->chip[chipnr]->int_clk_reg = 0x0;
531 candev->chip[chipnr]->int_bus_reg = 0x0;
532 candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
533 candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
534 candev->chip[chipnr]->chip_base_addr = candev->io_addr;
540 * tscan1_init_obj_data - Initialize message buffers
541 * @chip: Pointer to chip specific structure
542 * @objnr: Number of the message buffer
544 * The function tscan1_init_obj_data() is used to initialize the hardware
545 * structure containing information about the different message objects on the
546 * CAN chip. In case of the sja1000 there's only one message object but on the
547 * i82527 chip there are 15.
548 * The code below is for a i82527 chip and initializes the object base addresses
549 * The entry @obj_base_addr represents the first memory address of the message
550 * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
552 * Unless the hardware uses a segmented memory map, flags can be set zero.
553 * Return Value: The function always returns zero
556 int tscan1_init_obj_data(struct canchip_t *chip, int objnr)
558 chip->msgobj[objnr]->obj_base_addr = chip->chip_base_addr;
563 * tscan1_program_irq - program interrupts
564 * @candev: Pointer to candevice/board structure
566 * The function tscan1_program_irq() is used for hardware that uses
567 * programmable interrupts. If your hardware doesn't use programmable interrupts
568 * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
569 * leave this function unedited. Again this function is hardware specific so
570 * there's no example code.
571 * Return value: The function returns zero on success or %-ENODEV on failure
574 int tscan1_program_irq(struct candevice_t *candev)
580 * tscan1_write_register - Low level write register routine
581 * @data: data to be written
582 * @address: memory address to write to
584 * The function tscan1_write_register() is used to write to hardware registers
585 * on the CAN chip. You should only have to edit this function if your hardware
586 * uses some specific write process.
587 * Return Value: The function does not return a value
590 void tscan1_write_register(unsigned data, unsigned long address)
595 void ts7kv_write_register(unsigned data, unsigned long address)
597 unsigned long base = address & ~0x1f;
598 unsigned char nwin = 0x10;
599 unsigned char savewin;
601 can_spin_irqflags_t flags;
603 if((address&0x1f) > 0x1d) {
608 can_spin_lock_irqsave(&ts7kv_win_lock,flags);
609 savewin = inb(base+TS7KV_WIN_REG);
610 if(nwin == savewin) {
613 outb(nwin, base+TS7KV_WIN_REG);
615 outb(savewin, base+TS7KV_WIN_REG);
617 can_spin_unlock_irqrestore(&ts7kv_win_lock,flags);
621 * tscan1_read_register - Low level read register routine
622 * @address: memory address to read from
624 * The function tscan1_read_register() is used to read from hardware registers
625 * on the CAN chip. You should only have to edit this function if your hardware
626 * uses some specific read process.
627 * Return Value: The function returns the value stored in @address
630 unsigned tscan1_read_register(unsigned long address)
635 unsigned ts7kv_read_register(unsigned long address)
637 unsigned long base = address & ~0x1f;
638 unsigned char nwin = 0x10;
639 unsigned char savewin;
642 can_spin_irqflags_t flags;
644 if((address&0x1f) > 0x1d) {
649 can_spin_lock_irqsave(&ts7kv_win_lock,flags);
650 savewin = inb(base+TS7KV_WIN_REG);
651 if(nwin == savewin) {
654 outb(nwin, base+TS7KV_WIN_REG);
656 outb(savewin, base+TS7KV_WIN_REG);
658 can_spin_unlock_irqrestore(&ts7kv_win_lock,flags);
663 int tscan1_register(struct hwspecops_t *hwspecops)
665 hwspecops->request_io = tscan1_request_io;
666 hwspecops->release_io = tscan1_release_io;
667 hwspecops->reset = tscan1_reset;
668 hwspecops->init_hw_data = tscan1_init_hw_data;
669 hwspecops->init_chip_data = tscan1_init_chip_data;
670 hwspecops->init_obj_data = tscan1_init_obj_data;
671 hwspecops->write_register = tscan1_write_register;
672 hwspecops->read_register = tscan1_read_register;
673 hwspecops->program_irq = tscan1_program_irq;
677 extern int ts7kv_register(struct hwspecops_t *hwspecops)
679 hwspecops->request_io = ts7kv_request_io;
680 hwspecops->release_io = ts7kv_release_io;
681 hwspecops->reset = tscan1_reset;
682 hwspecops->init_hw_data = ts7kv_init_hw_data;
683 hwspecops->init_chip_data = ts7kv_init_chip_data;
684 hwspecops->init_obj_data = tscan1_init_obj_data;
685 hwspecops->write_register = ts7kv_write_register;
686 hwspecops->read_register = ts7kv_read_register;
687 hwspecops->program_irq = tscan1_program_irq;