X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/0333697630a0235151e52d239630623b85cd2d9c..a2eb4407e9772cf1057e7ea093250d5d38245c1d:/lincan/src/msmcan.c diff --git a/lincan/src/msmcan.c b/lincan/src/msmcan.c index e9f68f5..9851b5f 100644 --- a/lincan/src/msmcan.c +++ b/lincan/src/msmcan.c @@ -4,7 +4,7 @@ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member * email:pisa@cmp.felk.cvut.cz * This software is released under the GPL-License. - * Version lincan-0.2 9 Jul 2003 + * Version lincan-0.3 17 Jun 2004 */ #include "../include/can.h" @@ -13,7 +13,7 @@ #include "../include/msmcan.h" #include "../include/i82527.h" -static can_spinlock_t msmcan_port_lock=SPIN_LOCK_UNLOCKED; +static CAN_DEFINE_SPINLOCK(msmcan_port_lock); /* IO_RANGE is the io-memory range that gets reserved, please adjust according * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or @@ -56,13 +56,34 @@ int msmcan_release_io(struct candevice_t *candev) */ int msmcan_reset(struct candevice_t *candev) { - struct chip_t *chip=candev->chip[0]; + struct canchip_t *chip=candev->chip[0]; DEBUGMSG("Resetting msmcan hardware ...\n"); /* we don't use template_write_register because we don't use the two first registers of the card but the third in order to make a hard reset */ /* outb (1, msmcan_base + candev->res_addr); */ + + /* terrible MSMCAN reset design - best to comment out */ + if(0) { + int tic=jiffies; + int tac; + + msmcan_write_register(iCTL_INI, chip->chip_base_addr+iCTL); + /*CLKOUT stopped (iCPU_CEN=0) */ + msmcan_write_register(iCPU_DSC, chip->chip_base_addr+iCPU); + while(!(msmcan_read_register(chip->chip_base_addr+iCPU)&iCPU_CEN)){ + tac=jiffies; + if((tac-tic)>HZ*2){ + CANMSG("Unable to reset board\n"); + return -EIO; + } + schedule(); + } + + + } + can_disable_irq(chip->chip_irq); msmcan_write_register(iCTL_INI, chip->chip_base_addr+iCTL); can_enable_irq(chip->chip_irq); @@ -101,16 +122,16 @@ int msmcan_init_hw_data(struct candevice_t *candev) * argument supplied at module loading time. * The clock argument holds the chip clock value in Hz. */ -#define CHIP_TYPE "i82527" int msmcan_init_chip_data(struct candevice_t *candev, int chipnr) { - candev->chip[chipnr]->chip_type=CHIP_TYPE; + i82527_fill_chipspecops(candev->chip[chipnr]); /* device uses indexed access */ candev->chip[chipnr]->chip_base_addr= candev->io_addr << 16; candev->chip[chipnr]->clock = 16000000; - candev->chip[chipnr]->int_cpu_reg = iCPU_DSC; + /* The CLKOUT has to be enabled to reset MSMCAN MAX1232 watchdog */ + candev->chip[chipnr]->int_cpu_reg = iCPU_DSC | iCPU_CEN; candev->chip[chipnr]->int_clk_reg = iCLK_SL1; candev->chip[chipnr]->int_bus_reg = iBUS_CBY; @@ -127,7 +148,7 @@ int msmcan_init_chip_data(struct candevice_t *candev, int chipnr) * base address. * Unless the hardware uses a segmented memory map, flags can be set zero. */ -int msmcan_init_obj_data(struct chip_t *chip, int objnr) +int msmcan_init_obj_data(struct canchip_t *chip, int objnr) { chip->msgobj[objnr]->obj_base_addr= @@ -151,7 +172,7 @@ int msmcan_program_irq(struct candevice_t *candev) * on the CAN chip. You should only have to edit this function if your hardware * uses some specific write process. */ -void msmcan_write_register(unsigned char data, unsigned long address) +void msmcan_write_register(unsigned data, unsigned long address) { /* address is combination of base address shifted left by 16 and index */ can_spin_irqflags_t flags;