Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67883311 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: Add LED flash support for 8916 Camera."

parents 572a4528 f8a6db42
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@ Required properties:
    - 0, 1, 2, 3
- compatible :
    - "qcom,camera-led-flash"
    - "qcom,led-flash"
    - "qcom,led-flash1"
- reg : offset and length of the register set for the device.
    for the flash operating in compatible mode.
- gpios : should contain phandle to gpio controller node and array of
@@ -16,10 +18,12 @@ Required properties:
    qcom,gpio-req-tbl-num property (in the same order)
- qcom,gpio-req-tbl-label : should contain name of gpios present in
    qcom,gpio-req-tbl-num property (in the same order)
- qcom,gpio-flash-reset : should contain index to gpio used by flash's "flash reset" pin.
- qcom,gpio-flash-en : should contain index to gpio used by flash's "flash enable" pin.
- qcom,gpio-flash-now : should contain index to gpio used by flash's "flash now" pin.
- label : should contain unique flash name to differentiate from other flash
    - "adp1660"
    - "bd7710"
- qcom,flash-type : Should contain type flash device
    - 1 for LED flash
    - 2 for strobe flash
@@ -52,6 +56,8 @@ qcom,led-flash@60 {
		qcom,cci-master = <0>;
		gpios = <&msmgpio 23 0>,
			<&msmgpio 24 0>;
			<&msmgpio 25 0>;
		qcom,gpio-flash-reset = <0>;
		qcom,gpio-flash-en = <0>;
		qcom,gpio-flash-now = <1>;
		qcom,gpio-req-tbl-num = <0 1>;
+1 −0
Original line number Diff line number Diff line
@@ -4,4 +4,5 @@ obj-$(CONFIG_MSMB_CAMERA) += msm_led_flash.o
obj-$(CONFIG_MSMB_CAMERA) += msm_led_trigger.o
obj-$(CONFIG_MSMB_CAMERA) += msm_led_i2c_trigger.o
obj-$(CONFIG_MSMB_CAMERA) += adp1660.o
obj-$(CONFIG_MSMB_CAMERA) += bd7710.o
obj-$(CONFIG_MSMB_CAMERA) += msm_led_torch.o
+209 −0
Original line number Diff line number Diff line
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#include <linux/module.h>
#include <linux/export.h>
#include "msm_led_flash.h"

#define FLASH_NAME "qcom,led-flash1"

/*#define CONFIG_MSMB_CAMERA_DEBUG*/
#undef CDBG
#ifdef CONFIG_MSMB_CAMERA_DEBUG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
#else
#define CDBG(fmt, args...) do { } while (0)
#endif

static struct msm_led_flash_ctrl_t fctrl;
static struct i2c_driver bd7710_i2c_driver;

static struct msm_camera_i2c_reg_array bd7710_init_array[] = {
	{0x00, 0x10},
};

static struct msm_camera_i2c_reg_array bd7710_off_array[] = {
	{0x05, 0x00},
	{0x02, 0x00},
};

static struct msm_camera_i2c_reg_array bd7710_release_array[] = {
	{0x00, 0x00},
};

static struct msm_camera_i2c_reg_array bd7710_low_array[] = {
	{0x05, 0x25},
	{0x00, 0x38},
	{0x02, 0x40},
};

static struct msm_camera_i2c_reg_array bd7710_high_array[] = {
	{0x05, 0x25},
	{0x02, 0xBF},
};

static void __exit msm_flash_bd7710_i2c_remove(void)
{
	i2c_del_driver(&bd7710_i2c_driver);
	return;
}

static const struct of_device_id bd7710_trigger_dt_match[] = {
	{.compatible = "qcom,led-flash1", .data = &fctrl},
	{}
};

MODULE_DEVICE_TABLE(of, bd7710_trigger_dt_match);

static const struct i2c_device_id flash_i2c_id[] = {
	{"qcom,led-flash1", (kernel_ulong_t)&fctrl},
	{ }
};

static const struct i2c_device_id bd7710_i2c_id[] = {
	{FLASH_NAME, (kernel_ulong_t)&fctrl},
	{ }
};

static int msm_flash_bd7710_i2c_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	if (!id) {
		pr_err("msm_flash_bd7710_i2c_probe: id is NULL");
		id = bd7710_i2c_id;
	}

	return msm_flash_i2c_probe(client, id);
}

static struct i2c_driver bd7710_i2c_driver = {
	.id_table = bd7710_i2c_id,
	.probe  = msm_flash_bd7710_i2c_probe,
	.remove = __exit_p(msm_flash_bd7710_i2c_remove),
	.driver = {
		.name = FLASH_NAME,
		.owner = THIS_MODULE,
		.of_match_table = bd7710_trigger_dt_match,
	},
};

static int msm_flash_bd7710_platform_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;

	match = of_match_device(bd7710_trigger_dt_match, &pdev->dev);
	if (!match)
		return -EFAULT;
	return msm_flash_probe(pdev, match->data);
}

static struct platform_driver bd7710_platform_driver = {
	.probe = msm_flash_bd7710_platform_probe,
	.driver = {
		.name = "qcom,led-flash1",
		.owner = THIS_MODULE,
		.of_match_table = bd7710_trigger_dt_match,
	},
};

static int __init msm_flash_bd7710_init_module(void)
{
	int32_t rc = 0;

	rc = platform_driver_register(&bd7710_platform_driver);
	if (!rc)
		return rc;
	pr_debug("%s:%d rc %d\n", __func__, __LINE__, rc);
	return i2c_add_driver(&bd7710_i2c_driver);
}

static void __exit msm_flash_bd7710_exit_module(void)
{
	if (fctrl.pdev)
		platform_driver_unregister(&bd7710_platform_driver);
	else
		i2c_del_driver(&bd7710_i2c_driver);
}

static struct msm_camera_i2c_client bd7710_i2c_client = {
	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
};

static struct msm_camera_i2c_reg_setting bd7710_init_setting = {
	.reg_setting = bd7710_init_array,
	.size = ARRAY_SIZE(bd7710_init_array),
	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
	.delay = 0,
};

static struct msm_camera_i2c_reg_setting bd7710_off_setting = {
	.reg_setting = bd7710_off_array,
	.size = ARRAY_SIZE(bd7710_off_array),
	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
	.delay = 0,
};

static struct msm_camera_i2c_reg_setting bd7710_release_setting = {
	.reg_setting = bd7710_release_array,
	.size = ARRAY_SIZE(bd7710_release_array),
	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
	.delay = 0,
};

static struct msm_camera_i2c_reg_setting bd7710_low_setting = {
	.reg_setting = bd7710_low_array,
	.size = ARRAY_SIZE(bd7710_low_array),
	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
	.delay = 0,
};

static struct msm_camera_i2c_reg_setting bd7710_high_setting = {
	.reg_setting = bd7710_high_array,
	.size = ARRAY_SIZE(bd7710_high_array),
	.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
	.data_type = MSM_CAMERA_I2C_BYTE_DATA,
	.delay = 0,
};

static struct msm_led_flash_reg_t bd7710_regs = {
	.init_setting = &bd7710_init_setting,
	.off_setting = &bd7710_off_setting,
	.low_setting = &bd7710_low_setting,
	.high_setting = &bd7710_high_setting,
	.release_setting = &bd7710_release_setting,
};

static struct msm_flash_fn_t bd7710_func_tbl = {
	.flash_get_subdev_id = msm_led_i2c_trigger_get_subdev_id,
	.flash_led_config = msm_led_i2c_trigger_config,
	.flash_led_init = msm_flash_led_init,
	.flash_led_release = msm_flash_led_release,
	.flash_led_off = msm_flash_led_off,
	.flash_led_low = msm_flash_led_low,
	.flash_led_high = msm_flash_led_high,
};

static struct msm_led_flash_ctrl_t fctrl = {
	.flash_i2c_client = &bd7710_i2c_client,
	.reg_setting = &bd7710_regs,
	.func_tbl = &bd7710_func_tbl,
};

/*subsys_initcall(msm_flash_i2c_add_driver);*/
module_init(msm_flash_bd7710_init_module);
module_exit(msm_flash_bd7710_exit_module);
MODULE_DESCRIPTION("bd7710 FLASH");
MODULE_LICENSE("GPL v2");
+2 −0
Original line number Diff line number Diff line
@@ -62,7 +62,9 @@ struct msm_led_flash_ctrl_t {
	uint32_t num_sources;
	enum msm_camera_device_type_t flash_device_type;
	enum cci_i2c_master_t cci_i2c_master;
	enum msm_camera_led_config_t led_state;
	uint32_t subdev_id;
	struct msm_pinctrl_info pinctrl_info;
};

int msm_flash_i2c_probe(struct i2c_client *client,
+95 −6
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@
#include <linux/debugfs.h>

#define FLASH_NAME "camera-led-flash"

#define CAM_FLASH_PINCTRL_STATE_SLEEP "cam_flash_suspend"
#define CAM_FLASH_PINCTRL_STATE_DEFAULT "cam_flash_default"
/*#define CONFIG_MSMB_CAMERA_DEBUG*/
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)

@@ -92,6 +94,39 @@ int32_t msm_led_i2c_trigger_config(struct msm_led_flash_ctrl_t *fctrl,
	CDBG("flash_set_led_state: return %d\n", rc);
	return rc;
}
static int msm_flash_pinctrl_init(struct msm_led_flash_ctrl_t *ctrl)
{
	struct msm_pinctrl_info *flash_pctrl = NULL;

	flash_pctrl = &ctrl->pinctrl_info;
	flash_pctrl->pinctrl = devm_pinctrl_get(&ctrl->pdev->dev);

	if (IS_ERR_OR_NULL(flash_pctrl->pinctrl)) {
		pr_err("%s:%d Getting pinctrl handle failed\n",
			__func__, __LINE__);
		return -EINVAL;
	}
	flash_pctrl->gpio_state_active = pinctrl_lookup_state(
					       flash_pctrl->pinctrl,
					       CAM_FLASH_PINCTRL_STATE_DEFAULT);

	if (IS_ERR_OR_NULL(flash_pctrl->gpio_state_active)) {
		pr_err("%s:%d Failed to get the active state pinctrl handle\n",
			__func__, __LINE__);
		return -EINVAL;
	}
	flash_pctrl->gpio_state_suspend = pinctrl_lookup_state(
						flash_pctrl->pinctrl,
						CAM_FLASH_PINCTRL_STATE_SLEEP);

	if (IS_ERR_OR_NULL(flash_pctrl->gpio_state_suspend)) {
		pr_err("%s:%d Failed to get the suspend state pinctrl handle\n",
				__func__, __LINE__);
		return -EINVAL;
	}
	return 0;
}


int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl)
{
@@ -102,6 +137,7 @@ int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl)

	flashdata = fctrl->flashdata;
	power_info = &flashdata->power_info;
	fctrl->led_state = MSM_CAMERA_LED_RELEASE;
	if (power_info->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
		pr_err("%s:%d mux install\n", __func__, __LINE__);
	}
@@ -115,7 +151,6 @@ int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl)
			return rc;
		}
	}

	rc = msm_camera_request_gpio_table(
		power_info->gpio_conf->cam_gpio_req_tbl,
		power_info->gpio_conf->cam_gpio_req_tbl_size, 1);
@@ -124,7 +159,27 @@ int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl)
		return rc;
	}

	if (fctrl->pinctrl_info.use_pinctrl == true) {
		CDBG("%s:%d PC:: flash pins setting to active state",
				__func__, __LINE__);
		rc = pinctrl_select_state(fctrl->pinctrl_info.pinctrl,
				fctrl->pinctrl_info.gpio_state_active);
		if (rc < 0) {
			devm_pinctrl_put(fctrl->pinctrl_info.pinctrl);
			pr_err("%s:%d cannot set pin to active state",
					__func__, __LINE__);
		}
	}
	msleep(20);

	CDBG("before FL_RESET\n");
	if (power_info->gpio_conf->gpio_num_info->
			valid[SENSOR_GPIO_FL_RESET] == 1)
		gpio_set_value_cansleep(
			power_info->gpio_conf->gpio_num_info->
			gpio_num[SENSOR_GPIO_FL_RESET],
			GPIO_OUT_HIGH);

	gpio_set_value_cansleep(
		power_info->gpio_conf->gpio_num_info->
		gpio_num[SENSOR_GPIO_FL_EN],
@@ -142,22 +197,28 @@ int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl)
		if (rc < 0)
			pr_err("%s:%d failed\n", __func__, __LINE__);
	}
	fctrl->led_state = MSM_CAMERA_LED_INIT;
	return rc;
}

int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl)
{
	int rc = 0;
	int rc = 0, ret = 0;
	struct msm_camera_sensor_board_info *flashdata = NULL;
	struct msm_camera_power_ctrl_t *power_info = NULL;

	flashdata = fctrl->flashdata;
	power_info = &flashdata->power_info;
	CDBG("%s:%d called\n", __func__, __LINE__);
	if (!fctrl) {
		pr_err("%s:%d fctrl NULL\n", __func__, __LINE__);
		return -EINVAL;
	}
	flashdata = fctrl->flashdata;
	power_info = &flashdata->power_info;
	CDBG("%s:%d called\n", __func__, __LINE__);

	if (fctrl->led_state != MSM_CAMERA_LED_INIT) {
		pr_err("%s:%d invalid led state\n", __func__, __LINE__);
		return -EINVAL;
	}
	gpio_set_value_cansleep(
		power_info->gpio_conf->gpio_num_info->
		gpio_num[SENSOR_GPIO_FL_EN],
@@ -166,6 +227,22 @@ int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl)
		power_info->gpio_conf->gpio_num_info->
		gpio_num[SENSOR_GPIO_FL_NOW],
		GPIO_OUT_LOW);
	if (power_info->gpio_conf->gpio_num_info->
			valid[SENSOR_GPIO_FL_RESET] == 1)
		gpio_set_value_cansleep(
			power_info->gpio_conf->gpio_num_info->
			gpio_num[SENSOR_GPIO_FL_RESET],
			GPIO_OUT_LOW);

	if (fctrl->pinctrl_info.use_pinctrl == true) {
		ret = pinctrl_select_state(fctrl->pinctrl_info.pinctrl,
				fctrl->pinctrl_info.gpio_state_suspend);
		if (ret < 0) {
			devm_pinctrl_put(fctrl->pinctrl_info.pinctrl);
			pr_err("%s:%d cannot set pin to suspend state",
				__func__, __LINE__);
		}
	}
	rc = msm_camera_request_gpio_table(
		power_info->gpio_conf->cam_gpio_req_tbl,
		power_info->gpio_conf->cam_gpio_req_tbl_size, 0);
@@ -174,6 +251,7 @@ int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl)
		return rc;
	}

	fctrl->led_state = MSM_CAMERA_LED_RELEASE;
	/* CCI deInit */
	if (fctrl->flash_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
		rc = fctrl->flash_i2c_client->i2c_func_tbl->i2c_util(
@@ -181,6 +259,7 @@ int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl)
		if (rc < 0)
			pr_err("cci_deinit failed\n");
	}

	return 0;
}

@@ -331,6 +410,9 @@ static int32_t msm_led_get_dt_data(struct device_node *of_node,
		rc = 0;
	}

	fctrl->pinctrl_info.use_pinctrl = false;
	fctrl->pinctrl_info.use_pinctrl = of_property_read_bool(of_node,
						"qcom,enable_pinctrl");
	if (of_get_property(of_node, "qcom,flash-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
@@ -589,6 +671,10 @@ int msm_flash_i2c_probe(struct i2c_client *client,
		pr_err("%s failed line %d\n", __func__, __LINE__);
		return rc;
	}

	if (fctrl->pinctrl_info.use_pinctrl == true)
		msm_flash_pinctrl_init(fctrl);

	if (fctrl->flash_i2c_client != NULL) {
		fctrl->flash_i2c_client->client = client;
		if (fctrl->flashdata->slave_info->sensor_slave_addr)
@@ -642,6 +728,9 @@ int msm_flash_probe(struct platform_device *pdev,
		return rc;
	}

	if (fctrl->pinctrl_info.use_pinctrl == true)
		msm_flash_pinctrl_init(fctrl);

	/* Assign name for sub device */
	snprintf(fctrl->msm_sd.sd.name, sizeof(fctrl->msm_sd.sd.name),
			"%s", fctrl->flashdata->sensor_name);
Loading