⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hms30c7202_can.c

📁 HMS30C7202下的CAN驱动
💻 C
字号:
/* hms30c7202_can.c * * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de * Version 1.0  04 Feb 2003 */#include <linux/delay.h>#include "../include/candrv.h"#include "../include/hms30c7202_can.h"#include "../include/c_can.h"#include "../include/irq.h"/* * IO_RANGE is the io-memory range that gets reserved. */#define IO_RANGE 0x17E/** * hms30c7202_request_io: - reserve io memory * @io_addr: The reserved memory starts at @io_addr, wich is the module * parameter @io. * * * Return Value: The function returns zero on success or %-ENODEV on failure * File: src/hms30c7202_can.c */int hms30c7202_request_io(  struct chip_t *pchip  ){        DEBUGMSG("(c%d)calling hms30c7202_request_io(...)", pchip->chip_nr);        if ( check_mem_region( pchip->base_addr, IO_RANGE )) {                CANMSG(" -> hmsc30c7202_can failed to request mem region %lx.",                        (unsigned long)pchip->base_addr );        }        request_mem_region( pchip->base_addr, IO_RANGE, DEVICE_NAME );        if ( !( pchip->vbase_addr = (u32)ioremap( pchip->base_addr, IO_RANGE ))) {                DEBUGMSG( " -> Failed to map IO-memory: 0x%lx - 0x%lx, mapped to 0x%lx",                         (unsigned long)pchip->base_addr,                         (unsigned long)pchip->base_addr + IO_RANGE - 1,                         (unsigned long)pchip->vbase_addr );                return -ENODEV;        } else {                DEBUGMSG( " -> Mapped IO-memory: 0x%lx - 0x%lx, mapped to 0x%lx",                         (unsigned long)pchip->base_addr,                         (unsigned long)pchip->base_addr + IO_RANGE - 1,                         (unsigned long)pchip->vbase_addr );        }        pchip->start_chip( pchip);        return 0;}/** * hms30c7202_release_io - free reserved io-memory * @io_addr: Start of the memory range to be released. * * * Return Value: The function always returns zero * File: src/hms30c7202_can.c */int hms30c7202_release_io(  struct chip_t *pchip  ){        u16 tempReg;        /* disable IRQ generation */        tempReg = hms30c7202_read_register(pchip, CCCR);        c_can_config_irqs(pchip, 0);        /* power down HMS30c7202 - C_CAN */        pchip->stop_chip( pchip );        /* release I/O memory mapping */        iounmap( (void*)pchip->vbase_addr );        /* Release the memory region */        release_mem_region( pchip->base_addr, IO_RANGE );        return 0;}/** * hms30c7202_reset - hardware reset routine * @card: Number of the hardware card. * * Return Value: The function returns zero on success or %-ENODEV on failure * File: src/hms30c7202_can.c */int hms30c7202_reset(  struct chip_t *pchip  ){        int i=0;        int enableTest=0, disableTest=0;        enableTest = pchip->enable_configuration(pchip);        disableTest = pchip->disable_configuration(pchip);        if( enableTest || disableTest) {                CANMSG("Reset status timeout!");                CANMSG("Please check your hardware.");                return -ENODEV;        }        /* Check busoff status */        while ( (hms30c7202_read_register(pchip, CCSR) & SR_BOFF) && (i<=15)) {                udelay(20000);                i++;        }        if (i>=15) {                CANMSG("Reset status timeout!");                CANMSG("Please check your hardware.");                return -ENODEV;        } else        DEBUGMSG("Chip0 reset status ok.");        // pchip->config_irqs(pchip, CR_MIE | CR_SIE | CR_EIE);        return 0;}#define RESET_ADDR 0x0#define NR_C_CAN 1#define NR_MSGOBJ 32/** * hms30c7202_init_hw_data - Initialze hardware * * Return Value: The function always returns zero * File: src/template.c */int hms30c7202_init_hw_data( struct chip_t *pchip,                             u16 chip_nr,                             u16 startminor,                             u32 baseaddr,                             u8 irq ){//        u32 intCntrVAddr = 0;        u32 gpioVAddr = 0;        u32 tempReg = 0;        u16 i;        /* Map GPIO memory area of the HMS30C7202 */        if ( ! ( gpioVAddr = (u32)ioremap( 0x80023000, 0xAD ) )) {                DEBUGMSG("Failed to map GPIO memory");                return -EIO;        } else {                DEBUGMSG( "Mapped GPIO IO-memory: 0x%lx - 0x%lx to 0x%lx",                         (unsigned long)0X80023000,                         (unsigned long)0X800240AC,                         (unsigned long)gpioVAddr);        }        /* Activate the CAN0 or CAN1 pins of the HMS30C7202 */        if (baseaddr == 0x8002f000) {                tempReg = readl(gpioVAddr + 0x5C);                DEBUGMSG("Read GPIO-C Enable Register : 0x%.4lx\n",(long)tempReg);                DEBUGMSG("Trying to activate CAN0 (Bit 1 = 0 for CANTx0, Bit 2 = 0 for CANRx0,)");                writel(tempReg & ~0x6, gpioVAddr + 0x5C);                tempReg = readl(gpioVAddr + 0x5C);                DEBUGMSG("Read changed GPIO-C Enable Register : 0x%.4lx",(long)tempReg);                tempReg = readl(gpioVAddr + 0x44);                DEBUGMSG("Read GPIO-C Direction Register : 0x%.4lx",(long)tempReg);                DEBUGMSG("Trying to set CAN0 directions (Bit 1 = 0 for CANTx0 as OUT, Bit 2 = 1 for CANRx0 as IN,)");                writel((tempReg & ~0x2) | 0x4, gpioVAddr + 0x44);                tempReg = readl(gpioVAddr + 0x44);                DEBUGMSG("Read changed GPIO-C Direction Register : 0x%.4lx",(long)tempReg);        } else if (baseaddr == 0x80030000) {                tempReg = readl(gpioVAddr + 0x9C);                DEBUGMSG("Read GPIO-E Enable Register : 0x%.8lx\n",(long)tempReg);                DEBUGMSG("Trying to activate CAN1 (Bit 22 = 0 for CANRx1, Bit 23 = 0 for CANTx1,)");                writel(tempReg & 0xFF3FFFFF, gpioVAddr + 0x9C);                tempReg = readl(gpioVAddr + 0x9C);                DEBUGMSG("Read changed GPIO-E Enable Register : 0x%.8lx",(long)tempReg);                tempReg = readl(gpioVAddr + 0x84);                DEBUGMSG("Read GPIO-E Direction Register : 0x%.8lx",(long)tempReg);                DEBUGMSG("Trying to set CAN1 directions (Bit 22 = 1 for CANRx1 as IN, Bit 23 = 0 for CANTx1 as OUT,)");                writel((tempReg & ~(1<<23)) | 1<<22, gpioVAddr + 0x84);                tempReg = readl(gpioVAddr + 0x84);                DEBUGMSG("Read changed GPIO-E Direction Register : 0x%.8lx",(long)tempReg);        }        /* Unmap GPIO memory */        iounmap( (void*)gpioVAddr );        DEBUGMSG( "Unmapped GPIO IO-memory: 0x%lx",                 (unsigned long)gpioVAddr);        /* Initialize chip data ( only one chip ) */        //pcandev->pchip[ 0 ]->powner = pcandev;        pchip->ntype = CAN_CHIPTYPE_C_CAN;        pchip->chip_nr = chip_nr;        pchip->base_addr = baseaddr;        pchip->vbase_addr = 0;        pchip->irq = irq;        pchip->obj_cnt = NR_MSGOBJ;        pchip->active_obj_cnt = 0;        pchip->flags = 0;        pchip->clock = 16000000;        /* Register chip operations */        c_can_register( pchip );        /* Register hardware operations */        pchip->request_io = hms30c7202_request_io;        pchip->release_io = hms30c7202_release_io;        pchip->reset = hms30c7202_reset;        pchip->write_register = hms30c7202_write_register;        pchip->read_register = hms30c7202_read_register;        /* Set IRQ handler */        pchip->irq_handler = c_can_irq_handler;        /* Make rtr_id pointer to a NULL-pointer */        pchip->prtr_queue = NULL;        /* Initialize rtr spinlock */        spin_lock_init( &pchip->rtr_lock );        /* Initialize message objects */        for (i=0; i<pchip->obj_cnt; i++) {                /* Allocate storage for the message object */                pchip->pmsgobj[i] = (struct msgobj_t *)kmalloc( sizeof(struct msgobj_t),                                                                GFP_KERNEL );                if ( pchip->pmsgobj[ i ] == NULL ) {                        return -ENOMEM;                } else {                        if ( add_mem_to_list( pchip->pmsgobj[ i ] )) {                                return -ENOMEM;                        }                }                hms30c7202_init_obj_data(pchip, i, startminor++);        }        return 0;}/** * hms30c7202_init_obj_data - Initialize message object * @chipnr: Number of the CAN chip * @objnr: Number of the message buffer * * Return Value: The function always returns zero */int hms30c7202_init_obj_data(struct chip_t *pchip,                             u16 objnr,                             u16 minor){        DEBUGMSG("(c%d)calling hms30c7202_init_obj_data( ...)", pchip->chip_nr);        pchip->pmsgobj[objnr]->object = objnr;        pchip->pmsgobj[objnr]->minor = minor;        pchip->pmsgobj[objnr]->flags = 0;        pchip->pmsgobj[objnr]->msg_mode = pchip->init_msg_mode;        pchip->pmsgobj[objnr]->hostchip = pchip;        pchip->pmsgobj[objnr]->fifo = NULL;        return 0;}/** * hms30c7202_write_register - Low level write register routine * @data: data to be written * @*pchip: chip which should be accessed * @reg: register to write to * * Return Value: The function does not return a value * File: src/hms30c7202_can.c */void hms30c7202_write_register( u16 data, struct chip_t *pchip, int reg ){        int i;        u32 address = pchip->vbase_addr + reg;        //DEBUGMSG("Trying to write 0x%u16x to address 0x%lx\n",data,address);        writew(data,address);        for (i=0; i<5; i++);}/** * hms30c7202_read_register - Low level read register routine * @reg: register to read from * * Return Value: The function returns the value stored in @address * File: src/hms30c7202.c */u16 hms30c7202_read_register( struct chip_t *pchip, int reg ){        u16 value, i;        u32 address = pchip->vbase_addr + reg;        value = readw(address);        for (i=0;i<5;i++);        value = readw(address);        for (i=0;i<5;i++);        return value;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -