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

Commit 6c4ebc42 authored by Ivan Tiyanov's avatar Ivan Tiyanov
Browse files

msm: camera: Add Dual LED torch support



Adding Dual LED torch support.
This feature enables the Dual LED torch if HW supports it.
MSM8994 supports Dual LED for torch.

Change-Id: I1a4f7101997526f517d4794afca763e02dad2202
Signed-off-by: default avatarIvan Tiyanov <ivant@codeaurora.org>
parent 1450dc76
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -49,17 +49,21 @@ struct msm_led_flash_ctrl_t {
	struct msm_flash_fn_t *func_tbl;
	struct msm_camera_sensor_board_info *flashdata;
	struct msm_led_flash_reg_t *reg_setting;
	/* Flash */
	const char *flash_trigger_name[MAX_LED_TRIGGERS];
	struct led_trigger *flash_trigger[MAX_LED_TRIGGERS];
	uint32_t flash_num_sources;
	uint32_t flash_op_current[MAX_LED_TRIGGERS];
	uint32_t flash_max_current[MAX_LED_TRIGGERS];
	uint32_t flash_max_duration[MAX_LED_TRIGGERS];
	const char *torch_trigger_name;
	struct led_trigger *torch_trigger;
	uint32_t torch_op_current;
	uint32_t torch_max_current;
	/* Torch */
	const char *torch_trigger_name[MAX_LED_TRIGGERS];
	struct led_trigger *torch_trigger[MAX_LED_TRIGGERS];
	uint32_t torch_num_sources;
	uint32_t torch_op_current[MAX_LED_TRIGGERS];
	uint32_t torch_max_current[MAX_LED_TRIGGERS];

	void *data;
	uint32_t num_sources;
	enum msm_camera_device_type_t flash_device_type;
	enum cci_i2c_master_t cci_i2c_master;
	uint32_t subdev_id;
+2 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ int32_t msm_led_i2c_trigger_config(struct msm_led_flash_ctrl_t *fctrl,
				fctrl->flash_max_current[i];
			cfg->flash_duration[i] =
				fctrl->flash_max_duration[i];
			cfg->torch_current[i] =
				fctrl->torch_max_current[i];
		}
		break;

+14 −9
Original line number Diff line number Diff line
@@ -38,23 +38,28 @@ static struct led_classdev msm_torch_led = {
int32_t msm_led_torch_create_classdev(struct platform_device *pdev,
				void *data)
{
	int32_t rc = 0;
	int32_t i, rc = 0;
	struct msm_led_flash_ctrl_t *fctrl =
		(struct msm_led_flash_ctrl_t *)data;

	if (!fctrl || !fctrl->torch_trigger) {
		pr_err("Invalid fctrl or torch trigger\n");
	if (!fctrl) {
		pr_err("Invalid fctrl\n");
		return -EINVAL;
	}

	torch_trigger = fctrl->torch_trigger;
	for (i = 0; i < fctrl->torch_num_sources; i++) {
		if (fctrl->torch_trigger[i]) {
			torch_trigger = fctrl->torch_trigger[i];
			msm_led_torch_brightness_set(&msm_torch_led, LED_OFF);

			rc = led_classdev_register(&pdev->dev, &msm_torch_led);
			if (rc) {
		pr_err("Failed to register led dev. rc = %d\n", rc);
				pr_err("Failed to register %d led dev. rc = %d\n",
						i, rc);
				return rc;
			}
		}
	}

	return 0;
};
+81 −56
Original line number Diff line number Diff line
@@ -56,33 +56,40 @@ static int32_t msm_led_trigger_config(struct msm_led_flash_ctrl_t *fctrl,

	switch (cfg->cfgtype) {
	case MSM_CAMERA_LED_OFF:
		for (i = 0; i < fctrl->num_sources; i++)
		/* Flash off */
		for (i = 0; i < fctrl->flash_num_sources; i++)
			if (fctrl->flash_trigger[i])
				led_trigger_event(fctrl->flash_trigger[i], 0);
		if (fctrl->torch_trigger)
			led_trigger_event(fctrl->torch_trigger, 0);
		/* Torch off */
		for (i = 0; i < fctrl->torch_num_sources; i++)
			if (fctrl->torch_trigger[i])
				led_trigger_event(fctrl->torch_trigger[i], 0);
		break;

	case MSM_CAMERA_LED_LOW:
		if (fctrl->torch_trigger) {
			max_curr_l = fctrl->torch_max_current;
			if (cfg->torch_current > 0 &&
				cfg->torch_current < max_curr_l) {
				curr_l = cfg->torch_current;
		for (i = 0; i < fctrl->torch_num_sources; i++)
			if (fctrl->torch_trigger[i]) {
				max_curr_l = fctrl->torch_max_current[i];
				if (cfg->torch_current[i] > 0 &&
					cfg->torch_current[i] < max_curr_l) {
					curr_l = cfg->torch_current[i];
				} else {
				curr_l = fctrl->torch_op_current;
				pr_debug("LED current clamped to %d\n",
					curr_l);
					curr_l = fctrl->torch_op_current[i];
					pr_debug("LED torch %d clamped %d\n",
						i, curr_l);
				}
			led_trigger_event(fctrl->torch_trigger,
				led_trigger_event(fctrl->torch_trigger[i],
						curr_l);
			}
		break;

	case MSM_CAMERA_LED_HIGH:
		if (fctrl->torch_trigger)
			led_trigger_event(fctrl->torch_trigger, 0);
		for (i = 0; i < fctrl->num_sources; i++)
		/* Torch off */
		for (i = 0; i < fctrl->torch_num_sources; i++)
			if (fctrl->torch_trigger[i])
				led_trigger_event(fctrl->torch_trigger[i], 0);

		for (i = 0; i < fctrl->flash_num_sources; i++)
			if (fctrl->flash_trigger[i]) {
				max_curr_l = fctrl->flash_max_current[i];
				if (cfg->flash_current[i] > 0 &&
@@ -90,8 +97,8 @@ static int32_t msm_led_trigger_config(struct msm_led_flash_ctrl_t *fctrl,
					curr_l = cfg->flash_current[i];
				} else {
					curr_l = fctrl->flash_op_current[i];
					pr_debug("LED current clamped to %d\n",
						curr_l);
					pr_debug("LED flash %d clamped %d\n",
						i, curr_l);
				}
				led_trigger_event(fctrl->flash_trigger[i],
					curr_l);
@@ -100,11 +107,14 @@ static int32_t msm_led_trigger_config(struct msm_led_flash_ctrl_t *fctrl,

	case MSM_CAMERA_LED_INIT:
	case MSM_CAMERA_LED_RELEASE:
		for (i = 0; i < fctrl->num_sources; i++)
		/* Flash off */
		for (i = 0; i < fctrl->flash_num_sources; i++)
			if (fctrl->flash_trigger[i])
				led_trigger_event(fctrl->flash_trigger[i], 0);
		if (fctrl->torch_trigger)
			led_trigger_event(fctrl->torch_trigger, 0);
		/* Torch off */
		for (i = 0; i < fctrl->torch_num_sources; i++)
			if (fctrl->torch_trigger[i])
				led_trigger_event(fctrl->torch_trigger[i], 0);
		break;

	default:
@@ -146,7 +156,8 @@ static int32_t msm_led_trigger_probe(struct platform_device *pdev)
	}

	fctrl.pdev = pdev;
	fctrl.num_sources = 0;
	fctrl.flash_num_sources = 0;
	fctrl.torch_num_sources = 0;

	rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
	if (rc < 0) {
@@ -162,19 +173,20 @@ static int32_t msm_led_trigger_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	/* Flash source */
	if (of_get_property(of_node, "qcom,flash-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
		CDBG("qcom,flash-source count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("invalid count\n");
			pr_err("invalid count qcom,flash-source %d\n", count);
			return -EINVAL;
		}
		fctrl.num_sources = count;
		for (i = 0; i < count; i++) {
		fctrl.flash_num_sources = count;
		for (i = 0; i < fctrl.flash_num_sources; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,flash-source", i);
			if (!flash_src_node) {
				pr_err("flash_src_node NULL\n");
				pr_err("flash_src_node %d NULL\n", i);
				continue;
			}

@@ -224,56 +236,69 @@ static int32_t msm_led_trigger_probe(struct platform_device *pdev)
					temp = fctrl.flash_trigger[i];
		}

	}
	/* Torch source */
		flash_src_node = of_parse_phandle(of_node, "qcom,torch-source",
			0);
		if (flash_src_node) {
	if (of_get_property(of_node, "qcom,torch-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("qcom,torch-source count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("invalid count qcom,torch-source %d\n", count);
			return -EINVAL;
		}
		fctrl.torch_num_sources = count;

		for (i = 0; i < fctrl.torch_num_sources; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,torch-source", i);
			if (!flash_src_node) {
				pr_err("torch_src_node %d NULL\n", i);
				continue;
			}

			rc = of_property_read_string(flash_src_node,
				"linux,default-trigger",
				&fctrl.torch_trigger_name);
				&fctrl.torch_trigger_name[i]);

			rc_1 = of_property_read_string(flash_src_node,
				"qcom,default-led-trigger",
				&fctrl.torch_trigger_name);
				&fctrl.torch_trigger_name[i]);
			if ((rc < 0) && (rc_1 < 0)) {
				pr_err("default-trigger: read failed\n");
				goto torch_failed;
				of_node_put(flash_src_node);
				continue;
			}

			CDBG("default trigger %s\n",
				fctrl.torch_trigger_name);
				fctrl.torch_trigger_name[i]);

			if (flashtype == GPIO_FLASH) {
				/* use fake current */
				fctrl.torch_op_current = LED_HALF;
				if (temp)
					fctrl.torch_trigger = temp;
				else
					led_trigger_register_simple(
						fctrl.torch_trigger_name,
						&fctrl.torch_trigger);
				fctrl.torch_op_current[i] = LED_HALF;
			} else {
				rc = of_property_read_u32(flash_src_node,
					"qcom,current",
					&fctrl.torch_op_current);
					&fctrl.torch_op_current[i]);
				rc_1 = of_property_read_u32(flash_src_node,
					"qcom,max-current",
					&fctrl.torch_max_current);

					&fctrl.torch_max_current[i]);
				if ((rc < 0) || (rc_1 < 0)) {
					pr_err("current: read failed\n");
					goto torch_failed;
					of_node_put(flash_src_node);
					continue;
				}

				CDBG("torch max_current %d\n",
					fctrl.torch_op_current);

				led_trigger_register_simple(
					fctrl.torch_trigger_name,
					&fctrl.torch_trigger);
			}
torch_failed:

			of_node_put(flash_src_node);

			CDBG("torch max_current[%d] %d\n",
				i, fctrl.torch_op_current[i]);

			led_trigger_register_simple(fctrl.torch_trigger_name[i],
				&fctrl.torch_trigger[i]);

			if (flashtype == GPIO_FLASH)
				if (temp && !fctrl.torch_trigger[i])
					fctrl.torch_trigger[i] = temp;
		}
	}

+1 −1
Original line number Diff line number Diff line
@@ -547,7 +547,7 @@ enum msm_camera_led_config_t {

struct msm_camera_led_cfg_t {
	enum msm_camera_led_config_t cfgtype;
	uint32_t torch_current;
	uint32_t torch_current[MAX_LED_TRIGGERS];
	uint32_t flash_current[MAX_LED_TRIGGERS];
	uint32_t flash_duration[MAX_LED_TRIGGERS];
};