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

	mutex_lock(&flash->ctrls.lock);
	/* Reset faults before reading new ones. */
	flash->fault = 0;
	rval = adp1653_get_fault(flash);
	mutex_unlock(&flash->ctrls.lock);
	if (rval > 0) {
		dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
		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;
}
static int adp1653_get_ctrl(struct v4l2_ctrl *ctrl)
{
	struct adp1653_flash *flash =
		container_of(ctrl->handler, struct adp1653_flash, ctrls);
	int rval;

	rval = adp1653_get_fault(flash);
	if (IS_ERR_VALUE(rval))
		return rval;

	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;
}
static int adp1653_set_ctrl(struct v4l2_ctrl *ctrl)
{
	struct adp1653_flash *flash =
		container_of(ctrl->handler, struct adp1653_flash, ctrls);
	int rval;

	rval = adp1653_get_fault(flash);
	if (IS_ERR_VALUE(rval))
		return rval;
	if ((rval & (ADP1653_REG_FAULT_FLT_SCP |
		     ADP1653_REG_FAULT_FLT_OT |
		     ADP1653_REG_FAULT_FLT_OV)) &&
	    (ctrl->id == V4L2_CID_FLASH_STROBE ||
	     ctrl->id == V4L2_CID_FLASH_TORCH_INTENSITY ||
	     ctrl->id == V4L2_CID_FLASH_LED_MODE))
		return -EBUSY;

	switch (ctrl->id) {
	case V4L2_CID_FLASH_STROBE:
		return adp1653_strobe(flash, 1);
	case V4L2_CID_FLASH_STROBE_STOP:
		return adp1653_strobe(flash, 0);
	}

	return adp1653_update_hw(flash);
}
Exemplo n.º 4
0
static int adp1653_ioctl_g_ctrl(struct v4l2_int_device *s,
			struct v4l2_control *vc)
{
	struct adp1653_flash *flash = s->priv;

	switch (vc->id) {
	case V4L2_CID_FLASH_TIMEOUT:
		vc->value = flash->flash_timeout;
		break;
	case V4L2_CID_FLASH_INTENSITY:
		vc->value = flash->flash_intensity;
		break;
	case V4L2_CID_TORCH_INTENSITY:
		vc->value = flash->torch_intensity;
		break;
	case V4L2_CID_INDICATOR_INTENSITY:
		vc->value = flash->indicator_intensity;
		break;

	case V4L2_CID_FLASH_ADP1653_FAULT_SCP:
		vc->value = (adp1653_get_fault(s)
			    & ADP1653_REG_FAULT_FLT_SCP) != 0;
		break;
	case V4L2_CID_FLASH_ADP1653_FAULT_OT:
		vc->value = (adp1653_get_fault(s)
			    & ADP1653_REG_FAULT_FLT_OT) != 0;
		break;
	case V4L2_CID_FLASH_ADP1653_FAULT_TMR:
		vc->value = (adp1653_get_fault(s)
			    & ADP1653_REG_FAULT_FLT_TMR) != 0;
		break;
	case V4L2_CID_FLASH_ADP1653_FAULT_OV:
		vc->value = (adp1653_get_fault(s)
			    & ADP1653_REG_FAULT_FLT_OV) != 0;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}