Re: [RFC v2 3/3] adp1653: Add driver for LED flash controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sakari,

On Wednesday 18 May 2011 13:29:56 Sakari Ailus wrote:
> On Wed, May 18, 2011 at 09:31:24AM +0200, Laurent Pinchart wrote:
> > 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.
> 
> My understanding is that this is temporary until the faults are cleared.
> However, this is difficult to find out since the faults don't just occur
> that easily.
> 
> OUT_SEL register controls the current to LEDs so this turned everything
> off. The indicator should still remain on, I guess, since it's not
> affected by the faults, except possibly the over-temperature one.

OK, I'm fine with the code then.

> > > +	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 ?
> 
> Yes. Good catch. I've tried to simulate this code a bit but as always,
> error handling tends not to be one of the best parts of the driver,
> especially those errors that generally do not happen. :-I
> 
> > > +		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.
> 
> Good point. I'll look into this.
> 
> > > +}
> > > +
> > > +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 :-)
> 
> Ouch. I'll try to get the fix done for the next time. :-)

-- 
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


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux