1 /**************************************************************************/
2 /* File: tscan1.c - support for TS-CAN1 PC104 card from */
3 /* Technologic Systems <http://www.embeddedarm.com/> */
5 /* LinCAN - (Not only) Linux CAN bus driver */
6 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
7 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
8 /* Funded by OCERA and FRESCOR IST projects */
9 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
11 /* LinCAN is free software; you can redistribute it and/or modify it */
12 /* under terms of the GNU General Public License as published by the */
13 /* Free Software Foundation; either version 2, or (at your option) any */
14 /* later version. LinCAN is distributed in the hope that it will be */
15 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
16 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
17 /* General Public License for more details. You should have received a */
18 /* copy of the GNU General Public License along with LinCAN; see file */
19 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
20 /* Cambridge, MA 02139, USA. */
22 /* To allow use of LinCAN in the compact embedded systems firmware */
23 /* and RT-executives (RTEMS for example), main authors agree with next */
24 /* special exception: */
26 /* Including LinCAN header files in a file, instantiating LinCAN generics */
27 /* or templates, or linking other files with LinCAN objects to produce */
28 /* an application image/executable, does not by itself cause the */
29 /* resulting application image/executable to be covered by */
30 /* the GNU General Public License. */
31 /* This exception does not however invalidate any other reasons */
32 /* why the executable file might be covered by the GNU Public License. */
33 /* Publication of enhanced or derived LinCAN files is required although. */
34 /**************************************************************************/
37 #include "../include/can.h"
38 #include "../include/can_sysdep.h"
39 #include "../include/main.h"
40 #include "../include/sja1000p.h"
42 #include <linux/module.h>
43 #include "../include/modparms.h"
44 #include "../include/devcommon.h"
46 #include "../include/tscan1.h"
48 unsigned long tscanio[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
49 unsigned int tscanio_specified;
51 #if defined(TSXXX_BASE_IO)
52 unsigned long tsxxx_base=TSXXX_BASE_IO;
54 unsigned long tsxxx_base=0;
57 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12))
58 MODULE_PARM(tscanio, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
59 MODULE_PARM(tsxxx_base, "1i");
60 #else /* LINUX_VERSION_CODE >= 2,6,12 */
61 module_param_array(tscanio, ulong, &tscanio_specified, 0);
62 module_param(tsxxx_base, ulong, 0);
63 #endif /* LINUX_VERSION_CODE >= 2,6,12 */
65 MODULE_PARM_DESC(tscanio,"TSCAN CAN controller IO address for each board");
66 MODULE_PARM_DESC(tsxxx_base,"The base of the ISA/8-bit IO space for TSxxx CAN peripherals in the system");
68 static unsigned long tscan1_tscanio_ranges[] =
69 { 0x100, 0x120, 0x180, 0x1A0, 0x200, 0x240, 0x280, 0x320};
71 static inline unsigned tscan1_read_pld_register(struct candevice_t *candev, can_ioptr_t address)
73 return candev->hwspecops->read_register(address);
76 static inline void tscan1_write_pld_register(struct candevice_t *candev, unsigned data, can_ioptr_t address)
78 candev->hwspecops->write_register(data, address);
82 * tscan1_request_io: - reserve io or memory range for can board
83 * @candev: pointer to candevice/board which asks for io. Field @io_addr
84 * of @candev is used in most cases to define start of the range
86 * The function tscan1_request_io() is used to reserve the io-memory. If your
87 * hardware uses a dedicated memory range as hardware control registers you
88 * will have to add the code to reserve this memory as well.
89 * %IO_RANGE is the io-memory range that gets reserved, please adjust according
90 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
91 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
92 * Return Value: The function returns zero on success or %-ENODEV on failure
95 int tscan1_request_io(struct candevice_t *candev)
97 unsigned long can_io_addr;
98 unsigned long rebased_can_io_addr;
99 can_ioptr_t remap_can_io_addr;
100 can_ioptr_t remap_pld_io_addr;
105 if (!can_request_io_region(candev->io_addr, TSCAN1_IO_RANGE, "tscan1-base")) {
106 CANMSG("Unable to request base IO port: 0x%lx\n", candev->io_addr);
109 DEBUGMSG("Registered base IO port: 0x%lx - 0x%lx\n",
110 candev->io_addr, candev->io_addr+TSCAN1_IO_RANGE-1);
113 can_io_addr = tscanio[candev->candev_idx];
115 if(can_io_addr && (can_io_addr != (unsigned long)-1)) {
116 rebased_can_io_addr = tsxxx_base + can_io_addr;
118 if (!can_request_io_region(rebased_can_io_addr, TSCAN1_CAN_RANGE, "tscan1-can")) {
119 CANMSG("Unable to request CAN IO port: 0x%lx\n", rebased_can_io_addr);
120 can_release_io_region(candev->io_addr, TSCAN1_IO_RANGE);
123 DEBUGMSG("Registered CAN IO port: 0x%lx - 0x%lx\n",
124 rebased_can_io_addr, rebased_can_io_addr+TSCAN1_CAN_RANGE-1);
130 CANMSG("Unable find range for CAN IO port\n");
131 can_release_io_region(candev->io_addr, TSCAN1_IO_RANGE);
135 can_io_addr = tscan1_tscanio_ranges[i];
136 for (j = 0; j < MAX_HW_CARDS; j++) {
137 if(tscanio[j] == can_io_addr) {
145 rebased_can_io_addr = tsxxx_base + can_io_addr;
147 if (can_request_io_region(rebased_can_io_addr, TSCAN1_CAN_RANGE, "tscan1-can"))
151 tscanio[candev->candev_idx] = can_io_addr;
153 DEBUGMSG("Found free range and registered CAN IO port: 0x%lx - 0x%lx\n",
154 rebased_can_io_addr, rebased_can_io_addr+TSCAN1_CAN_RANGE-1);
157 remap_can_io_addr = can_ulong2ioptr(rebased_can_io_addr);
159 candev->chip[0]->chip_base_addr = remap_can_io_addr;
160 candev->chip[0]->msgobj[0]->obj_base_addr = remap_can_io_addr;
163 for(i = 0; i < 8; i++) {
164 if (can_io_addr == tscan1_tscanio_ranges[i]) {
170 remap_pld_io_addr = can_ulong2ioptr(candev->io_addr);
172 tscan1_write_pld_register(candev, 0x00, remap_pld_io_addr+TSCAN1_WIN_REG);
173 tscan1_write_pld_register(candev, mode, remap_pld_io_addr+TSCAN1_MOD_REG);
179 * tscan1_release_io - free reserved io memory range
180 * @candev: pointer to candevice/board which releases io
182 * The function tscan1_release_io() is used to free reserved io-memory.
183 * In case you have reserved more io memory, don't forget to free it here.
184 * IO_RANGE is the io-memory range that gets released, please adjust according
185 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
186 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
187 * Return Value: The function always returns zero
190 int tscan1_release_io(struct candevice_t *candev)
192 unsigned long rebased_can_io_addr;
193 can_ioptr_t remap_pld_io_addr = can_ulong2ioptr(candev->io_addr);
196 rebased_can_io_addr = candev->chip[0]->chip_base_addr;
197 if(rebased_can_io_addr != (unsigned long)-1)
198 can_release_io_region(rebased_can_io_addr, TSCAN1_CAN_RANGE);
201 tscan1_write_pld_register(candev, 0x20, remap_pld_io_addr+TSCAN1_MOD_REG);
203 can_release_io_region(candev->io_addr, TSCAN1_IO_RANGE);
208 * tscan1_reset - hardware reset routine
209 * @candev: Pointer to candevice/board structure
211 * The function tscan1_reset() is used to give a hardware reset. This is
212 * rather hardware specific so I haven't included example code. Don't forget to
213 * check the reset status of the chip before returning.
214 * Return Value: The function returns zero on success or %-ENODEV on failure
217 int tscan1_reset(struct candevice_t *candev)
219 unsigned short i=0, chipnr;
220 struct canchip_t *chip;
222 DEBUGMSG("Resetting %s hardware ...\n", candev->hwname);
224 for(chipnr=0;chipnr<candev->nr_sja1000_chips;chipnr++) {
225 chip=candev->chip[chipnr];
226 can_write_reg(chip, sjaMOD_RM, SJAMOD);
228 can_write_reg(chip, 0x00, SJAIER);
231 while (can_read_reg(chip, SJAMOD)&sjaMOD_RM){
232 if(!i--) return -ENODEV;
234 can_write_reg(chip, 0, SJAMOD);
237 can_write_reg(chip, sjaCDR_PELICAN, SJACDR);
238 can_write_reg(chip, 0x00, SJAIER);
244 #define RESET_ADDR 0x100
248 int tscan1_check_presence(struct candevice_t *candev, unsigned long rebased_pld_io_addr, int *pjmp)
250 can_ioptr_t remap_pld_io_addr;
251 int result = -ENODEV;
253 if (!can_request_io_region(rebased_pld_io_addr, TSCAN1_IO_RANGE, "tscan1-probe"))
257 remap_pld_io_addr = can_ulong2ioptr(rebased_pld_io_addr);
259 if (tscan1_read_pld_register(candev, remap_pld_io_addr+TSCAN1_ID0_REG)!=TSCAN1_ID0 ||
260 tscan1_read_pld_register(candev, remap_pld_io_addr+TSCAN1_ID1_REG)!=TSCAN1_ID1)
263 tscan1_write_pld_register(candev, 0x00, remap_pld_io_addr+TSCAN1_WIN_REG);
264 tscan1_write_pld_register(candev, 0x20, remap_pld_io_addr+TSCAN1_MOD_REG);
267 *pjmp = tscan1_read_pld_register(candev, remap_pld_io_addr+TSCAN1_JMP_REG);
272 can_release_io_region(rebased_pld_io_addr, TSCAN1_IO_RANGE);
279 * tscan1_init_hw_data - Initialize hardware cards
280 * @candev: Pointer to candevice/board structure
282 * The function tscan1_init_hw_data() is used to initialize the hardware
283 * structure containing information about the installed CAN-board.
284 * %RESET_ADDR represents the io-address of the hardware reset register.
285 * %NR_82527 represents the number of intel 82527 chips on the board.
286 * %NR_SJA1000 represents the number of philips sja1000 chips on the board.
287 * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
288 * the hardware uses programmable interrupts.
289 * Return Value: The function always returns zero
293 int tscan1_init_hw_data(struct candevice_t *candev)
296 unsigned long io_addr;
297 unsigned long rebased_pld_io_addr;
299 io_addr = candev->io_addr;
301 if(io_addr && (io_addr != (unsigned long)-1)) {
302 rebased_pld_io_addr = io_addr + tsxxx_base;
304 if(tscan1_check_presence(candev, rebased_pld_io_addr, &jmp)){
305 CANMSG("No TSCAN1 card found at address 0x%lx\n",
306 rebased_pld_io_addr);
310 DEBUGMSG("Scanning bus for TS-CAN1 boards...\n");
315 CANMSG("No TS-CAN1 boards found for slot %d\n", candev->candev_idx);
319 io_addr = TSCAN1_BASE_IO + i*TSCAN1_IO_RANGE;
320 rebased_pld_io_addr = io_addr + tsxxx_base;
322 for (j = 0; j < MAX_HW_CARDS; j++) {
323 if(io[j] == io_addr){
331 if(!tscan1_check_presence(candev, rebased_pld_io_addr, &jmp))
335 DEBUGMSG("TS-CAN1 board was found at 0x%lx for driver slot %d\n",
336 io_addr, candev->candev_idx);
338 io[candev->candev_idx] = io_addr;
341 candev->io_addr = rebased_pld_io_addr;
342 /* unused reset address is used to store jumper setting */
343 candev->res_addr = jmp;
345 candev->nr_82527_chips=NR_82527;
346 candev->nr_sja1000_chips=NR_SJA1000;
347 candev->nr_all_chips=NR_82527+NR_SJA1000;
348 candev->flags &= ~CANDEV_PROGRAMMABLE_IRQ;
350 DEBUGMSG("Memory region at 0x%lx assigned to sja1000 of driver %d/%s\n",
351 candev->io_addr, candev->candev_idx, candev->hwname);
358 * tscan1_init_chip_data - Initialize chips
359 * @candev: Pointer to candevice/board structure
360 * @chipnr: Number of the CAN chip on the hardware card
362 * The function tscan1_init_chip_data() is used to initialize the hardware
363 * structure containing information about the CAN chips.
364 * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
366 * The @chip_base_addr entry represents the start of the 'official' memory map
367 * of the installed chip. It's likely that this is the same as the @io_addr
368 * argument supplied at module loading time.
369 * The @clock entry holds the chip clock value in Hz.
370 * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
371 * register. Options defined in the %sja1000.h file:
372 * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN
373 * The entry @sja_ocr_reg holds hardware specific options for the Output Control
374 * register. Options defined in the %sja1000.h file:
375 * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK,
376 * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ.
377 * The entry @int_clk_reg holds hardware specific options for the Clock Out
378 * register. Options defined in the %i82527.h file:
379 * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
380 * The entry @int_bus_reg holds hardware specific options for the Bus
381 * Configuration register. Options defined in the %i82527.h file:
382 * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
383 * Return Value: The function always returns zero
386 int tscan1_init_chip_data(struct candevice_t *candev, int chipnr)
388 unsigned long default_clk = 16000 * 1000;
392 /* unused reset address is used to store jumper setting */
393 jmp = candev->res_addr;
395 if (jmp&0x10 && jmp&0x20) irq=TSXXX_IRQ5;
396 else if (jmp&0x10) irq=TSXXX_IRQ6;
397 else if (jmp&0x20) irq=TSXXX_IRQ7;
400 CANMSG("Jumpers select no IRQ for TSCAN1 at 0x%lx of driver %d/%s\n",
401 candev->io_addr, candev->candev_idx, candev->hwname);
404 candev->chip[chipnr]->chip_irq = irq;
406 sja1000p_fill_chipspecops(candev->chip[chipnr]);
408 if(candev->chip[chipnr]->clock <= 0)
409 candev->chip[chipnr]->clock = default_clk;
410 candev->chip[chipnr]->int_clk_reg = 0x0;
411 candev->chip[chipnr]->int_bus_reg = 0x0;
412 candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
413 candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
415 * The address is assigned during tscan1_request_io()
416 * according to found free ranges or tscanio option
418 candev->chip[chipnr]->chip_base_addr = (unsigned long)-1;
424 * tscan1_init_obj_data - Initialize message buffers
425 * @chip: Pointer to chip specific structure
426 * @objnr: Number of the message buffer
428 * The function tscan1_init_obj_data() is used to initialize the hardware
429 * structure containing information about the different message objects on the
430 * CAN chip. In case of the sja1000 there's only one message object but on the
431 * i82527 chip there are 15.
432 * The code below is for a i82527 chip and initializes the object base addresses
433 * The entry @obj_base_addr represents the first memory address of the message
434 * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
436 * Unless the hardware uses a segmented memory map, flags can be set zero.
437 * Return Value: The function always returns zero
440 int tscan1_init_obj_data(struct canchip_t *chip, int objnr)
442 chip->msgobj[objnr]->obj_base_addr = chip->chip_base_addr;
447 * tscan1_program_irq - program interrupts
448 * @candev: Pointer to candevice/board structure
450 * The function tscan1_program_irq() is used for hardware that uses
451 * programmable interrupts. If your hardware doesn't use programmable interrupts
452 * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
453 * leave this function unedited. Again this function is hardware specific so
454 * there's no example code.
455 * Return value: The function returns zero on success or %-ENODEV on failure
458 int tscan1_program_irq(struct candevice_t *candev)
464 * tscan1_write_register - Low level write register routine
465 * @data: data to be written
466 * @address: memory address to write to
468 * The function tscan1_write_register() is used to write to hardware registers
469 * on the CAN chip. You should only have to edit this function if your hardware
470 * uses some specific write process.
471 * Return Value: The function does not return a value
474 void tscan1_write_register(unsigned data, can_ioptr_t address)
476 can_outb(data, address);
479 void tscan1mmio_write_register(unsigned data, can_ioptr_t address)
481 can_writeb(data, address);
486 * tscan1_read_register - Low level read register routine
487 * @address: memory address to read from
489 * The function tscan1_read_register() is used to read from hardware registers
490 * on the CAN chip. You should only have to edit this function if your hardware
491 * uses some specific read process.
492 * Return Value: The function returns the value stored in @address
495 unsigned tscan1_read_register(can_ioptr_t address)
497 return can_inb(address);
500 unsigned tscan1mmio_read_register(can_ioptr_t address)
502 return can_readb(address);
505 int tscan1_register(struct hwspecops_t *hwspecops)
507 hwspecops->request_io = tscan1_request_io;
508 hwspecops->release_io = tscan1_release_io;
509 hwspecops->reset = tscan1_reset;
510 hwspecops->init_hw_data = tscan1_init_hw_data;
511 hwspecops->init_chip_data = tscan1_init_chip_data;
512 hwspecops->init_obj_data = tscan1_init_obj_data;
513 hwspecops->write_register = tscan1_write_register;
514 hwspecops->read_register = tscan1_read_register;
515 hwspecops->program_irq = tscan1_program_irq;
519 int tscan1mmio_register(struct hwspecops_t *hwspecops)
521 hwspecops->request_io = tscan1_request_io;
522 hwspecops->release_io = tscan1_release_io;
523 hwspecops->reset = tscan1_reset;
524 hwspecops->init_hw_data = tscan1_init_hw_data;
525 hwspecops->init_chip_data = tscan1_init_chip_data;
526 hwspecops->init_obj_data = tscan1_init_obj_data;
527 hwspecops->write_register = tscan1mmio_write_register;
528 hwspecops->read_register = tscan1mmio_read_register;
529 hwspecops->program_irq = tscan1_program_irq;