[PATCH] dt-bindings: Use portable sort for version cmp

2021-02-01 Thread Iskren Chernev
sort -C is like sort -c >/dev/null but less portable. It fails on
busybox sort (i.e alpine linux).

Signed-off-by: Iskren Chernev 
Fixes: ea5b8b5eb004 ("dt-bindings: Add a minimum version check for dtschema")
---
 Documentation/devicetree/bindings/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/Makefile 
b/Documentation/devicetree/bindings/Makefile
index 90fcad98984d..780e5618ec0a 100644
--- a/Documentation/devicetree/bindings/Makefile
+++ b/Documentation/devicetree/bindings/Makefile
@@ -10,7 +10,7 @@ DT_SCHEMA_MIN_VERSION = 2020.8.1
 PHONY += check_dtschema_version
 check_dtschema_version:
@{ echo $(DT_SCHEMA_MIN_VERSION); \
-   $(DT_DOC_CHECKER) --version 2>/dev/null || echo 0; } | sort -VC || \
+   $(DT_DOC_CHECKER) --version 2>/dev/null || echo 0; } | sort -Vc 
>/dev/null || \
{ echo "ERROR: dtschema minimum version is v$(DT_SCHEMA_MIN_VERSION)" 
>&2; false; }
 
 quiet_cmd_extract_ex = DTEX$@

base-commit: fd821bf0ed9a7db09d2e007df697f4d9ecfda99a
prerequisite-patch-id: c90e3d48df0672dab84da1b294374598bfc45db8
prerequisite-patch-id: f0b48cda55170cf82855daa6f7b4edfdba83d90c
prerequisite-patch-id: 48482c0c3e2797459e311f73db1828f2531bd11c
prerequisite-patch-id: 5512fd0c8367c8c8a2ace8003b533057422e1437
prerequisite-patch-id: 1635c0e78c99506fd2710f54be4e5fc5980712a6
prerequisite-patch-id: e80dacf2da55197be027f297617868832ddabfc9
prerequisite-patch-id: bd3efb4ced6ceb2c6a50dcd8527ea4d6d19baf5d
-- 
2.30.0



[PATCH v3 1/2] dt-bindings: panel: Add Samsung S6E3FA2 panel

2021-02-01 Thread Iskren Chernev
The Samsung S6E3FA2 AMOLED cmd LCD panel is used on the Samsung Galaxy
S5 (klte).

Signed-off-by: Iskren Chernev 
---
Add a simple generated panel driver that supports on/off and the corresponding
binding documentation.

Changes in v3:
- fix dt_binding_check issue with missing include
- fix panel type (cmd) in kconfig description

Changes in v2:
- move bindings to separate file, add 2 regulators
- add standalone panel driver

v1: https://lkml.org/lkml/2020/12/30/293
v2: https://lkml.org/lkml/2021/2/1/313

 .../display/panel/samsung,s6e3fa2.yaml| 64 +++
 1 file changed, 64 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml 
b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml
new file mode 100644
index ..c751ad589480
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fa2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung s6e3fa2 AMOLED CMD LCD panel
+
+maintainers:
+  - Iskren Chernev 
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+const: samsung,s6e3fa2
+
+  reg: true
+  reset-gpios: true
+  port: true
+
+  iovdd-supply:
+description: IOVDD regulator
+
+  vddr-supply:
+description: VDDR regulator
+
+required:
+  - compatible
+  - reset-gpios
+  - iovdd-supply
+  - vddr-supply
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+/* from Samsung Galaxy S5 klte */
+#include 
+
+dsi {
+#address-cells = <1>;
+#size-cells = <0>;
+
+panel@0 {
+compatible = "samsung,s6e3fa2";
+reg = <0>;
+
+reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
+
+iovdd-supply = <&pma8084_lvs4>;
+vddr-supply = <&vreg_panel>;
+
+port {
+panel_in: endpoint {
+remote-endpoint = <&dsi0_out>;
+};
+};
+};
+};
+
+...

base-commit: fd821bf0ed9a7db09d2e007df697f4d9ecfda99a
--
2.30.0



[PATCH v3 2/2] drm/panel: Add panel for Samsung Galaxy S5

2021-02-01 Thread Iskren Chernev
The Samsung Galaxy S5 uses the samsung s6e3fa2 AMOLED cmd LCD panel.

This driver was generated with [1], with the addition of
mipi_dsi_dcs_set_display_on at the end of the on method.

[1] https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator

Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/panel/Kconfig |   6 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c | 299 ++
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4894913936e9..82dff2afd5f1 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -348,6 +348,12 @@ config DRM_PANEL_SAMSUNG_S6D16D0
depends on DRM_MIPI_DSI
select VIDEOMODE_HELPERS
 
+config DRM_PANEL_SAMSUNG_S6E3FA2
+   tristate "Samsung S6E3FA2 DSI cmd mode panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   select VIDEOMODE_HELPERS
+
 config DRM_PANEL_SAMSUNG_S6E3HA2
tristate "Samsung S6E3HA2 DSI video mode panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index cae4d976c069..87d3f76f050e 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += 
panel-raydium-rm68200.o
 obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FA2) += panel-samsung-s6e3fa2.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c 
b/drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c
new file mode 100644
index ..8985fccf9792
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright (c) 2021 Iskren Chernev 
+// Generated with linux-mdss-dsi-panel-driver-generator from vendor device 
tree:
+// Copyright (c) 2021, The Linux Foundation. All rights reserved.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct samsung_s6e3fa2 {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   struct regulator_bulk_data supplies[2];
+   struct gpio_desc *reset_gpio;
+   bool prepared;
+};
+
+static inline
+struct samsung_s6e3fa2 *to_samsung_s6e3fa2(struct drm_panel *panel)
+{
+   return container_of(panel, struct samsung_s6e3fa2, panel);
+}
+
+#define dsi_generic_write_seq(dsi, seq...) do {
\
+   static const u8 d[] = { seq };  \
+   int ret;\
+   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));\
+   if (ret < 0)\
+   return ret; \
+   } while (0)
+
+#define dsi_dcs_write_seq(dsi, seq...) do {\
+   static const u8 d[] = { seq };  \
+   int ret;\
+   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
+   if (ret < 0)\
+   return ret; \
+   } while (0)
+
+static void samsung_s6e3fa2_reset(struct samsung_s6e3fa2 *ctx)
+{
+   gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+   usleep_range(5000, 6000);
+   gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+   usleep_range(5000, 6000);
+   gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+   usleep_range(7000, 8000);
+}
+
+static int samsung_s6e3fa2_on(struct samsung_s6e3fa2 *ctx)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct device *dev = &dsi->dev;
+   int ret;
+
+   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+   dsi_generic_write_seq(dsi, 0xf0, 0x5a, 0x5a);
+   dsi_generic_write_seq(dsi, 0xfc, 0x5a, 0x5a);
+   dsi_dcs_write_seq(dsi, 0xf2);
+   dsi_dcs_write_seq(dsi, 0xf9);
+   usleep_range(5000, 6000);
+
+   ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+   if (ret < 0) {
+   dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+   return ret;
+   }
+   msleep(20);
+
+   dsi_generic_write_seq(dsi, 0xca,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80,
+  

[PATCH v5 4/4] ARM: dts: qcom: msm8974-klte: Mark essential regulators

2021-02-01 Thread Iskren Chernev
s1 and l12 regulators are used for the memory and cache on the Samsung
S5 (klte). If they are turned off the phone shuts down. So mark them as
always-on to prevent that from happening.

Signed-off-by: Iskren Chernev 
Tested-by: Alexey Minnekhanov 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index d042c7cbab71..a0f7f461f48c 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -30,6 +30,7 @@ pma8084-regulators {
pma8084_s1: s1 {
regulator-min-microvolt = 
<675000>;
regulator-max-microvolt = 
<105>;
+   regulator-always-on;
};
 
pma8084_s2: s2 {
@@ -115,6 +116,7 @@ pma8084_l11: l11 {
pma8084_l12: l12 {
regulator-min-microvolt = 
<180>;
regulator-max-microvolt = 
<180>;
+   regulator-always-on;
};
 
pma8084_l13: l13 {
-- 
2.30.0



[PATCH v5 3/4] ARM: dts: qcom: msm8974-klte: add support for display

2021-02-01 Thread Iskren Chernev
From: Samuel Pascua 

Add initial support for the display found on the Samsung Galaxy 5 (klte)
phone. This is based on work from Jonathan Marek & Brian Masney.

Signed-off-by: Samuel Pascua 
[iskren.cher...@gmail.com: add reset gpio, regulators]
Signed-off-by: Iskren Chernev 
---
On downstream the panel uses a regulator and an enable pin, but it is hinted
that the enable pin is actually another regulator, so wrap the enable pin into
a regulator and put the two new regulator in the panel node.

 .../boot/dts/qcom-msm8974-samsung-klte.dts| 95 +++
 1 file changed, 95 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 86be4ae743f4..d042c7cbab71 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -298,6 +298,20 @@ vreg_wlan: wlan-regulator {
enable-active-high;
};
 
+   vreg_panel: panel-regulator {
+   compatible = "regulator-fixed";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&panel_en_pin>;
+
+   regulator-name = "panel-vddr-reg";
+   regulator-min-microvolt = <150>;
+   regulator-max-microvolt = <150>;
+
+   gpio = <&pma8084_gpios 14 GPIO_ACTIVE_HIGH>;
+   enable-active-high;
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -453,6 +467,16 @@ int {
bias-pull-down;
};
};
+
+   panel_te_pin: panel {
+   te {
+   pins = "gpio12";
+   function = "mdp_vsync";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};
 
sdhc_1: sdhci@f9824900 {
@@ -701,6 +725,60 @@ fuelgauge@36 {
adreno@fdb0 {
status = "ok";
};
+
+   mdss@fd90 {
+   status = "ok";
+
+   mdp@fd90 {
+   status = "ok";
+   };
+
+   dsi@fd922800 {
+   status = "ok";
+
+   vdda-supply = <&pma8084_l2>;
+   vdd-supply = <&pma8084_l22>;
+   vddio-supply = <&pma8084_l12>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <&panel_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+
+   panel: panel@0 {
+   reg = <0>;
+   compatible = "samsung,s6e3fa2";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
+
+   iovdd-supply = <&pma8084_lvs4>;
+   vddr-supply = <&vreg_panel>;
+
+   reset-gpios = <&pma8084_gpios 17 
GPIO_ACTIVE_LOW>;
+   te-gpios = <&msmgpio 12 GPIO_ACTIVE_HIGH>;
+
+   port {
+   panel_in: endpoint {
+   remote-endpoint = <&dsi0_out>;
+   };
+   };
+   };
+   };
+
+   dsi-phy@fd922a00 {
+   status = "ok";
+
+   vddio-supply = <&pma8084_l12>;
+   };
+   };
 };
 
 &spmi_bus {
@@ -730,6 +808,14 @@ touch_pin: touchscreen-int-pin {
power-source = ;
};
 
+   panel_en_pin: panel-en-pin {
+   pins = "gpio14";
+   function = "normal";
+   bias-pull-up;
+   power-source = ;
+   qcom,drive-strength = ;
+   };
+
wlan_sleep_clk_pin: wlan-sleep-clk-pin {
pins = "gpio16";
function = "func2";
@@ -739,6 +825,15 @@ wlan_sleep_clk_pin: wlan-slee

[PATCH v5 2/4] ARM: dts: qcom: msm8974-klte: add support for GPU

2021-02-01 Thread Iskren Chernev
From: Samuel Pascua 

Enable adreno dt node.

Signed-off-by: Samuel Pascua 
[iskren.cher...@gmail.com: changes after v1]
Signed-off-by: Iskren Chernev 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 3929c9435e29..86be4ae743f4 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -697,6 +697,10 @@ fuelgauge@36 {
pinctrl-0 = <&fuelgauge_pin>;
};
};
+
+   adreno@fdb0 {
+   status = "ok";
+   };
 };

 &spmi_bus {
--
2.30.0



[PATCH v5 1/4] ARM: dts: qcom: msm8974: add gpu support

2021-02-01 Thread Iskren Chernev
From: Brian Masney 

Add support for the a3xx GPU. opp_table is chosen to include lower
frequencies common to all different msm8974 variants.

Signed-off-by: Brian Masney 
[iskren.cher...@gmail.com: change after v1]
Signed-off-by: Iskren Chernev 
---
Update the panel/dsi patch according to new dt bindigs in
panel-v2: https://lkml.org/lkml/2021/2/1/313

v1: https://lkml.org/lkml/2020/12/30/322
v2: https://lkml.org/lkml/2021/1/24/142
v3: https://lkml.org/lkml/2021/1/25/398
v4: https://lkml.org/lkml/2021/1/28/374

Changes in v5:
- panel/dsi patch contains 2 regulators, now that the display can turn off

 arch/arm/boot/dts/qcom-msm8974.dtsi| 43 ++
 arch/arm/boot/dts/qcom-msm8974pro.dtsi |  5 +++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 51f5f904f9eb..c65d33591efa 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1399,6 +1399,49 @@ cnoc: interconnect@fc48 {
 <&rpmcc RPM_SMD_CNOC_A_CLK>;
};

+   gpu: adreno@fdb0 {
+   status = "disabled";
+
+   compatible = "qcom,adreno-330.1",
+"qcom,adreno";
+   reg = <0xfdb0 0x1>;
+   reg-names = "kgsl_3d0_reg_memory";
+   interrupts = ;
+   interrupt-names = "kgsl_3d0_irq";
+   clock-names = "core",
+ "iface",
+ "mem_iface";
+   clocks = <&mmcc OXILI_GFX3D_CLK>,
+<&mmcc OXILICX_AHB_CLK>,
+<&mmcc OXILICX_AXI_CLK>;
+   sram = <&gmu_sram>;
+   power-domains = <&mmcc OXILICX_GDSC>;
+   operating-points-v2 = <&gpu_opp_table>;
+
+   interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc 
BIMC_SLV_EBI_CH0>,
+   <&ocmemnoc OCMEM_VNOC_MAS_GFX3D 
&ocmemnoc OCMEM_SLV_OCMEM>;
+   interconnect-names = "gfx-mem",
+"ocmem";
+
+   // iommus = <&gpu_iommu 0>;
+
+   gpu_opp_table: opp_table {
+   compatible = "operating-points-v2";
+
+   opp-32000 {
+   opp-hz = /bits/ 64 <32000>;
+   };
+
+   opp-2 {
+   opp-hz = /bits/ 64 <2>;
+   };
+
+   opp-2700 {
+   opp-hz = /bits/ 64 <2700>;
+   };
+   };
+   };
+
mdss: mdss@fd90 {
status = "disabled";

diff --git a/arch/arm/boot/dts/qcom-msm8974pro.dtsi 
b/arch/arm/boot/dts/qcom-msm8974pro.dtsi
index 6740a4cb7da8..b64c28036dd0 100644
--- a/arch/arm/boot/dts/qcom-msm8974pro.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974pro.dtsi
@@ -14,5 +14,10 @@ sdhci@f9824900 {
clock-controller@fc40 {
compatible = "qcom,gcc-msm8974pro";
};
+
+   adreno@fdb0 {
+   compatible = "qcom,adreno-330.2",
+"qcom,adreno";
+   };
};
 };

base-commit: fd821bf0ed9a7db09d2e007df697f4d9ecfda99a
prerequisite-patch-id: b55fe8485f5dbf29159fb3130d81d93926be23d1
prerequisite-patch-id: 47e70201c831fab5fb987d9b0092ad46e1855efc
--
2.30.0



[PATCH v2 2/2] drm/panel: Add panel for Samsung Galaxy S5

2021-02-01 Thread Iskren Chernev
The Samsung Galaxy S5 uses the samsung s6e3fa2 AMOLED cmd LCD panel.

This driver was generated with [1], with the addition of
mipi_dsi_dcs_set_display_on at the end of the on method.

[1] https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator

Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/panel/Kconfig |   6 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c | 299 ++
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4894913936e9..82dff2afd5f1 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -348,6 +348,12 @@ config DRM_PANEL_SAMSUNG_S6D16D0
depends on DRM_MIPI_DSI
select VIDEOMODE_HELPERS
 
+config DRM_PANEL_SAMSUNG_S6E3FA2
+   tristate "Samsung S6E3FA2 DSI video mode panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   select VIDEOMODE_HELPERS
+
 config DRM_PANEL_SAMSUNG_S6E3HA2
tristate "Samsung S6E3HA2 DSI video mode panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index cae4d976c069..87d3f76f050e 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += 
panel-raydium-rm68200.o
 obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FA2) += panel-samsung-s6e3fa2.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c 
b/drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c
new file mode 100644
index ..8985fccf9792
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e3fa2.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright (c) 2021 Iskren Chernev 
+// Generated with linux-mdss-dsi-panel-driver-generator from vendor device 
tree:
+// Copyright (c) 2021, The Linux Foundation. All rights reserved.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct samsung_s6e3fa2 {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   struct regulator_bulk_data supplies[2];
+   struct gpio_desc *reset_gpio;
+   bool prepared;
+};
+
+static inline
+struct samsung_s6e3fa2 *to_samsung_s6e3fa2(struct drm_panel *panel)
+{
+   return container_of(panel, struct samsung_s6e3fa2, panel);
+}
+
+#define dsi_generic_write_seq(dsi, seq...) do {
\
+   static const u8 d[] = { seq };  \
+   int ret;\
+   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));\
+   if (ret < 0)\
+   return ret; \
+   } while (0)
+
+#define dsi_dcs_write_seq(dsi, seq...) do {\
+   static const u8 d[] = { seq };  \
+   int ret;\
+   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
+   if (ret < 0)\
+   return ret; \
+   } while (0)
+
+static void samsung_s6e3fa2_reset(struct samsung_s6e3fa2 *ctx)
+{
+   gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+   usleep_range(5000, 6000);
+   gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+   usleep_range(5000, 6000);
+   gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+   usleep_range(7000, 8000);
+}
+
+static int samsung_s6e3fa2_on(struct samsung_s6e3fa2 *ctx)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct device *dev = &dsi->dev;
+   int ret;
+
+   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+   dsi_generic_write_seq(dsi, 0xf0, 0x5a, 0x5a);
+   dsi_generic_write_seq(dsi, 0xfc, 0x5a, 0x5a);
+   dsi_dcs_write_seq(dsi, 0xf2);
+   dsi_dcs_write_seq(dsi, 0xf9);
+   usleep_range(5000, 6000);
+
+   ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+   if (ret < 0) {
+   dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+   return ret;
+   }
+   msleep(20);
+
+   dsi_generic_write_seq(dsi, 0xca,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80,
+  

[PATCH v2 1/2] dt-bindings: panel: Add Samsung S6E3FA2 panel

2021-02-01 Thread Iskren Chernev
The Samsung S6E3FA2 AMOLED cmd LCD panel is used on the Samsung Galaxy
S5 (klte).

Signed-off-by: Iskren Chernev 
---
OK, miraculously the panel turns on and off now, so the simple-panel can
graduate into its own driver.

v1: https://lkml.org/lkml/2020/12/30/293

Changes in v2:
- move bindings to separate file, add 2 regulators
- add standalone panel driver

 .../display/panel/samsung,s6e3fa2.yaml| 62 +++
 1 file changed, 62 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml 
b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml
new file mode 100644
index ..a759150bd539
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fa2.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fa2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung s6e3fa2 AMOLED CMD LCD panel
+
+maintainers:
+  - Iskren Chernev 
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+const: samsung,s6e3fa2
+
+  reg: true
+  reset-gpios: true
+  port: true
+
+  iovdd-supply:
+description: IOVDD regulator
+
+  vddr-supply:
+description: VDDR regulator
+
+required:
+  - compatible
+  - reset-gpios
+  - iovdd-supply
+  - vddr-supply
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+/* from Samsung Galaxy S5 klte */
+dsi@fd922800 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+panel@0 {
+compatible = "samsung,s6e3fa2";
+reg = <0>;
+
+reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
+
+iovdd-supply = <&pma8084_lvs4>;
+vddr-supply = <&vreg_panel>;
+
+port {
+panel_in: endpoint {
+remote-endpoint = <&dsi0_out>;
+};
+};
+};
+};
+
+...

base-commit: fd821bf0ed9a7db09d2e007df697f4d9ecfda99a
--
2.30.0



[PATCH v4 2/4] ARM: dts: qcom: msm8974-klte: add support for GPU

2021-01-28 Thread Iskren Chernev
From: Samuel Pascua 

Enable adreno dt nodes.

Signed-off-by: Samuel Pascua 
[iskren.cher...@gmail.com: changes after v1]
Signed-off-by: Iskren Chernev 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index f23d1002b8f8b..61e67b7a4a067 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -697,6 +697,10 @@ fuelgauge@36 {
pinctrl-0 = <&fuelgauge_pin>;
};
};
+
+   adreno@fdb0 {
+   status = "ok";
+   };
 };

 &spmi_bus {
--
2.30.0



[PATCH v4 4/4] ARM: dts: qcom: msm8974-klte: Mark essential regulators

2021-01-28 Thread Iskren Chernev
s1 and l12 regulators are used for the memory and cache on the Samsung
S5 (klte). If they are turned off the phone shuts down. So mark them as
always-on to prevent that from happening.

Signed-off-by: Iskren Chernev 
Tested-by: Alexey Minnekhanov 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 2ea9ec432df58..9124b968a197f 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -30,6 +30,7 @@ pma8084-regulators {
pma8084_s1: s1 {
regulator-min-microvolt = 
<675000>;
regulator-max-microvolt = 
<105>;
+   regulator-always-on;
};
 
pma8084_s2: s2 {
@@ -115,6 +116,7 @@ pma8084_l11: l11 {
pma8084_l12: l12 {
regulator-min-microvolt = 
<180>;
regulator-max-microvolt = 
<180>;
+   regulator-always-on;
};
 
pma8084_l13: l13 {
-- 
2.30.0



[PATCH v4 3/4] ARM: dts: qcom: msm8974-klte: add support for display

2021-01-28 Thread Iskren Chernev
From: Samuel Pascua 

Add initial support for the display found on the Samsung Galaxy 5 (klte)
phone. This is based on work from Jonathan Marek & Brian Masney.

Signed-off-by: Samuel Pascua 
Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 61e67b7a4a067..2ea9ec432df58 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -453,6 +453,16 @@ int {
bias-pull-down;
};
};
+
+   panel_pin: panel {
+   te {
+   pins = "gpio12";
+   function = "mdp_vsync";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};

sdhc_1: sdhci@f9824900 {
@@ -701,6 +711,54 @@ fuelgauge@36 {
adreno@fdb0 {
status = "ok";
};
+
+   mdss@fd90 {
+   status = "ok";
+
+   mdp@fd90 {
+   status = "ok";
+   };
+
+   dsi@fd922800 {
+   status = "ok";
+
+   vdda-supply = <&pma8084_l2>;
+   vdd-supply = <&pma8084_l22>;
+   vddio-supply = <&pma8084_l12>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <&panel_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+
+   panel: panel@0 {
+   reg = <0>;
+   compatible = "samsung,s6e3fa2";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&panel_pin>;
+
+   port {
+   panel_in: endpoint {
+   remote-endpoint = <&dsi0_out>;
+   };
+   };
+   };
+   };
+
+   dsi-phy@fd922a00 {
+   status = "ok";
+
+   vddio-supply = <&pma8084_l12>;
+   };
+   };
 };

 &spmi_bus {
--
2.30.0



[PATCH v4 1/4] ARM: dts: qcom: msm8974: add gpu support

2021-01-28 Thread Iskren Chernev
From: Brian Masney 

Add support for the a3xx GPU. opp_table is chosen to include lower
frequencies common to all different msm8974 variants.

Also correctly set gpu compat string on msm8974 and msm8974pro.

Signed-off-by: Brian Masney 
[iskren.cher...@gmail.com: change after v1]
Signed-off-by: Iskren Chernev 
---
Changes in v4:
- change adreno compat string to 330.1 in msm8974 and 330.2 in msm8974pro
- put opp_table node inside gpu node (similar to msm8916)
- fix tabs-whenever-possible lint warning

v3: https://lkml.org/lkml/2021/1/25/398
v2: https://lkml.org/lkml/2021/1/24/142
v1: https://lkml.org/lkml/2020/12/30/322

 arch/arm/boot/dts/qcom-msm8974.dtsi| 43 ++
 arch/arm/boot/dts/qcom-msm8974pro.dtsi |  5 +++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 51f5f904f9eb9..bae9ea3a3b871 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1399,6 +1399,49 @@ cnoc: interconnect@fc48 {
 <&rpmcc RPM_SMD_CNOC_A_CLK>;
};

+   gpu: adreno@fdb0 {
+   status = "disabled";
+
+   compatible = "qcom,adreno-330.1",
+"qcom,adreno";
+   reg = <0xfdb0 0x1>;
+   reg-names = "kgsl_3d0_reg_memory";
+   interrupts = ;
+   interrupt-names = "kgsl_3d0_irq";
+   clock-names = "core",
+ "iface",
+ "mem_iface";
+   clocks = <&mmcc OXILI_GFX3D_CLK>,
+<&mmcc OXILICX_AHB_CLK>,
+<&mmcc OXILICX_AXI_CLK>;
+   sram = <&gmu_sram>;
+   power-domains = <&mmcc OXILICX_GDSC>;
+   operating-points-v2 = <&gpu_opp_table>;
+
+   interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc 
BIMC_SLV_EBI_CH0>,
+   <&ocmemnoc OCMEM_VNOC_MAS_GFX3D 
&ocmemnoc OCMEM_SLV_OCMEM>;
+   interconnect-names = "gfx-mem",
+"ocmem";
+
+   // iommus = <&gpu_iommu 0>;
+
+   gpu_opp_table: opp_table {
+   compatible = "operating-points-v2";
+
+   opp-32000 {
+   opp-hz = /bits/ 64 <32000>;
+   };
+
+   opp-2 {
+   opp-hz = /bits/ 64 <2>;
+   };
+
+   opp-2700 {
+   opp-hz = /bits/ 64 <2700>;
+   };
+   };
+   };
+
mdss: mdss@fd90 {
status = "disabled";

diff --git a/arch/arm/boot/dts/qcom-msm8974pro.dtsi 
b/arch/arm/boot/dts/qcom-msm8974pro.dtsi
index 6740a4cb7da8d..b87de3c3f461a 100644
--- a/arch/arm/boot/dts/qcom-msm8974pro.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974pro.dtsi
@@ -14,5 +14,10 @@ sdhci@f9824900 {
clock-controller@fc40 {
compatible = "qcom,gcc-msm8974pro";
};
+
+   adreno@fdb0 {
+   compatible = "qcom,adreno-330.2",
+"qcom,adreno";
+   };
};
 };

base-commit: 226871e2eda4832d94c3239add7e52ad17b81ce5
--
2.30.0



Re: [PATCH 2/2] drm/panel: simple: add samsung,s6e3fa2 panel

2021-01-28 Thread Iskren Chernev



On 12/30/20 5:17 PM, Iskren Chernev wrote:
> From: Samuel Pascua 
> 
> This panel is used on the Samsung Galaxy S5 (klte).
> 
> Signed-off-by: Samuel Pascua 
> ---
>  drivers/gpu/drm/panel/panel-simple.c | 30 
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c 
> b/drivers/gpu/drm/panel/panel-simple.c
> index 41bbec72b2dad..5f16826f3ae06 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -4611,6 +4611,33 @@ static const struct panel_desc_dsi osd101t2045_53ts = {
>   .lanes = 4,
>  };
> 
> +static const struct drm_display_mode s6e3fa2_mode = {
> + .clock = 149769,
> + .hdisplay = 1080,
> + .hsync_start = 1080 + 162,
> + .hsync_end = 1080 + 162 + 10,
> + .htotal = 1080 + 162 + 10 + 36,
> + .vdisplay = 1920,
> + .vsync_start = 1920 + 13,
> + .vsync_end = 1920 + 13 + 2,
> + .vtotal = 1920 + 13 + 2 + 3,
> +};
> +
> +static const struct panel_desc_dsi samsung_s6e3fa2 = {
> + .desc = {
> + .modes = &s6e3fa2_mode,
> + .num_modes = 1,
> + .bpc = 8,
> + .size = {
> + .width = 65,
> + .height = 115,
> + },
> + },
> + .flags = MIPI_DSI_MODE_VIDEO_BURST,
> + .format = MIPI_DSI_FMT_RGB888,
> + .lanes = 4,
> +};
> +
>  static const struct of_device_id dsi_of_match[] = {
>   {
>   .compatible = "auo,b080uan01",
> @@ -4633,6 +4660,9 @@ static const struct of_device_id dsi_of_match[] = {
>   }, {
>   .compatible = "osddisplays,osd101t2045-53ts",
>   .data = &osd101t2045_53ts
> + }, {
> + .compatible = "samsung,s6e3fa2",
> + .data = &samsung_s6e3fa2

I just want to share some details to avoid issues in the future.

This setup (with simple panel and bindings), works in the sense that the
display shows stuff, after being left on by the bootloader on the Samsung
Galaxy S5 (klte). There is no provisions for turning the screen off and
back on, backlight, or anything else.

The display is a rather advanced one, containing many features, but so far
none of them (including on/off) has been made to work. It is possible that
in the future some of those features will be figured out, and these might
very well include additional DT properties.

So would it be better to put the bindings in a separate file, ready to
grow, and for the panel - include a simple custom driver that works no
better than the simple-panel one now, but can accommodate future expansion?

>   }, {
>   /* sentinel */
>   }
> --
> 2.29.2
> 


[PATCH] drm/msm/mdp5: Fix wait-for-commit for cmd panels

2021-01-27 Thread Iskren Chernev
Before the offending commit in msm_atomic_commit_tail wait_flush was
called once per frame, after the commit was submitted. After it
wait_flush is also called at the beginning to ensure previous
potentially async commits are done.

For cmd panels the source of wait_flush is a ping-pong irq notifying
a completion. The completion needs to be notified with complete_all so
multiple waiting parties (new async committers) can proceed.

Signed-off-by: Iskren Chernev 
Suggested-by: Rob Clark 
Fixes: 2d99ced787e3d ("drm/msm: async commit support")
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 0c8f9f88301fa..f5d71b2740793 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -1180,7 +1180,7 @@ static void mdp5_crtc_pp_done_irq(struct mdp_irq *irq, 
uint32_t irqstatus)
struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc,
pp_done);
 
-   complete(&mdp5_crtc->pp_completion);
+   complete_all(&mdp5_crtc->pp_completion);
 }
 
 static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc)

base-commit: 59fa6a163ffabc1bf25c5e0e33899e268a96d3cc
-- 
2.30.0



Re: [PATCH 1/4] ARM: dts: qcom: msm8974: add gpu support

2021-01-25 Thread Iskren Chernev



On 1/24/21 11:05 PM, Pavel Machek wrote:
> On Sun 2021-01-24 15:56:07, Iskren Chernev wrote:
>> From: Brian Masney 
>>
>> Add support for the a3xx GPU
> 
> This is phone, right? Can I ask phone-de...@vger.kernel.org to be
> cc-ed?

CC-ing phone-de...@vger.kernel.org.

I'm not sure why you didn't do it :-/

>
> Thank you,
>   Pavel
>   
>

Regards,
Iskren


[PATCH v3 2/4] ARM: dts: qcom: msm8974-klte: add support for GPU

2021-01-25 Thread Iskren Chernev
From: Samuel Pascua 

Enable adreno and opp_table dt nodes.

Signed-off-by: Samuel Pascua 
Signed-off-by: Iskren Chernev 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index f23d1002b8f8b..5a7ac4a31031f 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -697,6 +697,14 @@ fuelgauge@36 {
pinctrl-0 = <&fuelgauge_pin>;
};
};
+
+   opp_table {
+   status = "ok";
+   };
+
+   adreno@fdb0 {
+   status = "ok";
+   };
 };

 &spmi_bus {
--
2.30.0



[PATCH v3 1/4] ARM: dts: qcom: msm8974: add gpu support

2021-01-25 Thread Iskren Chernev
From: Brian Masney 

Add support for the a3xx GPU. opp_table is chosen to include lower
frequencies common to all different msm8974 variants.

Signed-off-by: Brian Masney 
[iskren.cher...@gmail.com: change opp-table values in v3]
Signed-off-by: Iskren Chernev 
---
Changes in v3:
- change opp-table as suggested by Konrad Dybcio
- remove tested-by/reviewed-by because of code changes

v2: https://lkml.org/lkml/2021/1/24/142
v1: https://lkml.org/lkml/2020/12/30/322

 arch/arm/boot/dts/qcom-msm8974.dtsi | 45 +
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 51f5f904f9eb9..683622d6c8954 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1399,6 +1399,51 @@ cnoc: interconnect@fc48 {
 <&rpmcc RPM_SMD_CNOC_A_CLK>;
};

+   gpu_opp_table: opp_table {
+   status = "disabled";
+
+   compatible = "operating-points-v2";
+
+   opp-32000 {
+   opp-hz = /bits/ 64 <32000>;
+   };
+
+   opp-2 {
+   opp-hz = /bits/ 64 <2>;
+   };
+
+   opp-2700 {
+   opp-hz = /bits/ 64 <2700>;
+   };
+   };
+
+   gpu: adreno@fdb0 {
+   status = "disabled";
+
+   compatible = "qcom,adreno-330.2",
+"qcom,adreno";
+   reg = <0xfdb0 0x1>;
+   reg-names = "kgsl_3d0_reg_memory";
+   interrupts = ;
+   interrupt-names = "kgsl_3d0_irq";
+   clock-names = "core",
+ "iface",
+ "mem_iface";
+   clocks = <&mmcc OXILI_GFX3D_CLK>,
+<&mmcc OXILICX_AHB_CLK>,
+<&mmcc OXILICX_AXI_CLK>;
+   sram = <&gmu_sram>;
+   power-domains = <&mmcc OXILICX_GDSC>;
+   operating-points-v2 = <&gpu_opp_table>;
+
+   interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc 
BIMC_SLV_EBI_CH0>,
+   <&ocmemnoc OCMEM_VNOC_MAS_GFX3D 
&ocmemnoc OCMEM_SLV_OCMEM>;
+   interconnect-names = "gfx-mem",
+"ocmem";
+
+   // iommus = <&gpu_iommu 0>;
+   };
+
mdss: mdss@fd90 {
status = "disabled";


base-commit: 226871e2eda4832d94c3239add7e52ad17b81ce5
--
2.30.0



[PATCH v3 4/4] ARM: dts: qcom: msm8974-klte: Mark essential regulators

2021-01-25 Thread Iskren Chernev
s1 and l12 regulators are used for the memory and cache on the Samsung
S5 (klte). If they are turned off the phone shuts down. So mark them as
always-on to prevent that from happening.

Signed-off-by: Iskren Chernev 
Tested-by: Alexey Minnekhanov 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 19c96b47a5dbd..27323403aa71d 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -30,6 +30,7 @@ pma8084-regulators {
pma8084_s1: s1 {
regulator-min-microvolt = 
<675000>;
regulator-max-microvolt = 
<105>;
+   regulator-always-on;
};
 
pma8084_s2: s2 {
@@ -115,6 +116,7 @@ pma8084_l11: l11 {
pma8084_l12: l12 {
regulator-min-microvolt = 
<180>;
regulator-max-microvolt = 
<180>;
+   regulator-always-on;
};
 
pma8084_l13: l13 {
-- 
2.30.0



[PATCH v3 3/4] ARM: dts: qcom: msm8974-klte: add support for display

2021-01-25 Thread Iskren Chernev
From: Samuel Pascua 

Add initial support for the display found on the Samsung Galaxy 5 (klte)
phone. This is based on work from Jonathan Marek & Brian Masney.

Signed-off-by: Samuel Pascua 
Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 5a7ac4a31031f..19c96b47a5dbd 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -453,6 +453,16 @@ int {
bias-pull-down;
};
};
+
+   panel_pin: panel {
+   te {
+   pins = "gpio12";
+   function = "mdp_vsync";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};

sdhc_1: sdhci@f9824900 {
@@ -705,6 +715,54 @@ opp_table {
adreno@fdb0 {
status = "ok";
};
+
+   mdss@fd90 {
+   status = "ok";
+
+   mdp@fd90 {
+   status = "ok";
+   };
+
+   dsi@fd922800 {
+   status = "ok";
+
+   vdda-supply = <&pma8084_l2>;
+   vdd-supply = <&pma8084_l22>;
+   vddio-supply = <&pma8084_l12>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <&panel_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+
+   panel: panel@0 {
+   reg = <0>;
+   compatible = "samsung,s6e3fa2";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&panel_pin>;
+
+   port {
+   panel_in: endpoint {
+   remote-endpoint = <&dsi0_out>;
+   };
+   };
+   };
+   };
+
+   dsi-phy@fd922a00 {
+   status = "ok";
+
+   vddio-supply = <&pma8084_l12>;
+   };
+   };
 };

 &spmi_bus {
--
2.30.0



[PATCH 2/4] ARM: dts: qcom: msm8974-klte: add support for GPU

2021-01-24 Thread Iskren Chernev
From: Samuel Pascua 

Enable adreno and opp_table dt nodes.

Signed-off-by: Samuel Pascua 
Signed-off-by: Iskren Chernev 
Tested-by: Alexey Minnekhanov 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index f23d1002b8f8b..5a7ac4a31031f 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -697,6 +697,14 @@ fuelgauge@36 {
pinctrl-0 = <&fuelgauge_pin>;
};
};
+
+   opp_table {
+   status = "ok";
+   };
+
+   adreno@fdb0 {
+   status = "ok";
+   };
 };
 
 &spmi_bus {
-- 
2.30.0



[PATCH 3/4] ARM: dts: qcom: msm8974-klte: add support for display

2021-01-24 Thread Iskren Chernev
From: Samuel Pascua 

Add initial support for the display found on the Samsung Galaxy 5 (klte)
phone. This is based on work from Jonathan Marek & Brian Masney.

Signed-off-by: Samuel Pascua 
Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 5a7ac4a31031f..19c96b47a5dbd 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -453,6 +453,16 @@ int {
bias-pull-down;
};
};
+
+   panel_pin: panel {
+   te {
+   pins = "gpio12";
+   function = "mdp_vsync";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};
 
sdhc_1: sdhci@f9824900 {
@@ -705,6 +715,54 @@ opp_table {
adreno@fdb0 {
status = "ok";
};
+
+   mdss@fd90 {
+   status = "ok";
+
+   mdp@fd90 {
+   status = "ok";
+   };
+
+   dsi@fd922800 {
+   status = "ok";
+
+   vdda-supply = <&pma8084_l2>;
+   vdd-supply = <&pma8084_l22>;
+   vddio-supply = <&pma8084_l12>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <&panel_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+
+   panel: panel@0 {
+   reg = <0>;
+   compatible = "samsung,s6e3fa2";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&panel_pin>;
+
+   port {
+   panel_in: endpoint {
+   remote-endpoint = <&dsi0_out>;
+   };
+   };
+   };
+   };
+
+   dsi-phy@fd922a00 {
+   status = "ok";
+
+   vddio-supply = <&pma8084_l12>;
+   };
+   };
 };
 
 &spmi_bus {
-- 
2.30.0



[PATCH 4/4] ARM: dts: qcom: msm8974-klte: Mark essential regulators

2021-01-24 Thread Iskren Chernev
s1 and l12 regulators are used for the memory and cache on the Samsung
S5 (klte). If they are turned off the phone shuts down. So mark them as
always-on to prevent that from happening.

Signed-off-by: Iskren Chernev 
Tested-by: Alexey Minnekhanov 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 19c96b47a5dbd..27323403aa71d 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -30,6 +30,7 @@ pma8084-regulators {
pma8084_s1: s1 {
regulator-min-microvolt = 
<675000>;
regulator-max-microvolt = 
<105>;
+   regulator-always-on;
};
 
pma8084_s2: s2 {
@@ -115,6 +116,7 @@ pma8084_l11: l11 {
pma8084_l12: l12 {
regulator-min-microvolt = 
<180>;
regulator-max-microvolt = 
<180>;
+   regulator-always-on;
};
 
pma8084_l13: l13 {
-- 
2.30.0



[PATCH 1/4] ARM: dts: qcom: msm8974: add gpu support

2021-01-24 Thread Iskren Chernev
From: Brian Masney 

Add support for the a3xx GPU

Signed-off-by: Brian Masney 
Signed-off-by: Iskren Chernev 
Tested-by: Alexey Minnekhanov 
Reviewed-by: Brian Masney 
---
Changes in v2:
- base set to next-20210122
- add tags from v1 replies
- add Signed-off-by: me on first three patches
- add commit message to 2nd patch

v1: https://lkml.org/lkml/2020/12/30/322

 arch/arm/boot/dts/qcom-msm8974.dtsi | 45 +
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 51f5f904f9eb9..c399446d8154e 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1399,6 +1399,51 @@ cnoc: interconnect@fc48 {
 <&rpmcc RPM_SMD_CNOC_A_CLK>;
};
 
+   gpu_opp_table: opp_table {
+   status = "disabled";
+
+   compatible = "operating-points-v2";
+
+   opp-8 {
+   opp-hz = /bits/ 64 <8>;
+   };
+
+   opp-5 {
+   opp-hz = /bits/ 64 <5>;
+   };
+
+   opp-27500 {
+   opp-hz = /bits/ 64 <27500>;
+   };
+   };
+
+   gpu: adreno@fdb0 {
+   status = "disabled";
+
+   compatible = "qcom,adreno-330.2",
+"qcom,adreno";
+   reg = <0xfdb0 0x1>;
+   reg-names = "kgsl_3d0_reg_memory";
+   interrupts = ;
+   interrupt-names = "kgsl_3d0_irq";
+   clock-names = "core",
+ "iface",
+ "mem_iface";
+   clocks = <&mmcc OXILI_GFX3D_CLK>,
+<&mmcc OXILICX_AHB_CLK>,
+<&mmcc OXILICX_AXI_CLK>;
+   sram = <&gmu_sram>;
+   power-domains = <&mmcc OXILICX_GDSC>;
+   operating-points-v2 = <&gpu_opp_table>;
+
+   interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc 
BIMC_SLV_EBI_CH0>,
+   <&ocmemnoc OCMEM_VNOC_MAS_GFX3D 
&ocmemnoc OCMEM_SLV_OCMEM>;
+   interconnect-names = "gfx-mem",
+"ocmem";
+
+   // iommus = <&gpu_iommu 0>;
+   };
+
mdss: mdss@fd90 {
status = "disabled";
 

base-commit: 226871e2eda4832d94c3239add7e52ad17b81ce5
-- 
2.30.0



Re: [PATCH] drm/msm: Fix MSM_INFO_GET_IOVA with carveout

2021-01-08 Thread Iskren Chernev



On 1/8/21 12:36 AM, Rob Clark wrote:
> On Thu, Jan 7, 2021 at 9:20 AM Rob Clark  wrote:
>>
>> On Sat, Jan 2, 2021 at 12:26 PM Iskren Chernev  
>> wrote:
>>>
>>> The msm_gem_get_iova should be guarded with gpu != NULL and not aspace
>>> != NULL, because aspace is NULL when using vram carveout.
>>>
>>> Fixes: 933415e24bd0d ("drm/msm: Add support for private address space 
>>> instances")
>>>
>>> Signed-off-by: Iskren Chernev 
>>> ---
>>>  drivers/gpu/drm/msm/msm_drv.c | 3 ++-
>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
>>> index c5e61cb3356df..c1953fb079133 100644
>>> --- a/drivers/gpu/drm/msm/msm_drv.c
>>> +++ b/drivers/gpu/drm/msm/msm_drv.c
>>> @@ -775,9 +775,10 @@ static int msm_ioctl_gem_info_iova(struct drm_device 
>>> *dev,
>>> struct drm_file *file, struct drm_gem_object *obj,
>>> uint64_t *iova)
>>>  {
>>> +   struct msm_drm_private *priv = dev->dev_private;
>>> struct msm_file_private *ctx = file->driver_priv;
>>>
>>> -   if (!ctx->aspace)
>>> +   if (!priv->gpu)
>>> return -EINVAL;
>>
>> Does this actually work?  It seems like you would hit a null ptr deref
>> in msm_gem_init_vma().. and in general I think a lot of code paths
>> would be surprised by a null address space, so this seems like a risky
>> idea.
>
> oh, actually, I suppose it is ok, since in the vram carveout case we
> create the vma up front when the gem obj is created..
>
> (still, it does seem a bit fragile.. and easy for folks testing on
> devices not using vram carvout to break.. hmm..)

In _msm_gem_new add_vma is called with NULL, so consequently lookup_vma
finds it when aspace is NULL.

Also, this is how the code was before the "breaking" change, so it should
not be worse.

I'll be happy to work on refactoring this a bit, but some some
documentation about the different gpu/mdp pieces and how they fit together
won't hurt.

Regards,
Iskren

> BR,
> -R
>
>> Maybe instead we should be creating an address space for the vram carveout?
>>
>> BR,
>> -R
>>
>>
>>> /*
>>> --
>>> 2.29.2
>>>


[PATCH] drm/msm: Fix MSM_INFO_GET_IOVA with carveout

2021-01-02 Thread Iskren Chernev
The msm_gem_get_iova should be guarded with gpu != NULL and not aspace
!= NULL, because aspace is NULL when using vram carveout.

Fixes: 933415e24bd0d ("drm/msm: Add support for private address space 
instances")

Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/msm/msm_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c5e61cb3356df..c1953fb079133 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -775,9 +775,10 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
struct drm_file *file, struct drm_gem_object *obj,
uint64_t *iova)
 {
+   struct msm_drm_private *priv = dev->dev_private;
struct msm_file_private *ctx = file->driver_priv;
 
-   if (!ctx->aspace)
+   if (!priv->gpu)
return -EINVAL;
 
/*
-- 
2.29.2



[PATCH 4/4] ARM: dts: qcom: msm8974-klte: Mark essential regulators

2020-12-30 Thread Iskren Chernev
s1 and l12 regulators are used for the memory and cache on the Samsung
S5 (klte). If they are turned off the phone shuts down. So mark them as
always-on to prevent that from happening.

Signed-off-by: Iskren Chernev 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 8b7e95b748e39..7291b858c2c53 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -30,6 +30,7 @@ pma8084-regulators {
pma8084_s1: s1 {
regulator-min-microvolt = 
<675000>;
regulator-max-microvolt = 
<105>;
+   regulator-always-on;
};
 
pma8084_s2: s2 {
@@ -115,6 +116,7 @@ pma8084_l11: l11 {
pma8084_l12: l12 {
regulator-min-microvolt = 
<180>;
regulator-max-microvolt = 
<180>;
+   regulator-always-on;
};
 
pma8084_l13: l13 {
-- 
2.29.2



[PATCH 3/4] ARM: dts: qcom: msm8974-klte: add support for display

2020-12-30 Thread Iskren Chernev
From: Samuel Pascua 

Add initial support for the display found on the Samsung Galaxy 5 (klte)
phone. This is based on work from Jonathan Marek & Brian Masney.

Please note that this patch depends on dt-binding patch in [1]

[1] https://lkml.org/lkml/2020/12/30/293

Signed-off-by: Samuel Pascua 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 58 +++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 1d5e8abdbda79..8b7e95b748e39 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -453,6 +453,16 @@ int {
bias-pull-down;
};
};
+
+   panel_pin: panel {
+   te {
+   pins = "gpio12";
+   function = "mdp_vsync";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};
 
sdhc_1: sdhci@f9824900 {
@@ -705,6 +715,54 @@ opp_table {
adreno@fdb0 {
status = "ok";
};
+
+   mdss@fd90 {
+   status = "ok";
+
+   mdp@fd90 {
+   status = "ok";
+   };
+
+   dsi@fd922800 {
+   status = "ok";
+
+   vdda-supply = <&pma8084_l2>;
+   vdd-supply = <&pma8084_l22>;
+   vddio-supply = <&pma8084_l12>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <&panel_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+
+   panel: panel@0 {
+   reg = <0>;
+   compatible = "samsung,s6e3fa2";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&panel_pin>;
+
+   port {
+   panel_in: endpoint {
+   remote-endpoint = <&dsi0_out>;
+   };
+   };
+   };
+   };
+
+   dsi-phy@fd922a00 {
+   status = "ok";
+
+   vddio-supply = <&pma8084_l12>;
+   };
+   };
 };
 
 &spmi_bus {
-- 
2.29.2



[PATCH 2/4] ARM: dts: qcom: msm8974-klte: add support for GPU

2020-12-30 Thread Iskren Chernev
From: Samuel Pascua 

Signed-off-by: Samuel Pascua 
---
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 97352de913142..1d5e8abdbda79 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -697,6 +697,14 @@ fuelgauge@36 {
pinctrl-0 = <&fuelgauge_pin>;
};
};
+
+   opp_table {
+   status = "ok";
+   };
+
+   adreno@fdb0 {
+   status = "ok";
+   };
 };
 
 &spmi_bus {
-- 
2.29.2



[PATCH 1/4] ARM: dts: qcom: msm8974: add gpu support

2020-12-30 Thread Iskren Chernev
From: Brian Masney 

Add support for the a3xx GPU

Signed-off-by: Brian Masney 
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 45 +
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 51f5f904f9eb9..c399446d8154e 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1399,6 +1399,51 @@ cnoc: interconnect@fc48 {
 <&rpmcc RPM_SMD_CNOC_A_CLK>;
};
 
+   gpu_opp_table: opp_table {
+   status = "disabled";
+
+   compatible = "operating-points-v2";
+
+   opp-8 {
+   opp-hz = /bits/ 64 <8>;
+   };
+
+   opp-5 {
+   opp-hz = /bits/ 64 <5>;
+   };
+
+   opp-27500 {
+   opp-hz = /bits/ 64 <27500>;
+   };
+   };
+
+   gpu: adreno@fdb0 {
+   status = "disabled";
+
+   compatible = "qcom,adreno-330.2",
+"qcom,adreno";
+   reg = <0xfdb0 0x1>;
+   reg-names = "kgsl_3d0_reg_memory";
+   interrupts = ;
+   interrupt-names = "kgsl_3d0_irq";
+   clock-names = "core",
+ "iface",
+ "mem_iface";
+   clocks = <&mmcc OXILI_GFX3D_CLK>,
+<&mmcc OXILICX_AHB_CLK>,
+<&mmcc OXILICX_AXI_CLK>;
+   sram = <&gmu_sram>;
+   power-domains = <&mmcc OXILICX_GDSC>;
+   operating-points-v2 = <&gpu_opp_table>;
+
+   interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc 
BIMC_SLV_EBI_CH0>,
+   <&ocmemnoc OCMEM_VNOC_MAS_GFX3D 
&ocmemnoc OCMEM_SLV_OCMEM>;
+   interconnect-names = "gfx-mem",
+"ocmem";
+
+   // iommus = <&gpu_iommu 0>;
+   };
+
mdss: mdss@fd90 {
status = "disabled";
 

base-commit: d7a03a44a5e93f39ece70ec75d25c6088caa0fdb
prerequisite-patch-id: aba6f684932cab35d98457c21e4ff7a5ac75c753
prerequisite-patch-id: 4884d57df1bd197896b69e115d9002d6c26ae2e2
prerequisite-patch-id: 4f1aba3c3675236b18578eedbe71b0cdca01ed77
prerequisite-patch-id: cbfe6ccfebb142370baff15bbdf3cf2f34ee77df
-- 
2.29.2



[PATCH 1/2] drm/msm: Call msm_init_vram before binding the gpu

2020-12-30 Thread Iskren Chernev
From: Craig Tatlor 

vram.size is needed when binding a gpu without an iommu and is defined
in msm_init_vram(), so run that before binding it.

Signed-off-by: Craig Tatlor 
---
 drivers/gpu/drm/msm/msm_drv.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 535a0263ceeb4..108c405e03dd9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -457,14 +457,14 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
 
drm_mode_config_init(ddev);
 
-   /* Bind all our sub-components: */
-   ret = component_bind_all(dev, ddev);
+   ret = msm_init_vram(ddev);
if (ret)
goto err_destroy_mdss;
 
-   ret = msm_init_vram(ddev);
+   /* Bind all our sub-components: */
+   ret = component_bind_all(dev, ddev);
if (ret)
-   goto err_msm_uninit;
+   goto err_destroy_mdss;
 
dma_set_max_seg_size(dev, UINT_MAX);
 

base-commit: d7a03a44a5e93f39ece70ec75d25c6088caa0fdb
prerequisite-patch-id: aba6f684932cab35d98457c21e4ff7a5ac75c753
prerequisite-patch-id: 4884d57df1bd197896b69e115d9002d6c26ae2e2
-- 
2.29.2



[PATCH 2/2] drm/msm: Add modparam to allow vram carveout

2020-12-30 Thread Iskren Chernev
Using the GPU with a VRAM Carveout is a security vulnerability.
Nevertheless it is sometimes required, especially when no IOMMU
implementation is available for a certain platform.

Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/msm/adreno/a2xx_gpu.c  | 6 --
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c  | 6 --
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c  | 6 --
 drivers/gpu/drm/msm/adreno/adreno_device.c | 4 
 drivers/gpu/drm/msm/adreno/adreno_gpu.h| 1 +
 5 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
index 7e82c41a85f1a..bdc989183c648 100644
--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
@@ -534,8 +534,10 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
 
if (!gpu->aspace) {
dev_err(dev->dev, "No memory protection without MMU\n");
-   ret = -ENXIO;
-   goto fail;
+   if (!allow_vram_carveout) {
+   ret = -ENXIO;
+   goto fail;
+   }
}
 
return gpu;
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 93da6683a8661..4534633fe7cdb 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -564,8 +564,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
 * implement a cmdstream validator.
 */
DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n");
-   ret = -ENXIO;
-   goto fail;
+   if (!allow_vram_carveout) {
+   ret = -ENXIO;
+   goto fail;
+   }
}
 
icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem");
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index c0be3a0f36b2c..82bebb40234de 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -692,8 +692,10 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
 * implement a cmdstream validator.
 */
DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n");
-   ret = -ENXIO;
-   goto fail;
+   if (!allow_vram_carveout) {
+   ret = -ENXIO;
+   goto fail;
+   }
}
 
icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem");
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 87c8b033ad1a6..12e75ba360f95 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -18,6 +18,10 @@ bool snapshot_debugbus = false;
 MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU 
devcoredump (if not fused off)");
 module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600);
 
+bool allow_vram_carveout = false;
+MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of 
IOMMU");
+module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600);
+
 static const struct adreno_info gpulist[] = {
{
.rev   = ADRENO_REV(2, 0, 0, 0),
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index c3775f79525a7..fe5444a1482ae 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -18,6 +18,7 @@
 #include "adreno_pm4.xml.h"
 
 extern bool snapshot_debugbus;
+extern bool allow_vram_carveout;
 
 enum {
ADRENO_FW_PM4 = 0,
-- 
2.29.2



[PATCH 2/2] drm/panel: simple: add samsung,s6e3fa2 panel

2020-12-30 Thread Iskren Chernev
From: Samuel Pascua 

This panel is used on the Samsung Galaxy S5 (klte).

Signed-off-by: Samuel Pascua 
---
 drivers/gpu/drm/panel/panel-simple.c | 30 
 1 file changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 41bbec72b2dad..5f16826f3ae06 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -4611,6 +4611,33 @@ static const struct panel_desc_dsi osd101t2045_53ts = {
.lanes = 4,
 };

+static const struct drm_display_mode s6e3fa2_mode = {
+   .clock = 149769,
+   .hdisplay = 1080,
+   .hsync_start = 1080 + 162,
+   .hsync_end = 1080 + 162 + 10,
+   .htotal = 1080 + 162 + 10 + 36,
+   .vdisplay = 1920,
+   .vsync_start = 1920 + 13,
+   .vsync_end = 1920 + 13 + 2,
+   .vtotal = 1920 + 13 + 2 + 3,
+};
+
+static const struct panel_desc_dsi samsung_s6e3fa2 = {
+   .desc = {
+   .modes = &s6e3fa2_mode,
+   .num_modes = 1,
+   .bpc = 8,
+   .size = {
+   .width = 65,
+   .height = 115,
+   },
+   },
+   .flags = MIPI_DSI_MODE_VIDEO_BURST,
+   .format = MIPI_DSI_FMT_RGB888,
+   .lanes = 4,
+};
+
 static const struct of_device_id dsi_of_match[] = {
{
.compatible = "auo,b080uan01",
@@ -4633,6 +4660,9 @@ static const struct of_device_id dsi_of_match[] = {
}, {
.compatible = "osddisplays,osd101t2045-53ts",
.data = &osd101t2045_53ts
+   }, {
+   .compatible = "samsung,s6e3fa2",
+   .data = &samsung_s6e3fa2
}, {
/* sentinel */
}
--
2.29.2



[PATCH 1/2] dt-bindings: panel-simple: add samsung,s6e3fa2 panel

2020-12-30 Thread Iskren Chernev
Add samsung,s6e3fa2 in the allowed simple-panel compat strings.

Signed-off-by: Iskren Chernev 
---
 .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 27fffafe5b5c0..52480ca230c7b 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -241,6 +241,8 @@ properties:
   - samsung,ltn101nt05
 # Samsung Electronics 14" WXGA (1366x768) TFT LCD panel
   - samsung,ltn140at29-301
+# Samsung Electronics 5.1" (1920x1080) AMOLED cmd panel
+  - samsung,s6e3fa2
 # Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel
   - satoz,sat050at40h12r2
 # Sharp LQ035Q7DB03 3.5" QVGA TFT LCD panel

base-commit: d7a03a44a5e93f39ece70ec75d25c6088caa0fdb
-- 
2.29.2



[PATCH 2/2] drm/msm: Ensure get_pages is called when locked

2020-12-28 Thread Iskren Chernev
get_pages is only called in a locked context. Add a WARN_ON to make sure
it stays that way.

Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/msm/msm_gem.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index c658deb31eb5d..9d10739c4eb2d 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -96,6 +96,8 @@ static struct page **get_pages(struct drm_gem_object *obj)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
 
+   WARN_ON(!msm_gem_is_locked(obj));
+
if (!msm_obj->pages) {
struct drm_device *dev = obj->dev;
struct page **p;
@@ -1129,8 +1131,9 @@ static struct drm_gem_object *_msm_gem_new(struct 
drm_device *dev,
 
to_msm_bo(obj)->vram_node = &vma->node;
 
-
+   msm_gem_lock(obj);
pages = get_pages(obj);
+   msm_gem_unlock(obj);
if (IS_ERR(pages)) {
ret = PTR_ERR(pages);
goto fail;
-- 
2.29.2



[PATCH 1/2] drm/msm: Fix null dereference in _msm_gem_new

2020-12-28 Thread Iskren Chernev
The crash was caused by locking an uninitialized lock during init of
drm_gem_object. The lock changed in the breaking commit, but the init
was not moved accordingly.

 8<--- cut here ---
 Unable to handle kernel NULL pointer dereference at virtual address 
 pgd = (ptrval)
 [] *pgd=
 Internal error: Oops: 5 [#1] PREEMPT SMP ARM
 Modules linked in: msm(+) qcom_spmi_vadc qcom_vadc_common dm_mod usb_f_rndis 
rmi_i2c rmi_core qnoc_msm8974 icc_smd_rpm pm8941_pwrkey
 CPU: 2 PID: 1020 Comm: udevd Not tainted 5.10.0-postmarketos-qcom-msm8974 #8
 Hardware name: Generic DT based system
 PC is at ww_mutex_lock+0x20/0xb0
 LR is at _msm_gem_new+0x13c/0x298 [msm]
 pc : []lr : []psr: 2013
 sp : c36e7ad0  ip : c3b3d800  fp : 
 r10: 0001  r9 : c3b22800  r8 : 
 r7 : c3b23000  r6 : c3b3d600  r5 : c3b3d600  r4 : 
 r3 : c34b4780  r2 : c3b3d6f4  r1 :   r0 : 
 Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
 Control: 10c5787d  Table: 03ae406a  DAC: 0051
 Process udevd (pid: 1020, stack limit = 0x(ptrval))
 Stack: (0xc36e7ad0 to 0xc36e8000)
 [...]
 [] (ww_mutex_lock) from [] (_msm_gem_new+0x13c/0x298 [msm])
 [] (_msm_gem_new [msm]) from [] 
(_msm_gem_kernel_new+0x20/0x190 [msm])
 [] (_msm_gem_kernel_new [msm]) from [] 
(msm_gem_kernel_new+0x24/0x2c [msm])
 [] (msm_gem_kernel_new [msm]) from [] 
(msm_gpu_init+0x308/0x548 [msm])
 [] (msm_gpu_init [msm]) from [] 
(adreno_gpu_init+0x13c/0x240 [msm])
 [] (adreno_gpu_init [msm]) from [] 
(a3xx_gpu_init+0x78/0x1dc [msm])
 [] (a3xx_gpu_init [msm]) from [] (adreno_bind+0x1cc/0x274 
[msm])
 [] (adreno_bind [msm]) from [] 
(component_bind_all+0x11c/0x278)
 [] (component_bind_all) from [] (msm_drm_bind+0x18c/0x5b4 
[msm])
 [] (msm_drm_bind [msm]) from [] 
(try_to_bring_up_master+0x200/0x2c8)
 [] (try_to_bring_up_master) from [] 
(component_master_add_with_match+0xc8/0xfc)
 [] (component_master_add_with_match) from [] 
(msm_pdev_probe+0x288/0x2c4 [msm])
 [] (msm_pdev_probe [msm]) from [] 
(platform_drv_probe+0x48/0x98)
 [] (platform_drv_probe) from [] (really_probe+0x108/0x528)
 [] (really_probe) from [] (driver_probe_device+0x78/0x1d4)
 [] (driver_probe_device) from [] 
(device_driver_attach+0xa8/0xb0)
 [] (device_driver_attach) from [] 
(__driver_attach+0xb4/0x154)
 [] (__driver_attach) from [] (bus_for_each_dev+0x78/0xb8)
 [] (bus_for_each_dev) from [] (bus_add_driver+0x10c/0x208)
 [] (bus_add_driver) from [] (driver_register+0x88/0x118)
 [] (driver_register) from [] (do_one_initcall+0x50/0x2b0)
 [] (do_one_initcall) from [] (do_init_module+0x60/0x288)
 [] (do_init_module) from [] (sys_finit_module+0xd4/0x120)
 [] (sys_finit_module) from [] (ret_fast_syscall+0x0/0x54)
 Exception stack(0xc36e7fa8 to 0xc36e7ff0)
 7fa0:   0002  0007 b6edd5b0  b6f2ff20
 7fc0: 0002  017b 017b b6eef980 bedc3a54 00473c99 
 7fe0: b6edd5b0 bedc3918 b6ed8a5f b6f6a8b0
 Code: e3c3303f e593300c e1a04000 f590f000 (e1940f9f)
 ---[ end trace 277e2a3da40bbb76 ]---

Fixes: 6c0e3ea250476 ("drm/msm/gem: Switch over to obj->resv for locking")
Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/msm/msm_gem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 32d5c514e28ad..c658deb31eb5d 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1116,6 +1116,8 @@ static struct drm_gem_object *_msm_gem_new(struct 
drm_device *dev,
struct msm_gem_vma *vma;
struct page **pages;
 
+   drm_gem_private_object_init(dev, obj, size);
+
msm_gem_lock(obj);
 
vma = add_vma(obj, NULL);
@@ -1127,7 +1129,6 @@ static struct drm_gem_object *_msm_gem_new(struct 
drm_device *dev,
 
to_msm_bo(obj)->vram_node = &vma->node;
 
-   drm_gem_private_object_init(dev, obj, size);
 
pages = get_pages(obj);
if (IS_ERR(pages)) {

base-commit: d7a03a44a5e93f39ece70ec75d25c6088caa0fdb
-- 
2.29.2



Re: [RFC 18/18] power: supply: max17040: Do not enforce (incorrect) interrupt trigger type

2020-12-11 Thread Iskren Chernev



On 12/11/20 9:47 AM, Krzysztof Kozlowski wrote:
> On Thu, Dec 10, 2020 at 10:25:34PM +0100, Krzysztof Kozlowski wrote:
>> Interrupt line can be configured on different hardware in different way,
>> even inverted.  Therefore driver should not enforce specific trigger
>> type - edge falling - but instead rely on Devicetree to configure it.
>>
>> The Maxim 14577/77836 datasheets describe the interrupt line as active
>> low with a requirement of acknowledge from the CPU therefore the edge
>> falling is not correct.
>>
>> Signed-off-by: Krzysztof Kozlowski 
>>
>> ---
>>
>> This patch should wait till DTS changes are merged, as it relies on
>> proper Devicetree.
>> ---
>> .../devicetree/bindings/power/supply/max17040_battery.txt   | 2 +-
>> drivers/power/supply/max17040_battery.c | 2 +-
>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt

>> index c802f664b508..194eb9fe574d 100644
>> --- 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> +++ 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt

>> @@ -39,7 +39,7 @@ Example:
>>          reg = <0x36>;
>>          maxim,alert-low-soc-level = <10>;
>>          interrupt-parent = <&gpio7>;
>> -        interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
>> +        interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
>>          wakeup-source;
>>      };
>>
>> diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c

>> index d956c67d5155..f737de0470de 100644
>> --- a/drivers/power/supply/max17040_battery.c
>> +++ b/drivers/power/supply/max17040_battery.c
>> @@ -367,7 +367,7 @@ static int max17040_enable_alert_irq(struct 
max17040_chip *chip)

>>
>>      flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
>
> This has to be removed. I will fix it in v2.
>
> Best regards,
> Krzysztof

I removed the IRQF_TRIGGER_FALLING, tweaked the DT as per the DT patch, and
it worked on the samsung klte.

I don't understand how the DT irq flag ends up being used by the kernel. It
is never explicitly read from DT or passed to interrupt API, only i2c->irq,
which is a pure int.

Fixing the DT and the drivers will hopefully set a precedent, so future
drivers (when copied/tweaked from existing drivers) will do it right.

Acked-by: Iskren Chernev 

>>      ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
>> -                    max17040_thread_handler, flags,
>> +                    max17040_thread_handler, IRQF_ONESHOT,
>>                      chip->battery->desc->name, chip);
>>
>>      return ret;
>> --
>> 2.25.1
>>



Re: [PATCH 11/18] ARM: dts: qcom: msm8974-lge-nexus5: correct fuel gauge interrupt trigger level

2020-12-11 Thread Iskren Chernev



On 12/10/20 11:25 PM, Krzysztof Kozlowski wrote:
> The Maxim fuel gauge datasheets describe the interrupt line as active
> low with a requirement of acknowledge from the CPU.  The falling edge
> interrupt will mostly work but it's not correct.
>
> Fixes: 45dfa741df86 ("ARM: dts: qcom: msm8974-lge-nexus5: Add fuel 
gauge")

> Signed-off-by: Krzysztof Kozlowski 
> ---
>  arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts 
b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts

> index e769f638f205..4c6f54aa9f66 100644
> --- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
> +++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
> @@ -575,7 +575,7 @@ fuelgauge: max17048@36 {
>              maxim,rcomp = /bits/ 8 <0x4d>;
>
>              interrupt-parent = <&msmgpio>;
> -            interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
> +            interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
>
>              pinctrl-names = "default";
>              pinctrl-0 = <&fuelgauge_pin>;

According to the datasheet for max17048 the ALRT pin is active low, so that
looks good. The reason it was implemented EDGE_FALLING is mostly due to
fragments taken from downstream, and the fact that it worked :)

Acked-by: Iskren Chernev 



Re: [PATCH 12/18] ARM: dts: qcom: msm8974-samsung-klte: correct fuel gauge interrupt trigger level

2020-12-11 Thread Iskren Chernev



On 12/10/20 11:25 PM, Krzysztof Kozlowski wrote:
> The Maxim fuel gauge datasheets describe the interrupt line as active
> low with a requirement of acknowledge from the CPU.  The falling edge
> interrupt will mostly work but it's not correct.
>
> Fixes: da8d46992e67 ("ARM: dts: qcom: msm8974-klte: Add fuel gauge")
> Signed-off-by: Krzysztof Kozlowski 
> ---
>  arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts

> index 97352de91314..64a3fdb79539 100644
> --- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
> +++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
> @@ -691,7 +691,7 @@ fuelgauge@36 {
>              maxim,rcomp = /bits/ 8 <0x56>;
>
>              interrupt-parent = <&pma8084_gpios>;
> -            interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
> +            interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
>
>              pinctrl-names = "default";
>              pinctrl-0 = <&fuelgauge_pin>;

After testing this patch + the rfc modifying 17040 driver I can confirm it
works on the klte. Also, according to the max17048 datasheet, the ALRT pin
is active low, so everything is in order.

Acked-By: Iskren Chernev 
Tested-By: Iskren Chernev 



Re: [PATCH] drm/msm: Fix WARN_ON() splat in _free_object()

2020-12-10 Thread Iskren Chernev



On 12/10/20 7:40 PM, Rob Clark wrote:
> From: Rob Clark 
>
> [  192.062000] [ cut here ]
> [  192.062498] WARNING: CPU: 3 PID: 2039 at 
drivers/gpu/drm/msm/msm_gem.c:381 put_iova_vmas+0x94/0xa0 [msm]
> [  192.062870] Modules linked in: snd_hrtimer snd_seq snd_seq_device 
rfcomm algif_hash algif_skcipher af_alg bnep xt_CHECKSUM nft_chain_nat 
xt_MASQUERADE nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 
nft_counter xt_tcpudp nft_compat cpufreq_powersave cpufreq_conservative 
q6asm_dai q6routing q6afe_dai q6adm bridge q6afe q6asm q6dsp_common 
q6core stp llc nf_tables libcrc32c nfnetlink snd_soc_wsa881x regmap_sdw 
soundwire_qcom gpio_wcd934x snd_soc_wcd934x wcd934x regmap_slimbus 
venus_enc venus_dec apr videobuf2_dma_sg qrtr_smd uvcvideo 
videobuf2_vmalloc videobuf2_memops ath10k_snoc ath10k_core hci_uart 
btqca btbcm mac80211 bluetooth snd_soc_sdm845 ath snd_soc_rt5663 
snd_soc_qcom_common snd_soc_rl6231 soundwire_bus ecdh_generic ecc 
qcom_spmi_adc5 venus_core qcom_pon qcom_spmi_temp_alarm qcom_vadc_common 
v4l2_mem2mem videobuf2_v4l2 cfg80211 videobuf2_common hid_multitouch 
reset_qcom_pdc qcrypto qcom_rng rfkill qcom_q6v5_mss libarc4 libdes qrtr 
ns qcom_wdt socinfo slim_qcom_ngd_ctrl
> [  192.065739]  pdr_interface qcom_q6v5_pas slimbus qcom_pil_info 
qcom_q6v5 qcom_sysmon qcom_common qcom_glink_smem qmi_helpers rmtfs_mem 
tcp_bbr sch_fq fuse ip_tables x_tables ipv6 crc_ccitt ti_sn65dsi86 
i2c_hid msm mdt_loader llcc_qcom rtc_pm8xxx ocmem drm_kms_helper 
crct10dif_ce phy_qcom_qusb2 i2c_qcom_geni panel_simple drm pwm_bl
> [  192.066066] CPU: 3 PID: 2039 Comm: gnome-shell Tainted: G    
W 5.10.0-rc7-next-20201208 #1
> [  192.066068] Hardware name: LENOVO 81JL/LNVNB161216, BIOS 
9UCN33WW(V2.06) 06/ 4/2019

> [  192.066072] pstate: 4045 (nZcv daif +PAN -UAO -TCO BTYPE=--)
> [  192.066099] pc : put_iova_vmas+0x94/0xa0 [msm]
> [  192.066262] lr : put_iova_vmas+0x1c/0xa0 [msm]
> [  192.066403] sp : 800019efbbb0
> [  192.066405] x29: 800019efbbb0 x28: 800019efbd88
> [  192.066411] x27:  x26: 109582efa400
> [  192.066417] x25: 0009 x24: 012b
> [  192.066422] x23: 109582efa438 x22: 109582efa450
> [  192.066427] x21: 109582efa528 x20: 1095cbd4f200
> [  192.066432] x19: 1095cbd4f200 x18: 
> [  192.066438] x17:  x16: c26c200ca750
> [  192.066727] x15:  x14: 
> [  192.066741] x13: 1096fb8c9100 x12: 0002
> [  192.066754] x11:  x10: 0002
> [  192.067046] x9 : 0001 x8 : 0a36
> [  192.067060] x7 : 4e2ad9f11000 x6 : c26c216d4000
> [  192.067212] x5 : c26c2022661c x4 : 1095c2b98000
> [  192.067367] x3 : 1095cbd4f300 x2 : 
> [  192.067380] x1 : 1095c2b98000 x0 : 
> [  192.067667] Call trace:
> [  192.067734]  put_iova_vmas+0x94/0xa0 [msm]
> [  192.068078]  msm_gem_free_object+0xb4/0x110 [msm]
> [  192.068399]  drm_gem_object_free+0x1c/0x30 [drm]
> [  192.068717]  drm_gem_object_handle_put_unlocked+0xf0/0xf8 [drm]
> [  192.069032]  drm_gem_object_release_handle+0x6c/0x88 [drm]
> [  192.069349]  drm_gem_handle_delete+0x68/0xc0 [drm]
> [  192.069666]  drm_gem_close_ioctl+0x30/0x48 [drm]
> [  192.069984]  drm_ioctl_kernel+0xc0/0x110 [drm]
> [  192.070303]  drm_ioctl+0x210/0x440 [drm]
> [  192.070588]  __arm64_sys_ioctl+0xa8/0xf0
> [  192.070599]  el0_svc_common.constprop.0+0x74/0x190
> [  192.070608]  do_el0_svc+0x24/0x90
> [  192.070618]  el0_svc+0x14/0x20
> [  192.070903]  el0_sync_handler+0xb0/0xb8
> [  192.070911]  el0_sync+0x174/0x180
> [  192.070918] ---[ end trace bee6b12a899001a3 ]---
> [  192.072140] [ cut here ]
>
> Fixes: 9b73bde39cf2 ("drm/msm: Fix use-after-free in msm_gem with 
carveout")

> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_gem.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_gem.c 
b/drivers/gpu/drm/msm/msm_gem.c

> index 68a6c7eacc0a..a21be5b910ff 100644
> --- a/drivers/gpu/drm/msm/msm_gem.c
> +++ b/drivers/gpu/drm/msm/msm_gem.c
> @@ -990,6 +990,8 @@ void msm_gem_free_object(struct drm_gem_object *obj)
>          if (msm_obj->pages)
>              kvfree(msm_obj->pages);
>
> +        put_iova_vmas(obj);
> +
>          /* dma_buf_detach() grabs resv lock, so we need to unlock
>           * prior to drm_prime_gem_destroy
>           */
> @@ -999,11 +1001,10 @@ void msm_gem_free_object(struct drm_gem_object 
*obj)

>      } else {
>          msm_gem_vunmap(obj);
>          put_pages(obj);
> +        put_iova_vmas(obj);
>          msm_gem_unlock(obj);
>      }
>
> -    put_iova_vmas(obj);
> -
>      drm_gem_object_release(obj);
>
>      kfree(msm_obj);

Ah, the put_iova_vmas needs to happen inside the msm_gem_lock|unlock.
My bad!

Acked-by: Iskren Chernev 



Re: linux-next: Fixes tag needs some work in the drm-msm tree

2020-12-06 Thread Iskren Chernev

On 12/6/20 10:05 PM, Stephen Rothwell wrote:
> Hi all,
>
> In commit
>
>   9b73bde39cf2 ("drm/msm: Fix use-after-free in msm_gem with carveout")
>
> Fixes tag
>
>   Fixes: 4b85f7f5cf7 ("drm/msm: support for an arbitrary number of 
address spaces")

>
> has these problem(s):
>
>   - SHA1 should be at least 12 digits long
>
> In the furture, this can be avoided by setting core.abbrev to 12 (or 
more)

> or (for git v2.11 or later) just making sure it is not set (or set to
> "auto").

I'm sorry, I copied and truncated the hash by hand. I should have used

    git log --pretty=reference

Also scripts/checkpatch.pl didn't notice it. Should I submit v3 of the
patch or it's too late.

Regards,
Iskren



[PATCH 2/2] ARM: dts: qcom: msm8974-lge-nexus5: Add fuel gauge

2020-11-26 Thread Iskren Chernev
The LG Nexus 5 uses a maxim17048 fuelgauge. The maxim,rcomp value is
taken from downstream dt. Temperature-based compensation is not yet
supported in the mainline driver, but the readings seem fine nevertheless.

Signed-off-by: Iskren Chernev 
Tested-by: Nícolas F. R. A. Prado 
---
 .../qcom-msm8974-lge-nexus5-hammerhead.dts| 25 +++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts 
b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
index 32b474bfeec32..e769f638f2052 100644
--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
@@ -566,6 +566,22 @@ charger: bq24192@6b {
 
usb_otg_vbus: usb-otg-vbus { };
};
+
+   fuelgauge: max17048@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+
+   maxim,double-soc;
+   maxim,rcomp = /bits/ 8 <0x4d>;
+
+   interrupt-parent = <&msmgpio>;
+   interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&fuelgauge_pin>;
+
+   maxim,alert-low-soc-level = <2>;
+   };
};
 
i2c@f9924000 {
@@ -706,6 +722,15 @@ gpio_keys_pin_a: gpio-keys-active {
power-source = ;
};
 
+   fuelgauge_pin: fuelgauge-int {
+   pins = "gpio9";
+   function = "normal";
+
+   bias-disable;
+   input-enable;
+   power-source = ;
+   };
+
wlan_sleep_clk_pin: wl-sleep-clk {
pins = "gpio16";
function = "func2";
-- 
2.29.2



[PATCH 1/2] ARM: dts: qcom: msm8974-klte: Add fuel gauge

2020-11-26 Thread Iskren Chernev
The Samsung Galaxy S5 uses a maxim17048 fuelgauge. The maxim,rcomp value
is taken from downstream kernel. Model data and temperature-based
compensation are not yet supported in the mainline driver, but the
readings seem fine nevertheless.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 39 +++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index b0899107f3ced..97352de913142 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -406,6 +406,16 @@ mux {
};
};
 
+   i2c12_pins: i2c12 {
+   mux {
+   pins = "gpio87", "gpio88";
+   function = "blsp_i2c12";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
+
i2c_touchkey_pins: i2c-touchkey {
mux {
pins = "gpio95", "gpio96";
@@ -666,6 +676,27 @@ max77826_buckboost: BUCKBOOST {
};
};
};
+
+   i2c@f9968000 {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c12_pins>;
+
+   fuelgauge@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+
+   maxim,double-soc;
+   maxim,rcomp = /bits/ 8 <0x56>;
+
+   interrupt-parent = <&pma8084_gpios>;
+   interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&fuelgauge_pin>;
+   };
+   };
 };
 
 &spmi_bus {
@@ -703,6 +734,14 @@ wlan_sleep_clk_pin: wlan-sleep-clk-pin {
power-source = ;
qcom,drive-strength = ;
};
+
+   fuelgauge_pin: fuelgauge-int-pin {
+   pins = "gpio21";
+   function = "normal";
+   bias-disable;
+   input-enable;
+   power-source = ;
+   };
};
};
 };

base-commit: 6147c83fd749d19a0d3ccc2f64d12138ab010b47
-- 
2.29.2



[PATCH v2] drm/msm: Fix use-after-free in msm_gem with carveout

2020-11-26 Thread Iskren Chernev
When using gem with vram carveout the page allocation is managed via
drm_mm. The necessary drm_mm_node is allocated in add_vma, but it is
referenced in msm_gem_object as well. It is freed before the drm_mm_node
has been deallocated leading to use-after-free on every single vram
allocation.

Currently put_iova is called before put_pages in both
msm_gem_free_object and msm_gem_purge:

put_iova -> del_vma -> kfree(vma) // vma holds drm_mm_node
/* later */
put_pages -> put_pages_vram -> drm_mm_remove_node(
msm_obj->vram_node)
// vram_node is a ref to
// drm_mm_node; in _msm_gem_new

It looks like del_vma does nothing else other than freeing the vma
object and removing it from it's list, so delaying the deletion should
be harmless.

This patch splits put_iova in put_iova_spaces and put_iova_vmas, so the
vma can be freed after the mm_node has been deallocated with the mm.

Note: The breaking commit separated the vma allocation from within
msm_gem_object to outside, so the vram_node reference became outside the
msm_gem_object allocation, and freeing order was therefore overlooked.

Fixes: 4b85f7f5cf7 ("drm/msm: support for an arbitrary number of address 
spaces")
Signed-off-by: Iskren Chernev 
---
v1: https://lkml.org/lkml/2020/11/26/130

Changes in v2:
- patch now compiles (oops)
- improve commit message
- add fixes tag

 drivers/gpu/drm/msm/msm_gem.c | 27 ++-
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 15715a156620f..dfe6387c62c86 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -355,18 +355,31 @@ static void del_vma(struct msm_gem_vma *vma)

 /* Called with msm_obj locked */
 static void
-put_iova(struct drm_gem_object *obj)
+put_iova_spaces(struct drm_gem_object *obj)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
-   struct msm_gem_vma *vma, *tmp;
+   struct msm_gem_vma *vma;

WARN_ON(!msm_gem_is_locked(obj));

-   list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) {
+   list_for_each_entry(vma, &msm_obj->vmas, list) {
if (vma->aspace) {
msm_gem_purge_vma(vma->aspace, vma);
msm_gem_close_vma(vma->aspace, vma);
}
+   }
+}
+
+/* Called with msm_obj locked */
+static void
+put_iova_vmas(struct drm_gem_object *obj)
+{
+   struct msm_gem_object *msm_obj = to_msm_bo(obj);
+   struct msm_gem_vma *vma, *tmp;
+
+   WARN_ON(!msm_gem_is_locked(obj));
+
+   list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) {
del_vma(vma);
}
 }
@@ -688,12 +701,14 @@ void msm_gem_purge(struct drm_gem_object *obj)
WARN_ON(!is_purgeable(msm_obj));
WARN_ON(obj->import_attach);

-   put_iova(obj);
+   put_iova_spaces(obj);

msm_gem_vunmap(obj);

put_pages(obj);

+   put_iova_vmas(obj);
+
msm_obj->madv = __MSM_MADV_PURGED;

drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
@@ -942,7 +957,7 @@ void msm_gem_free_object(struct drm_gem_object *obj)

msm_gem_lock(obj);

-   put_iova(obj);
+   put_iova_spaces(obj);

if (obj->import_attach) {
WARN_ON(msm_obj->vaddr);
@@ -965,6 +980,8 @@ void msm_gem_free_object(struct drm_gem_object *obj)
msm_gem_unlock(obj);
}

+   put_iova_vmas(obj);
+
drm_gem_object_release(obj);

kfree(msm_obj);

base-commit: 6147c83fd749d19a0d3ccc2f64d12138ab010b47
--
2.29.2



[PATCH] drm/msm: Fix use-after-free in msm_gem with carveout

2020-11-26 Thread Iskren Chernev
When using gem with vram carveout the page allocation is managed via
drm_mm. The necessary drm_mm_node is allocated in add_vma, but it freed
before the drm_mm_node has been deallocated leading to use-after-free on
every single vram allocation.

Currently put_iova is called before free_object.

put_iova -> del_vma -> kfree(vma) // vma holds drm_mm_node

free_object -> put_pages -> put_pages_vram
 -> drm_mm_remove_node

It looks like del_vma does nothing else other than freeing the vma
object and removing it from it's list, so delaying the deletion should
be harmless.

This patch splits put_iova in put_iova_spaces and put_iova_vmas, so the
vma can be freed after the mm_node has been deallocated with the mm.

Signed-off-by: Iskren Chernev 
---
 drivers/gpu/drm/msm/msm_gem.c | 27 ++-
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 15715a156620f..b83247202ea5d 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -355,18 +355,31 @@ static void del_vma(struct msm_gem_vma *vma)
 
 /* Called with msm_obj locked */
 static void
-put_iova(struct drm_gem_object *obj)
+put_iova_spaces(struct drm_gem_object *obj)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
-   struct msm_gem_vma *vma, *tmp;
+   struct msm_gem_vma *vma;
 
WARN_ON(!msm_gem_is_locked(obj));
 
-   list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) {
+   list_for_each_entry(vma, &msm_obj->vmas, list) {
if (vma->aspace) {
msm_gem_purge_vma(vma->aspace, vma);
msm_gem_close_vma(vma->aspace, vma);
}
+   }
+}
+
+/* Called with msm_obj locked */
+static void
+put_iova_vmas(struct drm_gem_object *obj)
+{
+   struct msm_gem_object *msm_obj = to_msm_bo(obj);
+   struct msm_gem_vma *vma, *tmp;
+
+   WARN_ON(!mutex_is_locked(&msm_obj->lock));
+
+   list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) {
del_vma(vma);
}
 }
@@ -688,12 +701,14 @@ void msm_gem_purge(struct drm_gem_object *obj)
WARN_ON(!is_purgeable(msm_obj));
WARN_ON(obj->import_attach);
 
-   put_iova(obj);
+   put_iova_spaces(obj);
 
msm_gem_vunmap(obj);
 
put_pages(obj);
 
+   put_iova_vmas(obj);
+
msm_obj->madv = __MSM_MADV_PURGED;
 
drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
@@ -942,7 +957,7 @@ void msm_gem_free_object(struct drm_gem_object *obj)
 
msm_gem_lock(obj);
 
-   put_iova(obj);
+   put_iova_spaces(obj);
 
if (obj->import_attach) {
WARN_ON(msm_obj->vaddr);
@@ -965,6 +980,8 @@ void msm_gem_free_object(struct drm_gem_object *obj)
msm_gem_unlock(obj);
}
 
+   put_iova_vma(obj);
+
drm_gem_object_release(obj);
 
kfree(msm_obj);

base-commit: 6147c83fd749d19a0d3ccc2f64d12138ab010b47
-- 
2.29.2



[PATCH] power: supply: ltc2941: Fix ptr to enum cast

2020-10-09 Thread Iskren Chernev
clang complains about casting pointers to smaller enum types.

Signed-off-by: Iskren Chernev 
---
 drivers/power/supply/ltc2941-battery-gauge.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/power/supply/ltc2941-battery-gauge.c 
b/drivers/power/supply/ltc2941-battery-gauge.c
index 30a9014b2f95e..10cd617516ec2 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -473,7 +473,8 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 
np = of_node_get(client->dev.of_node);
 
-   info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev);
+   info->id = (enum ltc294x_id) (uintptr_t) of_device_get_match_data(
+   &client->dev);
info->supply_desc.name = np->name;
 
/* r_sense can be negative, when sense+ is connected to the battery

base-commit: 411643e949f4e616f758e2c6079f333b0e704c49
-- 
2.28.0



[PATCH] power: supply: max17040: Fix ptr to enum cast

2020-10-05 Thread Iskren Chernev
clang complains about casting pointers to smaller enum types.

Reported-by: kernel test robot 
Signed-off-by: Iskren Chernev 
---

P.S. I fixed a similar issue in v5, but it was in another patch, and the
test robot only complains about the first issue, so I missed this one.

There is a similar warning in ltc2941-battery-gauge, let me know if I
should submit a fix for it as well.

 drivers/power/supply/max17040_battery.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 1d7510a59295d..d956c67d51558 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -247,7 +247,7 @@ static int max17040_get_of_data(struct max17040_chip *chip)
 {
struct device *dev = &chip->client->dev;
struct chip_data *data = &max17040_family[
-   (enum chip_id) of_device_get_match_data(dev)];
+   (uintptr_t) of_device_get_match_data(dev)];
int rcomp_len;
u8 rcomp[2];


base-commit: f9d293364b452b651292ed3034dd06c57b1754d5
--
2.28.0



[PATCH v5 2/7] power: supply: max17040: Use regmap i2c

2020-09-22 Thread Iskren Chernev
Rewrite i2c operations from i2c client read/write to regmap i2c. As
a result, most private functions now accept the private driver data
instead of an i2c client pointer.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/Kconfig|   1 +
 drivers/power/supply/max17040_battery.c | 219 ++--
 2 files changed, 93 insertions(+), 127 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index a4657484f38be..47a4e1d363fc3 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -367,6 +367,7 @@ config AXP288_FUEL_GAUGE
 config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
+   select REGMAP_I2C
help
  MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
  in handheld and portable equipment. The MAX17040 is configured
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 19b9e710bbd2f..fae4217960761 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -16,32 +16,30 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define MAX17040_VCELL 0x02
 #define MAX17040_SOC   0x04
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
-#define MAX17040_RCOMP 0x0C
+#define MAX17040_CONFIG0x0C
 #define MAX17040_CMD   0xFE
 
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
 
-#define MAX17040_ATHD_MASK 0xFFC0
+#define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
 
 struct max17040_chip {
struct i2c_client   *client;
+   struct regmap   *regmap;
struct delayed_work work;
struct power_supply *battery;
struct max17040_platform_data   *pdata;
 
-   /* State Of Connect */
-   int online;
-   /* battery voltage */
-   int vcell;
/* battery capacity */
int soc;
/* State Of Charge */
@@ -50,138 +48,68 @@ struct max17040_chip {
u32 low_soc_alert;
 };
 
-static int max17040_get_property(struct power_supply *psy,
-   enum power_supply_property psp,
-   union power_supply_propval *val)
+static int max17040_reset(struct max17040_chip *chip)
 {
-   struct max17040_chip *chip = power_supply_get_drvdata(psy);
-
-   switch (psp) {
-   case POWER_SUPPLY_PROP_STATUS:
-   val->intval = chip->status;
-   break;
-   case POWER_SUPPLY_PROP_ONLINE:
-   val->intval = chip->online;
-   break;
-   case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-   val->intval = chip->vcell;
-   break;
-   case POWER_SUPPLY_PROP_CAPACITY:
-   val->intval = chip->soc;
-   break;
-   case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
-   val->intval = chip->low_soc_alert;
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
+   return regmap_write(chip->regmap, MAX17040_CMD, 0x0054);
 }
 
-static int max17040_write_reg(struct i2c_client *client, int reg, u16 value)
+static int max17040_set_low_soc_alert(struct max17040_chip *chip, u32 level)
 {
-   int ret;
-
-   ret = i2c_smbus_write_word_swapped(client, reg, value);
-
-   if (ret < 0)
-   dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
-   return ret;
-}
-
-static int max17040_read_reg(struct i2c_client *client, int reg)
-{
-   int ret;
-
-   ret = i2c_smbus_read_word_swapped(client, reg);
-
-   if (ret < 0)
-   dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
-   return ret;
-}
-
-static void max17040_reset(struct i2c_client *client)
-{
-   max17040_write_reg(client, MAX17040_CMD, 0x0054);
-}
-
-static int max17040_set_low_soc_alert(struct i2c_client *client, u32 level)
-{
-   int ret;
-   u16 data;
-
level = 32 - level;
-   data = max17040_read_reg(client, MAX17040_RCOMP);
-   /* clear the alrt bit and set LSb 5 bits */
-   data &= MAX17040_ATHD_MASK;
-   data |= level;
-   ret = max17040_write_reg(client, MAX17040_RCOMP, data);
-
-   return ret;
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
+   MAX17040_ATHD_MASK, level);
 }
 
-static void max17040_get_vcell(struct i2c_client *client)
+static int max17040_get_vcell(struct max17040_chip *chip)
 {
-   struct max17040_chip *chip = i2c_get_clientdata(client);
-   u16 vcell;
+   u32 vcell;
 
-   vcell = max17040_read_reg(client, MAX17040_VCELL);
+   regmap_read(chip->regmap, MAX17040_VCELL, &vcell);
 
-   chip->vcell = (vcell >> 4) * 1250;
+   return (vcell >&

[PATCH v5 1/7] power: supply: max17040: Use devm_ to automate remove

2020-09-22 Thread Iskren Chernev
Two actions were performed during remove - power supply dereg and
delayed work cleanup. Power supply dereg can be handled by using the
devm_ version of the registration function. Work cleanup can be added as
a devm_action.

If probe fails after psy registration it will now be cleaned up
properly.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/max17040_battery.c | 39 +
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 6cb31b9a958dd..19b9e710bbd2f 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -207,6 +207,19 @@ static void max17040_check_changes(struct i2c_client 
*client)
max17040_get_status(client);
 }
 
+static void max17040_queue_work(struct max17040_chip *chip)
+{
+   queue_delayed_work(system_power_efficient_wq, &chip->work,
+  MAX17040_DELAY);
+}
+
+static void max17040_stop_work(void *data)
+{
+   struct max17040_chip *chip = data;
+
+   cancel_delayed_work_sync(&chip->work);
+}
+
 static void max17040_work(struct work_struct *work)
 {
struct max17040_chip *chip;
@@ -223,8 +236,7 @@ static void max17040_work(struct work_struct *work)
if (last_soc != chip->soc || last_status != chip->status)
power_supply_changed(chip->battery);
 
-   queue_delayed_work(system_power_efficient_wq, &chip->work,
-  MAX17040_DELAY);
+   max17040_queue_work(chip);
 }
 
 static irqreturn_t max17040_thread_handler(int id, void *dev)
@@ -339,7 +351,7 @@ static int max17040_probe(struct i2c_client *client,
i2c_set_clientdata(client, chip);
psy_cfg.drv_data = chip;
 
-   chip->battery = power_supply_register(&client->dev,
+   chip->battery = devm_power_supply_register(&client->dev,
&max17040_battery_desc, &psy_cfg);
if (IS_ERR(chip->battery)) {
dev_err(&client->dev, "failed: power supply register\n");
@@ -368,18 +380,11 @@ static int max17040_probe(struct i2c_client *client,
}
 
INIT_DEFERRABLE_WORK(&chip->work, max17040_work);
-   queue_delayed_work(system_power_efficient_wq, &chip->work,
-  MAX17040_DELAY);
-
-   return 0;
-}
-
-static int max17040_remove(struct i2c_client *client)
-{
-   struct max17040_chip *chip = i2c_get_clientdata(client);
+   ret = devm_add_action(&client->dev, max17040_stop_work, chip);
+   if (ret)
+   return ret;
+   max17040_queue_work(chip);
 
-   power_supply_unregister(chip->battery);
-   cancel_delayed_work(&chip->work);
return 0;
 }
 
@@ -403,12 +408,11 @@ static int max17040_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct max17040_chip *chip = i2c_get_clientdata(client);
 
-   queue_delayed_work(system_power_efficient_wq, &chip->work,
-  MAX17040_DELAY);
-
if (client->irq && device_may_wakeup(dev))
disable_irq_wake(client->irq);
 
+   max17040_queue_work(chip);
+
return 0;
 }
 
@@ -442,7 +446,6 @@ static struct i2c_driver max17040_i2c_driver = {
.pm = MAX17040_PM_OPS,
},
.probe  = max17040_probe,
-   .remove = max17040_remove,
.id_table   = max17040_id,
 };
 module_i2c_driver(max17040_i2c_driver);
-- 
2.28.0



[PATCH v5 4/7] power: supply: max17040: Support compatible devices

2020-09-22 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very
similar mode of operations and registers.

This change adds:
- compatible strings for all supported devices and handling for the
  minor differences between them;
- handling for devices reporting double capacity via maxim,double-soc;

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
Reported-by: kernel test robot 
---
 drivers/power/supply/Kconfig|  10 +-
 drivers/power/supply/max17040_battery.c | 155 +---
 2 files changed, 143 insertions(+), 22 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 47a4e1d363fc3..de9e0fa9a861b 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -369,9 +369,13 @@ config BATTERY_MAX17040
depends on I2C
select REGMAP_I2C
help
- MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
- in handheld and portable equipment. The MAX17040 is configured
- to operate with a single lithium cell
+ Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
+ (Li+) batteries in handheld and portable equipment, including
+ max17040, max17041, max17043, max17044, max17048, max17049, max17058,
+ max17059. It is also included in some batteries like max77836.
+
+ Driver supports reporting SOC (State of Charge, i.e capacity),
+ voltage and configurable low-SOC wakeup interrupt.
 
 config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index fae4217960761..4bcec86d92098 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -33,12 +34,92 @@
 #define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
 
+enum chip_id {
+   ID_MAX17040,
+   ID_MAX17041,
+   ID_MAX17043,
+   ID_MAX17044,
+   ID_MAX17048,
+   ID_MAX17049,
+   ID_MAX17058,
+   ID_MAX17059,
+};
+
+/* values that differ by chip_id */
+struct chip_data {
+   u16 reset_val;
+   u16 vcell_shift;
+   u16 vcell_mul;
+   u16 vcell_div;
+   u8  has_low_soc_alert;
+};
+
+static struct chip_data max17040_family[] = {
+   [ID_MAX17040] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .has_low_soc_alert = 0,
+   },
+   [ID_MAX17041] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .has_low_soc_alert = 0,
+   },
+   [ID_MAX17043] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17044] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17048] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 8,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17049] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 4,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17058] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 8,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17059] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 4,
+   .has_low_soc_alert = 1,
+   },
+};
+
 struct max17040_chip {
struct i2c_client   *client;
struct regmap   *regmap;
struct delayed_work work;
struct power_supply *battery;
struct max17040_platform_data   *pdata;
+   struct chip_datadata;
 
/* battery capacity */
int soc;
@@ -46,27 +127,37 @@ struct max17040_chip {
int status;
/* Low alert threshold f

[PATCH v5 6/7] power: supply: max17040: Support setting rcomp

2020-09-22 Thread Iskren Chernev
The Maxim ModelGauge family supports fine-tuning by setting
a compensation value (named rcomp in the docs). The value is affected by
battery chemistry and ambient temperature.

Add support for reading maxim,rcomp from DT and configuring the device
with the supplied value. Temperature adjustment is not implemented at
the moment, because there is no provision for receiving the ambient
temperature at the moment.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/max17040_battery.c | 40 +
 1 file changed, 40 insertions(+)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 4bcec86d92098..ae39ca5c6753e 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -30,9 +30,11 @@
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
+#define MAX17040_RCOMP_DEFAULT  0x9700
 
 #define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_CFG_RCOMP_MASK0xff00
 
 enum chip_id {
ID_MAX17040,
@@ -52,6 +54,7 @@ struct chip_data {
u16 vcell_mul;
u16 vcell_div;
u8  has_low_soc_alert;
+   u8  rcomp_bytes;
 };
 
 static struct chip_data max17040_family[] = {
@@ -61,6 +64,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 1250,
.vcell_div = 1,
.has_low_soc_alert = 0,
+   .rcomp_bytes = 2,
},
[ID_MAX17041] = {
.reset_val = 0x0054,
@@ -68,6 +72,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 2500,
.vcell_div = 1,
.has_low_soc_alert = 0,
+   .rcomp_bytes = 2,
},
[ID_MAX17043] = {
.reset_val = 0x0054,
@@ -75,6 +80,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 1250,
.vcell_div = 1,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17044] = {
.reset_val = 0x0054,
@@ -82,6 +88,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 2500,
.vcell_div = 1,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17048] = {
.reset_val = 0x5400,
@@ -89,6 +96,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 8,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17049] = {
.reset_val = 0x5400,
@@ -96,6 +104,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 4,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17058] = {
.reset_val = 0x5400,
@@ -103,6 +112,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 8,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17059] = {
.reset_val = 0x5400,
@@ -110,6 +120,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 4,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
 };
 
@@ -129,6 +140,8 @@ struct max17040_chip {
u32 low_soc_alert;
/* some devices return twice the capacity */
bool quirk_double_soc;
+   /* higher 8 bits for 17043+, 16 bits for 17040,41 */
+   u16 rcomp;
 };
 
 static int max17040_reset(struct max17040_chip *chip)
@@ -143,6 +156,14 @@ static int max17040_set_low_soc_alert(struct max17040_chip 
*chip, u32 level)
MAX17040_ATHD_MASK, level);
 }
 
+static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
+{
+   u16 mask = chip->data.rcomp_bytes == 2 ?
+   0x : MAX17040_CFG_RCOMP_MASK;
+
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG, mask, rcomp);
+}
+
 static int max17040_raw_vcell_to_uvolts(struct max17040_chip *chip, u16 vcell)
 {
struct chip_data *d = &chip->data;
@@ -206,6 +227,10 @@ static int max17040_get_status(struct max17040_chip *chip)
 static int max17040_get_of_data(struct max17040_chip *chip)
 {
struct device *dev = &chip->client->dev;
+   struct chip_data *data = &max17040_family[
+   (enum chip_id) of_device_get_match_data(dev)];
+   int rcomp_len;
+   u8 rcomp[2];
 
chip->quirk_double_soc = device_property_read_bool(dev,
   "maxim,double-soc");
@@ -221,6 +246,19 @@ static int max17040_get_of_data(struct max17040_chip *chip)
retur

[PATCH v5 5/7] dt-bindings: power: supply: max17040: Add maxim,rcomp

2020-09-22 Thread Iskren Chernev
To compensate for the battery chemistry and operating conditions the
chips support a compensation value. Specify one or two byte compensation
via the maxim,rcomp byte array.

Signed-off-by: Iskren Chernev 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/power/supply/max17040_battery.txt   | 6 ++
 1 file changed, 6 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 554bce82a08e6..2cf046d12d922 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -17,6 +17,11 @@ Optional properties :
Specify this boolean property to divide the
reported value in 2 and thus normalize it.
SOC == State of Charge == Capacity.
+- maxim,rcomp :A value to compensate readings for 
various
+   battery chemistries and operating temperatures.
+   max17040,41 have 2 byte rcomp, default to
+   0x97 0x00. All other devices have one byte
+   rcomp, default to 0x97.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -41,6 +46,7 @@ Example:
battery-fuel-gauge@36 {
compatible = "maxim,max17048";
reg = <0x36>;
+   maxim,rcomp = /bits/ 8 <0x56>;
maxim,alert-low-soc-level = <10>;
maxim,double-soc;
};
-- 
2.28.0



[PATCH v5 3/7] dt-bindings: power: supply: Extend max17040 compatibility

2020-09-22 Thread Iskren Chernev
Maxim max17040 is a fuel gauge from a larger family utilising the Model
Gauge technology. Document all different compatible strings that the
max17040 driver recognizes.

Some devices in the wild report double the capacity. The
maxim,double-soc (from State-Of-Charge) property fixes that.
Examples: https://lore.kernel.org/patchwork/patch/1263411/#1468420

Signed-off-by: Iskren Chernev 
Reviewed-by: Rob Herring 
---
 .../bindings/power/supply/max17040_battery.txt| 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 4e0186b8380fa..554bce82a08e6 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -2,7 +2,9 @@ max17040_battery
 
 
 Required properties :
- - compatible : "maxim,max17040" or "maxim,max77836-battery"
+ - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
+   "maxim,max17044", "maxim,max17048", "maxim,max17049",
+   "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
  - reg: i2c slave address
 
 Optional properties :
@@ -11,6 +13,10 @@ Optional properties :
generated. Can be configured from 1 up to 32
(%). If skipped the power up default value of
4 (%) will be used.
+- maxim,double-soc :   Certain devices return double the capacity.
+   Specify this boolean property to divide the
+   reported value in 2 and thus normalize it.
+   SOC == State of Charge == Capacity.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -31,3 +37,10 @@ Example:
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
wakeup-source;
};
+
+   battery-fuel-gauge@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+   maxim,alert-low-soc-level = <10>;
+   maxim,double-soc;
+   };
-- 
2.28.0



[PATCH v5 7/7] power: supply: max17040: Support soc alert

2020-09-22 Thread Iskren Chernev
max17048 and max17049 support SOC alerts (interrupts when battery
capacity changes by +/- 1%). At the moment the driver polls for changes
every second. Using the alerts removes the need for polling.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/max17040_battery.c | 82 ++---
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index ae39ca5c6753e..1d7510a59295d 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -25,6 +25,7 @@
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
 #define MAX17040_CONFIG0x0C
+#define MAX17040_STATUS0x1A
 #define MAX17040_CMD   0xFE
 
 
@@ -33,7 +34,10 @@
 #define MAX17040_RCOMP_DEFAULT  0x9700
 
 #define MAX17040_ATHD_MASK 0x3f
+#define MAX17040_ALSC_MASK 0x40
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_STATUS_HD_MASK0x1000
+#define MAX17040_STATUS_SC_MASK0x2000
 #define MAX17040_CFG_RCOMP_MASK0xff00
 
 enum chip_id {
@@ -55,6 +59,7 @@ struct chip_data {
u16 vcell_div;
u8  has_low_soc_alert;
u8  rcomp_bytes;
+   u8  has_soc_alert;
 };
 
 static struct chip_data max17040_family[] = {
@@ -65,6 +70,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 0,
.rcomp_bytes = 2,
+   .has_soc_alert = 0,
},
[ID_MAX17041] = {
.reset_val = 0x0054,
@@ -73,6 +79,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 0,
.rcomp_bytes = 2,
+   .has_soc_alert = 0,
},
[ID_MAX17043] = {
.reset_val = 0x0054,
@@ -81,6 +88,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17044] = {
.reset_val = 0x0054,
@@ -89,6 +97,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17048] = {
.reset_val = 0x5400,
@@ -97,6 +106,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 8,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 1,
},
[ID_MAX17049] = {
.reset_val = 0x5400,
@@ -105,6 +115,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 4,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 1,
},
[ID_MAX17058] = {
.reset_val = 0x5400,
@@ -113,6 +124,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 8,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17059] = {
.reset_val = 0x5400,
@@ -121,6 +133,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 4,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
 };
 
@@ -156,6 +169,12 @@ static int max17040_set_low_soc_alert(struct max17040_chip 
*chip, u32 level)
MAX17040_ATHD_MASK, level);
 }
 
+static int max17040_set_soc_alert(struct max17040_chip *chip, bool enable)
+{
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
+   MAX17040_ALSC_MASK, enable ? MAX17040_ALSC_MASK : 0);
+}
+
 static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
 {
u16 mask = chip->data.rcomp_bytes == 2 ?
@@ -300,11 +319,33 @@ static void max17040_work(struct work_struct *work)
max17040_queue_work(chip);
 }
 
+/* Returns true if alert cause was SOC change, not low SOC */
+static bool max17040_handle_soc_alert(struct max17040_chip *chip)
+{
+   bool ret = true;
+   u32 data;
+
+   regmap_read(chip->regmap, MAX17040_STATUS, &data);
+
+   if (data & MAX17040_STATUS_HD_MASK) {
+   // this alert was caused by low soc
+   ret = false;
+   }
+   if (data & MAX17040_STATUS_SC_MASK) {
+   // soc change bit -- deassert to mark as handled
+   regmap_write(chip->regmap, MAX17040_STATUS,
+   data & ~MAX17040_STATUS_SC_MASK);
+   }
+
+   return ret;
+}
+
 static irqreturn_t max17040_thread_handler(int id, void *dev)
 {
struct max17040_chip *chip = dev;
 
-   dev_warn(&chip-&

[PATCH v5 0/7] power: supply: max17040 support compatible devices

2020-09-22 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very
similar mode of operations and registers.

This patch set adds:
- compatible strings for all supported devices and handles the minor
  differences between them;
- handling for devices reporting double capacity via maxim,double-soc;
- handling for setting rcomp, a compensation value for more accurate
  reading, affected by battery chemistry and operating temps;
- suppot for SOC alerts (capacity changes by +/- 1%), to prevent polling
  every second;
- improved max17040 driver with regmap and devm_

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

v4: https://lkml.org/lkml/2020/9/6/237
v3: https://lkml.org/lkml/2020/6/24/874
v2: https://lkml.org/lkml/2020/6/18/260
v1: https://lkml.org/lkml/2020/6/8/682

Changes from v4:
- fix warning reported by kernel test robot  for v4
  patch 4/7
- ensure all patches have Sign-off-by matching author (was violated
  for v4 patch 2/7)

Iskren Chernev (7):
  power: supply: max17040: Use devm_ to automate remove
  power: supply: max17040: Use regmap i2c
  dt-bindings: power: supply: Extend max17040 compatibility
  power: supply: max17040: Support compatible devices
  dt-bindings: power: supply: max17040: Add maxim,rcomp
  power: supply: max17040: Support setting rcomp
  power: supply: max17040: Support soc alert

 .../power/supply/max17040_battery.txt |  21 +-
 drivers/power/supply/Kconfig  |  11 +-
 drivers/power/supply/max17040_battery.c   | 489 --
 3 files changed, 367 insertions(+), 154 deletions(-)


base-commit: e64997027d5f171148687e58b78c8b3c869a6158
--
2.28.0



[PATCH RESEND 6/7] ARM: dts: qcom: msm8974-klte: Add support for wifi

2020-09-20 Thread Iskren Chernev
The Samsung Galaxy S5 (klte), uses a Broadcom 4354 Chip connected on the
SDIO bus. The chip also requires a corresponding firmware + txt file[1].

[1] 
https://gitlab.com/postmarketOS/pmaports/-/blob/master/firmware/firmware-samsung-klte/APKBUILD

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 74 +++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 29099b83b231d..989447beb4319 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -282,6 +282,17 @@ led@3 {
};
};
 
+   vreg_wlan: wlan-regulator {
+   compatible = "regulator-fixed";
+
+   regulator-name = "wl-reg";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+
+   gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>;
+   enable-active-high;
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -338,6 +349,20 @@ cmd-data {
};
};
 
+   sdhc3_pin_a: sdhc3-pin-active {
+   clk {
+   pins = "sdc2_clk";
+   drive-strength = <6>;
+   bias-disable;
+   };
+
+   cmd-data {
+   pins = "sdc2_cmd", "sdc2_data";
+   drive-strength = <6>;
+   bias-pull-up;
+   };
+   };
+
i2c2_pins: i2c2 {
mux {
pins = "gpio6", "gpio7";
@@ -385,6 +410,16 @@ res {
drive-strength = <2>;
};
};
+
+   wifi_pin: wifi {
+   int {
+   pins = "gpio92";
+   function = "gpio";
+
+   input-enable;
+   bias-pull-down;
+   };
+   };
};
 
sdhci@f9824900 {
@@ -400,6 +435,36 @@ sdhci@f9824900 {
pinctrl-0 = <&sdhc1_pin_a>;
};
 
+   sdhci@f98a4900 {
+   status = "okay";
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   max-frequency = <1>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&sdhc3_pin_a>;
+
+   vmmc-supply = <&vreg_wlan>;
+   vqmmc-supply = <&pma8084_s4>;
+
+   bus-width = <4>;
+   non-removable;
+
+   wifi@1 {
+   reg = <1>;
+   compatible = "brcm,bcm4329-fmac";
+
+   interrupt-parent = <&msmgpio>;
+   interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "host-wake";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
+   };
+   };
+
usb@f9a55000 {
status = "ok";
 
@@ -587,6 +652,15 @@ touch_pin: touchscreen-int-pin {
input-enable;
power-source = ;
};
+
+   wlan_sleep_clk_pin: wlan-sleep-clk-pin {
+   pins = "gpio16";
+   function = "func2";
+
+   output-high;
+   power-source = ;
+   qcom,drive-strength = ;
+   };
};
};
 };
-- 
2.28.0



[PATCH RESEND 7/7] ARM: dts: qcom: msm8974-klte: Add support for SD card

2020-09-20 Thread Iskren Chernev
The Samsung Galaxy S5 (klte), has 3 SDHCI nodes used for internal
storage, WiFi, external SD card slot. The external SD card slot is
similar to the internal storage.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 44 ++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 989447beb4319..b0899107f3ced 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -12,6 +12,8 @@ / {
 
aliases {
serial0 = &blsp1_uart1;
+   sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
+   sdhc2 = &sdhc_2; /* SDC2 SD card slot */
};
 
chosen {
@@ -161,6 +163,9 @@ pma8084_l20: l20 {
pma8084_l21: l21 {
regulator-min-microvolt = 
<295>;
regulator-max-microvolt = 
<295>;
+
+   regulator-allow-set-load;
+   regulator-system-load = 
<20>;
};
 
pma8084_l22: l22 {
@@ -349,6 +354,24 @@ cmd-data {
};
};
 
+   sdhc2_pin_a: sdhc2-pin-active {
+   clk-cmd-data {
+   pins = "gpio35", "gpio36", "gpio37", "gpio38",
+   "gpio39", "gpio40";
+   function = "sdc3";
+   drive-strength = <8>;
+   bias-disable;
+   };
+   };
+
+   sdhc2_cd_pin: sdhc2-cd {
+   pins = "gpio62";
+   function = "gpio";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+
sdhc3_pin_a: sdhc3-pin-active {
clk {
pins = "sdc2_clk";
@@ -422,7 +445,7 @@ int {
};
};
 
-   sdhci@f9824900 {
+   sdhc_1: sdhci@f9824900 {
status = "ok";
 
vmmc-supply = <&pma8084_l20>;
@@ -435,6 +458,25 @@ sdhci@f9824900 {
pinctrl-0 = <&sdhc1_pin_a>;
};
 
+   sdhc_2: sdhci@f9864900 {
+   status = "ok";
+
+   max-frequency = <1>;
+
+   vmmc-supply = <&pma8084_l21>;
+   vqmmc-supply = <&pma8084_l13>;
+
+   bus-width = <4>;
+
+   /* cd-gpio is intentionally disabled. If enabled, an SD card
+* present during boot is not initialized correctly. Without
+* cd-gpios the driver resorts to polling, so hotplug works.
+*/
+   pinctrl-names = "default";
+   pinctrl-0 = <&sdhc2_pin_a /* &sdhc2_cd_pin */>;
+   // cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
+   };
+
sdhci@f98a4900 {
status = "okay";
 
-- 
2.28.0



[PATCH RESEND 3/7] ARM: dts: qcom: msm8974-klte: Add support for touchscreen

2020-09-20 Thread Iskren Chernev
Add support for the touchscreen found on the Samsung Galaxy S5.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 54 +++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 750e2f261139a..085636f182d01 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -284,6 +284,16 @@ cmd-data {
};
};
 
+   i2c2_pins: i2c2 {
+   mux {
+   pins = "gpio6", "gpio7";
+   function = "blsp_i2c2";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
+
i2c6_pins: i2c6 {
mux {
pins = "gpio29", "gpio30";
@@ -342,6 +352,42 @@ phy@a {
};
};
 
+   i2c@f9924000 {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c2_pins>;
+
+   touchscreen@20 {
+   compatible = "syna,rmi4-i2c";
+   reg = <0x20>;
+
+   interrupt-parent = <&pma8084_gpios>;
+   interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+
+   vdd-supply = <&max77826_ldo13>;
+   vio-supply = <&pma8084_lvs2>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&touch_pin>;
+
+   syna,startup-delay-ms = <100>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   rmi4-f01@1 {
+   reg = <0x1>;
+   syna,nosleep-mode = <1>;
+   };
+
+   rmi4-f12@12 {
+   reg = <0x12>;
+   syna,sensor-type = <1>;
+   };
+   };
+   };
+
i2c@f9928000 {
status = "okay";
 
@@ -460,6 +506,14 @@ touchkey_pin: touchkey-int-pin {
input-enable;
power-source = ;
};
+
+   touch_pin: touchscreen-int-pin {
+   pins = "gpio8";
+   function = "normal";
+   bias-disable;
+   input-enable;
+   power-source = ;
+   };
};
};
 };
-- 
2.28.0



[PATCH RESEND 4/7] ARM: dts: qcom: msm8974-klte: Add support for led

2020-09-20 Thread Iskren Chernev
The klte uses a Panasonic AN30259A LED controller for it's indicator
led.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 48 +++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 085636f182d01..7b398da9b75ed 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
model = "Samsung Galaxy S5";
@@ -228,6 +229,44 @@ touchkey@20 {
};
};
 
+   i2c-gpio-led {
+   compatible = "i2c-gpio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   scl-gpios = <&msmgpio 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   sda-gpios = <&msmgpio 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c_led_pins>;
+
+   i2c-gpio,delay-us = <2>;
+
+   led-controller@30 {
+   compatible = "panasonic,an30259a";
+   reg = <0x30>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   led@1 {
+   reg = <1>;
+   function = LED_FUNCTION_STATUS;
+   color = ;
+   };
+
+   led@2 {
+   reg = <2>;
+   function = LED_FUNCTION_STATUS;
+   color = ;
+   };
+
+   led@3 {
+   reg = <3>;
+   function = LED_FUNCTION_STATUS;
+   color = ;
+   };
+   };
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -312,6 +351,15 @@ mux {
bias-pull-up;
};
};
+
+   i2c_led_pins: i2c-led {
+   mux {
+   pins = "gpio120", "gpio121";
+   function = "gpio";
+   input-enable;
+   bias-pull-down;
+   };
+   };
};
 
sdhci@f9824900 {
-- 
2.28.0



[PATCH RESEND 5/7] ARM: dts: qcom: msm8974-klte: Add gpio expander chip

2020-09-20 Thread Iskren Chernev
The Samsung Galaxy S5 has a GPIO Expander chip, the PCAL6416A with 16
ports on a i2c bus. These pins are used for WiFi, NFC, IR among other
things.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 29 +--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 7b398da9b75ed..29099b83b231d 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -236,10 +236,25 @@ i2c-gpio-led {
scl-gpios = <&msmgpio 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&msmgpio 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
pinctrl-names = "default";
-   pinctrl-0 = <&i2c_led_pins>;
+   pinctrl-0 = <&i2c_led_gpioex_pins>;
 
i2c-gpio,delay-us = <2>;
 
+   gpio_expander: gpio@20 {
+   compatible = "nxp,pcal6416";
+   reg = <0x20>;
+
+   gpio-controller;
+   #gpio-cells = <2>;
+
+   vcc-supply = <&pma8084_s4>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&gpioex_pin>;
+
+   reset-gpios = <&msmgpio 145 GPIO_ACTIVE_LOW>;
+   };
+
led-controller@30 {
compatible = "panasonic,an30259a";
reg = <0x30>;
@@ -352,7 +367,7 @@ mux {
};
};
 
-   i2c_led_pins: i2c-led {
+   i2c_led_gpioex_pins: i2c-led-gpioex {
mux {
pins = "gpio120", "gpio121";
function = "gpio";
@@ -360,6 +375,16 @@ mux {
bias-pull-down;
};
};
+
+   gpioex_pin: gpioex {
+   res {
+   pins = "gpio145";
+   function = "gpio";
+
+   bias-pull-up;
+   drive-strength = <2>;
+   };
+   };
};
 
sdhci@f9824900 {
-- 
2.28.0



[PATCH RESEND 1/7] ARM: dts: qcom: msm8974-klte: Merge pinctrl nodes

2020-09-20 Thread Iskren Chernev
commit cd13c72c1853f219e1f ("ARM: dts: qcom: msm8974-klte: Add max77826
pmic node") and commit 8bf7a360a92cc6b2aebc8 ("ARM: dts: qcom:
msm8974-klte: Add sdhci1 node") both added pinctrl node. This patch merges
the two nodes.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 22 +--
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index d4dc98214225a..9520c6e7910ce 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -258,6 +258,16 @@ cmd-data {
bias-pull-up;
};
};
+
+   i2c6_pins: i2c6 {
+   mux {
+   pins = "gpio29", "gpio30";
+   function = "blsp_i2c6";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};
 
sdhci@f9824900 {
@@ -298,18 +308,6 @@ phy@a {
};
};
 
-   pinctrl@fd51 {
-   i2c6_pins: i2c6 {
-   mux {
-   pins = "gpio29", "gpio30";
-   function = "blsp_i2c6";
-
-   drive-strength = <2>;
-   bias-disable;
-   };
-   };
-   };
-
i2c@f9928000 {
status = "okay";
 
-- 
2.28.0



[PATCH RESEND 2/7] ARM: dts: qcom: msm8974-klte: Add support for touchkey

2020-09-20 Thread Iskren Chernev
Add support for the touchkey found on the Samsung Galaxy S5. The
touchkey is responsible for handling the application and back buttons
found around the home button.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 44 ++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 9520c6e7910ce..750e2f261139a 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -145,7 +145,7 @@ pma8084_l18: l18 {
};
 
pma8084_l19: l19 {
-   regulator-min-microvolt = 
<290>;
+   regulator-min-microvolt = 
<330>;
regulator-max-microvolt = 
<330>;
};
 
@@ -203,6 +203,31 @@ pma8084_l27: l27 {
};
};
 
+   i2c-gpio-touchkey {
+   compatible = "i2c-gpio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   sda-gpios = <&msmgpio 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   scl-gpios = <&msmgpio 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c_touchkey_pins>;
+
+   touchkey@20 {
+   compatible = "cypress,tm2-touchkey";
+   reg = <0x20>;
+
+   interrupt-parent = <&pma8084_gpios>;
+   interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&touchkey_pin>;
+
+   vcc-supply = <&max77826_ldo15>;
+   vdd-supply = <&pma8084_l19>;
+
+   linux,keycodes = ;
+   };
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -268,6 +293,15 @@ mux {
bias-disable;
};
};
+
+   i2c_touchkey_pins: i2c-touchkey {
+   mux {
+   pins = "gpio95", "gpio96";
+   function = "gpio";
+   input-enable;
+   bias-pull-up;
+   };
+   };
};
 
sdhci@f9824900 {
@@ -418,6 +452,14 @@ gpio_keys_pin_a: gpio-keys-active {
bias-pull-up;
power-source = ;
};
+
+   touchkey_pin: touchkey-int-pin {
+   pins = "gpio6";
+   function = "normal";
+   bias-disable;
+   input-enable;
+   power-source = ;
+   };
};
};
 };
-- 
2.28.0



[PATCH RESEND 0/7] ARM: dts: qcom: msm8974: klte: Enable some hardware

2020-09-20 Thread Iskren Chernev
Enable support for various hw found on the Samsung Galaxy S5:
- touchkey (the two buttons around the home button)
- touchscreen
- notification led
- wifi
- external SD card

Please note that for working wifi the correct firmware is needed. Check [1]
for links and locations.

Also note, that to actually run a mainline kernel on the klte, you'd need
to apply this patch [2]. Any feedback on getting this to run on pure
mainline are welcome.

Original patch series submission: [3]

[1] 
https://gitlab.com/postmarketOS/pmaports/-/blob/master/firmware/firmware-samsung-klte/APKBUILD
[2] 
https://gitlab.com/postmarketOS/linux-postmarketos/-/commit/765f55b248cd3b231af8431fe2f2aeca263b4e4b
[3] https://lkml.org/lkml/2020/6/30/643

Iskren Chernev (7):
  ARM: dts: qcom: msm8974-klte: Merge pinctrl nodes
  ARM: dts: qcom: msm8974-klte: Add support for touchkey
  ARM: dts: qcom: msm8974-klte: Add support for touchscreen
  ARM: dts: qcom: msm8974-klte: Add support for led
  ARM: dts: qcom: msm8974-klte: Add gpio expander chip
  ARM: dts: qcom: msm8974-klte: Add support for wifi
  ARM: dts: qcom: msm8974-klte: Add support for SD card

 .../boot/dts/qcom-msm8974-samsung-klte.dts| 301 +-
 1 file changed, 292 insertions(+), 9 deletions(-)


base-commit: b652d2a5f2a4e93d803cc33eb57fdc41ee528500
--
2.28.0



[PATCH v4 2/7] power: supply: max17040: Use regmap i2c

2020-09-06 Thread Iskren Chernev
From: Iskren Chernev 

Rewrite i2c operations from i2c client read/write to regmap i2c. As
a result, most private functions now accept the private driver data
instead of an i2c client pointer.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/Kconfig|   1 +
 drivers/power/supply/max17040_battery.c | 219 ++--
 2 files changed, 93 insertions(+), 127 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index d1ccf17df42e9..1e11a44077dde 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -367,6 +367,7 @@ config AXP288_FUEL_GAUGE
 config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
+   select REGMAP_I2C
help
  MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
  in handheld and portable equipment. The MAX17040 is configured
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 19b9e710bbd2f..fae4217960761 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -16,32 +16,30 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define MAX17040_VCELL 0x02
 #define MAX17040_SOC   0x04
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
-#define MAX17040_RCOMP 0x0C
+#define MAX17040_CONFIG0x0C
 #define MAX17040_CMD   0xFE
 
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
 
-#define MAX17040_ATHD_MASK 0xFFC0
+#define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
 
 struct max17040_chip {
struct i2c_client   *client;
+   struct regmap   *regmap;
struct delayed_work work;
struct power_supply *battery;
struct max17040_platform_data   *pdata;
 
-   /* State Of Connect */
-   int online;
-   /* battery voltage */
-   int vcell;
/* battery capacity */
int soc;
/* State Of Charge */
@@ -50,138 +48,68 @@ struct max17040_chip {
u32 low_soc_alert;
 };
 
-static int max17040_get_property(struct power_supply *psy,
-   enum power_supply_property psp,
-   union power_supply_propval *val)
+static int max17040_reset(struct max17040_chip *chip)
 {
-   struct max17040_chip *chip = power_supply_get_drvdata(psy);
-
-   switch (psp) {
-   case POWER_SUPPLY_PROP_STATUS:
-   val->intval = chip->status;
-   break;
-   case POWER_SUPPLY_PROP_ONLINE:
-   val->intval = chip->online;
-   break;
-   case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-   val->intval = chip->vcell;
-   break;
-   case POWER_SUPPLY_PROP_CAPACITY:
-   val->intval = chip->soc;
-   break;
-   case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
-   val->intval = chip->low_soc_alert;
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
+   return regmap_write(chip->regmap, MAX17040_CMD, 0x0054);
 }
 
-static int max17040_write_reg(struct i2c_client *client, int reg, u16 value)
+static int max17040_set_low_soc_alert(struct max17040_chip *chip, u32 level)
 {
-   int ret;
-
-   ret = i2c_smbus_write_word_swapped(client, reg, value);
-
-   if (ret < 0)
-   dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
-   return ret;
-}
-
-static int max17040_read_reg(struct i2c_client *client, int reg)
-{
-   int ret;
-
-   ret = i2c_smbus_read_word_swapped(client, reg);
-
-   if (ret < 0)
-   dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
-   return ret;
-}
-
-static void max17040_reset(struct i2c_client *client)
-{
-   max17040_write_reg(client, MAX17040_CMD, 0x0054);
-}
-
-static int max17040_set_low_soc_alert(struct i2c_client *client, u32 level)
-{
-   int ret;
-   u16 data;
-
level = 32 - level;
-   data = max17040_read_reg(client, MAX17040_RCOMP);
-   /* clear the alrt bit and set LSb 5 bits */
-   data &= MAX17040_ATHD_MASK;
-   data |= level;
-   ret = max17040_write_reg(client, MAX17040_RCOMP, data);
-
-   return ret;
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
+   MAX17040_ATHD_MASK, level);
 }
 
-static void max17040_get_vcell(struct i2c_client *client)
+static int max17040_get_vcell(struct max17040_chip *chip)
 {
-   struct max17040_chip *chip = i2c_get_clientdata(client);
-   u16 vcell;
+   u32 vcell;
 
-   vcell = max17040_read_reg(client, MAX17040_VCELL);
+   regmap_read(chip->regmap, MAX17040_VCELL, &vcell);
 
-   chip->vcell = (vcell >> 4) * 1250;
+  

[PATCH v4 1/7] power: supply: max17040: Use devm_ to automate remove

2020-09-06 Thread Iskren Chernev
Two actions were performed during remove - power supply dereg and
delayed work cleanup. Power supply dereg can be handled by using the
devm_ version of the registration function. Work cleanup can be added as
a devm_action.

If probe fails after psy registration it will now be cleaned up
properly.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/max17040_battery.c | 39 +
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 6cb31b9a958dd..19b9e710bbd2f 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -207,6 +207,19 @@ static void max17040_check_changes(struct i2c_client 
*client)
max17040_get_status(client);
 }
 
+static void max17040_queue_work(struct max17040_chip *chip)
+{
+   queue_delayed_work(system_power_efficient_wq, &chip->work,
+  MAX17040_DELAY);
+}
+
+static void max17040_stop_work(void *data)
+{
+   struct max17040_chip *chip = data;
+
+   cancel_delayed_work_sync(&chip->work);
+}
+
 static void max17040_work(struct work_struct *work)
 {
struct max17040_chip *chip;
@@ -223,8 +236,7 @@ static void max17040_work(struct work_struct *work)
if (last_soc != chip->soc || last_status != chip->status)
power_supply_changed(chip->battery);
 
-   queue_delayed_work(system_power_efficient_wq, &chip->work,
-  MAX17040_DELAY);
+   max17040_queue_work(chip);
 }
 
 static irqreturn_t max17040_thread_handler(int id, void *dev)
@@ -339,7 +351,7 @@ static int max17040_probe(struct i2c_client *client,
i2c_set_clientdata(client, chip);
psy_cfg.drv_data = chip;
 
-   chip->battery = power_supply_register(&client->dev,
+   chip->battery = devm_power_supply_register(&client->dev,
&max17040_battery_desc, &psy_cfg);
if (IS_ERR(chip->battery)) {
dev_err(&client->dev, "failed: power supply register\n");
@@ -368,18 +380,11 @@ static int max17040_probe(struct i2c_client *client,
}
 
INIT_DEFERRABLE_WORK(&chip->work, max17040_work);
-   queue_delayed_work(system_power_efficient_wq, &chip->work,
-  MAX17040_DELAY);
-
-   return 0;
-}
-
-static int max17040_remove(struct i2c_client *client)
-{
-   struct max17040_chip *chip = i2c_get_clientdata(client);
+   ret = devm_add_action(&client->dev, max17040_stop_work, chip);
+   if (ret)
+   return ret;
+   max17040_queue_work(chip);
 
-   power_supply_unregister(chip->battery);
-   cancel_delayed_work(&chip->work);
return 0;
 }
 
@@ -403,12 +408,11 @@ static int max17040_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct max17040_chip *chip = i2c_get_clientdata(client);
 
-   queue_delayed_work(system_power_efficient_wq, &chip->work,
-  MAX17040_DELAY);
-
if (client->irq && device_may_wakeup(dev))
disable_irq_wake(client->irq);
 
+   max17040_queue_work(chip);
+
return 0;
 }
 
@@ -442,7 +446,6 @@ static struct i2c_driver max17040_i2c_driver = {
.pm = MAX17040_PM_OPS,
},
.probe  = max17040_probe,
-   .remove = max17040_remove,
.id_table   = max17040_id,
 };
 module_i2c_driver(max17040_i2c_driver);
-- 
2.28.0



[PATCH v4 3/7] dt-bindings: power: supply: Extend max17040 compatibility

2020-09-06 Thread Iskren Chernev
Maxim max17040 is a fuel gauge from a larger family utilising the Model
Gauge technology. Document all different compatible strings that the
max17040 driver recognizes.

Some devices in the wild report double the capacity. The
maxim,double-soc (from State-Of-Charge) property fixes that.
Examples: https://lore.kernel.org/patchwork/patch/1263411/#1468420

Signed-off-by: Iskren Chernev 
Reviewed-by: Rob Herring 
---
 .../bindings/power/supply/max17040_battery.txt| 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 4e0186b8380fa..554bce82a08e6 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -2,7 +2,9 @@ max17040_battery
 
 
 Required properties :
- - compatible : "maxim,max17040" or "maxim,max77836-battery"
+ - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
+   "maxim,max17044", "maxim,max17048", "maxim,max17049",
+   "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
  - reg: i2c slave address
 
 Optional properties :
@@ -11,6 +13,10 @@ Optional properties :
generated. Can be configured from 1 up to 32
(%). If skipped the power up default value of
4 (%) will be used.
+- maxim,double-soc :   Certain devices return double the capacity.
+   Specify this boolean property to divide the
+   reported value in 2 and thus normalize it.
+   SOC == State of Charge == Capacity.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -31,3 +37,10 @@ Example:
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
wakeup-source;
};
+
+   battery-fuel-gauge@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+   maxim,alert-low-soc-level = <10>;
+   maxim,double-soc;
+   };
-- 
2.28.0



[PATCH v4 6/7] power: supply: max17040: Support setting rcomp

2020-09-06 Thread Iskren Chernev
The Maxim ModelGauge family supports fine-tuning by setting
a compensation value (named rcomp in the docs). The value is affected by
battery chemistry and ambient temperature.

Add support for reading maxim,rcomp from DT and configuring the device
with the supplied value. Temperature adjustment is not implemented at
the moment, because there is no provision for receiving the ambient
temperature at the moment.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/max17040_battery.c | 40 +
 1 file changed, 40 insertions(+)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 3d5003e3a277a..6ead2fded6a96 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -30,9 +30,11 @@
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
+#define MAX17040_RCOMP_DEFAULT  0x9700
 
 #define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_CFG_RCOMP_MASK0xff00
 
 enum chip_id {
ID_MAX17040,
@@ -52,6 +54,7 @@ struct chip_data {
u16 vcell_mul;
u16 vcell_div;
u8  has_low_soc_alert;
+   u8  rcomp_bytes;
 };
 
 static struct chip_data max17040_family[] = {
@@ -61,6 +64,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 1250,
.vcell_div = 1,
.has_low_soc_alert = 0,
+   .rcomp_bytes = 2,
},
[ID_MAX17041] = {
.reset_val = 0x0054,
@@ -68,6 +72,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 2500,
.vcell_div = 1,
.has_low_soc_alert = 0,
+   .rcomp_bytes = 2,
},
[ID_MAX17043] = {
.reset_val = 0x0054,
@@ -75,6 +80,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 1250,
.vcell_div = 1,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17044] = {
.reset_val = 0x0054,
@@ -82,6 +88,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 2500,
.vcell_div = 1,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17048] = {
.reset_val = 0x5400,
@@ -89,6 +96,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 8,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17049] = {
.reset_val = 0x5400,
@@ -96,6 +104,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 4,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17058] = {
.reset_val = 0x5400,
@@ -103,6 +112,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 8,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17059] = {
.reset_val = 0x5400,
@@ -110,6 +120,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 4,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
 };
 
@@ -129,6 +140,8 @@ struct max17040_chip {
u32 low_soc_alert;
/* some devices return twice the capacity */
bool quirk_double_soc;
+   /* higher 8 bits for 17043+, 16 bits for 17040,41 */
+   u16 rcomp;
 };
 
 static int max17040_reset(struct max17040_chip *chip)
@@ -143,6 +156,14 @@ static int max17040_set_low_soc_alert(struct max17040_chip 
*chip, u32 level)
MAX17040_ATHD_MASK, level);
 }
 
+static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
+{
+   u16 mask = chip->data.rcomp_bytes == 2 ?
+   0x : MAX17040_CFG_RCOMP_MASK;
+
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG, mask, rcomp);
+}
+
 static int max17040_raw_vcell_to_uvolts(struct max17040_chip *chip, u16 vcell)
 {
struct chip_data *d = &chip->data;
@@ -206,6 +227,10 @@ static int max17040_get_status(struct max17040_chip *chip)
 static int max17040_get_of_data(struct max17040_chip *chip)
 {
struct device *dev = &chip->client->dev;
+   struct chip_data *data = &max17040_family[
+   (enum chip_id) of_device_get_match_data(dev)];
+   int rcomp_len;
+   u8 rcomp[2];
 
chip->quirk_double_soc = device_property_read_bool(dev,
   "maxim,double-soc");
@@ -221,6 +246,19 @@ static int max17040_get_of_data(struct max17040_chip *chip)
retur

[PATCH v4 7/7] power: supply: max17040: Support soc alert

2020-09-06 Thread Iskren Chernev
max17048 and max17049 support SOC alerts (interrupts when battery
capacity changes by +/- 1%). At the moment the driver polls for changes
every second. Using the alerts removes the need for polling.

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/max17040_battery.c | 82 ++---
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 6ead2fded6a96..1c4cb7ddc785c 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -25,6 +25,7 @@
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
 #define MAX17040_CONFIG0x0C
+#define MAX17040_STATUS0x1A
 #define MAX17040_CMD   0xFE
 
 
@@ -33,7 +34,10 @@
 #define MAX17040_RCOMP_DEFAULT  0x9700
 
 #define MAX17040_ATHD_MASK 0x3f
+#define MAX17040_ALSC_MASK 0x40
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_STATUS_HD_MASK0x1000
+#define MAX17040_STATUS_SC_MASK0x2000
 #define MAX17040_CFG_RCOMP_MASK0xff00
 
 enum chip_id {
@@ -55,6 +59,7 @@ struct chip_data {
u16 vcell_div;
u8  has_low_soc_alert;
u8  rcomp_bytes;
+   u8  has_soc_alert;
 };
 
 static struct chip_data max17040_family[] = {
@@ -65,6 +70,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 0,
.rcomp_bytes = 2,
+   .has_soc_alert = 0,
},
[ID_MAX17041] = {
.reset_val = 0x0054,
@@ -73,6 +79,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 0,
.rcomp_bytes = 2,
+   .has_soc_alert = 0,
},
[ID_MAX17043] = {
.reset_val = 0x0054,
@@ -81,6 +88,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17044] = {
.reset_val = 0x0054,
@@ -89,6 +97,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17048] = {
.reset_val = 0x5400,
@@ -97,6 +106,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 8,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 1,
},
[ID_MAX17049] = {
.reset_val = 0x5400,
@@ -105,6 +115,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 4,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 1,
},
[ID_MAX17058] = {
.reset_val = 0x5400,
@@ -113,6 +124,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 8,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17059] = {
.reset_val = 0x5400,
@@ -121,6 +133,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 4,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
 };
 
@@ -156,6 +169,12 @@ static int max17040_set_low_soc_alert(struct max17040_chip 
*chip, u32 level)
MAX17040_ATHD_MASK, level);
 }
 
+static int max17040_set_soc_alert(struct max17040_chip *chip, bool enable)
+{
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
+   MAX17040_ALSC_MASK, enable ? MAX17040_ALSC_MASK : 0);
+}
+
 static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
 {
u16 mask = chip->data.rcomp_bytes == 2 ?
@@ -300,11 +319,33 @@ static void max17040_work(struct work_struct *work)
max17040_queue_work(chip);
 }
 
+/* Returns true if alert cause was SOC change, not low SOC */
+static bool max17040_handle_soc_alert(struct max17040_chip *chip)
+{
+   bool ret = true;
+   u32 data;
+
+   regmap_read(chip->regmap, MAX17040_STATUS, &data);
+
+   if (data & MAX17040_STATUS_HD_MASK) {
+   // this alert was caused by low soc
+   ret = false;
+   }
+   if (data & MAX17040_STATUS_SC_MASK) {
+   // soc change bit -- deassert to mark as handled
+   regmap_write(chip->regmap, MAX17040_STATUS,
+   data & ~MAX17040_STATUS_SC_MASK);
+   }
+
+   return ret;
+}
+
 static irqreturn_t max17040_thread_handler(int id, void *dev)
 {
struct max17040_chip *chip = dev;
 
-   dev_warn(&chip-&

[PATCH v4 4/7] power: supply: max17040: Support compatible devices

2020-09-06 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very
similar mode of operations and registers.

This change adds:
- compatible strings for all supported devices and handling for the
  minor differences between them;
- handling for devices reporting double capacity via maxim,double-soc;

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

Signed-off-by: Iskren Chernev 
Tested-by: Jonathan Bakker 
---
 drivers/power/supply/Kconfig|  10 +-
 drivers/power/supply/max17040_battery.c | 154 +---
 2 files changed, 142 insertions(+), 22 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 1e11a44077dde..f51ae86788ded 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -369,9 +369,13 @@ config BATTERY_MAX17040
depends on I2C
select REGMAP_I2C
help
- MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
- in handheld and portable equipment. The MAX17040 is configured
- to operate with a single lithium cell
+ Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
+ (Li+) batteries in handheld and portable equipment, including
+ max17040, max17041, max17043, max17044, max17048, max17049, max17058,
+ max17059. It is also included in some batteries like max77836.
+
+ Driver supports reporting SOC (State of Charge, i.e capacity),
+ voltage and configurable low-SOC wakeup interrupt.
 
 config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index fae4217960761..3d5003e3a277a 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -33,12 +34,92 @@
 #define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
 
+enum chip_id {
+   ID_MAX17040,
+   ID_MAX17041,
+   ID_MAX17043,
+   ID_MAX17044,
+   ID_MAX17048,
+   ID_MAX17049,
+   ID_MAX17058,
+   ID_MAX17059,
+};
+
+/* values that differ by chip_id */
+struct chip_data {
+   u16 reset_val;
+   u16 vcell_shift;
+   u16 vcell_mul;
+   u16 vcell_div;
+   u8  has_low_soc_alert;
+};
+
+static struct chip_data max17040_family[] = {
+   [ID_MAX17040] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .has_low_soc_alert = 0,
+   },
+   [ID_MAX17041] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .has_low_soc_alert = 0,
+   },
+   [ID_MAX17043] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17044] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17048] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 8,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17049] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 4,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17058] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 8,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17059] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 4,
+   .has_low_soc_alert = 1,
+   },
+};
+
 struct max17040_chip {
struct i2c_client   *client;
struct regmap   *regmap;
struct delayed_work work;
struct power_supply *battery;
struct max17040_platform_data   *pdata;
+   struct chip_datadata;
 
/* battery capacity */
int soc;
@@ -46,27 +127,37 @@ struct max17040_chip {
int status;
/* Low alert threshold from 32% to 1% of the State

[PATCH v4 5/7] dt-bindings: power: supply: max17040: Add maxim,rcomp

2020-09-06 Thread Iskren Chernev
To compensate for the battery chemistry and operating conditions the
chips support a compensation value. Specify one or two byte compensation
via the maxim,rcomp byte array.

Signed-off-by: Iskren Chernev 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/power/supply/max17040_battery.txt   | 6 ++
 1 file changed, 6 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 554bce82a08e6..2cf046d12d922 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -17,6 +17,11 @@ Optional properties :
Specify this boolean property to divide the
reported value in 2 and thus normalize it.
SOC == State of Charge == Capacity.
+- maxim,rcomp :A value to compensate readings for 
various
+   battery chemistries and operating temperatures.
+   max17040,41 have 2 byte rcomp, default to
+   0x97 0x00. All other devices have one byte
+   rcomp, default to 0x97.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -41,6 +46,7 @@ Example:
battery-fuel-gauge@36 {
compatible = "maxim,max17048";
reg = <0x36>;
+   maxim,rcomp = /bits/ 8 <0x56>;
maxim,alert-low-soc-level = <10>;
maxim,double-soc;
};
-- 
2.28.0



[PATCH v4 0/7] power: supply: max17040 support compatible devices

2020-09-06 Thread Iskren Chernev
From: Iskren Chernev 

The max17040 fuel gauge is part of a family of 8 chips that have very similar
mode of operations and registers.

This patch set adds:
- compatible strings for all supported devices and handles the minor
  differences between them;
- handling for devices reporting double capacity via maxim,double-soc;
- handling for setting rcomp, a compensation value for more accurate reading,
  affected by battery chemistry and operating temps;
- suppot for SOC alerts (capacity changes by +/- 1%), to prevent polling every
  second;
- improved max17040 driver with regmap and devm_

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

v3: https://lkml.org/lkml/2020/6/24/874
v2: https://lkml.org/lkml/2020/6/18/260
v1: https://lkml.org/lkml/2020/6/8/682

Changes in v4:
- split refactor patch into devm_ and regmap patches (as suggested by
  Sebastian Reichel)
- correct handling of soc alert for double-soc devices
- rebased on 5.9-rc, incorporating upstream work

Iskren Chernev (7):
  power: supply: max17040: Use devm_ to automate remove
  power: supply: max17040: Use regmap i2c
  dt-bindings: power: supply: Extend max17040 compatibility
  power: supply: max17040: Support compatible devices
  dt-bindings: power: supply: max17040: Add maxim,rcomp
  power: supply: max17040: Support setting rcomp
  power: supply: max17040: Support soc alert

 .../power/supply/max17040_battery.txt |  21 +-
 drivers/power/supply/Kconfig  |  11 +-
 drivers/power/supply/max17040_battery.c   | 488 --
 3 files changed, 366 insertions(+), 154 deletions(-)


base-commit: b36c969764ab12faebb74711c942fa3e6eaf1e96
--
2.28.0



Re: [PATCH v3 2/6] dt-bindings: power: supply: Extend max17040 compatibility

2020-07-14 Thread Iskren Chernev


On 7/13/20 10:03 PM, Rob Herring wrote:
> On Wed, Jun 24, 2020 at 06:56:29PM +0300, Iskren Chernev wrote:
>> Maxim max17040 is a fuel gauge from a larger family utilising the Model
>> Gauge technology. Document all different compatible strings that the
>> max17040 driver recognizes.
>>
>> Some devices in the wild report double the capacity. The
>> maxim,double-soc (from State-Of-Charge) property fixes that.
>>
>> Signed-off-by: Iskren Chernev 
>> ---
>>  .../bindings/power/supply/max17040_battery.txt    | 15 ++-
>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
>> b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> index 4e0186b8380fa..554bce82a08e6 100644
>> --- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> +++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> @@ -2,7 +2,9 @@ max17040_battery
>>  
>>
>>  Required properties :
>> - - compatible : "maxim,max17040" or "maxim,max77836-battery"
>> + - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
>> +         "maxim,max17044", "maxim,max17048", "maxim,max17049",
>> +        "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
>>   - reg: i2c slave address
>>
>>  Optional properties :
>> @@ -11,6 +13,10 @@ Optional properties :
>>                  generated. Can be configured from 1 up to 32
>>                  (%). If skipped the power up default value of
>>                  4 (%) will be used.
>> +- maxim,double-soc :         Certain devices return double the capacity.
>> +                Specify this boolean property to divide the
>> +                reported value in 2 and thus normalize it.
>> +                SOC == State of Charge == Capacity.
>
> This can't be implied by the compatible string?
>

>From what I can tell - no. Here are multiple examples of downstream code:

For max17043:
- single soc [1]
- double soc [2]
- both (toggle with macro) [3]

For max17048:
- single soc [4]
- double soc [5]
- both (toggle with dts) [6], docs [7]

For max17058:
- both (toggle with macro) [8], this device is single
- both (toggle with dts) [9], this device is double [10]

[1] 
https://github.com/LineageOS/lge-kernel-sniper/blob/9907b1312e9b4c5c4f73ac9bf2e772b12e1c9145/drivers/power/max17043_fuelgauge.c#L383
[2] 
https://github.com/LineageOS/android_kernel_lge_v500/blob/b4fe00e1f8f09c173a6c28a42ca69ff9529cc13b/drivers/power/max17043_fuelgauge.c#L307
[3] 
https://github.com/LineageOS/lge-kernel-p880/blob/c5795644a60338f88c7aa29208efadde835ea769/drivers/power/max17043_fuelgauge.c#L406
[4] 
https://github.com/LineageOS/lge-kernel-star/blob/d963160ebd8e64263ed740d5f1e1a0324085a826/drivers/power/max17048_battery.c#L168
[5] 
https://github.com/LineageOS/android_kernel_samsung_p4/blob/b190cf1bf4ca0e597a51c820a323f2aa3b2c8585/drivers/power/max17048_battery.c#L192
[6] 
https://github.com/LineageOS/android_kernel_htc_flounder/blob/03e0b4f36fc60c226adacdb48306df9ec65de33b/drivers/power/max17048_battery.c#L248
[7] 
https://github.com/LineageOS/android_kernel_htc_flounder/blob/03e0b4f36fc60c226adacdb48306df9ec65de33b/Documentation/devicetree/bindings/power_supply/max17048_battery.txt#L23
[8] 
https://github.com/LineageOS/android_kernel_asus_moorefield/blob/c3eae894ce8092c2a9a51f9a4924c8df714d6b3c/drivers/power/ASUS_BATTERY/max17058_battery.c#L551
[9] 
https://github.com/LineageOS/android_kernel_motorola_msm8916/blob/415000d938de1aa46206043e06f033edf33557ce/drivers/power/max17058_battery.c#L225
[10] 
https://github.com/LineageOS/android_kernel_motorola_msm8916/blob/415000d938de1aa46206043e06f033edf33557ce/arch/arm/boot/dts/qcom/msm8916-harpia-p0a.dts#L59

>>  - interrupts :             Interrupt line see Documentation/devicetree/
>>                  bindings/interrupt-controller/interrupts.txt
>>  - wakeup-source :        This device has wakeup capabilities. Use this
>> @@ -31,3 +37,10 @@ Example:
>>          interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
>>          wakeup-source;
>>      };
>> +
>> +    battery-fuel-gauge@36 {
>> +        compatible = "maxim,max17048";
>> +        reg = <0x36>;
>> +        maxim,alert-low-soc-level = <10>;
>> +        maxim,double-soc;
>> +    };
>> --
>> 2.27.0
>>



Re: [PATCH 0/7] ARM: dts: qcom: msm8974: klte: Enable some hardware

2020-07-01 Thread Iskren Chernev


On 7/1/20 1:30 PM, Brian Masney wrote:
> Hi Iskren,
>
> On Tue, Jun 30, 2020 at 05:09:05PM +0300, Iskren Chernev wrote:
>> Enable support for various hw found on the Samsung Galaxy S5:
>> - touchkey (the two buttons around the home button)
>> - touchscreen
>> - notification led
>> - wifi
>> - external SD card
>>
>> Please note that for working wifi the correct firmware is needed. Check [1]
>> for links and locations.
>>
>> Also note, that to actually run a mainline kernel on the klte, you'd need
>> to apply this patch [2]. Any feedback on getting this to run on pure
>> mainline are welcome.
>>
>> [1] 
>> https://gitlab.com/postmarketOS/pmaports/-/blob/master/firmware/firmware-samsung-klte/APKBUILD
>> [2] 
>> https://gitlab.com/postmarketOS/linux-postmarketos/-/commit/765f55b248cd3b231af8431fe2f2aeca263b4e4b
>
> Good to see more msm8974 support upstream!
>
> Regarding the second patch, that should only be needed in order to
> use the GPU on these devices.

For the klte, without this delay rpm init patch, the device reboots soon
after being booted. I tested with pure v5.8 and next-20200701 (both have
basic klte support, including usb ethernet for ssh). With the patch
applied, it works like a charm.

Note that there is no GPU enabled in this setup (unless I'm missing some
piece from the SOC dtsi).

> I hope that patch won't be needed once
> IOMMU support is added, which is the last major missing piece in order
> to have the GPU working upstream. I posted a RFC patch [3] in January
> but didn't get any suggestions. I suspect some kind of memory corruption
> since the board gets unstable with that patch.

If the IOMMU is only used for graphics, then the problem remains for klte.

> If that hack patch is still needed to use the GPU once IOMMU support is
> in place, then I planned to troubleshoot it further by adding some log
> statements to various probe functions with and without that patch to see
> the probe order between the various subsystems. I suspect the issue is
> that a clock isn't ticking yet.
>
> [3] 
> https://lore.kernel.org/lkml/20200109002606.35653-1-masn...@onstation.org/T/#u

I'll be happy to help with that.

> Brian

Iskren



[PATCH 3/7] ARM: dts: qcom: msm8974-klte: Add support for touchscreen

2020-06-30 Thread Iskren Chernev
Add support for the touchscreen found on the Samsung Galaxy S5.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 54 +++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 750e2f261139a..085636f182d01 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -284,6 +284,16 @@ cmd-data {
};
};
 
+   i2c2_pins: i2c2 {
+   mux {
+   pins = "gpio6", "gpio7";
+   function = "blsp_i2c2";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
+
i2c6_pins: i2c6 {
mux {
pins = "gpio29", "gpio30";
@@ -342,6 +352,42 @@ phy@a {
};
};
 
+   i2c@f9924000 {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c2_pins>;
+
+   touchscreen@20 {
+   compatible = "syna,rmi4-i2c";
+   reg = <0x20>;
+
+   interrupt-parent = <&pma8084_gpios>;
+   interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+
+   vdd-supply = <&max77826_ldo13>;
+   vio-supply = <&pma8084_lvs2>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&touch_pin>;
+
+   syna,startup-delay-ms = <100>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   rmi4-f01@1 {
+   reg = <0x1>;
+   syna,nosleep-mode = <1>;
+   };
+
+   rmi4-f12@12 {
+   reg = <0x12>;
+   syna,sensor-type = <1>;
+   };
+   };
+   };
+
i2c@f9928000 {
status = "okay";
 
@@ -460,6 +506,14 @@ touchkey_pin: touchkey-int-pin {
input-enable;
power-source = ;
};
+
+   touch_pin: touchscreen-int-pin {
+   pins = "gpio8";
+   function = "normal";
+   bias-disable;
+   input-enable;
+   power-source = ;
+   };
};
};
 };
-- 
2.27.0



[PATCH 7/7] ARM: dts: qcom: msm8974-klte: Add support for SD card

2020-06-30 Thread Iskren Chernev
The Samsung Galaxy S5 (klte), has 3 SDHCI nodes used for internal
storage, WiFi, external SD card slot. The external SD card slot is
similar to the internal storage.

The device has support for CD (card detect), but if enabled, the card is
not initialized properly if present during startup. That is why CD is
disabled and polling is used instead. Related thread [1]

[1] 
https://lore.kernel.org/linux-mmc/491cfef4-4a97-b6e8-0f41-d44e1c73e...@gmail.com/

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 44 ++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 989447beb4319..b0899107f3ced 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -12,6 +12,8 @@ / {

aliases {
serial0 = &blsp1_uart1;
+   sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
+   sdhc2 = &sdhc_2; /* SDC2 SD card slot */
};

chosen {
@@ -161,6 +163,9 @@ pma8084_l20: l20 {
pma8084_l21: l21 {
regulator-min-microvolt = 
<295>;
regulator-max-microvolt = 
<295>;
+
+   regulator-allow-set-load;
+   regulator-system-load = 
<20>;
};

pma8084_l22: l22 {
@@ -349,6 +354,24 @@ cmd-data {
};
};

+   sdhc2_pin_a: sdhc2-pin-active {
+   clk-cmd-data {
+   pins = "gpio35", "gpio36", "gpio37", "gpio38",
+   "gpio39", "gpio40";
+   function = "sdc3";
+   drive-strength = <8>;
+   bias-disable;
+   };
+   };
+
+   sdhc2_cd_pin: sdhc2-cd {
+   pins = "gpio62";
+   function = "gpio";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+
sdhc3_pin_a: sdhc3-pin-active {
clk {
pins = "sdc2_clk";
@@ -422,7 +445,7 @@ int {
};
};

-   sdhci@f9824900 {
+   sdhc_1: sdhci@f9824900 {
status = "ok";

vmmc-supply = <&pma8084_l20>;
@@ -435,6 +458,25 @@ sdhci@f9824900 {
pinctrl-0 = <&sdhc1_pin_a>;
};

+   sdhc_2: sdhci@f9864900 {
+   status = "ok";
+
+   max-frequency = <1>;
+
+   vmmc-supply = <&pma8084_l21>;
+   vqmmc-supply = <&pma8084_l13>;
+
+   bus-width = <4>;
+
+   /* cd-gpio is intentionally disabled. If enabled, an SD card
+* present during boot is not initialized correctly. Without
+* cd-gpios the driver resorts to polling, so hotplug works.
+*/
+   pinctrl-names = "default";
+   pinctrl-0 = <&sdhc2_pin_a /* &sdhc2_cd_pin */>;
+   // cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
+   };
+
sdhci@f98a4900 {
status = "okay";

--
2.27.0



[PATCH 6/7] ARM: dts: qcom: msm8974-klte: Add support for wifi

2020-06-30 Thread Iskren Chernev
The Samsung Galaxy S5 (klte), uses a Broadcom 4354 Chip connected on the
SDIO bus. The chip also requires a corresponding firmware + txt file[1].

[1] 
https://gitlab.com/postmarketOS/pmaports/-/blob/master/firmware/firmware-samsung-klte/APKBUILD

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 74 +++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 29099b83b231d..989447beb4319 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -282,6 +282,17 @@ led@3 {
};
};
 
+   vreg_wlan: wlan-regulator {
+   compatible = "regulator-fixed";
+
+   regulator-name = "wl-reg";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+
+   gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>;
+   enable-active-high;
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -338,6 +349,20 @@ cmd-data {
};
};
 
+   sdhc3_pin_a: sdhc3-pin-active {
+   clk {
+   pins = "sdc2_clk";
+   drive-strength = <6>;
+   bias-disable;
+   };
+
+   cmd-data {
+   pins = "sdc2_cmd", "sdc2_data";
+   drive-strength = <6>;
+   bias-pull-up;
+   };
+   };
+
i2c2_pins: i2c2 {
mux {
pins = "gpio6", "gpio7";
@@ -385,6 +410,16 @@ res {
drive-strength = <2>;
};
};
+
+   wifi_pin: wifi {
+   int {
+   pins = "gpio92";
+   function = "gpio";
+
+   input-enable;
+   bias-pull-down;
+   };
+   };
};
 
sdhci@f9824900 {
@@ -400,6 +435,36 @@ sdhci@f9824900 {
pinctrl-0 = <&sdhc1_pin_a>;
};
 
+   sdhci@f98a4900 {
+   status = "okay";
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   max-frequency = <1>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&sdhc3_pin_a>;
+
+   vmmc-supply = <&vreg_wlan>;
+   vqmmc-supply = <&pma8084_s4>;
+
+   bus-width = <4>;
+   non-removable;
+
+   wifi@1 {
+   reg = <1>;
+   compatible = "brcm,bcm4329-fmac";
+
+   interrupt-parent = <&msmgpio>;
+   interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "host-wake";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
+   };
+   };
+
usb@f9a55000 {
status = "ok";
 
@@ -587,6 +652,15 @@ touch_pin: touchscreen-int-pin {
input-enable;
power-source = ;
};
+
+   wlan_sleep_clk_pin: wlan-sleep-clk-pin {
+   pins = "gpio16";
+   function = "func2";
+
+   output-high;
+   power-source = ;
+   qcom,drive-strength = ;
+   };
};
};
 };
-- 
2.27.0



[PATCH 5/7] ARM: dts: qcom: msm8974-klte: Add gpio expander chip

2020-06-30 Thread Iskren Chernev
The Samsung Galaxy S5 has a GPIO Expander chip, the PCAL6416A with 16
ports on a i2c bus. These pins are used for WiFi, NFC, IR among other
things.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 29 +--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 7b398da9b75ed..29099b83b231d 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -236,10 +236,25 @@ i2c-gpio-led {
scl-gpios = <&msmgpio 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&msmgpio 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
pinctrl-names = "default";
-   pinctrl-0 = <&i2c_led_pins>;
+   pinctrl-0 = <&i2c_led_gpioex_pins>;
 
i2c-gpio,delay-us = <2>;
 
+   gpio_expander: gpio@20 {
+   compatible = "nxp,pcal6416";
+   reg = <0x20>;
+
+   gpio-controller;
+   #gpio-cells = <2>;
+
+   vcc-supply = <&pma8084_s4>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&gpioex_pin>;
+
+   reset-gpios = <&msmgpio 145 GPIO_ACTIVE_LOW>;
+   };
+
led-controller@30 {
compatible = "panasonic,an30259a";
reg = <0x30>;
@@ -352,7 +367,7 @@ mux {
};
};
 
-   i2c_led_pins: i2c-led {
+   i2c_led_gpioex_pins: i2c-led-gpioex {
mux {
pins = "gpio120", "gpio121";
function = "gpio";
@@ -360,6 +375,16 @@ mux {
bias-pull-down;
};
};
+
+   gpioex_pin: gpioex {
+   res {
+   pins = "gpio145";
+   function = "gpio";
+
+   bias-pull-up;
+   drive-strength = <2>;
+   };
+   };
};
 
sdhci@f9824900 {
-- 
2.27.0



[PATCH 1/7] ARM: dts: qcom: msm8974-klte: Merge pinctrl nodes

2020-06-30 Thread Iskren Chernev
commit cd13c72c1853 ("ARM: dts: qcom: msm8974-klte: Add max77826 pmic
node") and commit 8bf7a360a92c ("ARM: dts: qcom: msm8974-klte: Add sdhci1
node") both added pinctrl node. This patch merges the two nodes.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 22 +--
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index d4dc98214225a..9520c6e7910ce 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -258,6 +258,16 @@ cmd-data {
bias-pull-up;
};
};
+
+   i2c6_pins: i2c6 {
+   mux {
+   pins = "gpio29", "gpio30";
+   function = "blsp_i2c6";
+
+   drive-strength = <2>;
+   bias-disable;
+   };
+   };
};

sdhci@f9824900 {
@@ -298,18 +308,6 @@ phy@a {
};
};

-   pinctrl@fd51 {
-   i2c6_pins: i2c6 {
-   mux {
-   pins = "gpio29", "gpio30";
-   function = "blsp_i2c6";
-
-   drive-strength = <2>;
-   bias-disable;
-   };
-   };
-   };
-
i2c@f9928000 {
status = "okay";

--
2.27.0



[PATCH 4/7] ARM: dts: qcom: msm8974-klte: Add support for led

2020-06-30 Thread Iskren Chernev
The klte uses a Panasonic AN30259A LED controller for it's indicator
led.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 48 +++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 085636f182d01..7b398da9b75ed 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
model = "Samsung Galaxy S5";
@@ -228,6 +229,44 @@ touchkey@20 {
};
};
 
+   i2c-gpio-led {
+   compatible = "i2c-gpio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   scl-gpios = <&msmgpio 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   sda-gpios = <&msmgpio 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c_led_pins>;
+
+   i2c-gpio,delay-us = <2>;
+
+   led-controller@30 {
+   compatible = "panasonic,an30259a";
+   reg = <0x30>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   led@1 {
+   reg = <1>;
+   function = LED_FUNCTION_STATUS;
+   color = ;
+   };
+
+   led@2 {
+   reg = <2>;
+   function = LED_FUNCTION_STATUS;
+   color = ;
+   };
+
+   led@3 {
+   reg = <3>;
+   function = LED_FUNCTION_STATUS;
+   color = ;
+   };
+   };
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -312,6 +351,15 @@ mux {
bias-pull-up;
};
};
+
+   i2c_led_pins: i2c-led {
+   mux {
+   pins = "gpio120", "gpio121";
+   function = "gpio";
+   input-enable;
+   bias-pull-down;
+   };
+   };
};
 
sdhci@f9824900 {
-- 
2.27.0



[PATCH 0/7] ARM: dts: qcom: msm8974: klte: Enable some hardware

2020-06-30 Thread Iskren Chernev
Enable support for various hw found on the Samsung Galaxy S5:
- touchkey (the two buttons around the home button)
- touchscreen
- notification led
- wifi
- external SD card

Please note that for working wifi the correct firmware is needed. Check [1]
for links and locations.

Also note, that to actually run a mainline kernel on the klte, you'd need
to apply this patch [2]. Any feedback on getting this to run on pure
mainline are welcome.

[1] 
https://gitlab.com/postmarketOS/pmaports/-/blob/master/firmware/firmware-samsung-klte/APKBUILD
[2] 
https://gitlab.com/postmarketOS/linux-postmarketos/-/commit/765f55b248cd3b231af8431fe2f2aeca263b4e4b

Iskren Chernev (7):
  ARM: dts: qcom: msm8974-klte: Merge pinctrl nodes
  ARM: dts: qcom: msm8974-klte: Add support for touchkey
  ARM: dts: qcom: msm8974-klte: Add support for touchscreen
  ARM: dts: qcom: msm8974-klte: Add support for led
  ARM: dts: qcom: msm8974-klte: Add gpio expander chip
  ARM: dts: qcom: msm8974-klte: Add support for wifi
  ARM: dts: qcom: msm8974-klte: Add support for SD card

 .../boot/dts/qcom-msm8974-samsung-klte.dts| 301 +-
 1 file changed, 292 insertions(+), 9 deletions(-)


base-commit: c28e58ee9dadc99f79cf16ca805221feddd432ad
--
2.27.0



[PATCH 2/7] ARM: dts: qcom: msm8974-klte: Add support for touchkey

2020-06-30 Thread Iskren Chernev
Add support for the touchkey found on the Samsung Galaxy S5. The
touchkey is responsible for handling the application and back buttons
found around the home button.

Signed-off-by: Iskren Chernev 
---
 .../boot/dts/qcom-msm8974-samsung-klte.dts| 44 ++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts 
b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
index 9520c6e7910ce..750e2f261139a 100644
--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -145,7 +145,7 @@ pma8084_l18: l18 {
};
 
pma8084_l19: l19 {
-   regulator-min-microvolt = 
<290>;
+   regulator-min-microvolt = 
<330>;
regulator-max-microvolt = 
<330>;
};
 
@@ -203,6 +203,31 @@ pma8084_l27: l27 {
};
};
 
+   i2c-gpio-touchkey {
+   compatible = "i2c-gpio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   sda-gpios = <&msmgpio 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   scl-gpios = <&msmgpio 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c_touchkey_pins>;
+
+   touchkey@20 {
+   compatible = "cypress,tm2-touchkey";
+   reg = <0x20>;
+
+   interrupt-parent = <&pma8084_gpios>;
+   interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&touchkey_pin>;
+
+   vcc-supply = <&max77826_ldo15>;
+   vdd-supply = <&pma8084_l19>;
+
+   linux,keycodes = ;
+   };
+   };
+
/delete-node/ vreg-boost;
 };
 
@@ -268,6 +293,15 @@ mux {
bias-disable;
};
};
+
+   i2c_touchkey_pins: i2c-touchkey {
+   mux {
+   pins = "gpio95", "gpio96";
+   function = "gpio";
+   input-enable;
+   bias-pull-up;
+   };
+   };
};
 
sdhci@f9824900 {
@@ -418,6 +452,14 @@ gpio_keys_pin_a: gpio-keys-active {
bias-pull-up;
power-source = ;
};
+
+   touchkey_pin: touchkey-int-pin {
+   pins = "gpio6";
+   function = "normal";
+   bias-disable;
+   input-enable;
+   power-source = ;
+   };
};
};
 };
-- 
2.27.0



[PATCH v3 5/6] power: supply: max17040: Support setting rcomp

2020-06-24 Thread Iskren Chernev
The Maxim ModelGauge family supports fine-tuning by setting
a compensation value (named rcomp in the docs). The value is affected by
battery chemistry and ambient temperature.

Add support for reading maxim,rcomp from DT and configuring the device
with the supplied value. Temperature adjustment is not implemented, because
there is no provision for receiving the ambient temperature.

Signed-off-by: Iskren Chernev 
---
 drivers/power/supply/max17040_battery.c | 40 +
 1 file changed, 40 insertions(+)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index a6ecd84194e51..54393f411211e 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -30,9 +30,11 @@
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
+#define MAX17040_RCOMP_DEFAULT  0x9700
 
 #define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_CFG_RCOMP_MASK0xff00
 
 enum chip_id {
ID_MAX17040,
@@ -52,6 +54,7 @@ struct chip_data {
u16 vcell_mul;
u16 vcell_div;
u8  has_low_soc_alert;
+   u8  rcomp_bytes;
 };
 
 static struct chip_data max17040_family[] = {
@@ -61,6 +64,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 1250,
.vcell_div = 1,
.has_low_soc_alert = 0,
+   .rcomp_bytes = 2,
},
[ID_MAX17041] = {
.reset_val = 0x0054,
@@ -68,6 +72,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 2500,
.vcell_div = 1,
.has_low_soc_alert = 0,
+   .rcomp_bytes = 2,
},
[ID_MAX17043] = {
.reset_val = 0x0054,
@@ -75,6 +80,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 1250,
.vcell_div = 1,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17044] = {
.reset_val = 0x0054,
@@ -82,6 +88,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 2500,
.vcell_div = 1,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17048] = {
.reset_val = 0x5400,
@@ -89,6 +96,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 8,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17049] = {
.reset_val = 0x5400,
@@ -96,6 +104,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 4,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17058] = {
.reset_val = 0x5400,
@@ -103,6 +112,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 8,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
[ID_MAX17059] = {
.reset_val = 0x5400,
@@ -110,6 +120,7 @@ static struct chip_data max17040_family[] = {
.vcell_mul = 625,
.vcell_div = 4,
.has_low_soc_alert = 1,
+   .rcomp_bytes = 1,
},
 };
 
@@ -129,6 +140,8 @@ struct max17040_chip {
u32 low_soc_alert;
/* some devices return twice the capacity */
bool quirk_double_soc;
+   /* higher 8 bits for 17043+, 16 bits for 17040,41 */
+   u16 rcomp;
 };
 
 static int max17040_reset(struct max17040_chip *chip)
@@ -143,6 +156,14 @@ static int max17040_set_low_soc_alert(struct max17040_chip 
*chip, u32 level)
MAX17040_ATHD_MASK, level);
 }
 
+static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
+{
+   u16 mask = chip->data.rcomp_bytes == 2 ?
+   0x : MAX17040_CFG_RCOMP_MASK;
+
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG, mask, rcomp);
+}
+
 static int max17040_raw_vcell_to_uvolts(struct max17040_chip *chip, u16 vcell)
 {
struct chip_data *d = &chip->data;
@@ -206,6 +227,10 @@ static int max17040_get_status(struct max17040_chip *chip)
 static int max17040_get_of_data(struct max17040_chip *chip)
 {
struct device *dev = &chip->client->dev;
+   struct chip_data *data = &max17040_family[
+   (enum chip_id) of_device_get_match_data(dev)];
+   int rcomp_len;
+   u8 rcomp[2];
 
chip->low_soc_alert = MAX17040_ATHD_DEFAULT_POWER_UP;
device_property_read_u32(dev,
@@ -219,6 +244,19 @@ static int max17040_get_of_data(struct max17040_chip *chip)
chip->quirk_double_soc = device_property_read_bool(dev,
   "m

[PATCH v3 4/6] dt-bindings: power: supply: max17040: Add maxim,rcomp

2020-06-24 Thread Iskren Chernev
To compensate for the battery chemistry and operating conditions the
chips support a compensation value. Specify one or two byte compensation
via the maxim,rcomp byte array.

Signed-off-by: Iskren Chernev 
---
 .../devicetree/bindings/power/supply/max17040_battery.txt   | 6 ++
 1 file changed, 6 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 554bce82a08e6..2cf046d12d922 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -17,6 +17,11 @@ Optional properties :
Specify this boolean property to divide the
reported value in 2 and thus normalize it.
SOC == State of Charge == Capacity.
+- maxim,rcomp :A value to compensate readings for 
various
+   battery chemistries and operating temperatures.
+   max17040,41 have 2 byte rcomp, default to
+   0x97 0x00. All other devices have one byte
+   rcomp, default to 0x97.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -41,6 +46,7 @@ Example:
battery-fuel-gauge@36 {
compatible = "maxim,max17048";
reg = <0x36>;
+   maxim,rcomp = /bits/ 8 <0x56>;
maxim,alert-low-soc-level = <10>;
maxim,double-soc;
};
-- 
2.27.0



[PATCH v3 3/6] power: supply: max17040: Support compatible devices

2020-06-24 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very
similar mode of operations and registers.

This change adds:
- compatible strings for all supported devices and handling for the
  minor differences between them;
- handling for devices reporting double capacity via maxim,double-soc;

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

Signed-off-by: Iskren Chernev 
---
 drivers/power/supply/Kconfig|  10 +-
 drivers/power/supply/max17040_battery.c | 143 +---
 2 files changed, 135 insertions(+), 18 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 12ca79952768f..0efdb282fea28 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -369,9 +369,13 @@ config BATTERY_MAX17040
depends on I2C
select REGMAP_I2C
help
- MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
- in handheld and portable equipment. The MAX17040 is configured
- to operate with a single lithium cell
+ Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
+ (Li+) batteries in handheld and portable equipment, including
+ max17040, max17041, max17043, max17044, max17048, max17049, max17058,
+ max17059. It is also included in some batteries like max77836.
+
+ Driver supports reporting SOC (State of Charge, i.e capacity),
+ voltage and configurable low-SOC wakeup interrupt.
 
 config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 678241fcc2548..a6ecd84194e51 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -33,12 +34,92 @@
 #define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
 
+enum chip_id {
+   ID_MAX17040,
+   ID_MAX17041,
+   ID_MAX17043,
+   ID_MAX17044,
+   ID_MAX17048,
+   ID_MAX17049,
+   ID_MAX17058,
+   ID_MAX17059,
+};
+
+/* values that differ by chip_id */
+struct chip_data {
+   u16 reset_val;
+   u16 vcell_shift;
+   u16 vcell_mul;
+   u16 vcell_div;
+   u8  has_low_soc_alert;
+};
+
+static struct chip_data max17040_family[] = {
+   [ID_MAX17040] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .has_low_soc_alert = 0,
+   },
+   [ID_MAX17041] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .has_low_soc_alert = 0,
+   },
+   [ID_MAX17043] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17044] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17048] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 8,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17049] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 4,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17058] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 8,
+   .has_low_soc_alert = 1,
+   },
+   [ID_MAX17059] = {
+   .reset_val = 0x5400,
+   .vcell_shift = 0,
+   .vcell_mul = 625,
+   .vcell_div = 4,
+   .has_low_soc_alert = 1,
+   },
+};
+
 struct max17040_chip {
struct i2c_client   *client;
struct regmap   *regmap;
struct delayed_work work;
struct power_supply *battery;
struct max17040_platform_data   *pdata;
+   struct chip_datadata;
 
/* battery capacity */
int soc;
@@ -46,11 +127,13 @@ struct max17040_chip {
int status;
/* Low alert threshold from 32% to 1% of the State of Charge */
u32 low

[PATCH v3 6/6] power: supply: max17040: Support soc alert

2020-06-24 Thread Iskren Chernev
max17048 and max17049 support SOC alerts (interrupts when battery
capacity changes by +/- 1%). At the moment the driver polls for changes
every second. Using the alerts removes the need for polling.

Signed-off-by: Iskren Chernev 
---
 drivers/power/supply/max17040_battery.c | 82 ++---
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 54393f411211e..4425411775f26 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -25,6 +25,7 @@
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
 #define MAX17040_CONFIG0x0C
+#define MAX17040_STATUS0x1A
 #define MAX17040_CMD   0xFE
 
 
@@ -33,7 +34,10 @@
 #define MAX17040_RCOMP_DEFAULT  0x9700
 
 #define MAX17040_ATHD_MASK 0x3f
+#define MAX17040_ALSC_MASK 0x40
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_STATUS_HD_MASK0x1000
+#define MAX17040_STATUS_SC_MASK0x2000
 #define MAX17040_CFG_RCOMP_MASK0xff00
 
 enum chip_id {
@@ -55,6 +59,7 @@ struct chip_data {
u16 vcell_div;
u8  has_low_soc_alert;
u8  rcomp_bytes;
+   u8  has_soc_alert;
 };
 
 static struct chip_data max17040_family[] = {
@@ -65,6 +70,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 0,
.rcomp_bytes = 2,
+   .has_soc_alert = 0,
},
[ID_MAX17041] = {
.reset_val = 0x0054,
@@ -73,6 +79,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 0,
.rcomp_bytes = 2,
+   .has_soc_alert = 0,
},
[ID_MAX17043] = {
.reset_val = 0x0054,
@@ -81,6 +88,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17044] = {
.reset_val = 0x0054,
@@ -89,6 +97,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 1,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17048] = {
.reset_val = 0x5400,
@@ -97,6 +106,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 8,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 1,
},
[ID_MAX17049] = {
.reset_val = 0x5400,
@@ -105,6 +115,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 4,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 1,
},
[ID_MAX17058] = {
.reset_val = 0x5400,
@@ -113,6 +124,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 8,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
[ID_MAX17059] = {
.reset_val = 0x5400,
@@ -121,6 +133,7 @@ static struct chip_data max17040_family[] = {
.vcell_div = 4,
.has_low_soc_alert = 1,
.rcomp_bytes = 1,
+   .has_soc_alert = 0,
},
 };
 
@@ -156,6 +169,12 @@ static int max17040_set_low_soc_alert(struct max17040_chip 
*chip, u32 level)
MAX17040_ATHD_MASK, level);
 }
 
+static int max17040_set_soc_alert(struct max17040_chip *chip, bool enable)
+{
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
+   MAX17040_ALSC_MASK, enable ? MAX17040_ALSC_MASK : 0);
+}
+
 static int max17040_set_rcomp(struct max17040_chip *chip, u16 rcomp)
 {
u16 mask = chip->data.rcomp_bytes == 2 ?
@@ -298,11 +317,33 @@ static void max17040_work(struct work_struct *work)
max17040_queue_work(chip);
 }
 
+/* Returns true if alert cause was SOC change, not low SOC */
+static bool max17040_handle_soc_alert(struct max17040_chip *chip)
+{
+   bool ret = true;
+   u32 data;
+
+   regmap_read(chip->regmap, MAX17040_STATUS, &data);
+
+   if (data & MAX17040_STATUS_HD_MASK) {
+   // this alert was caused by low soc
+   ret = false;
+   }
+   if (data & MAX17040_STATUS_SC_MASK) {
+   // soc change bit -- deassert to mark as handled
+   regmap_write(chip->regmap, MAX17040_STATUS,
+   data & ~MAX17040_STATUS_SC_MASK);
+   }
+
+   return ret;
+}
+
 static irqreturn_t max17040_thread_handler(int id, void *dev)
 {
struct max17040_chip *chip = dev;
 
-   dev_warn(&chip->client->dev, "

[PATCH v3 2/6] dt-bindings: power: supply: Extend max17040 compatibility

2020-06-24 Thread Iskren Chernev
Maxim max17040 is a fuel gauge from a larger family utilising the Model
Gauge technology. Document all different compatible strings that the
max17040 driver recognizes.

Some devices in the wild report double the capacity. The
maxim,double-soc (from State-Of-Charge) property fixes that.

Signed-off-by: Iskren Chernev 
---
 .../bindings/power/supply/max17040_battery.txt| 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 4e0186b8380fa..554bce82a08e6 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -2,7 +2,9 @@ max17040_battery
 
 
 Required properties :
- - compatible : "maxim,max17040" or "maxim,max77836-battery"
+ - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
+   "maxim,max17044", "maxim,max17048", "maxim,max17049",
+   "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
  - reg: i2c slave address
 
 Optional properties :
@@ -11,6 +13,10 @@ Optional properties :
generated. Can be configured from 1 up to 32
(%). If skipped the power up default value of
4 (%) will be used.
+- maxim,double-soc :   Certain devices return double the capacity.
+   Specify this boolean property to divide the
+   reported value in 2 and thus normalize it.
+   SOC == State of Charge == Capacity.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -31,3 +37,10 @@ Example:
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
wakeup-source;
};
+
+   battery-fuel-gauge@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+   maxim,alert-low-soc-level = <10>;
+   maxim,double-soc;
+   };
-- 
2.27.0



[PATCH v3 0/6] power: supply: max17040 support compatible devices

2020-06-24 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very similar
mode of operations and registers.

This patch set adds:
- compatible strings for all supported devices and handles the minor
  differences between them;
- handling for devices reporting double capacity via maxim,double-soc;
- handling for setting rcomp, a compensation value for more accurate reading,
  affected by battery chemistry and operating temps;
- suppot for SOC alerts (capacity changes by +/- 1%), to prevent polling every
  second;
- improved max17040 driver with regmap and devm_

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

v2: https://lkml.org/lkml/2020/6/18/260
v1: https://lkml.org/lkml/2020/6/8/682

Changes in v2:
- remove maxim,skip-reset property in favor of device id
- split driver change into 4 pieces

Iskren Chernev (6):
  power: supply: max17040: Use regmap i2c
  dt-bindings: power: supply: Extend max17040 compatibility
  power: supply: max17040: Support compatible devices
  dt-bindings: power: supply: max17040: Add maxim,rcomp
  power: supply: max17040: Support setting rcomp
  power: supply: max17040: Support soc alert

 .../power/supply/max17040_battery.txt |  21 +-
 drivers/power/supply/Kconfig  |  11 +-
 drivers/power/supply/max17040_battery.c   | 473 --
 3 files changed, 357 insertions(+), 148 deletions(-)


base-commit: cfafde3c949cae39483639c03c5da5fd91bb234e
--
2.27.0



[PATCH v3 1/6] power: supply: max17040: Use regmap i2c

2020-06-24 Thread Iskren Chernev
Rewrite i2c operations from i2c client read/write to regmap i2c. As
a result, most private functions now accept the private driver data
instead of an i2c client pointer.

Signed-off-by: Iskren Chernev 
---
 drivers/power/supply/Kconfig|   1 +
 drivers/power/supply/max17040_battery.c | 250 +++-
 2 files changed, 110 insertions(+), 141 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 44d3c8512fb8d..12ca79952768f 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -367,6 +367,7 @@ config AXP288_FUEL_GAUGE
 config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
+   select REGMAP_I2C
help
  MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
  in handheld and portable equipment. The MAX17040 is configured
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 48aa44665e2f1..678241fcc2548 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -16,32 +16,30 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define MAX17040_VCELL 0x02
 #define MAX17040_SOC   0x04
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
-#define MAX17040_RCOMP 0x0C
+#define MAX17040_CONFIG0x0C
 #define MAX17040_CMD   0xFE
 
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
 
-#define MAX17040_ATHD_MASK 0xFFC0
+#define MAX17040_ATHD_MASK 0x3f
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
 
 struct max17040_chip {
struct i2c_client   *client;
+   struct regmap   *regmap;
struct delayed_work work;
struct power_supply *battery;
struct max17040_platform_data   *pdata;
 
-   /* State Of Connect */
-   int online;
-   /* battery voltage */
-   int vcell;
/* battery capacity */
int soc;
/* State Of Charge */
@@ -50,135 +48,68 @@ struct max17040_chip {
u32 low_soc_alert;
 };
 
-static int max17040_get_property(struct power_supply *psy,
-   enum power_supply_property psp,
-   union power_supply_propval *val)
-{
-   struct max17040_chip *chip = power_supply_get_drvdata(psy);
-
-   switch (psp) {
-   case POWER_SUPPLY_PROP_STATUS:
-   val->intval = chip->status;
-   break;
-   case POWER_SUPPLY_PROP_ONLINE:
-   val->intval = chip->online;
-   break;
-   case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-   val->intval = chip->vcell;
-   break;
-   case POWER_SUPPLY_PROP_CAPACITY:
-   val->intval = chip->soc;
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
-
-static int max17040_write_reg(struct i2c_client *client, int reg, u16 value)
-{
-   int ret;
-
-   ret = i2c_smbus_write_word_swapped(client, reg, value);
-
-   if (ret < 0)
-   dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
-   return ret;
-}
-
-static int max17040_read_reg(struct i2c_client *client, int reg)
-{
-   int ret;
-
-   ret = i2c_smbus_read_word_swapped(client, reg);
-
-   if (ret < 0)
-   dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
-   return ret;
-}
-
-static void max17040_reset(struct i2c_client *client)
+static int max17040_reset(struct max17040_chip *chip)
 {
-   max17040_write_reg(client, MAX17040_CMD, 0x0054);
+   return regmap_write(chip->regmap, MAX17040_CMD, 0x0054);
 }
 
-static int max17040_set_low_soc_alert(struct i2c_client *client, u32 level)
+static int max17040_set_low_soc_alert(struct max17040_chip *chip, u32 level)
 {
-   int ret;
-   u16 data;
-
level = 32 - level;
-   data = max17040_read_reg(client, MAX17040_RCOMP);
-   /* clear the alrt bit and set LSb 5 bits */
-   data &= MAX17040_ATHD_MASK;
-   data |= level;
-   ret = max17040_write_reg(client, MAX17040_RCOMP, data);
-
-   return ret;
+   return regmap_update_bits(chip->regmap, MAX17040_CONFIG,
+   MAX17040_ATHD_MASK, level);
 }
 
-static void max17040_get_vcell(struct i2c_client *client)
+static int max17040_get_vcell(struct max17040_chip *chip)
 {
-   struct max17040_chip *chip = i2c_get_clientdata(client);
-   u16 vcell;
+   u32 vcell;
 
-   vcell = max17040_read_reg(client, MAX17040_VCELL);
+   regmap_read(chip->regmap, MAX17040_VCELL, &vcell);
 
-   chip->vcell = (vcell >> 4) * 1250;
+   return (vcell >> 4) * 1250;
 }
 
-static void max17040_get_soc(struct i2c_client *client)
+static int max17040_get_soc(struct max17040_chip *chip)
 {
- 

Re: [PATCH v2 1/2] dt-bindings: power: supply: Document max17040 extensions

2020-06-20 Thread Iskren Chernev


On 6/20/20 12:31 AM, Sebastian Reichel wrote:
> Hi,
>
> On Fri, Jun 19, 2020 at 10:57:19PM +0300, Iskren Chernev wrote:
>> On 6/19/20 6:59 PM, Sebastian Reichel wrote:
>>> On Thu, Jun 18, 2020 at 01:13:39PM +0300, Iskren Chernev wrote:
>>>> Maxim max17040 is a fuel gauge from a larger family utilising the Model
>>>> Gauge technology. Document all different compatible strings that the
>>>> max17040 driver recognizes.
>>>>
>>>> Some devices in the wild report double the capacity. The
>>>> maxim,double-soc (from State-Of-Charge) property fixes that.
>>>>
>>>> Complete device reset might lead to very inaccurate readings. Specify
>>>> maxim,skip-reset to avoid that.
>>>>
>>>> To compensate for the battery chemistry and operating conditions the
>>>> chips support a compensation value. Specify one or two byte compensation
>>>> via the maxim,rcomp byte array.
>>>>
>>>> Signed-off-by: Iskren Chernev 
>>>> ---
>>>> v1: https://lkml.org/lkml/2020/6/8/682
>>>>
>>>> Changes in v2:
>>>> - add maxim,skip-reset
>>>> - remove 2 byte rcomp from example, the specified compat string supports 1 
>>>> byte
>>>>    rcomp
>>>>
>>>>   .../power/supply/max17040_battery.txt | 24 ++-
>>>>   1 file changed, 23 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git 
>>>> a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
>>>> b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>>>> index 4e0186b8380fa..3ee91c295027f 100644
>>>> --- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>>>> +++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>>>> @@ -2,7 +2,9 @@ max17040_battery
>>>>   
>>>>
>>>>   Required properties :
>>>> - - compatible : "maxim,max17040" or "maxim,max77836-battery"
>>>> + - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
>>>> + "maxim,max17044", "maxim,max17048", "maxim,max17049",
>>>> +    "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
>>>>    - reg: i2c slave address
>>>>
>>>>   Optional properties :
>>>> @@ -11,6 +13,18 @@ Optional properties :
>>>>  generated. Can be configured from 1 up to 32
>>>>  (%). If skipped the power up default value of
>>>>  4 (%) will be used.
>>>> +- maxim,double-soc : Certain devices return double the capacity.
>>>> +    Specify this boolean property to divide the
>>>> +    reported value in 2 and thus normalize it.
>>>> +    SOC == State of Charge == Capacity.
>>>
>>> Can this be derived from the compatible?
>>
>> So far, I'm aware of 2 devices using max17048 that need this setting. That
>> would be 100% of the 17048 devices I know of [1]. At the same time, 
>> according to
>> the max17048 documentation this is not the case.
>>
>> [1] These are the Samsung Galaxy S5 (klte) and the LG Nexus 5 (hammerhead).
>
> Wouldn't be the first time, that documentation is wrong. Have you
> checked how its handled in the downstream Android kernel?

Yes, I have checked both klte[1] and hammerhead[2] downstream. About the state
of charge -- the klte has the spec formula and the double formula, and the
hammerhead has provisions in it's DTS to configure max/min raw values,
effectively enabling arbitrary scaling of the value.

About the reset on start, klte does a quick-start (0x4000 to MODE reg).
Hammerhead resets the RI status bit (which in itself does not reset anything).

I now also looked at downstream implementation of the other fuelgauges.
Here are examples of 17040[3], 17043[4], 17058[5].  It looks like most of the
family (except 17040) is prone to this doubling. [4] and [5] have both formulas
toggleable with a macro. So I think leaving double-soc as an option in DTS is
the right choice.

About the reset -- looks like only 17040 is reset on start. The newer ones are
either quick-started or nothing. So hard-resetting only the 17040 might be
a good choice.

[1] 
https://github.com/LineageOS/android_kernel_samsung_msm8974/blob/5dddbe776631650086c4491ec4037fbe73fa5795/drivers/battery/max17048_fuelgauge.c#L135
[2] 
http

Re: [PATCH v2 2/2] power: supply: max17040: Support compatible devices

2020-06-19 Thread Iskren Chernev


On 6/19/20 7:13 PM, Sebastian Reichel wrote:
> Hi,
>
> On Thu, Jun 18, 2020 at 01:13:40PM +0300, Iskren Chernev wrote:
>> The max17040 fuel gauge is part of a family of 8 chips that have very
>> similar mode of operations and registers.
>>
>> This change adds:
>> - compatible strings for all supported devices and handles the minor
>>   differences between them;
>> - handling for devices reporting double capacity via maxim,double-soc;
>> - handling for setting rcomp, a compensation value for more accurate
>>   reading, affected by battery chemistry and operating temps;
>> - suppot for SOC alerts (capacity changes by +/- 1%), to prevent polling
>>   every second;
>> - redo i2c read/writes via regmap
>
> Please split this into multiple patches as described in
> Documentation/process/submitting-patches.rst:
>
> 3) Separate your changes
> 
>
> Separate each **logical change** into a separate patch.

So I did some cleanup on the existing code (unified function interfaces,
introduced regmap, and other small things). Can this be one commit?

> Thanks,
>
> -- Sebastian
>
>> The datasheets of the supported devices are linked [0] [1] [2] [3].
>>
>> [0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
>> [1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
>> [2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
>> [3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf
>>
>> Signed-off-by: Iskren Chernev 
>> ---
>> v1: https://lkml.org/lkml/2020/6/8/683
>>
>> changes in v2:
>> - make max17040_family static
>> - fix rcomp len check
>> - implement maxim,skip-reset
>> - reword Kconfig text
>>
>>  drivers/power/supply/Kconfig    |  11 +-
>>  drivers/power/supply/max17040_battery.c | 466 +---
>>  2 files changed, 338 insertions(+), 139 deletions(-)
>>
>> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
>> index 44d3c8512fb8d..69e9eaa100d9f 100644
>> --- a/drivers/power/supply/Kconfig
>> +++ b/drivers/power/supply/Kconfig
>> @@ -368,9 +368,14 @@ config BATTERY_MAX17040
>>  tristate "Maxim MAX17040 Fuel Gauge"
>>  depends on I2C
>>  help
>> -  MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
>> -  in handheld and portable equipment. The MAX17040 is configured
>> -  to operate with a single lithium cell
>> +  Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
>> +  (Li+) batteries in handheld and portable equipment, including
>> +  max17040, max17041, max17043, max17044, max17048, max17049, max17058,
>> +  max17059.  It is also included in some batteries like max77836.
>> +
>> +  Driver supports reporting SOC (State of Charge, i.e capacity),
>> +  voltage and configurable low-SOC wakeup interrupt. For certain models
>> +  a SOC change interrupt is also supported.
>>
>>  config BATTERY_MAX17042
>>  tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
>> diff --git a/drivers/power/supply/max17040_battery.c 
>> b/drivers/power/supply/max17040_battery.c
>> index 48aa44665e2f1..1244982cacacb 100644
>> --- a/drivers/power/supply/max17040_battery.c
>> +++ b/drivers/power/supply/max17040_battery.c
>> @@ -15,193 +15,342 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>> +#include 
>>  #include 
>>
>>  #define MAX17040_VCELL    0x02
>>  #define MAX17040_SOC    0x04
>>  #define MAX17040_MODE    0x06
>>  #define MAX17040_VER    0x08
>> -#define MAX17040_RCOMP    0x0C
>> +#define MAX17040_CONFIG    0x0C
>> +#define MAX17040_STATUS    0x1A
>>  #define MAX17040_CMD    0xFE
>>
>>
>>  #define MAX17040_DELAY    1000
>>  #define MAX17040_BATTERY_FULL    95
>> +#define MAX17040_RCOMP_DEFAULT  0x9700
>>
>> -#define MAX17040_ATHD_MASK    0xFFC0
>> +#define MAX17040_ATHD_MASK    0x3f
>> +#define MAX17040_ALSC_MASK    0x40
>>  #define MAX17040_ATHD_DEFAULT_POWER_UP    4
>> +#define MAX17040_STATUS_HD_MASK    0x1000
>> +#define MAX17040_STATUS_SC_MASK    0x2000
>> +#define MAX17040_CFG_RCOMP_MASK    0xff00
>> +
>> +enum chip_id {
>> +    ID_MAX17040,
>> +    ID_MAX17041,
>> +    ID_MAX17043,
>> +    ID_MAX17044,
>> +    ID_MAX17048,
>> +    ID_MAX17049,
>> +    ID_MAX17058,
>> +    ID_MAX

Re: [PATCH v2 1/2] dt-bindings: power: supply: Document max17040 extensions

2020-06-19 Thread Iskren Chernev


On 6/19/20 6:59 PM, Sebastian Reichel wrote:
> Hi,
>
> On Thu, Jun 18, 2020 at 01:13:39PM +0300, Iskren Chernev wrote:
>> Maxim max17040 is a fuel gauge from a larger family utilising the Model
>> Gauge technology. Document all different compatible strings that the
>> max17040 driver recognizes.
>>
>> Some devices in the wild report double the capacity. The
>> maxim,double-soc (from State-Of-Charge) property fixes that.
>>
>> Complete device reset might lead to very inaccurate readings. Specify
>> maxim,skip-reset to avoid that.
>>
>> To compensate for the battery chemistry and operating conditions the
>> chips support a compensation value. Specify one or two byte compensation
>> via the maxim,rcomp byte array.
>>
>> Signed-off-by: Iskren Chernev 
>> ---
>> v1: https://lkml.org/lkml/2020/6/8/682
>>
>> Changes in v2:
>> - add maxim,skip-reset
>> - remove 2 byte rcomp from example, the specified compat string supports 1 
>> byte
>>   rcomp
>>
>>  .../power/supply/max17040_battery.txt | 24 ++-
>>  1 file changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
>> b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> index 4e0186b8380fa..3ee91c295027f 100644
>> --- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> +++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
>> @@ -2,7 +2,9 @@ max17040_battery
>>  
>>
>>  Required properties :
>> - - compatible : "maxim,max17040" or "maxim,max77836-battery"
>> + - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
>> + "maxim,max17044", "maxim,max17048", "maxim,max17049",
>> +    "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
>>   - reg: i2c slave address
>>
>>  Optional properties :
>> @@ -11,6 +13,18 @@ Optional properties :
>>  generated. Can be configured from 1 up to 32
>>  (%). If skipped the power up default value of
>>  4 (%) will be used.
>> +- maxim,double-soc : Certain devices return double the capacity.
>> +    Specify this boolean property to divide the
>> +    reported value in 2 and thus normalize it.
>> +    SOC == State of Charge == Capacity.
>
> Can this be derived from the compatible?
>

So far, I'm aware of 2 devices using max17048 that need this setting. That
would be 100% of the 17048 devices I know of [1]. At the same time, according to
the max17048 documentation this is not the case.

[1] These are the Samsung Galaxy S5 (klte) and the LG Nexus 5 (hammerhead).

>> +- maxim,skip-reset :    Do not reset device on driver initialization.
>> +    Some devices report extremely inaccurately after
>> +    a hard reset.
>
> Same question.
>
> -- Sebastian
>

This is even weirder. There is no mention in the documentation about whether
the device should be reset on boot (because the fuelgauge is on even during
device off times). Testing on 17040 and 17043 reveals no issues with resetting
on boot, but on the 17048 I have; the readings are up to 2x wrong if you do
reset on boot. Not doing a reset *might* leave the device in a state that is
not 100% known by the driver, but I don't know of any real world problems
stemming from that.

So in a sense, I can apply both of these quirks for 17048, and it will work for
all devices I have tested on, but it won't follow the spec. That is why
I decided to mark them as special behavior needing configuration per use case.
On the other hand, I can incorporate them in 17048, and if someone complains
the bindings can be introduced later (because they are stable API and
introducing them now is a bit over engineered).

>> +- maxim,rcomp :    A value to compensate readings for various
>> +    battery chemistries and operating temperatures.
>> +    max17040,41 have 2 byte rcomp, default to
>> +    0x97 0x00. All other devices have one byte
>> +    rcomp, default to 0x97.
>>  - interrupts : Interrupt line see Documentation/devicetree/
>>  bindings/interrupt-controller/interrupts.txt
>>  - wakeup-source :    This device has wakeup capabilities. Use this
>> @@ -31,3 +45,11 @@ Example:
>>  interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
>>  wakeup-source;
>>  };
>> +
>> +    battery-fuel-gauge@36 {
>> +    compatible = "maxim,max17048";
>> +    reg = <0x36>;
>> +    maxim,rcomp = /bits/ 8 <0x97>;
>> +    maxim,alert-low-soc-level = <10>;
>> +    maxim,double-soc;
>> +    };
>>
>> base-commit: 1713116fa907cc7290020f0d8632ec646d2936f8
>> --
>> 2.27.0
>>

P.S sorry for the double email, forgot reply-all



[PATCH v2 2/2] power: supply: max17040: Support compatible devices

2020-06-18 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very
similar mode of operations and registers.

This change adds:
- compatible strings for all supported devices and handles the minor
  differences between them;
- handling for devices reporting double capacity via maxim,double-soc;
- handling for setting rcomp, a compensation value for more accurate
  reading, affected by battery chemistry and operating temps;
- suppot for SOC alerts (capacity changes by +/- 1%), to prevent polling
  every second;
- redo i2c read/writes via regmap

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

Signed-off-by: Iskren Chernev 
---
v1: https://lkml.org/lkml/2020/6/8/683

changes in v2:
- make max17040_family static
- fix rcomp len check
- implement maxim,skip-reset
- reword Kconfig text

 drivers/power/supply/Kconfig|  11 +-
 drivers/power/supply/max17040_battery.c | 466 +---
 2 files changed, 338 insertions(+), 139 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 44d3c8512fb8d..69e9eaa100d9f 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -368,9 +368,14 @@ config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
help
- MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
- in handheld and portable equipment. The MAX17040 is configured
- to operate with a single lithium cell
+ Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
+ (Li+) batteries in handheld and portable equipment, including
+ max17040, max17041, max17043, max17044, max17048, max17049, max17058,
+ max17059.  It is also included in some batteries like max77836.
+
+ Driver supports reporting SOC (State of Charge, i.e capacity),
+ voltage and configurable low-SOC wakeup interrupt. For certain models
+ a SOC change interrupt is also supported.
 
 config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 48aa44665e2f1..1244982cacacb 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -15,193 +15,342 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 #define MAX17040_VCELL 0x02
 #define MAX17040_SOC   0x04
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
-#define MAX17040_RCOMP 0x0C
+#define MAX17040_CONFIG0x0C
+#define MAX17040_STATUS0x1A
 #define MAX17040_CMD   0xFE
 
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
+#define MAX17040_RCOMP_DEFAULT  0x9700
 
-#define MAX17040_ATHD_MASK 0xFFC0
+#define MAX17040_ATHD_MASK 0x3f
+#define MAX17040_ALSC_MASK 0x40
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_STATUS_HD_MASK0x1000
+#define MAX17040_STATUS_SC_MASK0x2000
+#define MAX17040_CFG_RCOMP_MASK0xff00
+
+enum chip_id {
+   ID_MAX17040,
+   ID_MAX17041,
+   ID_MAX17043,
+   ID_MAX17044,
+   ID_MAX17048,
+   ID_MAX17049,
+   ID_MAX17058,
+   ID_MAX17059,
+};
+
+/* values that differ by chip_id */
+struct chip_data {
+   u16 reset_val;
+   u16 vcell_shift;
+   u16 vcell_mul;
+   u16 vcell_div;
+   u8  rcomp_bytes;
+   u8  has_low_soc_alert;
+   u8  has_soc_alert;
+};
+
+static struct chip_data max17040_family[] = {
+   [ID_MAX17040] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .rcomp_bytes = 2,
+   .has_low_soc_alert = 0,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17041] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .rcomp_bytes = 2,
+   .has_low_soc_alert = 0,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17043] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .rcomp_bytes = 1,
+   .has_low_soc_alert = 1,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17044] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .rcomp_bytes = 1,
+ 

[PATCH v2 1/2] dt-bindings: power: supply: Document max17040 extensions

2020-06-18 Thread Iskren Chernev
Maxim max17040 is a fuel gauge from a larger family utilising the Model
Gauge technology. Document all different compatible strings that the
max17040 driver recognizes.

Some devices in the wild report double the capacity. The
maxim,double-soc (from State-Of-Charge) property fixes that.

Complete device reset might lead to very inaccurate readings. Specify
maxim,skip-reset to avoid that.

To compensate for the battery chemistry and operating conditions the
chips support a compensation value. Specify one or two byte compensation
via the maxim,rcomp byte array.

Signed-off-by: Iskren Chernev 
---
v1: https://lkml.org/lkml/2020/6/8/682

Changes in v2:
- add maxim,skip-reset
- remove 2 byte rcomp from example, the specified compat string supports 1 byte
  rcomp

 .../power/supply/max17040_battery.txt | 24 ++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 4e0186b8380fa..3ee91c295027f 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -2,7 +2,9 @@ max17040_battery
 
 
 Required properties :
- - compatible : "maxim,max17040" or "maxim,max77836-battery"
+ - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
+   "maxim,max17044", "maxim,max17048", "maxim,max17049",
+   "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
  - reg: i2c slave address
 
 Optional properties :
@@ -11,6 +13,18 @@ Optional properties :
generated. Can be configured from 1 up to 32
(%). If skipped the power up default value of
4 (%) will be used.
+- maxim,double-soc :   Certain devices return double the capacity.
+   Specify this boolean property to divide the
+   reported value in 2 and thus normalize it.
+   SOC == State of Charge == Capacity.
+- maxim,skip-reset :   Do not reset device on driver initialization.
+   Some devices report extremely inaccurately after
+   a hard reset.
+- maxim,rcomp :A value to compensate readings for 
various
+   battery chemistries and operating temperatures.
+   max17040,41 have 2 byte rcomp, default to
+   0x97 0x00. All other devices have one byte
+   rcomp, default to 0x97.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -31,3 +45,11 @@ Example:
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
wakeup-source;
};
+
+   battery-fuel-gauge@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+   maxim,rcomp = /bits/ 8 <0x97>;
+   maxim,alert-low-soc-level = <10>;
+   maxim,double-soc;
+   };

base-commit: 1713116fa907cc7290020f0d8632ec646d2936f8
-- 
2.27.0



[PATCH 2/2] power: supply: max17040: Support compatible devices

2020-06-08 Thread Iskren Chernev
The max17040 fuel gauge is part of a family of 8 chips that have very
similar mode of operations and registers.

This change adds:
- compatible strings for all supported devices and handles the minor
  differences between them;
- handling for devices reporting double capacity via maxim,double-soc;
- handling for setting rcomp, a compensation value for more accurate
  reading, affected by battery chemistry and operating temps;
- suppot for SOC alerts (capacity changes by +/- 1%), to prevent polling
  every second;
- redo i2c read/writes via regmap

The datasheets of the supported devices are linked [0] [1] [2] [3].

[0] https://datasheets.maximintegrated.com/en/ds/MAX17040-MAX17041.pdf
[1] https://datasheets.maximintegrated.com/en/ds/MAX17043-MAX17044.pdf
[2] https://datasheets.maximintegrated.com/en/ds/MAX17048-MAX17049.pdf
[3] https://datasheets.maximintegrated.com/en/ds/MAX17058-MAX17059.pdf

Signed-off-by: Iskren Chernev 
---
 drivers/power/supply/Kconfig|  11 +-
 drivers/power/supply/max17040_battery.c | 458 +---
 2 files changed, 330 insertions(+), 139 deletions(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 44d3c8512fb8d..c5580b858ce4b 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -368,9 +368,14 @@ config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
help
- MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
- in handheld and portable equipment. The MAX17040 is configured
- to operate with a single lithium cell
+ Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
+ (Li+) batteries in handheld and portable equipment, include max17040,
+ max17041, max17043, max17044, max17048, max17049, max17058, max17059.
+ It is also included in some mfd devices like max77836.
+
+ Driver supports reporting SOC (State of Charge, i.e capacity),
+ voltage and configurable low-SOC wakeup interrupt. For certain models
+ a SOC change interrupt is also supported.
 
 config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
diff --git a/drivers/power/supply/max17040_battery.c 
b/drivers/power/supply/max17040_battery.c
index 48aa44665e2f1..4fd6cf7b60c71 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -15,193 +15,336 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 #define MAX17040_VCELL 0x02
 #define MAX17040_SOC   0x04
 #define MAX17040_MODE  0x06
 #define MAX17040_VER   0x08
-#define MAX17040_RCOMP 0x0C
+#define MAX17040_CONFIG0x0C
+#define MAX17040_STATUS0x1A
 #define MAX17040_CMD   0xFE
 
 
 #define MAX17040_DELAY 1000
 #define MAX17040_BATTERY_FULL  95
+#define MAX17040_RCOMP_DEFAULT  0x9700
 
-#define MAX17040_ATHD_MASK 0xFFC0
+#define MAX17040_ATHD_MASK 0x3f
+#define MAX17040_ALSC_MASK 0x40
 #define MAX17040_ATHD_DEFAULT_POWER_UP 4
+#define MAX17040_STATUS_HD_MASK0x1000
+#define MAX17040_STATUS_SC_MASK0x2000
+#define MAX17040_CFG_RCOMP_MASK0xff00
+
+enum chip_id {
+   ID_MAX17040,
+   ID_MAX17041,
+   ID_MAX17043,
+   ID_MAX17044,
+   ID_MAX17048,
+   ID_MAX17049,
+   ID_MAX17058,
+   ID_MAX17059,
+};
+
+/* values that differ by chip_id */
+struct chip_data {
+   u16 reset_val;
+   u16 vcell_shift;
+   u16 vcell_mul;
+   u16 vcell_div;
+   u8  rcomp_bytes;
+   u8  has_low_soc_alert;
+   u8  has_soc_alert;
+};
+
+struct chip_data max17040_family[] = {
+   [ID_MAX17040] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .rcomp_bytes = 2,
+   .has_low_soc_alert = 0,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17041] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .rcomp_bytes = 2,
+   .has_low_soc_alert = 0,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17043] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 1250,
+   .vcell_div = 1,
+   .rcomp_bytes = 1,
+   .has_low_soc_alert = 1,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17044] = {
+   .reset_val = 0x0054,
+   .vcell_shift = 4,
+   .vcell_mul = 2500,
+   .vcell_div = 1,
+   .rcomp_bytes = 1,
+   .has_low_soc_alert = 1,
+   .has_soc_alert = 0,
+   },
+   [ID_MAX17048] = {
+   .reset_val = 0x5400,
+   

[PATCH 1/2] dt-bindints: power: supply: Document max17040 extensions

2020-06-08 Thread Iskren Chernev
Maxim max17040 is a fuel gauge from a larger family utilising the Model
Gauge thechnology. Document all different compatible strings that the
max17040 driver recognizes.

Some devices in the wild report double the capacity. The
maxim,double-soc (from State-Of-Charge) property fixes that.

To compensate for the battery chemistry and operating conditions the
chips support a compensation value. Specify one or two byte compensation
via the maxim,rcomp byte array.

Signed-off-by: Iskren Chernev 
---
 .../power/supply/max17040_battery.txt | 22 ++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt 
b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
index 4e0186b8380fa..be11cab4530b9 100644
--- a/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
+++ b/Documentation/devicetree/bindings/power/supply/max17040_battery.txt
@@ -2,7 +2,9 @@ max17040_battery
 
 
 Required properties :
- - compatible : "maxim,max17040" or "maxim,max77836-battery"
+ - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
+   "maxim,max17044", "maxim,max17048", "maxim,max17049",
+   "maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
  - reg: i2c slave address
 
 Optional properties :
@@ -11,6 +13,15 @@ Optional properties :
generated. Can be configured from 1 up to 32
(%). If skipped the power up default value of
4 (%) will be used.
+- maxim,double-soc :   Certain devices return double the capacity.
+   Specify this boolean property to divide the
+   reported value in 2 and thus normalize it.
+   SOC == State of Charge == Capacity.
+- maxim,rcomp :A value to compensate readings for 
various
+   battery chemistries and operating temperatures.
+   max17040,41 have 2 byte rcomp, default to
+   0x97 0x00. All other devices have one byte
+   rcomp, default to 0x97.
 - interrupts : Interrupt line see 
Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt
 - wakeup-source :  This device has wakeup capabilities. Use this
@@ -27,7 +38,16 @@ Example:
compatible = "maxim,max77836-battery";
reg = <0x36>;
maxim,alert-low-soc-level = <10>;
+   maxim,rcomp = /bits/ 8 <0x97 0x00>;
interrupt-parent = <&gpio7>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
wakeup-source;
};
+
+   battery-fuel-gauge@36 {
+   compatible = "maxim,max17048";
+   reg = <0x36>;
+   maxim,rcomp = /bits/ 8 <0x97>;
+   maxim,alert-low-soc-level = <10>;
+   maxim,double-soc;
+   };

base-commit: 1713116fa907cc7290020f0d8632ec646d2936f8
-- 
2.27.0