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

Commit e4648711 authored by Kiran Gunda's avatar Kiran Gunda
Browse files

leds: qpnp-wled: Add sysfs property to enable/disable the irq



WLED interrupts need to be disabled and enabled during the entry and
exit of the secure display use case respectively. Add sysfs property
to allow the userspace to perform this operation.

To disable the interrupts:
 echo 1 > /sys/class/leds/wled/secure_mode

To enable the interrupts:
 echo 0 > /sys/class/leds/wled/secure_mode

Change-Id: Iedf70bcf2fecefcd2e58c213a17bd8b545f93c7a
Signed-off-by: default avatarKiran Gunda <kgunda@codeaurora.org>
parent 4b8ed544
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/spmi.h>
#include <linux/spmi.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/leds-qpnp-wled.h>
#include <linux/leds-qpnp-wled.h>
@@ -420,6 +421,7 @@ struct qpnp_wled {
	bool			prev_state;
	bool			prev_state;
	bool			stepper_en;
	bool			stepper_en;
	bool			ovp_irq_disabled;
	bool			ovp_irq_disabled;
	bool			secure_mode;
	bool			auto_calib_enabled;
	bool			auto_calib_enabled;
	bool			auto_calib_done;
	bool			auto_calib_done;
	bool			module_dis_perm;
	bool			module_dis_perm;
@@ -936,6 +938,46 @@ static ssize_t qpnp_wled_ramp_step_store(struct device *dev,
	return count;
	return count;
}
}


/* sysfs function for irqs enable/disable */
static ssize_t qpnp_wled_irq_control(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	struct qpnp_wled *wled = dev_get_drvdata(dev);
	int val, rc;

	rc = kstrtouint(buf, 0, &val);
	if (rc < 0)
		return rc;

	if (val != 0 && val != 1)
		return count;

	mutex_lock(&wled->lock);
	/* Disable irqs */
	if (val == 1 && !wled->secure_mode) {
		if (wled->ovp_irq > 0)
			disable_irq(wled->ovp_irq);

		if (wled->sc_irq > 0)
			disable_irq(wled->sc_irq);

		wled->secure_mode = true;
	} else if (val == 0 && wled->secure_mode) {
		if (wled->ovp_irq > 0)
			enable_irq(wled->ovp_irq);

		if (wled->sc_irq > 0)
			enable_irq(wled->sc_irq);

		wled->secure_mode = false;
	}

	mutex_unlock(&wled->lock);

	return count;
}

/* sysfs show function for dim mode */
/* sysfs show function for dim mode */
static ssize_t qpnp_wled_dim_mode_show(struct device *dev,
static ssize_t qpnp_wled_dim_mode_show(struct device *dev,
		struct device_attribute *attr, char *buf)
		struct device_attribute *attr, char *buf)
@@ -1055,6 +1097,7 @@ static struct device_attribute qpnp_wled_attrs[] = {
	__ATTR(ramp_ms, 0664, qpnp_wled_ramp_ms_show, qpnp_wled_ramp_ms_store),
	__ATTR(ramp_ms, 0664, qpnp_wled_ramp_ms_show, qpnp_wled_ramp_ms_store),
	__ATTR(ramp_step, 0664, qpnp_wled_ramp_step_show,
	__ATTR(ramp_step, 0664, qpnp_wled_ramp_step_show,
		qpnp_wled_ramp_step_store),
		qpnp_wled_ramp_step_store),
	__ATTR(secure_mode, 0664, NULL, qpnp_wled_irq_control),
};
};


/* worker for setting wled brightness */
/* worker for setting wled brightness */
@@ -1066,6 +1109,12 @@ static void qpnp_wled_work(struct work_struct *work)
	wled = container_of(work, struct qpnp_wled, work);
	wled = container_of(work, struct qpnp_wled, work);


	mutex_lock(&wled->lock);
	mutex_lock(&wled->lock);

	if (wled->secure_mode) {
		pr_debug("Can not set brightness in secure_mode\n ");
		goto unlock_mutex;
	}

	level = wled->cdev.brightness;
	level = wled->cdev.brightness;


	if (wled->brt_map_table) {
	if (wled->brt_map_table) {
@@ -2162,6 +2211,7 @@ static int qpnp_wled_config(struct qpnp_wled *wled)


	/* setup ovp and sc irqs */
	/* setup ovp and sc irqs */
	if (wled->ovp_irq >= 0) {
	if (wled->ovp_irq >= 0) {
		irq_set_status_flags(wled->ovp_irq, IRQ_DISABLE_UNLAZY);
		rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq,
		rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq,
				NULL, qpnp_wled_ovp_irq_handler, IRQF_ONESHOT,
				NULL, qpnp_wled_ovp_irq_handler, IRQF_ONESHOT,
				"qpnp_wled_ovp_irq", wled);
				"qpnp_wled_ovp_irq", wled);
@@ -2182,6 +2232,7 @@ static int qpnp_wled_config(struct qpnp_wled *wled)


	if (wled->sc_irq >= 0) {
	if (wled->sc_irq >= 0) {
		wled->sc_cnt = 0;
		wled->sc_cnt = 0;
		irq_set_status_flags(wled->sc_irq, IRQ_DISABLE_UNLAZY);
		rc = devm_request_threaded_irq(&wled->pdev->dev, wled->sc_irq,
		rc = devm_request_threaded_irq(&wled->pdev->dev, wled->sc_irq,
				NULL, qpnp_wled_sc_irq_handler, IRQF_ONESHOT,
				NULL, qpnp_wled_sc_irq_handler, IRQF_ONESHOT,
				"qpnp_wled_sc_irq", wled);
				"qpnp_wled_sc_irq", wled);