Commit 57644f56 authored by HeungJun, Kim's avatar HeungJun, Kim Committed by Mauro Carvalho Chehab

[media] m5mols: add m5mols_read_u8/u16/u32() according to I2C byte width

For now, the m5mols_read() share in case of I2C packet 1, 2, 4 byte(s) width.
So, this commit adds 3 functions - m5mols_read_u8/u16/u32() according to byte
width of I2C packet. And, the u32 variables in spite of u8 or u16 for fitting
to m5mols_read() having no choice, is replaced to have original byte width
like u8, u16, u32 as same reason.
Signed-off-by: default avatarHeungJun, Kim <riverful.kim@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent bbe66edc
...@@ -106,23 +106,23 @@ struct m5mols_capture { ...@@ -106,23 +106,23 @@ struct m5mols_capture {
* The each value according to each scenemode is recommended in the documents. * The each value according to each scenemode is recommended in the documents.
*/ */
struct m5mols_scenemode { struct m5mols_scenemode {
u32 metering; u8 metering;
u32 ev_bias; u8 ev_bias;
u32 wb_mode; u8 wb_mode;
u32 wb_preset; u8 wb_preset;
u32 chroma_en; u8 chroma_en;
u32 chroma_lvl; u8 chroma_lvl;
u32 edge_en; u8 edge_en;
u32 edge_lvl; u8 edge_lvl;
u32 af_range; u8 af_range;
u32 fd_mode; u8 fd_mode;
u32 mcc; u8 mcc;
u32 light; u8 light;
u32 flash; u8 flash;
u32 tone; u8 tone;
u32 iso; u8 iso;
u32 capt_mode; u8 capt_mode;
u32 wdr; u8 wdr;
}; };
/** /**
...@@ -216,9 +216,9 @@ struct m5mols_info { ...@@ -216,9 +216,9 @@ struct m5mols_info {
bool lock_ae; bool lock_ae;
bool lock_awb; bool lock_awb;
u8 resolution; u8 resolution;
u32 interrupt; u8 interrupt;
u32 mode; u8 mode;
u32 mode_save; u8 mode_save;
int (*set_power)(struct device *dev, int on); int (*set_power)(struct device *dev, int on);
}; };
...@@ -256,9 +256,11 @@ struct m5mols_info { ...@@ -256,9 +256,11 @@ struct m5mols_info {
* +-------+---+----------+-----+------+------+------+------+ * +-------+---+----------+-----+------+------+------+------+
* - d[0..3]: according to size1 * - d[0..3]: according to size1
*/ */
int m5mols_read(struct v4l2_subdev *sd, u32 reg_comb, u32 *val); int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val); int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value); int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 value);
/* /*
* Mode operation of the M-5MOLS * Mode operation of the M-5MOLS
...@@ -280,12 +282,12 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value); ...@@ -280,12 +282,12 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value);
* The available executing order between each modes are as follows: * The available executing order between each modes are as follows:
* PARAMETER <---> MONITOR <---> CAPTURE * PARAMETER <---> MONITOR <---> CAPTURE
*/ */
int m5mols_mode(struct m5mols_info *info, u32 mode); int m5mols_mode(struct m5mols_info *info, u8 mode);
int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg); int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
int m5mols_sync_controls(struct m5mols_info *info); int m5mols_sync_controls(struct m5mols_info *info);
int m5mols_start_capture(struct m5mols_info *info); int m5mols_start_capture(struct m5mols_info *info);
int m5mols_do_scenemode(struct m5mols_info *info, u32 mode); int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
int m5mols_lock_3a(struct m5mols_info *info, bool lock); int m5mols_lock_3a(struct m5mols_info *info, bool lock);
int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
......
...@@ -58,9 +58,9 @@ static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num, ...@@ -58,9 +58,9 @@ static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
{ {
u32 num, den; u32 num, den;
int ret = m5mols_read(sd, addr_num, &num); int ret = m5mols_read_u32(sd, addr_num, &num);
if (!ret) if (!ret)
ret = m5mols_read(sd, addr_den, &den); ret = m5mols_read_u32(sd, addr_den, &den);
if (ret) if (ret)
return ret; return ret;
*val = den == 0 ? 0 : num / den; *val = den == 0 ? 0 : num / den;
...@@ -99,20 +99,20 @@ static int m5mols_capture_info(struct m5mols_info *info) ...@@ -99,20 +99,20 @@ static int m5mols_capture_info(struct m5mols_info *info)
if (ret) if (ret)
return ret; return ret;
ret = m5mols_read(sd, EXIF_INFO_ISO, (u32 *)&exif->iso_speed); ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
if (!ret) if (!ret)
ret = m5mols_read(sd, EXIF_INFO_FLASH, (u32 *)&exif->flash); ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
if (!ret) if (!ret)
ret = m5mols_read(sd, EXIF_INFO_SDR, (u32 *)&exif->sdr); ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
if (!ret) if (!ret)
ret = m5mols_read(sd, EXIF_INFO_QVAL, (u32 *)&exif->qval); ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
if (ret) if (ret)
return ret; return ret;
if (!ret) if (!ret)
ret = m5mols_read(sd, CAPC_IMAGE_SIZE, &info->cap.main); ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
if (!ret) if (!ret)
ret = m5mols_read(sd, CAPC_THUMB_SIZE, &info->cap.thumb); ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
if (!ret) if (!ret)
info->cap.total = info->cap.main + info->cap.thumb; info->cap.total = info->cap.main + info->cap.thumb;
...@@ -122,7 +122,7 @@ static int m5mols_capture_info(struct m5mols_info *info) ...@@ -122,7 +122,7 @@ static int m5mols_capture_info(struct m5mols_info *info)
int m5mols_start_capture(struct m5mols_info *info) int m5mols_start_capture(struct m5mols_info *info)
{ {
struct v4l2_subdev *sd = &info->sd; struct v4l2_subdev *sd = &info->sd;
u32 resolution = info->resolution; u8 resolution = info->resolution;
int timeout; int timeout;
int ret; int ret;
......
...@@ -130,7 +130,7 @@ static struct m5mols_scenemode m5mols_default_scenemode[] = { ...@@ -130,7 +130,7 @@ static struct m5mols_scenemode m5mols_default_scenemode[] = {
* *
* WARNING: The execution order is important. Do not change the order. * WARNING: The execution order is important. Do not change the order.
*/ */
int m5mols_do_scenemode(struct m5mols_info *info, u32 mode) int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
{ {
struct v4l2_subdev *sd = &info->sd; struct v4l2_subdev *sd = &info->sd;
struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode]; struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
......
...@@ -133,13 +133,13 @@ static u32 m5mols_swap_byte(u8 *data, u8 length) ...@@ -133,13 +133,13 @@ static u32 m5mols_swap_byte(u8 *data, u8 length)
/** /**
* m5mols_read - I2C read function * m5mols_read - I2C read function
* @reg: combination of size, category and command for the I2C packet * @reg: combination of size, category and command for the I2C packet
* @size: desired size of I2C packet
* @val: read value * @val: read value
*/ */
int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
{ {
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1]; u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
u8 size = I2C_SIZE(reg);
u8 category = I2C_CATEGORY(reg); u8 category = I2C_CATEGORY(reg);
u8 cmd = I2C_COMMAND(reg); u8 cmd = I2C_COMMAND(reg);
struct i2c_msg msg[2]; struct i2c_msg msg[2];
...@@ -149,11 +149,6 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) ...@@ -149,11 +149,6 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val)
if (!client->adapter) if (!client->adapter)
return -ENODEV; return -ENODEV;
if (size != 1 && size != 2 && size != 4) {
v4l2_err(sd, "Wrong data size\n");
return -EINVAL;
}
msg[0].addr = client->addr; msg[0].addr = client->addr;
msg[0].flags = 0; msg[0].flags = 0;
msg[0].len = 5; msg[0].len = 5;
...@@ -184,6 +179,52 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) ...@@ -184,6 +179,52 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val)
return 0; return 0;
} }
int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
{
u32 val_32;
int ret;
if (I2C_SIZE(reg) != 1) {
v4l2_err(sd, "Wrong data size\n");
return -EINVAL;
}
ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
if (ret)
return ret;
*val = (u8)val_32;
return ret;
}
int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
{
u32 val_32;
int ret;
if (I2C_SIZE(reg) != 2) {
v4l2_err(sd, "Wrong data size\n");
return -EINVAL;
}
ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
if (ret)
return ret;
*val = (u16)val_32;
return ret;
}
int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
{
if (I2C_SIZE(reg) != 4) {
v4l2_err(sd, "Wrong data size\n");
return -EINVAL;
}
return m5mols_read(sd, I2C_SIZE(reg), reg, val);
}
/** /**
* m5mols_write - I2C command write function * m5mols_write - I2C command write function
* @reg: combination of size, category and command for the I2C packet * @reg: combination of size, category and command for the I2C packet
...@@ -231,13 +272,14 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val) ...@@ -231,13 +272,14 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
return 0; return 0;
} }
int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask) int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 mask)
{ {
u32 busy, i; u8 busy;
int i;
int ret; int ret;
for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) { for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) {
ret = m5mols_read(sd, I2C_REG(category, cmd, 1), &busy); ret = m5mols_read_u8(sd, I2C_REG(category, cmd, 1), &busy);
if (ret < 0) if (ret < 0)
return ret; return ret;
if ((busy & mask) == mask) if ((busy & mask) == mask)
...@@ -252,14 +294,14 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask) ...@@ -252,14 +294,14 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask)
* Before writing desired interrupt value the INT_FACTOR register should * Before writing desired interrupt value the INT_FACTOR register should
* be read to clear pending interrupts. * be read to clear pending interrupts.
*/ */
int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg) int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
{ {
struct m5mols_info *info = to_m5mols(sd); struct m5mols_info *info = to_m5mols(sd);
u32 mask = is_available_af(info) ? REG_INT_AF : 0; u8 mask = is_available_af(info) ? REG_INT_AF : 0;
u32 dummy; u8 dummy;
int ret; int ret;
ret = m5mols_read(sd, SYSTEM_INT_FACTOR, &dummy); ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
if (!ret) if (!ret)
ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask); ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
return ret; return ret;
...@@ -271,7 +313,7 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg) ...@@ -271,7 +313,7 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg)
* It always accompanies a little delay changing the M-5MOLS mode, so it is * It always accompanies a little delay changing the M-5MOLS mode, so it is
* needed checking current busy status to guarantee right mode. * needed checking current busy status to guarantee right mode.
*/ */
static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode) static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
{ {
int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode); int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
...@@ -286,16 +328,16 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode) ...@@ -286,16 +328,16 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode)
* can be guaranteed only when the sensor is operating in mode which which * can be guaranteed only when the sensor is operating in mode which which
* a command belongs to. * a command belongs to.
*/ */
int m5mols_mode(struct m5mols_info *info, u32 mode) int m5mols_mode(struct m5mols_info *info, u8 mode)
{ {
struct v4l2_subdev *sd = &info->sd; struct v4l2_subdev *sd = &info->sd;
int ret = -EINVAL; int ret = -EINVAL;
u32 reg; u8 reg;
if (mode < REG_PARAMETER && mode > REG_CAPTURE) if (mode < REG_PARAMETER && mode > REG_CAPTURE)
return ret; return ret;
ret = m5mols_read(sd, SYSTEM_SYSMODE, &reg); ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
if ((!ret && reg == mode) || ret) if ((!ret && reg == mode) || ret)
return ret; return ret;
...@@ -348,28 +390,24 @@ static int m5mols_get_version(struct v4l2_subdev *sd) ...@@ -348,28 +390,24 @@ static int m5mols_get_version(struct v4l2_subdev *sd)
struct m5mols_version ver; struct m5mols_version ver;
u8 bytes[VERSION_SIZE]; u8 bytes[VERSION_SIZE];
} version; } version;
u32 *value;
u8 cmd = CAT0_VER_CUSTOMER; u8 cmd = CAT0_VER_CUSTOMER;
int ret; int ret;
do { do {
value = (u32 *)&version.bytes[cmd]; ret = m5mols_read_u8(sd, SYSTEM_CMD(cmd), &version.bytes[cmd]);
ret = m5mols_read(sd, SYSTEM_CMD(cmd), value);
if (ret) if (ret)
return ret; return ret;
} while (cmd++ != CAT0_VER_AWB); } while (cmd++ != CAT0_VER_AWB);
do { do {
value = (u32 *)&version.bytes[cmd]; ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &version.bytes[cmd]);
ret = m5mols_read(sd, SYSTEM_VER_STRING, value);
if (ret) if (ret)
return ret; return ret;
if (cmd >= VERSION_SIZE - 1) if (cmd >= VERSION_SIZE - 1)
return -EINVAL; return -EINVAL;
} while (version.bytes[cmd++]); } while (version.bytes[cmd++]);
value = (u32 *)&version.bytes[cmd]; ret = m5mols_read_u8(sd, AF_VERSION, &version.bytes[cmd]);
ret = m5mols_read(sd, AF_VERSION, value);
if (ret) if (ret)
return ret; return ret;
...@@ -722,7 +760,7 @@ static int m5mols_init_controls(struct m5mols_info *info) ...@@ -722,7 +760,7 @@ static int m5mols_init_controls(struct m5mols_info *info)
int ret; int ret;
/* Determine value's range & step of controls for various FW version */ /* Determine value's range & step of controls for various FW version */
ret = m5mols_read(sd, AE_MAX_GAIN_MON, (u32 *)&max_exposure); ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure);
if (!ret) if (!ret)
step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1; step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
if (ret) if (ret)
...@@ -842,18 +880,18 @@ static void m5mols_irq_work(struct work_struct *work) ...@@ -842,18 +880,18 @@ static void m5mols_irq_work(struct work_struct *work)
struct m5mols_info *info = struct m5mols_info *info =
container_of(work, struct m5mols_info, work_irq); container_of(work, struct m5mols_info, work_irq);
struct v4l2_subdev *sd = &info->sd; struct v4l2_subdev *sd = &info->sd;
u32 reg; u8 reg;
int ret; int ret;
if (!is_powered(info) || if (!is_powered(info) ||
m5mols_read(sd, SYSTEM_INT_FACTOR, &info->interrupt)) m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt))
return; return;
switch (info->interrupt & REG_INT_MASK) { switch (info->interrupt & REG_INT_MASK) {
case REG_INT_AF: case REG_INT_AF:
if (!is_available_af(info)) if (!is_available_af(info))
break; break;
ret = m5mols_read(sd, AF_STATUS, &reg); ret = m5mols_read_u8(sd, AF_STATUS, &reg);
v4l2_dbg(2, m5mols_debug, sd, "AF %s\n", v4l2_dbg(2, m5mols_debug, sd, "AF %s\n",
reg == REG_AF_FAIL ? "Failed" : reg == REG_AF_FAIL ? "Failed" :
reg == REG_AF_SUCCESS ? "Success" : reg == REG_AF_SUCCESS ? "Success" :
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment