camera rk30:commit v0.2.6,support two cif controls.
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / ov2659.c
index 85f5c20e7b8f7b6df49ca9232de3e3f1601c839a..02259502ecc526c513631428f166d32677c1710d 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <mach/rk29_camera.h>
-
+#include <plat/rk_camera.h>
+#include <linux/vmalloc.h>
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   600
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#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_MBUS_FMT_YUYV8_2X8
+#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT     sensor_init_height
+#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
+#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
+#define SENSOR_BUS_PARAM  sensor_init_busparam
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
-#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
-                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
-                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
-
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1461,7 +1458,8 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
        int ret = 0;
-
+       //for fpga debug ,not control io
+       //return 0;
     SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
        switch (cmd)
        {
@@ -1501,6 +1499,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
+static s32 sensor_init_width = 800;
+static s32 sensor_init_height = 600;
+static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
+static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
+static struct reginfo* sensor_init_data_p = sensor_init_data;
+static struct reginfo* sensor_init_winseq_p = sensor_svga;
+static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1509,8 +1514,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0;
-
+    int ret,pid = 0,i = 0,j=0;
+       //if val ==1,mean that sensor need to be reinit
+    struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
+    sensor_init_data_p = sensor_init_data;
+       sensor_init_winseq_p = sensor_svga;
+       sensor_init_width = 800;
+       sensor_init_height = 600;
+       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
+               for(i = 0;i < RK_CAM_NUM;i++){
+                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
+                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
+                                       break;
+                       }
+               }
+       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
+       //user has defined the init data
+               //init reg
+               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
+                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
+                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
+                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
+                               }
+                       sensor_init_data_p = sensor_init_data;
+                       }
+               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
+                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
+                       }
+               //init winseq
+               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
+                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
+                       if(sensor_init_winseq_board)
+                               {
+                               vfree(sensor_init_winseq_board);
+                               sensor_init_winseq_board = NULL;
+                               }
+                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
+                       if(!sensor_init_winseq_board)
+                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
+                       for(j = 0;j< tmp_winseq_size;j++){
+                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
+                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
+                               }
+                       sensor_init_winseq_p = sensor_init_winseq_board;
+                       }
+               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
+                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
+                       }
+               //init width,height,bus,pixelcode
+               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
+                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
+               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
+                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
+               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
+                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
+               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
+                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
+       }
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1558,7 +1618,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data);
+    ret = sensor_write_array(client, sensor_init_data_p);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2775,18 +2835,21 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                {
                        sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
             if (sensor->sensor_io_request != NULL) { 
-                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
-                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
-                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
-                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
-                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
-                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
-                }
-            } else {
-                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                ret = -EINVAL;
-                goto sensor_ioctl_end;
-            }
+                       int j = 0;
+                       for(j = 0;j < RK_CAM_NUM;j++){
+                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
+                           (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
+                           sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
+                               break;
+                         } 
+                       }
+                       if(j == RK_CAM_NUM){
+                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                               ret = -EINVAL;
+                               goto sensor_ioctl_end;
+                               }
+               }
+                       
             /* 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