camera: camera driver and all sensor driver support
authorddl <ddl@rockchip.com>
Thu, 4 Aug 2011 04:29:21 +0000 (12:29 +0800)
committerddl <ddl@rockchip.com>
Thu, 4 Aug 2011 04:29:21 +0000 (12:29 +0800)
20 files changed:
drivers/media/video/Kconfig
drivers/media/video/gc0308.c
drivers/media/video/gc0309.c
drivers/media/video/gc2015.c
drivers/media/video/gt2005.c
drivers/media/video/hi253.c
drivers/media/video/hi704.c
drivers/media/video/mt9p111.c
drivers/media/video/nt99250.c
drivers/media/video/ov2640.c
drivers/media/video/ov2655.c
drivers/media/video/ov2659.c
drivers/media/video/ov3640.c
drivers/media/video/ov5640.c
drivers/media/video/ov5642.c
drivers/media/video/ov7675.c
drivers/media/video/rk29_camera_oneframe.c
drivers/media/video/s5k6aa.c
drivers/media/video/sid130B.c
drivers/media/video/siv120b.c

index c99dd2019b0ae0a1d95e24cb92552c2868664ad1..551ef42ecb03b13ad1e10e2598b5bab0fe5a2ccf 100755 (executable)
@@ -817,7 +817,11 @@ config SOC_CAMERA_MT9T111
        depends on SOC_CAMERA && I2C
        help
          This driver supports MT9T111 cameras from Micron.
-
+config SOC_CAMERA_MT9P111
+       tristate "mt9p111 support"
+       depends on SOC_CAMERA && I2C
+       help
+         This driver supports MT9P111 cameras from Micron.
 config SOC_CAMERA_MT9D112
        tristate "mt9d112 support"
        depends on SOC_CAMERA && I2C
@@ -952,10 +956,10 @@ config OV5640_FIXEDFOCUS
 endchoice
 
 config SOC_CAMERA_S5K6AA
-       tristate "Samsung S5K6AA MIPI CSI-2 (importek mu736asa)"
+       tristate "Samsung S5K6AA camera support"
        depends on SOC_CAMERA && I2C
        help
-         This is a samsung S5K6AA mobile camera driver
+         This is a samsung S5K6AA camera driver
 
 config SOC_CAMERA_GT2005
        tristate "GT2005 support"
index 21acf25f2e7f7b88507a4ce89196e308936859a3..5a8eb3c35153e9a25a92b3a38d4e93442c0e1f8c 100755 (executable)
@@ -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     1
 #define CONFIG_SENSOR_Brightness       0
@@ -90,6 +90,11 @@ 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;
@@ -1191,16 +1196,27 @@ 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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
+
+       return NULL;
+}
 
-static const struct soc_camera_data_format sensor_colour_formats[] = {
-       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
-       //JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+static const struct sensor_datafmt sensor_colour_fmts[] = {
+    {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}    
 };
 
 typedef struct sensor_info_priv_s
@@ -1220,8 +1236,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;
 
 struct sensor
@@ -1400,7 +1416,7 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
 }
 #endif
 
-
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray)
 {
   int ret;
@@ -1427,6 +1443,7 @@ static int sensor_check_array(struct i2c_client *client, struct reginfo *regarra
        
   return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -1478,6 +1495,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
@@ -1508,10 +1526,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     }
        
        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);
@@ -1561,9 +1584,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #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;
@@ -1573,16 +1597,18 @@ static int sensor_deactivate(struct i2c_client *client)
 {
        struct soc_camera_device *icd = client->dev.platform_data;
        //u8 reg_val;
-
+    struct sensor *sensor = to_sensor(client);
        SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
        sensor_ioctrl(icd, Sensor_PowerDown, 1);
+    msleep(100); 
 
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
        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[]=
@@ -1645,73 +1671,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1721,16 +1755,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_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)
        {
@@ -1773,12 +1807,12 @@ 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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1794,7 +1828,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1806,6 +1840,29 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+            msleep(600);
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
 
         SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
     }
@@ -1814,39 +1871,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2578,9 +2636,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:
@@ -2650,6 +2705,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,
@@ -2661,9 +2725,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 = {
@@ -2706,7 +2771,9 @@ 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
index 8d5b12bf96864e1562ecdd947dce1158602bc58b..a36cb41c407104734517e6e914ad8f426ad65aaf 100755 (executable)
@@ -29,7 +29,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
@@ -53,8 +53,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_UYVY
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YVYU
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -90,6 +89,10 @@ 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
 {
@@ -1126,16 +1129,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
@@ -1155,8 +1170,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;
 
 struct sensor
@@ -1206,10 +1221,13 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
                                preempt_enable();
                }
        }
-#endif
        return 0;
 sensor_task_lock_err:
-       return -1;
+       return -1;  
+#else
+    return 0;
+#endif
+
 }
 
 #if 0
@@ -1315,8 +1333,10 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
 {
     int err = 0, cnt;
     int i = 0;
+#if CONFIG_SENSOR_I2C_RDWRCHK    
        int j = 0;
        char valchk;
+#endif
 
        cnt = 0;
        if (sensor_task_lock(client, 1) < 0)
@@ -1350,6 +1370,7 @@ sensor_write_array_end:
        sensor_task_lock(client,0);
        return err;
 }
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
 {
     int cnt;
@@ -1368,6 +1389,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -1418,13 +1440,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret;
 
-    SENSOR_DG("\n-------------%s..%s.. %d,val = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__,val);
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
-                SENSOR_DG("\n-------------%s..%s.. %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
                ret = -ENODEV;
                goto sensor_INIT_ERR;
        }
@@ -1439,7 +1461,6 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         ret = -ENODEV;
                goto sensor_INIT_ERR;
     }
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
     mdelay(5);  //delay 5 microseconds
        /* check if it is an sensor sensor */
     ret = sensor_read(client, 0x00, &value);
@@ -1448,7 +1469,7 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
         ret = -ENODEV;
         goto sensor_INIT_ERR;
     }
-       SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
     if (value == SENSOR_ID) {
         sensor->model = SENSOR_V4L2_IDENT;
     } else {
@@ -1456,7 +1477,7 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
         ret = -ENODEV;
         goto sensor_INIT_ERR;
     }
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
     ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
@@ -1464,11 +1485,16 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
         goto sensor_INIT_ERR;
     }
        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;
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+    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);
        if (qctrl)
@@ -1509,7 +1535,7 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
        if (qctrl)
         sensor->info_priv.focus = qctrl->default_value;
        #endif
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
        #if CONFIG_SENSOR_Flash 
        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
        if (qctrl)
@@ -1517,9 +1543,10 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
     #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;
@@ -1528,15 +1555,19 @@ sensor_INIT_ERR:
 static int sensor_deactivate(struct i2c_client *client)
 {
        struct soc_camera_device *icd = client->dev.platform_data;
-       SENSOR_DG("\n----------------------------%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
+       u8 reg_val;
+    struct sensor *sensor = to_sensor(client);
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
        sensor_ioctrl(icd, Sensor_PowerDown, 1);
+    msleep(100); 
 
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
        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;
 }
 
@@ -1600,81 +1631,82 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
-       if (sensor->info_priv.pixfmt != pix->pixelformat) {
-               SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
-               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)
                {
-                       SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
-                       case V4L2_PIX_FMT_YUYV:
+                       case V4L2_MBUS_FMT_YUYV8_2X8:
                        {
-                               SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
                                winseqe_set_addr = sensor_ClrFmt_YUYV;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
-                               SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
                        }
@@ -1683,17 +1715,17 @@ 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_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code);
                }
        }
-       
-    set_w = pix->width;
-    set_h = pix->height;
-       SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
+    set_w = mf->width;
+    set_h = mf->height;
+
        if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
        {
                winseqe_set_addr = sensor_qcif;
@@ -1724,19 +1756,40 @@ 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);
     }
-       SENSOR_TR("------------------------------%s,    %s   ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
        if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
                ret |= sensor_write_array(client, winseqe_set_addr);
                if (ret != 0) {
                        SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,mf) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
                        goto sensor_s_fmt_end;
                }
 
                sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        if (sensor->info_priv.whiteBalance != 0) {
@@ -1744,7 +1797,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
                        }
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
@@ -1765,39 +1818,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2028,29 +2082,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)
     {
@@ -2059,7 +2113,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;
     }
 
@@ -2492,8 +2546,6 @@ static int sensor_video_probe(struct soc_camera_device *icd,
     int ret;
     struct sensor *sensor = to_sensor(client);
 
-       SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
-
     /* We must have a parent by now. And it cannot be a wrong one.
      * So this entire test is completely redundant. */
     if (!icd->dev.parent ||
@@ -2504,7 +2556,7 @@ static int sensor_video_probe(struct soc_camera_device *icd,
                ret = -ENODEV;
                goto sensor_video_probe_err;
        }
-       SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
     /* soft reset */
     ret = sensor_write(client, 0xfe, 0x80);
     if (ret != 0)
@@ -2513,7 +2565,7 @@ static int sensor_video_probe(struct soc_camera_device *icd,
         return -ENODEV;
     }
     mdelay(5);          //delay 5 microseconds
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
     /* check if it is an sensor sensor */
     ret = sensor_read(client, 0x00, &value);
     if (ret != 0) {
@@ -2521,7 +2573,7 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
         ret = -ENODEV;
         goto sensor_video_probe_err;
     }
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
     if (value == SENSOR_ID) {
         sensor->model = SENSOR_V4L2_IDENT;
                SENSOR_TR("chip id:0x%x\n",value);
@@ -2530,10 +2582,7 @@ SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION
         ret = -ENODEV;
         goto sensor_video_probe_err;
     }
-       
-    icd->formats = sensor_colour_formats;
-    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
-SENSOR_DG("--------------------%s  ,  %s,  %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
+
     return 0;
 
 sensor_video_probe_err:
@@ -2602,6 +2651,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,
@@ -2613,9 +2671,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 = {
@@ -2658,7 +2717,9 @@ 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
index 0a47fc97e5e39a4fa3ecff5c8955de9beb7f200b..4ffe4974be070eee3bdcc3d003246f1122674004 100755 (executable)
@@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      1024                    /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  768
 #define SENSOR_INIT_WINSEQADR sensor_svga
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -89,6 +89,10 @@ 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
 {
@@ -998,16 +1002,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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
 
-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),
+       return NULL;
+}
+
+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
@@ -1027,8 +1043,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;
 
 struct sensor
@@ -1187,8 +1203,10 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
 {
     int err = 0, cnt;
     int i = 0;
+#if CONFIG_SENSOR_I2C_RDWRCHK    
        int j = 0;
        char valchk;
+#endif    
 
        cnt = 0;
        if (sensor_task_lock(client, 1) < 0)
@@ -1222,6 +1240,7 @@ sensor_write_array_end:
        sensor_task_lock(client,0);
        return err;
 }
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
 {
     int cnt;
@@ -1240,6 +1259,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -1290,6 +1310,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -1346,10 +1367,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1399,9 +1425,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #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;
@@ -1411,15 +1438,18 @@ 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__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
-       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+    sensor_ioctrl(icd, Sensor_PowerDown, 1); 
+    msleep(100); 
 
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
        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;
 }
 
@@ -1483,76 +1513,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       SENSOR_TR("sensor_s_fmt\n");
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1562,16 +1597,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_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)
        {
@@ -1626,12 +1661,12 @@ 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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1647,7 +1682,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1659,7 +1694,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        if (sensor->info_priv.whiteBalance != 0) {
@@ -1667,7 +1702,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
                        }
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
@@ -1688,39 +1723,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -1951,29 +1987,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)
     {
@@ -1982,7 +2018,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;
     }
 
@@ -2462,9 +2498,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:
@@ -2533,6 +2566,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,
@@ -2540,13 +2582,14 @@ 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,
+       .ioctl = sensor_ioctl,  
 };
 
 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 = {
@@ -2589,7 +2632,9 @@ 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
index b260ddea4f3e8cff02b92989e609a2b174b5ef1d..b7e436615d1f09f5f2785cd0fdc5b7220dffbbb4 100755 (executable)
@@ -53,7 +53,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     1
 #define CONFIG_SENSOR_Brightness       0
@@ -89,6 +89,11 @@ 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
 {
     u16 reg;
@@ -1944,16 +1949,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
@@ -1973,8 +1990,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;
 
 struct sensor
@@ -2151,7 +2168,7 @@ sensor_write_array_end:
        return err;
 }
 
-
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray)
 {
   int ret;
@@ -2181,6 +2198,7 @@ static int sensor_check_array(struct i2c_client *client, struct reginfo *regarra
        
   return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -2232,6 +2250,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -2288,10 +2307,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -2341,9 +2365,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #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;
@@ -2353,17 +2378,22 @@ 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__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+    if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {
     sensor_write(client, 0x30b0, 0x00);
        sensor_write(client, 0x30b1, 0x00);
+    }
        sensor_ioctrl(icd, Sensor_PowerDown, 1);
+    msleep(100); 
 
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
        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;
 }
 
@@ -2431,76 +2461,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
-#if CONFIG_SENSOR_Flash    
+       const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
-#endif
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -2510,16 +2545,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_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)
        {
@@ -2568,13 +2603,12 @@ 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;
-               ret = -1;
-               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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -2590,7 +2624,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -2602,6 +2636,29 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+            msleep(600);
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
 
         SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
     }
@@ -2610,39 +2667,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2873,29 +2931,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)
     {
@@ -2904,7 +2962,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;
     }
 
@@ -2912,12 +2970,8 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
 }
 #endif
 #if CONFIG_SENSOR_Flash
-static int sensor_set_flash(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);
-       const struct v4l2_queryctrl *qctrl_info;
-    
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
     if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
         if (value == 3) {       /* ddl@rock-chips.com: torch */
             sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
@@ -3388,9 +3442,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:
@@ -3439,7 +3490,7 @@ 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(&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                      
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
                                }
                     }
                     sensor->info_priv.flash = 0xff;
@@ -3459,6 +3510,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,
@@ -3470,9 +3530,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 = {
@@ -3515,16 +3576,19 @@ 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
 
     ret = sensor_video_probe(icd, client);
-    if (ret) {
+    if (ret < 0) {
         icd->ops = NULL;
         i2c_set_clientdata(client, NULL);
         kfree(sensor);
+               sensor = NULL;
     }
     SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
     return ret;
index ee2f503b270fff63321ca0bb2c3dab0d3b42846d..31ae238802f982b01cc2181fc1adfd7e394aa48e 100755 (executable)
@@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      1600                    /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  1200
 #define SENSOR_INIT_WINSEQADR sensor_uxga
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -89,7 +89,10 @@ 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)
 #define END_REG 0xff
 
 struct reginfo
@@ -1872,16 +1875,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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
+
+       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
@@ -1901,7 +1916,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;
 
@@ -2075,6 +2091,7 @@ sensor_write_array_end:
        sensor_task_lock(client,0);
        return err;
 }
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
 {
     int cnt;
@@ -2093,6 +2110,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -2143,6 +2161,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;    
     char value;
     int ret;
 
@@ -2191,10 +2210,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -2245,8 +2268,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     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;
@@ -2255,7 +2280,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__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
@@ -2265,6 +2290,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;
 }
 
@@ -2328,75 +2354,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct sensor_datafmt *fmt;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -2406,16 +2438,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_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 != END_REG))
        {
@@ -2471,12 +2503,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -2504,7 +2536,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
         #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -2516,7 +2548,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        }
         #endif
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -2546,39 +2578,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2795,7 +2828,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);
@@ -2809,29 +2842,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;
     }
 
-    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)
     {
@@ -2840,7 +2873,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;
     }
 
@@ -3309,11 +3342,7 @@ static int sensor_video_probe(struct soc_camera_device *icd,
         ret = -ENODEV;
         goto sensor_video_probe_err;
     }
-
-               
-    icd->formats = sensor_colour_formats;
-    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
-
+       
     return 0;
 
 sensor_video_probe_err:
@@ -3382,6 +3411,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,
@@ -3392,10 +3430,12 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .ioctl = sensor_ioctl,
 };
 
+
 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 = {
@@ -3438,7 +3478,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
index 92dbb886e277e0328580a6573159963b528f55b8..5cd8e844a2e7545ff0f1be194a8216c9d59060d1 100755 (executable)
@@ -53,7 +53,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_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -88,7 +88,10 @@ 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)
 //lxh end of reg flag
 #define END_REG 0xff
 
@@ -1329,16 +1332,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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
+
+       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
@@ -1358,7 +1373,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;
 
@@ -1409,10 +1425,12 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
                                preempt_enable();
                }
        }
-#endif
        return 0;
 sensor_task_lock_err:
-       return -1;
+       return -1;  
+#else
+    return 0;
+#endif
 }
 
 #if 0
@@ -1551,6 +1569,7 @@ sensor_write_array_end:
        sensor_task_lock(client,0);
        return err;
 }
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
 {
     int cnt;
@@ -1569,6 +1588,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -1619,6 +1639,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret;
 
@@ -1667,10 +1688,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1720,9 +1745,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #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;
@@ -1731,7 +1757,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__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
@@ -1741,6 +1767,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;
 }
 
@@ -1804,75 +1831,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct sensor_datafmt *fmt;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1882,16 +1915,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_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 != END_REG))
        {
@@ -1923,12 +1956,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1944,7 +1977,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1956,7 +1989,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
         #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -1968,7 +2001,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        }
         #endif
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -1998,39 +2031,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2247,7 +2281,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);
@@ -2261,29 +2295,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)
     {
@@ -2292,7 +2326,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;
     }
 
@@ -2763,10 +2797,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:
@@ -2835,6 +2865,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,
@@ -2846,9 +2885,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 = {
@@ -2891,7 +2931,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
index 794bce5a8dc7b1ffbe34c05a52ac50e795b430a4..6a38b91ed05dcd2b4e57e65a386e42f1d2d23fa6 100644 (file)
@@ -33,7 +33,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
 #define CONS(a,b) _CONS(a,b)
@@ -60,7 +60,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_UYVY
+#define SENSOR_INIT_PIXFMT  V4L2_MBUS_FMT_UYVY8_2X8
 #define YUV420_BUFFER_MAX_SIZE  7558272     /* 2592*1944*1.5*/ 
 
 #define CONFIG_SENSOR_WhiteBalance     1
@@ -1719,12 +1719,12 @@ static  struct reginfo sensor_Effect_Normal[] =
        {0x8404,0x06, BYTE_LEN, 0 },
        {SEQUENCE_END, 0x00, 0, 0}
 };
-
+#if 0
 static  struct reginfo sensor_Effect_WandB[] =
 {
     {SEQUENCE_END, 0x00, 0, 0}
 };
-
+#endif
 static  struct reginfo sensor_Effect_Sepia[] =
 {
        {0x098e,0xdc38, WORD_LEN, 0},
@@ -1742,6 +1742,7 @@ static  struct reginfo sensor_Effect_Negative[] =
        {0x8404,0x06, BYTE_LEN, 0 },
        {SEQUENCE_END, 0x00, 0, 0}
 };
+#if 0
 static  struct reginfo sensor_Effect_Bluish[] =
 {
     {SEQUENCE_END, 0x00, 0, 0}
@@ -1751,7 +1752,7 @@ static  struct reginfo sensor_Effect_Green[] =
 {
     {SEQUENCE_END, 0x00, 0, 0}
 };
-
+#endif
 static struct reginfo sensor_Effect_Solarize[] =
 {
        {0x098e,0xdc38, WORD_LEN, 0},
@@ -2156,16 +2157,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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
 
-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),
+       return NULL;
+}
+
+static const struct sensor_datafmt sensor_colour_fmts[] = {
+    {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
+    {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}    
 };
 enum sensor_work_state
 {
@@ -2202,7 +2215,7 @@ typedef struct sensor_info_priv_s
        int preview_w;
        int preview_h;
     struct reginfo *winseqe_cur_addr;
-       unsigned int pixfmt;
+       struct sensor_datafmt fmt;
        unsigned int enable;
        unsigned int funmodule_state;
 } sensor_info_priv_t;
@@ -2355,7 +2368,7 @@ static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo
     int i=0;
     int sum =0;
     struct reginfo *tmpval = NULL;
-    u8 buf[1600];
+    u8 *buf;
     struct i2c_msg msg[1];
     tmpval = reg_info;
     
@@ -2363,7 +2376,13 @@ static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo
      return -EINVAL;
 
     memset((char*)&msg[0],0,sizeof(struct i2c_msg));   
-    memset(buf,0,1600*sizeof(u8));
+    buf = kmalloc((count*2+10)*sizeof(u8),GFP_KERNEL);
+    if (buf == NULL) {
+        SENSOR_TR("%s %s fail,because kmalloc failed",SENSOR_NAME_STRING(),__FUNCTION__);
+        err = -1;
+        goto sensor_write_Multiple_data_end;
+    }
+    memset(buf,0,sizeof(buf));
     
        switch (reg_info->reg)
        {
@@ -2431,6 +2450,11 @@ static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo
                    }            
                }                
        }
+sensor_write_Multiple_data_end:  
+    if (buf) {
+        kfree(buf);
+        buf = NULL;
+    }
     return err;
 }
 
@@ -2442,7 +2466,7 @@ static int sensor_read(struct i2c_client *client, u16 reg, u16 *val)
     struct i2c_msg msg[2];
 
     buf[0] = reg >> 8;
-    buf[1] = reg & 0xFF;
+    buf[1] = reg & 0xFF; 
 
     msg[0].addr = client->addr;
     msg[0].flags = client->flags;
@@ -2504,7 +2528,6 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
            num++;
            j++;
        }         
-     //SENSOR_TR("%s ..%s..num =%d,regarray[%d].reg=0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__,num,i,regarray[i].reg);         
        err = sensor_write_Multiple_data(client, &regarray[i], num) ;            
        if (err < 0)
         {
@@ -2527,8 +2550,6 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
 
        i=i+num;
     }
- //    SENSOR_TR("%s ..%s..quit\n",SENSOR_NAME_STRING(),__FUNCTION__);  
-
 sensor_write_array_end:
        sensor_task_lock(client,0);
     return err;
@@ -2538,15 +2559,12 @@ sensor_write_array_end:
 static int sensor_write_init_data(struct i2c_client *client, struct reginfo *regarray)
 {
     int err = 0, cnt;
-    int i = 0,j=0;
-    int num = 0;  
-    u16 temp = 0;
+    int i = 0;
+    int num = 0;
 #if CONFIG_SENSOR_I2C_RDWRCHK
        char valchk;
 #endif
-       cnt = 0;
-
-    int ti=0;            
+    int ti=0;     
     int table[167] = {                   /*written data numbers every time*/
         3,1,1,3,1,1,1,1,11,2,2,13,1,1,1,2,11,2,2,13,
         1,2,1,1,2,1,1,1,1,1,8,1,1,1,1,1,1,714,1,1,
@@ -2559,10 +2577,9 @@ static int sensor_write_init_data(struct i2c_client *client, struct reginfo *reg
         4,6,1,1,1,1,1
     };
     
+    cnt = 0; 
        if (sensor_task_lock(client, 1) < 0)
                goto sensor_write_array_end;
-    
-   // SENSOR_TR("%s ..%s..\n",SENSOR_NAME_STRING(),__FUNCTION__);         
    
     while (regarray[i].reg != SEQUENCE_END) { 
 
@@ -2570,7 +2587,6 @@ static int sensor_write_init_data(struct i2c_client *client, struct reginfo *reg
          num = table[ti];
          ti++;
        }         
-     //  SENSOR_TR("%s ..%s..num =%d,regarray[%d].reg=0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__,num,i,regarray[i].reg);         
        err = sensor_write_Multiple_data(client, &regarray[i], num) ;            
        if (err < 0)
         {
@@ -2592,8 +2608,6 @@ static int sensor_write_init_data(struct i2c_client *client, struct reginfo *reg
         }
        i=i+num;
     }
- //    SENSOR_TR("%s ..%s..quit\n",SENSOR_NAME_STRING(),__FUNCTION__);         
-
 sensor_write_array_end:
        sensor_task_lock(client,0);
     return err;
@@ -2850,9 +2864,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct i2c_client *client = sd->priv;
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
+#if (ADJUST_OPTIMIZE_TIME_FALG == 0)
        const struct v4l2_queryctrl *qctrl;
+#endif
+    const struct sensor_datafmt *fmt;
     int ret,pid = 0;
     int index  =0 ;
+#if (SENSOR_RESET_REG != SEQUENCE_END)
+    struct reginfo reg_info;
+#endif
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -2868,7 +2888,6 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
                goto sensor_INIT_ERR;
 
 #if (SENSOR_RESET_REG != SEQUENCE_END)
-    struct reginfo reg_info;
        reg_info.reg = SENSOR_RESET_REG;
        reg_info.val = SENSOR_RESET_VAL;
        reg_info.reg_len = SENSOR_RESET_REG_LEN;
@@ -2903,11 +2922,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     }
     
     SENSOR_DG("\n sensor_init_data..%s.\n",SENSOR_NAME_STRING());
-
-  // ret = sensor_write_array(client, sensor_init_data);
     ret =sensor_write_init_data(client, sensor_init_data);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
     }
@@ -2917,7 +2934,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     sensor->info_priv.capture_w = SENSOR_MAX_WIDTH;
     sensor->info_priv.capture_h = SENSOR_MAX_HEIGHT;
     sensor->info_priv.winseqe_cur_addr  = 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  */
 #if ADJUST_OPTIMIZE_TIME_FALG   
@@ -3119,56 +3142,53 @@ 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 soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
-    
-    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
 
-    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)
+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 struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *ret_h)
@@ -3427,35 +3447,32 @@ static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *r
 
 /*modify image with resolution 2592*1944;solve bug that the first 32 pixel data*/
 /*in the first line have misplace with the last 32 pixel data in the last line*/
-static int sensor_cb(struct videobuf_buffer  *vb)
+static int sensor_cb(void *arg)
 {
    void __iomem *vbpmem;
-   struct videobuf_buffer *buffer = vb;
+   struct videobuf_buffer *buffer;
    char *imagey_addr =NULL;
    char *imageuv_addr = NULL;
    char *tempaddr = NULL;
    int  tempsize = 0;
    
-
+   buffer = (struct videobuf_buffer*)arg; 
    if(buffer->width!=SENSOR_MAX_WIDTH||buffer->height!=SENSOR_MAX_HEIGHT||buffer==NULL)
     return -EINVAL;
  
    if (buffer->bsize< YUV420_BUFFER_MAX_SIZE)        //yuv420 format size
     return -EINVAL;
 
+   
    vbpmem = ioremap(buffer->boff,buffer->bsize);
-   if(vbpmem == NULL)
-    {
+   if(vbpmem == NULL) {
       SENSOR_DG("\n%s..%s..ioremap fail\n",__FUNCTION__,SENSOR_NAME_STRING());
       return -ENXIO;
-    }
+   }
      
    imagey_addr = (char*)vbpmem;         // y data  to be dealed with
    imageuv_addr = imagey_addr+buffer->width*buffer->height;
    
- //  SENSOR_DG("\n%s..%s..imagey_addr = 0x%x; imageuv_addr = 0x%x\n",__FUNCTION__,SENSOR_NAME_STRING(),imagey_addr,imageuv_addr);
-//   SENSOR_DG("\n%s..%s..buffer->bsize=%d\n",__FUNCTION__,SENSOR_NAME_STRING(),buffer->bsize);
-
    tempaddr =  imageuv_addr - 32;  
    memcpy(tempaddr,imagey_addr,32);
 
@@ -3473,12 +3490,12 @@ static int sensor_cb(struct videobuf_buffer  *vb)
 }
 
 
-static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
     struct soc_camera_device *icd = client->dev.platform_data;
     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;
     int ret = 0, set_w,set_h,cnt;
     u16 seq_state=0;
@@ -3487,15 +3504,22 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     
     SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -3505,16 +3529,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_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;
 
        winseqe_set_addr = sensor_fmt_catch(set_w, set_h, &set_w, &set_h);
 
@@ -3545,8 +3569,8 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                SENSOR_DG("\n%s..%s..Capture icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
                } else {
                        SENSOR_DG("\n%s..%s..Video icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
-                       sensor->info_priv.preview_w = pix->width;
-                       sensor->info_priv.preview_h = pix->height;
+                       sensor->info_priv.preview_w = mf->width;
+                       sensor->info_priv.preview_h = mf->height;
                }
     }
 
@@ -3578,7 +3602,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING());
                        goto sensor_s_fmt_end;
                }
-                SENSOR_DG("mt9p111 Preview 2 Capture again\n",cnt,seq_state);
+                SENSOR_DG("mt9p111 Preview 2 Capture again\n");
             }
             SENSOR_DG("mt9p111 Preview 2 Capture count = %d;seq_state = 0x%x\n",cnt,seq_state);
          } while((seq_state != 0x07) && (time < 4));
@@ -3616,7 +3640,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                sensor->info_priv.capture_h = set_h;
                sensor->info_priv.snap2preview = true;
        } else if (sensor->info_priv.snap2preview == true) {
-               if (winseqe_set_addr || ((sensor->info_priv.preview_w == pix->width) && (sensor->info_priv.preview_h == pix->height))) {
+               if (winseqe_set_addr || ((sensor->info_priv.preview_w == mf->width) && (sensor->info_priv.preview_h == mf->height))) {
                        ret |= sensor_write_array(client, sensor_Capture2Preview);
                        if (ret != 0) {
                        SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING());
@@ -3641,54 +3665,48 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                 SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
             }
             #endif        
-               sensor->info_priv.preview_w = pix->width;
-               sensor->info_priv.preview_h = pix->height;
+               sensor->info_priv.preview_w = mf->width;
+               sensor->info_priv.preview_h = mf->height;
                sensor->info_priv.snap2preview = false;
                } else {
-                       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);
                }
        }
 
-       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)
 {
-       int ret = 0;
-    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);
-
-       if (sensor_fmt_catch(pix->width, pix->height, &pix->width, &pix->height) == NULL) {
-               pix->width = 0;
-               pix->height = 0;
-       }
-
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    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;
@@ -3913,7 +3931,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);
@@ -3927,29 +3945,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)
     {
@@ -3958,7 +3976,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;
     }
 
@@ -3966,12 +3984,8 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
 }
 #endif
 #if CONFIG_SENSOR_Flash
-static int sensor_set_flash(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);
-       const struct v4l2_queryctrl *qctrl_info;
-    
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
     if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
         if (value == 3) {       /* ddl@rock-chips.com: torch */
             sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
@@ -4545,7 +4559,9 @@ static int sensor_video_probe(struct soc_camera_device *icd,
 {
     int ret,pid = 0;
     struct sensor *sensor = to_sensor(client);
-
+#if (SENSOR_RESET_REG != SEQUENCE_END)
+    struct reginfo reg_info;
+#endif
     /* We must have a parent by now. And it cannot be a wrong one.
      * So this entire test is completely redundant. */
     if (!icd->dev.parent ||
@@ -4558,8 +4574,7 @@ static int sensor_video_probe(struct soc_camera_device *icd,
        }
 
     /* soft reset */
-#if (SENSOR_RESET_REG != SEQUENCE_END)
-    struct reginfo reg_info;
+#if (SENSOR_RESET_REG != SEQUENCE_END)   
        reg_info.reg = SENSOR_RESET_REG;
        reg_info.val = SENSOR_RESET_VAL;
        reg_info.reg_len = SENSOR_RESET_REG_LEN;
@@ -4595,9 +4610,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:
@@ -4609,6 +4621,9 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
        struct i2c_client *client = sd->priv;
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
     int ret = 0;
     
     rk29_camera_sensor_cb_s *icd_cb =NULL;
@@ -4640,12 +4655,11 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
-            int i;
                if (sensor->sensor_gpio_res) {
                 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(&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                      
+                                       memset((char*)(icd->ops->controls+i),0x00,sizeof(struct v4l2_queryctrl));                                       
                                }
                     }
                     sensor->info_priv.flash = 0xff;
@@ -4671,7 +4685,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,
@@ -4681,14 +4703,13 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .g_chip_ident   = sensor_g_chip_ident,
        .ioctl = sensor_ioctl,
 };
-
 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,
        .s_stream   = sensor_s_stream,
 };
-
 static struct v4l2_subdev_ops sensor_subdev_ops = {
        .core   = &sensor_subdev_core_ops,
        .video = &sensor_subdev_video_ops,
@@ -4729,7 +4750,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
index 7f33b67e3ebb63eba00810da2452e1c1b27d99d8..a5776931de848b17719cb71a3cb0159daba0cedc 100755 (executable)
@@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  600
 #define SENSOR_INIT_WINSEQADR sensor_svga
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -89,6 +89,11 @@ 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
 {
     u16 reg;
@@ -1155,16 +1160,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
@@ -1184,7 +1201,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;
 
@@ -1362,6 +1380,7 @@ sensor_write_array_end:
        sensor_task_lock(client,0);
        return err;
 }
+#if CONFIG_SENSOR_I2C_RDWRCHK
 static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
 {
     int cnt;
@@ -1380,6 +1399,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     return 0;
 }
+#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -1430,6 +1450,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -1441,7 +1462,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        }
 
     /* soft reset */
-       sensor_task_lock(client,1);
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
+
     ret = sensor_write(client, 0x3021, 0x61);
     if (ret != 0)
     {
@@ -1487,10 +1510,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1540,9 +1568,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #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;
@@ -1551,17 +1580,18 @@ sensor_INIT_ERR:
 static int sensor_deactivate(struct i2c_client *client)
 {
        struct soc_camera_device *icd = client->dev.platform_data;
-       //u8 reg_val;
-
+    struct sensor *sensor = to_sensor(client);
        SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
        sensor_ioctrl(icd, Sensor_PowerDown, 1);
+    msleep(100); 
 
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
        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;
 }
 
@@ -1629,70 +1659,64 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
-       const struct v4l2_queryctrl *qctrl;
-       struct soc_camera_device *icd = client->dev.platform_data;
-    struct reginfo *winseqe_set_addr=NULL;
-       char readval;
+    struct reginfo *winseqe_set_addr=NULL;     
     int ret=0, set_w,set_h;
-    
-u16    AE_reg, AGC_reg;        
-       u8      temp_reg12,temp_reg13;  
-       u16 shutter,reg_1, reg;         
+    u8 reg_1, reg;     
+       u16 shutter;
        
        //turn on scaler for preivew
        sensor_read(client ,0x3201, &reg_1);    
@@ -1702,6 +1726,8 @@ u16       AE_reg, AGC_reg;
        sensor_write(client, 0x32f1, (reg|0x10) ); 
 
        #if 0  //preview_fastmode
+    u16        AE_reg, AGC_reg;        
+       u8      temp_reg12,temp_reg13
        // turn off AE  for preview
        sensor_read(client ,0x3201, &AE_reg);   
        sensor_write(client, 0x3201, (AE_reg|0x20) );   
@@ -1713,15 +1739,22 @@ u16     AE_reg, AGC_reg;
        sensor_read(client, 0x3013, &temp_reg13);       
        shutter = (temp_reg13 & 0x00FF) | (temp_reg12 << 8);    
        #endif
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1731,16 +1764,16 @@ u16     AE_reg, AGC_reg;
                }
                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_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)
        {
@@ -1789,12 +1822,12 @@ u16     AE_reg, AGC_reg;
         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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1810,7 +1843,7 @@ u16       AE_reg, AGC_reg;
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1873,43 +1906,44 @@ u16     AE_reg, AGC_reg;
         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)
-{
-    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);
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
 /*not support 720p video*/     
-       if(pix->height == 720 && pix->width == 1280){
-               pix->height = 480;
-               pix->width = 640;
+       if(mf->height == 720 && mf->width == 1280){
+               mf->height = 480;
+               mf->width = 640;
        }
-    return 0;
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2140,29 +2174,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)
     {
@@ -2171,7 +2205,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;
     }
 
@@ -2617,11 +2651,11 @@ static int sensor_video_probe(struct soc_camera_device *icd,
 
     /* soft reset */
     ret = sensor_write(client, 0x3021, 0x61);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
-        return -ENODEV;
-    }
+        ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
     mdelay(5);          //delay 5 microseconds
 
     /* check if it is an sensor sensor */
@@ -2651,9 +2685,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:
@@ -2722,6 +2753,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,
@@ -2733,9 +2773,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 = {
@@ -2778,7 +2819,9 @@ 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
index 90978af1a8f2f3708295debb517711aebb41bc1e..f8368ab308eb3d749571fc9db845e35c8bb92c9e 100755 (executable)
@@ -29,7 +29,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//V4L2_PIX_FMT_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       1
@@ -1284,16 +1284,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
@@ -1313,7 +1325,7 @@ 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;
 
 } sensor_info_priv_t;
 
@@ -1557,6 +1569,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -1615,10 +1628,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1757,75 +1774,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct sensor_datafmt *fmt;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1835,16 +1858,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_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)
        {
@@ -1899,12 +1922,12 @@ 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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1920,7 +1943,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1932,7 +1955,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
         #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -1944,7 +1967,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        }
         #endif
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -1973,41 +1996,41 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    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;
@@ -2747,9 +2770,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:
@@ -2762,7 +2782,7 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
        struct i2c_client *client = sd->priv;
     struct soc_camera_device *icd = client->dev.platform_data;  
     struct sensor *sensor = to_sensor(client);
-    int ret = 0,i;
+    int ret = 0;
     
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
@@ -2817,6 +2837,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,
@@ -2828,9 +2857,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 = {
@@ -2873,7 +2903,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
index ec94d6760e682d29e3a1b3966dcca469a2f5f03d..b0b191e5893b6d117f0eeebfb8da0a405628c6e2 100755 (executable)
@@ -53,7 +53,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_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -1402,17 +1402,28 @@ static struct soc_camera_ops sensor_ops =
     .num_controls              = ARRAY_SIZE(sensor_controls),
     .num_menus         = ARRAY_SIZE(sensor_menus),
 };
+/* only one fixed colorspace per pixelcode */
+struct sensor_datafmt {
+       enum v4l2_mbus_pixelcode code;
+       enum v4l2_colorspace colorspace;
+};
 
-#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
-       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
-       .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
@@ -1432,7 +1443,7 @@ 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;
 
@@ -1679,6 +1690,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -1735,10 +1747,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1886,75 +1902,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1964,16 +1986,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_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)
        {
@@ -2028,12 +2050,12 @@ 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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -2049,7 +2071,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -2061,7 +2083,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        if (sensor->info_priv.whiteBalance != 0) {
@@ -2069,7 +2091,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
                        }
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
@@ -2091,41 +2113,41 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    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;
@@ -2865,9 +2887,6 @@ static int sensor_video_probe(struct soc_camera_device *icd,
         ret = -ENODEV;
         goto sensor_video_probe_err;
     }
-
-    icd->formats = sensor_colour_formats;
-    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
     return 0;
 
 sensor_video_probe_err:
@@ -2933,6 +2952,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,
@@ -2942,11 +2970,11 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .g_chip_ident   = sensor_g_chip_ident,
        .ioctl = sensor_ioctl,
 };
-
 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 = {
@@ -2989,7 +3017,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
index 5a45a36de5f6cbafafbfedb3de18ca4f484fea01..28a91011ecc4ee26ecc1366da9945320b06344dc 100755 (executable)
@@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  600
 #define SENSOR_INIT_WINSEQADR sensor_svga
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -434,7 +434,7 @@ static struct reginfo sensor_720p[]=
        {0x5061, 0x7d   },
        {0x5062, 0x7d   },
        {0x5063, 0x69   },
-               {0x0100, 0x01   },
+       {0x0100, 0x01   },
        {0x0000 ,0x00}
 
 };
@@ -1198,8 +1198,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 =
@@ -1214,16 +1218,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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
+
+       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
@@ -1243,7 +1259,7 @@ 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;
 
@@ -1491,6 +1507,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -1548,10 +1565,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1698,75 +1720,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -1776,16 +1804,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_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)
        {
@@ -1846,12 +1874,12 @@ 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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1867,7 +1895,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1879,7 +1907,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        if (sensor->info_priv.whiteBalance != 0) {
@@ -1887,7 +1915,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
                        }
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
@@ -1910,39 +1938,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2173,29 +2202,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)
     {
@@ -2204,7 +2233,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;
     }
 
@@ -2684,9 +2713,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:
@@ -2699,7 +2725,10 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
        struct i2c_client *client = sd->priv;
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
-    int ret = 0,i;
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
     
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
@@ -2753,7 +2782,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,
@@ -2761,15 +2798,15 @@ 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,
+       .ioctl = sensor_ioctl,  
 };
 
 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 = {
        .core   = &sensor_subdev_core_ops,
        .video = &sensor_subdev_video_ops,
@@ -2810,7 +2847,9 @@ 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
index 51f16390be054fba53c68a5f0b44678d8f092233..3c373d9f15862a5d20aaad2ef671d9a496884d9f 100755 (executable)
@@ -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
 #define CONS(a,b) _CONS(a,b)
@@ -53,7 +53,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_init_data
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -1964,18 +1964,29 @@ 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(YUYV), 16, V4L2_PIX_FMT_YUYV),
-       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}    
 };
-
 enum sensor_work_state
 {
        sensor_work_ready = 0,
@@ -2007,7 +2018,7 @@ 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 enable;
        unsigned int funmodule_state;
 } sensor_info_priv_t;
@@ -2581,6 +2592,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;    
     char value;
     int ret,pid = 0;
 
@@ -2639,10 +2651,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -2778,77 +2795,82 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
     const struct v4l2_queryctrl *qctrl;
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
        int isCapture = 0; 
        
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -2858,17 +2880,17 @@ 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_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code);
                }
        }
 
-    set_w = pix->width;
-    set_h = pix->height;
-       isCapture = sensor_fmt_capturechk(sd, f);
+    set_w = mf->width;
+    set_h = mf->height;
+       isCapture = sensor_fmt_capturechk(sd, mf);
        
        if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[isCapture][0].reg)
        {
@@ -2884,7 +2906,6 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     }
     else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[isCapture][0].reg)
     {
-        //printk("===> isCapture: %d!\n", isCapture);
         winseqe_set_addr = sensor_cif[isCapture];
         set_w = 352;
         set_h = 288;
@@ -2930,19 +2951,15 @@ 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)
-    {
-               //srt --if capture,then should write sensor_qxga[1] first
-               
-               if((winseqe_set_addr != sensor_qxga[isCapture]) && isCapture)
-               {
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr){
+               //srt --if capture,then should write sensor_qxga[1] first               
+               if((winseqe_set_addr != sensor_qxga[isCapture]) && isCapture) {
                        SENSOR_DG("%s  write sensor_qxga[1]\n", SENSOR_NAME_STRING());
                        ret = sensor_write_array(client, sensor_qxga[isCapture]);
-                       if (ret != 0)
-                       {
+                       if (ret != 0) {
                            SENSOR_TR("%s  write sensor_qxga[1] failed\n", SENSOR_NAME_STRING());
                            return ret;
                        }
@@ -2958,7 +2975,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                #endif
 
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -2975,7 +2992,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -2985,7 +3002,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
             goto sensor_s_fmt_end;
         } else {
             sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
-            if (sensor_fmt_capturechk(sd,f) == true) {                             /* ddl@rock-chips.com : Capture */
+            if (sensor_fmt_capturechk(sd,mf) == true) {                                    /* ddl@rock-chips.com : Capture */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        if (sensor->info_priv.whiteBalance != 0) {
@@ -2993,7 +3010,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
                        }
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
@@ -3010,45 +3027,42 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
             mdelay(100);  // by FAE.
         }
         SENSOR_DG("\n%s..%s.. icd->width=%d..icd->height=%d..isCapture=%d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h,isCapture);
-    }
-    else
-    {
+    } else {
         SENSOR_TR("\n %s .. Current Format is validate. icd->width=%d..icd->height=%d..isCapture=%d\n",SENSOR_NAME_STRING(),set_w,set_h,isCapture);
     }
-
-    //add by duanyp. Improve the green phenomenon when startup camera every time.
-    //mdelay(500);
-
+    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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -3892,18 +3906,21 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
 {
        struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
-    #if CONFIG_SENSOR_Focus
+       #if CONFIG_SENSOR_Focus
        struct soc_camera_device *icd = client->dev.platform_data;
-       struct v4l2_format fmt;
-    #endif
+       struct v4l2_mbus_framefmt mf;
+       #endif
 
        if (enable == 1) {
                sensor->info_priv.enable = 1;
                #if CONFIG_SENSOR_Focus
-               fmt.fmt.pix.width = icd->user_width;
-               fmt.fmt.pix.height = icd->user_height;
+               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;
                /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */
-               if (sensor_fmt_capturechk(sd, &fmt) == false) {
+               if (sensor_fmt_capturechk(sd, &mf) == false) {
                        if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) {
                                if (sensor->sensor_wq != NULL) {
                                        mutex_lock(&sensor->wq_lock);
@@ -3990,10 +4007,6 @@ static int sensor_video_probe(struct soc_camera_device *icd,
         ret = -ENODEV;
         goto sensor_video_probe_err;
     }
-
-    icd->formats = sensor_colour_formats;
-    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
-
     return 0;
 
 sensor_video_probe_err:
@@ -4059,7 +4072,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,
@@ -4071,9 +4092,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,
        .s_stream   = sensor_s_stream,
 };
 
@@ -4117,7 +4139,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
index 50d140e529a00c935ae973ed7a8ab47633b733fd..1c10f84067e2b974134615f941a15d75cfd725e5 100755 (executable)
@@ -53,8 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  600
 #define SENSOR_INIT_WINSEQADR sensor_svga
-//#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -722,14 +721,21 @@ static struct reginfo sensor_svga[] =
        {0x370c, 0x03},
        {0x3a02, 0x03},
        {0x3a03, 0xd8},
+       {0x3a08 ,0x01},///
+       {0x3a09, 0x27},///
+       {0x3a0a, 0x00},///
+       {0x3a0b, 0xf6},///
        {0x3a0e, 0x03},
        {0x3a0d, 0x04},
        {0x3a14, 0x03},
        {0x3a15, 0xd8},
        {0x4004, 0x02},
+       {0x3002, 0x1c},////
+       {0x4713, 0x03},////
        {0x3035, 0x21},
        {0x3036, 0x46},
        {0x4837, 0x22},
+       {0x3824, 0x02},////
        {0x5001, 0xa3},
        {SEQUENCE_END, 0x00}
 };
@@ -1348,17 +1354,28 @@ static struct soc_camera_ops sensor_ops =
     .num_controls              = ARRAY_SIZE(sensor_controls),
     .num_menus         = ARRAY_SIZE(sensor_menus),
 };
+/* only one fixed colorspace per pixelcode */
+struct sensor_datafmt {
+       enum v4l2_mbus_pixelcode code;
+       enum v4l2_colorspace colorspace;
+};
 
-#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
-       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
-       .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}    
 };
 enum sensor_work_state
 {
@@ -1391,7 +1408,7 @@ typedef struct sensor_info_priv_s
     unsigned char mirror;                                        /* HFLIP */
     unsigned char flip;                                          /* VFLIP */
     struct reginfo *winseqe_cur_addr;
-       unsigned int pixfmt;
+       struct sensor_datafmt fmt;
        unsigned int enable;
        unsigned int funmodule_state;
 } sensor_info_priv_t;
@@ -2193,6 +2210,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -2249,10 +2267,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        sensor_task_lock(client,0);
-    //icd->user_width = SENSOR_INIT_WIDTH;
-    //icd->user_height = SENSOR_INIT_HEIGHT;
     sensor->info_priv.winseqe_cur_addr  = 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);
@@ -2392,74 +2414,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret = 0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -2469,16 +2498,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_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!=SEQUENCE_END))
        {
@@ -2557,12 +2586,12 @@ 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 (winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
     {
-               if (sensor_fmt_capturechk(sd,f) == true) {                                      /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                     /* ddl@rock-chips.com : Capture */
                        sensor_parameter_record(client);
                /*#if CONFIG_SENSOR_Focus
                        sensor_af_idlechk(client);
@@ -2594,7 +2623,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -2605,7 +2634,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         }
         sensor->info_priv.winseqe_cur_addr  = winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
                        sensor_ae_transfer(client);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -2614,7 +2643,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
                        }
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
 
@@ -2636,38 +2665,39 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2945,8 +2975,10 @@ static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct
        int ret = 0;
 
        qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
-       if (!qctrl_info)
-               return -EINVAL;
+       if (!qctrl_info) {
+               ret = -EINVAL;
+        goto sensor_set_focus_absolute_end;
+       }
 
        if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) {
                if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) {                 
@@ -2972,8 +3004,10 @@ static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct
        int ret = 0;
 
        qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE);
-       if (!qctrl_info)
-               return -EINVAL;
+       if (!qctrl_info) {
+               ret = -EINVAL;
+        goto sensor_set_focus_relative_end;
+       }
 
        if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) {
                if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) {                 
@@ -3476,16 +3510,19 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
     struct sensor *sensor = to_sensor(client);
        #if CONFIG_SENSOR_Focus
        struct soc_camera_device *icd = client->dev.platform_data;
-       struct v4l2_format fmt;
+       struct v4l2_mbus_framefmt mf;
        #endif
     
        if (enable == 1) {
                sensor->info_priv.enable = 1;
                #if CONFIG_SENSOR_Focus
-               fmt.fmt.pix.width = icd->user_width;
-               fmt.fmt.pix.height = icd->user_height;
+               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;
                /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */
-               if (sensor_fmt_capturechk(sd, &fmt) == false) {
+               if (sensor_fmt_capturechk(sd, &mf) == false) {
                        if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) {
                                if (sensor->sensor_wq != NULL) {
                                        mutex_lock(&sensor->wq_lock);
@@ -3573,9 +3610,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:
@@ -3642,7 +3676,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,
@@ -3654,9 +3696,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,
        .s_stream   = sensor_s_stream,
 };
 
@@ -3700,7 +3743,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
index 65cc68ad764265d84acaf41e653d50b4ea0e4762..134a1598e97be307832a1c7e0e6b5ca3b68a89d8 100755 (executable)
@@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
 #define SENSOR_INIT_HEIGHT  600
 #define SENSOR_INIT_WINSEQADR sensor_svga
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -3261,8 +3261,8 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
 static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
 static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
 static int sensor_deactivate(struct i2c_client *client);
-static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f);
-static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f);
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);
 
 static struct soc_camera_ops sensor_ops =
 {
@@ -3276,17 +3276,30 @@ 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}    
 };
+
 enum sensor_work_state
 {
        sensor_work_ready = 0,
@@ -3318,7 +3331,7 @@ typedef struct sensor_info_priv_s
        bool snap2preview;
        bool video2preview;
     struct reginfo *winseqe_cur_addr;
-       unsigned int pixfmt;
+       struct sensor_datafmt fmt;
        unsigned int enable;
        unsigned int funmodule_state;
 } sensor_info_priv_t;
@@ -3825,7 +3838,7 @@ static int sensor_af_wq_function(struct i2c_client *client)
        struct af_cmdinfo cmdinfo;
        int ret=0, focus_pos = 0xfe;
     struct soc_camera_device *icd = client->dev.platform_data;
-    struct v4l2_format fmt;
+    struct v4l2_mbus_framefmt mf;
                
        SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__);
 
@@ -3836,9 +3849,12 @@ static int sensor_af_wq_function(struct i2c_client *client)
        } else {
                sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK;
         
-        fmt.fmt.pix.width = icd->user_width;
-               fmt.fmt.pix.height = icd->user_height;
-        if (sensor_fmt_videochk(NULL, &fmt) == true) {    /* ddl@rock-chips.com: focus mode fix const auto focus in video */
+        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;
+        if (sensor_fmt_videochk(NULL, &mf) == true) {    /* ddl@rock-chips.com: focus mode fix const auto focus in video */
             ret = sensor_af_const(client);
         } else {
                switch (sensor->info_priv.auto_focus)
@@ -4091,6 +4107,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     char value;
     int ret,pid = 0;
 
@@ -4141,16 +4158,19 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     }
 
     ret = sensor_write_array(client, sensor_init_data);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
     }
        sensor_task_lock(client,0);
-    //icd->user_width = SENSOR_INIT_WIDTH;
-    //icd->user_height = SENSOR_INIT_HEIGHT;
     sensor->info_priv.winseqe_cur_addr  = 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);
@@ -4288,76 +4308,81 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
+    const struct sensor_datafmt *fmt;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
     int ret = 0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -4367,16 +4392,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_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)
        {
@@ -4455,12 +4480,12 @@ 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 (winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
     {
-               if (sensor_fmt_capturechk(sd,f) == true) {                                      /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                     /* ddl@rock-chips.com : Capture */
                        sensor_parameter_record(client);
         #if CONFIG_SENSOR_Flash
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
@@ -4489,7 +4514,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -4501,7 +4526,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
                        sensor_ae_transfer(client);
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -4521,7 +4546,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
             }
            #endif
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
             #if CONFIG_SENSOR_Focus
@@ -4562,38 +4587,39 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -5444,16 +5470,21 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
 {
        struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
+    #if CONFIG_SENSOR_Focus
        struct soc_camera_device *icd = client->dev.platform_data;
-       struct v4l2_format fmt;
+       struct v4l2_mbus_framefmt mf;
+    #endif
 
        if (enable == 1) {
                sensor->info_priv.enable = 1;
                #if CONFIG_SENSOR_Focus
-               fmt.fmt.pix.width = icd->user_width;
-               fmt.fmt.pix.height = icd->user_height;
+        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;
                /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */
-               if (sensor_fmt_capturechk(sd, &fmt) == false) {
+               if (sensor_fmt_capturechk(sd, &mf) == false) {
                        if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) {
                                if (sensor->sensor_wq != NULL) {
                                        mutex_lock(&sensor->wq_lock);
@@ -5541,9 +5572,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:
@@ -5612,7 +5640,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,
@@ -5624,12 +5660,12 @@ 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,
        .s_stream   = sensor_s_stream,
 };
-
 static struct v4l2_subdev_ops sensor_subdev_ops = {
        .core   = &sensor_subdev_core_ops,
        .video = &sensor_subdev_video_ops,
@@ -5670,7 +5706,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
index 8417928571eed07c84cf733045820b607b6dd22f..7453d6d97499b06e51388b9c1d30a25e5c9f9784 100755 (executable)
@@ -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
@@ -144,7 +144,7 @@ static struct reginfo sensor_init_data[] =
        {0x0e, 0x61},
        {0x0f, 0x4b},
        {0x16, 0x02},
-       {0x1e, 0x07},       //0x27
+       {0x1e, 0x17},       //0x07//0x27
        {0x21, 0x02},
        {0x22, 0x91},
        {0x29, 0x07},
@@ -181,22 +181,22 @@ static struct reginfo sensor_init_data[] =
        {0x66, 0x05},
        {0x94, 0x10},
        {0x95, 0x12},
-       {0x7a, 0x24},
-       {0x7b, 0x04},
-       {0x7c, 0x07},
-       {0x7d, 0x12},
-       {0x7e, 0x2f},
-       {0x7f, 0x3f},
-       {0x80, 0x4d},
-       {0x81, 0x5a},
-       {0x82, 0x69},
-       {0x83, 0x74},
-       {0x84, 0x7f},
-       {0x85, 0x91},
-       {0x86, 0x9e},
-       {0x87, 0xbb},
-       {0x88, 0xd2},
-       {0x89, 0xe5},
+       {0x7a, 0x20},// {0x7a, 0x24}, 
+       {0x7b, 0x16},// {0x7b, 0x04}, 
+       {0x7c, 0x23},// {0x7c, 0x07}, 
+       {0x7d, 0x3c},// {0x7d, 0x12}, 
+       {0x7e, 0x5c},// {0x7e, 0x2f}, 
+       {0x7f, 0x69},// {0x7f, 0x3f}, 
+       {0x80, 0x75},// {0x80, 0x4d}, 
+       {0x81, 0x7e},// {0x81, 0x5a}, 
+       {0x82, 0x88},// {0x82, 0x69}, 
+       {0x83, 0x8f},// {0x83, 0x74}, 
+       {0x84, 0x96},// {0x84, 0x7f}, 
+       {0x85, 0xa3},// {0x85, 0x91}, 
+       {0x86, 0xaf},// {0x86, 0x9e}, 
+       {0x87, 0xc4},// {0x87, 0xbb}, 
+       {0x88, 0xd7},// {0x88, 0xd2}, 
+       {0x89, 0xe8},// {0x89, 0xe5}, 
        {0x43, 0x0a},
        {0x44, 0xf0},
        {0x45, 0x34},
@@ -228,7 +228,7 @@ static struct reginfo sensor_init_data[] =
        {0x75, 0x63},
        {0x76, 0xe1},
        {0x4c, 0x00},
-       {0x77, 0x01},
+       {0x77, 0x04},//0x01
        {0x4b, 0x09},
        {0xc9, 0x60},
        {0x41, 0x38},
@@ -1103,16 +1103,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
@@ -1132,7 +1144,7 @@ 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;
 
 } sensor_info_priv_t;
 
@@ -1214,7 +1226,7 @@ static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
 
     while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
         err = i2c_transfer(client->adapter, msg, 1);
-
+                               udelay(50);
         if (err >= 0) {
             return 0;
         } else {
@@ -1230,13 +1242,10 @@ static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
 static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
 {
     int err,cnt;
-    //u8 buf[2];
     u8 buf[1];
     struct i2c_msg msg[2];
-
-    //buf[0] = reg >> 8;
+   
     buf[0] = reg;
-    buf[1] = reg & 0xFF;
 
     msg[0].addr = client->addr;
     msg[0].flags = client->flags;
@@ -1270,7 +1279,6 @@ static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
 }
 
 /* write a array of registers  */
-#if 1
 static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
 {
     int err = 0, cnt;
@@ -1311,27 +1319,24 @@ sensor_write_array_end:
        sensor_task_lock(client,0);
        return err;
 }
-#else
-static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
 {
-    int err;
+    int cnt;
     int i = 0;
-       u8 val_read;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
     while (regarray[i].reg != 0)
     {
-        err = sensor_write(client, regarray[i].reg, regarray[i].val);
-        if (err != 0)
-        {
-            SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i);
-            return err;
-        }
-               err = sensor_read(client, regarray[i].reg, &val_read);
-               SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val);
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
         i++;
     }
     return 0;
 }
-#endif
 static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -1343,10 +1348,12 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
                case Sensor_PowerDown:
                {
                        if (icl->powerdown) {
+                               if (on == 0)
+                                       mdelay(1);
                                ret = icl->powerdown(icd->pdev, on);
                                if (ret == RK29_CAM_IO_SUCCESS) {
                                        if (on == 0) {
-                                               mdelay(2);
+                                               mdelay(20);
                                                if (icl->reset)
                                                        icl->reset(icd->pdev);
                                        }
@@ -1382,6 +1389,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
@@ -1411,10 +1419,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        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);
@@ -1548,71 +1560,77 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct sensor_datafmt *fmt;
        const struct v4l2_queryctrl *qctrl;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
        char readval;
     int ret=0, set_w,set_h;
+    
+       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.pixfmt != pix->pixelformat) {
-               switch (pix->pixelformat)
+       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;
                                sensor_read(client, 0x3a, &readval);
@@ -1621,7 +1639,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                                sensor_write(client,0x3d,readval&0xfe);
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                //winseqe_set_addr = sensor_ClrFmt_UYVY;
                                sensor_read(client, 0x3a, &readval);
@@ -1635,16 +1653,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_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)
        {
@@ -1678,7 +1696,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     }
     else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
     {
-        winseqe_set_addr = sensor_sxga;
+               winseqe_set_addr = sensor_vga; //sensor_sxga;
         set_w = 1280;
         set_h = 1024;
     }
@@ -1687,12 +1705,12 @@ 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) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -1708,7 +1726,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -1720,7 +1738,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */
         #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -1732,7 +1750,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        }
         #endif
                        sensor->info_priv.snap2preview = true;
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */
                #if CONFIG_SENSOR_Effect
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
@@ -1762,39 +1780,40 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }
 
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
@@ -2144,10 +2163,9 @@ 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;
+    struct soc_camera_device *icd = client->dev.platform_data;    
     const struct v4l2_queryctrl *qctrl;
-
-
+    
     qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
 
     if (!qctrl)
@@ -2525,9 +2543,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:
@@ -2597,6 +2612,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,
@@ -2608,9 +2632,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 = {
@@ -2653,7 +2678,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
index f1e3350ca374b5fadd3a6d33839dcc465452b071..89a0ac76f93a7ce1885cfb624a3379443e3c4545 100755 (executable)
@@ -36,6 +36,7 @@
 #include <media/v4l2-dev.h>
 #include <media/videobuf-dma-contig.h>
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 #include <mach/rk29-ipp.h>
 
 
@@ -47,7 +48,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
        printk(KERN_WARNING"rk29xx_camera: " fmt , ## arg); } while (0)
 
 #define RK29CAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define RK29CAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
+#define RK29CAMERA_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
 
 // VIP Reg Offset
 #define RK29_VIP_AHBR_CTRL                0x00
@@ -130,7 +131,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CAM_IPPWORK_IS_EN()     ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))                                  
 
 //Configure Macro
-#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 2)
+#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 2)
 
 /* limit to rk29 hardware capabilities */
 #define RK29_CAM_BUS_PARAM   (SOCAM_MASTER |\
@@ -158,21 +159,13 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 
 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
-extern void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
-            struct videobuf_queue_ops *ops,
-            struct device *dev,
-            spinlock_t *irqlock,
-            enum v4l2_buf_type type,
-            enum v4l2_field field,
-            unsigned int msize,
-            void *priv);
 
 /* buffer for one video frame */
 struct rk29_buffer
 {
     /* common v4l buffer stuff -- must be first */
     struct videobuf_buffer vb;
-    const struct soc_camera_data_format        *fmt;
+    enum v4l2_mbus_pixelcode   code;
     int                        inwork;
 };
 enum rk29_camera_reg_state
@@ -265,18 +258,18 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
     struct soc_camera_device *icd = vq->priv_data;
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
     struct rk29_camera_dev *pcdev = ici->priv;
+    int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+                                               icd->current_fmt->host_fmt);
 
     dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
 
+       if (bytes_per_line < 0)
+               return bytes_per_line;
+
        /* planar capture requires Y, U and V buffers to be page aligned */
-       #if 0
-    int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
-    *size = PAGE_ALIGN(icd->user_width* icd->user_height * bytes_per_pixel);                               /* Y pages UV pages, yuv422*/
-       pcdev->vipmem_bsize = PAGE_ALIGN(pcdev->host_width * pcdev->host_height * bytes_per_pixel);
-       #else
-       *size = PAGE_ALIGN((icd->user_width* icd->user_height * icd->current_fmt->depth + 7)>>3);                               /* Y pages UV pages, yuv422*/
-       pcdev->vipmem_bsize = PAGE_ALIGN((pcdev->host_width * pcdev->host_height * icd->current_fmt->depth + 7)>>3);
-       #endif
+       *size = PAGE_ALIGN(bytes_per_line*icd->user_height);       /* Y pages UV pages, yuv422*/
+       pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line * pcdev->host_height);
+
 
        if (CAM_WORKQUEUE_IS_EN()) {
         if (CAM_IPPWORK_IS_EN()) {
@@ -328,6 +321,10 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff
     struct soc_camera_device *icd = vq->priv_data;
     struct rk29_buffer *buf;
     int ret;
+    int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+                                               icd->current_fmt->host_fmt);
+       if (bytes_per_line < 0)
+               return bytes_per_line;
 
     buf = container_of(vb, struct rk29_buffer, vb);
 
@@ -345,18 +342,18 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff
 
     BUG_ON(NULL == icd->current_fmt);
 
-    if (buf->fmt    != icd->current_fmt ||
+    if (buf->code    != icd->current_fmt->code ||
             vb->width   != icd->user_width ||
             vb->height  != icd->user_height ||
              vb->field   != field) {
-        buf->fmt    = icd->current_fmt;
+        buf->code    = icd->current_fmt->code;
         vb->width   = icd->user_width;
         vb->height  = icd->user_height;
         vb->field   = field;
         vb->state   = VIDEOBUF_NEEDS_INIT;
     }
 
-    vb->size = (((vb->width * vb->height *buf->fmt->depth) + 7) >> 3) ;          /* ddl@rock-chips.com : fmt->depth is coorect */
+    vb->size = bytes_per_line*vb->height;          /* ddl@rock-chips.com : fmt->depth is coorect */
     if (0 != vb->baddr && vb->bsize < vb->size) {
         ret = -EINVAL;
         goto out;
@@ -827,16 +824,38 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd)
 
        return;
 }
-
 static int rk29_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 {
     unsigned long bus_flags, camera_flags, common_flags;
     unsigned int vip_ctrl_val = 0;
-    int ret = 0;
+       const struct soc_mbus_pixelfmt *fmt;
+       int ret = 0;
 
     RK29CAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
 
+       fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
+       if (!fmt)
+               return -EINVAL;
+
     bus_flags = RK29_CAM_BUS_PARAM;
+       /* If requested data width is supported by the platform, use it */
+       switch (fmt->bits_per_sample) {
+       case 10:
+               if (!(bus_flags & SOCAM_DATAWIDTH_10))
+                       return -EINVAL;                 
+               break;
+       case 9:
+               if (!(bus_flags & SOCAM_DATAWIDTH_9))
+                       return -EINVAL;                 
+               break;
+       case 8:
+               if (!(bus_flags & SOCAM_DATAWIDTH_8))
+                       return -EINVAL;                 
+               break;
+       default:
+               return -EINVAL;
+       }
+    
        if (icd->ops->query_bus_param)
        camera_flags = icd->ops->query_bus_param(icd);
        else
@@ -852,12 +871,6 @@ static int rk29_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt
     if (ret < 0)
         goto RK29_CAMERA_SET_BUS_PARAM_END;
 
-       if (common_flags & SOCAM_DATAWIDTH_8) {
-        icd->buswidth = 8;
-       } else if (common_flags & SOCAM_DATAWIDTH_10) {
-           icd->buswidth = 10;
-       }
-
     vip_ctrl_val = read_vip_reg(RK29_VIP_CTRL);
     if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
         vip_ctrl_val |= NEGATIVE_EDGE;
@@ -907,36 +920,36 @@ static int rk29_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt
                         camera_flags, bus_flags);
     return ret;
 }
-static const struct soc_camera_data_format rk29_camera_formats[] = {
-       {
-               .name           = "YUV420 NV12",
-               .depth          = 12,
-               .fourcc         = V4L2_PIX_FMT_NV12,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
+
+static const struct soc_mbus_pixelfmt rk29_camera_formats[] = {
+   {
+               .fourcc                 = V4L2_PIX_FMT_NV12,
+               .name                   = "YUV420 NV12",
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_2X8_PADHI,
+               .order                  = SOC_MBUS_ORDER_LE,
        },{
-               .name           = "YUV422 NV16",
-               .depth          = 16,
-               .fourcc         = V4L2_PIX_FMT_NV16,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
+               .fourcc                 = V4L2_PIX_FMT_NV16,
+               .name                   = "YUV422 NV16",
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_2X8_PADHI,
+               .order                  = SOC_MBUS_ORDER_LE,
        },{
-               .name           = "NV12(v0.0.1)",           /* ddl@rock-chips.com: 0.0.1 driver */
-               .depth          = 12,
-               .fourcc         = V4L2_PIX_FMT_YUV420,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
+               .fourcc                 = V4L2_PIX_FMT_YUV420,
+               .name                   = "NV12(v0.0.1)",
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_2X8_PADHI,
+               .order                  = SOC_MBUS_ORDER_LE,
        },{
-               .name           = "NV16(v0.0.1)",
-               .depth          = 16,
-               .fourcc         = V4L2_PIX_FMT_YUV422P,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
-       },{ 
-               .name           = "Raw Bayer RGB 10 bit",
-               .depth          = 16,
-               .fourcc         = V4L2_PIX_FMT_SGRBG10,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fourcc                 = V4L2_PIX_FMT_YUV422P,
+               .name                   = "NV16(v0.0.1)",
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_2X8_PADHI,
+               .order                  = SOC_MBUS_ORDER_LE,
        }
 };
 
-static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, __u32 cam_pixfmt, struct v4l2_rect *rect)
+static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
     struct rk29_camera_dev *pcdev = ici->priv;
@@ -958,22 +971,17 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p
                                pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
                        pcdev->pixfmt = host_pixfmt;
             break;
-               case V4L2_PIX_FMT_SGRBG10:
-                       vip_ctrl_val |= (VIP_RAW | VIP_SENSOR | VIP_DATA_LITTLEEND);
-                       pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC;
-                       pcdev->pixfmt = host_pixfmt;
-                       break;
         default:                                                                                /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */
             vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & VIPREGYUV422);
             break;
     }
 
-    switch (cam_pixfmt)
+    switch (icd_code)
     {
-        case V4L2_PIX_FMT_UYVY:
+        case V4L2_MBUS_FMT_UYVY8_2X8:
             vip_ctrl_val |= SENSOR_UYVY;
             break;
-        case V4L2_PIX_FMT_YUYV:
+        case V4L2_MBUS_FMT_YUYV8_2X8:
             vip_ctrl_val |= SENSOR_YUYV;
             break;
         default :
@@ -1007,74 +1015,66 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p
 static int rk29_camera_get_formats(struct soc_camera_device *icd, int idx,
                                  struct soc_camera_format_xlate *xlate)
 {
+    struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
     struct device *dev = icd->dev.parent;
-    int formats = 0, buswidth, ret;
-
-    buswidth = 8;
+    int formats = 0, ret;
+       enum v4l2_mbus_pixelcode code;
+       const struct soc_mbus_pixelfmt *fmt;
+
+       ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
+       if (ret < 0)
+               /* No more formats */
+               return 0;
+
+       fmt = soc_mbus_get_fmtdesc(code);
+       if (!fmt) {
+               dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
+               return 0;
+       }
 
-    ret = rk29_camera_try_bus_param(icd, buswidth);
+    ret = rk29_camera_try_bus_param(icd, fmt->bits_per_sample);
     if (ret < 0)
         return 0;
 
-    switch (icd->formats[idx].fourcc) {
-        case V4L2_PIX_FMT_UYVY:
-        case V4L2_PIX_FMT_YUYV:
+    switch (code) {
+        case V4L2_MBUS_FMT_UYVY8_2X8:
+        case V4L2_MBUS_FMT_YUYV8_2X8:
             formats++;
             if (xlate) {
                 xlate->host_fmt = &rk29_camera_formats[0];
-                xlate->cam_fmt = icd->formats + idx;
-                xlate->buswidth = buswidth;
+                xlate->code    = code;
                 xlate++;
-                dev_dbg(dev, "Providing format %s using %s\n",
-                       rk29_camera_formats[0].name,
-                       icd->formats[idx].name);
+                dev_dbg(dev, "Providing format %s using code %d\n",
+                       rk29_camera_formats[0].name,code);
             }
 
             formats++;
             if (xlate) {
                 xlate->host_fmt = &rk29_camera_formats[1];
-                xlate->cam_fmt = icd->formats + idx;
-                xlate->buswidth = buswidth;
+                xlate->code    = code;
                 xlate++;
-                dev_dbg(dev, "Providing format %s using %s\n",
-                       rk29_camera_formats[1].name,
-                       icd->formats[idx].name);
+                dev_dbg(dev, "Providing format %s using code %d\n",
+                       rk29_camera_formats[1].name,code);
             }
 
             formats++;
             if (xlate) {
                 xlate->host_fmt = &rk29_camera_formats[2];
-                xlate->cam_fmt = icd->formats + idx;
-                xlate->buswidth = buswidth;
+                xlate->code    = code;
                 xlate++;
-                dev_dbg(dev, "Providing format %s using %s\n",
-                       rk29_camera_formats[2].name,
-                       icd->formats[idx].name);
+                dev_dbg(dev, "Providing format %s using code %d\n",
+                       rk29_camera_formats[2].name,code);
             } 
 
             formats++;
             if (xlate) {
                 xlate->host_fmt = &rk29_camera_formats[3];
-                xlate->cam_fmt = icd->formats + idx;
-                xlate->buswidth = buswidth;
+                xlate->code    = code;
                 xlate++;
-                dev_dbg(dev, "Providing format %s using %s\n",
-                       rk29_camera_formats[3].name,
-                       icd->formats[idx].name);
+                dev_dbg(dev, "Providing format %s using code %d\n",
+                       rk29_camera_formats[3].name,code);;
             }
-                       break;
-               case V4L2_PIX_FMT_SGRBG10:
-                       formats++;
-            if (xlate) {
-                xlate->host_fmt = &rk29_camera_formats[4];
-                xlate->cam_fmt = icd->formats + idx;
-                xlate->buswidth = 10;
-                xlate++;
-                dev_dbg(dev, "Providing format %s using %s\n",
-                       rk29_camera_formats[2].name,
-                       icd->formats[idx].name);
-            }
-                       break;
+                       break;          
         default:
             break;
     }
@@ -1091,34 +1091,32 @@ static int rk29_camera_set_crop(struct soc_camera_device *icd,
                               struct v4l2_crop *a)
 {
     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-    struct v4l2_format f;
-    struct v4l2_pix_format *pix = &f.fmt.pix;
+       struct v4l2_mbus_framefmt mf;
+       u32 fourcc = icd->current_fmt->host_fmt->fourcc;
     int ret;
 
-    f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+    ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
     if (ret < 0)
         return ret;
 
-    if ((pix->width < (a->c.left + a->c.width)) || (pix->height < (a->c.top + a->c.height)))  {
+    if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height)))  {
 
-        pix->width = a->c.left + a->c.width;
-        pix->height = a->c.top + a->c.height;
+        mf.width = a->c.left + a->c.width;
+        mf.height = a->c.top + a->c.height;
 
-        v4l_bound_align_image(&pix->width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1,
-            &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
-            icd->current_fmt->fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
+        v4l_bound_align_image(&mf.width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1,
+            &mf.height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
+            fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
 
-        ret = v4l2_subdev_call(sd, video, s_fmt, &f);
+        ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
         if (ret < 0)
             return ret;
     }
 
-    rk29_camera_setup_format(icd, icd->current_fmt->fourcc, pix->pixelformat, &a->c);
+    rk29_camera_setup_format(icd, fourcc, mf.code, &a->c);
 
-    icd->user_width = pix->width;
-    icd->user_height = pix->height;
+    icd->user_width = mf.width;
+    icd->user_height = mf.height;
 
     return 0;
 }
@@ -1128,12 +1126,11 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
 {
     struct device *dev = icd->dev.parent;
     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-    const struct soc_camera_data_format *cam_fmt = NULL;
     const struct soc_camera_format_xlate *xlate = NULL;
        struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
     struct rk29_camera_dev *pcdev = ici->priv;
     struct v4l2_pix_format *pix = &f->fmt.pix;
-    struct v4l2_format cam_f = *f;
+    struct v4l2_mbus_framefmt mf;
     struct v4l2_rect rect;
     int ret,usr_w,usr_h;
     int stream_on = 0;
@@ -1148,8 +1145,7 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
         ret = -EINVAL;
         goto RK29_CAMERA_SET_FMT_END;
     }
-
-    cam_fmt = xlate->cam_fmt;
+    
     /* ddl@rock-chips.com: sensor init code transmit in here after open */
     if (pcdev->icd_init == 0) {
         v4l2_subdev_call(sd,core, init, 0);        
@@ -1159,14 +1155,22 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
     stream_on = read_vip_reg(RK29_VIP_CTRL);
     if (stream_on & ENABLE_CAPTURE)
         write_vip_reg(RK29_VIP_CTRL, (stream_on & (~ENABLE_CAPTURE)));
-    cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
-    ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
-    cam_f.fmt.pix.pixelformat = pix->pixelformat;
-    *pix = cam_f.fmt.pix;
+    
+       mf.width        = pix->width;
+       mf.height       = pix->height;
+       mf.field        = pix->field;
+       mf.colorspace   = pix->colorspace;
+       mf.code         = xlate->code;
+
+       ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+
+       if (mf.code != xlate->code)
+               return -EINVAL;
+
        #ifdef CONFIG_VIDEO_RK29_WORK_IPP
-       if ((pix->width != usr_w) || (pix->height != usr_h)) {
-        if (unlikely((pix->width <16) || (pix->width > 8190) || (pix->height < 16) || (pix->height > 8190))) {
-               RK29CAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",pix->width,pix->height);
+       if ((mf.width != usr_w) || (mf.height != usr_h)) {
+        if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
+               RK29CAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
                ret = -EINVAL;
                goto RK29_CAMERA_SET_FMT_END;
        }       
@@ -1175,8 +1179,8 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
                ret = -EINVAL;
             goto RK29_CAMERA_SET_FMT_END;
        }
-               pix->width = usr_w;
-               pix->height = usr_h;
+               mf.width = usr_w;
+               mf.height = usr_h;
        }
        #endif
     icd->sense = NULL;
@@ -1184,18 +1188,22 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
     if (!ret) {
         rect.left = 0;
         rect.top = 0;
-        rect.width = cam_f.fmt.pix.width;
-        rect.height = cam_f.fmt.pix.height;
-
-        RK29CAMERA_DG("%s..%s..%s icd width:%d  host width:%d \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name,
-                                  rect.width, pix->width);
-        rk29_camera_setup_format(icd, pix->pixelformat, cam_fmt->fourcc, &rect);
-        icd->buswidth = xlate->buswidth;
-        icd->current_fmt = xlate->host_fmt;
+        rect.width = mf.width;
+        rect.height = mf.height;
 
+        RK29CAMERA_DG("%s..%s..v4l2_mbus_code:%d  icd:%dx%d  host:%dx%d \n",__FUNCTION__,xlate->host_fmt->name, mf.code,
+                                  rect.width,rect.height, pix->width,pix->height);
+        rk29_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); 
+        
                if (CAM_IPPWORK_IS_EN()) {
                        BUG_ON(pcdev->vipmem_phybase == 0);
                }
+
+        pix->width = mf.width;
+       pix->height = mf.height;
+       pix->field = mf.field;
+       pix->colorspace = mf.colorspace;
+       icd->current_fmt = xlate;        
     }
 
 RK29_CAMERA_SET_FMT_END:
@@ -1234,10 +1242,10 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
     const struct soc_camera_format_xlate *xlate;
     struct v4l2_pix_format *pix = &f->fmt.pix;
     __u32 pixfmt = pix->pixelformat;
-    enum v4l2_field field;
     int ret,usr_w,usr_h,i;
        bool is_capture = rk29_camera_fmt_capturechk(f);
        bool vipmem_is_overflow = false;
+    struct v4l2_mbus_framefmt mf;
 
        usr_w = pix->width;
        usr_h = pix->height;
@@ -1245,7 +1253,7 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
 
     xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
     if (!xlate) {
-        dev_err(ici->v4l2_dev.dev, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
+        dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
                        (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
         ret = -EINVAL;
         RK29CAMERA_TR("%s(version:%c%c%c) support format:\n",rk29_cam_driver_description,(RK29_CAM_VERSION_CODE&0xff0000)>>16,
@@ -1262,21 +1270,29 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
              &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0,
              pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0);
 
-    pix->bytesperline = pix->width * DIV_ROUND_UP(xlate->host_fmt->depth, 8);
-    pix->sizeimage = pix->height * pix->bytesperline;
+    pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
+                                                   xlate->host_fmt);
+       if (pix->bytesperline < 0)
+               return pix->bytesperline;
 
-    /* camera has to see its format, but the user the original one */
-    pix->pixelformat = xlate->cam_fmt->fourcc;
     /* limit to sensor capabilities */
-    ret = v4l2_subdev_call(sd, video, try_fmt, f);
-    pix->pixelformat = pixfmt;
+       mf.width        = pix->width;
+       mf.height       = pix->height;
+       mf.field        = pix->field;
+       mf.colorspace   = pix->colorspace;
+       mf.code         = xlate->code;
+
+       ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+       if (ret < 0)
+               goto RK29_CAMERA_TRY_FMT_END;
+    
        #ifdef CONFIG_VIDEO_RK29_WORK_IPP       
-       if ((pix->width > usr_w) && (pix->height > usr_h)) {
+       if ((mf.width > usr_w) && (mf.height > usr_h)) {
                if (is_capture) {
-                       vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size);
+                       vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
                } else {
                        /* Assume preview buffer minimum is 4 */
-                       vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size);
+                       vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
                }
                if (vipmem_is_overflow == false) {
                        pix->width = usr_w;
@@ -1284,12 +1300,12 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
                } else {
                        RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",pix->width,pix->height,usr_w,usr_h);
                }
-       } else if ((pix->width < usr_w) && (pix->height < usr_h)) {
-               if (((usr_w>>1) < pix->width) && ((usr_h>>1) < pix->height)) {
+       } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
+               if (((usr_w>>1) < mf.width) && ((usr_h>>1) < mf.height)) {
                        if (is_capture) {
-                               vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size);
+                               vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
                        } else {
-                               vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size);
+                               vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
                        }
                        if (vipmem_is_overflow == false) {
                                pix->width = usr_w;
@@ -1301,17 +1317,23 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
                        RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",pix->width,pix->height,usr_w,usr_h);
                }
        }
-       #endif
-
-    field = pix->field;
-
-    if (field == V4L2_FIELD_ANY) {
-        pix->field = V4L2_FIELD_NONE;
-    } else if (field != V4L2_FIELD_NONE) {
-        dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
-        ret = -EINVAL;
-        goto RK29_CAMERA_TRY_FMT_END;
-    }
+       #else
+    pix->width = mf.width;
+       pix->height     = mf.height;    
+    #endif
+    pix->colorspace    = mf.colorspace;    
+
+    switch (mf.field) {
+       case V4L2_FIELD_ANY:
+       case V4L2_FIELD_NONE:
+               pix->field      = V4L2_FIELD_NONE;
+               break;
+       default:
+               /* TODO: support interlaced at least in pass-through mode */
+               dev_err(icd->dev.parent, "Field type %d unsupported.\n",
+                       mf.field);
+               goto RK29_CAMERA_TRY_FMT_END;
+       }
 
 RK29_CAMERA_TRY_FMT_END:
        if (ret)
@@ -1446,7 +1468,7 @@ static void rk29_camera_reinit_work(struct work_struct *work)
 {
        struct device *control;
     struct v4l2_subdev *sd;
-       struct v4l2_format cam_f;
+       struct v4l2_mbus_framefmt mf;
        const struct soc_camera_format_xlate *xlate;
        int ret;
 
@@ -1456,11 +1478,12 @@ static void rk29_camera_reinit_work(struct work_struct *work)
        sd = dev_get_drvdata(control);
        ret = v4l2_subdev_call(sd,core, init, 1);
 
-       cam_f.fmt.pix.width = rk29_camdev_info_ptr->icd->user_width;
-       cam_f.fmt.pix.height = rk29_camdev_info_ptr->icd->user_height;
-       xlate = soc_camera_xlate_by_fourcc(rk29_camdev_info_ptr->icd, rk29_camdev_info_ptr->icd->current_fmt->fourcc);
-       cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
-       ret |= v4l2_subdev_call(sd, video, s_fmt, &cam_f);
+       mf.width = rk29_camdev_info_ptr->icd->user_width;
+       mf.height = rk29_camdev_info_ptr->icd->user_height;
+       xlate = soc_camera_xlate_by_fourcc(rk29_camdev_info_ptr->icd, rk29_camdev_info_ptr->icd->current_fmt->host_fmt->fourcc);        
+       mf.code = xlate->code;
+
+       ret |= v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
 
        write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL)|ENABLE_CAPTURE));
 
index cddf4a8e3d0e0352a7a395573ea91b077137ff52..96ae6dffe4805e13ad6bbcdfd37642e7a74f1541 100644 (file)
@@ -57,7 +57,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
@@ -2932,15 +2932,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 }
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
 
-static const struct soc_camera_data_format sensor_colour_formats[] = {
-       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+       return NULL;
+}
+
+static const struct sensor_datafmt sensor_colour_fmts[] = {
+    {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}
 };
 enum sensor_work_state
 {
@@ -2977,7 +2990,7 @@ typedef struct sensor_info_priv_s
        int preview_w;
        int preview_h;
     struct reginfo *winseqe_cur_addr;
-       unsigned int pixfmt;
+       struct sensor_datafmt fmt;
        unsigned int enable;
        unsigned int funmodule_state;
 } sensor_info_priv_t;
@@ -3304,6 +3317,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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;
     u16 pid = 0;
 
@@ -3362,7 +3376,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     }
        sensor_task_lock(client,0);
     sensor->info_priv.winseqe_cur_addr  = 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);
@@ -3562,54 +3582,53 @@ 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 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)
+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 struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *ret_h)
@@ -3691,23 +3710,30 @@ static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *r
        return winseqe_set_addr;
 }
 
-static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
-    struct sensor *sensor = to_sensor(client);
-    struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct sensor_datafmt *fmt;
+    struct sensor *sensor = to_sensor(client);    
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
-       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;
                                break;
                        }
-                       case V4L2_PIX_FMT_UYVY:
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
                        {
                                winseqe_set_addr = sensor_ClrFmt_UYVY;
                                break;
@@ -3717,22 +3743,22 @@ 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_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;
 
        winseqe_set_addr = sensor_fmt_catch(set_w, set_h, &set_w, &set_h);
 
     if ((winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) && winseqe_set_addr) {
         #if CONFIG_SENSOR_Flash
-        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+        if (sensor_fmt_capturechk(sd,mf) == true) {      /* ddl@rock-chips.com : Capture */
             if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                 sensor_ioctrl(icd, Sensor_Flash, Flash_On);
                 SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
@@ -3748,7 +3774,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
             #if CONFIG_SENSOR_Flash
-            if (sensor_fmt_capturechk(sd,f) == true) {
+            if (sensor_fmt_capturechk(sd,mf) == true) {
                 if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
                     sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
                     SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
@@ -3766,47 +3792,39 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         SENSOR_TR("\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)
 {
-       int ret = 0;
-    struct v4l2_pix_format *pix = &f->fmt.pix;
-       int set_w,set_h;
-    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
-    */
-       set_w = pix->width;
-       set_h = pix->height;
-
-    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);
-
-       if (sensor_fmt_catch(pix->width, pix->height, &pix->width, &pix->height) == NULL) {
-               pix->width = 0;
-               pix->height = 0;
-       }
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
     return ret;
 }
 
@@ -4561,9 +4579,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:
@@ -4631,6 +4646,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,
@@ -4642,12 +4666,12 @@ 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_stream   = sensor_s_stream,
+       .s_mbus_fmt     = sensor_s_fmt,
+       .g_mbus_fmt     = sensor_g_fmt,
+       .try_mbus_fmt   = sensor_try_fmt,
+       .enum_mbus_fmt  = sensor_enum_fmt,
+    .s_stream   = sensor_s_stream,     
 };
-
 static struct v4l2_subdev_ops sensor_subdev_ops = {
        .core   = &sensor_subdev_core_ops,
        .video = &sensor_subdev_video_ops,
@@ -4688,7 +4712,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];
 
     ret = sensor_video_probe(icd, client);
     if (ret) {
index e8dc7f8474bcfc9bab45857e6baf3efee66c848f..89cbcfa1e8e5ae808dc983d799aa09c0cb3ba120 100755 (executable)
@@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */\r
 #define SENSOR_INIT_HEIGHT  480\r
 #define SENSOR_INIT_WINSEQADR sensor_vga\r
-#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY\r
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8\r
 \r
 #define CONFIG_SENSOR_WhiteBalance 1\r
 #define CONFIG_SENSOR_Brightness       0\r
@@ -89,6 +89,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
 #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
 \r
+#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)\r
+\r
 struct reginfo\r
 {\r
     u8 reg;\r
@@ -1388,16 +1393,28 @@ static struct soc_camera_ops sensor_ops =
     .num_menus         = ARRAY_SIZE(sensor_menus),\r
 };\r
 \r
-#define COL_FMT(_name, _depth, _fourcc, _colorspace) \\r
-       { .name = _name, .depth = _depth, .fourcc = _fourcc, \\r
-       .colorspace = _colorspace }\r
-\r
-#define JPG_FMT(_name, _depth, _fourcc) \\r
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)\r
-\r
-static const struct soc_camera_data_format sensor_colour_formats[] = {\r
-       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),\r
-       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),\r
+/* 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;
+
+       return NULL;
+}
+
+static const struct sensor_datafmt sensor_colour_fmts[] = {
+    {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
+    {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}    
 };\r
 \r
 typedef struct sensor_info_priv_s\r
@@ -1417,8 +1434,8 @@ typedef struct sensor_info_priv_s
     unsigned char mirror;                                        /* HFLIP */\r
     unsigned char flip;                                          /* VFLIP */\r
     unsigned int winseqe_cur_addr;\r
-       unsigned int pixfmt;\r
-\r
+       struct sensor_datafmt fmt;\r
+    unsigned int funmodule_state;\r
 } sensor_info_priv_t;\r
 \r
 struct sensor\r
@@ -1663,6 +1680,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct soc_camera_device *icd = client->dev.platform_data;\r
     struct sensor *sensor = to_sensor(client);\r
        const struct v4l2_queryctrl *qctrl;\r
+    const struct sensor_datafmt *fmt;\r
     char value;\r
     int ret,pid = 0;\r
 \r
@@ -1732,10 +1750,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;\r
     }\r
     sensor_task_lock(client,0);\r
-   // icd->user_width = SENSOR_INIT_WIDTH;\r
-    //icd->user_height = SENSOR_INIT_HEIGHT;\r
-      sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;\r
-      sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;\r
+    sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;\r
+    fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts));\r
+    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;\r
 \r
     /* sensor sensor information for initialization  */\r
        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
@@ -1786,9 +1808,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #endif\r
 \r
     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);\r
-\r
+    sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK;\r
     return 0;\r
 sensor_INIT_ERR:\r
+    sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
        sensor_task_lock(client,0);\r
        sensor_deactivate(client);\r
     return ret;\r
@@ -1797,20 +1820,20 @@ sensor_INIT_ERR:
 static int sensor_deactivate(struct i2c_client *client)\r
 {\r
        struct soc_camera_device *icd = client->dev.platform_data;\r
-\r
+    struct sensor *sensor = to_sensor(client);\r
+    \r
        SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
 \r
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */\r
-       //sensor_task_lock(client, 1);\r
-       //sensor_write(client, 0x30b0, 0x00);\r
-       //sensor_write(client, 0x30b1, 0x00);\r
-       //sensor_task_lock(client, 0);\r
+       \r
        sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
 \r
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */\r
        icd->user_width = SENSOR_INIT_WIDTH;\r
-       icd->user_height = SENSOR_INIT_HEIGHT;\r
+    icd->user_height = SENSOR_INIT_HEIGHT;\r
        msleep(100);\r
+\r
+    sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
        return 0;\r
 }\r
 \r
@@ -1874,94 +1897,100 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
     return soc_camera_apply_sensor_flags(icl, flags);\r
 }\r
 \r
-static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)\r
-{\r
-    struct i2c_client *client = sd->priv;\r
-    struct soc_camera_device *icd = client->dev.platform_data;\r
-    struct sensor *sensor = to_sensor(client);\r
-    struct v4l2_pix_format *pix = &f->fmt.pix;\r
-\r
-    pix->width         = icd->user_width;\r
-    pix->height                = icd->user_height;\r
-    pix->pixelformat   = sensor->info_priv.pixfmt;\r
-    pix->field         = V4L2_FIELD_NONE;\r
-    pix->colorspace            = V4L2_COLORSPACE_JPEG;\r
-\r
-    return 0;\r
-}\r
-static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)\r
-{\r
-    bool ret = false;\r
-\r
-       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {\r
-               ret = true;\r
-       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {\r
-               ret = true;\r
-       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {\r
-               ret = true;\r
-       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {\r
-               ret = true;\r
-       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {\r
-               ret = true;\r
-       }\r
-\r
-       if (ret == true)\r
-               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);\r
-       return ret;\r
-}\r
-\r
-static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)\r
-{\r
-    bool ret = false;\r
-\r
-       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {\r
-               ret = true;\r
-       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {\r
-               ret = true;\r
-       }\r
-\r
-       if (ret == true)\r
-               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);\r
-       return ret;\r
-}\r
-static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)\r
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+
+    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_mbus_framefmt *mf)
+{
+    bool ret = false;
+
+       if ((mf->width == 1024) && (mf->height == 768)) {
+               ret = true;
+       } else if ((mf->width == 1280) && (mf->height == 1024)) {
+               ret = true;
+       } else if ((mf->width == 1600) && (mf->height == 1200)) {
+               ret = true;
+       } else if ((mf->width == 2048) && (mf->height == 1536)) {
+               ret = true;
+       } else if ((mf->width == 2592) && (mf->height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               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_mbus_framefmt *mf)
+{
+    bool ret = false;
+
+       if ((mf->width == 1280) && (mf->height == 720)) {
+               ret = true;
+       } else if ((mf->width == 1920) && (mf->height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               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_mbus_framefmt *mf)\r
 {\r
     struct i2c_client *client = sd->priv;\r
     struct sensor *sensor = to_sensor(client);\r
-    struct v4l2_pix_format *pix = &f->fmt.pix;\r
+    const struct sensor_datafmt *fmt;\r
        const struct v4l2_queryctrl *qctrl;\r
        struct soc_camera_device *icd = client->dev.platform_data;\r
     struct reginfo *winseqe_set_addr=NULL;\r
     int ret=0, set_w,set_h;\r
 \r
-       if (sensor->info_priv.pixfmt != pix->pixelformat) {\r
-               switch (pix->pixelformat)\r
-               {\r
-                       case V4L2_PIX_FMT_YUYV:\r
-                       {\r
-                               winseqe_set_addr = sensor_ClrFmt_YUYV;\r
-                               break;\r
-                       }\r
-                       case V4L2_PIX_FMT_UYVY:\r
-                       {\r
-                               winseqe_set_addr = sensor_ClrFmt_UYVY;\r
-                               break;\r
-                       }\r
-                       default:\r
-                               break;\r
-               }\r
-               if (winseqe_set_addr != NULL) {\r
-            sensor_write_array(client, winseqe_set_addr);\r
-                       sensor->info_priv.pixfmt = pix->pixelformat;\r
-\r
-                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);\r
-               } else {\r
-                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);\r
-               }\r
-       }\r
-\r
-    set_w = pix->width;\r
-    set_h = pix->height;\r
+       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_MBUS_FMT_YUYV8_2X8:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               break;
+                       }
+                       case V4L2_MBUS_FMT_UYVY8_2X8:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               if (winseqe_set_addr != NULL) {
+            sensor_write_array(client, winseqe_set_addr);
+                       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 v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code);
+               }
+       }
+
+    set_w = mf->width;
+    set_h = mf->height;\r
 \r
        if (((set_w <= 176) && (set_h <= 144)) &&( sensor_qcif[0].reg!=0xff))\r
        {\r
@@ -2016,7 +2045,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  */\r
         set_w = SENSOR_INIT_WIDTH;\r
         set_h = SENSOR_INIT_HEIGHT;            \r
-               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);\r
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height);\r
     }\r
 \r
     if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {\r
@@ -2049,7 +2078,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 \r
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;\r
 \r
-               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */\r
+               if (sensor_fmt_capturechk(sd,mf) == true) {                                 /* ddl@rock-chips.com : Capture */\r
         #if CONFIG_SENSOR_Effect\r
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
@@ -2061,7 +2090,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        }\r
         #endif\r
                        sensor->info_priv.snap2preview = true;\r
-               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */\r
+               } else if (sensor_fmt_videochk(sd,mf) == true) {                        /* ddl@rock-chips.com : Video */\r
                #if CONFIG_SENSOR_Effect\r
                        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
                        sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
@@ -2090,37 +2119,40 @@ 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);\r
     }\r
 \r
-       pix->width = set_w;\r
-    pix->height = set_h;\r
+       mf->width = set_w;\r
+    mf->height = set_h;\r
 \r
 sensor_s_fmt_end:\r
     return ret;\r
 }\r
 \r
-static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)\r
-{\r
-    struct v4l2_pix_format *pix = &f->fmt.pix;\r
-    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||\r
-        pix->pixelformat == V4L2_PIX_FMT_YUYV;\r
-\r
-    /*\r
-    * With Bayer format enforce even side lengths, but let the user play\r
-    * with the starting pixel\r
-    */\r
-    if (pix->height > SENSOR_MAX_HEIGHT)\r
-        pix->height = SENSOR_MAX_HEIGHT;\r
-    else if (pix->height < SENSOR_MIN_HEIGHT)\r
-        pix->height = SENSOR_MIN_HEIGHT;\r
-    else if (bayer)\r
-        pix->height = ALIGN(pix->height, 2);\r
-\r
-    if (pix->width > SENSOR_MAX_WIDTH)\r
-        pix->width = SENSOR_MAX_WIDTH;\r
-    else if (pix->width < SENSOR_MIN_WIDTH)\r
-        pix->width = SENSOR_MIN_WIDTH;\r
-    else if (bayer)\r
-        pix->width = ALIGN(pix->width, 2);\r
-    return 0;\r
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    mf->colorspace = fmt->colorspace;
+    
+    return ret;
 }\r
 \r
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)\r
@@ -2337,7 +2369,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v
 }\r
 #endif\r
 #if CONFIG_SENSOR_DigitalZoom\r
-static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)\r
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
 {\r
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
     struct sensor *sensor = to_sensor(client);\r
@@ -2351,29 +2383,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
     digitalzoom_cur = sensor->info_priv.digitalzoom;\r
     digitalzoom_total = qctrl_info->maximum;\r
 \r
-    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))\r
+    if ((value > 0) && (digitalzoom_cur >= digitalzoom_total))\r
     {\r
         SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
         return -EINVAL;\r
     }\r
 \r
-    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))\r
+    if  ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum))\r
     {\r
         SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
         return -EINVAL;\r
     }\r
 \r
-    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))\r
+    if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total))\r
     {\r
-        *value = digitalzoom_total - digitalzoom_cur;\r
+        value = digitalzoom_total - digitalzoom_cur;\r
     }\r
 \r
-    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))\r
+    if ((value < 0) && ((digitalzoom_cur + value) < 0))\r
     {\r
-        *value = 0 - digitalzoom_cur;\r
+        value = 0 - digitalzoom_cur;\r
     }\r
 \r
-    digitalzoom_cur += *value;\r
+    digitalzoom_cur += value;\r
 \r
     if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)\r
     {\r
@@ -2382,7 +2414,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__);\r
             return -EINVAL;\r
         }\r
-        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);\r
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
         return 0;\r
     }\r
 \r
@@ -2861,8 +2893,6 @@ static int sensor_video_probe(struct soc_camera_device *icd,
         goto sensor_video_probe_err;\r
     }\r
 #endif\r
-    icd->formats = sensor_colour_formats;\r
-    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);\r
 \r
     return 0;\r
 \r
@@ -2932,6 +2962,15 @@ sensor_ioctl_end:
        return ret;\r
 \r
 }\r
+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;
+}\r
 static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {\r
        .init           = sensor_init,\r
        .g_ctrl         = sensor_g_control,\r
@@ -2942,10 +2981,11 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .ioctl = sensor_ioctl,\r
 };\r
 \r
-static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\r
-       .s_fmt          = sensor_s_fmt,\r
-       .g_fmt          = sensor_g_fmt,\r
-       .try_fmt        = sensor_try_fmt,\r
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
+       .s_mbus_fmt     = sensor_s_fmt,
+       .g_mbus_fmt     = sensor_g_fmt,
+       .try_mbus_fmt   = sensor_try_fmt,
+       .enum_mbus_fmt  = sensor_enum_fmt,
 };\r
 \r
 static struct v4l2_subdev_ops sensor_subdev_ops = {\r
@@ -2988,7 +3028,7 @@ static int sensor_probe(struct i2c_client *client,
 \r
     /* Second stage probe - when a capture adapter is there */\r
     icd->ops           = &sensor_ops;\r
-    icd->y_skip_top            = 0;\r
+    sensor->info_priv.fmt = sensor_colour_fmts[0];\r
        #if CONFIG_SENSOR_I2C_NOSCHED\r
        atomic_set(&sensor->tasklock_cnt,0);\r
        #endif\r
index ade9562072ac79684cf19747c9e8bbda8b0f2570..40eb75327829b9341496ecc58f99d7da93b1919d 100755 (executable)
@@ -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
@@ -90,6 +90,10 @@ 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;
@@ -394,11 +398,13 @@ static struct reginfo sensor_qcif[] =
 
 static  struct reginfo sensor_ClrFmt_YUYV[]=
 {
+    {0x00,0x00}
 
 };
 
 static  struct reginfo sensor_ClrFmt_UYVY[]=
 {
+    {0x00,0x00}
 
 };
 
@@ -787,6 +793,7 @@ static  struct reginfo sensor_Effect_Negative[] =
        {0xb8,0x00},
 
 };
+#if 0
 static  struct reginfo sensor_Effect_Bluish[] =
 {
     // Bluish  -- aqua
@@ -796,7 +803,7 @@ static  struct reginfo sensor_Effect_Bluish[] =
        {0xb8,0x60},
 
 };
-
+#endif
 static  struct reginfo sensor_Effect_Green[] =
 {
     //  Greenish
@@ -1167,8 +1174,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 +1194,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;
+};
 
-#define JPG_FMT(_name, _depth, _fourcc) \
-       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* 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;
 
-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),
+       return NULL;
+}
+
+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 +1235,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;
 
@@ -1440,6 +1464,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     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 +1485,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 +1502,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);
@@ -1531,9 +1560,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     #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 +1572,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 +1583,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 +1647,86 @@ 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 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)
+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)
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
     struct i2c_client *client = sd->priv;
     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 +1738,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 +1778,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,41 +1802,41 @@ 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);
-
-    return 0;
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct sensor_datafmt *fmt;
+    int ret = 0;
+   
+       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;
+
+    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;
@@ -2028,7 +2064,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 +2078,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 +2109,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;
     }
 
@@ -2543,9 +2579,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:
@@ -2615,6 +2648,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 +2668,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 +2714,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