Ejemplo n.º 1
0
/**
 * m5mols_s_power - Main sensor power control function
 *
 * To prevent breaking the lens when the sensor is powered off the Soft-Landing
 * algorithm is called where available. The Soft-Landing algorithm availability
 * dependends on the firmware provider.
 */
static int m5mols_s_power(struct v4l2_subdev *sd, int on)
{
	struct m5mols_info *info = to_m5mols(sd);
	int ret;

	mutex_lock(&info->lock);

	if (on) {
		ret = m5mols_sensor_power(info, true);
		if (!ret)
			ret = m5mols_fw_start(sd);
	} else {
		if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
			ret = m5mols_set_mode(info, REG_MONITOR);
			if (!ret)
				ret = m5mols_auto_focus_stop(info);
			if (ret < 0)
				v4l2_warn(sd, "Soft landing lens failed\n");
		}
		ret = m5mols_sensor_power(info, false);

		info->ctrl_sync = 0;
	}

	mutex_unlock(&info->lock);
	return ret;
}
Ejemplo n.º 2
0
/**
 * m5mols_s_power - Main sensor power control function
 *
 * To prevent breaking the lens when the sensor is powered off the Soft-Landing
 * algorithm is called where available. The Soft-Landing algorithm availability
 * dependends on the firmware provider.
 */
static int m5mols_s_power(struct v4l2_subdev *sd, int on)
{
	struct m5mols_info *info = to_m5mols(sd);
	int ret;

	if (on) {
		ret = m5mols_sensor_power(info, true);
		if (!ret)
			ret = m5mols_fw_start(sd);
		return ret;
	}

	if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
		ret = m5mols_set_mode(info, REG_MONITOR);
		if (!ret)
			ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
		if (!ret)
			ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
		if (!ret)
			ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
					       0xff, -1);
		if (ret < 0)
			v4l2_warn(sd, "Soft landing lens failed\n");
	}

	ret = m5mols_sensor_power(info, false);
	info->ctrl_sync = 0;

	return ret;
}
Ejemplo n.º 3
0
static int m5mols_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	const struct m5mols_platform_data *pdata = client->dev.platform_data;
	struct m5mols_info *info;
	struct v4l2_subdev *sd;
	int ret;

	if (pdata == NULL) {
		dev_err(&client->dev, "No platform data\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_reset)) {
		dev_err(&client->dev, "No valid RESET GPIO specified\n");
		return -EINVAL;
	}

	if (!client->irq) {
		dev_err(&client->dev, "Interrupt not assigned\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->pdata = pdata;
	info->set_power	= pdata->set_power;

	ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
	if (ret) {
		dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
		goto out_free;
	}
	gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);

	ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
	if (ret) {
		dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
		goto out_gpio;
	}

	sd = &info->sd;
	v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
	strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	sd->internal_ops = &m5mols_subdev_internal_ops;
	info->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
	if (ret < 0)
		goto out_reg;
	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

	init_waitqueue_head(&info->irq_waitq);
	mutex_init(&info->lock);

	ret = request_irq(client->irq, m5mols_irq_handler,
			  IRQF_TRIGGER_RISING, MODULE_NAME, sd);
	if (ret) {
		dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
		goto out_me;
	}
	info->res_type = M5MOLS_RESTYPE_MONITOR;
	info->ffmt[0] = m5mols_default_ffmt[0];
	info->ffmt[1] =	m5mols_default_ffmt[1];

	ret = m5mols_sensor_power(info, true);
	if (ret)
		goto out_irq;

	ret = m5mols_fw_start(sd);
	if (!ret)
		ret = m5mols_init_controls(sd);

	ret = m5mols_sensor_power(info, false);
	if (!ret)
		return 0;
out_irq:
	free_irq(client->irq, sd);
out_me:
	media_entity_cleanup(&sd->entity);
out_reg:
	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
out_gpio:
	gpio_free(pdata->gpio_reset);
out_free:
	kfree(info);
	return ret;
}