X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/8d06c4e166846c170775c086d1565a0e281d6dbc..5f3731f0f3ee5b9b2b7e475a01cca9411ba27415:/lincan/src/tscan1.c diff --git a/lincan/src/tscan1.c b/lincan/src/tscan1.c index 5f7ca7a..c3ff8d1 100644 --- a/lincan/src/tscan1.c +++ b/lincan/src/tscan1.c @@ -13,7 +13,6 @@ #include "../include/can.h" #include "../include/can_sysdep.h" #include "../include/main.h" -#include "../include/pcm3680.h" #include "../include/sja1000p.h" #include @@ -22,30 +21,38 @@ #include "../include/tscan1.h" -static CAN_DEFINE_SPINLOCK(ts7kv_win_lock); - unsigned long tscanio[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1}; unsigned int tscanio_specified; -#if defined(TS7XXX_IO8_BASE)&&defined(TSXXX_BASE_IO) -int tsxxx_base=TS7XXX_IO8_BASE+TSXXX_BASE_IO; -#elif defined(TS7XXX_IO8_BASE) -int tsxxx_base=TS7XXX_IO8_BASE; -#else /*TS7XXX_IO8_BASE*/ +#if defined(TSXXX_BASE_IO) +unsigned long tsxxx_base=TSXXX_BASE_IO; +#else unsigned long tsxxx_base=0; -#endif /*TS7XXX_IO8_BASE*/ +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)) MODULE_PARM(tscanio, "1-" __MODULE_STRING(MAX_HW_CARDS)"i"); MODULE_PARM(tsxxx_base, "1i"); #else /* LINUX_VERSION_CODE >= 2,6,12 */ -module_param_array(tscanio, int, &tscanio_specified, 0); +module_param_array(tscanio, ulong, &tscanio_specified, 0); module_param(tsxxx_base, ulong, 0); #endif /* LINUX_VERSION_CODE >= 2,6,12 */ MODULE_PARM_DESC(tscanio,"TSCAN CAN controller IO address for each board"); MODULE_PARM_DESC(tsxxx_base,"The base of the ISA/8-bit IO space for TSxxx CAN peripherals in the system"); +static unsigned long tscan1_tscanio_ranges[] = + { 0x100, 0x120, 0x180, 0x1A0, 0x200, 0x240, 0x280, 0x320}; + +static inline unsigned tscan1_read_pld_register(struct candevice_t *candev, can_ioptr_t address) +{ + return candev->hwspecops->read_register(address); +} + +static inline void tscan1_write_pld_register(struct candevice_t *candev, unsigned data, can_ioptr_t address) +{ + candev->hwspecops->write_register(data, address); +} /** * tscan1_request_io: - reserve io or memory range for can board @@ -64,42 +71,44 @@ MODULE_PARM_DESC(tsxxx_base,"The base of the ISA/8-bit IO space for TSxxx CAN pe int tscan1_request_io(struct candevice_t *candev) { unsigned long can_io_addr; - unsigned long remap_can_io_addr = 0; + unsigned long rebased_can_io_addr; + can_ioptr_t remap_can_io_addr; + can_ioptr_t remap_pld_io_addr; unsigned char mode; int i, j; - if (!can_request_io_region(candev->io_addr, TSXXX_IO_RANGE, "tscan1-base")) { + if (!can_request_io_region(candev->io_addr, TSCAN1_IO_RANGE, "tscan1-base")) { CANMSG("Unable to request base IO port: 0x%lx\n", candev->io_addr); return -ENODEV; } else { DEBUGMSG("Registered base IO port: 0x%lx - 0x%lx\n", - candev->io_addr, candev->io_addr+TSXXX_IO_RANGE-1); + candev->io_addr, candev->io_addr+TSCAN1_IO_RANGE-1); } can_io_addr = tscanio[candev->candev_idx]; if(can_io_addr && (can_io_addr != (unsigned long)-1)) { - remap_can_io_addr = tsxxx_base + can_io_addr; + rebased_can_io_addr = tsxxx_base + can_io_addr; - if (!can_request_io_region(remap_can_io_addr, TSXXX_CAN_RANGE, "tscan1-can")) { - CANMSG("Unable to request CAN IO port: 0x%lx\n", remap_can_io_addr); - can_release_io_region(candev->io_addr, TSXXX_IO_RANGE); + if (!can_request_io_region(rebased_can_io_addr, TSCAN1_CAN_RANGE, "tscan1-can")) { + CANMSG("Unable to request CAN IO port: 0x%lx\n", rebased_can_io_addr); + can_release_io_region(candev->io_addr, TSCAN1_IO_RANGE); return -ENODEV; } else { DEBUGMSG("Registered CAN IO port: 0x%lx - 0x%lx\n", - remap_can_io_addr, remap_can_io_addr+TSXXX_CAN_RANGE-1); + rebased_can_io_addr, rebased_can_io_addr+TSCAN1_CAN_RANGE-1); } } else { for(i = 0; 1; i++) { if(i>=8) { CANMSG("Unable find range for CAN IO port\n"); - can_release_io_region(candev->io_addr, TSXXX_IO_RANGE); + can_release_io_region(candev->io_addr, TSCAN1_IO_RANGE); return -ENODEV; } - can_io_addr = 0x100 + i * TSXXX_CAN_RANGE; + can_io_addr = tscan1_tscanio_ranges[i]; for (j = 0; j < MAX_HW_CARDS; j++) { if(tscanio[j] == can_io_addr) { j = -1; @@ -109,48 +118,35 @@ int tscan1_request_io(struct candevice_t *candev) if(j<0) continue; - remap_can_io_addr = tsxxx_base + can_io_addr; + rebased_can_io_addr = tsxxx_base + can_io_addr; - if (can_request_io_region(remap_can_io_addr, TSXXX_CAN_RANGE, "tscan1-can")) + if (can_request_io_region(rebased_can_io_addr, TSCAN1_CAN_RANGE, "tscan1-can")) break; } tscanio[candev->candev_idx] = can_io_addr; DEBUGMSG("Found free range and registered CAN IO port: 0x%lx - 0x%lx\n", - remap_can_io_addr, remap_can_io_addr+TSXXX_CAN_RANGE-1); + rebased_can_io_addr, rebased_can_io_addr+TSCAN1_CAN_RANGE-1); } + remap_can_io_addr = can_ulong2ioptr(rebased_can_io_addr); + candev->chip[0]->chip_base_addr = remap_can_io_addr; candev->chip[0]->msgobj[0]->obj_base_addr = remap_can_io_addr; - switch(can_io_addr) { - case 0x100: mode=0x60; break; - case 0x120: mode=0x61; break; - case 0x180: mode=0x62; break; - case 0x1A0: mode=0x63; break; - case 0x200: mode=0x64; break; - case 0x240: mode=0x65; break; - case 0x280: mode=0x66; break; - case 0x320: mode=0x67; break; - default: mode=0x60; break; + mode = 0x60; + for(i = 0; i < 8; i++) { + if (can_io_addr == tscan1_tscanio_ranges[i]) { + mode |= i; + break; + } } - can_outb(0x00, candev->io_addr+TSCAN1_WIN_REG); - can_outb(mode, candev->io_addr+TSCAN1_MOD_REG); - - return 0; -} + remap_pld_io_addr = can_ulong2ioptr(candev->io_addr); -int ts7kv_request_io(struct candevice_t *candev) -{ - if (!can_request_io_region(candev->io_addr, TSXXX_CAN_RANGE, "ts7kv-can")) { - CANMSG("Unable to request CAN IO port: 0x%lx\n", candev->io_addr); - return -ENODEV; - } else { - DEBUGMSG("Registered CAN IO port: 0x%lx - 0x%lx\n", - candev->io_addr, candev->io_addr+TSXXX_CAN_RANGE-1); - } + tscan1_write_pld_register(candev, 0x00, remap_pld_io_addr+TSCAN1_WIN_REG); + tscan1_write_pld_register(candev, mode, remap_pld_io_addr+TSCAN1_MOD_REG); return 0; } @@ -169,23 +165,18 @@ int ts7kv_request_io(struct candevice_t *candev) */ int tscan1_release_io(struct candevice_t *candev) { - unsigned long remap_can_io_addr; + unsigned long rebased_can_io_addr; + can_ioptr_t remap_pld_io_addr = can_ulong2ioptr(candev->io_addr); if(candev->chip[0]){ - remap_can_io_addr = candev->chip[0]->chip_base_addr; - if(remap_can_io_addr != (unsigned long)-1) - can_release_io_region(remap_can_io_addr, TSXXX_CAN_RANGE); + rebased_can_io_addr = candev->chip[0]->chip_base_addr; + if(rebased_can_io_addr != (unsigned long)-1) + can_release_io_region(rebased_can_io_addr, TSCAN1_CAN_RANGE); } - can_outb(0x20, candev->io_addr+TSCAN1_MOD_REG); + tscan1_write_pld_register(candev, 0x20, remap_pld_io_addr+TSCAN1_MOD_REG); - can_release_io_region(candev->io_addr, TSXXX_IO_RANGE); - return 0; -} - -int ts7kv_release_io(struct candevice_t *candev) -{ - can_release_io_region(candev->io_addr, TSXXX_CAN_RANGE); + can_release_io_region(candev->io_addr, TSCAN1_IO_RANGE); return 0; } @@ -230,28 +221,31 @@ int tscan1_reset(struct candevice_t *candev) #define NR_82527 0 #define NR_SJA1000 1 -int tscan1_check_presence(unsigned long remap_io_addr, int *pjmp) +int tscan1_check_presence(struct candevice_t *candev, unsigned long rebased_pld_io_addr, int *pjmp) { + can_ioptr_t remap_pld_io_addr; int result = -ENODEV; - if (!can_request_io_region(remap_io_addr, TSXXX_IO_RANGE, "tscan1-probe")) + if (!can_request_io_region(rebased_pld_io_addr, TSCAN1_IO_RANGE, "tscan1-probe")) return -ENODEV; do { - if (can_inb(remap_io_addr+TSXXX_ID0_REG)!=TSCAN1_ID0 || - can_inb(remap_io_addr+TSXXX_ID1_REG)!=TSCAN1_ID1) + remap_pld_io_addr = can_ulong2ioptr(rebased_pld_io_addr); + + if (tscan1_read_pld_register(candev, remap_pld_io_addr+TSCAN1_ID0_REG)!=TSCAN1_ID0 || + tscan1_read_pld_register(candev, remap_pld_io_addr+TSCAN1_ID1_REG)!=TSCAN1_ID1) break; - can_outb(0x00, remap_io_addr+TSCAN1_WIN_REG); - can_outb(0x20, remap_io_addr+TSCAN1_MOD_REG); + tscan1_write_pld_register(candev, 0x00, remap_pld_io_addr+TSCAN1_WIN_REG); + tscan1_write_pld_register(candev, 0x20, remap_pld_io_addr+TSCAN1_MOD_REG); if(pjmp) - *pjmp = can_inb(remap_io_addr+TSCAN1_JMP_REG); + *pjmp = tscan1_read_pld_register(candev, remap_pld_io_addr+TSCAN1_JMP_REG); result = 0; } while (0); - can_release_io_region(remap_io_addr, TSXXX_IO_RANGE); + can_release_io_region(rebased_pld_io_addr, TSCAN1_IO_RANGE); return result; } @@ -276,16 +270,16 @@ int tscan1_init_hw_data(struct candevice_t *candev) { int i, j, jmp; unsigned long io_addr; - unsigned long remap_io_addr; + unsigned long rebased_pld_io_addr; io_addr = candev->io_addr; if(io_addr && (io_addr != (unsigned long)-1)) { - remap_io_addr = io_addr + tsxxx_base; + rebased_pld_io_addr = io_addr + tsxxx_base; - if(tscan1_check_presence(remap_io_addr, &jmp)){ + if(tscan1_check_presence(candev, rebased_pld_io_addr, &jmp)){ CANMSG("No TSCAN1 card found at address 0x%lx\n", - remap_io_addr); + rebased_pld_io_addr); return -ENODEV; } } else { @@ -298,8 +292,8 @@ int tscan1_init_hw_data(struct candevice_t *candev) return -ENODEV; } - io_addr = TSCAN1_BASE_IO + i*TSXXX_IO_RANGE; - remap_io_addr = io_addr + tsxxx_base; + io_addr = TSCAN1_BASE_IO + i*TSCAN1_IO_RANGE; + rebased_pld_io_addr = io_addr + tsxxx_base; for (j = 0; j < MAX_HW_CARDS; j++) { if(io[j] == io_addr){ @@ -310,7 +304,7 @@ int tscan1_init_hw_data(struct candevice_t *candev) if(j<0) continue; - if(!tscan1_check_presence(remap_io_addr, &jmp)) + if(!tscan1_check_presence(candev, rebased_pld_io_addr, &jmp)) break; } @@ -320,7 +314,7 @@ int tscan1_init_hw_data(struct candevice_t *candev) io[candev->candev_idx] = io_addr; } - candev->io_addr = remap_io_addr; + candev->io_addr = rebased_pld_io_addr; /* unused reset address is used to store jumper setting */ candev->res_addr = jmp; @@ -336,101 +330,6 @@ int tscan1_init_hw_data(struct candevice_t *candev) } -int ts7kv_check_presence(unsigned long remap_io_addr, int *pjmp) -{ - int result = -ENODEV; - - if (!can_request_io_region(remap_io_addr, TSXXX_IO_RANGE, "ts7kv-probe")) - return -ENODEV; - - do { - if (can_inb(remap_io_addr+TSXXX_ID0_REG)!=TS7KV_ID0 || - can_inb(remap_io_addr+TSXXX_ID1_REG)!=TS7KV_ID1) - break; - - if(pjmp) - *pjmp = can_inb(remap_io_addr+TS7KV_JMP_REG); - - result = 0; - } while (0); - - can_release_io_region(remap_io_addr, TSXXX_IO_RANGE); - - return result; -} - -int ts7kv_init_hw_data(struct candevice_t *candev) -{ - int i, j, jmp; - unsigned long io_addr; - unsigned long remap_io_addr; - unsigned long can_io_addr; - - io_addr = candev->io_addr; - - if(io_addr && (io_addr != (unsigned long)-1)) { - remap_io_addr = io_addr + tsxxx_base; - - if(ts7kv_check_presence(remap_io_addr, &jmp)){ - CANMSG("No TS7KV card found at address 0x%lx\n", - remap_io_addr); - return -ENODEV; - } - } else { - DEBUGMSG("Scanning bus for TS7KV boards...\n"); - - for (i=0; 1;i++) - { - if(i >= 4) { - CANMSG("No TS7KV boards found for slot %d\n", candev->candev_idx); - return -ENODEV; - } - - io_addr = TS7KV_BASE_IO + i*TSXXX_IO_RANGE; - remap_io_addr = io_addr + tsxxx_base; - - for (j = 0; j < MAX_HW_CARDS; j++) { - if(io[j] == io_addr){ - j = -1; - break; - } - } - if(j<0) - continue; - - if(!ts7kv_check_presence(remap_io_addr, &jmp)) - break; - - } - DEBUGMSG("TS7KV board was found at 0x%lx for driver slot %d\n", - io_addr, candev->candev_idx); - - io[candev->candev_idx] = io_addr; - } - - can_io_addr = ((io_addr>>3)&0x03)*0x20; - tscanio[candev->candev_idx] = can_io_addr; - - /* dev_base_addr address is used to store remapped PLD base address */ - candev->dev_base_addr = remap_io_addr; - - /* dev_base_addr address is used to store remapped slave window address */ - candev->io_addr = can_io_addr+tsxxx_base; - - /* unused reset address is used to store jumper setting */ - candev->res_addr = jmp; - - candev->nr_82527_chips=NR_82527; - candev->nr_sja1000_chips=NR_SJA1000; - candev->nr_all_chips=NR_82527+NR_SJA1000; - candev->flags &= ~CANDEV_PROGRAMMABLE_IRQ; - - DEBUGMSG("Memory region at 0x%lx assigned to sja1000 of driver %d/%s\n", - candev->io_addr, candev->candev_idx, candev->hwname); - - return 0; -} - /** * tscan1_init_chip_data - Initialize chips * @candev: Pointer to candevice/board structure @@ -497,40 +396,6 @@ int tscan1_init_chip_data(struct candevice_t *candev, int chipnr) return 0; } -int ts7kv_init_chip_data(struct candevice_t *candev, int chipnr) -{ - unsigned long default_clk = 16000 * 1000; - int jmp; - int irq = -1; - - /* unused reset address is used to store jumper setting */ - jmp = candev->res_addr; - - if (jmp&0x10 && jmp&0x20) irq=TSXXX_IRQ5; - else if (jmp&0x10) irq=TSXXX_IRQ6; - else if (jmp&0x20) irq=TSXXX_IRQ7; - - if(irq<0) { - CANMSG("Jumpers select no IRQ for TS7KV CAN at 0x%lx of driver %d/%s\n", - candev->io_addr, candev->candev_idx, candev->hwname); - return -ENODEV; - } - - candev->chip[chipnr]->chip_irq = irq; - - sja1000p_fill_chipspecops(candev->chip[chipnr]); - - if(candev->chip[chipnr]->clock <= 0) - candev->chip[chipnr]->clock = default_clk; - candev->chip[chipnr]->int_clk_reg = 0x0; - candev->chip[chipnr]->int_bus_reg = 0x0; - candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF; - candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH; - candev->chip[chipnr]->chip_base_addr = candev->io_addr; - - return 0; -} - /** * tscan1_init_obj_data - Initialize message buffers * @chip: Pointer to chip specific structure @@ -587,32 +452,12 @@ void tscan1_write_register(unsigned data, can_ioptr_t address) can_outb(data, address); } -void ts7kv_write_register(unsigned data, can_ioptr_t address) +void tscan1mmio_write_register(unsigned data, can_ioptr_t address) { - unsigned long addr=can_ioptr2ulong(address); - can_ioptr_t base = can_ulong2ioptr(addr & ~0x1f); - unsigned char nwin = 0x10; - unsigned char savewin; - - can_spin_irqflags_t flags; - - if((addr&0x1f) > 0x1d) { - nwin++; - address -= 0x10; - } - - can_spin_lock_irqsave(&ts7kv_win_lock,flags); - savewin = can_inb(base+TS7KV_WIN_REG); - if(nwin == savewin) { - can_outb(data, address); - }else{ - can_outb(nwin, base+TS7KV_WIN_REG); - can_outb(data, address); - can_outb(savewin, base+TS7KV_WIN_REG); - } - can_spin_unlock_irqrestore(&ts7kv_win_lock,flags); + can_writeb(data, address); } + /** * tscan1_read_register - Low level read register routine * @address: memory address to read from @@ -628,33 +473,9 @@ unsigned tscan1_read_register(can_ioptr_t address) return can_inb(address); } -unsigned ts7kv_read_register(can_ioptr_t address) +unsigned tscan1mmio_read_register(can_ioptr_t address) { - unsigned long addr=can_ioptr2ulong(address); - can_ioptr_t base = can_ulong2ioptr(addr & ~0x1f); - unsigned char nwin = 0x10; - unsigned char savewin; - unsigned val; - - can_spin_irqflags_t flags; - - if((addr&0x1f) > 0x1d) { - nwin++; - address -= 0x10; - } - - can_spin_lock_irqsave(&ts7kv_win_lock,flags); - savewin = can_inb(base+TS7KV_WIN_REG); - if(nwin == savewin) { - val = can_inb(address); - }else{ - can_outb(nwin, base+TS7KV_WIN_REG); - val = can_inb(address); - can_outb(savewin, base+TS7KV_WIN_REG); - } - can_spin_unlock_irqrestore(&ts7kv_win_lock,flags); - - return val; + return can_readb(address); } int tscan1_register(struct hwspecops_t *hwspecops) @@ -671,16 +492,16 @@ int tscan1_register(struct hwspecops_t *hwspecops) return 0; } -extern int ts7kv_register(struct hwspecops_t *hwspecops) +int tscan1mmio_register(struct hwspecops_t *hwspecops) { - hwspecops->request_io = ts7kv_request_io; - hwspecops->release_io = ts7kv_release_io; + hwspecops->request_io = tscan1_request_io; + hwspecops->release_io = tscan1_release_io; hwspecops->reset = tscan1_reset; - hwspecops->init_hw_data = ts7kv_init_hw_data; - hwspecops->init_chip_data = ts7kv_init_chip_data; + hwspecops->init_hw_data = tscan1_init_hw_data; + hwspecops->init_chip_data = tscan1_init_chip_data; hwspecops->init_obj_data = tscan1_init_obj_data; - hwspecops->write_register = ts7kv_write_register; - hwspecops->read_register = ts7kv_read_register; + hwspecops->write_register = tscan1mmio_write_register; + hwspecops->read_register = tscan1mmio_read_register; hwspecops->program_irq = tscan1_program_irq; return 0; }