Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pwm/for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
"This rather small set of changes includes some minor fixes and
improvements.

The AB8500 driver gained support for reading the initial hardware
state and the Synopsys DesignWare driver received some work to prepare
for device tree and platform support"

* tag 'pwm/for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
pwm: dwc: Use devm_pwmchip_add()
pwm: dwc: Move memory allocation to own function
pwm: dwc: Change &pci->dev to dev in probe
dt-bindings: pwm: Document Synopsys DesignWare snps,pwm-dw-apb-timers-pwm2
pwm: iqs620a: Replace one remaining instance of regmap_update_bits()
pwm: ab8500: Implement .get_state()
pwm: ab8500: Fix calculation of duty and period
pwm: lp3943: Drop unused i2c include
dt-bindings: pwm: mediatek: Convert pwm-mediatek to DT schema
pwm: stm32-lp: fix the check on arr and cmp registers update
pwm: Move pwm_capture() dummy to restore order
pwm: sifive: Always let the first pwm_apply_state succeed

+302 -90
+93
Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/pwm/mediatek,mt2712-pwm.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek PWM Controller 8 + 9 + maintainers: 10 + - John Crispin <john@phrozen.org> 11 + 12 + allOf: 13 + - $ref: pwm.yaml# 14 + 15 + properties: 16 + compatible: 17 + oneOf: 18 + - enum: 19 + - mediatek,mt2712-pwm 20 + - mediatek,mt6795-pwm 21 + - mediatek,mt7622-pwm 22 + - mediatek,mt7623-pwm 23 + - mediatek,mt7628-pwm 24 + - mediatek,mt7629-pwm 25 + - mediatek,mt8183-pwm 26 + - mediatek,mt8365-pwm 27 + - mediatek,mt8516-pwm 28 + - items: 29 + - enum: 30 + - mediatek,mt8195-pwm 31 + - const: mediatek,mt8183-pwm 32 + 33 + reg: 34 + maxItems: 1 35 + 36 + "#pwm-cells": 37 + const: 2 38 + 39 + interrupts: 40 + maxItems: 1 41 + 42 + clocks: 43 + minItems: 2 44 + maxItems: 10 45 + 46 + clock-names: 47 + description: 48 + This controller needs two input clocks for its core and one 49 + clock for each PWM output. 50 + minItems: 2 51 + items: 52 + - const: top 53 + - const: main 54 + - const: pwm1 55 + - const: pwm2 56 + - const: pwm3 57 + - const: pwm4 58 + - const: pwm5 59 + - const: pwm6 60 + - const: pwm7 61 + - const: pwm8 62 + 63 + required: 64 + - compatible 65 + - reg 66 + - "#pwm-cells" 67 + - clocks 68 + - clock-names 69 + 70 + additionalProperties: false 71 + 72 + examples: 73 + - | 74 + #include <dt-bindings/interrupt-controller/arm-gic.h> 75 + #include <dt-bindings/clock/mt2712-clk.h> 76 + #include <dt-bindings/interrupt-controller/irq.h> 77 + 78 + pwm0: pwm@11006000 { 79 + compatible = "mediatek,mt2712-pwm"; 80 + reg = <0x11006000 0x1000>; 81 + #pwm-cells = <2>; 82 + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>; 83 + clocks = <&topckgen CLK_TOP_PWM_SEL>, <&pericfg CLK_PERI_PWM>, 84 + <&pericfg CLK_PERI_PWM0>, <&pericfg CLK_PERI_PWM1>, 85 + <&pericfg CLK_PERI_PWM2>, <&pericfg CLK_PERI_PWM3>, 86 + <&pericfg CLK_PERI_PWM4>, <&pericfg CLK_PERI_PWM5>, 87 + <&pericfg CLK_PERI_PWM6>, <&pericfg CLK_PERI_PWM7>; 88 + clock-names = "top", "main", 89 + "pwm1", "pwm2", 90 + "pwm3", "pwm4", 91 + "pwm5", "pwm6", 92 + "pwm7", "pwm8"; 93 + };
-52
Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
··· 1 - MediaTek PWM controller 2 - 3 - Required properties: 4 - - compatible: should be "mediatek,<name>-pwm": 5 - - "mediatek,mt2712-pwm": found on mt2712 SoC. 6 - - "mediatek,mt6795-pwm": found on mt6795 SoC. 7 - - "mediatek,mt7622-pwm": found on mt7622 SoC. 8 - - "mediatek,mt7623-pwm": found on mt7623 SoC. 9 - - "mediatek,mt7628-pwm": found on mt7628 SoC. 10 - - "mediatek,mt7629-pwm": found on mt7629 SoC. 11 - - "mediatek,mt8183-pwm": found on mt8183 SoC. 12 - - "mediatek,mt8195-pwm", "mediatek,mt8183-pwm": found on mt8195 SoC. 13 - - "mediatek,mt8365-pwm": found on mt8365 SoC. 14 - - "mediatek,mt8516-pwm": found on mt8516 SoC. 15 - - reg: physical base address and length of the controller's registers. 16 - - #pwm-cells: must be 2. See pwm.yaml in this directory for a description of 17 - the cell format. 18 - - clocks: phandle and clock specifier of the PWM reference clock. 19 - - clock-names: must contain the following, except for MT7628 which 20 - has no clocks 21 - - "top": the top clock generator 22 - - "main": clock used by the PWM core 23 - - "pwm1-3": the three per PWM clocks for mt8365 24 - - "pwm1-8": the eight per PWM clocks for mt2712 25 - - "pwm1-6": the six per PWM clocks for mt7622 26 - - "pwm1-5": the five per PWM clocks for mt7623 27 - - "pwm1" : the PWM1 clock for mt7629 28 - - pinctrl-names: Must contain a "default" entry. 29 - - pinctrl-0: One property must exist for each entry in pinctrl-names. 30 - See pinctrl/pinctrl-bindings.txt for details of the property values. 31 - 32 - Optional properties: 33 - - assigned-clocks: Reference to the PWM clock entries. 34 - - assigned-clock-parents: The phandle of the parent clock of PWM clock. 35 - 36 - Example: 37 - pwm0: pwm@11006000 { 38 - compatible = "mediatek,mt7623-pwm"; 39 - reg = <0 0x11006000 0 0x1000>; 40 - #pwm-cells = <2>; 41 - clocks = <&topckgen CLK_TOP_PWM_SEL>, 42 - <&pericfg CLK_PERI_PWM>, 43 - <&pericfg CLK_PERI_PWM1>, 44 - <&pericfg CLK_PERI_PWM2>, 45 - <&pericfg CLK_PERI_PWM3>, 46 - <&pericfg CLK_PERI_PWM4>, 47 - <&pericfg CLK_PERI_PWM5>; 48 - clock-names = "top", "main", "pwm1", "pwm2", 49 - "pwm3", "pwm4", "pwm5"; 50 - pinctrl-names = "default"; 51 - pinctrl-0 = <&pwm0_pins>; 52 - };
+68
Documentation/devicetree/bindings/pwm/snps,dw-apb-timers-pwm2.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (C) 2022 SiFive, Inc. 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/pwm/snps,dw-apb-timers-pwm2.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Synopsys DW-APB timers PWM controller 9 + 10 + maintainers: 11 + - Ben Dooks <ben.dooks@sifive.com> 12 + 13 + description: 14 + This describes the DesignWare APB timers module when used in the PWM 15 + mode. The IP core can be generated with various options which can 16 + control the functionality, the number of PWMs available and other 17 + internal controls the designer requires. 18 + 19 + The IP block has a version register so this can be used for detection 20 + instead of having to encode the IP version number in the device tree 21 + comaptible. 22 + 23 + allOf: 24 + - $ref: pwm.yaml# 25 + 26 + properties: 27 + compatible: 28 + const: snps,dw-apb-timers-pwm2 29 + 30 + reg: 31 + maxItems: 1 32 + 33 + "#pwm-cells": 34 + const: 3 35 + 36 + clocks: 37 + items: 38 + - description: Interface bus clock 39 + - description: PWM reference clock 40 + 41 + clock-names: 42 + items: 43 + - const: bus 44 + - const: timer 45 + 46 + snps,pwm-number: 47 + $ref: /schemas/types.yaml#/definitions/uint32 48 + description: The number of PWM channels configured for this instance 49 + enum: [1, 2, 3, 4, 5, 6, 7, 8] 50 + 51 + required: 52 + - compatible 53 + - reg 54 + - "#pwm-cells" 55 + - clocks 56 + - clock-names 57 + 58 + additionalProperties: false 59 + 60 + examples: 61 + - | 62 + pwm: pwm@180000 { 63 + compatible = "snps,dw-apb-timers-pwm2"; 64 + reg = <0x180000 0x200>; 65 + #pwm-cells = <3>; 66 + clocks = <&bus>, <&timer>; 67 + clock-names = "bus", "timer"; 68 + };
+103 -9
drivers/pwm/pwm-ab8500.c
··· 3 3 * Copyright (C) ST-Ericsson SA 2010 4 4 * 5 5 * Author: Arun R Murthy <arun.murthy@stericsson.com> 6 + * Datasheet: https://web.archive.org/web/20130614115108/http://www.stericsson.com/developers/CD00291561_UM1031_AB8500_user_manual-rev5_CTDS_public.pdf 6 7 */ 7 8 #include <linux/err.h> 8 9 #include <linux/platform_device.h> ··· 21 20 #define AB8500_PWM_OUT_CTRL2_REG 0x61 22 21 #define AB8500_PWM_OUT_CTRL7_REG 0x66 23 22 23 + #define AB8500_PWM_CLKRATE 9600000 24 + 24 25 struct ab8500_pwm_chip { 25 26 struct pwm_chip chip; 26 27 unsigned int hwid; ··· 38 35 { 39 36 int ret; 40 37 u8 reg; 41 - unsigned int higher_val, lower_val; 38 + u8 higher_val, lower_val; 39 + unsigned int duty_steps, div; 42 40 struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); 43 41 44 42 if (state->polarity != PWM_POLARITY_NORMAL) 45 43 return -EINVAL; 46 44 47 - if (!state->enabled) { 45 + if (state->enabled) { 46 + /* 47 + * A time quantum is 48 + * q = (32 - FreqPWMOutx[3:0]) / AB8500_PWM_CLKRATE 49 + * The period is always 1024 q, duty_cycle is between 1q and 1024q. 50 + * 51 + * FreqPWMOutx[3:0] | output frequency | output frequency | 1024q = period 52 + * | (from manual) | (1 / 1024q) | = 1 / freq 53 + * -----------------+------------------+------------------+-------------- 54 + * b0000 | 293 Hz | 292.968750 Hz | 3413333.33 ns 55 + * b0001 | 302 Hz | 302.419355 Hz | 3306666.66 ns 56 + * b0010 | 312 Hz | 312.500000 Hz | 3200000 ns 57 + * b0011 | 323 Hz | 323.275862 Hz | 3093333.33 ns 58 + * b0100 | 334 Hz | 334.821429 Hz | 2986666.66 ns 59 + * b0101 | 347 Hz | 347.222222 Hz | 2880000 ns 60 + * b0110 | 360 Hz | 360.576923 Hz | 2773333.33 ns 61 + * b0111 | 375 Hz | 375.000000 Hz | 2666666.66 ns 62 + * b1000 | 390 Hz | 390.625000 Hz | 2560000 ns 63 + * b1001 | 407 Hz | 407.608696 Hz | 2453333.33 ns 64 + * b1010 | 426 Hz | 426.136364 Hz | 2346666.66 ns 65 + * b1011 | 446 Hz | 446.428571 Hz | 2240000 ns 66 + * b1100 | 468 Hz | 468.750000 Hz | 2133333.33 ns 67 + * b1101 | 493 Hz | 493.421053 Hz | 2026666.66 ns 68 + * b1110 | 520 Hz | 520.833333 Hz | 1920000 ns 69 + * b1111 | 551 Hz | 551.470588 Hz | 1813333.33 ns 70 + * 71 + * 72 + * AB8500_PWM_CLKRATE is a multiple of 1024, so the division by 73 + * 1024 can be done in this factor without loss of precision. 74 + */ 75 + div = min_t(u64, mul_u64_u64_div_u64(state->period, 76 + AB8500_PWM_CLKRATE >> 10, 77 + NSEC_PER_SEC), 32); /* 32 - FreqPWMOutx[3:0] */ 78 + if (div <= 16) 79 + /* requested period < 3413333.33 */ 80 + return -EINVAL; 81 + 82 + duty_steps = max_t(u64, mul_u64_u64_div_u64(state->duty_cycle, 83 + AB8500_PWM_CLKRATE, 84 + (u64)NSEC_PER_SEC * div), 1024); 85 + } 86 + 87 + /* 88 + * The hardware doesn't support duty_steps = 0 explicitly, but emits low 89 + * when disabled. 90 + */ 91 + if (!state->enabled || duty_steps == 0) { 48 92 ret = abx500_mask_and_set_register_interruptible(chip->dev, 49 93 AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 50 94 1 << ab8500->hwid, 0); ··· 103 53 } 104 54 105 55 /* 106 - * get the first 8 bits that are be written to 56 + * The lower 8 bits of duty_steps is written to ... 107 57 * AB8500_PWM_OUT_CTRL1_REG[0:7] 108 58 */ 109 - lower_val = state->duty_cycle & 0x00FF; 59 + lower_val = (duty_steps - 1) & 0x00ff; 110 60 /* 111 - * get bits [9:10] that are to be written to 112 - * AB8500_PWM_OUT_CTRL2_REG[0:1] 61 + * The two remaining high bits to 62 + * AB8500_PWM_OUT_CTRL2_REG[0:1]; together with FreqPWMOutx. 113 63 */ 114 - higher_val = ((state->duty_cycle & 0x0300) >> 8); 64 + higher_val = ((duty_steps - 1) & 0x0300) >> 8 | (32 - div) << 4; 115 65 116 66 reg = AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2); 117 67 118 68 ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, 119 - reg, (u8)lower_val); 69 + reg, lower_val); 120 70 if (ret < 0) 121 71 return ret; 122 72 123 73 ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, 124 - (reg + 1), (u8)higher_val); 74 + (reg + 1), higher_val); 125 75 if (ret < 0) 126 76 return ret; 127 77 78 + /* enable */ 128 79 ret = abx500_mask_and_set_register_interruptible(chip->dev, 129 80 AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 130 81 1 << ab8500->hwid, 1 << ab8500->hwid); ··· 136 85 return ret; 137 86 } 138 87 88 + static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 89 + struct pwm_state *state) 90 + { 91 + u8 ctrl7, lower_val, higher_val; 92 + int ret; 93 + struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); 94 + unsigned int div, duty_steps; 95 + 96 + ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, 97 + AB8500_PWM_OUT_CTRL7_REG, 98 + &ctrl7); 99 + if (ret) 100 + return ret; 101 + 102 + state->polarity = PWM_POLARITY_NORMAL; 103 + 104 + if (!(ctrl7 & 1 << ab8500->hwid)) { 105 + state->enabled = false; 106 + return 0; 107 + } 108 + 109 + ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, 110 + AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2), 111 + &lower_val); 112 + if (ret) 113 + return ret; 114 + 115 + ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, 116 + AB8500_PWM_OUT_CTRL2_REG + (ab8500->hwid * 2), 117 + &higher_val); 118 + if (ret) 119 + return ret; 120 + 121 + div = 32 - ((higher_val & 0xf0) >> 4); 122 + duty_steps = ((higher_val & 3) << 8 | lower_val) + 1; 123 + 124 + state->period = DIV64_U64_ROUND_UP((u64)div << 10, AB8500_PWM_CLKRATE); 125 + state->duty_cycle = DIV64_U64_ROUND_UP((u64)div * duty_steps, AB8500_PWM_CLKRATE); 126 + 127 + return 0; 128 + } 129 + 139 130 static const struct pwm_ops ab8500_pwm_ops = { 140 131 .apply = ab8500_pwm_apply, 132 + .get_state = ab8500_pwm_get_state, 141 133 .owner = THIS_MODULE, 142 134 }; 143 135
+21 -17
drivers/pwm/pwm-dwc.c
··· 198 198 .owner = THIS_MODULE, 199 199 }; 200 200 201 + static struct dwc_pwm *dwc_pwm_alloc(struct device *dev) 202 + { 203 + struct dwc_pwm *dwc; 204 + 205 + dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); 206 + if (!dwc) 207 + return NULL; 208 + 209 + dwc->chip.dev = dev; 210 + dwc->chip.ops = &dwc_pwm_ops; 211 + dwc->chip.npwm = DWC_TIMERS_TOTAL; 212 + 213 + dev_set_drvdata(dev, dwc); 214 + return dwc; 215 + } 216 + 201 217 static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) 202 218 { 203 219 struct device *dev = &pci->dev; 204 220 struct dwc_pwm *dwc; 205 221 int ret; 206 222 207 - dwc = devm_kzalloc(&pci->dev, sizeof(*dwc), GFP_KERNEL); 223 + dwc = dwc_pwm_alloc(dev); 208 224 if (!dwc) 209 225 return -ENOMEM; 210 226 211 227 ret = pcim_enable_device(pci); 212 228 if (ret) { 213 - dev_err(&pci->dev, 214 - "Failed to enable device (%pe)\n", ERR_PTR(ret)); 229 + dev_err(dev, "Failed to enable device (%pe)\n", ERR_PTR(ret)); 215 230 return ret; 216 231 } 217 232 ··· 234 219 235 220 ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci)); 236 221 if (ret) { 237 - dev_err(&pci->dev, 238 - "Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret)); 222 + dev_err(dev, "Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret)); 239 223 return ret; 240 224 } 241 225 242 226 dwc->base = pcim_iomap_table(pci)[0]; 243 227 if (!dwc->base) { 244 - dev_err(&pci->dev, "Base address missing\n"); 228 + dev_err(dev, "Base address missing\n"); 245 229 return -ENOMEM; 246 230 } 247 231 248 - pci_set_drvdata(pci, dwc); 249 - 250 - dwc->chip.dev = dev; 251 - dwc->chip.ops = &dwc_pwm_ops; 252 - dwc->chip.npwm = DWC_TIMERS_TOTAL; 253 - 254 - ret = pwmchip_add(&dwc->chip); 232 + ret = devm_pwmchip_add(dev, &dwc->chip); 255 233 if (ret) 256 234 return ret; 257 235 ··· 256 248 257 249 static void dwc_pwm_remove(struct pci_dev *pci) 258 250 { 259 - struct dwc_pwm *dwc = pci_get_drvdata(pci); 260 - 261 251 pm_runtime_forbid(&pci->dev); 262 252 pm_runtime_get_noresume(&pci->dev); 263 - 264 - pwmchip_remove(&dwc->chip); 265 253 } 266 254 267 255 #ifdef CONFIG_PM_SLEEP
+2 -2
drivers/pwm/pwm-iqs620a.c
··· 55 55 if (ret) 56 56 return ret; 57 57 58 - return regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS, 59 - IQS620_PWR_SETTINGS_PWM_OUT, 0xff); 58 + return regmap_set_bits(iqs62x->regmap, IQS620_PWR_SETTINGS, 59 + IQS620_PWR_SETTINGS_PWM_OUT); 60 60 } 61 61 62 62 static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
-1
drivers/pwm/pwm-lp3943.c
··· 8 8 */ 9 9 10 10 #include <linux/err.h> 11 - #include <linux/i2c.h> 12 11 #include <linux/mfd/lp3943.h> 13 12 #include <linux/module.h> 14 13 #include <linux/platform_device.h>
+7 -1
drivers/pwm/pwm-sifive.c
··· 161 161 162 162 mutex_lock(&ddata->lock); 163 163 if (state->period != ddata->approx_period) { 164 - if (ddata->user_count != 1) { 164 + /* 165 + * Don't let a 2nd user change the period underneath the 1st user. 166 + * However if ddate->approx_period == 0 this is the first time we set 167 + * any period, so let whoever gets here first set the period so other 168 + * users who agree on the period won't fail. 169 + */ 170 + if (ddata->user_count != 1 && ddata->approx_period) { 165 171 mutex_unlock(&ddata->lock); 166 172 return -EBUSY; 167 173 }
+1 -1
drivers/pwm/pwm-stm32-lp.c
··· 127 127 128 128 /* ensure CMP & ARR registers are properly written */ 129 129 ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, 130 - (val & STM32_LPTIM_CMPOK_ARROK), 130 + (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 131 131 100, 1000); 132 132 if (ret) { 133 133 dev_err(priv->chip.dev, "ARR/CMP registers write issue\n");
+7 -7
include/linux/pwm.h
··· 440 440 return -EINVAL; 441 441 } 442 442 443 - static inline int pwm_capture(struct pwm_device *pwm, 444 - struct pwm_capture *result, 445 - unsigned long timeout) 446 - { 447 - return -EINVAL; 448 - } 449 - 450 443 static inline int pwm_enable(struct pwm_device *pwm) 451 444 { 452 445 might_sleep(); ··· 449 456 static inline void pwm_disable(struct pwm_device *pwm) 450 457 { 451 458 might_sleep(); 459 + } 460 + 461 + static inline int pwm_capture(struct pwm_device *pwm, 462 + struct pwm_capture *result, 463 + unsigned long timeout) 464 + { 465 + return -EINVAL; 452 466 } 453 467 454 468 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)