From 4e8b9a053660bf8de1e397151b6ee96b23267e54 Mon Sep 17 00:00:00 2001 From: ddl Date: Thu, 9 Dec 2010 17:50:49 +0800 Subject: [PATCH] camera: add v4l2_subdev_core_ops ioctl function in sensor driver, and all sensor output pin must change to input for dual camera work after exit --- arch/arm/mach-rk29/include/mach/rk29_camera.h | 4 ++ drivers/media/video/ov2655.c | 31 +++++++++++++++ drivers/media/video/ov2659.c | 39 ++++++++++++++++++- drivers/media/video/ov5642.c | 33 +++++++++++++++- drivers/media/video/rk29_camera_oneframe.c | 2 + 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-rk29/include/mach/rk29_camera.h b/arch/arm/mach-rk29/include/mach/rk29_camera.h index 9853c1239649..ae542c97303b 100755 --- a/arch/arm/mach-rk29/include/mach/rk29_camera.h +++ b/arch/arm/mach-rk29/include/mach/rk29_camera.h @@ -42,6 +42,10 @@ #define RK29_CAM_RESETACTIVE_H (0x01< #include #include +#include #define _CONS(a,b) a##b #define CONS(a,b) _CONS(a,b) @@ -1655,6 +1656,19 @@ sensor_INIT_ERR: return ret; } +static int sensor_deactivate(struct v4l2_subdev *sd) +{ + struct i2c_client *client = sd->priv; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_write(client, 0x30b0, 0x00); + sensor_write(client, 0x30b1, 0x00); + + return 0; +} + static struct reginfo sensor_power_down_sequence[]= { {0x30ab, 0x00}, @@ -2610,7 +2624,23 @@ sensor_video_probe_err: return ret; } +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(sd); + break; + } + default: + break; + } + + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2618,6 +2648,7 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_ext_ctrls = sensor_g_ext_controls, .s_ext_ctrls = sensor_s_ext_controls, .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c index d3350da431d8..e85a8bdbf954 100644 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -19,6 +19,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include +#include #define _CONS(a,b) a##b #define CONS(a,b) _CONS(a,b) @@ -53,7 +54,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #define CONFIG_SENSOR_Mirror 0 #define CONFIG_SENSOR_Flip 0 -#define CONFIG_SENSOR_I2C_SPEED 400000 /* Hz */ +#define CONFIG_SENSOR_I2C_SPEED 300000 /* Hz */ #define CONFIG_SENSOR_TR 1 #define CONFIG_SENSOR_DEBUG 1 @@ -1293,6 +1294,23 @@ sensor_INIT_ERR: return ret; } +static int sensor_deactivate(struct v4l2_subdev *sd) +{ + struct i2c_client *client = sd->priv; + u8 reg_val; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_read(client,0x3000,®_val); + sensor_write(client, 0x3000, reg_val&0xfc); + sensor_write(client, 0x3001, 0x00); + sensor_read(client,0x3002,®_val); + sensor_write(client, 0x3002, reg_val&0x1f); + + return 0; +} + static struct reginfo sensor_power_down_sequence[]= { {0x30ab, 0x00}, @@ -2248,6 +2266,24 @@ sensor_video_probe_err: return ret; } +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(sd); + break; + } + default: + break; + } + + return 0; + +} + static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2255,6 +2291,7 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_ext_ctrls = sensor_g_ext_controls, .s_ext_ctrls = sensor_s_ext_controls, .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c index 0230d6f1560d..a809fadf11ee 100644 --- a/drivers/media/video/ov5642.c +++ b/drivers/media/video/ov5642.c @@ -19,6 +19,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include +#include #define _CONS(a,b) a##b #define CONS(a,b) _CONS(a,b) @@ -58,7 +59,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #define CONFIG_SENSOR_Mirror 0 #define CONFIG_SENSOR_Flip 0 -#define CONFIG_SENSOR_I2C_SPEED 400000 /* Hz */ +#define CONFIG_SENSOR_I2C_SPEED 300000 /* Hz */ #define CONFIG_SENSOR_TR 1 #define CONFIG_SENSOR_DEBUG 1 @@ -1909,7 +1910,19 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) sensor_INIT_ERR: return ret; } +static int sensor_deactivate(struct v4l2_subdev *sd) +{ + struct i2c_client *client = sd->priv; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_write(client, 0x3017, 0x00); // FREX,VSYNC,HREF,PCLK,D9-D6 + sensor_write(client, 0x3018, 0x03); // D5-D0 + sensor_write(client,0x3019,0X00); // STROBE,SDA + + return 0; +} static struct reginfo sensor_power_down_sequence[]= { {0x00,0x00} @@ -2963,6 +2976,23 @@ sensor_video_probe_err: return ret; } +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(sd); + break; + } + default: + break; + } + + return 0; + +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, @@ -2971,6 +3001,7 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_ext_ctrls = sensor_g_ext_controls, .s_ext_ctrls = sensor_s_ext_controls, .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { diff --git a/drivers/media/video/rk29_camera_oneframe.c b/drivers/media/video/rk29_camera_oneframe.c index 641ea2ff9345..4593b8e5ffe4 100644 --- a/drivers/media/video/rk29_camera_oneframe.c +++ b/drivers/media/video/rk29_camera_oneframe.c @@ -580,12 +580,14 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct rk29_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); BUG_ON(icd != pcdev->icd); dev_info(&icd->dev, "RK29 Camera driver detached from camera %d\n", icd->devnum); + v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL); rk29_camera_deactivate(pcdev); /* ddl@rock-chips.com: Call videobuf_mmap_free here for free the struct video_buffer which malloc in videobuf_alloc */ -- 2.34.1