📄 tvp5150a.c
字号:
//read out status i2c_read(0x1F, &status); if (!(status & 0x01)) //not ready for capture: no video source detected return VT_UNKNOWN; else if (status & 0x20) return NTSC; //60Hz => NTSC else return PAL; //50Hz => PAL*/ int ret; i2c_write(0x00,0x00); if((ret=i2c_write(0x03, 0x6D)) <0) printk("i2c write failure!\n"); i2c_write(0x0D,0x47); i2c_write(0x0F,0x02); i2c_write(0x1B,0x14);// i2c_write(0x11,0x04); //AVID start MSB// i2c_write(0x12,0x04); //AVID start LSB /* if((ret=i2c_write(0x03, 0x09)) <0) printk("i2c write failure!\n");*/ printk("i2c write %x\n",ret); return 0;}static int tvp5150a_set_vsrc(int videosrc){ if(videosrc==1) i2c_write(0x00,0x00); else if(videosrc==2) i2c_write(0x00,0x02); return 0;}/** * fill up video paramters */static void tvp5150a_fill_parm(int video_type){ if(video_type == NTSC) { g_tvp5150a_cfg.video_type = NTSC; g_tvp5150a_cfg.width = 720; g_tvp5150a_cfg.f1height = 244; //only first 240 contain valid data g_tvp5150a_cfg.f2height = 243; //only first 240 contain valid data g_tvp5150a_cfg.color_format = YUV; g_tvp5150a_cfg.fps = 30; } else if(video_type == PAL) { g_tvp5150a_cfg.video_type = PAL; g_tvp5150a_cfg.width = 720; g_tvp5150a_cfg.f1height = 288; g_tvp5150a_cfg.f2height = 288; g_tvp5150a_cfg.color_format = YUV; g_tvp5150a_cfg.fps = 25; } else //no video source detected { g_tvp5150a_cfg.video_type = VT_UNKNOWN; }}void tvp5150a_cleanup(void){//let sensor enter power saving mode tvp5150a_hard_reset(); tvp5150a_hard_standby_control(0); return; }#ifdef SAA7113H_PM/** * @brief PM request handler, to save power in sleep mode*/int saa7113h_handle_pm_request(struct pm_dev *dev, pm_request_t rqst, void *data){ switch (rqst) { case PM_SUSPEND: if (g_saa7113h_pm_status != SAA7113H_PMST_SUSPEND) { saa7113h_hard_standby_control(0); } g_saa7113h_pm_status = SAA7113H_PMST_SUSPEND; printk("TVin: SAA7113H suspend.\n"); break; case PM_RESUME: if (g_saa7113h_pm_status != SAA7113H_PMST_RESUME) { if (g_saa7113h_cfg.video_source != -1) saa7113h_init(g_saa7113h_cfg.video_source); } g_saa7113h_pm_status = SAA7113H_PMST_RESUME; printk("TVin: SAA7113H resume.\n"); break; } return 0;}#endif/************************************************************************************************* sensor driver*************************************************************************************************///global staticstatic devfs_handle_t devfs_handle;static int gMajor = 0;//functions and interfacestatic int tvp5150a_open(struct inode *inode, struct file *filp);static int tvp5150a_release(struct inode *inode, struct file *filp);static ssize_t tvp5150a_read(struct file *filp, char *buf, size_t size, loff_t *l);static ssize_t tvp5150a_write(struct file *filp, const char *buf, size_t size, loff_t *l);static int tvp5150a_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);struct file_operations tvp5150a_fops = { open: tvp5150a_open, release: tvp5150a_release, read: tvp5150a_read, write: tvp5150a_write, ioctl: tvp5150a_ioctl,};int __init init_module(){ int result; printk("tvp5150a driver version 0.0\n"__DATE__" / "__TIME__"\n"); //register character device result = devfs_register_chrdev(0, "tvp5150a", &tvp5150a_fops); if ( result < 0 ) { printk("tvp5150a error: Unable to register driver\n"); return -ENODEV; } devfs_handle = devfs_register(NULL, "tvp5150a", DEVFS_FL_DEFAULT, result, 0, S_IFCHR | S_IRUSR | S_IWUSR, &tvp5150a_fops, NULL); gMajor = result; i2c_init(); tvp5150a_hard_standby_control(0); #ifdef SAA7113H_PM g_saa7113h_pm = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, saa7113h_handle_pm_request);#endif return 0;}void __exit cleanup_module(){#ifdef SAA7113H_PM pm_unregister(g_saa7113h_pm);#endif tvp5150a_cleanup(); i2c_cleanup(); if(gMajor > 0) { devfs_unregister_chrdev(gMajor, "tvp5150a"); devfs_unregister(devfs_handle); } printk("tvp5150a unloaded sucessfully\n\n"); return;}static int tvp5150a_open(struct inode *inode, struct file *filp){ MOD_INC_USE_COUNT; return 0;}static int tvp5150a_release(struct inode *inode, struct file *filp){ MOD_DEC_USE_COUNT; return 0; }static ssize_t tvp5150a_read(struct file *filp, char *buf, size_t size, loff_t *l){ printk("tvp5150a: read ioctl not implemented\n"); return -1;}static ssize_t tvp5150a_write(struct file *filp, const char *buf, size_t size, loff_t *l){ printk("tvp5150a: write ioctl not implemented\n"); return -1;}static int tvp5150a_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int ret; switch(cmd) { case TVP5150A_IOC_CONFIG: { int rt;/* if(arg) { if(copy_from_user((void *)&g_tvp5150a_cfg, (void *)arg, sizeof(TVP5150A_CFG))) return -EFAULT; } rt = tvp5150a_init(g_tvp5150a_cfg.video_source); tvp5150a_fill_parm(rt); if(arg) { if(copy_to_user((void *)arg, (void *)&g_tvp5150a_cfg, sizeof(TVP5150A_CFG))) return -EFAULT; }*/ tvp5150a_init(CVBS); break; } case TVP5150A_IOC_I2C_TEST: { tvp5150a_i2c_test(); break; } case TVP5150A_IOC_SELVIDEO : { int videosrc; if(arg) { if(copy_from_user((void *)&videosrc, (void *)arg, sizeof(int))) return -EFAULT; } tvp5150a_set_vsrc(videosrc); break; } case TVP5150A_SET_BRIGHT : { unsigned char bright; if(arg) { if(copy_from_user((unsigned char *)&bright, (void *)arg, sizeof(unsigned char))) return -EFAULT; } i2c_write(0x09,bright); break; } case TVP5150A_SET_SATURATION : { unsigned char saturation; if(arg) { if(copy_from_user((unsigned char *)&saturation, (void *)arg, sizeof(unsigned char))) return -EFAULT; } i2c_write(0x0A,saturation); break; } case TVP5150A_SET_CONTRAST : { unsigned char contrast; if(arg) { if(copy_from_user((unsigned char *)&contrast, (void *)arg, sizeof(unsigned char))) return -EFAULT; } i2c_write(0x0C,contrast); break; } case TVP5150A_SET_HUE: { char hue; if(arg) { if(copy_from_user((char *)&hue, (void *)arg, sizeof(char))) return -EFAULT; } i2c_write(0x0B,hue); break; } case TVP5150A_SET_ACTIVE_DOWN: { char down; if(arg) { if(copy_from_user((char *)&down, (void *)arg, sizeof(char))) return -EFAULT; } i2c_write(0x18,down); break; } case TVP5150A_SET_ACTIVE_TOP: { char top; if(arg) { if(copy_from_user((char *)&top, (void *)arg, sizeof(char))) return -EFAULT; } i2c_write(0x19,top); break; } case TVP5150A_SET_ACTIVE_LEFT: { short left; if(arg) { if(copy_from_user((short *)&left, (void *)arg, sizeof(short))) return -EFAULT; } if(left<0) left+=1024; i2c_write(0x11,left>>2); i2c_write(0x12,left&0x3); break; } case TVP5150A_SET_ACTIVE_RIGHT: { short right; if(arg) { if(copy_from_user((short *)&right, (void *)arg, sizeof(short))) return -EFAULT; } if(right<0) right+=1024; i2c_write(0x13,right>>2); i2c_write(0x14,right&0x3); break; } case TVP5150A_IOC_READ_CONFIG: { if (arg) { unsigned char status; int video_type; /* i2c_read(0x1F, &status); if (!(status & 0x01)) //not ready for capture: no video source detected video_type = VT_UNKNOWN; else if (status & 0x20) video_type = NTSC; //60Hz => NTSC else video_type = PAL; //50Hz => PAL tvp5150a_fill_parm(video_type); */ if((ret=i2c_read(0x03, &status))<0) printk("i2c read error\n"); printk("i2c read %x\n",ret); if (copy_to_user((void *)arg, (void *)&status, sizeof(unsigned char))) return -EFAULT; } break; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -