diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c index 3dd28f2201f..ed92b4b4123 100644 --- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c @@ -162,7 +162,6 @@ static video_fmt_idx video_index = TV_NOT_LOCKED; static int mxc_v4l2_master_attach(struct v4l2_int_device *slave); static void mxc_v4l2_master_detach(struct v4l2_int_device *slave); -static u8 camera_power(cam_data *cam, bool cameraOn); static int start_preview(cam_data *cam); static int stop_preview(cam_data *cam); @@ -2380,26 +2379,113 @@ static void init_camera_struct(cam_data *cam) spin_lock_init(&cam->dqueue_int_lock); } -/*! - * camera_power function - * Turns Sensor power On/Off - * - * @param cam cam data struct - * @param cameraOn true to turn camera on, false to turn off power. - * - * @return status - */ -static u8 camera_power(cam_data *cam, bool cameraOn) +static ssize_t show_streaming(struct device *dev, + struct device_attribute *attr, char *buf) { - pr_debug("In MVC:camera_power on=%d\n", cameraOn); + struct video_device *video_dev = container_of(dev, + struct video_device, dev); + cam_data *g_cam = video_get_drvdata(video_dev); - if (cameraOn == true) { - ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); - vidioc_int_s_power(cam->sensor, 1); - } else { - ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); - vidioc_int_s_power(cam->sensor, 0); + if (g_cam->capture_on) + return sprintf(buf, "stream on\n"); + else + return sprintf(buf, "stream off\n"); +} +static DEVICE_ATTR(fsl_v4l2_capture_property, S_IRUGO, show_streaming, NULL); + +static ssize_t show_overlay(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct video_device *video_dev = container_of(dev, + struct video_device, dev); + cam_data *g_cam = video_get_drvdata(video_dev); + + if (g_cam->overlay_on) + return sprintf(buf, "overlay on\n"); + else + return sprintf(buf, "overlay off\n"); +} +static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL); + +/*! + * This function is called to probe the devices if registered. + * + * @param pdev the device structure used to give information on which device + * to probe + * + * @return The function returns 0 on success and -1 on failure. + */ +static int mxc_v4l2_probe(struct platform_device *pdev) +{ + /* Create g_cam and initialize it. */ + g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL); + if (g_cam == NULL) { + pr_err("ERROR: v4l2 capture: failed to register camera\n"); + return -1; } + init_camera_struct(g_cam, pdev); + pdev->dev.release = camera_platform_release; + + /* Set up the v4l2 device and register it*/ + mxc_v4l2_int_device.priv = g_cam; + /* This function contains a bug that won't let this be rmmod'd. */ + v4l2_int_device_register(&mxc_v4l2_int_device); + + /* register v4l video device */ + if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr) + == -1) { + kfree(g_cam); + g_cam = NULL; + pr_err("ERROR: v4l2 capture: video_register_device failed\n"); + return -1; + } + pr_debug(" Video device registered: %s #%d\n", + g_cam->video_dev->name, g_cam->video_dev->minor); + + if (device_create_file(&g_cam->video_dev->dev, + &dev_attr_fsl_v4l2_capture_property)) + dev_err(&pdev->dev, "Error on creating sysfs file" + " for capture\n"); + + if (device_create_file(&g_cam->video_dev->dev, + &dev_attr_fsl_v4l2_overlay_property)) + dev_err(&pdev->dev, "Error on creating sysfs file" + " for overlay\n"); + + return 0; +} + +/*! + * This function is called to remove the devices when device unregistered. + * + * @param pdev the device structure used to give information on which device + * to remove + * + * @return The function returns 0 on success and -1 on failure. + */ +static int mxc_v4l2_remove(struct platform_device *pdev) +{ + + if (g_cam->open_count) { + pr_err("ERROR: v4l2 capture:camera open " + "-- setting ops to NULL\n"); + return -EBUSY; + } else { + device_remove_file(&g_cam->video_dev->dev, + &dev_attr_fsl_v4l2_capture_property); + device_remove_file(&g_cam->video_dev->dev, + &dev_attr_fsl_v4l2_overlay_property); + + pr_info("V4L2 freeing image input device\n"); + v4l2_int_device_unregister(&mxc_v4l2_int_device); + video_unregister_device(g_cam->video_dev); + + mxc_free_frame_buf(g_cam); + kfree(g_cam); + g_cam = NULL; + } + + pr_info("V4L2 unregistering video\n"); return 0; } @@ -2431,7 +2517,7 @@ static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state) if ((cam->capture_on == true) && cam->enc_disable) { cam->enc_disable(cam); } - camera_power(cam, false); + vidioc_int_s_power(cam->sensor, 0); return 0; } @@ -2457,7 +2543,7 @@ static int mxc_v4l2_resume(struct platform_device *pdev) cam->low_power = false; wake_up_interruptible(&cam->power_queue); - camera_power(cam, true); + vidioc_int_s_power(cam->sensor, 1); if (cam->overlay_on == true) start_preview(cam);