?? i2c-tomega8.c
字號(hào):
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);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -