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;

	flash->led_mode->val = V4L2_FLASH_LED_MODE_NONE;

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

	return flash->fault;
}
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_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);
}
Example #4
0
static int adp1653_strobe(struct v4l2_int_device *s)
{
	struct adp1653_flash *flash = s->priv;
	int rval;

	if (flash->torch_intensity > 0) {
		/* Disabling torch enables flash in update_hw() */
		flash->torch_intensity = 0;
		rval = adp1653_update_hw(s);
		if (rval)
			return rval;
	}

	if (flash->platform_data->strobe) {
		/* Hardware-specific strobe using I/O pin */
		return flash->platform_data->strobe(s);
	} else {
		/* Software strobe using i2c */
		rval = i2c_smbus_write_byte_data(flash->i2c_client,
			ADP1653_REG_SW_STROBE, ADP1653_REG_SW_STROBE_SW_STROBE);
		if (rval)
			return rval;
		rval = i2c_smbus_write_byte_data(flash->i2c_client,
			ADP1653_REG_SW_STROBE, 0);
		return rval;
	}
}
Example #5
0
static int adp1653_ioctl_s_ctrl(struct v4l2_int_device *s,
				struct v4l2_control *vc)
{
	struct adp1653_flash *flash = s->priv;
	int ctrl;
	int *value;

	switch (vc->id) {
	case V4L2_CID_FLASH_STROBE:
		return adp1653_strobe(s);

	case V4L2_CID_FLASH_TIMEOUT:
		ctrl = CTRL_CAMERA_FLASH_TIMEOUT;
		value = &flash->flash_timeout;
		break;
	case V4L2_CID_FLASH_INTENSITY:
		ctrl = CTRL_CAMERA_FLASH_INTENSITY;
		value = &flash->flash_intensity;
		break;
	case V4L2_CID_TORCH_INTENSITY:
		ctrl = CTRL_CAMERA_FLASH_TORCH_INTENSITY;
		value = &flash->torch_intensity;
		break;
	case V4L2_CID_INDICATOR_INTENSITY:
		ctrl = CTRL_CAMERA_FLASH_INDICATOR_INTENSITY;
		value = &flash->indicator_intensity;
		break;

	default:
		return -EINVAL;
	}

	if (vc->value < adp1653_ctrls[ctrl].minimum)
		vc->value = adp1653_ctrls[ctrl].minimum;
	if (vc->value > adp1653_ctrls[ctrl].maximum)
		vc->value = adp1653_ctrls[ctrl].maximum;
	vc->value = (vc->value - adp1653_ctrls[ctrl].minimum
		    + (adp1653_ctrls[ctrl].step >> 1))
		    / adp1653_ctrls[ctrl].step;
	vc->value = vc->value * adp1653_ctrls[ctrl].step
		    + adp1653_ctrls[ctrl].minimum;
	*value = vc->value;

	return adp1653_update_hw(s);
}
Example #6
0
static int adp1653_init_device(struct v4l2_int_device *s)
{
	struct adp1653_flash *flash = s->priv;
	int rval;

	/* Clear FAULT register by writing zero to OUT_SEL */
	rval = i2c_smbus_write_byte_data(flash->i2c_client,
					 ADP1653_REG_OUT_SEL, 0);
	if (rval < 0) {
		dev_err(&flash->i2c_client->dev,
			"failed writing fault register\n");
		return -ENODEV;
	}

	/* Read FAULT register */
	rval = i2c_smbus_read_byte_data(flash->i2c_client, ADP1653_REG_FAULT);
	if (rval < 0) {
		dev_err(&flash->i2c_client->dev,
			"failed reading fault register\n");
		return -ENODEV;
	}

	if ((rval & 0x0f) != 0) {
		dev_err(&flash->i2c_client->dev, "device fault\n");
		return -ENODEV;
	}

	rval = adp1653_update_hw(s);
	if (rval) {
		dev_err(&flash->i2c_client->dev,
			"adp1653_update_hw failed at adp1653_init_device\n");
		return -ENODEV;
	}

	return 0;
}