PCM9880是一块PC/104界面的双端口隔离CAN总线通讯卡

源代码在线查看: template.c

软件大小: 43 K
上传用户: LOOK1980
关键词: 9880 PCM 104 CAN
下载地址: 免注册下载 普通下载 VIP

相关代码

				/* template.c				 * Linux CAN-bus device driver.				 * Written by Arnaud Westenberg email:arnaud@wanadoo.nl				 * This software is released under the GPL-License.				 * Version 0.7  6 Aug 2001				 */ 								/* This file is intended as a template file for currently unsupported hardware.				 * Once you've changed/added the functions specific to your hardware it is				 * possible to load the driver with the hardware option hw=template.				 */								#include 				#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)				#define MODVERSIONS				#endif								#if defined (MODVERSIONS)				#include 				#endif								#include 				#include 				#include 				#include 								#include "../include/main.h"				#include "../include/template.h"				#include "../include/i82527.h"				#include "../include/sja1000.h"								/*				 * IO_RANGE is the io-memory range that gets reserved, please adjust according				 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or				 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.				 */				#define IO_RANGE 0x100								/**				 * template_request_io: - reserve io memory				 * @io_addr: The reserved memory starts at @io_addr, wich is the module 				 * parameter @io.				 *				 * The function template_request_io() is used to reserve the io-memory. If your				 * hardware uses a dedicated memory range as hardware control registers you				 * will have to add the code to reserve this memory as well. 				 * %IO_RANGE is the io-memory range that gets reserved, please adjust according				 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or				 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.				 * Return Value: The function returns zero on success or %-ENODEV on failure				 * File: src/template.c				 */				int template_request_io(unsigned long io_addr)				{					if (check_region(io_addr,IO_RANGE)) {						CANMSG("Unable to open port: 0x%lx\n",io_addr);						return -ENODEV;					}					else {						request_region(io_addr,IO_RANGE,DEVICE_NAME);						DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", io_addr, io_addr + IO_RANGE - 1);					}					return 0;				}								/**				 * template_release_io - free reserved io-memory				 * @io_addr: Start of the memory range to be released.				 *				 * The function template_release_io() is used to free reserved io-memory.				 * In case you have reserved more io memory, don't forget to free it here.				 * IO_RANGE is the io-memory range that gets released, please adjust according				 * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or				 * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.				 * Return Value: The function always returns zero				 * File: src/template.c				 */				int template_release_io(unsigned long io_addr)				{					release_region(io_addr,IO_RANGE);									return 0;				}								/**				 * template_reset - hardware reset routine				 * @card: Number of the hardware card.				 *				 * The function template_reset() is used to give a hardware reset. This is 				 * rather hardware specific so I haven't included example code. Don't forget to 				 * check the reset status of the chip before returning.				 * Return Value: The function returns zero on success or %-ENODEV on failure				 * File: src/template.c				 */				int template_reset(int card)				{					return 0;				}								#define RESET_ADDR 0x0				#define NR_82527 0				#define NR_SJA1000 0								/**				 * template_init_hw_data - Initialze hardware cards				 * @card: Number of the hardware card.				 *				 * The function template_init_hw_data() is used to initialize the hardware				 * structure containing information about the installed CAN-board.				 * %RESET_ADDR represents the io-address of the hardware reset register.				 * %NR_82527 represents the number of intel 82527 chips on the board.				 * %NR_SJA1000 represents the number of philips sja1000 chips on the board.				 * The flags entry can currently only be %PROGRAMMABLE_IRQ to indicate that				 * the hardware uses programmable interrupts.				 * Return Value: The function always returns zero				 * File: src/template.c				 */				int template_init_hw_data(int card) 				{					candevices_p[card]->res_addr=RESET_ADDR;					candevices_p[card]->nr_82527_chips=1;					candevices_p[card]->nr_sja1000_chips=0;					candevices_p[card]->flags |= PROGRAMMABLE_IRQ;									return 0;				}								#define CHIP_TYPE "i82527"				/**				 * template_init_chip_data - Initialize chips				 * @card: Number of the hardware card				 * @chipnr: Number of the CAN chip on the hardware card				 *				 * The function template_init_chip_data() is used to initialize the hardware				 * structure containing information about the CAN chips.				 * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or				 * "sja1000".				 * The @chip_base_addr entry represents the start of the 'official' memory map				 * of the installed chip. It's likely that this is the same as the @io_addr				 * argument supplied at module loading time.				 * The @clock entry holds the chip clock value in Hz.				 * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider				 * register. Options defined in the %sja1000.h file:				 * %CDR_CLKOUT_MASK, %CDR_CLK_OFF, %CDR_RXINPEN, %CDR_CBP, %CDR_PELICAN				 * The entry @sja_ocr_reg holds hardware specific options for the Output Control				 * register. Options defined in the %sja1000.h file:				 * %OCR_MODE_BIPHASE, %OCR_MODE_TEST, %OCR_MODE_NORMAL, %OCR_MODE_CLOCK,				 * %OCR_TX0_LH, %OCR_TX1_ZZ.				 * The entry @int_clk_reg holds hardware specific options for the Clock Out				 * register. Options defined in the %i82527.h file:				 * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.				 * The entry @int_bus_reg holds hardware specific options for the Bus 				 * Configuration register. Options defined in the %i82527.h file:				 * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.				 * The entry @int_cpu_reg holds hardware specific options for the cpu interface				 * register. Options defined in the %i82527.h file:				 * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.				 * Return Value: The function always returns zero				 * File: src/template.c				 */				int template_init_chip_data(int card, int chipnr)				{					candevices_p[card]->chip[chipnr]->chip_type=CHIP_TYPE;					candevices_p[card]->chip[chipnr]->chip_base_addr=candevices_p[card]->io_addr;					candevices_p[card]->chip[chipnr]->clock = 16000000;					candevices_p[card]->chip[chipnr]->int_cpu_reg = iCPU_DSC;					candevices_p[card]->chip[chipnr]->int_clk_reg = iCLK_SL1;					candevices_p[card]->chip[chipnr]->int_bus_reg = iBUS_CBY;					candevices_p[card]->chip[chipnr]->sja_cdr_reg = CDR_CBP | CDR_CLK_OFF;					candevices_p[card]->chip[chipnr]->sja_ocr_reg = OCR_MODE_NORMAL |												OCR_TX0_LH;									return 0;				}								/**				 * template_init_obj_data - Initialize message buffers				 * @chipnr: Number of the CAN chip				 * @objnr: Number of the message buffer				 *				 * The function template_init_obj_data() is used to initialize the hardware				 * structure containing information about the different message objects on the				 * CAN chip. In case of the sja1000 there's only one message object but on the				 * i82527 chip there are 15.				 * The code below is for a i82527 chip and initializes the object base addresses				 * The entry @obj_base_addr represents the first memory address of the message 				 * object. In case of the sja1000 @obj_base_addr is taken the same as the chips				 * base address.				 * Unless the hardware uses a segmented memory map, flags can be set zero.				 * Return Value: The function always returns zero				 * File: src/template.c				 */				int template_init_obj_data(int chipnr, int objnr)				{					chips_p[chipnr]->msgobj[objnr]->obj_base_addr=chips_p[chipnr]->chip_base_addr+(objnr+1)*0x10;					chips_p[chipnr]->msgobj[objnr]->flags=0;										return 0;				}								/**				 * template_program_irq - program interrupts				 * @card: Number of the hardware card.				 *				 * The function template_program_irq() is used for hardware that uses 				 * programmable interrupts. If your hardware doesn't use programmable interrupts				 * you should not set the @candevices_t->flags entry to %PROGRAMMABLE_IRQ and 				 * leave this function unedited. Again this function is hardware specific so 				 * there's no example code.				 * Return value: The function returns zero on success or %-ENODEV on failure				 * File: src/template.c				 */				int template_program_irq(int card)				{					return 0;				}								/**				 * template_write_register - Low level write register routine				 * @data: data to be written				 * @address: memory address to write to				 *				 * The function template_write_register() is used to write to hardware registers				 * on the CAN chip. You should only have to edit this function if your hardware				 * uses some specific write process.				 * Return Value: The function does not return a value				 * File: src/template.c				 */				void template_write_register(unsigned char data, unsigned long address)				{					outb(data,address);				}								/**				 * template_read_register - Low level read register routine				 * @address: memory address to read from				 *				 * The function template_read_register() is used to read from hardware registers				 * on the CAN chip. You should only have to edit this function if your hardware				 * uses some specific read process.				 * Return Value: The function returns the value stored in @address				 * File: src/template.c				 */				unsigned template_read_register(unsigned long address)				{					return inb(address);				}								/* !!! Don't change this function !!! */				int template_register(struct hwspecops_t *hwspecops)				{					hwspecops->request_io = template_request_io;					hwspecops->release_io = template_release_io;					hwspecops->reset = template_reset;					hwspecops->init_hw_data = template_init_hw_data;					hwspecops->init_chip_data = template_init_chip_data;					hwspecops->init_obj_data = template_init_obj_data;					hwspecops->write_register = template_write_register;					hwspecops->read_register = template_read_register;					hwspecops->program_irq = template_program_irq;					return 0;				}							

相关资源