📄 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 + -