Merge branch android-common-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / siv120b.c
index ade9562072ac79684cf19747c9e8bbda8b0f2570..6bc4b92ea13c1b2f90eb6064dc8c065513671f26 100755 (executable)
@@ -20,7 +20,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <mach/rk29_camera.h>
+#include <plat/rk_camera.h>
 
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
@@ -30,7 +30,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
        printk(KERN_WARNING fmt , ## arg); } while (0)
 
 #define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
 
 
 #define _CONS(a,b) a##b
@@ -54,7 +54,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  480
 #define SENSOR_INIT_WINSEQADR sensor_vga
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -65,7 +65,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_DigitalZoom   0
 #define CONFIG_SENSOR_Focus         0
 #define CONFIG_SENSOR_Exposure      0
-#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Flash         1
 #define CONFIG_SENSOR_Mirror        0
 #define CONFIG_SENSOR_Flip          0
 
@@ -90,12 +90,28 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
 #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
 
+#define SENSOR_AF_IS_ERR    (0x00<<0)
+#define SENSOR_AF_IS_OK                (0x01<<0)
+#define SENSOR_INIT_IS_ERR   (0x00<<28)
+#define SENSOR_INIT_IS_OK    (0x01<<28)
 struct reginfo
 {
     u8 reg;
     u8 val;
 };
 
+//flash off in fixed time to prevent from too hot , zyc
+struct  flash_timer{
+    struct soc_camera_device *icd;
+       struct hrtimer timer;
+};
+static enum hrtimer_restart flash_off_func(struct hrtimer *timer);
+
+static struct  flash_timer flash_off_timer;
+//for user defined if user want to customize the series , zyc
+#ifdef CONFIG_SIV120B_USER_DEFINED_SERIES
+#include "siv120b_user_series.c"
+#else
 /* init 640X480 VGA */
 static struct reginfo sensor_init_data[] =
 {
@@ -391,14 +407,16 @@ static struct reginfo sensor_qcif[] =
 {
     {0x00,0x00}
 };
-
+#endif
 static  struct reginfo sensor_ClrFmt_YUYV[]=
 {
+    {0x00,0x00}
 
 };
 
 static  struct reginfo sensor_ClrFmt_UYVY[]=
 {
+    {0x00,0x00}
 
 };
 
@@ -787,6 +805,7 @@ static  struct reginfo sensor_Effect_Negative[] =
        {0xb8,0x00},
 
 };
+#if 0
 static  struct reginfo sensor_Effect_Bluish[] =
 {
     // Bluish  -- aqua
@@ -796,7 +815,7 @@ static  struct reginfo sensor_Effect_Bluish[] =
        {0xb8,0x60},
 
 };
-
+#endif
 static  struct reginfo sensor_Effect_Green[] =
 {
     //  Greenish
@@ -970,7 +989,7 @@ static struct reginfo sensor_Zoom3[] =
 };
 static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
 #endif
-static const struct v4l2_querymenu sensor_menus[] =
+static struct v4l2_querymenu sensor_menus[] =
 {
        #if CONFIG_SENSOR_WhiteBalance
     { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},
@@ -994,7 +1013,7 @@ static const struct v4l2_querymenu sensor_menus[] =
     #endif
 };
 
-static const struct v4l2_queryctrl sensor_controls[] =
+static  struct v4l2_queryctrl sensor_controls[] =
 {
        #if CONFIG_SENSOR_WhiteBalance
     {
@@ -1167,8 +1186,12 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
 static int sensor_resume(struct soc_camera_device *icd);
 static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
 static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+#if CONFIG_SENSOR_Effect
 static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+#if CONFIG_SENSOR_WhiteBalance
 static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
 static int sensor_deactivate(struct i2c_client *client);
 
 static struct soc_camera_ops sensor_ops =
@@ -1183,16 +1206,28 @@ static struct soc_camera_ops sensor_ops =
     .num_menus         = ARRAY_SIZE(sensor_menus),
 };
 
-#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
-       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
-       .colorspace = _colorspace }
+/* only one fixed colorspace per pixelcode */
+struct sensor_datafmt {
+       enum v4l2_mbus_pixelcode code;
+       enum v4l2_colorspace colorspace;
+};
+
+/* Find a data format by a pixel code in an array */
+static const struct sensor_datafmt *sensor_find_datafmt(
+       enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt,
+       int n)
+{
+       int i;
+       for (i = 0; i < n; i++)
+               if (fmt[i].code == code)
+                       return fmt + i;
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+       return NULL;
+}
 
-static const struct soc_camera_data_format sensor_colour_formats[] = {
-       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
-       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
+static const struct sensor_datafmt sensor_colour_fmts[] = {
+    {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
+    {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}    
 };
 
 typedef struct sensor_info_priv_s
@@ -1212,7 +1247,8 @@ typedef struct sensor_info_priv_s
     unsigned char mirror;                                        /* HFLIP */
     unsigned char flip;                                          /* VFLIP */
     unsigned int winseqe_cur_addr;
-       unsigned int pixfmt;
+    struct sensor_datafmt fmt;
+    unsigned int funmodule_state;
 
 } sensor_info_priv_t;
 
@@ -1421,6 +1457,11 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 
                        if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
                                sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                if(on){
+                    //flash off after 2 secs
+                       hrtimer_cancel(&(flash_off_timer.timer));
+                       hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL);
+                    }
                        }
             break;
                }
@@ -1434,12 +1475,20 @@ sensor_power_end:
        return ret;
 }
 
+static enum hrtimer_restart flash_off_func(struct hrtimer *timer){
+       struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer);
+    sensor_ioctrl(fps_timer->icd,Sensor_Flash,0);
+       SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__);
+    return 0;
+    
+}
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
+    const struct sensor_datafmt *fmt;
     int ret, i;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
@@ -1460,7 +1509,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 //             goto sensor_INIT_ERR;
 //   }
 
-    mdelay(5);  //delay 5 microseconds
+//    mdelay(5);  //delay 5 microseconds
 
     for(i = 0; i < sizeof(sensor_init_data)/2;i++){
                
@@ -1477,11 +1526,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        //      printk("read from reg[0x%x] 0x%x\n",sensor_init_data[i].reg,tmp);
        }
        sensor_task_lock(client,0);
-               
-    icd->user_width = SENSOR_INIT_WIDTH;
-    icd->user_height = SENSOR_INIT_HEIGHT;
+
     sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
-       sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
+       fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts));
+    if (!fmt) {
+        SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING());
+        ret = -EINVAL;
+        goto sensor_INIT_ERR;
+    }
+       sensor->info_priv.fmt = *fmt;
 
     /* sensor sensor information for initialization  */
        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
@@ -1528,12 +1581,16 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
        if (qctrl)
         sensor->info_priv.flash = qctrl->default_value;
+    flash_off_timer.icd = icd;
+       flash_off_timer.timer.function = flash_off_func;
     #endif
 
     SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
-
+    sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK;
     return 0;
 sensor_INIT_ERR:
+    sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;
+    sensor_task_lock(client,0);
        sensor_deactivate(client);
     return ret;
 }
@@ -1541,6 +1598,7 @@ sensor_INIT_ERR:
 static int sensor_deactivate(struct i2c_client *client)
 {
        struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
 
        SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -1551,6 +1609,7 @@ static int sensor_deactivate(struct i2c_client *client)
        icd->user_width = SENSOR_INIT_WIDTH;
     icd->user_height = SENSOR_INIT_HEIGHT;
        msleep(100);
+    sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;
        return 0;
 }
 static  struct reginfo sensor_power_down_sequence[]=
@@ -1614,80 +1673,88 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
     return soc_camera_apply_sensor_flags(icl, flags);
 }
 
-static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
 
-    pix->width         = icd->user_width;
-    pix->height                = icd->user_height;
-    pix->pixelformat   = sensor->info_priv.pixfmt;
-    pix->field         = V4L2_FIELD_NONE;
-    pix->colorspace            = V4L2_COLORSPACE_JPEG;
+    mf->width  = icd->user_width;
+       mf->height      = icd->user_height;
+       mf->code        = sensor->info_priv.fmt.code;
+       mf->colorspace  = sensor->info_priv.fmt.colorspace;
+       mf->field       = V4L2_FIELD_NONE;
 
     return 0;
 }
-static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+#if 0
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     bool ret = false;
 
-       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+       if ((mf->width == 1024) && (mf->height == 768)) {
                ret = true;
-       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+       } else if ((mf->width == 1280) && (mf->height == 1024)) {
                ret = true;
-       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+       } else if ((mf->width == 1600) && (mf->height == 1200)) {
                ret = true;
-       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+       } else if ((mf->width == 2048) && (mf->height == 1536)) {
                ret = true;
-       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+       } else if ((mf->width == 2592) && (mf->height == 1944)) {
                ret = true;
        }
 
        if (ret == true)
-               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height);
        return ret;
 }
 
-static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     bool ret = false;
 
-       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+       if ((mf->width == 1280) && (mf->height == 720)) {
                ret = true;
-       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+       } else if ((mf->width == 1920) && (mf->height == 1080)) {
                ret = true;
        }
 
        if (ret == true)
-               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height);
        return ret;
 }
-static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+#endif
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct sensor_datafmt *fmt;
     struct reginfo *winseqe_set_addr=NULL;
        char readval;
     int ret=0, set_w,set_h,i;
 
-       if (sensor->info_priv.pixfmt != pix->pixelformat) {
-               switch (pix->pixelformat)
+       fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
+                                  ARRAY_SIZE(sensor_colour_fmts));
+       if (!fmt) {
+        ret = -EINVAL;
+        goto sensor_s_fmt_end;
+    }
+
+       if (sensor->info_priv.fmt.code != mf->code) {
+               switch (mf->code)
                {
-                       case V4L2_PIX_FMT_YUYV:
+                       case V4L2_MBUS_FMT_YUYV8_2X8:
                        {
-                               //winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
                                sensor_read(client, 0x3a, &readval);
                                sensor_write(client,0x3a, readval&0xf7);
                                sensor_read(client,0x3d,&readval);
                                sensor_write(client,0x3d,readval&0xfe);
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
-                               //winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
                                sensor_read(client, 0x3a, &readval);
                                sensor_write(client,0x3a, readval|0x08);
                                sensor_read(client,0x3d,&readval);
@@ -1699,19 +1766,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                }
                if (winseqe_set_addr != NULL) {
             sensor_write_array(client, winseqe_set_addr);
-                       sensor->info_priv.pixfmt = pix->pixelformat;
-
-                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+                       sensor->info_priv.fmt.code = mf->code;
+            sensor->info_priv.fmt.colorspace= mf->colorspace;            
+                       SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code);
                } else {
-                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);
-               //      sensor->info_priv.pixfmt = pix->pixelformat;
-
-               //      SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+                       SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code);
                }
        }
 
-    set_w = pix->width;
-    set_h = pix->height;
+    set_w = mf->width;
+    set_h = mf->height;
 
        if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
        {
@@ -1742,7 +1806,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
         set_w = SENSOR_INIT_WIDTH;
         set_h = SENSOR_INIT_HEIGHT;            
-               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height);
     }
 
     if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
@@ -1766,44 +1830,74 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
     }
 
-       pix->width = set_w;
-    pix->height = set_h;
+       mf->width = set_w;
+    mf->height = set_h;
 
 sensor_s_fmt_end:
     return ret;
 }
 
-static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
-    struct v4l2_pix_format *pix = &f->fmt.pix;
-    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||
-        pix->pixelformat == V4L2_PIX_FMT_YUYV;
-
-    /*
-    * With Bayer format enforce even side lengths, but let the user play
-    * with the starting pixel
-    */
-
-    if (pix->height > SENSOR_MAX_HEIGHT)
-        pix->height = SENSOR_MAX_HEIGHT;
-    else if (pix->height < SENSOR_MIN_HEIGHT)
-        pix->height = SENSOR_MIN_HEIGHT;
-    else if (bayer)
-        pix->height = ALIGN(pix->height, 2);
-
-    if (pix->width > SENSOR_MAX_WIDTH)
-        pix->width = SENSOR_MAX_WIDTH;
-    else if (pix->width < SENSOR_MIN_WIDTH)
-        pix->width = SENSOR_MIN_WIDTH;
-    else if (bayer)
-        pix->width = ALIGN(pix->width, 2);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0,set_w,set_h;
+   
+       fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
+                                  ARRAY_SIZE(sensor_colour_fmts));
+       if (fmt == NULL) {
+               fmt = &sensor->info_priv.fmt;
+        mf->code = fmt->code;
+       } 
+
+    if (mf->height > SENSOR_MAX_HEIGHT)
+        mf->height = SENSOR_MAX_HEIGHT;
+    else if (mf->height < SENSOR_MIN_HEIGHT)
+        mf->height = SENSOR_MIN_HEIGHT;
+
+    if (mf->width > SENSOR_MAX_WIDTH)
+        mf->width = SENSOR_MAX_WIDTH;
+    else if (mf->width < SENSOR_MIN_WIDTH)
+        mf->width = SENSOR_MIN_WIDTH;
+    
+    set_w = mf->width;
+    set_h = mf->height;
 
-    return 0;
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;            
+    }
+    mf->width = set_w;
+    mf->height = set_h;  
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
-
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
 
     if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
         return -EINVAL;
@@ -2028,7 +2122,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v
 }
 #endif
 #if CONFIG_SENSOR_DigitalZoom
-static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
 {
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
     struct sensor *sensor = to_sensor(client);
@@ -2042,29 +2136,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
     digitalzoom_cur = sensor->info_priv.digitalzoom;
     digitalzoom_total = qctrl_info->maximum;
 
-    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))
+    if ((value > 0) && (digitalzoom_cur >= digitalzoom_total))
     {
         SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
         return -EINVAL;
     }
 
-    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
+    if  ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
     {
         SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
         return -EINVAL;
     }
 
-    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))
+    if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total))
     {
-        *value = digitalzoom_total - digitalzoom_cur;
+        value = digitalzoom_total - digitalzoom_cur;
     }
 
-    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))
+    if ((value < 0) && ((digitalzoom_cur + value) < 0))
     {
-        *value = 0 - digitalzoom_cur;
+        value = 0 - digitalzoom_cur;
     }
 
-    digitalzoom_cur += *value;
+    digitalzoom_cur += value;
 
     if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)
     {
@@ -2073,7 +2167,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
             SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
             return -EINVAL;
         }
-        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
         return 0;
     }
 
@@ -2100,7 +2194,7 @@ static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_que
 
 static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct v4l2_queryctrl *qctrl;
 
@@ -2159,9 +2253,9 @@ static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 
 static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-    struct i2c_client *client = sd->priv;
-    struct sensor *sensor = to_sensor(client);
-    struct soc_camera_device *icd = client->dev.platform_data;
+    //ruct i2c_client *client = v4l2_get_subdevdata(sd);
+    //ruct sensor *sensor = to_sensor(client);
+    //ruct soc_camera_device *icd = client->dev.platform_data;
     const struct v4l2_queryctrl *qctrl;
 
 
@@ -2449,7 +2543,7 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
 
 static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct soc_camera_device *icd = client->dev.platform_data;
     int i, error_cnt=0, error_idx=-1;
 
@@ -2474,7 +2568,7 @@ static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control
 
 static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
 {
-    struct i2c_client *client = sd->priv;
+    struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct soc_camera_device *icd = client->dev.platform_data;
     int i, error_cnt=0, error_idx=-1;
 
@@ -2543,9 +2637,6 @@ static int sensor_video_probe(struct soc_camera_device *icd,
         goto sensor_video_probe_err;
     }
 
-    icd->formats = sensor_colour_formats;
-    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
-
     return 0;
 
 sensor_video_probe_err:
@@ -2555,7 +2646,7 @@ sensor_video_probe_err:
 
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
-       struct i2c_client *client = sd->priv;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
     int ret = 0;
@@ -2576,12 +2667,17 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                {
                        sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
             if (sensor->sensor_io_request != NULL) { 
-                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
-                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
-                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
-                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
-                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
-                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
                 }
             } else {
                 SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
@@ -2595,11 +2691,18 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                 if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
                     for (i = 0; i < icd->ops->num_controls; i++) {
                                if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
-                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                                       //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));  
+                              sensor_controls[i].id=0xffff;                            
                                }
                     }
                     sensor->info_priv.flash = 0xff;
                     SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }else{ //two cameras are the same,need to deal diffrently ,zyc
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                           if(0xffff == icd->ops->controls[i].id){
+                              sensor_controls[i].id=V4L2_CID_FLASH;
+                           }               
+                    }
                 }
                }
             #endif
@@ -2615,6 +2718,15 @@ sensor_ioctl_end:
        return ret;
 
 }
+static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+                           enum v4l2_mbus_pixelcode *code)
+{
+       if (index >= ARRAY_SIZE(sensor_colour_fmts))
+               return -EINVAL;
+
+       *code = sensor_colour_fmts[index].code;
+       return 0;
+}
 static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .init           = sensor_init,
        .g_ctrl         = sensor_g_control,
@@ -2626,9 +2738,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
 };
 
 static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
-       .s_fmt          = sensor_s_fmt,
-       .g_fmt          = sensor_g_fmt,
-       .try_fmt        = sensor_try_fmt,
+       .s_mbus_fmt     = sensor_s_fmt,
+       .g_mbus_fmt     = sensor_g_fmt,
+       .try_mbus_fmt   = sensor_try_fmt,
+       .enum_mbus_fmt  = sensor_enum_fmt,
 };
 
 static struct v4l2_subdev_ops sensor_subdev_ops = {
@@ -2671,7 +2784,7 @@ static int sensor_probe(struct i2c_client *client,
 
     /* Second stage probe - when a capture adapter is there */
     icd->ops           = &sensor_ops;
-    icd->y_skip_top            = 0;
+    sensor->info_priv.fmt = sensor_colour_fmts[0];
        #if CONFIG_SENSOR_I2C_NOSCHED
        atomic_set(&sensor->tasklock_cnt,0);
        #endif
@@ -2683,6 +2796,7 @@ static int sensor_probe(struct i2c_client *client,
         kfree(sensor);
                sensor = NULL;
     }
+       hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
     SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
     return ret;
 }