Hi Sakari, On Tuesday 17 May 2011 17:14:04 Sakari Ailus wrote: > This patch adds the driver for the adp1653 LED flash controller. This > controller supports a high power led in flash and torch modes and an > indicator light, sometimes also called privacy light. > > The adp1653 is used on the Nokia N900. [snip] > diff --git a/drivers/media/video/adp1653.c b/drivers/media/video/adp1653.c > new file mode 100644 > index 0000000..1679707 > --- /dev/null > +++ b/drivers/media/video/adp1653.c [snip] > +static int adp1653_get_fault(struct adp1653_flash *flash) > +{ > + struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); > + int fault; > + int rval; > + > + fault = i2c_smbus_read_byte_data(client, ADP1653_REG_FAULT); > + if (IS_ERR_VALUE(fault)) > + return fault; > + > + flash->fault |= fault; > + > + if (!flash->fault) > + return 0; > + > + /* Clear faults. */ > + rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0); > + if (IS_ERR_VALUE(rval)) > + return rval; Should the faults be cleared right away, instead of when the user reads the faults control ? > + flash->led_mode->val = V4L2_FLASH_LED_MODE_NONE; Does the hardware switch back to "none" mode when a fault occurs ? The datasheet just states that "the ADP1653 is disabled". Does that mean temporarily disabled until the faults are cleared ? If so you should update the registers to turn the LED off. > + return flash->fault; > +} [snip] > +static int adp1653_get_ctrl(struct v4l2_ctrl *ctrl) > +{ > + struct adp1653_flash *flash = > + container_of(ctrl->handler, struct adp1653_flash, ctrls); > + > + adp1653_get_fault(flash); > + if (IS_ERR_VALUE(flash->fault)) Shouldn't you check the adp1653_get_fault() return value instead ? > + return flash->fault; > + > + ctrl->cur.val = 0; > + > + if (flash->fault & ADP1653_REG_FAULT_FLT_SCP) > + ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; > + if (flash->fault & ADP1653_REG_FAULT_FLT_OT) > + ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; > + if (flash->fault & ADP1653_REG_FAULT_FLT_TMR) > + ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT; > + if (flash->fault & ADP1653_REG_FAULT_FLT_OV) > + ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE; > + > + flash->fault = 0; > + > + return 0; > +} [snip] > +static int > +adp1653_registered(struct v4l2_subdev *subdev) > +{ > + struct adp1653_flash *flash = to_adp1653_flash(subdev); > + > + return adp1653_init_controls(flash); Can't this be moved to adp1653_probe() ? You could then get rid of the registered callback. > +} > + > +static int > +adp1653_init_device(struct adp1653_flash *flash) > +{ > + struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); > + int rval; > + > + /* Clear FAULT register by writing zero to OUT_SEL */ > + rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0); > + if (rval < 0) { > + dev_err(&client->dev, "failed writing fault register\n"); > + return -EIO; > + } > + > + /* Read FAULT register */ > + rval = i2c_smbus_read_byte_data(client, ADP1653_REG_FAULT); > + if (rval < 0) { > + dev_err(&client->dev, "failed reading fault register\n"); > + return -EIO; > + } > + > + if ((rval & 0x0f) != 0) { > + dev_err(&client->dev, "device fault\n"); Same comment as last time :-) > + return -EIO; > + } > + > + mutex_lock(&flash->ctrls.lock); > + rval = adp1653_update_hw(flash); > + mutex_unlock(&flash->ctrls.lock); > + if (rval) { > + dev_err(&client->dev, > + "adp1653_update_hw failed at %s\n", __func__); > + return -EIO; > + } > + > + return 0; > +} [snip] -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html