mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
camera: fix sensor driver obtain i2c fail in atomic, so check i2c bus is locked or not before into atomic
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#include "ov5640.h"
|
||||
|
||||
struct reginfo sensor_af_firmware[] =
|
||||
static struct reginfo sensor_af_firmware[] =
|
||||
{
|
||||
SEQUENCE_END,SEQUENCE_END
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define VCM_DRIVER VCM_DRIVER_A3907
|
||||
|
||||
#if (VCM_DRIVER == VCM_DRIVER_A3907)
|
||||
struct reginfo sensor_af_firmware[] =
|
||||
static struct reginfo sensor_af_firmware[] =
|
||||
{
|
||||
{0x3000,0x20},
|
||||
{0x8000,0x02},
|
||||
@@ -6065,7 +6065,7 @@ struct reginfo sensor_af_firmware[] =
|
||||
};
|
||||
#elif (VCM_DRIVER == VCM_DRIVER_AD5820)
|
||||
/* support const-focus */
|
||||
struct reginfo sensor_af_firmware[] =
|
||||
static struct reginfo sensor_af_firmware[] =
|
||||
{
|
||||
{0x3000,0x20},
|
||||
{0x8000,0x02},
|
||||
@@ -11962,7 +11962,7 @@ struct reginfo sensor_af_firmware[] =
|
||||
{0x0000,0x00}
|
||||
};
|
||||
#elif (VCM_DRIVER == VCM_DRIVER_DW9710)
|
||||
struct reginfo sensor_af_firmware[] =
|
||||
static struct reginfo sensor_af_firmware[] =
|
||||
{
|
||||
{0x3000,0x20},
|
||||
{0x8000,0x02},
|
||||
|
||||
Reference in New Issue
Block a user