Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285410
b: refs/heads/master
c: 0f2ee1d
h: refs/heads/master
v: v3
  • Loading branch information
HeungJun Kim authored and Mauro Carvalho Chehab committed Dec 30, 2011
1 parent 6386918 commit fff7b56
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 630caa23b75ca5d399791fa5a4d8d5f4adf81489
refs/heads/master: 0f2ee1dd4907e1daae3c4bf00467417aba04c53e
12 changes: 7 additions & 5 deletions trunk/drivers/media/video/m5mols/m5mols.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ struct m5mols_version {
* @ver: information of the version
* @cap: the capture mode attributes
* @power: current sensor's power status
* @ctrl_sync: true means all controls of the sensor are initialized
* @int_capture: true means the capture interrupt is issued once
* @isp_ready: 1 when the ISP controller has completed booting
* @ctrl_sync: 1 when the control handler state is restored in H/W
* @lock_ae: true means the Auto Exposure is locked
* @lock_awb: true means the Aut WhiteBalance is locked
* @resolution: register value for current resolution
Expand Down Expand Up @@ -204,16 +204,18 @@ struct m5mols_info {

struct m5mols_version ver;
struct m5mols_capture cap;
bool power;
bool ctrl_sync;

unsigned int isp_ready:1;
unsigned int power:1;
unsigned int ctrl_sync:1;

bool lock_ae;
bool lock_awb;
u8 resolution;
u8 mode;
int (*set_power)(struct device *dev, int on);
};

#define is_powered(__info) (__info->power)
#define is_ctrl_synced(__info) (__info->ctrl_sync)
#define is_available_af(__info) (__info->ver.af)
#define is_code(__code, __type) (__code == m5mols_default_ffmt[__type].code)
Expand Down
78 changes: 46 additions & 32 deletions trunk/drivers/media/video/m5mols/m5mols_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,13 @@ static u32 m5mols_swap_byte(u8 *data, u8 length)
* @reg: combination of size, category and command for the I2C packet
* @size: desired size of I2C packet
* @val: read value
*
* Returns 0 on success, or else negative errno.
*/
static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct m5mols_info *info = to_m5mols(sd);
u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
u8 category = I2C_CATEGORY(reg);
u8 cmd = I2C_COMMAND(reg);
Expand Down Expand Up @@ -168,15 +171,17 @@ static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
usleep_range(200, 200);

ret = i2c_transfer(client->adapter, msg, 2);
if (ret < 0) {
v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
size, category, cmd, ret);
return ret;

if (ret == 2) {
*val = m5mols_swap_byte(&rbuf[1], size);
return 0;
}

*val = m5mols_swap_byte(&rbuf[1], size);
if (info->isp_ready)
v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
size, category, cmd, ret);

return 0;
return ret < 0 ? ret : -EIO;
}

int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
Expand Down Expand Up @@ -229,10 +234,13 @@ int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
* m5mols_write - I2C command write function
* @reg: combination of size, category and command for the I2C packet
* @val: value to write
*
* Returns 0 on success, or else negative errno.
*/
int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct m5mols_info *info = to_m5mols(sd);
u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
u8 category = I2C_CATEGORY(reg);
u8 cmd = I2C_COMMAND(reg);
Expand Down Expand Up @@ -263,13 +271,14 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
usleep_range(200, 200);

ret = i2c_transfer(client->adapter, msg, 1);
if (ret < 0) {
v4l2_err(sd, "write failed: size:%d cat:%02x cmd:%02x. %d\n",
size, category, cmd, ret);
return ret;
}
if (ret == 1)
return 0;

return 0;
if (info->isp_ready)
v4l2_err(sd, "write failed: cat:%02x cmd:%02x ret:%d\n",
category, cmd, ret);

return ret < 0 ? ret : -EIO;
}

/**
Expand Down Expand Up @@ -620,7 +629,7 @@ int m5mols_sync_controls(struct m5mols_info *info)
return ret;

v4l2_ctrl_handler_setup(&info->handle);
info->ctrl_sync = true;
info->ctrl_sync = 1;
}

return ret;
Expand Down Expand Up @@ -700,10 +709,10 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
const struct m5mols_platform_data *pdata = info->pdata;
int ret;

if (enable) {
if (is_powered(info))
return 0;
if (info->power == enable)
return 0;

if (enable) {
if (info->set_power) {
ret = info->set_power(&client->dev, 1);
if (ret)
Expand All @@ -717,15 +726,11 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
}

gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
usleep_range(1000, 1000);
info->power = true;
info->power = 1;

return ret;
}

if (!is_powered(info))
return 0;

ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
if (ret)
return ret;
Expand All @@ -734,8 +739,9 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
info->set_power(&client->dev, 0);

gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
usleep_range(1000, 1000);
info->power = false;

info->isp_ready = 0;
info->power = 0;

return ret;
}
Expand All @@ -748,21 +754,29 @@ int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
}

/**
* m5mols_sensor_armboot - Booting M-5MOLS internal ARM core.
* m5mols_fw_start - M-5MOLS internal ARM controller initialization
*
* Booting internal ARM core makes the M-5MOLS is ready for getting commands
* with I2C. It's the first thing to be done after it powered up. It must wait
* at least 520ms recommended by M-5MOLS datasheet, after executing arm booting.
* Execute the M-5MOLS internal ARM controller initialization sequence.
* This function should be called after the supply voltage has been
* applied and before any requests to the device are made.
*/
static int m5mols_sensor_armboot(struct v4l2_subdev *sd)
static int m5mols_fw_start(struct v4l2_subdev *sd)
{
struct m5mols_info *info = to_m5mols(sd);
int ret;

ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
atomic_set(&info->irq_done, 0);
/* Wait until I2C slave is initialized in Flash Writer mode */
ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE,
M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1);
if (!ret)
ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
if (!ret)
ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000);
if (ret < 0)
return ret;

msleep(520);
info->isp_ready = 1;

ret = m5mols_get_version(sd);
if (!ret)
Expand Down Expand Up @@ -840,7 +854,7 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
if (on) {
ret = m5mols_sensor_power(info, true);
if (!ret)
ret = m5mols_sensor_armboot(sd);
ret = m5mols_fw_start(sd);
if (!ret)
ret = m5mols_init_controls(info);
if (ret)
Expand Down Expand Up @@ -869,7 +883,7 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
ret = m5mols_sensor_power(info, false);
if (!ret) {
v4l2_ctrl_handler_free(&info->handle);
info->ctrl_sync = false;
info->ctrl_sync = 0;
}

return ret;
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/media/video/m5mols/m5mols_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@

/* Starts internal ARM core booting after power-up */
#define FLASH_CAM_START I2C_REG(CAT_FLASH, 0x12, 1)
#define REG_START_ARM_BOOT 0x01
#define REG_START_ARM_BOOT 0x01 /* write value */
#define REG_IN_FLASH_MODE 0x00 /* read value */

#endif /* M5MOLS_REG_H */

0 comments on commit fff7b56

Please sign in to comment.