summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt201
-rw-r--r--arch/arm/boot/dts/qcom/Makefile3
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts88
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-rumi.dts6
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-cdp.dtsi59
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mtp.dtsi59
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi74
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-rumi.dts35
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-sim.dts35
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi51
-rw-r--r--arch/arm/configs/sdm660-perf_defconfig1
-rw-r--r--arch/arm/configs/sdm660_defconfig1
-rw-r--r--arch/arm64/configs/sdm660-perf_defconfig1
-rw-r--r--arch/arm64/configs/sdm660_defconfig1
-rw-r--r--drivers/clk/clk.c9
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c9
-rw-r--r--drivers/clk/qcom/gcc-sdm660.c2
-rw-r--r--drivers/media/platform/msm/vidc/msm_smem.c6
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c8
-rw-r--r--drivers/mmc/core/core.c7
-rw-r--r--drivers/mmc/core/mmc.c9
-rw-r--r--drivers/mmc/core/sdio.c1
-rw-r--r--drivers/mmc/host/sdhci.c3
-rw-r--r--drivers/regulator/qpnp-labibb-regulator.c2304
-rw-r--r--include/media/msm_vidc.h3
-rw-r--r--net/rmnet_data/rmnet_map_command.c10
-rwxr-xr-xscripts/build-all.py2
27 files changed, 2156 insertions, 832 deletions
diff --git a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt
index c039caca22c8..3e22f178aa82 100644
--- a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt
@@ -26,7 +26,7 @@ Main node optional properties:
in LAB and IBB modules. Make sure the
hardware has needed support before
enabling this property.
-- qcom,swire-control: A bool property which indicates if the LAB/IBB is
+- qcom,swire-control: A boolean property which indicates if the LAB/IBB is
controlled by the SWIRE interface. Enable only
if qcom,qpnp-labibb-mode = "amoled".
- qcom,labibb-ttw-force-lab-on: A boolean property which forces LAB to be
@@ -53,6 +53,15 @@ Main node optional properties:
needed when LAB and IBB are operating
in standalone mode to vote for MBG.
+Following properties are available only for PM660A:
+
+- qcom,pbs-control: A boolean property which indicates if
+ the LAB/IBB is controlled by the PBS
+ sequencer. If this mode is enabled the
+ PBS sequencer does the SWIRE remapping
+ and program the voltages based on the
+ SWIRE count.
+
LAB subnode required properties:
- reg: Specifies the SPMI address and size for this peripheral.
@@ -72,29 +81,9 @@ LAB subnode required properties:
is configured in amoled mode.
- qcom,qpnp-lab-init-lcd-voltage: The default output voltage when LAB regulator
is configured in lcd mode.
-- qcom,qpnp-lab-soft-start: The soft start time in us of LAB regulator.
- Supported value are 200, 400, 600 and 800.
-
- qcom,qpnp-lab-ps-threshold: The threshold in mA of Pulse Skip Mode for
LAB regulator. Supported values are 20, 30,
40 and 50.
-- qcom,qpnp-lab-pfet-size: PFET size in percentage. Supported values
- are 25, 50, 75 and 100.
-- qcom,qpnp-lab-nfet-size: NFET size in percentage. Supported values
- are 25, 50, 75 and 100.
-- qcom,qpnp-lab-max-precharge-time: Precharge time in uS for LAB regulator.
- Supported values are 200, 300, 400 and 500.
- Suggested values for LCD and AMOLED mode
- are 500 and 300uS respectively.
-- qcom,qpnp-lab-switching-clock-frequency: The PWM switching clock frequency in
- kHz of Lab regulator, Supported values
- are: 3200, 2740, 2400, 2130, 1920,
- 1750, 1600, 1480, 1370, 1280, 1200,
- 1130, 1070, 1010, 960, 910.
-- qcom,qpnp-lab-limit-maximum-current: The maximum inductor current limit in
- mA of LAB regulator. Supported values
- are 200, 400, 600, 800, 1000, 1200,
- 1400 and 1600.
- interrupts: Specify the interrupts as per the interrupt
encoding.
Currently "lab-vreg-ok" is required for
@@ -125,9 +114,9 @@ LAB subnode optional properties:
- qcom,qpnp-lab-pull-down-enable: A boolean property which upon set will enable
the pull down for LAB regulator. Otherwise,
it is disabled.
-- qcom,qpnp-lab-max-precharge-enable: A boolean property which upon set will
- enable fast precharge. Otherwise, it is
- disabled.
+- qcom,qpnp-lab-max-precharge-enable: A boolean property which upon set will
+ enable fast precharge. Otherwise, it is
+ disabled.
- qcom,qpnp-lab-ring-suppression-enable: A boolean property which upon set will
enable ring suppression for LAB
regulator. Otherwise, it is disabled.
@@ -135,14 +124,65 @@ LAB subnode optional properties:
enforce maximum inductor current constraint
for LAB regulator. Otherwise, there is no
maximum current constraint.
-- qcom,qpnp-lab-use-default-voltage: A boolean property which upon set will
- use the value specified in
- qcom,qpnp-lab-init-voltage property.
- This will be used only if the bootloader
- doesn't configure the output voltage
- already. If it it not specified, then
- output voltage can be configured to
- any value in the allowed limit.
+- qcom,qpnp-lab-switching-clock-frequency: The PWM switching clock frequency in
+ kHz of Lab regulator, Supported values
+ are: 3200, 2740, 2400, 2130, 1920,
+ 1750, 1600, 1480, 1370, 1280, 1200,
+ 1130, 1070, 1010, 960, 910.
+- qcom,qpnp-lab-limit-maximum-current: The maximum inductor current limit in
+ mA of LAB regulator. Supported values
+ are 200, 400, 600, 800, 1000, 1200,
+ 1400 and 1600.
+- qcom,qpnp-lab-pfet-size: PFET size in percentage. Supported values
+ are 25, 50, 75 and 100.
+- qcom,qpnp-lab-nfet-size: NFET size in percentage. Supported values
+ are 25, 50, 75 and 100.
+- qcom,qpnp-lab-max-precharge-time: Precharge time in uS for LAB regulator.
+ Supported values are 200, 300, 400 and 500.
+ Suggested values for LCD and AMOLED mode
+ are 500 and 300uS respectively.
+- qcom,qpnp-lab-use-default-voltage: A boolean property which upon set will
+ use the value specified in
+ qcom,qpnp-lab-init-voltage property.
+ This will be used only if the bootloader
+ doesn't configure the output voltage
+ already. If it it not specified, then
+ output voltage can be configured to
+ any value in the allowed limit.
+
+Following properties are available only for PM660A:
+
+- qcom,qpnp-lab-soft-start: The soft start time in us of LAB regulator.
+ Supported value are 200, 400, 600 and 800.
+- qcom,qpnp-lab-ldo-pulldown-enable: This property is used to enable/disable
+ the LDO pull down.
+ 1 - enable pulldown
+ 0 - disable pulldown
+- qcom,qpnp-lab-enable-sw-high-psrr: A boolean property to enable the
+ software high psrr
+ (Power Suppy Rejection Rate) mode.
+- qcom,qpnp-lab-high-psrr-src-select: This property is used to select the LAB
+ HW high psrr source.
+ The supported values are:
+ 0 = Either vph_high or high_psrr enable
+ 1 = vph_high only
+ 2 = high_psrr enable only
+ 3 = Either vph_high or high_psrr enable
+ This property is not valid if the
+ qcom,qpnp-lab-enable-sw-high-psrr property
+ is specified.
+- qcom,qpnp-lab-vref-high-psrr-select: This property is required if the
+ qcom,qpnp-lab-high-psrr-src-select is
+ specified. The supported values (in mV)
+ are 350, 400, 450 and 500. Once the
+ rejection rate crosses the selected
+ high-psrr voltage the LDO is enabled
+ based on the value specified under
+ qcom,qpnp-lab-high-psrr-src-select
+ property.
+ This property is not valid if the
+ qcom,qpnp-lab-enable-sw-high-psrr property
+ is specified.
IBB subnode required properties:
@@ -154,8 +194,6 @@ IBB subnode required properties:
- qcom,qpnp-ibb-min-voltage: The minimum voltage in microvolts IBB regulator can support.
- qcom,qpnp-ibb-step-size: The step size in microvolts of IBB regulator.
-- qcom,qpnp-ibb-slew-rate: The time in us taken by the regulator to change
- voltage value in one step.
- qcom,qpnp-ibb-soft-start: The soft start time in us of IBB regulator.
- qcom,qpnp-ibb-init-voltage: The default initial voltage when the bootloader does
@@ -168,13 +206,41 @@ IBB subnode required properties:
- qcom,qpnp-ibb-discharge-resistor: The discharge resistor in Kilo Ohms which
controls the soft start time. Supported values
are 300, 64, 32 and 16.
+IBB subnode optional properties:
+
+- qcom,qpnp-ibb-slew-rate: The time (in us) taken by the regulator to change
+ voltage value in one step. This property is not
+ applicable to PM660A.
+ The following properties can be used as an
+ alternate.
+ qcom,qpnp-ibb-slew-rate-config
+ qcom,qpnp-ibb-fast-slew-rate
+ qcom,qpnp-ibb-slow-slew-rate
+- qcom,qpnp-ibb-ps-enable: A boolean property which upon set will enable
+ pulse skip mode for IBB regulator. Otherwise,
+ it is disabled.
+- qcom,qpnp-ibb-num-swire-trans: The number of SWIRE transactions
+ after which the pulse skipping is
+ enabled. This property is required when
+ qpnp-ibb-smart-ps-enable property is
+ set.
+- qcom,qpnp-ibb-neg-curr-limit: This property must be set when the
+ qpnp-ibb-smart-ps-enable is specified.
+ The supported values in mA are 1, 2, 3,
+ 4, 5, 6 and 7. The recommended value is
+- qcom,qpnp-ibb-full-pull-down: A boolean property which upon set will
+ enable the pull down strength of IBB
+ regulator to full. Otherwise, the pull
+ down strength is configured to half.
+- qcom,qpnp-ibb-pull-down-enable: A boolean property which upon set will enable
+ the pull down for IBB regulator. Otherwise,
+ it is disabled.
- qcom,qpnp-ibb-lab-pwrup-delay: Power up delay (in us) for IBB regulator when
it is enabled or turned on. Supported values
are 1000, 2000, 4000 and 8000.
- qcom,qpnp-ibb-lab-pwrdn-delay: Power down delay (in us) for IBB regulator
when it is disabled or turned off. Supported
values are 1000, 2000, 4000 and 8000.
-
- qcom,qpnp-ibb-switching-clock-frequency: The PWM switching clock frequency in
kHz of IBB regulator. Supported values
are: 3200, 2740, 2400, 2130, 1920,
@@ -182,26 +248,13 @@ IBB subnode required properties:
1130, 1070, 1010, 960, 910.
- qcom,qpnp-ibb-limit-maximum-current: The maximum inductor current limit in
mA of IBB regulator. Supported values
- are: 0, 50, 100, 150, 200, 250, 300,
+ are: 0, 50, 100, 150, 200, 250, 300,
350, 400, 450, 500, 550, 600, 650, 700,
750, 800, 850, 900, 950, 1000, 1050,
- 1100, 1150, 1200, 1250, 1300, 1350,
+ 1100, 1150, 1200, 1250, 1300, 1350,
1400, 1450, 1500 and 1550.
- qcom,qpnp-ibb-debounce-cycle: The debounce cycle of IBB regulator.
Supported values are 8, 16, 32 and 64.
-
-IBB subnode optional properties:
-
-- qcom,qpnp-ibb-ps-enable: A boolean property which upon set will enable
- pulse skip mode for IBB regulator. Otherwise,
- it is disabled.
-- qcom,qpnp-ibb-full-pull-down: A boolean property which upon set will enable
- the pull down strength of IBB regulator to
- full. Otherwise, the pull down strength is
- configured to half.
-- qcom,qpnp-ibb-pull-down-enable: A boolean property which upon set will enable
- the pull down for IBB regulator. Otherwise,
- it is disabled.
- qcom,qpnp-ibb-en-discharge: A boolean property which upon set will
enable discharge for IBB regulator.
Otherwise, it is kept disabled.
@@ -220,12 +273,58 @@ IBB subnode optional properties:
already. If it it not specified, then
output voltage can be configured to
any value in the allowed limit.
-- qcom,output-voltage-one-pulse The expected voltage (in mV) of VDISN signal
+- qcom,output-voltage-one-pulse: The expected voltage (in mV) of VDISN signal
on the first SWIRE pulse. This property
can be specified only if 'qcom,swire-control'
is defined. The minimum and maximum values
are 1400mV and 7700mV.
+Following properties are available only for PM660A:
+
+- qcom,qpnp-ibb-smart-ps-enable: A boolean property which upon set
+ enables smart pulse skip mode for IBB
+ regulator. Otherwise, it is disabled.
+ This property is only applicable to
+ PM660A.
+- qcom,qpnp-ibb-enable-pfm-mode: A boolean property which enables the IBB to work
+ in pfm mode.
+- qcom,qpnp-ibb-pfm-peak-curr: The PFM peak current limit settings in mA.
+ Supported values are 150, 200, 250, 300,
+ 350, 400, 450 and 500. This property is
+ required if the qcom,qpnp-ibb-enable-pfm-mode
+ is true.
+- qcom,qpnp-ibb-pfm-hysteresis: The PFM hysteresis voltage threshold in mV.
+ Supported values are 0, 25 and 50.
+ This property is required if the
+ qcom,qpnp-ibb-enable-pfm-mode is specified.
+- qcom,qpnp-ibb-overload-blank: A boolean property which upon set enables
+ the IBB overload blanking.
+- qcom,qpnp-ibb-overload-debounce: The expected overload debounce time (in ms)
+ values are 1, 2, 4 and 8.
+ This property is required only when the
+ qcom,qpnp-ibb-overload-blank is set.
+- qcom,qpnp-ibb-vreg-ok-debounce: The expected vreg-ok-debounce time (us)
+ values are 4, 8, 16 and 32.
+ This property is required only when the
+ qcom,qpnp-ibb-overload-blank is set.
+- qcom,qpnp-ibb-slew-rate-config: A boolean property to configure the
+ ibb fast/slow slew rate.
+ Either qcom,qpnp-ibb-fast-slew-rate or
+ qcom,qpnp-ibb-slow-slew-rate has to be
+ specified. Otherwise the
+ qcom,qpnp-ibb-slow-slew-rate takes precedence
+ over the qcom,qpnp-ibb-fast-slew-rate.
+- qcom,qpnp-ibb-fast-slew-rate: This property is required if the qcom,
+ qpnp-ibb-slew-rate-config property is
+ specified. Supported values (in us) are
+ 100, 200, 500, 1000, 2000, 10000, 12000
+ and 15000.
+- qcom,qpnp-ibb-slow-slew-rate: This property is required if the qcom,
+ qpnp-ibb-slew-rate-config property is
+ specified. Supported values (in us) are
+ 100, 200, 500, 1000, 2000, 10000, 12000
+ and 15000.
+
Example:
qcom,pmi8994@3 {
qpnp-labibb-regulator {
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index af4c3d1d6de4..97508071c18b 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -161,7 +161,8 @@ dtb-$(CONFIG_ARCH_SDM660) += sdm660-sim.dtb \
sda660-pm660a-mtp.dtb \
sda660-pm660a-rcm.dtb
-dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb
+dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \
+ sdm630-pm660a-rumi.dtb
ifeq ($(CONFIG_ARM64),y)
always := $(dtb-y)
diff --git a/arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts b/arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts
new file mode 100644
index 000000000000..398496a943ac
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts
@@ -0,0 +1,88 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm630.dtsi"
+#include "sdm660-pinctrl.dtsi"
+#include "msm-pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660A RUMI";
+ compatible = "qcom,sdm630-rumi", "qcom,sdm630", "qcom,rumi";
+ qcom,board-id = <15 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>;
+
+ chosen {
+ bootargs = "lpm_levels.sleep_disabled=1";
+ };
+};
+
+&usb3 {
+ /delete-property/ USB3_GDSC-supply;
+ /delete-property/ extcon;
+ dwc3@a800000 {
+ maximum-speed = "high-speed";
+ };
+};
+
+&ssphy {
+ compatible = "usb-nop-xceiv";
+};
+
+&qusb_phy0 {
+ reg = <0x0a928000 0x8000>,
+ <0x0a8f8800 0x400>,
+ <0x0a920000 0x100>;
+ reg-names = "qusb_phy_base",
+ "qscratch_base",
+ "emu_phy_base";
+ qcom,emulation;
+ qcom,qusb-phy-init-seq = <0x19 0x1404
+ 0x20 0x1414
+ 0x79 0x1410
+ 0x00 0x1418
+ 0x99 0x1404
+ 0x04 0x1408
+ 0xd9 0x1404>;
+ qcom,emu-dcm-reset-seq = <0x100000 0x20
+ 0x0 0x20
+ 0x1a0 0x20
+ 0x5 0x14>;
+};
+
+&uartblsp1dm1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
+
+&clock_gcc {
+ compatible = "qcom,dummycc";
+ clock-output-names = "gcc_clocks";
+};
+
+&clock_gfx {
+ compatible = "qcom,dummycc";
+ clock-output-names = "gfx_clocks";
+};
+
+&clock_mmss {
+ compatible = "qcom,dummycc";
+ clock-output-names = "mmss_clocks";
+};
+
+&clock_debug {
+ compatible = "qcom,dummycc";
+ clock-output-names = "debug_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630-rumi.dts b/arch/arm/boot/dts/qcom/sdm630-rumi.dts
index 92e6c4ccc790..ddf954f9f6ff 100644
--- a/arch/arm/boot/dts/qcom/sdm630-rumi.dts
+++ b/arch/arm/boot/dts/qcom/sdm630-rumi.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,9 +17,11 @@
#include "sdm660-pinctrl.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. SDM 630 RUMI";
+ model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660L RUMI";
compatible = "qcom,sdm630-rumi", "qcom,sdm630", "qcom,rumi";
qcom,board-id = <15 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
chosen {
bootargs = "lpm_levels.sleep_disabled=1";
diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
index 8304f3386c8a..a3654c21f2db 100644
--- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
@@ -88,6 +88,65 @@
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+&sdhc_1 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l4>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <200 570000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660_l8>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 325000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+ 384000000>;
+
+ qcom,nonremovable;
+ qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+
+ status = "ok";
+};
+
+&sdhc_2 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l5>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 900000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660l_l2>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &tlmm 54 0>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&tlmm 54 0x1>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
+
&soc {
qcom,msm-ssc-sensors {
compatible = "qcom,msm-ssc-sensors";
diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
index ef324de2de9f..fbf44f8350bd 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
@@ -88,6 +88,65 @@
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+&sdhc_1 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l4>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <200 570000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660_l8>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 325000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+ 384000000>;
+
+ qcom,nonremovable;
+ qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+
+ status = "ok";
+};
+
+&sdhc_2 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l5>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 900000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660l_l2>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &tlmm 54 0>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&tlmm 54 0x1>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
+
&soc {
qcom,msm-ssc-sensors {
compatible = "qcom,msm-ssc-sensors";
diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
index 29343a243b9c..172668f7ec0b 100644
--- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
@@ -126,6 +126,80 @@
};
};
+ sdc2_clk_on: sdc2_clk_on {
+ config {
+ pins = "sdc2_clk";
+ drive-strength = <16>; /* 16 MA */
+ bias-disable; /* NO pull */
+ };
+ };
+
+ sdc2_clk_off: sdc2_clk_off {
+ config {
+ pins = "sdc2_clk";
+ bias-disable; /* NO pull */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ sdc2_cmd_on: sdc2_cmd_on {
+ config {
+ pins = "sdc2_cmd";
+ bias-pull-up; /* pull up */
+ drive-strength = <10>; /* 10 MA */
+ };
+ };
+
+ sdc2_cmd_off: sdc2_cmd_off {
+ config {
+ pins = "sdc2_cmd";
+ bias-pull-up; /* pull up */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ sdc2_data_on: sdc2_data_on {
+ config {
+ pins = "sdc2_data";
+ bias-pull-up; /* pull up */
+ drive-strength = <10>; /* 10 MA */
+ };
+ };
+
+ sdc2_data_off: sdc2_data_off {
+ config {
+ pins = "sdc2_data";
+ bias-pull-up; /* pull up */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ sdc2_cd_on: cd_on {
+ mux {
+ pins = "gpio54";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio54";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ sdc2_cd_off: cd_off {
+ mux {
+ pins = "gpio54";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio54";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
/* I2C CONFIGURATION */
i2c_1 {
i2c_1_active: i2c_1_active {
diff --git a/arch/arm/boot/dts/qcom/sdm660-rumi.dts b/arch/arm/boot/dts/qcom/sdm660-rumi.dts
index f5759b6af7fd..80202cc87322 100644
--- a/arch/arm/boot/dts/qcom/sdm660-rumi.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-rumi.dts
@@ -84,7 +84,7 @@
pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
- qcom,clk-rates = <400000 20000000 25000000 50000000 192000000
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
384000000>;
qcom,nonremovable;
@@ -93,6 +93,39 @@
status = "ok";
};
+&sdhc_2 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l5>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 900000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660l_l2>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &tlmm 54 0>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&tlmm 54 0x1>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
+
&clock_gcc {
compatible = "qcom,dummycc";
clock-output-names = "gcc_clocks";
diff --git a/arch/arm/boot/dts/qcom/sdm660-sim.dts b/arch/arm/boot/dts/qcom/sdm660-sim.dts
index bb896cb7437d..a3ee70d0bed0 100644
--- a/arch/arm/boot/dts/qcom/sdm660-sim.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-sim.dts
@@ -68,7 +68,7 @@
pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
- qcom,clk-rates = <400000 20000000 25000000 50000000 192000000
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
384000000>;
qcom,nonremovable;
@@ -77,6 +77,39 @@
status = "ok";
};
+&sdhc_2 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l5>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 900000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660l_l2>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &tlmm 54 0>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&tlmm 54 0x1>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
+
&pm660_charger {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index 856608e4e47a..b32742ab00f6 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -28,6 +28,7 @@
aliases {
serial0 = &uartblsp1dm1;
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
+ sdhc2 = &sdhc_2; /* SDC2 for SD card */
};
chosen {
@@ -1183,7 +1184,7 @@
reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>;
reg-names = "hc_mem", "cmdq_mem";
- interrupts = <0 129 0>, <0 227 0>;
+ interrupts = <0 110 0>, <0 112 0>;
interrupt-names = "hc_irq", "pwr_irq";
qcom,bus-width = <8>;
@@ -1191,6 +1192,21 @@
qcom,devfreq,freq-table = <50000000 200000000>;
+ qcom,msm-bus,name = "sdhc1";
+ qcom,msm-bus,num-cases = <9>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */
+ <78 512 1046 3200>, /* 400 KB/s*/
+ <78 512 52286 160000>, /* 20 MB/s */
+ <78 512 65360 200000>, /* 25 MB/s */
+ <78 512 130718 400000>, /* 50 MB/s */
+ <78 512 130718 400000>, /* 100 MB/s */
+ <78 512 261438 800000>, /* 200 MB/s */
+ <78 512 261438 800000>, /* 400 MB/s */
+ <78 512 1338562 4096000>; /* Max. bandwidth */
+ qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
+ 100000000 200000000 400000000 4294967295>;
+
clocks = <&clock_gcc GCC_SDCC1_AHB_CLK>,
<&clock_gcc GCC_SDCC1_APPS_CLK>;
clock-names = "iface_clk", "core_clk";
@@ -1198,6 +1214,39 @@
status = "disabled";
};
+ sdhc_2: sdhci@c084000 {
+ compatible = "qcom,sdhci-msm-v5";
+ reg = <0xc084000 0x1000>;
+ reg-names = "hc_mem";
+
+ interrupts = <0 125 0>, <0 221 0>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ qcom,bus-width = <4>;
+ qcom,large-address-bus;
+
+ qcom,msm-bus,name = "sdhc2";
+ qcom,msm-bus,num-cases = <8>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */
+ <81 512 1046 3200>, /* 400 KB/s */
+ <81 512 52286 160000>, /* 20 MB/s */
+ <81 512 65360 200000>, /* 25 MB/s */
+ <81 512 130718 400000>, /* 50 MB/s */
+ <81 512 261438 800000>, /* 100 MB/s */
+ <81 512 261438 800000>, /* 200 MB/s */
+ <81 512 1338562 4096000>; /* Max. bandwidth */
+ qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
+ 100000000 200000000 4294967295>;
+
+ qcom,devfreq,freq-table = <50000000 200000000>;
+ clocks = <&clock_gcc GCC_SDCC2_AHB_CLK>,
+ <&clock_gcc GCC_SDCC2_APPS_CLK>;
+ clock-names = "iface_clk", "core_clk";
+
+ status = "disabled";
+ };
+
ipa_hw: qcom,ipa@14780000 {
compatible = "qcom,ipa";
reg = <0x14780000 0x4effc>, <0x14784000 0x26934>;
diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig
index d6ed666062cc..ac968edff299 100644
--- a/arch/arm/configs/sdm660-perf_defconfig
+++ b/arch/arm/configs/sdm660-perf_defconfig
@@ -445,6 +445,7 @@ CONFIG_MMC_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_CQ_HCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP=y
diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig
index f993fcc12bb2..10b8666a2d40 100644
--- a/arch/arm/configs/sdm660_defconfig
+++ b/arch/arm/configs/sdm660_defconfig
@@ -446,6 +446,7 @@ CONFIG_MMC_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_CQ_HCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP=y
diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig
index e23dddb07ea1..f15fd895e65c 100644
--- a/arch/arm64/configs/sdm660-perf_defconfig
+++ b/arch/arm64/configs/sdm660-perf_defconfig
@@ -474,6 +474,7 @@ CONFIG_MMC_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_CQ_HCI=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_QPNP_WLED=y
diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig
index c6cc69664591..b52a672a5b5e 100644
--- a/arch/arm64/configs/sdm660_defconfig
+++ b/arch/arm64/configs/sdm660_defconfig
@@ -476,6 +476,7 @@ CONFIG_MMC_TEST=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_CQ_HCI=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_QPNP_WLED=y
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ac815c6dbac0..6493b59dac01 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -188,6 +188,9 @@ static bool clk_core_is_enabled(struct clk_core *core)
return core->ops->is_enabled(core->hw);
}
+static void clk_core_unprepare(struct clk_core *core);
+static void clk_core_disable(struct clk_core *core);
+
static void clk_unprepare_unused_subtree(struct clk_core *core)
{
struct clk_core *child;
@@ -207,7 +210,7 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
*/
if (core->need_handoff_prepare) {
core->need_handoff_prepare = false;
- core->prepare_count--;
+ clk_core_unprepare(core);
}
if (core->prepare_count)
@@ -246,7 +249,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
*/
if (core->need_handoff_enable) {
core->need_handoff_enable = false;
- core->enable_count--;
+ flags = clk_enable_lock();
+ clk_core_disable(core);
+ clk_enable_unlock(flags);
}
flags = clk_enable_lock();
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index 9332e99e642b..349af277291d 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -323,7 +323,7 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw)
mutex_lock(&rpm_smd_clk_lock);
if (!r->rate)
- goto out;
+ goto enable;
/* Take peer clock's rate into account only if it's enabled. */
if (peer->enabled)
@@ -340,6 +340,7 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw)
if (ret)
goto out;
+enable:
r->enabled = false;
out:
@@ -575,6 +576,8 @@ static DEFINE_CLK_VOTER(pnoc_pm_clk, pnoc_clk, LONG_MAX);
static DEFINE_CLK_VOTER(pnoc_sps_clk, pnoc_clk, 0);
static DEFINE_CLK_VOTER(mmssnoc_a_clk_cpu_vote, mmssnoc_axi_rpm_a_clk,
19200000);
+static DEFINE_CLK_VOTER(mmssnoc_a_cpu_clk, mmssnoc_axi_a_clk,
+ 19200000);
/* Voter Branch clocks */
static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, cxo);
@@ -744,11 +747,12 @@ static struct clk_hw *sdm660_clks[] = {
[CXO_PIL_LPASS_CLK] = &cxo_pil_lpass_clk.hw,
[CXO_PIL_CDSP_CLK] = &cxo_pil_cdsp_clk.hw,
[CNOC_PERIPH_KEEPALIVE_A_CLK] = &cnoc_periph_keepalive_a_clk.hw,
+ [MMSSNOC_A_CLK_CPU_VOTE] = &mmssnoc_a_cpu_clk.hw
};
static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
.clks = sdm660_clks,
- .num_rpm_clks = RPM_CNOC_PERIPH_A_CLK,
+ .num_rpm_clks = MMSSNOC_AXI_A_CLK,
.num_clks = ARRAY_SIZE(sdm660_clks),
};
@@ -855,6 +859,7 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
/* Hold an active set vote for the cnoc_periph resource */
clk_set_rate(cnoc_periph_keepalive_a_clk.hw.clk, 19200000);
clk_prepare_enable(cnoc_periph_keepalive_a_clk.hw.clk);
+ clk_prepare_enable(mmssnoc_a_cpu_clk.hw.clk);
}
dev_info(&pdev->dev, "Registered RPM clocks\n");
diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
index da4c6e8797d7..1ae71a6ee93b 100644
--- a/drivers/clk/qcom/gcc-sdm660.c
+++ b/drivers/clk/qcom/gcc-sdm660.c
@@ -3028,7 +3028,7 @@ static struct clk_debug_mux gcc_debug_mux = {
{ "snoc_clk", 0x000 },
{ "cnoc_clk", 0x00E },
{ "cnoc_periph_clk", 0x198 },
- { "bimc_clk", 0x14E },
+ { "bimc_clk", 0x19D },
{ "ce1_clk", 0x097 },
{ "ipa_clk", 0x11b },
{ "gcc_aggre2_ufs_axi_clk", 0x10B },
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 90047a608984..44c5c08f074c 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -513,10 +513,10 @@ static int ion_cache_operations(struct smem_client *client,
rc = -EINVAL;
goto cache_op_failed;
}
- rc = msm_ion_do_cache_op(client->clnt,
+ rc = msm_ion_do_cache_offset_op(client->clnt,
(struct ion_handle *)mem->smem_priv,
- 0, (unsigned long)mem->size,
- msm_cache_ops);
+ 0, mem->offset,
+ (unsigned long)mem->size, msm_cache_ops);
if (rc) {
dprintk(VIDC_ERR,
"cache operation failed %d\n", rc);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 8b1329db1742..babea6824c51 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -333,7 +333,7 @@ static inline void populate_buf_info(struct buffer_info *binfo,
binfo->timestamp.tv_sec = b->timestamp.tv_sec;
binfo->timestamp.tv_usec = b->timestamp.tv_usec;
dprintk(VIDC_DBG, "%s: fd[%d] = %d b->index = %d",
- __func__, i, binfo->fd[0], b->index);
+ __func__, i, binfo->fd[i], b->index);
}
static inline void repopulate_v4l2_buffer(struct v4l2_buffer *b,
@@ -658,8 +658,12 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
for (i = 0; i < binfo->num_planes; i++) {
if (binfo->handle[i]) {
+ struct msm_smem smem = *binfo->handle[i];
+
+ smem.offset = (unsigned int)(binfo->buff_off[i]);
+ smem.size = binfo->size[i];
rc = msm_comm_smem_cache_operations(inst,
- binfo->handle[i], SMEM_CACHE_INVALIDATE);
+ &smem, SMEM_CACHE_INVALIDATE);
if (rc) {
dprintk(VIDC_ERR,
"%s: Failed to clean caches: %d\n",
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index a444a3a80f52..152a3e3b4f47 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1748,6 +1748,10 @@ EXPORT_SYMBOL(mmc_start_req);
*/
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
+#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
+ if (mmc_bus_needs_resume(host))
+ mmc_resume_bus(host);
+#endif
__mmc_start_req(host, mrq);
mmc_wait_for_req_done(host, mrq);
}
@@ -3105,9 +3109,6 @@ int mmc_resume_bus(struct mmc_host *host)
}
}
- if (host->bus_ops->detect && !host->bus_dead)
- host->bus_ops->detect(host);
-
mmc_bus_put(host);
pr_debug("%s: Deferred resume completed\n", mmc_hostname(host));
return 0;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 89288bd1eaa4..a3f650f5ee9f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2514,12 +2514,6 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
goto out;
}
- if (mmc_card_doing_auto_bkops(host->card)) {
- err = mmc_set_auto_bkops(host->card, false);
- if (err)
- goto out;
- }
-
err = mmc_flush_cache(host->card);
if (err)
goto out;
@@ -2599,9 +2593,6 @@ static int mmc_partial_init(struct mmc_host *host)
pr_debug("%s: %s: reading and comparing ext_csd successful\n",
mmc_hostname(host), __func__);
- if (mmc_card_support_auto_bkops(host->card))
- (void)mmc_set_auto_bkops(host->card, true);
-
if (card->ext_csd.cmdq_support && (card->host->caps2 &
MMC_CAP2_CMD_QUEUE)) {
err = mmc_select_cmdq(card);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index e7ebc3cb8eda..5fedab49cf34 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -1078,6 +1078,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
mmc_release_host(host);
host->pm_flags &= ~MMC_PM_KEEP_POWER;
+ host->pm_flags &= ~MMC_PM_WAKE_SDIO_IRQ;
return err;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d51195e8a352..08822464d82f 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2997,7 +2997,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
host->ops->adma_workaround(host, intmask);
}
if (host->data->error) {
- if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT)) {
+ if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT
+ | SDHCI_INT_DATA_END_BIT)) {
command = SDHCI_GET_CMD(sdhci_readw(host,
SDHCI_COMMAND));
if ((command != MMC_SEND_TUNING_BLOCK_HS200) &&
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;
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 0a089c4faee1..003adc38eb14 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -68,6 +68,7 @@ struct msm_smem {
void *smem_priv;
enum hal_buffer buffer_type;
struct dma_mapping_info mapping_info;
+ unsigned int offset;
};
enum smem_cache_ops {
diff --git a/net/rmnet_data/rmnet_map_command.c b/net/rmnet_data/rmnet_map_command.c
index 055d5f402957..9dac2b27d4c3 100644
--- a/net/rmnet_data/rmnet_map_command.c
+++ b/net/rmnet_data/rmnet_map_command.c
@@ -121,6 +121,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
{
struct rmnet_map_control_command_s *cmd;
int xmit_status;
+ int rc;
if (unlikely(!skb))
BUG();
@@ -149,6 +150,15 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
netif_tx_unlock(skb->dev);
LOGD("MAP command ACK=%hhu sent with rc: %d", type & 0x03, xmit_status);
+
+ if (xmit_status != NETDEV_TX_OK) {
+ rc = dev_queue_xmit(skb);
+ if (rc != 0) {
+ LOGD("Failed to queue packet for transmission on [%s]",
+ skb->dev->name);
+ }
+ }
+
}
/**
diff --git a/scripts/build-all.py b/scripts/build-all.py
index 9e4942d21da9..4f02c33d4248 100755
--- a/scripts/build-all.py
+++ b/scripts/build-all.py
@@ -303,9 +303,11 @@ def scan_configs():
r'apq*_defconfig',
r'qsd*_defconfig',
r'mpq*_defconfig',
+ r'sdm[0-9]*_defconfig',
)
arch64_pats = (
r'msm*_defconfig',
+ r'sdm[0-9]*_defconfig',
)
for p in arch_pats:
for n in glob.glob('arch/arm/configs/' + p):