camera: fix sensor driver obtain i2c fail in atomic, so check i2c bus is locked or...
authorddl <ddl@rockchip.com>
Sun, 30 Jan 2011 23:16:11 +0000 (07:16 +0800)
committerddl <ddl@rockchip.com>
Sun, 30 Jan 2011 23:19:10 +0000 (07:19 +0800)
drivers/media/video/ov2655.c
drivers/media/video/ov2659.c
drivers/media/video/ov5640.c
drivers/media/video/ov5640_af_firmware.c
drivers/media/video/ov5642.c
drivers/media/video/ov5642_af_firmware.c

index b422b8808211102998daeadf6983889249026551..c977cf527829e92e84c13bc3f61b2bcdce45e0aa 100755 (executable)
@@ -1448,11 +1448,22 @@ static struct sensor* to_sensor(const struct i2c_client *client)
 static int sensor_task_lock(struct i2c_client *client, int lock)
 {
 #if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
     struct sensor *sensor = to_sensor(client);
 
        if (lock) {
-               if (atomic_read(&sensor->tasklock_cnt) == 0)
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
                        preempt_disable();
+               }
 
                atomic_add(1, &sensor->tasklock_cnt);
        } else {
@@ -1465,6 +1476,8 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
        }
 #endif
        return 0;
+sensor_task_lock_err:
+       return -1;
 }
 
 /* sensor register write */
@@ -1551,7 +1564,8 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
        char valchk;
 
        cnt = 0;
-       sensor_task_lock(client, 1);
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
     while (regarray[i].reg != 0)
     {
         err = sensor_write(client, regarray[i].reg, regarray[i].val);
@@ -1658,7 +1672,8 @@ 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, 0x3012, 0x80);
     if (ret != 0)
     {
index a694977937505715d86c59caa3a1e2d3ecfd6fa8..f598647d413c87636eb343fb6c4c8fe29600a27a 100755 (executable)
@@ -20,7 +20,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 #include <mach/rk29_camera.h>
-
+#include <mach/gpio.h>
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -70,7 +70,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 
 #define CONFIG_SENSOR_I2C_SPEED     250000       /* Hz */
 /* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
-#define CONFIG_SENSOR_I2C_NOSCHED   1
+#define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
 #define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_FALLING|\
@@ -1253,11 +1253,22 @@ static struct sensor* to_sensor(const struct i2c_client *client)
 static int sensor_task_lock(struct i2c_client *client, int lock)
 {
 #if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
     struct sensor *sensor = to_sensor(client);
 
        if (lock) {
-               if (atomic_read(&sensor->tasklock_cnt) == 0)
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
                        preempt_disable();
+               }
 
                atomic_add(1, &sensor->tasklock_cnt);
        } else {
@@ -1270,6 +1281,8 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
        }
 #endif
        return 0;
+sensor_task_lock_err:
+       return -1;
 }
 
 /* sensor register write */
@@ -1299,8 +1312,8 @@ static int sensor_write(struct i2c_client *client, u16 reg, u8 val)
         if (err >= 0) {
             return 0;
         } else {
-            SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
-            udelay(10);
+               SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+               udelay(10);
         }
     }
 
@@ -1356,7 +1369,9 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
        char valchk;
 
        cnt = 0;
-       sensor_task_lock(client, 1);
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
+
     while (regarray[i].reg != 0)
     {
         err = sensor_write(client, regarray[i].reg, regarray[i].val);
@@ -1463,7 +1478,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, 0x0103, 0x01);
     if (ret != 0)
     {
@@ -1676,6 +1693,9 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     struct reginfo *winseqe_set_addr=NULL;
     int ret=0, set_w,set_h;
 
+       gpio_direction_output(RK29_PIN6_PB7,1);
+       gpio_set_value(RK29_PIN6_PB7, 1);
+
        if (sensor->info_priv.pixfmt != pix->pixelformat) {
                switch (pix->pixelformat)
                {
@@ -1784,6 +1804,8 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     pix->height = set_h;
 
 sensor_s_fmt_end:
+       gpio_direction_output(RK29_PIN6_PB7,0);
+       gpio_set_value(RK29_PIN6_PB7, 0);
     return ret;
 }
 
index e66f28da30c136e67f49640d9cd96f4f35bf1b01..bcbee7f48bb261eb2f3e21df420080306574d608 100755 (executable)
@@ -1361,11 +1361,22 @@ static struct sensor* to_sensor(const struct i2c_client *client)
 static int sensor_task_lock(struct i2c_client *client, int lock)
 {
 #if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
     struct sensor *sensor = to_sensor(client);
 
        if (lock) {
-               if (atomic_read(&sensor->tasklock_cnt) == 0)
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
                        preempt_disable();
+               }
 
                atomic_add(1, &sensor->tasklock_cnt);
        } else {
@@ -1378,6 +1389,8 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
        }
 #endif
        return 0;
+sensor_task_lock_err:
+       return -1;
 }
 
 /* sensor register write */
@@ -1469,7 +1482,8 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
 #endif
 
        cnt = 0;
-       sensor_task_lock(client, 1);
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
     while (regarray[i].reg != SEQUENCE_END)
     {
        #if CONFIG_SENSOR_Focus
@@ -2050,7 +2064,8 @@ 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, 0x3008, 0x80);
     if (ret != 0) {
         SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
index bffcd9c88d8f0b5d7ebeb2deae78b4455b9ebce6..20d9e5336e4b5ae69a1f2b7e9ee58ebb9f5df7c3 100755 (executable)
@@ -9,7 +9,7 @@
  */\r
 #include "ov5640.h"\r
 \r
-struct reginfo sensor_af_firmware[] =\r
+static struct reginfo sensor_af_firmware[] =\r
 {\r
        SEQUENCE_END,SEQUENCE_END\r
 };\r
index 09098a4daf6939cc56bc7cdbbd094749e3c1ee84..066f7993c1dc6138ab6235d88058d2ca29ceee34 100755 (executable)
@@ -3344,11 +3344,22 @@ static struct sensor* to_sensor(const struct i2c_client *client)
 static int sensor_task_lock(struct i2c_client *client, int lock)
 {
 #if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
     struct sensor *sensor = to_sensor(client);
 
        if (lock) {
-               if (atomic_read(&sensor->tasklock_cnt) == 0)
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
                        preempt_disable();
+               }
 
                atomic_add(1, &sensor->tasklock_cnt);
        } else {
@@ -3361,6 +3372,8 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
        }
 #endif
        return 0;
+sensor_task_lock_err:
+       return -1;
 }
 
 /* sensor register write */
@@ -3452,7 +3465,8 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
 #endif
 
        cnt = 0;
-       sensor_task_lock(client, 1);
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
     while (regarray[i].reg != 0)
     {
        #if CONFIG_SENSOR_Focus
@@ -4032,7 +4046,8 @@ 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, 0x3008, 0x80);
     if (ret != 0) {
         SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
index 4ee405a75b6e5f9df266f4c80a63181a56515595..84907b88f23169fca858dbdce4462f6df48eb9ad 100644 (file)
@@ -15,7 +15,7 @@
 #define VCM_DRIVER         VCM_DRIVER_A3907\r
 \r
 #if (VCM_DRIVER == VCM_DRIVER_A3907)\r
-struct reginfo sensor_af_firmware[] =\r
+static struct reginfo sensor_af_firmware[] =\r
 {\r
        {0x3000,0x20},\r
        {0x8000,0x02},\r
@@ -6065,7 +6065,7 @@ struct reginfo sensor_af_firmware[] =
 };\r
 #elif (VCM_DRIVER == VCM_DRIVER_AD5820)\r
 /* support const-focus */\r
-struct reginfo sensor_af_firmware[] =\r
+static struct reginfo sensor_af_firmware[] =\r
 {\r
        {0x3000,0x20},\r
        {0x8000,0x02},\r
@@ -11962,7 +11962,7 @@ struct reginfo sensor_af_firmware[] =
        {0x0000,0x00}\r
 };\r
 #elif (VCM_DRIVER == VCM_DRIVER_DW9710)\r
-struct reginfo sensor_af_firmware[] =\r
+static struct reginfo sensor_af_firmware[] =\r
 {\r
        {0x3000,0x20},\r
        {0x8000,0x02},\r