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

Commit d9093bd2 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: bug fix in IR LED driver"

parents 6476ff8f 67dcbd3c
Loading
Loading
Loading
Loading
+61 −66
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

#include <linux/module.h>
#include <linux/pwm.h>
#include <linux/delay.h>
#include "msm_ir_led.h"
#include "msm_camera_dt_util.h"

@@ -41,7 +42,6 @@ static int32_t msm_ir_led_get_subdev_id(
{
	uint32_t *subdev_id = (uint32_t *)arg;

	CDBG("Enter\n");
	if (!subdev_id) {
		pr_err("subdevice ID is not valid\n");
		return -EINVAL;
@@ -54,7 +54,6 @@ static int32_t msm_ir_led_get_subdev_id(
	*subdev_id = ir_led_ctrl->pdev->id;

	CDBG("subdev_id %d\n", *subdev_id);
	CDBG("Exit\n");
	return 0;
}

@@ -64,45 +63,64 @@ static int32_t msm_ir_led_init(
{
	int32_t rc = 0;

	CDBG("Enter\n");

	rc = ir_led_ctrl->func_tbl->camera_ir_led_off(ir_led_ctrl, ir_led_data);

	CDBG("Exit\n");
	return rc;
}

static int32_t msm_ir_led_release(
	struct msm_ir_led_ctrl_t *ir_led_ctrl)
	struct msm_ir_led_ctrl_t *ir_led_ctrl,
		struct msm_ir_led_cfg_data_t *ir_led_data)
{
	int32_t rc = 0;
	int32_t rc = -EFAULT;

	if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_RELEASE) {
		pr_err("Invalid ir_led state = %d\n",
			ir_led_ctrl->ir_led_state);
		return 0;
		return rc;
	}

	rc = ir_led_ctrl->func_tbl->camera_ir_led_off(ir_led_ctrl, NULL);
	rc = ir_led_ctrl->func_tbl->camera_ir_led_off(ir_led_ctrl, ir_led_data);
	if (rc < 0) {
		pr_err("camera_ir_led_off failed (%d)\n", rc);
		return rc;
	}
	ir_led_ctrl->ir_led_state = MSM_CAMERA_IR_LED_RELEASE;
	return 0;

	return rc;
}

static int32_t msm_ir_led_off(struct msm_ir_led_ctrl_t *ir_led_ctrl,
	struct msm_ir_led_cfg_data_t *ir_led_data)
{
	CDBG("Enter\n");
	int32_t rc = 0;

	CDBG("pwm duty on(ns) %d, pwm period(ns) %d\n",
		ir_led_data->pwm_duty_on_ns, ir_led_data->pwm_period_ns);

	if (ir_led_data->pwm_period_ns <= 0)
		ir_led_data->pwm_period_ns = DEFAULT_PWM_TIME_PERIOD_NS;

	if (ir_led_data->pwm_duty_on_ns != 0)
		ir_led_data->pwm_duty_on_ns = DEFAULT_PWM_DUTY_CYCLE_NS;

	if (ir_led_ctrl->pwm_dev) {
		rc = pwm_config(ir_led_ctrl->pwm_dev,
			ir_led_data->pwm_duty_on_ns,
			ir_led_data->pwm_period_ns);

		if (rc) {
			pr_err("PWM config failed (%d)\n", rc);
			return rc;
		}
		/*workaround to disable pwm_module*/
		udelay(50);

	if (ir_led_ctrl->pwm_dev)
		pwm_disable(ir_led_ctrl->pwm_dev);
	else
		pr_err("pwm device is null\n");
	} else {
		CDBG("pwm device is null\n");
	}

	CDBG("Exit\n");
	return 0;
}

@@ -110,7 +128,7 @@ static int32_t msm_ir_led_on(
	struct msm_ir_led_ctrl_t *ir_led_ctrl,
	struct msm_ir_led_cfg_data_t *ir_led_data)
{
	int rc;
	int32_t rc = 0;

	CDBG("pwm duty on(ns) %d, pwm period(ns) %d\n",
		ir_led_data->pwm_duty_on_ns, ir_led_data->pwm_period_ns);
@@ -129,9 +147,9 @@ static int32_t msm_ir_led_on(
			pr_err("PWM enable failed(%d)\n", rc);
			return rc;
		}
	} else
		pr_err("pwm device is null\n");

	} else {
		CDBG("pwm device is null\n");
	}
	return 0;
}

@@ -144,12 +162,10 @@ static int32_t msm_ir_led_handle_init(
	enum msm_ir_led_driver_type ir_led_driver_type =
		ir_led_ctrl->ir_led_driver_type;

	CDBG("Enter\n");

	if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT) {
		pr_err("Invalid ir_led state = %d\n",
				ir_led_ctrl->ir_led_state);
		return 0;
		return rc;
	}

	for (i = 0; i < ARRAY_SIZE(ir_led_table); i++) {
@@ -175,8 +191,8 @@ static int32_t msm_ir_led_handle_init(

	ir_led_ctrl->ir_led_state = MSM_CAMERA_IR_LED_INIT;

	CDBG("Exit\n");
	return 0;
	CDBG("IR LED STATE intialised Successfully\n");
	return rc;
}

static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl,
@@ -186,10 +202,10 @@ static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl,
	struct msm_ir_led_cfg_data_t *ir_led_data =
		(struct msm_ir_led_cfg_data_t *) argp;

	mutex_lock(ir_led_ctrl->ir_led_mutex);

	CDBG("type %d\n", ir_led_data->cfg_type);

	mutex_lock(ir_led_ctrl->ir_led_mutex);

	switch (ir_led_data->cfg_type) {
	case CFG_IR_LED_INIT:
		rc = msm_ir_led_handle_init(ir_led_ctrl, ir_led_data);
@@ -197,7 +213,7 @@ static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl,
	case CFG_IR_LED_RELEASE:
		if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT)
			rc = ir_led_ctrl->func_tbl->camera_ir_led_release(
				ir_led_ctrl);
				ir_led_ctrl, ir_led_data);
		break;
	case CFG_IR_LED_OFF:
		if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT)
@@ -216,7 +232,7 @@ static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl,

	mutex_unlock(ir_led_ctrl->ir_led_mutex);

	CDBG("Exit: type %d\n", ir_led_data->cfg_type);
	CDBG("Exit (%d): type %d\n", rc, ir_led_data->cfg_type);

	return rc;
}
@@ -226,8 +242,7 @@ static long msm_ir_led_subdev_ioctl(struct v4l2_subdev *sd,
{
	struct msm_ir_led_ctrl_t *fctrl = NULL;
	void __user *argp = (void __user *)arg;

	CDBG("Enter\n");
	struct msm_ir_led_cfg_data_t *ir_led_data;

	if (!sd) {
		pr_err(" v4l2 ir led subdevice is NULL\n");
@@ -246,17 +261,18 @@ static long msm_ir_led_subdev_ioctl(struct v4l2_subdev *sd,
	case MSM_SD_NOTIFY_FREEZE:
		return 0;
	case MSM_SD_SHUTDOWN:
		ir_led_data = (struct msm_ir_led_cfg_data_t *)argp;
		if (!fctrl->func_tbl) {
			pr_err("No call back funcions\n");
			return -EINVAL;
		} else {
			return fctrl->func_tbl->camera_ir_led_release(fctrl);
			return fctrl->func_tbl->camera_ir_led_release(fctrl,
							ir_led_data);
		}
	default:
		pr_err_ratelimited("invalid cmd %d\n", cmd);
		return -ENOIOCTLCMD;
	}
	CDBG("Exit\n");
}

static struct v4l2_subdev_core_ops msm_ir_led_subdev_core_ops = {
@@ -267,39 +283,13 @@ static struct v4l2_subdev_ops msm_ir_led_subdev_ops = {
	.core = &msm_ir_led_subdev_core_ops,
};

static int msm_ir_led_close(struct v4l2_subdev *sd,
			struct v4l2_subdev_fh *fh) {

	int rc = 0;
	struct msm_ir_led_ctrl_t *ir_led_ctrl = v4l2_get_subdevdata(sd);

	if (!ir_led_ctrl) {
		pr_err("v4l2 subdevice data read failed\n");
		return -EINVAL;
	}

	CDBG("Enter\n");

	if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT)
		rc = ir_led_ctrl->func_tbl->camera_ir_led_release(
			ir_led_ctrl);

	CDBG("Exit (%d)\n", rc);

	return rc;
}

static const struct v4l2_subdev_internal_ops msm_ir_led_internal_ops = {
	.close = msm_ir_led_close,
};
static const struct v4l2_subdev_internal_ops msm_ir_led_internal_ops;

static int32_t msm_ir_led_get_dt_data(struct device_node *of_node,
	struct msm_ir_led_ctrl_t *fctrl)
{
	int32_t rc = 0;

	CDBG("called\n");

	/* Read the sub device */
	rc = of_property_read_u32(of_node, "cell-index", &fctrl->pdev->id);
	if (rc < 0) {
@@ -323,7 +313,6 @@ static long msm_ir_led_subdev_do_ioctl(
		(struct msm_ir_led_cfg_data_t32 *)arg;
	struct msm_ir_led_cfg_data_t ir_led_data;

	CDBG("Enter\n");
	ir_led_data.cfg_type = u32->cfg_type;
	ir_led_data.pwm_duty_on_ns = u32->pwm_duty_on_ns;
	ir_led_data.pwm_period_ns = u32->pwm_period_ns;
@@ -338,7 +327,6 @@ static long msm_ir_led_subdev_do_ioctl(

	rc = msm_ir_led_subdev_ioctl(sd, cmd, &ir_led_data);

	CDBG("Exit\n");
	return rc;
}

@@ -354,7 +342,6 @@ static int32_t msm_ir_led_platform_probe(struct platform_device *pdev)
	int32_t rc = 0;
	struct msm_ir_led_ctrl_t *ir_led_ctrl = NULL;

	CDBG("Enter\n");
	if (!pdev->dev.of_node) {
		pr_err("IR LED device node is not present in device tree\n");
		return -EINVAL;
@@ -370,16 +357,20 @@ static int32_t msm_ir_led_platform_probe(struct platform_device *pdev)
	/* Reading PWM device node */
	ir_led_ctrl->pwm_dev = of_pwm_get(pdev->dev.of_node, NULL);

	if (PTR_ERR(ir_led_ctrl->pwm_dev) == -EPROBE_DEFER) {
		pr_info("Deferring probe...Cannot get PWM device\n");
		return -EPROBE_DEFER;
	}

	if (IS_ERR(ir_led_ctrl->pwm_dev)) {
		rc = PTR_ERR(ir_led_ctrl->pwm_dev);
		pr_err("Cannot get PWM device (%d)\n", rc);
		CDBG("Cannot get PWM device (%d)\n", rc);
		ir_led_ctrl->pwm_dev = NULL;
	}

	rc = msm_ir_led_get_dt_data(pdev->dev.of_node, ir_led_ctrl);
	if (rc < 0) {
		pr_err("msm_ir_led_get_dt_data failed\n");
		devm_kfree(&pdev->dev, ir_led_ctrl);
		return -EINVAL;
	}

@@ -401,7 +392,12 @@ static int32_t msm_ir_led_platform_probe(struct platform_device *pdev)
	ir_led_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	ir_led_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_IR_LED;
	ir_led_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
	msm_sd_register(&ir_led_ctrl->msm_sd);

	rc = msm_sd_register(&ir_led_ctrl->msm_sd);
	if (rc < 0) {
		pr_err("sub dev register failed for ir_led device\n");
		return rc;
	}

	CDBG("ir_led sd name = %s\n",
		ir_led_ctrl->msm_sd.sd.entity.name);
@@ -431,7 +427,6 @@ static int __init msm_ir_led_init_module(void)
{
	int32_t rc = 0;

	CDBG("Enter\n");
	rc = platform_driver_register(&msm_ir_led_platform_driver);
	if (!rc)
		return rc;
+6 −1
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@
#define DEFINE_MSM_MUTEX(mutexname) \
	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)

/* Default frequency is taken as 15KHz*/
#define DEFAULT_PWM_TIME_PERIOD_NS 66667
#define DEFAULT_PWM_DUTY_CYCLE_NS 0

enum msm_camera_ir_led_state_t {
	MSM_CAMERA_IR_LED_INIT,
	MSM_CAMERA_IR_LED_RELEASE,
@@ -39,7 +43,8 @@ struct msm_ir_led_ctrl_t;
struct msm_ir_led_func_t {
	int32_t (*camera_ir_led_init)(struct msm_ir_led_ctrl_t *,
		struct msm_ir_led_cfg_data_t *);
	int32_t (*camera_ir_led_release)(struct msm_ir_led_ctrl_t *);
	int32_t (*camera_ir_led_release)(struct msm_ir_led_ctrl_t *,
		struct msm_ir_led_cfg_data_t *);
	int32_t (*camera_ir_led_off)(struct msm_ir_led_ctrl_t *,
		struct msm_ir_led_cfg_data_t *);
	int32_t (*camera_ir_led_on)(struct msm_ir_led_ctrl_t *,