Loading Documentation/devicetree/bindings/pwm/pwm-qti-lpg.txt +7 −3 Original line number Diff line number Diff line Loading @@ -11,9 +11,7 @@ device module in Qualcomm Technologies, Inc. PMIC chips. - reg: Usage: required Value type: <prop-encoded-array> Definition: Register base and length for LPG and LUT modules. LPG size or length available per channel varies depending on the number of channels in PMIC. Definition: Register base for LPG and LUT modules. - reg-names: Usage: required Loading @@ -30,6 +28,11 @@ device module in Qualcomm Technologies, Inc. PMIC chips. the PWM channel ID indexed from 0, and the second cell is the PWM default period in nanoseconds. - qcom,num-lpg-channels: Usage: required Value type: <u32> Definition: The number of the consecutive LPG/PWM channels in the chip. - qcom,lut-patterns: Usage: optional Value type: <prop-encoded-array> Loading Loading @@ -122,6 +125,7 @@ Example: compatible = "qcom,pwm-lpg"; reg = <0xb100 0x600>, <0xb000 0x100>; reg-names = "lpg-base", "lut-base"; qcom,num-lpg-channels = <6>; #pwm-cells = <2>; qcom,lut-patterns = <0 14 28 42 56 70 84 100 100 84 70 56 42 28 14 0>; Loading arch/arm64/boot/dts/qcom/pm8150b.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,7 @@ reg = <0xb100 0x200>; reg-names = "lpg-base"; #pwm-cells = <2>; qcom,num-lpg-channels = <2>; }; pm8150b_hr_led: qcom,leds@d000 { Loading arch/arm64/boot/dts/qcom/pm8150l.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -266,6 +266,7 @@ reg = <0xb100 0x300>, <0xb000 0x100>; reg-names = "lpg-base", "lut-base"; #pwm-cells = <2>; qcom,num-lpg-channels = <3>; qcom,lut-patterns = <0 10 20 30 40 50 60 70 80 90 100 90 80 70 60 50 40 30 20 10 0>; lpg1 { Loading drivers/leds/leds-qpnp-flash-v2.c +26 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,22 @@ static int qpnp_flash_led_headroom_config(struct qpnp_flash_led *led) return rc; } static int qpnp_flash_led_safety_tmr_config(struct qpnp_flash_led *led) { int rc = 0, i, addr_offset; for (i = 0; i < led->num_fnodes; i++) { addr_offset = led->fnode[i].id; rc = qpnp_flash_led_write(led, FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset), FLASH_LED_SAFETY_TMR_DISABLED); if (rc < 0) return rc; } return rc; } static int qpnp_flash_led_strobe_config(struct qpnp_flash_led *led) { int i, rc, addr_offset; Loading Loading @@ -542,6 +558,10 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) if (rc < 0) return rc; rc = qpnp_flash_led_safety_tmr_config(led); if (rc < 0) return rc; rc = qpnp_flash_led_strobe_config(led); if (rc < 0) return rc; Loading Loading @@ -1138,6 +1158,12 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode) if (rc < 0) return rc; rc = qpnp_flash_led_write(led, FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset), FLASH_LED_SAFETY_TMR_DISABLED); if (rc < 0) return rc; led->fnode[i].led_on = false; if (led->fnode[i].strobe_sel == HW_STROBE) { Loading drivers/pwm/pwm-qti-lpg.c +45 −10 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ Loading Loading @@ -867,6 +867,19 @@ static int qpnp_lpg_pwm_enable(struct pwm_chip *pwm_chip, return -ENODEV; } /* * Update PWM_VALUE_SYNC to make sure PWM_VALUE * will be updated everytime before enabling. */ if (lpg->src_sel == PWM_VALUE) { rc = qpnp_lpg_write(lpg, REG_LPG_PWM_SYNC, LPG_PWM_VALUE_SYNC); if (rc < 0) { dev_err(lpg->chip->dev, "Write LPG_PWM_SYNC failed, rc=%d\n", rc); return rc; } } rc = qpnp_lpg_set_glitch_removal(lpg, true); if (rc < 0) { dev_err(lpg->chip->dev, "Enable glitch-removal failed, rc=%d\n", Loading Loading @@ -1009,13 +1022,9 @@ static const struct pwm_ops qpnp_lpg_pwm_ops = { .owner = THIS_MODULE, }; static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip) static int qpnp_get_lpg_channels(struct qpnp_lpg_chip *chip, u32 *base) { struct device_node *child; struct qpnp_lpg_channel *lpg; struct lpg_ramp_config *ramp; int rc = 0, i; u32 base, length, lpg_chan_id, tmp; int rc; const __be32 *addr; addr = of_get_address(chip->dev->of_node, 0, NULL, NULL); Loading @@ -1024,10 +1033,36 @@ static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip) return -EINVAL; } base = be32_to_cpu(addr[0]); length = be32_to_cpu(addr[1]); *base = be32_to_cpu(addr[0]); rc = of_property_read_u32(chip->dev->of_node, "qcom,num-lpg-channels", &chip->num_lpgs); if (rc < 0) { dev_err(chip->dev, "Failed to get qcom,num-lpg-channels, rc=%d\n", rc); return rc; } if (chip->num_lpgs == 0) { dev_err(chip->dev, "No LPG channels specified\n"); return -EINVAL; } return 0; } static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip) { struct device_node *child; struct qpnp_lpg_channel *lpg; struct lpg_ramp_config *ramp; int rc = 0, i; u32 base, length, lpg_chan_id, tmp; const __be32 *addr; rc = qpnp_get_lpg_channels(chip, &base); if (rc < 0) return rc; chip->num_lpgs = length / REG_SIZE_PER_LPG; chip->lpgs = devm_kcalloc(chip->dev, chip->num_lpgs, sizeof(*chip->lpgs), GFP_KERNEL); if (!chip->lpgs) Loading Loading
Documentation/devicetree/bindings/pwm/pwm-qti-lpg.txt +7 −3 Original line number Diff line number Diff line Loading @@ -11,9 +11,7 @@ device module in Qualcomm Technologies, Inc. PMIC chips. - reg: Usage: required Value type: <prop-encoded-array> Definition: Register base and length for LPG and LUT modules. LPG size or length available per channel varies depending on the number of channels in PMIC. Definition: Register base for LPG and LUT modules. - reg-names: Usage: required Loading @@ -30,6 +28,11 @@ device module in Qualcomm Technologies, Inc. PMIC chips. the PWM channel ID indexed from 0, and the second cell is the PWM default period in nanoseconds. - qcom,num-lpg-channels: Usage: required Value type: <u32> Definition: The number of the consecutive LPG/PWM channels in the chip. - qcom,lut-patterns: Usage: optional Value type: <prop-encoded-array> Loading Loading @@ -122,6 +125,7 @@ Example: compatible = "qcom,pwm-lpg"; reg = <0xb100 0x600>, <0xb000 0x100>; reg-names = "lpg-base", "lut-base"; qcom,num-lpg-channels = <6>; #pwm-cells = <2>; qcom,lut-patterns = <0 14 28 42 56 70 84 100 100 84 70 56 42 28 14 0>; Loading
arch/arm64/boot/dts/qcom/pm8150b.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,7 @@ reg = <0xb100 0x200>; reg-names = "lpg-base"; #pwm-cells = <2>; qcom,num-lpg-channels = <2>; }; pm8150b_hr_led: qcom,leds@d000 { Loading
arch/arm64/boot/dts/qcom/pm8150l.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -266,6 +266,7 @@ reg = <0xb100 0x300>, <0xb000 0x100>; reg-names = "lpg-base", "lut-base"; #pwm-cells = <2>; qcom,num-lpg-channels = <3>; qcom,lut-patterns = <0 10 20 30 40 50 60 70 80 90 100 90 80 70 60 50 40 30 20 10 0>; lpg1 { Loading
drivers/leds/leds-qpnp-flash-v2.c +26 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,22 @@ static int qpnp_flash_led_headroom_config(struct qpnp_flash_led *led) return rc; } static int qpnp_flash_led_safety_tmr_config(struct qpnp_flash_led *led) { int rc = 0, i, addr_offset; for (i = 0; i < led->num_fnodes; i++) { addr_offset = led->fnode[i].id; rc = qpnp_flash_led_write(led, FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset), FLASH_LED_SAFETY_TMR_DISABLED); if (rc < 0) return rc; } return rc; } static int qpnp_flash_led_strobe_config(struct qpnp_flash_led *led) { int i, rc, addr_offset; Loading Loading @@ -542,6 +558,10 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) if (rc < 0) return rc; rc = qpnp_flash_led_safety_tmr_config(led); if (rc < 0) return rc; rc = qpnp_flash_led_strobe_config(led); if (rc < 0) return rc; Loading Loading @@ -1138,6 +1158,12 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode) if (rc < 0) return rc; rc = qpnp_flash_led_write(led, FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset), FLASH_LED_SAFETY_TMR_DISABLED); if (rc < 0) return rc; led->fnode[i].led_on = false; if (led->fnode[i].strobe_sel == HW_STROBE) { Loading
drivers/pwm/pwm-qti-lpg.c +45 −10 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ Loading Loading @@ -867,6 +867,19 @@ static int qpnp_lpg_pwm_enable(struct pwm_chip *pwm_chip, return -ENODEV; } /* * Update PWM_VALUE_SYNC to make sure PWM_VALUE * will be updated everytime before enabling. */ if (lpg->src_sel == PWM_VALUE) { rc = qpnp_lpg_write(lpg, REG_LPG_PWM_SYNC, LPG_PWM_VALUE_SYNC); if (rc < 0) { dev_err(lpg->chip->dev, "Write LPG_PWM_SYNC failed, rc=%d\n", rc); return rc; } } rc = qpnp_lpg_set_glitch_removal(lpg, true); if (rc < 0) { dev_err(lpg->chip->dev, "Enable glitch-removal failed, rc=%d\n", Loading Loading @@ -1009,13 +1022,9 @@ static const struct pwm_ops qpnp_lpg_pwm_ops = { .owner = THIS_MODULE, }; static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip) static int qpnp_get_lpg_channels(struct qpnp_lpg_chip *chip, u32 *base) { struct device_node *child; struct qpnp_lpg_channel *lpg; struct lpg_ramp_config *ramp; int rc = 0, i; u32 base, length, lpg_chan_id, tmp; int rc; const __be32 *addr; addr = of_get_address(chip->dev->of_node, 0, NULL, NULL); Loading @@ -1024,10 +1033,36 @@ static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip) return -EINVAL; } base = be32_to_cpu(addr[0]); length = be32_to_cpu(addr[1]); *base = be32_to_cpu(addr[0]); rc = of_property_read_u32(chip->dev->of_node, "qcom,num-lpg-channels", &chip->num_lpgs); if (rc < 0) { dev_err(chip->dev, "Failed to get qcom,num-lpg-channels, rc=%d\n", rc); return rc; } if (chip->num_lpgs == 0) { dev_err(chip->dev, "No LPG channels specified\n"); return -EINVAL; } return 0; } static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip) { struct device_node *child; struct qpnp_lpg_channel *lpg; struct lpg_ramp_config *ramp; int rc = 0, i; u32 base, length, lpg_chan_id, tmp; const __be32 *addr; rc = qpnp_get_lpg_channels(chip, &base); if (rc < 0) return rc; chip->num_lpgs = length / REG_SIZE_PER_LPG; chip->lpgs = devm_kcalloc(chip->dev, chip->num_lpgs, sizeof(*chip->lpgs), GFP_KERNEL); if (!chip->lpgs) Loading