?? i2c-tomega8.c
字號:
case 2: /* SEEK_END */ file->f_pos = iccd->memsize + offset; break; default: return -EINVAL; } if (file->f_pos < 0) file->f_pos = 0; else if (file->f_pos >= iccd->memsize) file->f_pos = iccd->memsize - 1; return file->f_pos;}static ssize_t mega8_iccard_read (struct file *file, char *buf, size_t count, loff_t *offset){ ICCARD_DEV_INFO *iccd= (ICCARD_DEV_INFO*)file->private_data; struct i2c_client *client = &mega8_client; I2C_ICCard buffer; size_t total_retlen=0; int ret=0; int len; if (*offset + count > iccd->memsize) count = iccd->memsize- *offset; while (count) { if (count > MAX_ICCARD_RWBUFFER) len = MAX_ICCARD_RWBUFFER; else len = count; buffer.cmd=CMD_ICC_READ; iccarddev.iccard_data.address = buffer.iccard_addr = *offset; iccarddev.iccard_data.cnt = buffer.iccard_cnt = len; iccarddev.lasterrcode = ICC_FAILED_WAITING; ret = i2c_master_send(client, (const char*)&buffer, ICCARD_COUNT_OFFSET); if(ret<0){ iccarddev.lasterrcode=ICC_FAILED_READERR; break; }retry: if(iccarddev.lasterrcode==ICC_FAILED_WAITING){ interruptible_sleep_on(&(iccarddev.wq)); if (signal_pending(current)) return -ERESTARTSYS; goto retry; } else if(iccarddev.lasterrcode==ICC_FAILED_NULL){ //read successfully *offset += buffer.iccard_cnt; copy_to_user(buf, (char *)iccarddev.iccard_data.buffer, buffer.iccard_cnt); if (copy_to_user(buf, (char *)iccarddev.iccard_data.buffer, buffer.iccard_cnt)) { return -EFAULT; }else{ total_retlen += buffer.iccard_cnt; count -= buffer.iccard_cnt; buf += buffer.iccard_cnt; } } else{ //read error break; } } return total_retlen;}static ssize_t mega8_iccard_write(struct file * file, const char * buf, size_t count, loff_t *offset){ ICCARD_DEV_INFO *iccd= (ICCARD_DEV_INFO*)file->private_data; struct i2c_client *client = &mega8_client; I2C_ICCard buffer; size_t total_retlen=0; int ret=0; int len; if (*offset + count > iccd->memsize) count = iccd->memsize- *offset; while (count) { if (count > MAX_ICCARD_RWBUFFER) len = MAX_ICCARD_RWBUFFER; else len = count; buffer.cmd=CMD_ICC_WRITE; iccarddev.iccard_data.address = buffer.iccard_addr = *offset; iccarddev.iccard_data.cnt = buffer.iccard_cnt = len; iccarddev.lasterrcode = ICC_FAILED_WAITING; if (copy_from_user(buffer.iccard_buf, buf, len)) { return -EFAULT; } ret = i2c_master_send(client, (const char*)&buffer, ICCARD_COUNT_OFFSET + len); if(ret<0){ iccarddev.lasterrcode=ICC_FAILED_READERR; break; }retry: if(iccarddev.lasterrcode==ICC_FAILED_WAITING){ interruptible_sleep_on(&(iccarddev.wq)); if (signal_pending(current)) return -ERESTARTSYS; goto retry; } else if(iccarddev.lasterrcode==ICC_FAILED_NULL){ //write successfully *offset += buffer.iccard_cnt; total_retlen += buffer.iccard_cnt; count -= buffer.iccard_cnt; buf += buffer.iccard_cnt; } else{ //write error break; } } return total_retlen;}static int mega8_iccard_release (struct inode *inode, struct file *file){ mega8_device_release (DTYPE_ICCARD); atomic_inc (&atom_cnt); return 0;}static int iccard_sle4442_read_manufacture_info (unsigned char *buf){ int ret = -1; int count = 32; struct i2c_client *client = &mega8_client;//(struct i2c_client *)file->private_data; I2C_ICCard buffer; while(count!=0){ buffer.cmd=CMD_ICC_READ; iccarddev.iccard_data.address=buffer.iccard_addr=0; iccarddev.iccard_data.cnt=buffer.iccard_cnt=count; iccarddev.lasterrcode=ICC_FAILED_WAITING; ret = i2c_master_send(client, (const char*)&buffer, ICCARD_COUNT_OFFSET); if(ret<0){ iccarddev.lasterrcode=ICC_FAILED_READERR; }retry: if(iccarddev.lasterrcode==ICC_FAILED_WAITING){ interruptible_sleep_on_timeout (&(iccarddev.wq), HZ); if (signal_pending(current)) return -ERESTARTSYS; goto retry; } else if(iccarddev.lasterrcode==ICC_FAILED_NULL){ //read successfully memcpy (buf, (char*)iccarddev.iccard_data.buffer, buffer.iccard_cnt); ret = 0; break; } else{ //read error ret = -1; break; } } return ret;}static int do_verification_sle4442 (unsigned char *password ){ int ret = -1; int count = 3; struct i2c_client *client = &mega8_client;//(struct i2c_client *)file->private_data; I2C_ICCard iccard_verifybuffer; while(count!=0){ iccard_verifybuffer.cmd=CMD_ICC_VERIFY; iccarddev.iccard_data.cnt=iccard_verifybuffer.iccard_pwdcnt=3; memcpy (iccard_verifybuffer.iccard_pwdbuf, password, 3); iccarddev.lasterrcode=ICC_FAILED_WAITING; ret = i2c_master_send(client, (const char*)&iccard_verifybuffer, ICCARD_COUNT_PWD_OFFSET+iccard_verifybuffer.iccard_pwdcnt); if(ret<0){ iccarddev.lasterrcode=ICC_FAILED_VERIFYERR; }retry: if(iccarddev.lasterrcode==ICC_FAILED_WAITING){ interruptible_sleep_on_timeout(&(iccarddev.wq), HZ); DPRINTK ("do verify 4442 retry out\n"); if (signal_pending(current)) return -ERESTARTSYS; goto retry; }else if(iccarddev.lasterrcode == ICC_FAILED_NULL){ //verify successfully DPRINTK ("do verify 4442 success\n"); ret = 0; break; }else{ DPRINTK ("do verify 4442 fail\n"); ret = -1; break; } } return ret;}static int verify_sle4442 (unsigned char *input){ unsigned char manuinfo[32]; unsigned char passwd[3]; /* read manufacture info */#if 0 if (iccard_sle4442_read_manufacture_info (manuinfo)) return -1;#endif /* generate password according to the manufacture info */ /* FIXME: here, we need generate password but not copy first 3 byte to it */ passwd[0]=input[0]; passwd[1]=input[1]; passwd[2]=input[2]; /* verify it */ if (do_verification_sle4442 (passwd)) return -1; /* success */ DPRINTK ("verify sle4442 successfully\n"); return 0;}static int select_card_type ( unsigned char cardtype){ I2C_control i2c_ctrl; int ret; i2c_ctrl.cmd = CMD_ICC_TYPESEL; i2c_ctrl.ctrl = (unsigned char)cardtype; iccarddev.lasterrcode=ICC_FAILED_WAITING; ret = i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl)); if (ret < 0){ DPRINTK("set ic card type failed!.\n"); return ret; } ret = 0;retry: if(iccarddev.lasterrcode==ICC_FAILED_WAITING){ interruptible_sleep_on_timeout (&(iccarddev.wq), HZ); if (signal_pending(current)) return -ERESTARTSYS; goto retry; }else if(iccarddev.lasterrcode!=ICC_FAILED_NULL){ //select error ret = -1; } DPRINTK ("select_card_type return :%d\n", ret); return ret;}static int valid_iccard_dev (unsigned char minor){ int i; for (i = 0; i < DEVNM_SIZE; i ++){ if (minor == iccarddevinfo[i].minor) return i; } return -1;}static int mega8_iccard_open (struct inode *inode, struct file *file){/* if (!mega8_kbd_client->adapter) return -ENODEV; if (mega8_kbd_client->adapter->inc_use) mega8_kbd_client->adapter->inc_use (mega8_kbd_client->adapter);*/ unsigned char dev_minor = MINOR(inode->i_rdev); int cardindex = valid_iccard_dev (dev_minor); DPRINTK ("minor:%d\n", dev_minor); if (!inode || cardindex < 0) return -ENODEV; if (!atomic_dec_and_test (&atom_cnt)){ DPRINTK ("iccard busy\n"); atomic_inc (&atom_cnt); return -EBUSY; } iccarddev.lasterrcode=ICC_FAILED_NULL; init_waitqueue_head(&(iccarddev.wq)); DPRINTK( "iccard opened\n"); mega8_device_request (DTYPE_ICCARD); /*Select Card Type */ if (select_card_type(dev_minor)) goto erropen;#if 0 /* If using sle4442 card, do verification */ if ( dev_minor == ICCARD_TYPE_SLE4442 ){ unsigned char passwd[]={0xab, 0xcd, 0xef}; DPRINTK ("begin verify\n"); if (verify_sle4442(passwd)) goto erropen; }#endif file->private_data = iccarddevinfo + cardindex; return 0;erropen: mega8_device_release (DTYPE_ICCARD); atomic_inc (&atom_cnt); return -ENODEV;}static int mega8_iccard_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ I2C_control i2c_ctrl; int ret; ICCARD_DEV_INFO *iccd= (ICCARD_DEV_INFO*)file->private_data; switch(cmd){ case ICCARD_IOCTL_LASTERR: *((unsigned char*)arg)=iccarddev.lasterrcode; return 0; case ICCARD_IOCTL_SELCARD: return select_card_type((unsigned char)arg); case ICCARD_IOCTL_4442VERIFY: if (iccd->minor != ICCARD_4442_MINOR) return -1; return verify_sle4442((unsigned char*)arg); } return 0;}///ENODEV#ifdef CONFIG_DEVFS_FSstatic void reg_dev_files (devfs_handle_t i2c_root){ int i; for (i = 0; i < DEVNM_SIZE; i ++){ iccard_devfs_handle[i] = devfs_register (i2c_root, iccarddevinfo[i].devname, DEVFS_FL_DEFAULT, iccardmajor, iccarddevinfo[i].minor, S_IFCHR | S_IRUSR | S_IWUSR, &mega8_iccard_fops, NULL); DPRINTK ("Registered '%s' as minor %d\n", iccarddevinfo[i].devname, iccarddevinfo[i].minor); }}#endif#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t mega8_iccard_init (devfs_handle_t i2c_root)#elsestatic int mega8_iccard_init ()#endif{ int ret;// I2C_control i2c_ctrl; ret = register_chrdev(0, ICCARD_NAME, &mega8_iccard_fops); if (ret < 0) { DPRINTK(ICCARD_NAME" can't be registered\n");#ifdef CONFIG_DEVFS_FS return NULL;#else return ret;#endif } iccardmajor = ret;#ifdef CONFIG_DEVFS_FS reg_dev_files (i2c_root);#endif //set default ic-card is AT24C16/* i2c_ctrl.cmd=CMD_ICC_TYPESEL; i2c_ctrl.ctrl=ICCARD_TYPE_AT24C16; ret=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl)); if(ret<0){ DPRINTK("set ic card type failed!.\n"); }*/ atomic_set (&atom_cnt, 1);#ifdef CONFIG_DEVFS_FS return iccard_devfs_handle[0];#else return 0;#endif}static void mega8_iccard_exit (void){ int i;#ifdef CONFIG_DEVFS_FS for ( i = 0; i < DEVNM_SIZE; i++){ if (iccard_devfs_handle[i]){ devfs_unregister(iccard_devfs_handle[i]); iccard_devfs_handle[i] = NULL; } }#endif unregister_chrdev(iccardmajor, ICCARD_NAME);}#endif //#ifdef CONFIG_I2C_MEGA8_IC_CARD/******************I2C_ICCARD*****************/#define PS2_DEVICE_NULL 0#define PS2_DEVICE_KBD 1#define PS2_DEVICE_MOUSE 2typedef struct{ wait_queue_head_t wq; spinlock_t lock; unsigned char data; int waiting; int ps2device; int ndata;}PS2_DEV;#define KBD_BAT 0xaa /* in */#define KBD_SETLEDS 0xed /* out */#define KBD_ECHO 0xee /* in/out */#define KBD_BREAK 0xf0 /* in */#define KBD_TYPRATEDLY 0xf3 /* out */#define KBD_SCANENABLE 0xf4 /* out */#define KBD_DEFDISABLE 0xf5 /* out */#define KBD_DEFAULT 0xf6 /* out */#define KBD_ACK 0xfa /* in */#define KBD_DIAGFAIL 0xfd /* in */#define KBD_RESEND 0xfe /* in/out */#define KBD_RESET 0xff /* out */#define KBD_READID 0xf2 /* out */#define MOUSE_DATAENABLE 0xf4 //out#ifdef CONFIG_I2C_MEGA8_PS2_0static PS2_DEV ps2dev0;static ps2_handle_event ps2_hdevent0=NULL;#define PS20_SET_WAITING() ps2dev0.waiting=1#define PS20_CLR_WAITING() ps2dev0.waiting=0/*********************************************************\ send a data to ps2 device via i2c\*********************************************************/int mega8_PS20_Send(unsigned char data){ int ret; I2C_control i2c_ctrl; i2c_ctrl.cmd=CMD_PS2_0; i2c_ctrl.ctrl=data; ret=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl)); if(ret<0){ DPRINTK("ps2 0 send failed!.\n"); return -1; } return 0;}#define mega8_PS20_FlushData() ps2dev0.ndata=0;/*********************************************************\ wait ps2 send back data via i2c\*********************************************************/int mega8_PS20_WaitData(unsigned char *data, long timeout){ if(ps2dev0.ndata==1){ *data=ps2dev0.data; ps2dev0.ndata=0; // ps2dev0.waiting=0; return 0; } if(timeout==0){ interruptible_sleep_on(&ps2dev0.wq); *data=ps2dev0.data; ps2dev0.ndata=0; return 0; } if(interruptible_sleep_on_timeout(&ps2dev0.wq, timeout)==0){ *data=0; ps2dev0.ndata=0; return -1; } *data=ps2dev0.data; ps2dev0.ndata=0; return 0;}static void mega8_ps2_raw0(unsigned char data){ ps2dev0.ndata=1; if(ps2dev0.waiting){ ps2dev0.data=data; wake_up_interruptible(&(ps2dev0.wq)); return; }#ifdef DEBUG if(ps2dev0.ps2device==PS2_DEVICE_KBD){ //send data into keyboard DPRINTK("keyboard receive data=0x%x\n", data); } else if(ps2dev0.ps2device==PS2_DEVICE_MOUSE){ DPRINTK("mouse receive data=0x%x\n", data); }#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -