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

📄 i2c-tomega8.c

📁 linux下S3C2410的I2C总线的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	if(ps2_hdevent0)		ps2_hdevent0(0, data);}static int mega8_PS20_init (void){	unsigned char data[10];	unsigned char id;	init_waitqueue_head(&(ps2dev0.wq));	ps2dev0.waiting=0;	ps2dev0.ps2device=PS2_DEVICE_NULL;	ps2dev0.ndata=0;	DPRINTK("PS/2 0 initialization...\n");	mega8_device_request (DTYPE_PS2_0);	//reset ps2 device	PS20_SET_WAITING();	mega8_PS20_Send(KBD_RESET);	mega8_PS20_WaitData(&data[0], KBD_TIMEOUT);	mega8_PS20_WaitData(&data[1], KBD_TIMEOUT);	if(data[0]!=KBD_ACK){		printk("no PS/2 device found on PS/2 Port 0!\n");		mega8_device_release (DTYPE_PS2_0);		return -1;	}	if(data[1]!=KBD_BAT){		printk("PS/2 device respond error on PS/2 Port 0!\n");		mega8_device_release (DTYPE_PS2_0);		return -1;	}	DPRINTK("PS/2 device found on PS/2 Port 0!\n");	mdelay(10);	//wait data receive	mega8_PS20_FlushData();	//get ps2 device id	mega8_PS20_Send(KBD_READID);	mega8_PS20_WaitData(&data[0], KBD_TIMEOUT);	mega8_PS20_WaitData(&id, KBD_TIMEOUT);	// maybe keyboard can't respond.	if(id==0xAB){		mega8_PS20_WaitData(&id, KBD_TIMEOUT);		printk("PS/2 keyboard found on PS/2 Port 0.\n");		ps2dev0.ps2device=PS2_DEVICE_KBD;		PS20_CLR_WAITING();		ps2_hdevent0=Ps2_kbd_init_hw(0);	}	else if(id == 0x00){		printk("PS/2 standard mouse found on PS/2 Port 0.\n");		ps2dev0.ps2device=PS2_DEVICE_MOUSE;		PS20_CLR_WAITING();		ps2_hdevent0=Ps2_Mouse_init_hw(0);	}else{		printk("unknown PS/2 device id=0x%x on PS/2 Port 0.\n", id);		mega8_device_release (DTYPE_PS2_0);		return -1;	}	if(ps2_hdevent0==NULL){		printk("PS/2 device init failed on PS/2 Port 0.\n");		mega8_device_release (DTYPE_PS2_0);	}	return 0;}static void mega8_PS20_exit (void){	if(ps2dev0.ps2device==PS2_DEVICE_KBD)		Ps2_kbd_release();	mega8_device_release (DTYPE_PS2_0);}#endif	//#ifdef CONFIG_I2C_MEGA8_PS2_0#ifdef CONFIG_I2C_MEGA8_PS2_1static PS2_DEV ps2dev1;static ps2_handle_event ps2_hdevent1=NULL;#define PS21_SET_WAITING()		ps2dev1.waiting=1#define PS21_CLR_WAITING()		ps2dev1.waiting=0/*********************************************************\	send a data to ps2 device via i2c\*********************************************************/int mega8_PS21_Send(unsigned char data){	int ret;	I2C_control i2c_ctrl;	i2c_ctrl.cmd=CMD_PS2_1;	i2c_ctrl.ctrl=data;	ret=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl));	if(ret<0){		DPRINTK("ps2 1 send  failed!.\n");		return -1;	}	return 0;}#define mega8_PS21_FlushData()		ps2dev1.ndata=0;/*********************************************************\	wait ps2 send back data via i2c\*********************************************************/int mega8_PS21_WaitData(unsigned char *data, long timeout){	if(ps2dev1.ndata==1){		*data=ps2dev1.data;		ps2dev1.ndata=0;		return 0;	}	if(timeout==0){		interruptible_sleep_on(&ps2dev1.wq);		*data=ps2dev1.data;		ps2dev1.ndata=0;		return 0;	}	if(interruptible_sleep_on_timeout(&ps2dev1.wq, timeout)==0){		*data=0;		ps2dev1.ndata=0;		return -1;	}	*data=ps2dev1.data;	ps2dev1.ndata=0;	return 0;}static void mega8_ps2_raw1(unsigned char data){	ps2dev1.ndata=1;	if(ps2dev1.waiting){		ps2dev1.data=data;		wake_up_interruptible(&(ps2dev1.wq));		return;	}#ifdef DEBUG	if(ps2dev1.ps2device==PS2_DEVICE_KBD){		//send data into keyboard		DPRINTK("keyboard receive data=0x%x\n", data);	}	else if(ps2dev1.ps2device==PS2_DEVICE_MOUSE){		DPRINTK("mouse receive data=0x%x\n", data);	}#endif	if(ps2_hdevent1)		ps2_hdevent1(1, data);}static int mega8_PS21_init (void){	unsigned char data[10];	unsigned char id;	init_waitqueue_head(&(ps2dev1.wq));	ps2dev1.waiting=0;	ps2dev1.ps2device=PS2_DEVICE_NULL;	ps2dev1.ndata=0;	DPRINTK("PS/2 1 initialization...\n");	mega8_device_request (DTYPE_PS2_1);	//reset ps2 device	PS21_SET_WAITING();	mega8_PS21_Send(KBD_RESET);	mega8_PS21_WaitData(&data[0], KBD_TIMEOUT);	mega8_PS21_WaitData(&data[1], KBD_TIMEOUT);	if(data[0]!=KBD_ACK){		printk("no PS/2 device found on PS/2 Port 1!\n");		mega8_device_release (DTYPE_PS2_1);		return -1;	}	if(data[1]!=KBD_BAT){		printk("PS/2 device respond error on PS/2 Port 1!\n");		mega8_device_release (DTYPE_PS2_1);		return -1;	}	DPRINTK("PS/2 device found on PS/2 Port 1!\n");	mdelay(10);	//wait data receive	mega8_PS21_FlushData();	//get ps2 device id	mega8_PS21_Send(KBD_READID);	mega8_PS21_WaitData(&data[0], KBD_TIMEOUT);	mega8_PS21_WaitData(&id, KBD_TIMEOUT);	// maybe keyboard can't respond.	if(id==0xAB){		mega8_PS21_WaitData(&id, KBD_TIMEOUT);		printk("PS/2 keyboard found on PS/2 Port 1.\n");		ps2dev1.ps2device=PS2_DEVICE_KBD;		PS21_CLR_WAITING();		ps2_hdevent1=Ps2_kbd_init_hw(1);	}	else if(id == 0x00){		printk("PS/2 standard mouse found on PS/2 Port 1.\n");		ps2dev1.ps2device=PS2_DEVICE_MOUSE;		PS21_CLR_WAITING();		ps2_hdevent1=Ps2_Mouse_init_hw(1);	}else{		printk("unknown PS/2 device id=0x%x on PS/2 Port 1.\n", id);		mega8_device_release (DTYPE_PS2_1);		return -1;	}	if(ps2_hdevent1==NULL){		printk("PS/2 device init failed on PS/2 Port 1.\n");		mega8_device_release (DTYPE_PS2_1);	}	return 0;}static void mega8_PS21_exit (void){	if(ps2dev0.ps2device==PS2_DEVICE_KBD)		Ps2_kbd_release();	mega8_device_release (DTYPE_PS2_1);}#endif	//#ifdef CONFIG_I2C_MEGA8_PS2_0#if defined( CONFIG_I2C_MEGA8_PS2_0) ||defined( CONFIG_I2C_MEGA8_PS2_1)#include "ps2_kbd_mouse.c"#endif/**************************//* Mega8 Keyboard Driver End *//**************************/static int RequestArray[6];static void mega8_device_request (int devtype){	if (devtype < 0 || devtype >= sizeof(RequestArray)/sizeof(int))		return ;	RequestArray[devtype]++;	DPRINTK("device %d request: %d\n", devtype, RequestArray[devtype]);}static void mega8_device_release (int devtype){	if (devtype < 0 || devtype > sizeof(RequestArray)/sizeof(int))		return ;	RequestArray[devtype]--;	if (RequestArray[devtype] < 0)		RequestArray[devtype] = 0;}static int i2c_mega8_initialized;static int i2c_mega8_slvRcv( char *buf, int len, int begin){	static int index = 0;	static I2C_MEGA8_BUFFER frame;	char *p = frame.m_buffer;	if(begin==1)	//the first byte of a i2c frame		index=0;	DPRINTK ("mega8 slv Rcv:%d\n",*buf);	memcpy(p + index, buf, len);	index += len;	DPRINTK ("index:%d\n",index);	if (index >= BUFFER_TYPE_LEN){		switch (GetI2C_Devtype(frame.m_cmd)){			case	DTYPE_SECURITY:				break;#ifdef CONFIG_I2C_MEGA8_MATRIX_KEYBOARD			case	DTYPE_MKEYB:				if (index >= sizeof (frame.m_kbd)){					DPRINTK ("Request kbd:%d\n", RequestArray[DTYPE_MKEYB]);					if (RequestArray[DTYPE_MKEYB]){						mega8_kbd_raw((I2C_kbd * )&frame);					}					index = 0;				}				break;#endif#ifdef CONFIG_I2C_MEGA8_IC_CARD			case	DTYPE_ICCARD:				if((frame.m_cmd==CMD_ICC_FAILED && index >= ICCARD_COUNT_FAILED_OFFSET) ||					(index>ICCARD_COUNT_OFFSET && index >= frame.m_iccard.iccard_cnt+ICCARD_COUNT_OFFSET && frame.m_cmd==CMD_ICC_READ)||					(index>=ICCARD_COUNT_OFFSET && frame.m_cmd==CMD_ICC_WRITE) ||					(index >= ICCARD_COUNT_PWD_OFFSET && frame.m_cmd == CMD_ICC_VERIFY) ||					(index >= ICCARD_COUNT_TYPESEL_OFFSET && frame.m_cmd == CMD_ICC_TYPESEL)){					DPRINTK ("Request ic-card:%d\n", RequestArray[DTYPE_ICCARD]);					if (RequestArray[DTYPE_ICCARD]){						mega8_iccard_raw((I2C_ICCard * )&frame);					}					index = 0;				}				break;#endif#ifdef CONFIG_I2C_MEGA8_PS2_0			case	DTYPE_PS2_0:				if(index >= sizeof(frame.m_ps2)){					DPRINTK ("Request ps2-0:%d\n", RequestArray[DTYPE_PS2_0]);					if (RequestArray[DTYPE_PS2_0]){						mega8_ps2_raw0(frame.m_ps2.ps2data);					}					index = 0;				}				break;#endif#ifdef CONFIG_I2C_MEGA8_PS2_1			case	DTYPE_PS2_1:				if(index >= sizeof(frame.m_ps2)){					DPRINTK ("Request ps2-1:%d\n", RequestArray[DTYPE_PS2_1]);					if (RequestArray[DTYPE_PS2_1]){						mega8_ps2_raw1(frame.m_ps2.ps2data);					}					index = 0;				}				break;#endif			case	DTYPE_ALL:				break;			}	}	return 0;}static int i2c_mega8_attach_adapter(struct i2c_adapter *adap){	int i;	char name[8];	if ((i = i2c_adapter_id(adap)) < 0) {		DPRINTK("Unknown adapter ?!?\n");		return -ENODEV;	}	if (i >= I2CDEV_ADAPS_MAX) {		DPRINTK("Adapter number too large?!? (%d)\n",i);		return -ENODEV;	}	sprintf (name, "%d", i);	if (! i2cdev_adaps[i]) {		i2cdev_adaps[i] = adap;		mega8_client.adapter = adap;		i2c_attach_client(&mega8_client);#ifdef CONFIG_I2C_MEGA8_MATRIX_KEYBOARD		/* init mega8 keyboard */#ifdef CONFIG_DEVFS_FS		mega8_kbd_init (devfs_handle);#else		mega8_kbd_init();#endif#endif //#ifdef CONFIG_I2C_MEGA8_MATRIX_KEYBOARD		/* init mega8 ic card controller */#ifdef CONFIG_I2C_MEGA8_IC_CARD#ifdef CONFIG_DEVFS_FS		mega8_iccard_init (devfs_handle);#else		mega8_iccard_init();#endif#endif //#ifdef CONFIG_I2C_MEGA8_IC_CARD	} else {#ifdef CONFIG_I2C_MEGA8_MATRIX_KEYBOARD		/* exit mega8 keyboard*/		mega8_kbd_exit();#endif#ifdef CONFIG_I2C_MEGA8_IC_CARD		/* exit mega8 ic card controller*/		/* ......*/		mega8_iccard_exit();#endif#ifdef CONFIG_I2C_MEGA8_PS2_0		mega8_PS20_exit();#endif	//#ifdef CONFIG_I2C_MEGA8_PS2_0#ifdef CONFIG_I2C_MEGA8_PS2_1		mega8_PS21_exit();#endif	//#ifdef CONFIG_I2C_MEGA8_PS2_1				i2cdev_adaps[i] = NULL;		DPRINTK ("detach_client\n");		i2c_detach_client (&mega8_client);#ifdef DEBUG		DPRINTK("Adapter unregistered: %s\n",adap->name);#endif	}	return 0;}static int i2c_mega8_detach_client(struct i2c_client *client){	return 0;}static int i2c_mega8_command(struct i2c_client *client, unsigned int cmd,                           void *arg){	return -1;}static int __init i2c_mega8_init(void){	int res;	I2C_control i2c_ctrl;	int mega8_ctrl=0;	DPRINTK(KERN_DEBUG "i2c /dev entries driver module\n");	memset(RequestArray, 0 , sizeof(RequestArray));	i2c_mega8_initialized = 0;#ifdef CONFIG_DEVFS_FS	devfs_handle = devfs_mk_dir(NULL, "mcu", NULL);#endif	i2c_mega8_initialized ++;	if ((res = i2c_add_driver(&i2c_mega8_driver))) {		DPRINTK("Driver registration failed, module not inserted.\n");		i2c_mega8_cleanup();		return res;	}	i2c_mega8_initialized ++;	//set owner i2c address to mega8	i2c_ctrl.cmd=CMD_MST_ADDR;	i2c_ctrl.ctrl=I2COWNER_ADDRESS;	res=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl));	if(res<0){		DPRINTK("set ower address failed!.\n");	}	//set chip ctrl#ifdef CONFIG_I2C_MEGA8_MATRIX_KEYBOARD	mega8_ctrl |= CTRL_MKEn;#endif#ifdef CONFIG_I2C_MEGA8_IC_CARD	mega8_ctrl |= CTRL_ICEn;#endif#ifdef CONFIG_I2C_MEGA8_PS2_0	mega8_ctrl |= CTRL_PS0En;#endif#ifdef CONFIG_I2C_MEGA8_PS2_1	mega8_ctrl |= CTRL_PS1En;#endif	i2c_ctrl.cmd=CMD_CTRL;	i2c_ctrl.ctrl = mega8_ctrl;	res=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl));	if(res<0){		DPRINTK("set chip controller failed!.\n");	}#ifdef CONFIG_I2C_MEGA8_PS2_0	mega8_PS20_init();#endif	//#ifdef CONFIG_I2C_MEGA8_PS2_0#ifdef CONFIG_I2C_MEGA8_PS2_1	mega8_PS21_init();#endif	//#ifdef CONFIG_I2C_MEGA8_PS2_1	return 0;}static void i2c_mega8_cleanup(void){	int res;#if 0	if (i2c_mega8_initialized >= 2) {		if ((res = i2c_del_driver(&i2c_mega8_driver))) {			DPRINTK("Driver deregistration failed, "			       "module not removed.\n");			return;		}		i2c_mega8_initialized --;	}	if (i2c_mega8_initialized >= 1) {		i2c_mega8_initialized --;	}#endif	if ((res = i2c_del_driver(&i2c_mega8_driver))) {		DPRINTK("Driver deregistration failed, "		       "module not removed.\n");		return;	}}EXPORT_NO_SYMBOLS;MODULE_AUTHOR("Richard R.Zhang");MODULE_DESCRIPTION("I2C Mega8 driver");MODULE_LICENSE("GPL");module_init(i2c_mega8_init);module_exit(i2c_mega8_cleanup);

⌨️ 快捷键说明

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