leds: qpnp-flash-v2: Add support to handle ramp up and down irqs
Add support to register and handle the all-ramp-up-done and all-ramp-down-done irqs for flash-led. CRs-Fixed: 921325 Change-Id: I843a008dbe6900f9f16c202a05435dbaf7a37627 Signed-off-by: Devesh Jhunjhunwala <deveshj@codeaurora.org>
This commit is contained in:
parent
956d9b1ab3
commit
6820e0c51b
3 changed files with 129 additions and 9 deletions
|
@ -13,6 +13,8 @@ Required properties:
|
||||||
- reg : Base address and size for flash LED modules
|
- reg : Base address and size for flash LED modules
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
|
- interrupts : Specifies the interrupts associated with flash-led.
|
||||||
|
- interrupt-names : Specify the interrupt names associated with interrupts.
|
||||||
- qcom,hdrm-auto-mode : Boolean type to select headroom auto mode enabled or not
|
- qcom,hdrm-auto-mode : Boolean type to select headroom auto mode enabled or not
|
||||||
- qcom,isc-delay : Integer type to specify short circuit delay. Valid values are 32, 64,
|
- qcom,isc-delay : Integer type to specify short circuit delay. Valid values are 32, 64,
|
||||||
128, 192. Unit is us.
|
128, 192. Unit is us.
|
||||||
|
@ -93,6 +95,22 @@ Example:
|
||||||
status = "okay";
|
status = "okay";
|
||||||
reg = <0xd300 0x100>;
|
reg = <0xd300 0x100>;
|
||||||
label = "flash";
|
label = "flash";
|
||||||
|
interrupts = <0x3 0xd3 0x0 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x1 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x2 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x3 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x4 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x5 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x6 IRQ_TYPE_EDGE_BOTH>,
|
||||||
|
<0x3 0xd3 0x7 IRQ_TYPE_EDGE_BOTH>;
|
||||||
|
interrupt-names = "led-fault-irq",
|
||||||
|
"mitigation-irq",
|
||||||
|
"flash-timer-exp-irq",
|
||||||
|
"all-ramp-down-done-irq",
|
||||||
|
"all-ramp-up-done-irq",
|
||||||
|
"led3-ramp-up-done-irq",
|
||||||
|
"led2-ramp-up-done-irq",
|
||||||
|
"led1-ramp-up-done-irq";
|
||||||
|
|
||||||
qcom,hdrm-auto-mode;
|
qcom,hdrm-auto-mode;
|
||||||
qcom,isc-delay = <192>;
|
qcom,isc-delay = <192>;
|
||||||
|
|
|
@ -16,13 +16,16 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_gpio.h>
|
#include <linux/of_gpio.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/leds-qpnp-flash-v2.h>
|
#include <linux/leds-qpnp-flash-v2.h>
|
||||||
|
|
||||||
|
#define FLASH_LED_REG_INT_RT_STS(base) (base + 0x10)
|
||||||
#define FLASH_LED_REG_SAFETY_TMR(base) (base + 0x40)
|
#define FLASH_LED_REG_SAFETY_TMR(base) (base + 0x40)
|
||||||
#define FLASH_LED_REG_TGR_CURRENT(base) (base + 0x43)
|
#define FLASH_LED_REG_TGR_CURRENT(base) (base + 0x43)
|
||||||
#define FLASH_LED_REG_MOD_CTRL(base) (base + 0x46)
|
#define FLASH_LED_REG_MOD_CTRL(base) (base + 0x46)
|
||||||
|
@ -40,6 +43,7 @@
|
||||||
#define FLASH_LED_ENABLE_MASK GENMASK(2, 0)
|
#define FLASH_LED_ENABLE_MASK GENMASK(2, 0)
|
||||||
#define FLASH_LED_SAFETY_TMR_MASK GENMASK(7, 0)
|
#define FLASH_LED_SAFETY_TMR_MASK GENMASK(7, 0)
|
||||||
#define FLASH_LED_ISC_DELAY_MASK GENMASK(1, 0)
|
#define FLASH_LED_ISC_DELAY_MASK GENMASK(1, 0)
|
||||||
|
#define FLASH_LED_INT_RT_STS_MASK GENMASK(7, 0)
|
||||||
#define FLASH_LED_MOD_CTRL_MASK BIT(7)
|
#define FLASH_LED_MOD_CTRL_MASK BIT(7)
|
||||||
#define FLASH_LED_HW_SW_STROBE_SEL_MASK BIT(2)
|
#define FLASH_LED_HW_SW_STROBE_SEL_MASK BIT(2)
|
||||||
|
|
||||||
|
@ -125,9 +129,11 @@ struct flash_switch_data {
|
||||||
* Flash LED configuration read from device tree
|
* Flash LED configuration read from device tree
|
||||||
*/
|
*/
|
||||||
struct flash_led_platform_data {
|
struct flash_led_platform_data {
|
||||||
u8 isc_delay_us;
|
int all_ramp_up_done_irq;
|
||||||
u8 hw_strobe_option;
|
int all_ramp_down_done_irq;
|
||||||
bool hdrm_auto_mode_en;
|
u8 isc_delay_us;
|
||||||
|
u8 hw_strobe_option;
|
||||||
|
bool hdrm_auto_mode_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -146,20 +152,37 @@ struct qpnp_flash_led {
|
||||||
u16 base;
|
u16 base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
uint val;
|
||||||
|
|
||||||
|
rc = regmap_read(led->regmap, addr, &val);
|
||||||
|
if (rc < 0)
|
||||||
|
dev_err(&led->pdev->dev, "Unable to read from 0x%04X rc = %d\n",
|
||||||
|
addr, rc);
|
||||||
|
else
|
||||||
|
dev_dbg(&led->pdev->dev, "Read 0x%02X from addr 0x%04X\n",
|
||||||
|
val, addr);
|
||||||
|
|
||||||
|
*data = (u8)val;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qpnp_flash_led_masked_write(struct qpnp_flash_led *led, u16 addr, u8 mask,
|
qpnp_flash_led_masked_write(struct qpnp_flash_led *led, u16 addr, u8 mask,
|
||||||
u8 val)
|
u8 val)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = regmap_update_bits(led->regmap, addr, mask, val);
|
rc = regmap_update_bits(led->regmap, addr, mask, val);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
dev_err(&led->pdev->dev,
|
dev_err(&led->pdev->dev, "Unable to update bits from 0x%04X, rc = %d\n",
|
||||||
"Unable to update bits from 0x%02X, rc = %d\n",
|
addr, rc);
|
||||||
addr, rc);
|
|
||||||
else
|
else
|
||||||
dev_dbg(&led->pdev->dev, "Wrote 0x%02X to addr 0x%02X\n",
|
dev_dbg(&led->pdev->dev, "Wrote 0x%02X to addr 0x%04X\n",
|
||||||
val, addr);
|
val, addr);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -521,6 +544,34 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
|
||||||
spin_unlock(&led->lock);
|
spin_unlock(&led->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* irq handler */
|
||||||
|
static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
|
||||||
|
{
|
||||||
|
struct qpnp_flash_led *led = _led;
|
||||||
|
enum flash_led_irq_type irq_type = INVALID_IRQ;
|
||||||
|
int rc;
|
||||||
|
u8 status;
|
||||||
|
|
||||||
|
dev_dbg(&led->pdev->dev, "irq received, irq=%d\n", irq);
|
||||||
|
|
||||||
|
rc = qpnp_flash_led_read(led,
|
||||||
|
FLASH_LED_REG_INT_RT_STS(led->base), &status);
|
||||||
|
if (rc < 0) {
|
||||||
|
dev_err(&led->pdev->dev, "Failed to read interrupt status reg, rc=%d\n",
|
||||||
|
rc);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irq == led->pdata->all_ramp_up_done_irq)
|
||||||
|
irq_type = ALL_RAMP_UP_DONE_IRQ;
|
||||||
|
else if (irq == led->pdata->all_ramp_down_done_irq)
|
||||||
|
irq_type = ALL_RAMP_DOWN_DONE_IRQ;
|
||||||
|
|
||||||
|
dev_dbg(&led->pdev->dev, "irq handled, irq_type=%x, irq_status=%x\n",
|
||||||
|
irq_type, status);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
static int qpnp_flash_led_regulator_setup(struct qpnp_flash_led *led,
|
static int qpnp_flash_led_regulator_setup(struct qpnp_flash_led *led,
|
||||||
struct flash_switch_data *snode, bool on)
|
struct flash_switch_data *snode, bool on)
|
||||||
{
|
{
|
||||||
|
@ -923,6 +974,16 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
led->pdata->all_ramp_up_done_irq =
|
||||||
|
of_irq_get_byname(node, "all-ramp-up-done-irq");
|
||||||
|
if (led->pdata->all_ramp_up_done_irq < 0)
|
||||||
|
dev_dbg(&led->pdev->dev, "all-ramp-up-done-irq not used\n");
|
||||||
|
|
||||||
|
led->pdata->all_ramp_down_done_irq =
|
||||||
|
of_irq_get_byname(node, "all-ramp-down-done-irq");
|
||||||
|
if (led->pdata->all_ramp_down_done_irq < 0)
|
||||||
|
dev_dbg(&led->pdev->dev, "all-ramp-down-done-irq not used\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,6 +1094,35 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* setup irqs */
|
||||||
|
if (led->pdata->all_ramp_up_done_irq >= 0) {
|
||||||
|
rc = devm_request_threaded_irq(&led->pdev->dev,
|
||||||
|
led->pdata->all_ramp_up_done_irq,
|
||||||
|
NULL, qpnp_flash_led_irq_handler,
|
||||||
|
IRQF_ONESHOT,
|
||||||
|
"qpnp_flash_led_all_ramp_up_done_irq", led);
|
||||||
|
if (rc < 0) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n",
|
||||||
|
led->pdata->all_ramp_up_done_irq, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (led->pdata->all_ramp_down_done_irq >= 0) {
|
||||||
|
rc = devm_request_threaded_irq(&led->pdev->dev,
|
||||||
|
led->pdata->all_ramp_down_done_irq,
|
||||||
|
NULL, qpnp_flash_led_irq_handler,
|
||||||
|
IRQF_ONESHOT,
|
||||||
|
"qpnp_flash_led_all_ramp_down_done_irq", led);
|
||||||
|
if (rc < 0) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n",
|
||||||
|
led->pdata->all_ramp_down_done_irq, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc = qpnp_flash_led_init_settings(led);
|
rc = qpnp_flash_led_init_settings(led);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
|
|
|
@ -19,6 +19,18 @@
|
||||||
#define ENABLE_REGULATOR BIT(0)
|
#define ENABLE_REGULATOR BIT(0)
|
||||||
#define QUERY_MAX_CURRENT BIT(1)
|
#define QUERY_MAX_CURRENT BIT(1)
|
||||||
|
|
||||||
|
enum flash_led_irq_type {
|
||||||
|
LED_FAULT_IRQ = BIT(0),
|
||||||
|
MITIGATION_IRQ = BIT(1),
|
||||||
|
FLASH_TIMER_EXP_IRQ = BIT(2),
|
||||||
|
ALL_RAMP_DOWN_DONE_IRQ = BIT(3),
|
||||||
|
ALL_RAMP_UP_DONE_IRQ = BIT(4),
|
||||||
|
LED3_RAMP_UP_DONE_IRQ = BIT(5),
|
||||||
|
LED2_RAMP_UP_DONE_IRQ = BIT(6),
|
||||||
|
LED1_RAMP_UP_DONE_IRQ = BIT(7),
|
||||||
|
INVALID_IRQ = BIT(8),
|
||||||
|
};
|
||||||
|
|
||||||
int qpnp_flash_led_prepare(struct led_classdev *led_cdev, int options);
|
int qpnp_flash_led_prepare(struct led_classdev *led_cdev, int options);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue