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

📄 k.c

📁 键盘驱动程序Based on xtkbd.c/locomkbd.c
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Keyboard driver for Sharp Corgi models (SL-C7xx) * *  Copyright (c) 2004-2005 Richard Purdie * *  Based on xtkbd.c/locomkbd.c * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation. *1	射频卡数据							R	W2	4442卡数据							R	W3	顾显显示数据						-	W4	矩阵键盘KM62数据					R	-5	PS2键盘数据							R	W6	Cash_drawer							-	W7	磁卡数据							R	-8	FM 收音机							R	W9	E2PROM								R	W跟上层用户程序间:W:	DEV_TYPE	Para1	Para2	Para3	Data	1			1		1		1		***#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/init.h>#include <linux/input.h>#include <linux/irq.h>#include <linux/interrupt.h>#include <linux/jiffies.h>#include <linux/module.h>#include <linux/slab.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/arch/regs-gpio.h> */#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/input.h>#include <linux/platform_device.h>#include <linux/fs.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/list.h>#include <linux/completion.h>#include <linux/interrupt.h>#include <linux/jiffies.h>#include <linux/delay.h>#include <linux/irq.h>#include <asm/uaccess.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/io.h>#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-iic.h>#define PHERIAL_MAJOR	252typedef unsigned char	BYTE;typedef unsigned short	WORD;typedef unsigned long	DWORD;/*#define IIC_TPUR 1000	// 上电到读操作#define IIC_FSCL	1000             #define IIC_TAA		1#define IIC_TBUF	1#define IIC_THD_STA	1#define IIC_TLOW	1#define IIC_THIGH	1#define IIC_TSU_STA	1#define IIC_THD_DAT	0#define IIC_TSU_DAT	1#define IIC_TR		1#define IIC_TF		1#define IIC_TSU_STO	1#define IIC_TDH		1#define IIC_TWR		10000*/#define IIC_TPUR 1000	// 上电到读操作#define IIC_FSCL	400             #define IIC_TAA		1#define IIC_TBUF	1#define IIC_THD_STA	1#define IIC_TLOW	1#define IIC_THIGH	1#define IIC_TSU_STA	1#define IIC_THD_DAT	0#define IIC_TSU_DAT	1#define IIC_TR		1#define IIC_TF		1#define IIC_TSU_STO	1#define IIC_TDH		1#define IIC_TWR		10000///////////////// 器件寻址控制字#define IIC_ADDR_EEPROM 0xA0	// CAT24C02#define IIC_ADDR_RADIO  0xC0	// FM RADIO#define IIC_ADDR_NEC    0x60	// NEC 单片机#define IIC_CTL_BYTE_W	0	#define IIC_CTL_BYTE_R	1#define IIC_PAGE_SIZE	16	// 写的时候,一页的大小#define IIC_MAX_ERROR	10	// 最多允许出错次数#define iic_debug	1#define dpk_iic(msg...)	if (iic_debug) { printk( " s3c2410-iic: " msg); }#define SCL(x) s3c2410_gpio_setpin(S3C2410_GPE14,x)#define SDA(x) s3c2410_gpio_setpin(S3C2410_GPE15,x)#define OUTP_SCL s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_OUTP)#define OUTP_SDA s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_OUTP)#define INP_SCL s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_INP)#define INP_SDA s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_INP)#define	DEV_RF		1#define	DEV_4442	2#define	DEV_DSP		3#define	DEV_KM62	4#define	DEV_PS2		5#define	DEV_CASH	6#define	DEV_MAG		7#define	DEV_FM		8#define	DEV_E2PROM	9#define	CASH_PORT	S3C2410_GPB9static int	CASH_MS = 200;	//开钱箱通电保持几毫秒static int OPERATING_PHERIAL = DEV_RF;			//当前操作的设备static char fm_rx[5];//static char fm_tx[5]={0x2b,0xe1,0x10,0x16,0};	//99.6Mhz -> PLL=0x2f99, 96.8Mhz -> PLL=0x2e43 ,91.8Mhz -> PLL=0x2be1static char fm_tx[5]={0x2b,0xe1,0x10,0x16,0};	//99.6Mhz -> PLL=0x2f99, 96.8Mhz -> PLL=0x2e43 ,91.8Mhz -> PLL=0x2be1static char dsp_digi_data[10]={0x3f,6,0x5b,0x4f,0x66,0x5d,0x7d,7,0x7f,0x6f};		//数码管数字0-9段位的值static char dsp_tx[9] = {03,06,0,0,0,0x80,0,0,0};									//0x80是第4位的小数点值static unsigned char km62kbd_keycode[64] = {	0x1e,0x17,0x10,0x2f,KEY_DELETE,0x0b,0x1c,0x00,	0x30,0x24,0x13,0x11,KEY_KPPLUS,0x0b,0x1c,0x00,	0x2e,0x25,0x1f,0x2d,0x34,0x42,0x00,0x3f,	0x20,0x26,0x14,0x15,0x04,0x07,0x0a,0x3e,	0x12,0x32,0x16,0x2c,0x03,0x06,0x09,0x3d,	0x21,0x31,KEY_PAGEUP,KEY_LEFT,0x02,0x05,0x08,0x3c,	0x22,0x18,KEY_UP,KEY_DOWN,KEY_MINUS,0x37,KEY_SLASH,0x3b,	0x23,0x19,KEY_PAGEDOWN,KEY_RIGHT,0x0e,0x39,0x0f,0x01};struct km62kbd {	unsigned char keycode[ARRAY_SIZE(km62kbd_keycode)];	struct input_dev *input;	spinlock_t lock;	struct timer_list timer;	unsigned int suspended;	unsigned long suspend_jiffies;};struct km62kbd *km62kbd;// 发送开始信号void IICStart(){	dpk_iic("IICStart\n");	//////////////////	// 函数的功能:给出如下时序	// SCL __--------_	// SDA x-----_____	// 并且SDA需要一定的建立和保持时间	// 首先要置SCL为0,否则当SCL置为1,此时如果SDA为0,则必须	// 在SCL为1时给出SDA的下跳沿,这就成了STOP信号	OUTP_SDA;		SCL(0);	SDA(1);	SCL(1);	// tSU: STA 起始信号建立时间,有一个最小值。需要一定的建立时间。	udelay(IIC_TSU_STA);	// 给出下跳沿	SDA(0);	// Thd:sta起始信号保持时间,有个最小值。起始信号不能太快。	udelay(IIC_THD_STA);	// 结束	SCL(0);}// 发送停止信号void IICStop(){	dpk_iic("IICStop\n");	//////////////////	// 函数的功能:给出如下时序	// SCL __--------_	// SDA x_____-----	// 需要一定的建立时间,之后就是总线空闲时间。	OUTP_SDA;	SCL(0);	SDA(0);	SCL(1);	// tSU: STO 停止信号建立时间。有最小时间。不能太快。	udelay(IIC_TSU_STO);	// 给出上升沿	SDA(1);	// 文档上没说多少保持时间,这里定为tSU: STO	udelay(IIC_TSU_STO);	// 结束//	SCL(0);	SCL(1);}// 向IIC发送一个字节void IICSendByte(BYTE value){	BYTE count;	dpk_iic("IICSendByte: 0x%x\n",value);	OUTP_SDA;	// 从高位开始发	for(count = 8; count > 0; count--,value <<= 1)	{		//写bit:在SCL低电平时置SDA,等待Tsu:DAT时间,然后		//是SCL高电平,SCL低电平之后需要SDA保持THD:DAT时间。		SCL(0);		udelay(IIC_THD_DAT);		if(value & 0x80)			SDA(1);		else			SDA(0);		udelay(IIC_TSU_DAT);		udelay(IIC_TLOW);	// SCL的低电平至少保持这么长时间		SCL(1);		udelay(IIC_THIGH);	// SCL的高电平至少保持这么长时间	}	SCL(0);}// 从IIC接受一个字节unsigned char IICRecvByte(){	BYTE count;	BYTE value;	dpk_iic("IICRecvByte :");	// 从高位开始接收	OUTP_SDA;	SDA(1);	// 在读取SDA的电平时先要置其为1	udelay(1);	INP_SDA;	for(count = 8,value = 0; count > 0; count--)	{		value <<= 1;		// 读bit:SCL低电平以后在规定的时间TAA内数据在SDA上出现		// ,然后置SCL高,读取这个bit,然后置为低,数据还会保持		// TDH时间。		SCL(0);		udelay(IIC_TAA);		udelay(IIC_TLOW);	// SCL的低电平至少保持这么长时间		SCL(1);//printk(" %x ",s3c2410_gpio_getpin(S3C2410_GPE15) >> 15);		if (s3c2410_gpio_getpin(S3C2410_GPE15) >> 15)		{			value |= 1;		}		udelay(IIC_THIGH);	// SCL的高电平至少保持这么长时间	}	SCL(0);	dpk_iic("  0x%x\n",value);	return value;}// 是否可以接收到一个应答信号unsigned char IICHasRecvAck(){	BYTE RetValue = 0;	dpk_iic("IICHasRecvAck?");	OUTP_SDA;	SDA(1);	// 在读取SDA的电平时先要置其为1	// 读bit:SCL低电平以后在规定的时间TAA内数据在SDA上出现	// ,然后置SCL高,读取这个bit,然后置为低,数据还会保持	// TDH时间。	SCL(0);	udelay(IIC_TAA);	udelay(IIC_TLOW);	// SCL的低电平至少保持这么长时间	SCL(1);	INP_SDA;	RetValue = s3c2410_gpio_getpin(S3C2410_GPE15) >> 15;	udelay(IIC_THIGH);	// SCL的高电平至少保持这么长时间	SCL(0);	if(RetValue == 0)	{		printk(" - Y \n");		return 1;	}	else	{		printk(" - N \n");		return 0;	}}// 发送一个应答信号给IICvoid IICSendAck(){	dpk_iic("IICSendAck\n");	//写bit:在SCL低电平时置SDA,等待Tsu:DAT时间,然后	//是SCL高电平,SCL低电平之后需要SDA保持THD:DAT时间。	OUTP_SDA;	SCL(0);	udelay(IIC_THD_DAT);	SDA(0);	udelay(IIC_TSU_DAT);	udelay(IIC_TLOW);	// SCL的低电平至少保持这么长时间	SCL(1);	udelay(IIC_THIGH);	// SCL的高电平至少保持这么长时间	SCL(0);}// 不发送应答信号,但是给出一个时钟void IICSendNoAck(){	dpk_iic("IICSendNoAck\n");	//写bit:在SCL低电平时置SDA,等待Tsu:DAT时间,然后	//是SCL高电平,SCL低电平之后需要SDA保持THD:DAT时间。	SCL(0);	udelay(IIC_THD_DAT);	OUTP_SDA;	SDA(1);	udelay(IIC_TSU_DAT);	udelay(IIC_TLOW);	// SCL的低电平至少保持这么长时间	SCL(1);	udelay(IIC_THIGH);	// SCL的高电平至少保持这么长时间	SCL(0);}// 检测IIC是否擦写完毕。// 在擦写过程中IIC不会相应总线。当IIC响应总线以后说明擦写完毕unsigned char IICCompleteBuf(BYTE SlaveAddr){	dpk_iic("IICCompleteBuf?\n\n");	IICStart();	IICSendByte(SlaveAddr | IIC_CTL_BYTE_W);	return IICHasRecvAck();}/////////////////// 初始化函数// 上电以后需要等待TPURvoid IICInitial(){	udelay(IIC_TPUR);}//EEPROM写一个字节unsigned char IICWRITE_EEPROM_BYTE(BYTE * buf,BYTE addr){	dpk_iic("IICWRITE_EEPROM\n");	// 给一个起始信号	IICStart();	// 发送控制字	// 发送从器件地址,高5位为10100,然后是A2,A1,A0(如果和器	// 件的地址相同则那个器件会应答),读写控制(0为读)。	IICSendByte(IIC_ADDR_EEPROM | IIC_CTL_BYTE_W);	// 器件是否应答	if(IICHasRecvAck())	{					IICSendByte((BYTE)addr);		// 应答		if(IICHasRecvAck())		{			IICSendByte(*buf);			// 应答,如果没有应答则退出			if(!IICHasRecvAck())				return 0;			// 停止			IICStop();			// 等待写完毕			while(!IICCompleteBuf(IIC_ADDR_EEPROM));		}	}	return 1;}//EEPROM写一个字符串unsigned char IICWRITE_EEPROM_STR(BYTE * buf,BYTE addr,BYTE count){	int i;	dpk_iic("IICWRITE_EEPROM_STR\n");	if (addr > 255)		return 0;	if (count > 255)		return 0;	if ((addr + count) > 255)		count = 256 - addr;	for(i=0;i<count;i++)	{		if ( IICWRITE_EEPROM_BYTE(buf,addr + i) == 0 )			return 0;		buf ++;	}	return 1;}//EEPROM读一个字节unsigned char IICREAD_EEPROM_BYTE(BYTE * buf,BYTE addr){	dpk_iic("IICREAD_EEPROM\n");	/////////////////////	// 器件寻址				// 给一个起始信号	IICStart();	// 发送控制字	// 发送从器件地址,高5位为10100,然后是A2,A1,A0(如果和器	// 件的地址相同则那个器件会应答),读写控制(0为读)。	IICSendByte(IIC_ADDR_EEPROM | IIC_CTL_BYTE_W);	// 器件是否应答	if(IICHasRecvAck())	{					IICSendByte((BYTE)addr);		// 应答		if(IICHasRecvAck())		{			// 发送Start			IICStart();			// 器件选择			IICSendByte(IIC_ADDR_EEPROM | IIC_CTL_BYTE_R);						// 接收			if(IICHasRecvAck())			{				*buf = IICRecvByte();				IICSendNoAck();				IICStop();			}		}	}		return 1;}//EEPROM读一个字符串unsigned char IICREAD_EEPROM_STR(BYTE * buf,BYTE addr,BYTE count){	BYTE i;	dpk_iic("IICREAD_EEPROM STRING\n");	/////////////////////	// 器件寻址				// 给一个起始信号	IICStart();	// 发送控制字	// 发送从器件地址,高5位为10100,然后是A2,A1,A0(如果和器	// 件的地址相同则那个器件会应答),读写控制(0为读)。	IICSendByte(IIC_ADDR_EEPROM | IIC_CTL_BYTE_W);	// 器件是否应答	if(IICHasRecvAck())	{					IICSendByte((BYTE)addr);		// 应答		if(IICHasRecvAck())		{			// 发送Start			IICStart();			// 器件选择			IICSendByte(IIC_ADDR_EEPROM | IIC_CTL_BYTE_R);						// 接收			if(IICHasRecvAck())			{				for (i=0;i<count;i++)				{					*buf = IICRecvByte();					IICSendAck();					buf++;				}				IICSendNoAck();				IICStop();			}		}	}		return 1;}//写FM五个字节unsigned char IICWRITE_FM(void){	int i;	dpk_iic("IICWRITE_FM\n");	// 给一个起始信号	IICStart();	IICSendByte(IIC_ADDR_RADIO | IIC_CTL_BYTE_W);	// 器件是否应答	if(IICHasRecvAck())	{			//		IICSendByte(IIC_ADDR_RADIO);		// 应答//		if(IICHasRecvAck())		{			for(i=0;i<5;i++)			{				IICSendByte(fm_tx[i]);				// 应答,如果没有应答则退出				if(!IICHasRecvAck())					return 0;			}			// 停止

⌨️ 快捷键说明

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