From e9fc3417353cced4971b463dd22c614fe977038d Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Mon, 16 Jan 2017 14:12:33 -0800 Subject: smb138x-charger: add handler for slave chg state change Add an IRQ handler function that notifies when the slave charge state changes. Change-Id: I359ed08c5ad289ceeabd6fa8720a959c74b6bb5e Signed-off-by: Nicholas Troast --- drivers/power/supply/qcom/smb138x-charger.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c index 1bdae492f44c..7e1f34e1ec30 100644 --- a/drivers/power/supply/qcom/smb138x-charger.c +++ b/drivers/power/supply/qcom/smb138x-charger.c @@ -108,6 +108,17 @@ module_param_named( debug_mask, __debug_mask, int, S_IRUSR | S_IWUSR ); +irqreturn_t smb138x_handle_slave_chg_state_change(int irq, void *data) +{ + struct smb_irq_data *irq_data = data; + struct smb138x *chip = irq_data->parent_data; + + if (chip->parallel_psy) + power_supply_changed(chip->parallel_psy); + + return IRQ_HANDLED; +} + static int smb138x_parse_dt(struct smb138x *chip) { struct smb_charger *chg = &chip->chg; @@ -989,7 +1000,8 @@ static const struct smb138x_irq_info smb138x_irqs[] = { }, { .name = "chg-state-change", - .handler = smblib_handle_debug, + .handler = smb138x_handle_slave_chg_state_change, + .wake = true, }, { .name = "step-chg-state-change", -- cgit v1.2.3 From c9329b856ecbda6a908e405949a31ca16db43d2d Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Mon, 16 Jan 2017 14:15:22 -0800 Subject: ARM: dts: msm: enable the chg-state-change IRQ for SMB138X The chg-state-change IRQ will be used to notify when the parallel slave charger changes its charge state. Enable it. Change-Id: Ia57db8ec5f2263b62217c235725ee9caa07f86e4 Signed-off-by: Nicholas Troast --- arch/arm/boot/dts/qcom/msm-smb138x.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi index 138fa2b57248..8edc1fc61830 100644 --- a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi +++ b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi @@ -108,6 +108,12 @@ "connector_temp_thr3", "charger_temp_max"; + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x10 0x1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "chg-state-change"; + }; + qcom,chgr-misc@1600 { reg = <0x1600 0x100>; interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>, -- cgit v1.2.3 From d86ba09f57f6c6faf0ab66a80ad3bf3380dfd81c Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Sat, 28 Jan 2017 09:32:17 -0800 Subject: power_supply: add INPUT_VOLTAGE_SETTLED property INPUT_VOLTAGE_SETTLED is the negotiated adapter voltage setting. Change-Id: I2ac529a77e8ed007c908c4f37eea718a80bc11d3 Signed-off-by: Nicholas Troast --- drivers/power/power_supply_sysfs.c | 1 + include/linux/power_supply.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index a9bb96df56c9..7d594c9c9e53 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -239,6 +239,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(input_current_max), POWER_SUPPLY_ATTR(input_current_trim), POWER_SUPPLY_ATTR(input_current_settled), + POWER_SUPPLY_ATTR(input_voltage_settled), POWER_SUPPLY_ATTR(bypass_vchg_loop_debouncer), POWER_SUPPLY_ATTR(charge_counter_shadow), POWER_SUPPLY_ATTR(hi_power), diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 41568e45c024..753f90b1fec7 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -191,6 +191,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, POWER_SUPPLY_PROP_VCHG_LOOP_DBC_BYPASS, POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW, POWER_SUPPLY_PROP_HI_POWER, -- cgit v1.2.3 From 13c4202dde3542875c19cc206544e0019e1b7ef7 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Wed, 11 Jan 2017 18:16:25 +0800 Subject: smb-lib: fix slave BCL for HVDCP3 Currently, fixed 5V adapter voltage is used for calculating slave FCC. When HVDCP 3.0 is used it skews the desired FCC distribution. Fix this by using the HVDCP3 pulse count to determine the actual adapter voltage when limiting the slave battery current. Change-Id: Ib4735ffe7b6287a3e57e0f74eb24c13c6a2b7a5a Signed-off-by: Fenglin Wu Signed-off-by: Nicholas Troast --- drivers/power/supply/qcom/battery.c | 35 +++++++++++++++------------ drivers/power/supply/qcom/qpnp-smb2.c | 4 ++++ drivers/power/supply/qcom/smb-lib.c | 45 ++++++++++++++++++++++++++--------- drivers/power/supply/qcom/smb-lib.h | 2 ++ 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index efa88c239379..bd84de1b8bc1 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -247,12 +247,11 @@ done: * FCC * **********/ #define EFFICIENCY_PCT 80 -#define MICRO_5V 5000000 static void split_fcc(struct pl_data *chip, int total_ua, int *master_ua, int *slave_ua) { int rc, effective_total_ua, slave_limited_ua, hw_cc_delta_ua = 0, - aicl_settled_ua, input_limited_fcc_ua; + icl_ua, adapter_uv, bcl_ua; union power_supply_propval pval = {0, }; rc = power_supply_get_property(chip->main_psy, @@ -262,24 +261,30 @@ static void split_fcc(struct pl_data *chip, int total_ua, else hw_cc_delta_ua = pval.intval; - input_limited_fcc_ua = INT_MAX; + bcl_ua = INT_MAX; if (chip->pl_mode == POWER_SUPPLY_PARALLEL_MID_MID) { rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, - &pval); - if (rc < 0) - aicl_settled_ua = 0; - else - aicl_settled_ua = pval.intval; - - input_limited_fcc_ua = div64_s64( - (s64)aicl_settled_ua * MICRO_5V * EFFICIENCY_PCT, - (s64)get_effective_result(chip->fv_votable) - * 100); + POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); + if (rc < 0) { + pr_err("Couldn't get aicl settled value rc=%d\n", rc); + return; + } + icl_ua = pval.intval; + + rc = power_supply_get_property(chip->main_psy, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, &pval); + if (rc < 0) { + pr_err("Couldn't get adaptive voltage rc=%d\n", rc); + return; + } + adapter_uv = pval.intval; + + bcl_ua = div64_s64((s64)icl_ua * adapter_uv * EFFICIENCY_PCT, + (s64)get_effective_result(chip->fv_votable) * 100); } effective_total_ua = max(0, total_ua + hw_cc_delta_ua); - slave_limited_ua = min(effective_total_ua, input_limited_fcc_ua); + slave_limited_ua = min(effective_total_ua, bcl_ua); *slave_ua = (slave_limited_ua * chip->slave_pct) / 100; *slave_ua = (*slave_ua * chip->taper_pct) / 100; *master_ua = max(0, total_ua - *slave_ua); diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index f8bca0645340..1fb0cab6c364 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -613,6 +613,7 @@ static enum power_supply_property smb2_usb_main_props[] = { POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_TYPE, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, POWER_SUPPLY_PROP_FCC_DELTA, /* * TODO move the TEMP and TEMP_MAX properties here, @@ -645,6 +646,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: rc = smblib_get_prop_input_current_settled(chg, val); break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED: + rc = smblib_get_prop_input_voltage_settled(chg, val); + break; case POWER_SUPPLY_PROP_FCC_DELTA: rc = smblib_get_prop_fcc_delta(chg, val); break; diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index f56c70beb5f0..c42552bc6444 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -331,7 +331,6 @@ static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg) return result; } - /******************** * REGISTER SETTERS * ********************/ @@ -1998,6 +1997,39 @@ int smblib_get_prop_input_current_settled(struct smb_charger *chg, return smblib_get_charge_param(chg, &chg->param.icl_stat, &val->intval); } +#define HVDCP3_STEP_UV 200000 +int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, + union power_supply_propval *val) +{ + const struct apsd_result *apsd_result = smblib_get_apsd_result(chg); + int rc, pulses; + u8 stat; + + val->intval = MICRO_5V; + if (apsd_result == NULL) { + smblib_err(chg, "APSD result is NULL\n"); + return 0; + } + + switch (apsd_result->pst) { + case POWER_SUPPLY_TYPE_USB_HVDCP_3: + rc = smblib_read(chg, QC_PULSE_COUNT_STATUS_REG, &stat); + if (rc < 0) { + smblib_err(chg, + "Couldn't read QC_PULSE_COUNT rc=%d\n", rc); + return 0; + } + pulses = (stat & QC_PULSE_COUNT_MASK); + val->intval = MICRO_5V + HVDCP3_STEP_UV * pulses; + break; + default: + val->intval = MICRO_5V; + break; + } + + return 0; +} + int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, union power_supply_propval *val) { @@ -2887,6 +2919,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) u8 stat; int pulses; + power_supply_changed(chg->usb_main_psy); if (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) { @@ -2939,13 +2972,6 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) } } -static void smblib_handle_adaptive_voltage_done(struct smb_charger *chg, - bool rising) -{ - smblib_dbg(chg, PR_INTERRUPT, "IRQ: adaptive-voltage-done %s\n", - rising ? "rising" : "falling"); -} - /* triggers when HVDCP 3.0 authentication has finished */ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, bool rising) @@ -3087,9 +3113,6 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data) smblib_handle_hvdcp_3p0_auth_done(chg, (bool)(stat & QC_AUTH_DONE_STATUS_BIT)); - smblib_handle_adaptive_voltage_done(chg, - (bool)(stat & VADP_CHANGE_DONE_AFTER_AUTH_BIT)); - smblib_handle_sdp_enumeration_done(chg, (bool)(stat & ENUMERATION_DONE_BIT)); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 864e7d691a43..5516f339026f 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -377,6 +377,8 @@ int smblib_get_prop_pd_allowed(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_input_current_settled(struct smb_charger *chg, union power_supply_propval *val); +int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, + union power_supply_propval *val); int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_pe_start(struct smb_charger *chg, -- cgit v1.2.3 From 580b03cf01fc09bbee0c89d9d9840d9a97152552 Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Thu, 9 Feb 2017 10:57:28 -0800 Subject: smb-lib: add ICL settled value to IRQ debug print Print the ICL settled value within the icl-changed IRQ handler. Change-Id: I5553abecfc5e32b24bef3525f532f4b3505c0757 Signed-off-by: Nicholas Troast --- drivers/power/supply/qcom/smb-lib.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index c42552bc6444..c9603fa39b03 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -2877,22 +2877,20 @@ irqreturn_t smblib_handle_icl_change(int irq, void *data) struct smb_charger *chg = irq_data->parent_data; int rc, settled_ua; - smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); - rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &settled_ua); if (rc < 0) { smblib_err(chg, "Couldn't get ICL status rc=%d\n", rc); return IRQ_HANDLED; } - if (chg->mode != PARALLEL_MASTER) - return IRQ_HANDLED; - - power_supply_changed(chg->usb_main_psy); - - vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, - settled_ua >= USB_WEAK_INPUT_UA, 0); + if (chg->mode == PARALLEL_MASTER) { + power_supply_changed(chg->usb_main_psy); + vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, + settled_ua >= USB_WEAK_INPUT_UA, 0); + } + smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s icl_settled=%d\n", + irq_data->name, settled_ua); return IRQ_HANDLED; } -- cgit v1.2.3 From 1f0f1184a030001389ad2e4e23f8400eb4a778fd Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Mon, 6 Feb 2017 16:04:32 -0800 Subject: qcom: storm-watch: add support to reset storm count There are some circumstances where we have to reset the storm watch interrupt count. Add support for it. Change-Id: Iacbeb3258d53010aab8ba881d10de773fe54dd93 Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/supply/qcom/qpnp-smb2.c | 1 + drivers/power/supply/qcom/smb138x-charger.c | 1 + drivers/power/supply/qcom/storm-watch.c | 11 ++++++++++- drivers/power/supply/qcom/storm-watch.h | 16 ++++++++++------ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 1fb0cab6c364..4f0d85b8e1e6 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1881,6 +1881,7 @@ static int smb2_request_interrupt(struct smb2 *chip, irq_data->parent_data = chip; irq_data->name = irq_name; irq_data->storm_data = smb2_irqs[irq_index].storm_data; + mutex_init(&irq_data->storm_data.storm_lock); rc = devm_request_threaded_irq(chg->dev, irq, NULL, smb2_irqs[irq_index].handler, diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c index 7e1f34e1ec30..8f91642db214 100644 --- a/drivers/power/supply/qcom/smb138x-charger.c +++ b/drivers/power/supply/qcom/smb138x-charger.c @@ -1197,6 +1197,7 @@ static int smb138x_request_interrupt(struct smb138x *chip, irq_data->parent_data = chip; irq_data->name = irq_name; irq_data->storm_data = smb138x_irqs[irq_index].storm_data; + mutex_init(&irq_data->storm_data.storm_lock); rc = devm_request_threaded_irq(chg->dev, irq, NULL, smb138x_irqs[irq_index].handler, diff --git a/drivers/power/supply/qcom/storm-watch.c b/drivers/power/supply/qcom/storm-watch.c index 90fec12bd742..5275079c53e0 100644 --- a/drivers/power/supply/qcom/storm-watch.c +++ b/drivers/power/supply/qcom/storm-watch.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017 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 @@ -39,6 +39,7 @@ bool is_storming(struct storm_watch *data) if (data->storm_period_ms <= 0) return false; + mutex_lock(&data->storm_lock); curr_kt = ktime_get_boottime(); delta_kt = ktime_sub(curr_kt, data->last_kt); @@ -53,5 +54,13 @@ bool is_storming(struct storm_watch *data) } data->last_kt = curr_kt; + mutex_unlock(&data->storm_lock); return is_storming; } + +void reset_storm_count(struct storm_watch *data) +{ + mutex_lock(&data->storm_lock); + data->storm_count = 0; + mutex_unlock(&data->storm_lock); +} diff --git a/drivers/power/supply/qcom/storm-watch.h b/drivers/power/supply/qcom/storm-watch.h index 44b9d64d8a87..ff05c4a661c3 100644 --- a/drivers/power/supply/qcom/storm-watch.h +++ b/drivers/power/supply/qcom/storm-watch.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017 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 @@ -13,6 +13,7 @@ #ifndef __STORM_WATCH_H #define __STORM_WATCH_H #include +#include /** * Data used to track an event storm. @@ -23,14 +24,17 @@ * @max_storm_count: The number of chained events required to trigger a storm. * @storm_count: The current number of chained events. * @last_kt: Kernel time of the last event seen. + * @storm_lock: Mutex lock to protect storm_watch data. */ struct storm_watch { - bool enabled; - int storm_period_ms; - int max_storm_count; - int storm_count; - ktime_t last_kt; + bool enabled; + int storm_period_ms; + int max_storm_count; + int storm_count; + ktime_t last_kt; + struct mutex storm_lock; }; bool is_storming(struct storm_watch *data); +void reset_storm_count(struct storm_watch *data); #endif -- cgit v1.2.3 From 2b9d6a362f9ae5f7e2228e3c1df9b9cf56417b7c Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Mon, 6 Feb 2017 16:22:48 -0800 Subject: qcom: smb-lib: make smb_irq_info common for smb2 and smb138x chargers Since the interrupt information for both smb2 and smb138x charger devices are almost common, abstract it to a single smb_irq_info struct. Also, keep an interrupt index for every interrupt which can be used when necessary. Change-Id: I4e42dd15a46b59c1a9c27412ca6fdff281fa71ec Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/supply/qcom/qpnp-smb2.c | 89 +++++++++++++---------------- drivers/power/supply/qcom/smb-lib.h | 53 +++++++++++++++++ drivers/power/supply/qcom/smb138x-charger.c | 87 +++++++++++++--------------- 3 files changed, 134 insertions(+), 95 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 4f0d85b8e1e6..a1afd1e236b8 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -1660,180 +1659,172 @@ static int smb2_determine_initial_status(struct smb2 *chip) * INTERRUPT REGISTRATION * **************************/ -struct smb2_irq_info { - const char *name; - const irq_handler_t handler; - const bool wake; - const struct storm_watch storm_data; - int irq; -}; - -static struct smb2_irq_info smb2_irqs[] = { +static struct smb_irq_info smb2_irqs[] = { /* CHARGER IRQs */ - { + [CHG_ERROR_IRQ] = { .name = "chg-error", .handler = smblib_handle_debug, }, - { + [CHG_STATE_CHANGE_IRQ] = { .name = "chg-state-change", .handler = smblib_handle_chg_state_change, .wake = true, }, - { + [STEP_CHG_STATE_CHANGE_IRQ] = { .name = "step-chg-state-change", .handler = smblib_handle_step_chg_state_change, .wake = true, }, - { + [STEP_CHG_SOC_UPDATE_FAIL_IRQ] = { .name = "step-chg-soc-update-fail", .handler = smblib_handle_step_chg_soc_update_fail, .wake = true, }, - { + [STEP_CHG_SOC_UPDATE_REQ_IRQ] = { .name = "step-chg-soc-update-request", .handler = smblib_handle_step_chg_soc_update_request, .wake = true, }, /* OTG IRQs */ - { + [OTG_FAIL_IRQ] = { .name = "otg-fail", .handler = smblib_handle_debug, }, - { + [OTG_OVERCURRENT_IRQ] = { .name = "otg-overcurrent", .handler = smblib_handle_otg_overcurrent, }, - { + [OTG_OC_DIS_SW_STS_IRQ] = { .name = "otg-oc-dis-sw-sts", .handler = smblib_handle_debug, }, - { + [TESTMODE_CHANGE_DET_IRQ] = { .name = "testmode-change-detect", .handler = smblib_handle_debug, }, /* BATTERY IRQs */ - { + [BATT_TEMP_IRQ] = { .name = "bat-temp", .handler = smblib_handle_batt_temp_changed, }, - { + [BATT_OCP_IRQ] = { .name = "bat-ocp", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_OV_IRQ] = { .name = "bat-ov", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_LOW_IRQ] = { .name = "bat-low", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_THERM_ID_MISS_IRQ] = { .name = "bat-therm-or-id-missing", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_TERM_MISS_IRQ] = { .name = "bat-terminal-missing", .handler = smblib_handle_batt_psy_changed, }, /* USB INPUT IRQs */ - { + [USBIN_COLLAPSE_IRQ] = { .name = "usbin-collapse", .handler = smblib_handle_debug, }, - { + [USBIN_LT_3P6V_IRQ] = { .name = "usbin-lt-3p6v", .handler = smblib_handle_debug, }, - { + [USBIN_UV_IRQ] = { .name = "usbin-uv", .handler = smblib_handle_debug, }, - { + [USBIN_OV_IRQ] = { .name = "usbin-ov", .handler = smblib_handle_debug, }, - { + [USBIN_PLUGIN_IRQ] = { .name = "usbin-plugin", .handler = smblib_handle_usb_plugin, .wake = true, }, - { + [USBIN_SRC_CHANGE_IRQ] = { .name = "usbin-src-change", .handler = smblib_handle_usb_source_change, .wake = true, }, - { + [USBIN_ICL_CHANGE_IRQ] = { .name = "usbin-icl-change", .handler = smblib_handle_icl_change, .wake = true, }, - { + [TYPE_C_CHANGE_IRQ] = { .name = "type-c-change", .handler = smblib_handle_usb_typec_change, .wake = true, }, /* DC INPUT IRQs */ - { + [DCIN_COLLAPSE_IRQ] = { .name = "dcin-collapse", .handler = smblib_handle_debug, }, - { + [DCIN_LT_3P6V_IRQ] = { .name = "dcin-lt-3p6v", .handler = smblib_handle_debug, }, - { + [DCIN_UV_IRQ] = { .name = "dcin-uv", .handler = smblib_handle_debug, }, - { + [DCIN_OV_IRQ] = { .name = "dcin-ov", .handler = smblib_handle_debug, }, - { + [DCIN_PLUGIN_IRQ] = { .name = "dcin-plugin", .handler = smblib_handle_dc_plugin, .wake = true, }, - { + [DIV2_EN_DG_IRQ] = { .name = "div2-en-dg", .handler = smblib_handle_debug, }, - { + [DCIN_ICL_CHANGE_IRQ] = { .name = "dcin-icl-change", .handler = smblib_handle_debug, }, /* MISCELLANEOUS IRQs */ - { + [WDOG_SNARL_IRQ] = { .name = "wdog-snarl", .handler = NULL, }, - { + [WDOG_BARK_IRQ] = { .name = "wdog-bark", .handler = NULL, }, - { + [AICL_FAIL_IRQ] = { .name = "aicl-fail", .handler = smblib_handle_debug, }, - { + [AICL_DONE_IRQ] = { .name = "aicl-done", .handler = smblib_handle_debug, }, - { + [HIGH_DUTY_CYCLE_IRQ] = { .name = "high-duty-cycle", .handler = smblib_handle_high_duty_cycle, .wake = true, }, - { + [INPUT_CURRENT_LIMIT_IRQ] = { .name = "input-current-limiting", .handler = smblib_handle_debug, }, - { + [TEMPERATURE_CHANGE_IRQ] = { .name = "temperature-change", .handler = smblib_handle_debug, }, - { + [SWITCH_POWER_OK_IRQ] = { .name = "switcher-power-ok", .handler = smblib_handle_switcher_power_ok, .storm_data = {true, 1000, 3}, @@ -1892,6 +1883,7 @@ static int smb2_request_interrupt(struct smb2 *chip, } smb2_irqs[irq_index].irq = irq; + smb2_irqs[irq_index].irq_data = irq_data; if (smb2_irqs[irq_index].wake) enable_irq_wake(irq); @@ -2005,6 +1997,7 @@ static int smb2_probe(struct platform_device *pdev) chg->param = v1_params; chg->debug_mask = &__debug_mask; chg->mode = PARALLEL_MASTER; + chg->irq_info = smb2_irqs; chg->name = "PMI"; chg->regmap = dev_get_regmap(chg->dev->parent, NULL); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 5516f339026f..d7dea7172464 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -13,6 +13,7 @@ #ifndef __SMB2_CHARGER_H #define __SMB2_CHARGER_H #include +#include #include #include #include @@ -79,6 +80,57 @@ enum { TYPEC_CC2_REMOVAL_WA_BIT = BIT(2), }; +enum smb_irq_index { + CHG_ERROR_IRQ = 0, + CHG_STATE_CHANGE_IRQ, + STEP_CHG_STATE_CHANGE_IRQ, + STEP_CHG_SOC_UPDATE_FAIL_IRQ, + STEP_CHG_SOC_UPDATE_REQ_IRQ, + OTG_FAIL_IRQ, + OTG_OVERCURRENT_IRQ, + OTG_OC_DIS_SW_STS_IRQ, + TESTMODE_CHANGE_DET_IRQ, + BATT_TEMP_IRQ, + BATT_OCP_IRQ, + BATT_OV_IRQ, + BATT_LOW_IRQ, + BATT_THERM_ID_MISS_IRQ, + BATT_TERM_MISS_IRQ, + USBIN_COLLAPSE_IRQ, + USBIN_LT_3P6V_IRQ, + USBIN_UV_IRQ, + USBIN_OV_IRQ, + USBIN_PLUGIN_IRQ, + USBIN_SRC_CHANGE_IRQ, + USBIN_ICL_CHANGE_IRQ, + TYPE_C_CHANGE_IRQ, + DCIN_COLLAPSE_IRQ, + DCIN_LT_3P6V_IRQ, + DCIN_UV_IRQ, + DCIN_OV_IRQ, + DCIN_PLUGIN_IRQ, + DIV2_EN_DG_IRQ, + DCIN_ICL_CHANGE_IRQ, + WDOG_SNARL_IRQ, + WDOG_BARK_IRQ, + AICL_FAIL_IRQ, + AICL_DONE_IRQ, + HIGH_DUTY_CYCLE_IRQ, + INPUT_CURRENT_LIMIT_IRQ, + TEMPERATURE_CHANGE_IRQ, + SWITCH_POWER_OK_IRQ, + SMB_IRQ_MAX, +}; + +struct smb_irq_info { + const char *name; + const irq_handler_t handler; + const bool wake; + const struct storm_watch storm_data; + struct smb_irq_data *irq_data; + int irq; +}; + static const unsigned int smblib_extcon_cable[] = { EXTCON_USB, EXTCON_USB_HOST, @@ -167,6 +219,7 @@ struct smb_charger { struct device *dev; char *name; struct regmap *regmap; + struct smb_irq_info *irq_info; struct smb_params param; struct smb_iio iio; int *debug_mask; diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c index 8f91642db214..554625adda7d 100644 --- a/drivers/power/supply/qcom/smb138x-charger.c +++ b/drivers/power/supply/qcom/smb138x-charger.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -985,171 +984,164 @@ static int smb138x_determine_initial_status(struct smb138x *chip) * INTERRUPT REGISTRATION * **************************/ -struct smb138x_irq_info { - const char *name; - const irq_handler_t handler; - const bool wake; - const struct storm_watch storm_data; -}; - -static const struct smb138x_irq_info smb138x_irqs[] = { +static struct smb_irq_info smb138x_irqs[] = { /* CHARGER IRQs */ - { + [CHG_ERROR_IRQ] = { .name = "chg-error", .handler = smblib_handle_debug, }, - { + [CHG_STATE_CHANGE_IRQ] = { .name = "chg-state-change", .handler = smb138x_handle_slave_chg_state_change, .wake = true, }, - { + [STEP_CHG_STATE_CHANGE_IRQ] = { .name = "step-chg-state-change", .handler = smblib_handle_debug, }, - { + [STEP_CHG_SOC_UPDATE_FAIL_IRQ] = { .name = "step-chg-soc-update-fail", .handler = smblib_handle_debug, }, - { + [STEP_CHG_SOC_UPDATE_REQ_IRQ] = { .name = "step-chg-soc-update-request", .handler = smblib_handle_debug, }, /* OTG IRQs */ - { + [OTG_FAIL_IRQ] = { .name = "otg-fail", .handler = smblib_handle_debug, }, - { + [OTG_OVERCURRENT_IRQ] = { .name = "otg-overcurrent", .handler = smblib_handle_debug, }, - { + [OTG_OC_DIS_SW_STS_IRQ] = { .name = "otg-oc-dis-sw-sts", .handler = smblib_handle_debug, }, - { + [TESTMODE_CHANGE_DET_IRQ] = { .name = "testmode-change-detect", .handler = smblib_handle_debug, }, /* BATTERY IRQs */ - { + [BATT_TEMP_IRQ] = { .name = "bat-temp", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_OCP_IRQ] = { .name = "bat-ocp", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_OV_IRQ] = { .name = "bat-ov", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_LOW_IRQ] = { .name = "bat-low", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_THERM_ID_MISS_IRQ] = { .name = "bat-therm-or-id-missing", .handler = smblib_handle_batt_psy_changed, }, - { + [BATT_TERM_MISS_IRQ] = { .name = "bat-terminal-missing", .handler = smblib_handle_batt_psy_changed, }, /* USB INPUT IRQs */ - { + [USBIN_COLLAPSE_IRQ] = { .name = "usbin-collapse", .handler = smblib_handle_debug, }, - { + [USBIN_LT_3P6V_IRQ] = { .name = "usbin-lt-3p6v", .handler = smblib_handle_debug, }, - { + [USBIN_UV_IRQ] = { .name = "usbin-uv", .handler = smblib_handle_debug, }, - { + [USBIN_OV_IRQ] = { .name = "usbin-ov", .handler = smblib_handle_debug, }, - { + [USBIN_PLUGIN_IRQ] = { .name = "usbin-plugin", .handler = smblib_handle_usb_plugin, }, - { + [USBIN_SRC_CHANGE_IRQ] = { .name = "usbin-src-change", .handler = smblib_handle_usb_source_change, }, - { + [USBIN_ICL_CHANGE_IRQ] = { .name = "usbin-icl-change", .handler = smblib_handle_debug, }, - { + [TYPE_C_CHANGE_IRQ] = { .name = "type-c-change", .handler = smblib_handle_usb_typec_change, }, /* DC INPUT IRQs */ - { + [DCIN_COLLAPSE_IRQ] = { .name = "dcin-collapse", .handler = smblib_handle_debug, }, - { + [DCIN_LT_3P6V_IRQ] = { .name = "dcin-lt-3p6v", .handler = smblib_handle_debug, }, - { + [DCIN_UV_IRQ] = { .name = "dcin-uv", .handler = smblib_handle_debug, }, - { + [DCIN_OV_IRQ] = { .name = "dcin-ov", .handler = smblib_handle_debug, }, - { + [DCIN_PLUGIN_IRQ] = { .name = "dcin-plugin", .handler = smblib_handle_debug, }, - { + [DIV2_EN_DG_IRQ] = { .name = "div2-en-dg", .handler = smblib_handle_debug, }, - { + [DCIN_ICL_CHANGE_IRQ] = { .name = "dcin-icl-change", .handler = smblib_handle_debug, }, /* MISCELLANEOUS IRQs */ - { + [WDOG_SNARL_IRQ] = { .name = "wdog-snarl", .handler = smblib_handle_debug, }, - { + [WDOG_BARK_IRQ] = { .name = "wdog-bark", .handler = smblib_handle_wdog_bark, .wake = true, }, - { + [AICL_FAIL_IRQ] = { .name = "aicl-fail", .handler = smblib_handle_debug, }, - { + [AICL_DONE_IRQ] = { .name = "aicl-done", .handler = smblib_handle_debug, }, - { + [HIGH_DUTY_CYCLE_IRQ] = { .name = "high-duty-cycle", .handler = smblib_handle_debug, }, - { + [INPUT_CURRENT_LIMIT_IRQ] = { .name = "input-current-limiting", .handler = smblib_handle_debug, }, - { + [TEMPERATURE_CHANGE_IRQ] = { .name = "temperature-change", .handler = smb138x_handle_temperature_change, }, - { + [SWITCH_POWER_OK_IRQ] = { .name = "switcher-power-ok", .handler = smblib_handle_debug, }, @@ -1411,6 +1403,7 @@ static int smb138x_probe(struct platform_device *pdev) chip->chg.dev = &pdev->dev; chip->chg.debug_mask = &__debug_mask; + chip->chg.irq_info = smb138x_irqs; chip->chg.name = "SMB"; chip->chg.regmap = dev_get_regmap(chip->chg.dev->parent, NULL); -- cgit v1.2.3