[PATCH] dt-bindings: Use portable sort for version cmp
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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