📄 tvp5150.c
字号:
* Composite/S-Video Input** - Accept composite or s-video video from input A11* - Automatic field detection, PAL or NTSC expected* - Standard CCIR656 output enable* - VBI-data slicer disable* - VSYNC & HSYNC out enable* - ITU recommended contrast, brightness & saturation control* - Chrominance processin with nominal BW (800kHz)** @param type TVP5150_INPUT_COMPOSITE Accept composite video* TVP5150_INPUT_SVIDEO Accept s-video video*/static int tvp5150_init(int type){ unsigned char status, status2; //hard reset //tvp5150_reset(); //mdelay(10); //tvp5150_normal_mode(); if (type == CVBS) { printk("CVBS\n"); i2c_tvin_write(0x03, 0x09); //Miscellaneous controls register address, Enables YCbCr output and the clock output } else { printk("SVIDEO\n"); i2c_tvin_write(0x00, 0x01); //analog input control 1 (S-video in) i2c_tvin_write(0x03, 0x0D); //Miscellaneous cnotrols register address, Enables the YCbCr output data, HSYNC, VSYNC/PALI, AVID, and FID/GLCO i2c_tvin_write(0x04, 0xC0); //Autoswitch mask register i2c_tvin_write(0x0D, 0x40); //Outputs and data rates select register } status = 0; status2 = 0; //read out status i2c_tvin_read(0x8C, &status); printk("status(0x8c) = %x\n",status); status >>= 1; status &= 0x07; i2c_tvin_read(0x88, &status2); printk("status2(0x88) = %x\n",status2); switch(status) { case 0x0: printk("NTSC0\n"); return NTSC; //60Hz => NTSC case 0x1: printk("PAL1\n"); return PAL; //50Hz => PAL case 0x2: printk("PAL2\n"); return PAL; case 0x3: printk("PAL3\n"); return PAL; case 0x4: printk("NTSC1\n"); return NTSC; case 0x5: printk("SECAM\n"); return SECAM; default: printk("EINVAL\n"); return -EINVAL; }}/** * fill up video paramters */static void tvp5150_fill_parm(int video_type){ if(video_type == NTSC) { // NTSC: 60Hz, 720x480 g_tvp5150_cfg.video_type = NTSC; g_tvp5150_cfg.width = 720; g_tvp5150_cfg.f1height = 244; //only first 240 contain valid data g_tvp5150_cfg.f2height = 243; //only first 240 contain valid data g_tvp5150_cfg.color_format = YUV; g_tvp5150_cfg.fps = 30; } else if(video_type == PAL) { // PAL: 50Hz, 720x576 g_tvp5150_cfg.video_type = PAL; g_tvp5150_cfg.width = 720; g_tvp5150_cfg.f1height = 288; g_tvp5150_cfg.f2height = 288; g_tvp5150_cfg.color_format = YUV; g_tvp5150_cfg.fps = 25; } else { //no video source detected g_tvp5150_cfg.video_type = VT_UNKNOWN; }}static void tvp5150_cleanup(void){ //let sensor enter power saving mode tvp5150_power_down(); return; }/************************************************************************************************* sensor driver*************************************************************************************************/static int tvp5150_open(struct inode *inode, struct file *filp){ return 0;}static int tvp5150_release(struct inode *inode, struct file *filp){ return 0; }static ssize_t tvp5150_read(struct file *filp, char *buf, size_t size, loff_t *l){ printk("tvp5150: read ioctl not implemented\n"); return -1;}static ssize_t tvp5150_write(struct file *filp, const char *buf, size_t size, loff_t *l){ printk("tvp5150: write ioctl not implemented\n"); return -1;}static int tvp5150_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ unsigned char status, status2; int video_type; int rt; switch(cmd) { case TVP5150_IOC_CONFIG: if(arg) { if(copy_from_user((void *)&g_tvp5150_cfg, (void *)arg, sizeof(TVP5150_CFG))) return -EFAULT; } rt = tvp5150_init(g_tvp5150_cfg.video_source); tvp5150_fill_parm(rt); if(arg) { if(copy_to_user((void *)arg, (void *)&g_tvp5150_cfg, sizeof(TVP5150_CFG))) return -EFAULT; } break; case TVP5150_IOC_I2C_TEST: tvp5150_i2c_test(); break; case TVP5150_IOC_READ_CONFIG: if (arg) { //read out status i2c_tvin_read(0x8C, &status); status >>= 1; status &= 0x07; i2c_tvin_read(0x88, &status2); if (!(status2 & 0x01)) //not ready for capture: no video source detected video_type = VT_UNKNOWN; else { switch (status) { case 0x0: video_type = NTSC; //60Hz => NTSC case 0x1: video_type = PAL; //50Hz => PAL case 0x2: video_type = PAL; case 0x3: video_type = PAL; case 0x4: video_type = NTSC; case 0x5: video_type = SECAM; default: video_type = -1; } } tvp5150_fill_parm(video_type); if (copy_to_user((void *)arg, (void *)&g_tvp5150_cfg, sizeof(TVP5150_CFG))) return -EFAULT; } break; } return 0;}static void tvp5150_interface(sensor_interface * param, u32 width, u32 height){ param->Vsync_pol = 0x0; param->clk_mode = 0x0; //gated param->pixclk_pol = 0x0; param->data_width = 0x1; param->data_pol = 0x0; param->ext_vsync = 0x1; param->Vsync_pol = 0x0; param->Hsync_pol = 0x0; param->width = width - 1; param->height = height - 1; //param->pixel_fmt = IPU_PIX_FMT_UYVY; param->pixel_fmt = PRP_PIXIN_YUYV; param->mclk = 27000000;}static void tvp5150_rate_cal(int *frame_rate, int mclk){ reset_frame_rate = 30;}static void tvp5150_set_color(int bright, int saturation, int red, int green, int blue){ return;}static void tvp5150_get_color(int *bright, int *saturation, int *red, int *green, int *blue){ return;}static void tvp5150_set_ae_mode(int ae_mode){ return;}static void tvp5150_get_ae_mode(int *ae_mode){ return;}sensor_interface *tvp5150_config_csi(int *frame_rate, int high_quality){ u32 out_width, out_height; int rt; out_width = 720; out_height = 288; /*output size */ tvp5150_interface(interface_param, out_width, out_height); set_mclk_rate(&interface_param->mclk); tvp5150_rate_cal(frame_rate, interface_param->mclk); g_tvp5150_cfg.video_source = CVBS; rt = tvp5150_init(g_tvp5150_cfg.video_source); tvp5150_fill_parm(rt); return interface_param;}sensor_interface *tvp5150_config_csi1(int *frame_rate, int high_quality){ u32 out_width, out_height; int rt; out_width = 720; out_height = 288; /*output size */ tvp5150_interface(interface_param, out_width, out_height); set_mclk_rate(&interface_param->mclk); tvp5150_rate_cal(frame_rate, interface_param->mclk); return interface_param;}static sensor_interface *tvp5150_reset_csi(void){ return tvp5150_config_csi1(&reset_frame_rate, 0);}static void tvp5150_set_ae(int active){ return;}static void tvp5150_set_awb(int active){ return;}static void tvp5150_flicker_control(int control){ return;}static void tvp5150_get_control_params(int *ae, int *awb, int *flicker){ return;}static int tvp5150_get_status(void){ int retval = 0; return retval;}struct camera_sensor camera_sensor_if = { .set_color = tvp5150_set_color, .get_color = tvp5150_get_color, .set_ae_mode = tvp5150_set_ae_mode, .get_ae_mode = tvp5150_get_ae_mode, .set_ae = tvp5150_set_ae, .set_awb = tvp5150_set_awb, .flicker_control = tvp5150_flicker_control, .get_control_params = tvp5150_get_control_params, .config = tvp5150_config_csi, .reset = tvp5150_reset_csi, .get_status = tvp5150_get_status,};struct file_operations tvp5150_fops = { owner: THIS_MODULE, open: tvp5150_open, release: tvp5150_release, read: tvp5150_read, write: tvp5150_write, ioctl: tvp5150_ioctl,};static int __init mx21_tvin_init(void){ printk("tvp5150 driver version 0.0\n"); //register character device gMajor = register_chrdev(0, "tvp5150", &tvp5150_fops); if ( gMajor < 0 ) { printk("tvp5150 error: Unable to register driver\n"); return -ENODEV; } printk("/dev/tvin device number is: %d\n", gMajor); i2c_tvin_init(); tvp5150_i2c_test(); return 0;}static void __exit mx21_tvin_exit(void){ tvp5150_cleanup(); i2c_tvin_cleanup(); if(gMajor > 0) unregister_chrdev(gMajor, "tvp5150"); printk("tvp5150 unloaded sucessfully\n\n"); return;}/* Exported symbols for modules. */EXPORT_SYMBOL(camera_sensor_if);module_init(mx21_tvin_init);module_exit(mx21_tvin_exit);MODULE_DESCRIPTION("MX27 TVIN tvp5150 Driver ");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -