summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKiran Gunda <kgunda@codeaurora.org>2016-10-28 17:45:57 +0530
committerKiran Gunda <kgunda@codeaurora.org>2016-12-30 10:24:54 +0530
commit3f384542db23506c998ec6c71fe4e3c4f7abf8e4 (patch)
tree5341b0f69af009ae53d56ee7cf31e9f21db7cf90 /drivers
parent98a47a04197524b06396a3e37489f0f8802cf386 (diff)
regulator: qpnp-labibb: Add support for PM660A
Modify the driver to support the new lab/ibb hardware changes supported on PM660A. New hardware supports the following features: 1) Smart pulse skip mode 2) LDO mode for LAB 3) PFM mode 4) PBS sequencer handling SWIRE decoding 5) Default output voltage configuration Change-Id: I5461995cc0ac930dd354c63b97223085306e869d Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/qpnp-labibb-regulator.c2304
1 files changed, 1553 insertions, 751 deletions
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 15ade85f446b..8dbe3080873c 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -46,6 +46,7 @@
/* LAB register offset definitions */
#define REG_LAB_STATUS1 0x08
+#define REG_LAB_SWIRE_PGM_CTL 0x40
#define REG_LAB_VOLTAGE 0x41
#define REG_LAB_RING_SUPPRESSION_CTL 0x42
#define REG_LAB_LCD_AMOLED_SEL 0x44
@@ -63,16 +64,25 @@
#define REG_LAB_SPARE_CTL 0x60
#define REG_LAB_PFM_CTL 0x62
+/* LAB registers for PM660A */
+#define REG_LAB_VOUT_DEFAULT 0x44
+#define REG_LAB_SW_HIGH_PSRR_CTL 0x70
+#define REG_LAB_LDO_PD_CTL 0x78
+#define REG_LAB_VPH_ENVELOP_CTL 0x7E
+
/* LAB register bits definitions */
/* REG_LAB_STATUS1 */
#define LAB_STATUS1_VREG_OK_MASK BIT(7)
#define LAB_STATUS1_VREG_OK BIT(7)
+/* REG_LAB_SWIRE_PGM_CTL */
+#define LAB_EN_SWIRE_PGM_VOUT BIT(7)
+#define LAB_EN_SWIRE_PGM_PD BIT(6)
+
/* REG_LAB_VOLTAGE */
#define LAB_VOLTAGE_OVERRIDE_EN BIT(7)
-#define LAB_VOLTAGE_SET_BITS 4
-#define LAB_VOLTAGE_SET_MASK ((1 << LAB_VOLTAGE_SET_BITS) - 1)
+#define LAB_VOLTAGE_SET_MASK GENMASK(3, 0)
/* REG_LAB_RING_SUPPRESSION_CTL */
#define LAB_RING_SUPPRESSION_CTL_EN BIT(7)
@@ -98,34 +108,27 @@
#define LAB_OVERRIDE_CURRENT_MAX_BIT BIT(3)
/* REG_LAB_CURRENT_SENSE */
-#define LAB_CURRENT_SENSE_GAIN_BITS 2
-#define LAB_CURRENT_SENSE_GAIN_MASK ((1 << LAB_CURRENT_SENSE_GAIN_BITS) \
- - 1)
+#define LAB_CURRENT_SENSE_GAIN_MASK GENMASK(1, 0)
/* REG_LAB_PS_CTL */
-#define LAB_PS_CTL_BITS 2
-#define LAB_PS_CTL_MASK ((1 << LAB_PS_CTL_BITS) - 1)
+#define LAB_PS_THRESH_MASK GENMASK(1, 0)
#define LAB_PS_CTL_EN BIT(7)
/* REG_LAB_RDSON_MNGMNT */
#define LAB_RDSON_MNGMNT_NFET_SLEW_EN BIT(5)
#define LAB_RDSON_MNGMNT_PFET_SLEW_EN BIT(4)
-#define LAB_RDSON_MNGMNT_NFET_BITS 2
-#define LAB_RDSON_MNGMNT_NFET_MASK ((1 << LAB_RDSON_MNGMNT_NFET_BITS) - 1)
+#define LAB_RDSON_MNGMNT_NFET_MASK GENMASK(3, 2)
#define LAB_RDSON_MNGMNT_NFET_SHIFT 2
-#define LAB_RDSON_MNGMNT_PFET_BITS 2
-#define LAB_RDSON_MNGMNT_PFET_MASK ((1 << LAB_RDSON_MNGMNT_PFET_BITS) - 1)
+#define LAB_RDSON_MNGMNT_PFET_MASK GENMASK(1, 0)
#define LAB_RDSON_NFET_SW_SIZE_QUARTER 0x0
#define LAB_RDSON_PFET_SW_SIZE_QUARTER 0x0
/* REG_LAB_PRECHARGE_CTL */
-#define LAB_PRECHARGE_CTL_EN BIT(2)
-#define LAB_PRECHARGE_CTL_EN_BITS 2
-#define LAB_PRECHARGE_CTL_EN_MASK ((1 << LAB_PRECHARGE_CTL_EN_BITS) - 1)
+#define LAB_FAST_PRECHARGE_CTL_EN BIT(2)
+#define LAB_MAX_PRECHARGE_TIME_MASK GENMASK(1, 0)
/* REG_LAB_SOFT_START_CTL */
-#define LAB_SOFT_START_CTL_BITS 2
-#define LAB_SOFT_START_CTL_MASK ((1 << LAB_SOFT_START_CTL_BITS) - 1)
+#define LAB_SOFT_START_CTL_MASK GENMASK(1, 0)
/* REG_LAB_SPARE_CTL */
#define LAB_SPARE_TOUCH_WAKE_BIT BIT(3)
@@ -134,10 +137,19 @@
/* REG_LAB_PFM_CTL */
#define LAB_PFM_EN_BIT BIT(7)
+/* REG_LAB_SW_HIGH_PSRR_CTL */
+#define LAB_EN_SW_HIGH_PSRR_MODE BIT(7)
+#define LAB_SW_HIGH_PSRR_REQ BIT(0)
+
+/* REG_LAB_VPH_ENVELOP_CTL */
+#define LAB_VREF_HIGH_PSRR_SEL_MASK GENMASK(7, 6)
+#define LAB_SEL_HW_HIGH_PSRR_SRC_MASK GENMASK(1, 0)
+#define LAB_SEL_HW_HIGH_PSRR_SRC_SHIFT 6
+
/* IBB register offset definitions */
#define REG_IBB_REVISION4 0x03
#define REG_IBB_STATUS1 0x08
-#define REG_IBB_VOLTAGE 0x41
+#define REG_IBB_VOLTAGE 0x41
#define REG_IBB_RING_SUPPRESSION_CTL 0x42
#define REG_IBB_LCD_AMOLED_SEL 0x44
#define REG_IBB_MODULE_RDY 0x45
@@ -153,9 +165,19 @@
#define REG_IBB_PWRUP_PWRDN_CTL_2 0x59
#define REG_IBB_SOFT_START_CTL 0x5F
#define REG_IBB_SWIRE_CTL 0x5A
+#define REG_IBB_OUTPUT_SLEW_CTL 0x5D
#define REG_IBB_SPARE_CTL 0x60
#define REG_IBB_NLIMIT_DAC 0x61
+/* IBB registers for PM660A */
+#define REG_IBB_DEFAULT_VOLTAGE 0x40
+#define REG_IBB_FLOAT_CTL 0x43
+#define REG_IBB_VREG_OK_CTL 0x55
+#define REG_IBB_VOUT_MIN_MAGNITUDE 0x5C
+#define REG_IBB_PFM_CTL 0x62
+#define REG_IBB_SMART_PS_CTL 0x65
+#define REG_IBB_ADAPT_DEAD_TIME 0x67
+
/* IBB register bits definition */
/* REG_IBB_STATUS1 */
@@ -164,12 +186,22 @@
/* REG_IBB_VOLTAGE */
#define IBB_VOLTAGE_OVERRIDE_EN BIT(7)
-#define IBB_VOLTAGE_SET_BITS 6
-#define IBB_VOLTAGE_SET_MASK ((1 << IBB_VOLTAGE_SET_BITS) - 1)
+#define IBB_VOLTAGE_SET_MASK GENMASK(5, 0)
+
+/* REG_IBB_CLK_DIV */
+#define IBB_CLK_DIV_OVERRIDE_EN BIT(7)
+#define IBB_CLK_DIV_MASK GENMASK(3, 0)
/* REG_IBB_RING_SUPPRESSION_CTL */
#define IBB_RING_SUPPRESSION_CTL_EN BIT(7)
+/* REG_IBB_FLOAT_CTL */
+#define IBB_FLOAT_EN BIT(0)
+#define IBB_SMART_FLOAT_EN BIT(7)
+
+/* REG_IBB_MIN_MAGNITUDE */
+#define IBB_MIN_VOLTAGE_0P8_V BIT(3)
+
/* REG_IBB_MODULE_RDY */
#define IBB_MODULE_RDY_EN BIT(7)
@@ -182,35 +214,47 @@
#define IBB_PD_CTL_HALF_STRENGTH BIT(0)
#define IBB_PD_CTL_STRENGTH_MASK BIT(0)
#define IBB_PD_CTL_EN BIT(7)
+#define IBB_SWIRE_PD_UPD BIT(1)
#define IBB_PD_CTL_EN_MASK BIT(7)
/* REG_IBB_CURRENT_LIMIT */
-#define IBB_CURRENT_LIMIT_BITS 5
-#define IBB_CURRENT_LIMIT_MASK ((1 << IBB_CURRENT_LIMIT_BITS) - 1)
+#define IBB_CURRENT_LIMIT_MASK GENMASK(4, 0)
#define IBB_CURRENT_LIMIT_DEBOUNCE_SHIFT 5
+#define IBB_CURRENT_LIMIT_DEBOUNCE_MASK GENMASK(6, 5)
#define IBB_CURRENT_LIMIT_EN BIT(7)
#define IBB_ILIMIT_COUNT_CYC8 0
#define IBB_CURRENT_MAX_500MA 0xA
/* REG_IBB_PS_CTL */
#define IBB_PS_CTL_EN 0x85
-#define IBB_PS_CTL_DISABLE 0x5
+
+/* REG_IBB_SMART_PS_CTL */
+#define IBB_SMART_PS_CTL_EN BIT(7)
+#define IBB_NUM_SWIRE_PULSE_WAIT 0x5
+
+/* REG_IBB_OUTPUT_SLEW_CTL */
+#define IBB_SLEW_CTL_EN BIT(7)
+#define IBB_SLEW_RATE_SPEED_FAST_EN BIT(6)
+#define IBB_SLEW_RATE_TRANS_TIME_FAST_SHIFT 3
+#define IBB_SLEW_RATE_TRANS_TIME_FAST_MASK GENMASK(5, 3)
+#define IBB_SLEW_RATE_TRANS_TIME_SLOW_MASK GENMASK(2, 0)
+
+/* REG_IBB_VREG_OK_CTL */
+#define IBB_VREG_OK_EN_OVERLOAD_BLANK BIT(7)
+#define IBB_VREG_OK_OVERLOAD_DEB_SHIFT 5
+#define IBB_VREG_OK_OVERLOAD_DEB_MASK GENMASK(6, 5)
/* REG_IBB_RDSON_MNGMNT */
#define IBB_NFET_SLEW_EN BIT(7)
#define IBB_PFET_SLEW_EN BIT(6)
#define IBB_OVERRIDE_NFET_SW_SIZE BIT(5)
#define IBB_OVERRIDE_PFET_SW_SIZE BIT(2)
-#define IBB_NFET_SW_SIZE_BITS 2
-#define IBB_PFET_SW_SIZE_BITS 2
-#define IBB_NFET_SW_SIZE_MASK ((1 << NFET_SW_SIZE_BITS) - 1)
-#define IBB_PFET_SW_SIZE_MASK ((1 << PFET_SW_SIZE_BITS) - 1)
-#define IBB_NFET_SW_SIZE_SHIFT 3
+#define IBB_NFET_SW_SIZE_MASK GENMASK(3, 2)
+#define IBB_PFET_SW_SIZE_MASK GENMASK(1, 0)
/* REG_IBB_NONOVERLAP_TIME_1 */
-#define IBB_OVERRIDE_NONOVERLAP BIT(6)
-#define IBB_NONOVERLAP_NFET_BITS 3
-#define IBB_NONOVERLAP_NFET_MASK ((1 << IBB_NONOVERLAP_NFET_BITS) - 1)
+#define IBB_OVERRIDE_NONOVERLAP BIT(6)
+#define IBB_NONOVERLAP_NFET_MASK GENMASK(2, 0)
#define IBB_NFET_GATE_DELAY_2 0x3
/* REG_IBB_NONOVERLAP_TIME_2 */
@@ -226,37 +270,41 @@
#define IBB_FAST_STARTUP BIT(3)
/* REG_IBB_SWIRE_CTL */
-#define IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_BITS 6
-#define IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_MASK \
- ((1 << IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_BITS) - 1)
+#define IBB_SWIRE_VOUT_UPD_EN BIT(6)
+#define IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_MASK GENMASK(5, 0)
+#define MAX_OUTPUT_EDGE_VOLTAGE_MV 6300
#define MAX_OUTPUT_PULSE_VOLTAGE_MV 7700
#define MIN_OUTPUT_PULSE_VOLTAGE_MV 1400
#define OUTPUT_VOLTAGE_STEP_MV 100
/* REG_IBB_NLIMIT_DAC */
-#define IBB_NLIMIT_DAC_EN 0x0
-#define IBB_NLIMIT_DAC_DISABLE 0x5
+#define IBB_DEFAULT_NLIMIT_DAC 0x5
+
+/* REG_IBB_PFM_CTL */
+#define IBB_PFM_ENABLE BIT(7)
+#define IBB_PFM_PEAK_CURRENT_BIT_SHIFT 1
+#define IBB_PFM_PEAK_CURRENT_MASK GENMASK(3, 1)
+#define IBB_PFM_HYSTERESIS_BIT_SHIFT 4
+#define IBB_PFM_HYSTERESIS_MASK GENMASK(5, 4)
/* REG_IBB_PWRUP_PWRDN_CTL_1 */
#define IBB_PWRUP_PWRDN_CTL_1_DLY1_BITS 2
-#define IBB_PWRUP_PWRDN_CTL_1_DLY1_MASK \
- ((1 << IBB_PWRUP_PWRDN_CTL_1_DLY1_BITS) - 1)
+#define IBB_PWRUP_PWRDN_CTL_1_DLY1_MASK GENMASK(5, 4)
#define IBB_PWRUP_PWRDN_CTL_1_DLY1_SHIFT 4
-#define IBB_PWRUP_PWRDN_CTL_1_DLY2_BITS 2
-#define IBB_PWRUP_PWRDN_CTL_1_DLY2_MASK \
- ((1 << IBB_PWRUP_PWRDN_CTL_1_DLY2_BITS) - 1)
+#define IBB_PWRUP_PWRDN_CTL_1_EN_DLY2 BIT(3)
+#define IBB_PWRUP_PWRDN_CTL_1_DLY2_MASK GENMASK(1, 0)
#define IBB_PWRUP_PWRDN_CTL_1_LAB_VREG_OK BIT(7)
#define IBB_PWRUP_PWRDN_CTL_1_EN_DLY1 BIT(6)
#define PWRUP_PWRDN_CTL_1_DISCHARGE_EN BIT(2)
/* REG_IBB_PWRUP_PWRDN_CTL_2 */
-#define IBB_DIS_DLY_BITS 2
-#define IBB_DIS_DLY_MASK ((1 << IBB_DIS_DLY_BITS) - 1)
+#define IBB_DIS_DLY_MASK GENMASK(1, 0)
#define IBB_WAIT_MBG_OK BIT(2)
/* Constants */
#define SWIRE_DEFAULT_2ND_CMD_DLY_MS 20
#define SWIRE_DEFAULT_IBB_PS_ENABLE_DLY_MS 200
+#define IBB_HW_DEFAULT_SLEW_RATE 12000
/**
* enum qpnp_labibb_mode - working mode of LAB/IBB regulators
@@ -285,28 +333,28 @@ enum ibb_mode {
IBB_HW_SW_CONTROL,
};
-static const int ibb_discharge_resistor_plan[] = {
+static const int ibb_discharge_resistor_table[] = {
300,
64,
32,
16,
};
-static const int ibb_pwrup_dly_plan[] = {
+static const int ibb_pwrup_dly_table[] = {
1000,
2000,
4000,
8000,
};
-static const int ibb_pwrdn_dly_plan[] = {
+static const int ibb_pwrdn_dly_table[] = {
1000,
2000,
4000,
8000,
};
-static const int lab_clk_div_plan[] = {
+static const int lab_clk_div_table[] = {
3200,
2740,
2400,
@@ -325,7 +373,7 @@ static const int lab_clk_div_plan[] = {
910,
};
-static const int ibb_clk_div_plan[] = {
+static const int ibb_clk_div_table[] = {
3200,
2740,
2400,
@@ -344,7 +392,7 @@ static const int ibb_clk_div_plan[] = {
910,
};
-static const int lab_current_limit_plan[] = {
+static const int lab_current_limit_table[] = {
200,
400,
600,
@@ -355,14 +403,14 @@ static const int lab_current_limit_plan[] = {
1600,
};
-static const char * const lab_current_sense_plan[] = {
+static const char * const lab_current_sense_table[] = {
"0.5x",
"1x",
"1.5x",
"2x"
};
-static const int ibb_current_limit_plan[] = {
+static const int ibb_current_limit_table[] = {
0,
50,
100,
@@ -397,48 +445,105 @@ static const int ibb_current_limit_plan[] = {
1550,
};
-static const int ibb_debounce_plan[] = {
+static const int ibb_output_slew_ctl_table[] = {
+ 100,
+ 200,
+ 500,
+ 1000,
+ 2000,
+ 10000,
+ 12000,
+ 15000
+};
+
+static const int ibb_debounce_table[] = {
8,
16,
32,
64,
};
-static const int lab_ps_threshold_plan[] = {
+static const int ibb_overload_debounce_table[] = {
+ 1,
+ 2,
+ 4,
+ 8
+};
+
+static const int ibb_vreg_ok_deb_table[] = {
+ 4,
+ 8,
+ 16,
+ 32
+};
+
+static const int lab_ps_thresh_table_v1[] = {
20,
30,
40,
50,
};
-static const int lab_soft_start_plan[] = {
+static const int lab_ps_thresh_table_v2[] = {
+ 50,
+ 60,
+ 70,
+ 80,
+};
+
+static const int lab_soft_start_table[] = {
200,
400,
600,
800,
};
-static const int lab_rdson_nfet_plan[] = {
+static const int lab_rdson_nfet_table[] = {
25,
50,
75,
100,
};
-static const int lab_rdson_pfet_plan[] = {
+static const int lab_rdson_pfet_table[] = {
25,
50,
75,
100,
};
-static const int lab_max_precharge_plan[] = {
+static const int lab_max_precharge_table[] = {
200,
300,
400,
500,
};
+static const int ibb_pfm_peak_curr_table[] = {
+ 150,
+ 200,
+ 250,
+ 300,
+ 350,
+ 400,
+ 450,
+ 500
+};
+
+static const int ibb_pfm_hysteresis_table[] = {
+ 0,
+ 25,
+ 50,
+ 0
+};
+
+static const int lab_vref_high_psrr_table[] = {
+ 350,
+ 400,
+ 450,
+ 500
+};
+
struct lab_regulator {
struct regulator_desc rdesc;
struct regulator_dev *rdev;
@@ -471,6 +576,7 @@ struct ibb_regulator {
u32 pwrdn_dly;
int vreg_enabled;
+ int num_swire_trans;
};
struct qpnp_labibb {
@@ -484,12 +590,16 @@ struct qpnp_labibb {
u8 ibb_dig_major;
struct lab_regulator lab_vreg;
struct ibb_regulator ibb_vreg;
+ const struct ibb_ver_ops *ibb_ver_ops;
+ const struct lab_ver_ops *lab_ver_ops;
+ struct mutex bus_mutex;
enum qpnp_labibb_mode mode;
bool standalone;
bool ttw_en;
bool in_ttw_mode;
bool ibb_settings_saved;
bool swire_control;
+ bool pbs_control;
bool ttw_force_lab_on;
bool skip_2nd_swire_cmd;
bool pfm_enable;
@@ -497,6 +607,28 @@ struct qpnp_labibb {
u32 swire_ibb_ps_enable_delay;
};
+struct ibb_ver_ops {
+ int (*set_default_voltage)(struct qpnp_labibb *labibb,
+ bool use_default);
+ int (*set_voltage)(struct qpnp_labibb *labibb, int min_uV, int max_uV);
+ int (*sel_mode)(struct qpnp_labibb *labibb, bool is_ibb);
+ int (*get_mode)(struct qpnp_labibb *labibb);
+ int (*set_clk_div)(struct qpnp_labibb *labibb, u8 val);
+ int (*smart_ps_config)(struct qpnp_labibb *labibb, bool enable,
+ int num_swire_trans, int neg_curr_limit);
+ int (*soft_start_ctl)(struct qpnp_labibb *labibb,
+ struct device_node *of_node);
+ int (*voltage_at_one_pulse)(struct qpnp_labibb *labibb, u32 volt);
+};
+
+struct lab_ver_ops {
+ const char *ver_str;
+ int (*set_default_voltage)(struct qpnp_labibb *labibb,
+ bool default_pres);
+ int (*ps_ctl)(struct qpnp_labibb *labibb,
+ u32 thresh, bool enable);
+};
+
enum ibb_settings_index {
IBB_PD_CTL = 0,
IBB_CURRENT_LIMIT,
@@ -545,114 +677,722 @@ static struct settings lab_settings[LAB_SETTINGS_MAX] = {
SETTING(LAB_RDSON_MNGMNT, false),
};
-static int qpnp_labibb_read(struct qpnp_labibb *labibb, u8 *val, u16 address,
- int count)
+static int
+qpnp_labibb_read(struct qpnp_labibb *labibb, u16 address,
+ u8 *val, int count)
{
int rc = 0;
struct platform_device *pdev = labibb->pdev;
- if (address == 0) {
- pr_err("address cannot be zero address=0x%02x sid=0x%02x rc=%d\n",
- address, to_spmi_device(pdev->dev.parent)->usid, rc);
- return -EINVAL;
- }
-
+ mutex_lock(&(labibb->bus_mutex));
rc = regmap_bulk_read(labibb->regmap, address, val, count);
- if (rc) {
+ if (rc < 0)
pr_err("SPMI read failed address=0x%02x sid=0x%02x rc=%d\n",
address, to_spmi_device(pdev->dev.parent)->usid, rc);
- return rc;
- }
- return 0;
+ mutex_unlock(&(labibb->bus_mutex));
+ return rc;
}
-static int qpnp_labibb_write(struct qpnp_labibb *labibb, u16 address, u8 *val,
- int count)
+static int
+qpnp_labibb_write(struct qpnp_labibb *labibb, u16 address,
+ u8 *val, int count)
{
int rc = 0;
struct platform_device *pdev = labibb->pdev;
+ mutex_lock(&(labibb->bus_mutex));
if (address == 0) {
pr_err("address cannot be zero address=0x%02x sid=0x%02x rc=%d\n",
address, to_spmi_device(pdev->dev.parent)->usid, rc);
- return -EINVAL;
+ rc = -EINVAL;
+ goto error;
}
rc = regmap_bulk_write(labibb->regmap, address, val, count);
- if (rc) {
+ if (rc < 0)
pr_err("write failed address=0x%02x sid=0x%02x rc=%d\n",
address, to_spmi_device(pdev->dev.parent)->usid, rc);
- return rc;
- }
- return 0;
+error:
+ mutex_unlock(&(labibb->bus_mutex));
+ return rc;
}
-static int qpnp_labibb_masked_write(struct qpnp_labibb *labibb, u16 address,
- u8 mask, u8 val)
+static int
+qpnp_labibb_masked_write(struct qpnp_labibb *labibb, u16 address,
+ u8 mask, u8 val)
{
- int rc;
+ int rc = 0;
+ struct platform_device *pdev = labibb->pdev;
+
+ mutex_lock(&(labibb->bus_mutex));
+ if (address == 0) {
+ pr_err("address cannot be zero address=0x%02x sid=0x%02x\n",
+ address, to_spmi_device(pdev->dev.parent)->usid);
+ rc = -EINVAL;
+ goto error;
+ }
rc = regmap_update_bits(labibb->regmap, address, mask, val);
- if (rc) {
+ if (rc < 0)
pr_err("spmi write failed: addr=%03X, rc=%d\n", address, rc);
- return rc;
- }
- return 0;
+error:
+ mutex_unlock(&(labibb->bus_mutex));
+ return rc;
}
static int qpnp_labibb_sec_write(struct qpnp_labibb *labibb, u16 base,
- u8 offset, u8 *val, int count)
+ u8 offset, u8 val)
{
- int rc;
+ int rc = 0;
u8 sec_val = REG_LAB_IBB_SEC_UNLOCK_CODE;
+ struct platform_device *pdev = labibb->pdev;
- rc = qpnp_labibb_write(labibb, base + REG_LAB_IBB_SEC_ACCESS, &sec_val,
- 1);
- if (rc) {
- pr_err("qpnp_lab_write register %x failed rc = %d\n",
+ mutex_lock(&(labibb->bus_mutex));
+ if (base == 0) {
+ pr_err("base cannot be zero base=0x%02x sid=0x%02x\n",
+ base, to_spmi_device(pdev->dev.parent)->usid);
+ rc = -EINVAL;
+ goto error;
+ }
+
+ rc = regmap_write(labibb->regmap, base + REG_LAB_IBB_SEC_ACCESS,
+ sec_val);
+ if (rc < 0) {
+ pr_err("register %x failed rc = %d\n",
base + REG_LAB_IBB_SEC_ACCESS, rc);
- return rc;
+ goto error;
}
- rc = qpnp_labibb_write(labibb, base + offset, val, count);
- if (rc)
- pr_err("qpnp_labibb_write failed: addr=%03X, rc=%d\n",
+ rc = regmap_write(labibb->regmap, base + offset, val);
+ if (rc < 0)
+ pr_err("failed: addr=%03X, rc=%d\n",
base + offset, rc);
+error:
+ mutex_unlock(&(labibb->bus_mutex));
return rc;
}
static int qpnp_labibb_sec_masked_write(struct qpnp_labibb *labibb, u16 base,
u8 offset, u8 mask, u8 val)
{
- int rc;
+ int rc = 0;
u8 sec_val = REG_LAB_IBB_SEC_UNLOCK_CODE;
+ struct platform_device *pdev = labibb->pdev;
- rc = qpnp_labibb_write(labibb, base + REG_LAB_IBB_SEC_ACCESS, &sec_val,
- 1);
- if (rc) {
- pr_err("qpnp_lab_write register %x failed rc = %d\n",
+ mutex_lock(&(labibb->bus_mutex));
+ if (base == 0) {
+ pr_err("base cannot be zero base=0x%02x sid=0x%02x\n",
+ base, to_spmi_device(pdev->dev.parent)->usid);
+ rc = -EINVAL;
+ goto error;
+ }
+
+ rc = regmap_write(labibb->regmap, base + REG_LAB_IBB_SEC_ACCESS,
+ sec_val);
+ if (rc < 0) {
+ pr_err("register %x failed rc = %d\n",
base + REG_LAB_IBB_SEC_ACCESS, rc);
+ goto error;
+ }
+
+ rc = regmap_update_bits(labibb->regmap, base + offset, mask, val);
+ if (rc < 0)
+ pr_err("spmi write failed: addr=%03X, rc=%d\n", base, rc);
+
+error:
+ mutex_unlock(&(labibb->bus_mutex));
+ return rc;
+}
+
+static int qpnp_ibb_smart_ps_config_v1(struct qpnp_labibb *labibb, bool enable,
+ int num_swire_trans, int neg_curr_limit)
+{
+ return 0;
+}
+
+static int qpnp_ibb_smart_ps_config_v2(struct qpnp_labibb *labibb, bool enable,
+ int num_swire_trans, int neg_curr_limit)
+{
+ u8 val;
+ int rc = 0;
+
+ if (enable) {
+ val = IBB_NUM_SWIRE_PULSE_WAIT;
+ rc = qpnp_labibb_write(labibb,
+ labibb->ibb_base + REG_IBB_PS_CTL, &val, 1);
+ if (rc < 0) {
+ pr_err("write register %x failed rc = %d\n",
+ REG_IBB_PS_CTL, rc);
+ return rc;
+ }
+ }
+
+ val = enable ? IBB_SMART_PS_CTL_EN : IBB_NUM_SWIRE_PULSE_WAIT;
+ if (num_swire_trans)
+ val |= num_swire_trans;
+ else
+ val |= IBB_NUM_SWIRE_PULSE_WAIT;
+
+ rc = qpnp_labibb_write(labibb,
+ labibb->ibb_base + REG_IBB_SMART_PS_CTL, &val, 1);
+ if (rc < 0) {
+ pr_err("write register %x failed rc = %d\n",
+ REG_IBB_SMART_PS_CTL, rc);
return rc;
}
- rc = qpnp_labibb_masked_write(labibb, base + offset, mask, val);
- if (rc)
- pr_err("qpnp_lab_write register %x failed rc = %d\n",
- base + offset, rc);
+ val = enable ? (neg_curr_limit ? neg_curr_limit :
+ IBB_DEFAULT_NLIMIT_DAC) : IBB_DEFAULT_NLIMIT_DAC;
+
+ rc = qpnp_labibb_write(labibb,
+ labibb->ibb_base + REG_IBB_NLIMIT_DAC, &val, 1);
+ if (rc < 0)
+ pr_err("write register %x failed rc = %d\n",
+ REG_IBB_NLIMIT_DAC, rc);
return rc;
}
+static int qpnp_labibb_sel_mode_v1(struct qpnp_labibb *labibb, bool is_ibb)
+{
+ int rc = 0;
+ u8 val;
+ u16 base;
+
+ val = (labibb->mode == QPNP_LABIBB_LCD_MODE) ? REG_LAB_IBB_LCD_MODE :
+ REG_LAB_IBB_AMOLED_MODE;
+
+ base = is_ibb ? labibb->ibb_base : labibb->lab_base;
+
+ rc = qpnp_labibb_sec_write(labibb, base, REG_LAB_LCD_AMOLED_SEL,
+ val);
+ if (rc < 0)
+ pr_err("register %x failed rc = %d\n",
+ REG_LAB_LCD_AMOLED_SEL, rc);
+
+ return rc;
+}
+
+static int qpnp_labibb_sel_mode_v2(struct qpnp_labibb *labibb, bool is_ibb)
+{
+ return 0;
+}
+
+static int qpnp_ibb_get_mode_v1(struct qpnp_labibb *labibb)
+{
+ int rc = 0;
+ u8 val;
+
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base + REG_IBB_LCD_AMOLED_SEL,
+ &val, 1);
+ if (rc < 0)
+ return rc;
+
+ if (val == REG_LAB_IBB_AMOLED_MODE)
+ labibb->mode = QPNP_LABIBB_AMOLED_MODE;
+ else
+ labibb->mode = QPNP_LABIBB_LCD_MODE;
+
+ return 0;
+}
+
+static int qpnp_ibb_get_mode_v2(struct qpnp_labibb *labibb)
+{
+ labibb->mode = QPNP_LABIBB_AMOLED_MODE;
+
+ return 0;
+}
+
+static int qpnp_ibb_set_clk_div_v1(struct qpnp_labibb *labibb, u8 val)
+{
+ int rc = 0;
+
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_CLK_DIV,
+ &val, 1);
+
+ return rc;
+}
+
+static int qpnp_ibb_set_clk_div_v2(struct qpnp_labibb *labibb, u8 val)
+{
+ int rc = 0;
+
+ val |= IBB_CLK_DIV_OVERRIDE_EN;
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_CLK_DIV, IBB_CLK_DIV_MASK |
+ IBB_CLK_DIV_OVERRIDE_EN, val);
+
+ return rc;
+}
+
+static int qpnp_ibb_soft_start_ctl_v1(struct qpnp_labibb *labibb,
+ struct device_node *of_node)
+{
+ int rc = 0;
+ u8 val;
+ u32 tmp;
+
+ rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-soft-start",
+ &(labibb->ibb_vreg.soft_start));
+ if (rc < 0) {
+ pr_err("qcom,qpnp-ibb-soft-start is missing, rc = %d\n",
+ rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-discharge-resistor",
+ &tmp);
+
+ if (rc < 0) {
+ pr_err("qcom,qpnp-ibb-discharge-resistor is missing, rc = %d\n",
+ rc);
+ return rc;
+ }
+
+ if (labibb->mode == QPNP_LABIBB_AMOLED_MODE) {
+ /*
+ * AMOLED mode needs ibb discharge resistor to be
+ * configured for 300KOhm
+ */
+ if (tmp < ibb_discharge_resistor_table[0])
+ tmp = ibb_discharge_resistor_table[0];
+ }
+
+ for (val = 0; val < ARRAY_SIZE(ibb_discharge_resistor_table); val++)
+ if (ibb_discharge_resistor_table[val] == tmp)
+ break;
+
+ if (val == ARRAY_SIZE(ibb_discharge_resistor_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-discharge-resistor\n");
+ return -EINVAL;
+ }
+
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base +
+ REG_IBB_SOFT_START_CTL, &val, 1);
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
+ REG_IBB_SOFT_START_CTL, rc);
+
+ return rc;
+}
+
+static int qpnp_ibb_soft_start_ctl_v2(struct qpnp_labibb *labibb,
+ struct device_node *of_node)
+{
+ return 0;
+}
+
+static int qpnp_ibb_vreg_ok_ctl(struct qpnp_labibb *labibb,
+ struct device_node *of_node)
+{
+ u8 val = 0;
+ int rc = 0, i = 0;
+ u32 tmp;
+
+ if (labibb->pmic_rev_id->pmic_subtype != PM660L_SUBTYPE)
+ return rc;
+
+ val |= IBB_VREG_OK_EN_OVERLOAD_BLANK;
+
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-ibb-overload-debounce", &tmp);
+ if (rc < 0) {
+ pr_err("failed to read qcom,qpnp-ibb-overload-debounce rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ibb_overload_debounce_table); i++)
+ if (ibb_overload_debounce_table[i] == tmp)
+ break;
+
+ if (i == ARRAY_SIZE(ibb_overload_debounce_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-overload-debounce\n");
+ return -EINVAL;
+ }
+ val |= i << IBB_VREG_OK_OVERLOAD_DEB_SHIFT;
+
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-ibb-vreg-ok-debounce", &tmp);
+ if (rc < 0) {
+ pr_err("failed to read qcom,qpnp-ibb-vreg-ok-debounce rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ibb_vreg_ok_deb_table); i++)
+ if (ibb_vreg_ok_deb_table[i] == tmp)
+ break;
+
+ if (i == ARRAY_SIZE(ibb_vreg_ok_deb_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-vreg-ok-debounce\n");
+ return -EINVAL;
+ }
+ val |= i;
+
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base +
+ REG_IBB_VREG_OK_CTL,
+ &val, 1);
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
+ REG_IBB_VREG_OK_CTL, rc);
+
+ return rc;
+}
+
+static int qpnp_ibb_set_default_voltage_v1(struct qpnp_labibb *labibb,
+ bool use_default)
+{
+ u8 val;
+ int rc = 0;
+
+ if (!use_default) {
+ if (labibb->ibb_vreg.curr_volt < labibb->ibb_vreg.min_volt) {
+ pr_err("qcom,qpnp-ibb-init-voltage %d is less than the the minimum voltage %d",
+ labibb->ibb_vreg.curr_volt, labibb->ibb_vreg.min_volt);
+ return -EINVAL;
+ }
+
+ val = DIV_ROUND_UP(labibb->ibb_vreg.curr_volt -
+ labibb->ibb_vreg.min_volt,
+ labibb->ibb_vreg.step_size);
+ if (val > IBB_VOLTAGE_SET_MASK) {
+ pr_err("qcom,qpnp-lab-init-voltage %d is larger than the max supported voltage %ld",
+ labibb->ibb_vreg.curr_volt,
+ labibb->ibb_vreg.min_volt +
+ labibb->ibb_vreg.step_size *
+ IBB_VOLTAGE_SET_MASK);
+ return -EINVAL;
+ }
+
+ labibb->ibb_vreg.curr_volt = val * labibb->ibb_vreg.step_size +
+ labibb->ibb_vreg.min_volt;
+ val |= IBB_VOLTAGE_OVERRIDE_EN;
+ } else {
+ val = 0;
+ }
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_VOLTAGE, IBB_VOLTAGE_SET_MASK |
+ IBB_VOLTAGE_OVERRIDE_EN, val);
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n", REG_IBB_VOLTAGE,
+ rc);
+
+ return rc;
+}
+
+static int qpnp_ibb_set_default_voltage_v2(struct qpnp_labibb *labibb,
+ bool use_default)
+{
+ int rc = 0;
+ u8 val;
+
+ val = DIV_ROUND_UP(labibb->ibb_vreg.curr_volt,
+ labibb->ibb_vreg.step_size);
+ if (val > IBB_VOLTAGE_SET_MASK) {
+ pr_err("Invalid qcom,qpnp-ibb-init-voltage property %d",
+ labibb->ibb_vreg.curr_volt);
+ return -EINVAL;
+ }
+
+ labibb->ibb_vreg.curr_volt = val * labibb->ibb_vreg.step_size;
+
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base +
+ REG_IBB_DEFAULT_VOLTAGE, &val, 1);
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
+ REG_IBB_DEFAULT_VOLTAGE, rc);
+
+ return rc;
+}
+
+static int qpnp_ibb_set_voltage_v1(struct qpnp_labibb *labibb,
+ int min_uV, int max_uV)
+{
+ int rc, new_uV;
+ u8 val;
+
+ if (min_uV < labibb->ibb_vreg.min_volt) {
+ pr_err("min_uV %d is less than min_volt %d", min_uV,
+ labibb->ibb_vreg.min_volt);
+ return -EINVAL;
+ }
+
+ val = DIV_ROUND_UP(min_uV - labibb->ibb_vreg.min_volt,
+ labibb->ibb_vreg.step_size);
+ new_uV = val * labibb->ibb_vreg.step_size + labibb->ibb_vreg.min_volt;
+
+ if (new_uV > max_uV) {
+ pr_err("unable to set voltage %d (min:%d max:%d)\n", new_uV,
+ min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_VOLTAGE,
+ IBB_VOLTAGE_SET_MASK |
+ IBB_VOLTAGE_OVERRIDE_EN,
+ val | IBB_VOLTAGE_OVERRIDE_EN);
+
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n", REG_IBB_VOLTAGE,
+ rc);
+ return rc;
+ }
+
+ if (new_uV > labibb->ibb_vreg.curr_volt) {
+ val = DIV_ROUND_UP(new_uV - labibb->ibb_vreg.curr_volt,
+ labibb->ibb_vreg.step_size);
+ udelay(val * labibb->ibb_vreg.slew_rate);
+ }
+ labibb->ibb_vreg.curr_volt = new_uV;
+
+ return 0;
+}
+
+static int qpnp_ibb_set_voltage_v2(struct qpnp_labibb *labibb,
+ int min_uV, int max_uV)
+{
+ int rc, new_uV;
+ u8 val;
+
+ val = DIV_ROUND_UP(min_uV, labibb->ibb_vreg.step_size);
+ new_uV = val * labibb->ibb_vreg.step_size;
+
+ if (new_uV > max_uV) {
+ pr_err("unable to set voltage %d (min:%d max:%d)\n", new_uV,
+ min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base +
+ REG_IBB_VOLTAGE, &val, 1);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n", REG_IBB_VOLTAGE,
+ rc);
+ return rc;
+ }
+
+ if (new_uV > labibb->ibb_vreg.curr_volt) {
+ val = DIV_ROUND_UP(new_uV - labibb->ibb_vreg.curr_volt,
+ labibb->ibb_vreg.step_size);
+ udelay(val * labibb->ibb_vreg.slew_rate);
+ }
+ labibb->ibb_vreg.curr_volt = new_uV;
+
+ return 0;
+}
+
+static int qpnp_ibb_output_voltage_at_one_pulse_v1(struct qpnp_labibb *labibb,
+ u32 volt)
+{
+ int rc = 0;
+ u8 val;
+
+ /*
+ * Set the output voltage 100mV lower as the IBB HW module
+ * counts one pulse less in SWIRE mode.
+ */
+ val = DIV_ROUND_UP((volt - MIN_OUTPUT_PULSE_VOLTAGE_MV),
+ OUTPUT_VOLTAGE_STEP_MV) - 1;
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_SWIRE_CTL,
+ IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_MASK,
+ val);
+ if (rc < 0)
+ pr_err("write register %x failed rc = %d\n",
+ REG_IBB_SWIRE_CTL, rc);
+
+ return rc;
+}
+
+static int qpnp_ibb_output_voltage_at_one_pulse_v2(struct qpnp_labibb *labibb,
+ u32 volt)
+{
+ int rc = 0;
+ u8 val;
+
+ val = DIV_ROUND_UP(volt, OUTPUT_VOLTAGE_STEP_MV);
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_SWIRE_CTL,
+ IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_MASK,
+ val);
+ if (rc < 0)
+ pr_err("qpnp_labiibb_write register %x failed rc = %d\n",
+ REG_IBB_SWIRE_CTL, rc);
+
+ return rc;
+}
+
+static const struct ibb_ver_ops ibb_ops_v1 = {
+ .set_default_voltage = qpnp_ibb_set_default_voltage_v1,
+ .set_voltage = qpnp_ibb_set_voltage_v1,
+ .sel_mode = qpnp_labibb_sel_mode_v1,
+ .get_mode = qpnp_ibb_get_mode_v1,
+ .set_clk_div = qpnp_ibb_set_clk_div_v1,
+ .smart_ps_config = qpnp_ibb_smart_ps_config_v1,
+ .soft_start_ctl = qpnp_ibb_soft_start_ctl_v1,
+ .voltage_at_one_pulse = qpnp_ibb_output_voltage_at_one_pulse_v1,
+};
+
+static const struct ibb_ver_ops ibb_ops_v2 = {
+ .set_default_voltage = qpnp_ibb_set_default_voltage_v2,
+ .set_voltage = qpnp_ibb_set_voltage_v2,
+ .sel_mode = qpnp_labibb_sel_mode_v2,
+ .get_mode = qpnp_ibb_get_mode_v2,
+ .set_clk_div = qpnp_ibb_set_clk_div_v2,
+ .smart_ps_config = qpnp_ibb_smart_ps_config_v2,
+ .soft_start_ctl = qpnp_ibb_soft_start_ctl_v2,
+ .voltage_at_one_pulse = qpnp_ibb_output_voltage_at_one_pulse_v2,
+};
+
+static int qpnp_lab_set_default_voltage_v1(struct qpnp_labibb *labibb,
+ bool default_pres)
+{
+ u8 val;
+ int rc = 0;
+
+ if (!default_pres) {
+ if (labibb->lab_vreg.curr_volt < labibb->lab_vreg.min_volt) {
+ pr_err("qcom,qpnp-lab-init-voltage %d is less than the the minimum voltage %d",
+ labibb->lab_vreg.curr_volt,
+ labibb->lab_vreg.min_volt);
+ return -EINVAL;
+ }
+
+ val = DIV_ROUND_UP(labibb->lab_vreg.curr_volt -
+ labibb->lab_vreg.min_volt,
+ labibb->lab_vreg.step_size);
+ if (val > LAB_VOLTAGE_SET_MASK) {
+ pr_err("qcom,qpnp-lab-init-voltage %d is larger than the max supported voltage %ld",
+ labibb->lab_vreg.curr_volt,
+ labibb->lab_vreg.min_volt +
+ labibb->lab_vreg.step_size *
+ LAB_VOLTAGE_SET_MASK);
+ return -EINVAL;
+ }
+
+ labibb->lab_vreg.curr_volt = val * labibb->lab_vreg.step_size +
+ labibb->lab_vreg.min_volt;
+ val |= LAB_VOLTAGE_OVERRIDE_EN;
+
+ } else {
+ val = 0;
+ }
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_VOLTAGE, LAB_VOLTAGE_SET_MASK |
+ LAB_VOLTAGE_OVERRIDE_EN, val);
+
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n", REG_LAB_VOLTAGE,
+ rc);
+
+ return rc;
+}
+
+static int qpnp_lab_set_default_voltage_v2(struct qpnp_labibb *labibb,
+ bool default_pres)
+{
+ int rc = 0;
+ u8 val;
+
+ val = DIV_ROUND_UP((labibb->lab_vreg.curr_volt
+ - labibb->lab_vreg.min_volt), labibb->lab_vreg.step_size);
+
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_VOUT_DEFAULT, &val, 1);
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_VOUT_DEFAULT, rc);
+
+ return rc;
+}
+
+static int qpnp_lab_ps_ctl_v1(struct qpnp_labibb *labibb,
+ u32 thresh, bool enable)
+{
+ int rc = 0;
+ u8 val;
+
+ if (enable) {
+ for (val = 0; val < ARRAY_SIZE(lab_ps_thresh_table_v1); val++)
+ if (lab_ps_thresh_table_v1[val] == thresh)
+ break;
+
+ if (val == ARRAY_SIZE(lab_ps_thresh_table_v1)) {
+ pr_err("Invalid value in qcom,qpnp-lab-ps-threshold\n");
+ return -EINVAL;
+ }
+
+ val |= LAB_PS_CTL_EN;
+ } else {
+ val = 0;
+ }
+
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_PS_CTL, &val, 1);
+
+ if (rc < 0)
+ pr_err("write register %x failed rc = %d\n",
+ REG_LAB_PS_CTL, rc);
+
+ return rc;
+}
+
+static int qpnp_lab_ps_ctl_v2(struct qpnp_labibb *labibb,
+ u32 thresh, bool enable)
+{
+ int rc = 0;
+ u8 val;
+
+ if (enable) {
+ for (val = 0; val < ARRAY_SIZE(lab_ps_thresh_table_v2); val++)
+ if (lab_ps_thresh_table_v2[val] == thresh)
+ break;
+
+ if (val == ARRAY_SIZE(lab_ps_thresh_table_v2)) {
+ pr_err("Invalid value in qcom,qpnp-lab-ps-threshold\n");
+ return -EINVAL;
+ }
+
+ val |= LAB_PS_CTL_EN;
+ } else {
+ val = 0;
+ }
+
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_PS_CTL, &val, 1);
+
+ if (rc < 0)
+ pr_err("write register %x failed rc = %d\n",
+ REG_LAB_PS_CTL, rc);
+
+ return rc;
+}
+
+static const struct lab_ver_ops lab_ops_v1 = {
+ .set_default_voltage = qpnp_lab_set_default_voltage_v1,
+ .ps_ctl = qpnp_lab_ps_ctl_v1,
+};
+
+static const struct lab_ver_ops lab_ops_v2 = {
+ .set_default_voltage = qpnp_lab_set_default_voltage_v2,
+ .ps_ctl = qpnp_lab_ps_ctl_v2,
+};
+
static int qpnp_labibb_get_matching_idx(const char *val)
{
int i;
- for (i = 0; i < ARRAY_SIZE(lab_current_sense_plan); i++)
- if (!strcmp(lab_current_sense_plan[i], val))
+ for (i = 0; i < ARRAY_SIZE(lab_current_sense_table); i++)
+ if (!strcmp(lab_current_sense_table[i], val))
return i;
return -EINVAL;
@@ -677,7 +1417,7 @@ static int qpnp_ibb_set_mode(struct qpnp_labibb *labibb, enum ibb_mode mode)
rc = qpnp_labibb_masked_write(labibb,
labibb->ibb_base + REG_IBB_ENABLE_CTL,
IBB_ENABLE_CTL_MASK, val);
- if (rc)
+ if (rc < 0)
pr_err("Unable to configure IBB_ENABLE_CTL rc=%d\n", rc);
return rc;
@@ -688,21 +1428,21 @@ static int qpnp_ibb_ps_config(struct qpnp_labibb *labibb, bool enable)
u8 val;
int rc;
- val = enable ? IBB_PS_CTL_EN : IBB_PS_CTL_DISABLE;
+ val = enable ? IBB_PS_CTL_EN : IBB_NUM_SWIRE_PULSE_WAIT;
rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_PS_CTL,
- &val, 1);
- if (rc) {
- pr_err("qpnp_ibb_ps_config write register %x failed rc = %d\n",
- REG_IBB_PS_CTL, rc);
+ &val, 1);
+ if (rc < 0) {
+ pr_err("write register %x failed rc = %d\n",
+ REG_IBB_PS_CTL, rc);
return rc;
}
- val = enable ? IBB_NLIMIT_DAC_EN : IBB_NLIMIT_DAC_DISABLE;
+ val = enable ? 0 : IBB_DEFAULT_NLIMIT_DAC;
rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_NLIMIT_DAC,
- &val, 1);
- if (rc)
- pr_err("qpnp_ibb_ps_config write register %x failed rc = %d\n",
- REG_IBB_NLIMIT_DAC, rc);
+ &val, 1);
+ if (rc < 0)
+ pr_err("write register %x failed rc = %d\n",
+ REG_IBB_NLIMIT_DAC, rc);
return rc;
}
@@ -710,7 +1450,7 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
struct device_node *of_node)
{
int rc = 0;
- u8 i, val;
+ u8 i, val, mask;
u32 tmp;
/*
@@ -718,234 +1458,242 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
* GPIO selector.
*/
if (labibb->pmic_rev_id->pmic_subtype != PMI8998_SUBTYPE) {
- if (labibb->mode == QPNP_LABIBB_LCD_MODE)
- val = REG_LAB_IBB_LCD_MODE;
- else
- val = REG_LAB_IBB_AMOLED_MODE;
-
- rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
- REG_LAB_LCD_AMOLED_SEL, &val, 1);
-
- if (rc) {
- pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
- REG_LAB_LCD_AMOLED_SEL, rc);
+ rc = labibb->ibb_ver_ops->sel_mode(labibb, 0);
+ if (rc < 0)
return rc;
- }
}
val = 0;
-
if (of_property_read_bool(of_node, "qcom,qpnp-lab-full-pull-down"))
val |= LAB_PD_CTL_STRONG_PULL;
if (!of_property_read_bool(of_node, "qcom,qpnp-lab-pull-down-enable"))
val |= LAB_PD_CTL_DISABLE_PD;
- rc = qpnp_labibb_write(labibb, labibb->lab_base + REG_LAB_PD_CTL,
- &val, 1);
+ mask = LAB_PD_CTL_EN_MASK | LAB_PD_CTL_STRENGTH_MASK;
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base + REG_LAB_PD_CTL,
+ mask, val);
- if (rc) {
- pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_LAB_PD_CTL, rc);
return rc;
}
rc = of_property_read_u32(of_node,
- "qcom,qpnp-lab-switching-clock-frequency", &tmp);
- if (rc) {
- pr_err("get qcom,qpnp-lab-switching-clock-frequency failed rc = %d\n",
- rc);
- return rc;
- }
-
- for (val = 0; val < ARRAY_SIZE(lab_clk_div_plan); val++)
- if (lab_clk_div_plan[val] == tmp)
- break;
+ "qcom,qpnp-lab-switching-clock-frequency", &tmp);
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(lab_clk_div_table); val++)
+ if (lab_clk_div_table[val] == tmp)
+ break;
- if (val == ARRAY_SIZE(lab_clk_div_plan)) {
- pr_err("Invalid property in qpnp-lab-switching-clock-frequency\n");
- return -EINVAL;
- }
+ if (val == ARRAY_SIZE(lab_clk_div_table)) {
+ pr_err("Invalid value in qpnp-lab-switching-clock-frequency\n");
+ return -EINVAL;
+ }
- rc = qpnp_labibb_write(labibb, labibb->lab_base + REG_LAB_CLK_DIV,
- &val, 1);
- if (rc) {
- pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
- REG_LAB_CLK_DIV, rc);
- return rc;
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_CLK_DIV, &val, 1);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_CLK_DIV, rc);
+ return rc;
+ }
}
- rc = of_property_read_u32(of_node,
- "qcom,qpnp-lab-limit-maximum-current", &tmp);
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-lab-limit-max-current-enable")) {
+ val = LAB_CURRENT_LIMIT_EN_BIT;
- if (rc) {
- pr_err("get qcom,qpnp-lab-limit-maximum-current failed rc = %d\n",
- rc);
- return rc;
- }
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-lab-limit-maximum-current", &tmp);
- for (val = 0; val < ARRAY_SIZE(lab_current_limit_plan); val++)
- if (lab_current_limit_plan[val] == tmp)
- break;
+ if (rc < 0) {
+ pr_err("get qcom,qpnp-lab-limit-maximum-current failed rc = %d\n",
+ rc);
+ return rc;
+ }
- if (val == ARRAY_SIZE(lab_current_limit_plan)) {
- pr_err("Invalid property in qcom,qpnp-lab-limit-maximum-current\n");
- return -EINVAL;
- }
+ for (i = 0; i < ARRAY_SIZE(lab_current_limit_table); i++)
+ if (lab_current_limit_table[i] == tmp)
+ break;
- if (of_property_read_bool(of_node,
- "qcom,qpnp-lab-limit-max-current-enable"))
- val |= LAB_CURRENT_LIMIT_EN_BIT;
+ if (i == ARRAY_SIZE(lab_current_limit_table)) {
+ pr_err("Invalid value in qcom,qpnp-lab-limit-maximum-current\n");
+ return -EINVAL;
+ }
- rc = qpnp_labibb_write(labibb, labibb->lab_base +
- REG_LAB_CURRENT_LIMIT, &val, 1);
- if (rc) {
- pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
- REG_LAB_CURRENT_LIMIT, rc);
- return rc;
+ val |= i;
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_CURRENT_LIMIT, &val, 1);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_CURRENT_LIMIT, rc);
+ return rc;
+ }
}
if (of_property_read_bool(of_node,
"qcom,qpnp-lab-ring-suppression-enable")) {
val = LAB_RING_SUPPRESSION_CTL_EN;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
- REG_LAB_RING_SUPPRESSION_CTL,
- &val,
- 1);
- if (rc) {
- pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
+ REG_LAB_RING_SUPPRESSION_CTL, &val, 1);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_LAB_RING_SUPPRESSION_CTL, rc);
return rc;
}
}
- rc = of_property_read_u32(of_node, "qcom,qpnp-lab-ps-threshold", &tmp);
+ if (of_property_read_bool(of_node, "qcom,qpnp-lab-ps-enable")) {
- if (rc) {
- pr_err("get qcom,qpnp-lab-ps-threshold failed rc = %d\n",
- rc);
- return rc;
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-lab-ps-threshold", &tmp);
+
+ if (rc < 0) {
+ pr_err("get qcom,qpnp-lab-ps-threshold failed rc = %d\n",
+ rc);
+ return rc;
+ }
+ rc = labibb->lab_ver_ops->ps_ctl(labibb, tmp, true);
+ if (rc < 0)
+ return rc;
+ } else {
+ rc = labibb->lab_ver_ops->ps_ctl(labibb, tmp, false);
+ if (rc < 0)
+ return rc;
}
- for (val = 0; val < ARRAY_SIZE(lab_ps_threshold_plan); val++)
- if (lab_ps_threshold_plan[val] == tmp)
- break;
+ val = 0;
+ mask = 0;
+ rc = of_property_read_u32(of_node, "qcom,qpnp-lab-pfet-size", &tmp);
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(lab_rdson_pfet_table); val++)
+ if (tmp == lab_rdson_pfet_table[val])
+ break;
- if (val == ARRAY_SIZE(lab_ps_threshold_plan)) {
- pr_err("Invalid property in qcom,qpnp-lab-ps-threshold\n");
- return -EINVAL;
+ if (val == ARRAY_SIZE(lab_rdson_pfet_table)) {
+ pr_err("Invalid value in qcom,qpnp-lab-pfet-size\n");
+ return -EINVAL;
+ }
+ val |= LAB_RDSON_MNGMNT_PFET_SLEW_EN;
+ mask |= LAB_RDSON_MNGMNT_PFET_MASK |
+ LAB_RDSON_MNGMNT_PFET_SLEW_EN;
}
- if (of_property_read_bool(of_node, "qcom,qpnp-lab-ps-enable"))
- val |= LAB_PS_CTL_EN;
+ rc = of_property_read_u32(of_node, "qcom,qpnp-lab-nfet-size",
+ &tmp);
+ if (!rc) {
+ for (i = 0; i < ARRAY_SIZE(lab_rdson_nfet_table); i++)
+ if (tmp == lab_rdson_nfet_table[i])
+ break;
- rc = qpnp_labibb_write(labibb, labibb->lab_base + REG_LAB_PS_CTL,
- &val, 1);
+ if (i == ARRAY_SIZE(lab_rdson_nfet_table)) {
+ pr_err("Invalid value in qcom,qpnp-lab-nfet-size\n");
+ return -EINVAL;
+ }
- if (rc) {
- pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
- REG_LAB_PS_CTL, rc);
- return rc;
+ val |= i << LAB_RDSON_MNGMNT_NFET_SHIFT;
+ val |= LAB_RDSON_MNGMNT_NFET_SLEW_EN;
+ mask |= LAB_RDSON_MNGMNT_NFET_MASK |
+ LAB_RDSON_MNGMNT_NFET_SLEW_EN;
}
- rc = of_property_read_u32(of_node, "qcom,qpnp-lab-pfet-size", &tmp);
-
- if (rc) {
- pr_err("get qcom,qpnp-lab-pfet-size, rc = %d\n", rc);
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_RDSON_MNGMNT, mask, val);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_RDSON_MNGMNT, rc);
return rc;
}
- for (val = 0; val < ARRAY_SIZE(lab_rdson_pfet_plan); val++)
- if (tmp == lab_rdson_pfet_plan[val])
- break;
-
- if (val == ARRAY_SIZE(lab_rdson_pfet_plan)) {
- pr_err("Invalid property in qcom,qpnp-lab-pfet-size\n");
- return -EINVAL;
+ rc = of_property_read_u32(of_node, "qcom,qpnp-lab-init-voltage",
+ &(labibb->lab_vreg.curr_volt));
+ if (rc < 0) {
+ pr_err("get qcom,qpnp-lab-init-voltage failed, rc = %d\n",
+ rc);
+ return rc;
}
- rc = of_property_read_u32(of_node, "qcom,qpnp-lab-nfet-size", &tmp);
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-lab-use-default-voltage"))
+ rc = labibb->lab_ver_ops->set_default_voltage(labibb, true);
+ else
+ rc = labibb->lab_ver_ops->set_default_voltage(labibb, false);
- if (rc) {
- pr_err("get qcom,qpnp-lab-nfet-size, rc = %d\n", rc);
+ if (rc < 0)
return rc;
- }
- for (i = 0; i < ARRAY_SIZE(lab_rdson_nfet_plan); i++)
- if (tmp == lab_rdson_nfet_plan[i])
- break;
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-lab-enable-sw-high-psrr")) {
+ val = LAB_EN_SW_HIGH_PSRR_MODE;
- if (i == ARRAY_SIZE(lab_rdson_nfet_plan)) {
- pr_err("Iniid property in qcom,qpnp-lab-nfet-size\n");
- return -EINVAL;
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_SW_HIGH_PSRR_CTL, &val, 1);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_SW_HIGH_PSRR_CTL, rc);
+ return rc;
+ }
}
- val |= i << LAB_RDSON_MNGMNT_NFET_SHIFT;
- val |= (LAB_RDSON_MNGMNT_NFET_SLEW_EN | LAB_RDSON_MNGMNT_PFET_SLEW_EN);
-
- rc = qpnp_labibb_write(labibb, labibb->lab_base + REG_LAB_RDSON_MNGMNT,
- &val, 1);
- if (rc) {
- pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
- REG_LAB_RDSON_MNGMNT, rc);
- return rc;
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-lab-ldo-pulldown-enable", (u32 *)&val);
+ if (!rc) {
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ REG_LAB_LDO_PD_CTL, &val, 1);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_LDO_PD_CTL, rc);
+ return rc;
+ }
}
- rc = of_property_read_u32(of_node, "qcom,qpnp-lab-init-voltage",
- &(labibb->lab_vreg.curr_volt));
- if (rc) {
- pr_err("get qcom,qpnp-lab-init-voltage failed, rc = %d\n", rc);
- return rc;
- }
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-lab-high-psrr-src-select", &tmp);
+ if (!rc) {
+ val = tmp;
- if (!of_property_read_bool(of_node,
- "qcom,qpnp-lab-use-default-voltage")) {
- if (labibb->lab_vreg.curr_volt < labibb->lab_vreg.min_volt) {
- pr_err("Invalid qcom,qpnp-lab-init-voltage property, qcom,qpnp-lab-init-voltage %d is less than the the minimum voltage %d",
- labibb->lab_vreg.curr_volt,
- labibb->lab_vreg.min_volt);
- return -EINVAL;
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-lab-vref-high-psrr-select", &tmp);
+ if (rc < 0) {
+ pr_err("get qcom,qpnp-lab-vref-high-psrr-select failed rc = %d\n",
+ rc);
+ return rc;
}
- val = DIV_ROUND_UP(labibb->lab_vreg.curr_volt -
- labibb->lab_vreg.min_volt,
- labibb->lab_vreg.step_size);
+ for (i = 0; i < ARRAY_SIZE(lab_vref_high_psrr_table); i++)
+ if (lab_vref_high_psrr_table[i] == tmp)
+ break;
- if (val > LAB_VOLTAGE_SET_MASK) {
- pr_err("Invalid qcom,qpnp-lab-init-voltage property, qcom,qpnp-lab-init-voltage %d is larger than the max supported voltage %d",
- labibb->lab_vreg.curr_volt,
- labibb->lab_vreg.min_volt +
- labibb->lab_vreg.step_size *
- LAB_VOLTAGE_SET_MASK);
+ if (i == ARRAY_SIZE(lab_vref_high_psrr_table)) {
+ pr_err("Invalid value in qpnp-lab-vref-high-psrr-selct\n");
return -EINVAL;
}
+ val |= (i << LAB_SEL_HW_HIGH_PSRR_SRC_SHIFT);
- labibb->lab_vreg.curr_volt = val * labibb->lab_vreg.step_size +
- labibb->lab_vreg.min_volt;
- val |= LAB_VOLTAGE_OVERRIDE_EN;
- } else {
- val = 0;
- }
-
- rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
- REG_LAB_VOLTAGE,
- LAB_VOLTAGE_SET_MASK |
- LAB_VOLTAGE_OVERRIDE_EN,
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_VPH_ENVELOP_CTL,
+ LAB_VREF_HIGH_PSRR_SEL_MASK |
+ LAB_SEL_HW_HIGH_PSRR_SRC_MASK,
val);
- if (rc) {
- pr_err("write to register %x failed rc = %d\n", REG_LAB_VOLTAGE,
- rc);
- return rc;
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_LAB_VPH_ENVELOP_CTL, rc);
+ return rc;
+ }
}
if (labibb->swire_control) {
rc = qpnp_ibb_set_mode(labibb, IBB_HW_CONTROL);
- if (rc)
+ if (rc < 0) {
pr_err("Unable to set SWIRE_RDY rc=%d\n", rc);
+ return rc;
+ }
}
- return rc;
+ return 0;
}
#define LAB_CURRENT_MAX_1600MA 0x7
@@ -1038,14 +1786,14 @@ static int qpnp_labibb_restore_settings(struct qpnp_labibb *labibb)
if (ibb_settings[i].sec_access)
rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
ibb_settings[i].address,
- &ibb_settings[i].value, 1);
+ ibb_settings[i].value);
else
rc = qpnp_labibb_write(labibb, labibb->ibb_base +
ibb_settings[i].address,
&ibb_settings[i].value, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
ibb_settings[i].address, rc);
return rc;
}
@@ -1055,14 +1803,14 @@ static int qpnp_labibb_restore_settings(struct qpnp_labibb *labibb)
if (lab_settings[i].sec_access)
rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
lab_settings[i].address,
- &lab_settings[i].value, 1);
+ lab_settings[i].value);
else
rc = qpnp_labibb_write(labibb, labibb->lab_base +
lab_settings[i].address,
&lab_settings[i].value, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
lab_settings[i].address, rc);
return rc;
}
@@ -1076,22 +1824,20 @@ static int qpnp_labibb_save_settings(struct qpnp_labibb *labibb)
int rc, i;
for (i = 0; i < ARRAY_SIZE(ibb_settings); i++) {
- rc = qpnp_labibb_read(labibb, &ibb_settings[i].value,
- labibb->ibb_base +
- ibb_settings[i].address, 1);
- if (rc) {
- pr_err("qpnp_labibb_read register %x failed rc = %d\n",
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ ibb_settings[i].address, &ibb_settings[i].value, 1);
+ if (rc < 0) {
+ pr_err("read register %x failed rc = %d\n",
ibb_settings[i].address, rc);
return rc;
}
}
for (i = 0; i < ARRAY_SIZE(lab_settings); i++) {
- rc = qpnp_labibb_read(labibb, &lab_settings[i].value,
- labibb->lab_base +
- lab_settings[i].address, 1);
- if (rc) {
- pr_err("qpnp_labibb_read register %x failed rc = %d\n",
+ rc = qpnp_labibb_read(labibb, labibb->lab_base +
+ lab_settings[i].address, &lab_settings[i].value, 1);
+ if (rc < 0) {
+ pr_err("read register %x failed rc = %d\n",
lab_settings[i].address, rc);
return rc;
}
@@ -1108,17 +1854,17 @@ static int qpnp_labibb_ttw_enter_ibb_common(struct qpnp_labibb *labibb)
val = 0;
rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_PD_CTL,
&val, 1);
- if (rc) {
- pr_err("qpnp_labibb_read register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("read register %x failed rc = %d\n",
REG_IBB_PD_CTL, rc);
return rc;
}
val = 0;
rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_IBB_PWRUP_PWRDN_CTL_1, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ REG_IBB_PWRUP_PWRDN_CTL_1, val);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_PWRUP_PWRDN_CTL_1, rc);
return rc;
}
@@ -1127,8 +1873,8 @@ static int qpnp_labibb_ttw_enter_ibb_common(struct qpnp_labibb *labibb)
rc = qpnp_labibb_sec_masked_write(labibb, labibb->ibb_base,
REG_IBB_PWRUP_PWRDN_CTL_2,
IBB_DIS_DLY_MASK | IBB_WAIT_MBG_OK, val);
- if (rc) {
- pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_PWRUP_PWRDN_CTL_2, rc);
return rc;
}
@@ -1137,8 +1883,8 @@ static int qpnp_labibb_ttw_enter_ibb_common(struct qpnp_labibb *labibb)
IBB_OVERRIDE_PFET_SW_SIZE;
rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
REG_IBB_RDSON_MNGMNT, 0xFF, val);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_RDSON_MNGMNT, rc);
return rc;
}
@@ -1146,9 +1892,9 @@ static int qpnp_labibb_ttw_enter_ibb_common(struct qpnp_labibb *labibb)
val = IBB_CURRENT_LIMIT_EN | IBB_CURRENT_MAX_500MA |
(IBB_ILIMIT_COUNT_CYC8 << IBB_CURRENT_LIMIT_DEBOUNCE_SHIFT);
rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_IBB_CURRENT_LIMIT, &val, 1);
- if (rc)
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ REG_IBB_CURRENT_LIMIT, val);
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_CURRENT_LIMIT, rc);
return rc;
@@ -1162,8 +1908,8 @@ static int qpnp_labibb_ttw_enter_ibb_pmi8996(struct qpnp_labibb *labibb)
val = IBB_BYPASS_PWRDN_DLY2_BIT | IBB_FAST_STARTUP;
rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_SPARE_CTL,
&val, 1);
- if (rc)
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_SPARE_CTL, rc);
return rc;
@@ -1175,7 +1921,7 @@ static int qpnp_labibb_ttw_enter_ibb_pmi8950(struct qpnp_labibb *labibb)
u8 val;
rc = qpnp_ibb_ps_config(labibb, true);
- if (rc) {
+ if (rc < 0) {
pr_err("Failed to enable ibb_ps_config rc=%d\n", rc);
return rc;
}
@@ -1183,8 +1929,8 @@ static int qpnp_labibb_ttw_enter_ibb_pmi8950(struct qpnp_labibb *labibb)
val = IBB_SOFT_START_CHARGING_RESISTOR_16K;
rc = qpnp_labibb_write(labibb, labibb->ibb_base +
REG_IBB_SOFT_START_CTL, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_SOFT_START_CTL, rc);
return rc;
}
@@ -1192,8 +1938,8 @@ static int qpnp_labibb_ttw_enter_ibb_pmi8950(struct qpnp_labibb *labibb)
val = IBB_MODULE_RDY_EN;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_IBB_MODULE_RDY, &val, 1);
- if (rc)
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0)
+ pr_err("write to register %x failed rc = %d\n",
REG_IBB_MODULE_RDY, rc);
return rc;
@@ -1218,8 +1964,8 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
val = LAB_MODULE_RDY_EN;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_MODULE_RDY, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_LAB_MODULE_RDY, rc);
return rc;
}
@@ -1228,8 +1974,8 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
val = LAB_ENABLE_CTL_EN;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_ENABLE_CTL, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_LAB_ENABLE_CTL, rc);
return rc;
}
@@ -1240,15 +1986,15 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
LAB_RDSON_PFET_SW_SIZE_QUARTER;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_RDSON_MNGMNT, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
REG_LAB_RDSON_MNGMNT, rc);
return rc;
}
rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
REG_LAB_PS_CTL, LAB_PS_CTL_EN, LAB_PS_CTL_EN);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_PS_CTL, rc);
return rc;
@@ -1257,7 +2003,7 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
val = LAB_PD_CTL_DISABLE_PD;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_PD_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_PD_CTL, rc);
return rc;
@@ -1268,7 +2014,7 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
val |= LAB_SPARE_TOUCH_WAKE_BIT;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_SPARE_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_SPARE_CTL, rc);
return rc;
@@ -1277,7 +2023,7 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
val = 0;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_SOFT_START_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_SOFT_START_CTL, rc);
return rc;
@@ -1298,13 +2044,13 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
rc = qpnp_labibb_ttw_enter_ibb_pmi8950(labibb);
break;
}
- if (rc) {
+ if (rc < 0) {
pr_err("Failed to configure TTW-enter for IBB rc=%d\n", rc);
return rc;
}
rc = qpnp_ibb_set_mode(labibb, IBB_HW_CONTROL);
- if (rc) {
+ if (rc < 0) {
pr_err("Unable to set SWIRE_RDY rc = %d\n", rc);
return rc;
}
@@ -1320,7 +2066,7 @@ static int qpnp_labibb_ttw_exit_ibb_common(struct qpnp_labibb *labibb)
val = IBB_FASTER_PFET_OFF;
rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_SPARE_CTL,
&val, 1);
- if (rc)
+ if (rc < 0)
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_IBB_SPARE_CTL, rc);
@@ -1339,7 +2085,7 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
/* Restore the IBB settings back to switch back to normal mode */
rc = qpnp_labibb_restore_settings(labibb);
- if (rc) {
+ if (rc < 0) {
pr_err("Error in restoring IBB setttings, rc=%d\n", rc);
return rc;
}
@@ -1348,7 +2094,7 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
val = 0;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_ENABLE_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_ENABLE_CTL, rc);
return rc;
@@ -1357,7 +2103,7 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
val = LAB_PD_CTL_STRONG_PULL;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_PD_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_PD_CTL, rc);
return rc;
@@ -1366,7 +2112,7 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
val = 0;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_SPARE_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_SPARE_CTL, rc);
return rc;
@@ -1380,7 +2126,7 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
rc = qpnp_labibb_ttw_exit_ibb_common(labibb);
break;
}
- if (rc) {
+ if (rc < 0) {
pr_err("Failed to configure TTW-exit for IBB rc=%d\n", rc);
return rc;
}
@@ -1418,9 +2164,9 @@ static int qpnp_labibb_regulator_enable(struct qpnp_labibb *labibb)
usleep_range(dly, dly + 100);
/* after this delay, lab should be enabled */
- rc = qpnp_labibb_read(labibb, &val,
- labibb->lab_base + REG_LAB_STATUS1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->lab_base + REG_LAB_STATUS1,
+ &val, 1);
+ if (rc < 0) {
pr_err("read register %x failed rc = %d\n",
REG_LAB_STATUS1, rc);
goto err_out;
@@ -1439,9 +2185,9 @@ static int qpnp_labibb_regulator_enable(struct qpnp_labibb *labibb)
dly = labibb->ibb_vreg.soft_start + labibb->ibb_vreg.pwrup_dly;
retries = 10;
while (retries--) {
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_STATUS1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_STATUS1, &val, 1);
+ if (rc < 0) {
pr_err("read register %x failed rc = %d\n",
REG_IBB_STATUS1, rc);
goto err_out;
@@ -1465,7 +2211,7 @@ static int qpnp_labibb_regulator_enable(struct qpnp_labibb *labibb)
return 0;
err_out:
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
- if (rc) {
+ if (rc < 0) {
pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
return rc;
}
@@ -1490,7 +2236,7 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb)
*/
if (labibb->ttw_en && !labibb->in_ttw_mode) {
rc = qpnp_labibb_regulator_ttw_mode_enter(labibb);
- if (rc) {
+ if (rc < 0) {
pr_err("Error in entering TTW mode rc = %d\n", rc);
return rc;
}
@@ -1500,7 +2246,7 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb)
}
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
- if (rc) {
+ if (rc < 0) {
pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
return rc;
}
@@ -1510,9 +2256,9 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb)
retries = 2;
while (retries--) {
usleep_range(dly, dly + 100);
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_STATUS1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_STATUS1, &val, 1);
+ if (rc < 0) {
pr_err("read register %x failed rc = %d\n",
REG_IBB_STATUS1, rc);
return rc;
@@ -1553,7 +2299,7 @@ static int qpnp_lab_regulator_enable(struct regulator_dev *rdev)
if (labibb->skip_2nd_swire_cmd) {
rc = qpnp_ibb_ps_config(labibb, false);
- if (rc) {
+ if (rc < 0) {
pr_err("Failed to disable IBB PS rc=%d\n", rc);
return rc;
}
@@ -1567,7 +2313,7 @@ static int qpnp_lab_regulator_enable(struct regulator_dev *rdev)
val = LAB_ENABLE_CTL_EN;
rc = qpnp_labibb_write(labibb,
labibb->lab_base + REG_LAB_ENABLE_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_lab_regulator_enable write register %x failed rc = %d\n",
REG_LAB_ENABLE_CTL, rc);
return rc;
@@ -1575,9 +2321,9 @@ static int qpnp_lab_regulator_enable(struct regulator_dev *rdev)
udelay(labibb->lab_vreg.soft_start);
- rc = qpnp_labibb_read(labibb, &val,
- labibb->lab_base + REG_LAB_STATUS1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->lab_base +
+ REG_LAB_STATUS1, &val, 1);
+ if (rc < 0) {
pr_err("qpnp_lab_regulator_enable read register %x failed rc = %d\n",
REG_LAB_STATUS1, rc);
return rc;
@@ -1608,7 +2354,7 @@ static int qpnp_lab_regulator_disable(struct regulator_dev *rdev)
val = 0;
rc = qpnp_labibb_write(labibb,
labibb->lab_base + REG_LAB_ENABLE_CTL, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_lab_regulator_enable write register %x failed rc = %d\n",
REG_LAB_ENABLE_CTL, rc);
return rc;
@@ -1661,7 +2407,7 @@ static int qpnp_lab_regulator_set_voltage(struct regulator_dev *rdev,
LAB_VOLTAGE_OVERRIDE_EN,
val | LAB_VOLTAGE_OVERRIDE_EN);
- if (rc) {
+ if (rc < 0) {
pr_err("write to register %x failed rc = %d\n", REG_LAB_VOLTAGE,
rc);
return rc;
@@ -1684,9 +2430,9 @@ static int qpnp_skip_swire_command(struct qpnp_labibb *labibb)
do {
/* poll for ibb vreg_ok */
- rc = qpnp_labibb_read(labibb, &reg,
- labibb->ibb_base + REG_IBB_STATUS1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_STATUS1, &reg, 1);
+ if (rc < 0) {
pr_err("Failed to read ibb_status1 reg rc=%d\n", rc);
return rc;
}
@@ -1705,7 +2451,7 @@ static int qpnp_skip_swire_command(struct qpnp_labibb *labibb)
/* move to SW control */
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_EN);
- if (rc) {
+ if (rc < 0) {
pr_err("Failed switch to IBB_SW_CONTROL rc=%d\n", rc);
return rc;
}
@@ -1720,7 +2466,7 @@ static int qpnp_skip_swire_command(struct qpnp_labibb *labibb)
usleep_range(dly, dly + 10);
rc = qpnp_ibb_set_mode(labibb, IBB_HW_SW_CONTROL);
- if (rc) {
+ if (rc < 0) {
pr_err("Failed switch to IBB_HW_SW_CONTROL rc=%d\n", rc);
return rc;
}
@@ -1730,13 +2476,13 @@ static int qpnp_skip_swire_command(struct qpnp_labibb *labibb)
/* Move back to SWIRE control */
rc = qpnp_ibb_set_mode(labibb, IBB_HW_CONTROL);
- if (rc)
+ if (rc < 0)
pr_err("Failed switch to IBB_HW_CONTROL rc=%d\n", rc);
/* delay before enabling the PS mode */
msleep(labibb->swire_ibb_ps_enable_delay);
rc = qpnp_ibb_ps_config(labibb, true);
- if (rc)
+ if (rc < 0)
pr_err("Unable to enable IBB PS rc=%d\n", rc);
return rc;
@@ -1804,7 +2550,7 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
struct regulator_init_data *init_data;
struct regulator_desc *rdesc = &labibb->lab_vreg.rdesc;
struct regulator_config cfg = {};
- u8 val;
+ u8 val, mask;
const char *current_sense_str;
bool config_current_sense = false;
u32 tmp;
@@ -1845,54 +2591,53 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
rc = of_property_read_u32(of_node, "qcom,qpnp-lab-soft-start",
&(labibb->lab_vreg.soft_start));
- if (rc < 0) {
- pr_err("qcom,qpnp-lab-soft-start is missing, rc = %d\n",
- rc);
- return rc;
- }
-
- for (val = 0; val < ARRAY_SIZE(lab_soft_start_plan); val++)
- if (lab_soft_start_plan[val] == labibb->lab_vreg.soft_start)
- break;
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(lab_soft_start_table); val++)
+ if (lab_soft_start_table[val] ==
+ labibb->lab_vreg.soft_start)
+ break;
- if (val == ARRAY_SIZE(lab_soft_start_plan))
- val = ARRAY_SIZE(lab_soft_start_plan) - 1;
+ if (val == ARRAY_SIZE(lab_soft_start_table))
+ val = ARRAY_SIZE(lab_soft_start_table) - 1;
- rc = qpnp_labibb_write(labibb, labibb->lab_base +
+ rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_SOFT_START_CTL, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
- REG_LAB_SOFT_START_CTL, rc);
- return rc;
- }
+ if (rc < 0) {
+ pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ REG_LAB_SOFT_START_CTL, rc);
+ return rc;
+ }
- labibb->lab_vreg.soft_start = lab_soft_start_plan
+ labibb->lab_vreg.soft_start = lab_soft_start_table
[val & LAB_SOFT_START_CTL_MASK];
-
- rc = of_property_read_u32(of_node, "qcom,qpnp-lab-max-precharge-time",
- &tmp);
- if (rc) {
- pr_err("get qcom,qpnp-lab-max-precharge-time failed, rc = %d\n",
- rc);
- return rc;
}
- for (val = 0; val < ARRAY_SIZE(lab_max_precharge_plan); val++)
- if (lab_max_precharge_plan[val] == tmp)
- break;
+ val = 0;
+ mask = 0;
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-lab-max-precharge-time", &tmp);
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(lab_max_precharge_table); val++)
+ if (lab_max_precharge_table[val] == tmp)
+ break;
- if (val == ARRAY_SIZE(lab_max_precharge_plan)) {
- pr_err("Invalid property in qcom,qpnp-lab-max-precharge-time\n");
- return -EINVAL;
+ if (val == ARRAY_SIZE(lab_max_precharge_table)) {
+ pr_err("Invalid value in qcom,qpnp-lab-max-precharge-time\n");
+ return -EINVAL;
+ }
+
+ mask = LAB_MAX_PRECHARGE_TIME_MASK;
}
if (of_property_read_bool(of_node,
- "qcom,qpnp-lab-max-precharge-enable"))
- val |= LAB_PRECHARGE_CTL_EN;
+ "qcom,qpnp-lab-max-precharge-enable")) {
+ val |= LAB_FAST_PRECHARGE_CTL_EN;
+ mask |= LAB_FAST_PRECHARGE_CTL_EN;
+ }
- rc = qpnp_labibb_write(labibb, labibb->lab_base +
- REG_LAB_PRECHARGE_CTL, &val, 1);
- if (rc) {
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_PRECHARGE_CTL, mask, val);
+ if (rc < 0) {
pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
REG_LAB_PRECHARGE_CTL, rc);
return rc;
@@ -1930,7 +2675,7 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
REG_LAB_CURRENT_SENSE,
LAB_CURRENT_SENSE_GAIN_MASK,
val);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_CURRENT_SENSE, rc);
return rc;
@@ -1939,17 +2684,17 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
val = (labibb->standalone) ? 0 : LAB_IBB_EN_RDY_EN;
rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
- REG_LAB_IBB_EN_RDY, &val, 1);
+ REG_LAB_IBB_EN_RDY, val);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
REG_LAB_IBB_EN_RDY, rc);
return rc;
}
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_ENABLE_CTL, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base + REG_IBB_ENABLE_CTL,
+ &val, 1);
+ if (rc < 0) {
pr_err("qpnp_labibb_read register %x failed rc = %d\n",
REG_IBB_ENABLE_CTL, rc);
return rc;
@@ -1958,53 +2703,41 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
if (!(val & (IBB_ENABLE_CTL_SWIRE_RDY | IBB_ENABLE_CTL_MODULE_EN))) {
/* SWIRE_RDY and IBB_MODULE_EN not enabled */
rc = qpnp_lab_dt_init(labibb, of_node);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp-lab: wrong DT parameter specified: rc = %d\n",
rc);
return rc;
}
} else {
- rc = qpnp_labibb_read(labibb, &val,
- labibb->lab_base + REG_LAB_LCD_AMOLED_SEL, 1);
- if (rc) {
- pr_err("qpnp_labibb_read register %x failed rc = %d\n",
- REG_LAB_LCD_AMOLED_SEL, rc);
- return rc;
- }
-
- if (val == REG_LAB_IBB_AMOLED_MODE)
- labibb->mode = QPNP_LABIBB_AMOLED_MODE;
- else
- labibb->mode = QPNP_LABIBB_LCD_MODE;
+ rc = labibb->ibb_ver_ops->get_mode(labibb);
- rc = qpnp_labibb_read(labibb, &val, labibb->lab_base +
- REG_LAB_VOLTAGE, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->lab_base +
+ REG_LAB_VOLTAGE, &val, 1);
+ if (rc < 0) {
pr_err("qpnp_lab_read read register %x failed rc = %d\n",
REG_LAB_VOLTAGE, rc);
return rc;
}
- if (val & LAB_VOLTAGE_OVERRIDE_EN) {
- labibb->lab_vreg.curr_volt =
+ labibb->lab_vreg.curr_volt =
(val &
LAB_VOLTAGE_SET_MASK) *
labibb->lab_vreg.step_size +
labibb->lab_vreg.min_volt;
- } else if (labibb->mode == QPNP_LABIBB_LCD_MODE) {
+ if (labibb->mode == QPNP_LABIBB_LCD_MODE) {
rc = of_property_read_u32(of_node,
"qcom,qpnp-lab-init-lcd-voltage",
&(labibb->lab_vreg.curr_volt));
- if (rc) {
+ if (rc < 0) {
pr_err("get qcom,qpnp-lab-init-lcd-voltage failed, rc = %d\n",
rc);
return rc;
}
- } else {
+ } else if (!(val & LAB_VOLTAGE_OVERRIDE_EN)) {
rc = of_property_read_u32(of_node,
"qcom,qpnp-lab-init-amoled-voltage",
&(labibb->lab_vreg.curr_volt));
- if (rc) {
+ if (rc < 0) {
pr_err("get qcom,qpnp-lab-init-amoled-voltage failed, rc = %d\n",
rc);
return rc;
@@ -2027,9 +2760,9 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
}
}
- rc = qpnp_labibb_read(labibb, &val,
- labibb->lab_base + REG_LAB_MODULE_RDY, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->lab_base + REG_LAB_MODULE_RDY,
+ &val, 1);
+ if (rc < 0) {
pr_err("qpnp_lab_read read register %x failed rc = %d\n",
REG_LAB_MODULE_RDY, rc);
return rc;
@@ -2041,7 +2774,7 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_MODULE_RDY, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
REG_LAB_MODULE_RDY, rc);
return rc;
@@ -2084,12 +2817,161 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
return 0;
}
+static int qpnp_ibb_pfm_mode_enable(struct qpnp_labibb *labibb,
+ struct device_node *of_node)
+{
+ int rc = 0;
+ u32 i, tmp = 0;
+ u8 val = IBB_PFM_ENABLE;
+
+ rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-pfm-peak-curr",
+ &tmp);
+ if (rc < 0) {
+ pr_err("qcom,qpnp-ibb-pfm-peak-curr is missing, rc = %d\n",
+ rc);
+ return rc;
+ }
+ for (i = 0; i < ARRAY_SIZE(ibb_pfm_peak_curr_table); i++)
+ if (ibb_pfm_peak_curr_table[i] == tmp)
+ break;
+
+ if (i == ARRAY_SIZE(ibb_pfm_peak_curr_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-pfm-peak-curr\n");
+ return -EINVAL;
+ }
+
+ val |= (i << IBB_PFM_PEAK_CURRENT_BIT_SHIFT);
+
+ rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-pfm-hysteresis",
+ &tmp);
+ if (rc < 0) {
+ pr_err("qcom,qpnp-ibb-pfm-hysteresis is missing, rc = %d\n",
+ rc);
+ return rc;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ibb_pfm_hysteresis_table); i++)
+ if (ibb_pfm_hysteresis_table[i] == tmp)
+ break;
+
+ if (i == ARRAY_SIZE(ibb_pfm_hysteresis_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-pfm-hysteresis\n");
+ return -EINVAL;
+ }
+
+ val |= (i << IBB_PFM_HYSTERESIS_BIT_SHIFT);
+
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base +
+ REG_IBB_PFM_CTL, &val, 1);
+ if (rc < 0)
+ pr_err("qpnp_ibb_pfm_ctl write register %x failed rc = %d\n",
+ REG_IBB_PFM_CTL, rc);
+
+ return rc;
+}
+
+static int qpnp_labibb_pbs_mode_enable(struct qpnp_labibb *labibb,
+ struct device_node *of_node)
+{
+ int rc = 0;
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_SWIRE_CTL,
+ IBB_SWIRE_VOUT_UPD_EN, 0);
+ if (rc < 0) {
+ pr_err("qpnp_ibb_swire_ctl write register %x failed rc = %d\n",
+ REG_IBB_SWIRE_CTL, rc);
+ return rc;
+ }
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_PD_CTL, IBB_SWIRE_PD_UPD, 0);
+ if (rc < 0) {
+ pr_err("qpnp_ibb_pd_ctl write register %x failed rc = %d\n",
+ REG_IBB_PD_CTL, rc);
+ return rc;
+ }
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_SWIRE_PGM_CTL, LAB_EN_SWIRE_PGM_VOUT |
+ LAB_EN_SWIRE_PGM_PD, 0);
+ if (rc < 0)
+ pr_err("qpnp_lab_swire_pgm_ctl write register %x failed rc = %d\n",
+ REG_LAB_SWIRE_PGM_CTL, rc);
+
+ return rc;
+}
+
+static int qpnp_ibb_slew_rate_config(struct qpnp_labibb *labibb,
+ struct device_node *of_node)
+{
+ int rc = 0;
+ u32 i, tmp = 0;
+ u8 val = 0, mask = 0;
+
+ rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-fast-slew-rate",
+ &tmp);
+ if (!rc) {
+ for (i = 0; i < ARRAY_SIZE(ibb_output_slew_ctl_table); i++)
+ if (ibb_output_slew_ctl_table[i] == tmp)
+ break;
+
+ if (i == ARRAY_SIZE(ibb_output_slew_ctl_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-fast-slew-rate\n");
+ return -EINVAL;
+ }
+
+ labibb->ibb_vreg.slew_rate = tmp;
+ val |= (i << IBB_SLEW_RATE_TRANS_TIME_FAST_SHIFT) |
+ IBB_SLEW_RATE_SPEED_FAST_EN | IBB_SLEW_CTL_EN;
+
+ mask = IBB_SLEW_RATE_SPEED_FAST_EN |
+ IBB_SLEW_RATE_TRANS_TIME_FAST_MASK | IBB_SLEW_CTL_EN;
+ }
+
+ rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-slow-slew-rate",
+ &tmp);
+ if (!rc) {
+ for (i = 0; i < ARRAY_SIZE(ibb_output_slew_ctl_table); i++)
+ if (ibb_output_slew_ctl_table[i] == tmp)
+ break;
+
+ if (i == ARRAY_SIZE(ibb_output_slew_ctl_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-slow-slew-rate\n");
+ return -EINVAL;
+ }
+
+ labibb->ibb_vreg.slew_rate = tmp;
+ val |= (i | IBB_SLEW_CTL_EN);
+
+ mask |= IBB_SLEW_RATE_SPEED_FAST_EN |
+ IBB_SLEW_RATE_TRANS_TIME_SLOW_MASK | IBB_SLEW_CTL_EN;
+ }
+
+ rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
+ REG_IBB_OUTPUT_SLEW_CTL,
+ mask, val);
+ if (rc < 0)
+ pr_err("qpnp_labibb_write register %x failed rc = %d\n",
+ REG_IBB_OUTPUT_SLEW_CTL, rc);
+
+ return rc;
+}
+
+static bool qpnp_ibb_poff_ctl_required(struct qpnp_labibb *labibb)
+{
+ if (labibb->pmic_rev_id->pmic_subtype == PM660L_SUBTYPE)
+ return false;
+
+ return true;
+}
+
static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb,
struct device_node *of_node)
{
int rc = 0;
- u32 i, tmp;
- u8 val;
+ u32 i, tmp = 0;
+ u8 val, mask;
/*
* Do not configure LCD_AMOLED_SEL for pmi8998 as it will be done by
@@ -2097,180 +2979,166 @@ static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb,
* by the bootloader.
*/
if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) {
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_LCD_AMOLED_SEL, 1);
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_LCD_AMOLED_SEL, &val, 1);
if (rc) {
pr_err("qpnp_labibb_read register %x failed rc = %d\n",
- REG_IBB_LCD_AMOLED_SEL, rc);
+ REG_IBB_LCD_AMOLED_SEL, rc);
return rc;
}
-
if (val == REG_LAB_IBB_AMOLED_MODE)
labibb->mode = QPNP_LABIBB_AMOLED_MODE;
else
labibb->mode = QPNP_LABIBB_LCD_MODE;
} else {
- if (labibb->mode == QPNP_LABIBB_LCD_MODE)
- val = REG_LAB_IBB_LCD_MODE;
- else
- val = REG_LAB_IBB_AMOLED_MODE;
-
- rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_LAB_LCD_AMOLED_SEL, &val, 1);
- if (rc) {
+ rc = labibb->ibb_ver_ops->sel_mode(labibb, 1);
+ if (rc < 0) {
pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
REG_IBB_LCD_AMOLED_SEL, rc);
return rc;
}
}
- rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-lab-pwrdn-delay",
- &tmp);
- if (rc < 0) {
- pr_err("qcom,qpnp-ibb-lab-pwrdn-delay is missing, rc = %d\n",
- rc);
- return rc;
- }
-
val = 0;
+ mask = 0;
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-ibb-lab-pwrdn-delay", &tmp);
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(ibb_pwrdn_dly_table); val++)
+ if (ibb_pwrdn_dly_table[val] == tmp)
+ break;
- for (val = 0; val < ARRAY_SIZE(ibb_pwrdn_dly_plan); val++)
- if (ibb_pwrdn_dly_plan[val] == tmp)
- break;
+ if (val == ARRAY_SIZE(ibb_pwrdn_dly_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-lab-pwrdn-delay\n");
+ return -EINVAL;
+ }
- if (val == ARRAY_SIZE(ibb_pwrdn_dly_plan)) {
- pr_err("Invalid property in qcom,qpnp-ibb-lab-pwrdn-delay\n");
- return -EINVAL;
+ labibb->ibb_vreg.pwrdn_dly = tmp;
+ val |= IBB_PWRUP_PWRDN_CTL_1_EN_DLY2;
+ mask |= IBB_PWRUP_PWRDN_CTL_1_EN_DLY2;
}
- labibb->ibb_vreg.pwrdn_dly = tmp;
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-ibb-lab-pwrup-delay", &tmp);
+ if (!rc) {
+ for (i = 0; i < ARRAY_SIZE(ibb_pwrup_dly_table); i++)
+ if (ibb_pwrup_dly_table[i] == tmp)
+ break;
- rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-lab-pwrup-delay",
- &tmp);
- if (rc < 0) {
- pr_err("qcom,qpnp-ibb-lab-pwrup-delay is missing, rc = %d\n",
- rc);
- return rc;
- }
+ if (i == ARRAY_SIZE(ibb_pwrup_dly_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-lab-pwrup-delay\n");
+ return -EINVAL;
+ }
- for (i = 0; i < ARRAY_SIZE(ibb_pwrup_dly_plan); i++)
- if (ibb_pwrup_dly_plan[i] == tmp)
- break;
+ labibb->ibb_vreg.pwrup_dly = tmp;
- if (i == ARRAY_SIZE(ibb_pwrup_dly_plan)) {
- pr_err("Invalid property in qcom,qpnp-ibb-lab-pwrup-delay\n");
- return -EINVAL;
+ val |= (i << IBB_PWRUP_PWRDN_CTL_1_DLY1_SHIFT);
+ val |= (IBB_PWRUP_PWRDN_CTL_1_EN_DLY1 |
+ IBB_PWRUP_PWRDN_CTL_1_LAB_VREG_OK);
+ mask |= (IBB_PWRUP_PWRDN_CTL_1_EN_DLY1 |
+ IBB_PWRUP_PWRDN_CTL_1_DLY1_MASK |
+ IBB_PWRUP_PWRDN_CTL_1_LAB_VREG_OK);
}
- labibb->ibb_vreg.pwrup_dly = tmp;
-
- val |= (i << IBB_PWRUP_PWRDN_CTL_1_DLY1_SHIFT);
-
- if (of_property_read_bool(of_node, "qcom,qpnp-ibb-en-discharge"))
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-ibb-en-discharge")) {
val |= PWRUP_PWRDN_CTL_1_DISCHARGE_EN;
+ mask |= PWRUP_PWRDN_CTL_1_DISCHARGE_EN;
+ }
- val |= (IBB_PWRUP_PWRDN_CTL_1_EN_DLY1 |
- IBB_PWRUP_PWRDN_CTL_1_LAB_VREG_OK);
-
- rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_IBB_PWRUP_PWRDN_CTL_1,
- &val,
- 1);
- if (rc) {
+ rc = qpnp_labibb_sec_masked_write(labibb, labibb->ibb_base,
+ REG_IBB_PWRUP_PWRDN_CTL_1, mask, val);
+ if (rc < 0) {
pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
REG_IBB_PWRUP_PWRDN_CTL_1, rc);
return rc;
}
- val = 0;
+ if (of_property_read_bool(of_node, "qcom,qpnp-ibb-slew-rate-config")) {
+ rc = qpnp_ibb_slew_rate_config(labibb, of_node);
+ if (rc < 0)
+ return rc;
+ }
+
+ val = 0;
if (!of_property_read_bool(of_node, "qcom,qpnp-ibb-full-pull-down"))
- val |= IBB_PD_CTL_HALF_STRENGTH;
+ val = IBB_PD_CTL_HALF_STRENGTH;
if (of_property_read_bool(of_node, "qcom,qpnp-ibb-pull-down-enable"))
val |= IBB_PD_CTL_EN;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_PD_CTL,
- &val, 1);
+ mask = IBB_PD_CTL_STRENGTH_MASK | IBB_PD_CTL_EN;
+ rc = qpnp_labibb_masked_write(labibb,
+ labibb->ibb_base + REG_IBB_PD_CTL, mask, val);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_lab_dt_init write register %x failed rc = %d\n",
REG_IBB_PD_CTL, rc);
return rc;
}
rc = of_property_read_u32(of_node,
- "qcom,qpnp-ibb-switching-clock-frequency", &tmp);
- if (rc) {
- pr_err("get qcom,qpnp-ibb-switching-clock-frequency failed rc = %d\n",
- rc);
- return rc;
- }
-
- for (val = 0; val < ARRAY_SIZE(ibb_clk_div_plan); val++)
- if (ibb_clk_div_plan[val] == tmp)
- break;
-
- if (val == ARRAY_SIZE(ibb_clk_div_plan)) {
- pr_err("Invalid property in qpnp-ibb-switching-clock-frequency\n");
- return -EINVAL;
- }
+ "qcom,qpnp-ibb-switching-clock-frequency", &tmp);
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(ibb_clk_div_table); val++)
+ if (ibb_clk_div_table[val] == tmp)
+ break;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_CLK_DIV,
- &val, 1);
- if (rc) {
- pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
- REG_IBB_CLK_DIV, rc);
- return rc;
+ if (val == ARRAY_SIZE(ibb_clk_div_table)) {
+ pr_err("Invalid value in qpnp-ibb-switching-clock-frequency\n");
+ return -EINVAL;
+ }
+ rc = labibb->ibb_ver_ops->set_clk_div(labibb, val);
+ if (rc < 0) {
+ pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
+ REG_IBB_CLK_DIV, rc);
+ return rc;
+ }
}
+ val = 0;
+ mask = 0;
rc = of_property_read_u32(of_node,
"qcom,qpnp-ibb-limit-maximum-current", &tmp);
+ if (!rc) {
+ for (val = 0; val < ARRAY_SIZE(ibb_current_limit_table); val++)
+ if (ibb_current_limit_table[val] == tmp)
+ break;
- if (rc) {
- pr_err("get qcom,qpnp-ibb-limit-maximum-current failed rc = %d\n",
- rc);
- return rc;
- }
-
- for (val = 0; val < ARRAY_SIZE(ibb_current_limit_plan); val++)
- if (ibb_current_limit_plan[val] == tmp)
- break;
+ if (val == ARRAY_SIZE(ibb_current_limit_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-limit-maximum-current\n");
+ return -EINVAL;
+ }
- if (val == ARRAY_SIZE(ibb_current_limit_plan)) {
- pr_err("Invalid property in qcom,qpnp-ibb-limit-maximum-current\n");
- return -EINVAL;
+ mask = IBB_CURRENT_LIMIT_MASK;
}
- rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-debounce-cycle",
- &tmp);
-
- if (rc) {
- pr_err("get qcom,qpnp-ibb-debounce-cycle failed rc = %d\n",
- rc);
- return rc;
- }
+ rc = of_property_read_u32(of_node,
+ "qcom,qpnp-ibb-debounce-cycle", &tmp);
+ if (!rc) {
+ for (i = 0; i < ARRAY_SIZE(ibb_debounce_table); i++)
+ if (ibb_debounce_table[i] == tmp)
+ break;
- for (i = 0; i < ARRAY_SIZE(ibb_debounce_plan); i++)
- if (ibb_debounce_plan[i] == tmp)
- break;
+ if (i == ARRAY_SIZE(ibb_debounce_table)) {
+ pr_err("Invalid value in qcom,qpnp-ibb-debounce-cycle\n");
+ return -EINVAL;
+ }
- if (i == ARRAY_SIZE(ibb_debounce_plan)) {
- pr_err("Invalid property in qcom,qpnp-ibb-debounce-cycle\n");
- return -EINVAL;
+ val |= (i << IBB_CURRENT_LIMIT_DEBOUNCE_SHIFT);
+ mask |= IBB_CURRENT_LIMIT_DEBOUNCE_MASK;
}
- val |= (i << IBB_CURRENT_LIMIT_DEBOUNCE_SHIFT);
-
if (of_property_read_bool(of_node,
- "qcom,qpnp-ibb-limit-max-current-enable"))
+ "qcom,qpnp-ibb-limit-max-current-enable")) {
val |= IBB_CURRENT_LIMIT_EN;
+ mask |= IBB_CURRENT_LIMIT_EN;
+ }
- rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_IBB_CURRENT_LIMIT,
- &val,
- 1);
- if (rc) {
+ rc = qpnp_labibb_sec_masked_write(labibb, labibb->ibb_base,
+ REG_IBB_CURRENT_LIMIT, mask, val);
+ if (rc < 0) {
pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
REG_IBB_CURRENT_LIMIT, rc);
return rc;
@@ -2283,7 +3151,7 @@ static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb,
REG_IBB_RING_SUPPRESSION_CTL,
&val,
1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
REG_IBB_RING_SUPPRESSION_CTL, rc);
return rc;
@@ -2292,67 +3160,60 @@ static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb,
if (of_property_read_bool(of_node, "qcom,qpnp-ibb-ps-enable")) {
rc = qpnp_ibb_ps_config(labibb, true);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_ibb_dt_init PS enable failed rc=%d\n", rc);
return rc;
}
} else {
rc = qpnp_ibb_ps_config(labibb, false);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_ibb_dt_init PS disable failed rc=%d\n",
rc);
return rc;
}
}
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-ibb-smart-ps-enable")){
+ of_property_read_u32(of_node, "qcom,qpnp-ibb-num-swire-trans",
+ &labibb->ibb_vreg.num_swire_trans);
+
+ of_property_read_u32(of_node,
+ "qcom,qpnp-ibb-neg-curr-limit", &tmp);
+
+ rc = labibb->ibb_ver_ops->smart_ps_config(labibb, true,
+ labibb->ibb_vreg.num_swire_trans, tmp);
+ if (rc < 0) {
+ pr_err("qpnp_ibb_dt_init smart PS enable failed rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ }
+
rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-init-voltage",
&(labibb->ibb_vreg.curr_volt));
- if (rc) {
+ if (rc < 0) {
pr_err("get qcom,qpnp-ibb-init-voltage failed, rc = %d\n", rc);
return rc;
}
- if (!of_property_read_bool(of_node,
- "qcom,qpnp-ibb-use-default-voltage")) {
- if (labibb->ibb_vreg.curr_volt < labibb->ibb_vreg.min_volt) {
- pr_err("Invalid qcom,qpnp-ibb-init-voltage property, qcom,qpnp-ibb-init-voltage %d is less than the the minimum voltage %d",
- labibb->ibb_vreg.curr_volt,
- labibb->ibb_vreg.min_volt);
- return -EINVAL;
- }
-
- val = DIV_ROUND_UP(labibb->ibb_vreg.curr_volt -
- labibb->ibb_vreg.min_volt,
- labibb->ibb_vreg.step_size);
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-ibb-use-default-voltage"))
+ rc = labibb->ibb_ver_ops->set_default_voltage(labibb, true);
+ else
+ rc = labibb->ibb_ver_ops->set_default_voltage(labibb, false);
- if (val > IBB_VOLTAGE_SET_MASK) {
- pr_err("Invalid qcom,qpnp-ibb-init-voltage property, qcom,qpnp-lab-init-voltage %d is larger than the max supported voltage %d",
- labibb->ibb_vreg.curr_volt,
- labibb->ibb_vreg.min_volt +
- labibb->ibb_vreg.step_size *
- IBB_VOLTAGE_SET_MASK);
- return -EINVAL;
- }
+ if (rc < 0)
+ return rc;
- labibb->ibb_vreg.curr_volt = val * labibb->ibb_vreg.step_size +
- labibb->ibb_vreg.min_volt;
- val |= IBB_VOLTAGE_OVERRIDE_EN;
- } else {
- val = 0;
+ if (of_property_read_bool(of_node, "qcom,qpnp-ibb-overload-blank")) {
+ rc = qpnp_ibb_vreg_ok_ctl(labibb, of_node);
+ if (rc < 0)
+ return rc;
}
- rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
- REG_IBB_VOLTAGE,
- IBB_VOLTAGE_SET_MASK |
- IBB_VOLTAGE_OVERRIDE_EN,
- val);
-
- if (rc)
- pr_err("qpnp_ibb_masked_write write register %x failed rc = %d\n",
- REG_IBB_VOLTAGE, rc);
-
-
- return rc;
+ return 0;
}
static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev)
@@ -2367,7 +3228,7 @@ static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev)
return qpnp_labibb_regulator_enable(labibb);
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_EN);
- if (rc) {
+ if (rc < 0) {
pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
return rc;
}
@@ -2377,9 +3238,9 @@ static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev)
/* Wait for a small period before reading IBB_STATUS1 */
usleep_range(delay, delay + 100);
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_STATUS1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_STATUS1, &val, 1);
+ if (rc < 0) {
pr_err("qpnp_ibb_regulator_enable read register %x failed rc = %d\n",
REG_IBB_STATUS1, rc);
return rc;
@@ -2410,7 +3271,7 @@ static int qpnp_ibb_regulator_disable(struct regulator_dev *rdev)
return qpnp_labibb_regulator_disable(labibb);
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
- if (rc) {
+ if (rc < 0) {
pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
return rc;
}
@@ -2433,51 +3294,18 @@ static int qpnp_ibb_regulator_is_enabled(struct regulator_dev *rdev)
static int qpnp_ibb_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
- int rc, new_uV;
- u8 val;
+ int rc = 0;
+
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
if (labibb->swire_control)
return 0;
- if (min_uV < labibb->ibb_vreg.min_volt) {
- pr_err("min_uV %d is less than min_volt %d", min_uV,
- labibb->ibb_vreg.min_volt);
- return -EINVAL;
- }
-
- val = DIV_ROUND_UP(min_uV - labibb->ibb_vreg.min_volt,
- labibb->ibb_vreg.step_size);
- new_uV = val * labibb->ibb_vreg.step_size + labibb->ibb_vreg.min_volt;
-
- if (new_uV > max_uV) {
- pr_err("unable to set voltage %d (min:%d max:%d)\n", new_uV,
- min_uV, max_uV);
- return -EINVAL;
- }
-
- rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
- REG_IBB_VOLTAGE,
- IBB_VOLTAGE_SET_MASK |
- IBB_VOLTAGE_OVERRIDE_EN,
- val | IBB_VOLTAGE_OVERRIDE_EN);
-
- if (rc) {
- pr_err("write to register %x failed rc = %d\n", REG_IBB_VOLTAGE,
- rc);
- return rc;
- }
-
- if (new_uV > labibb->ibb_vreg.curr_volt) {
- val = DIV_ROUND_UP(new_uV - labibb->ibb_vreg.curr_volt,
- labibb->ibb_vreg.step_size);
- udelay(val * labibb->ibb_vreg.slew_rate);
- }
- labibb->ibb_vreg.curr_volt = new_uV;
-
- return 0;
+ rc = labibb->ibb_ver_ops->set_voltage(labibb, min_uV, max_uV);
+ return rc;
}
+
static int qpnp_ibb_regulator_get_voltage(struct regulator_dev *rdev)
{
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
@@ -2534,50 +3362,11 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-slew-rate",
&(labibb->ibb_vreg.slew_rate));
- if (rc < 0) {
- pr_err("qcom,qpnp-ibb-slew-rate is missing, rc = %d\n",
- rc);
- return rc;
- }
+ if (rc < 0)
+ labibb->ibb_vreg.slew_rate = IBB_HW_DEFAULT_SLEW_RATE;
- rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-soft-start",
- &(labibb->ibb_vreg.soft_start));
+ rc = labibb->ibb_ver_ops->soft_start_ctl(labibb, of_node);
if (rc < 0) {
- pr_err("qcom,qpnp-ibb-soft-start is missing, rc = %d\n",
- rc);
- return rc;
- }
-
- rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-discharge-resistor",
- &tmp);
-
- if (rc < 0) {
- pr_err("qcom,qpnp-ibb-discharge-resistor is missing, rc = %d\n",
- rc);
- return rc;
- }
-
- if (labibb->mode == QPNP_LABIBB_AMOLED_MODE) {
- /*
- * AMOLED mode needs ibb discharge resistor to be
- * configured for 300KOhm
- */
- if (tmp < ibb_discharge_resistor_plan[0])
- tmp = ibb_discharge_resistor_plan[0];
- }
-
- for (val = 0; val < ARRAY_SIZE(ibb_discharge_resistor_plan); val++)
- if (ibb_discharge_resistor_plan[val] == tmp)
- break;
-
- if (val == ARRAY_SIZE(ibb_discharge_resistor_plan)) {
- pr_err("Invalid property in qcom,qpnp-ibb-discharge-resistor\n");
- return -EINVAL;
- }
-
- rc = qpnp_labibb_write(labibb, labibb->ibb_base +
- REG_IBB_SOFT_START_CTL, &val, 1);
- if (rc) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_IBB_SOFT_START_CTL, rc);
return rc;
@@ -2585,42 +3374,29 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
if (of_find_property(of_node, "qcom,output-voltage-one-pulse", NULL)) {
if (!labibb->swire_control) {
- pr_err("Invalid property 'qcom,output-voltage-one-pulse', valid only in SWIRE config\n");
+ pr_err("output-voltage-one-pulse valid for SWIRE only\n");
return -EINVAL;
}
rc = of_property_read_u32(of_node,
"qcom,output-voltage-one-pulse", &tmp);
- if (rc) {
+ if (rc < 0) {
pr_err("failed to read qcom,output-voltage-one-pulse rc=%d\n",
rc);
return rc;
}
if (tmp > MAX_OUTPUT_PULSE_VOLTAGE_MV ||
- tmp < MIN_OUTPUT_PULSE_VOLTAGE_MV) {
+ tmp < MIN_OUTPUT_PULSE_VOLTAGE_MV) {
pr_err("Invalid one-pulse voltage range %d\n", tmp);
return -EINVAL;
}
-
- /*
- * Set the output voltage 100mV lower as the IBB HW module
- * counts one pulse less in SWIRE mode.
- */
- val = DIV_ROUND_UP((tmp - MIN_OUTPUT_PULSE_VOLTAGE_MV),
- OUTPUT_VOLTAGE_STEP_MV) - 1;
- rc = qpnp_labibb_masked_write(labibb, labibb->ibb_base +
- REG_IBB_SWIRE_CTL,
- IBB_OUTPUT_VOLTAGE_AT_ONE_PULSE_MASK,
- val);
- if (rc) {
- pr_err("qpnp_labiibb_write register %x failed rc = %d\n",
- REG_IBB_SWIRE_CTL, rc);
+ rc = labibb->ibb_ver_ops->voltage_at_one_pulse(labibb, tmp);
+ if (rc < 0)
return rc;
- }
}
- rc = qpnp_labibb_read(labibb, &ibb_enable_ctl,
- labibb->ibb_base + REG_IBB_ENABLE_CTL, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base + REG_IBB_ENABLE_CTL,
+ &ibb_enable_ctl, 1);
+ if (rc < 0) {
pr_err("qpnp_ibb_read register %x failed rc = %d\n",
REG_IBB_ENABLE_CTL, rc);
return rc;
@@ -2635,47 +3411,40 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
if (ibb_enable_ctl &
(IBB_ENABLE_CTL_SWIRE_RDY | IBB_ENABLE_CTL_MODULE_EN)) {
- /* SWIRE_RDY or IBB_MODULE_EN enabled */
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_LCD_AMOLED_SEL, 1);
- if (rc) {
+
+ rc = labibb->ibb_ver_ops->get_mode(labibb);
+ if (rc < 0) {
pr_err("qpnp_labibb_read register %x failed rc = %d\n",
REG_IBB_LCD_AMOLED_SEL, rc);
return rc;
}
-
- if (val == REG_LAB_IBB_AMOLED_MODE)
- labibb->mode = QPNP_LABIBB_AMOLED_MODE;
- else
- labibb->mode = QPNP_LABIBB_LCD_MODE;
-
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_VOLTAGE, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_VOLTAGE, &val, 1);
+ if (rc < 0) {
pr_err("qpnp_labibb_read read register %x failed rc = %d\n",
REG_IBB_VOLTAGE, rc);
return rc;
}
- if (val & IBB_VOLTAGE_OVERRIDE_EN) {
- labibb->ibb_vreg.curr_volt =
- (val & IBB_VOLTAGE_SET_MASK) *
- labibb->ibb_vreg.step_size +
- labibb->ibb_vreg.min_volt;
- } else if (labibb->mode == QPNP_LABIBB_LCD_MODE) {
+ labibb->ibb_vreg.curr_volt =
+ (val & IBB_VOLTAGE_SET_MASK) *
+ labibb->ibb_vreg.step_size +
+ labibb->ibb_vreg.min_volt;
+
+ if (labibb->mode == QPNP_LABIBB_LCD_MODE) {
rc = of_property_read_u32(of_node,
"qcom,qpnp-ibb-init-lcd-voltage",
&(labibb->ibb_vreg.curr_volt));
- if (rc) {
+ if (rc < 0) {
pr_err("get qcom,qpnp-ibb-init-lcd-voltage failed, rc = %d\n",
rc);
return rc;
}
- } else {
+ } else if (!(val & IBB_VOLTAGE_OVERRIDE_EN)) {
rc = of_property_read_u32(of_node,
"qcom,qpnp-ibb-init-amoled-voltage",
&(labibb->ibb_vreg.curr_volt));
- if (rc) {
+ if (rc < 0) {
pr_err("get qcom,qpnp-ibb-init-amoled-voltage failed, rc = %d\n",
rc);
return rc;
@@ -2683,40 +3452,41 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
}
- rc = qpnp_labibb_read(labibb, &val, labibb->ibb_base +
- REG_IBB_PWRUP_PWRDN_CTL_1, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_PWRUP_PWRDN_CTL_1, &val, 1);
+ if (rc < 0) {
pr_err("qpnp_labibb_config_init read register %x failed rc = %d\n",
REG_IBB_PWRUP_PWRDN_CTL_1, rc);
return rc;
}
- labibb->ibb_vreg.pwrup_dly = ibb_pwrup_dly_plan[
- (val >>
- IBB_PWRUP_PWRDN_CTL_1_DLY1_SHIFT) &
- IBB_PWRUP_PWRDN_CTL_1_DLY1_MASK];
- labibb->ibb_vreg.pwrdn_dly = ibb_pwrdn_dly_plan[val &
+ labibb->ibb_vreg.pwrup_dly = ibb_pwrup_dly_table[
+ (val &
+ IBB_PWRUP_PWRDN_CTL_1_DLY1_MASK)];
+ labibb->ibb_vreg.pwrdn_dly = ibb_pwrdn_dly_table[val &
IBB_PWRUP_PWRDN_CTL_1_DLY2_MASK];
labibb->ibb_vreg.vreg_enabled = 1;
} else {
/* SWIRE_RDY and IBB_MODULE_EN not enabled */
rc = qpnp_ibb_dt_init(labibb, of_node);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp-ibb: wrong DT parameter specified: rc = %d\n",
rc);
return rc;
}
}
- if (labibb->mode == QPNP_LABIBB_AMOLED_MODE) {
+ if (labibb->mode == QPNP_LABIBB_AMOLED_MODE &&
+ qpnp_ibb_poff_ctl_required(labibb)) {
+
val = IBB_OVERRIDE_NONOVERLAP | IBB_NFET_GATE_DELAY_2;
rc = qpnp_labibb_sec_masked_write(labibb, labibb->ibb_base,
REG_IBB_NONOVERLAP_TIME_1,
IBB_OVERRIDE_NONOVERLAP | IBB_NONOVERLAP_NFET_MASK,
val);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_sec_masked_write register %x failed rc = %d\n",
REG_IBB_NONOVERLAP_TIME_1, rc);
return rc;
@@ -2724,9 +3494,9 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
val = IBB_N2P_MUX_SEL;
rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_IBB_NONOVERLAP_TIME_2, &val, 1);
+ REG_IBB_NONOVERLAP_TIME_2, val);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
REG_IBB_NONOVERLAP_TIME_2, rc);
return rc;
@@ -2734,11 +3504,11 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
val = IBB_FASTER_PFET_OFF;
rc = qpnp_labibb_masked_write(labibb,
- labibb->ibb_base + REG_IBB_SPARE_CTL,
- IBB_POFF_CTL_MASK, val);
- if (rc) {
- pr_err("qpnp_labibb_masked_write %x failed rc = %d\n",
- REG_IBB_SPARE_CTL, rc);
+ labibb->ibb_base + REG_IBB_SPARE_CTL,
+ IBB_POFF_CTL_MASK, val);
+ if (rc < 0) {
+ pr_err("write to register %x failed rc = %d\n",
+ REG_IBB_SPARE_CTL, rc);
return rc;
}
}
@@ -2746,8 +3516,8 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
if (labibb->standalone) {
val = 0;
rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_IBB_PWRUP_PWRDN_CTL_1, &val, 1);
- if (rc) {
+ REG_IBB_PWRUP_PWRDN_CTL_1, val);
+ if (rc < 0) {
pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
REG_IBB_PWRUP_PWRDN_CTL_1, rc);
return rc;
@@ -2756,9 +3526,9 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
labibb->ibb_vreg.pwrdn_dly = 0;
}
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_MODULE_RDY, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base + REG_IBB_MODULE_RDY,
+ &val, 1);
+ if (rc < 0) {
pr_err("qpnp_ibb_read read register %x failed rc = %d\n",
REG_IBB_MODULE_RDY, rc);
return rc;
@@ -2770,13 +3540,26 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
rc = qpnp_labibb_write(labibb, labibb->ibb_base +
REG_IBB_MODULE_RDY, &val, 1);
- if (rc) {
+ if (rc < 0) {
pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
REG_IBB_MODULE_RDY, rc);
return rc;
}
}
+ if (of_property_read_bool(of_node,
+ "qcom,qpnp-ibb-enable-pfm-mode")) {
+ rc = qpnp_ibb_pfm_mode_enable(labibb, of_node);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (labibb->pbs_control) {
+ rc = qpnp_labibb_pbs_mode_enable(labibb, of_node);
+ if (rc < 0)
+ return rc;
+ }
+
if (init_data->constraints.name) {
rdesc->owner = THIS_MODULE;
rdesc->type = REGULATOR_VOLTAGE;
@@ -2835,9 +3618,9 @@ static int qpnp_labibb_check_ttw_supported(struct qpnp_labibb *labibb)
switch (labibb->pmic_rev_id->pmic_subtype) {
case PMI8996_SUBTYPE:
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_REVISION4, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, labibb->ibb_base +
+ REG_IBB_REVISION4, &val, 1);
+ if (rc < 0) {
pr_err("qpnp_labibb_read register %x failed rc = %d\n",
REG_IBB_REVISION4, rc);
return rc;
@@ -2891,6 +3674,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
mutex_init(&(labibb->lab_vreg.lab_mutex));
mutex_init(&(labibb->ibb_vreg.ibb_mutex));
+ mutex_init(&(labibb->bus_mutex));
revid_dev_node = of_parse_phandle(labibb->dev->of_node,
"qcom,pmic-revid", 0);
@@ -2905,21 +3689,33 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
- rc = of_property_read_string(labibb->dev->of_node,
- "qcom,qpnp-labibb-mode", &mode_name);
- if (!rc) {
- if (strcmp("lcd", mode_name) == 0) {
- labibb->mode = QPNP_LABIBB_LCD_MODE;
- } else if (strcmp("amoled", mode_name) == 0) {
- labibb->mode = QPNP_LABIBB_AMOLED_MODE;
+ if (labibb->pmic_rev_id->pmic_subtype == PM660L_SUBTYPE) {
+ labibb->ibb_ver_ops = &ibb_ops_v2;
+ labibb->lab_ver_ops = &lab_ops_v2;
+ } else {
+ labibb->ibb_ver_ops = &ibb_ops_v1;
+ labibb->lab_ver_ops = &lab_ops_v1;
+ }
+
+ if (labibb->pmic_rev_id->pmic_subtype == PM660L_SUBTYPE) {
+ labibb->mode = QPNP_LABIBB_AMOLED_MODE;
+ } else {
+ rc = of_property_read_string(labibb->dev->of_node,
+ "qcom,qpnp-labibb-mode", &mode_name);
+ if (!rc) {
+ if (strcmp("lcd", mode_name) == 0) {
+ labibb->mode = QPNP_LABIBB_LCD_MODE;
+ } else if (strcmp("amoled", mode_name) == 0) {
+ labibb->mode = QPNP_LABIBB_AMOLED_MODE;
+ } else {
+ pr_err("Invalid device property in qcom,qpnp-labibb-mode: %s\n",
+ mode_name);
+ return -EINVAL;
+ }
} else {
- pr_err("Invalid device property in qcom,qpnp-labibb-mode: %s\n",
- mode_name);
- return -EINVAL;
+ pr_err("qpnp_labibb: qcom,qpnp-labibb-mode is missing.\n");
+ return rc;
}
- } else {
- pr_err("qpnp_labibb: qcom,qpnp-labibb-mode is missing.\n");
- return rc;
}
labibb->standalone = of_property_read_bool(labibb->dev->of_node,
@@ -2937,6 +3733,9 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
labibb->swire_control = of_property_read_bool(labibb->dev->of_node,
"qcom,swire-control");
+
+ labibb->pbs_control = of_property_read_bool(labibb->dev->of_node,
+ "qcom,pbs-control");
if (labibb->swire_control && labibb->mode != QPNP_LABIBB_AMOLED_MODE) {
pr_err("Invalid mode for SWIRE control\n");
return -EINVAL;
@@ -2950,14 +3749,14 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
rc = of_property_read_u32(labibb->dev->of_node,
"qcom,swire-2nd-cmd-delay",
&labibb->swire_2nd_cmd_delay);
- if (rc)
+ if (rc < 0)
labibb->swire_2nd_cmd_delay =
SWIRE_DEFAULT_2ND_CMD_DLY_MS;
rc = of_property_read_u32(labibb->dev->of_node,
"qcom,swire-ibb-ps-enable-delay",
&labibb->swire_ibb_ps_enable_delay);
- if (rc)
+ if (rc < 0)
labibb->swire_ibb_ps_enable_delay =
SWIRE_DEFAULT_IBB_PS_ENABLE_DLY_MS;
}
@@ -2976,16 +3775,16 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
return rc;
}
- rc = qpnp_labibb_read(labibb, &revision, base + REG_REVISION_2,
- 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, base + REG_REVISION_2,
+ &revision, 1);
+ if (rc < 0) {
pr_err("Reading REVISION_2 failed rc=%d\n", rc);
goto fail_registration;
}
- rc = qpnp_labibb_read(labibb, &type,
- base + REG_PERPH_TYPE, 1);
- if (rc) {
+ rc = qpnp_labibb_read(labibb, base + REG_PERPH_TYPE,
+ &type, 1);
+ if (rc < 0) {
pr_err("Peripheral type read failed rc=%d\n", rc);
goto fail_registration;
}
@@ -3001,7 +3800,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
goto fail_registration;
}
rc = register_qpnp_lab_regulator(labibb, child);
- if (rc)
+ if (rc < 0)
goto fail_registration;
break;
@@ -3009,7 +3808,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
labibb->ibb_base = base;
labibb->ibb_dig_major = revision;
rc = register_qpnp_ibb_regulator(labibb, child);
- if (rc)
+ if (rc < 0)
goto fail_registration;
break;
@@ -3023,13 +3822,16 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
if (labibb->ttw_en) {
rc = qpnp_labibb_check_ttw_supported(labibb);
- if (rc) {
+ if (rc < 0) {
pr_err("pmic revision check failed for TTW rc=%d\n",
rc);
goto fail_registration;
}
}
dev_set_drvdata(&pdev->dev, labibb);
+ pr_info("LAB/IBB registered successfully, lab_vreg enable=%d ibb_vreg enable=%d\n",
+ labibb->lab_vreg.vreg_enabled,
+ labibb->ibb_vreg.vreg_enabled);
return 0;