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.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux

Pull pwm updates from Uwe Kleine-König:
"This contains some cleanups to the core and some mostly minor updates
to a bunch of drivers and device tree bindings. One thing worth
pointing out is that it contains an immutable branch containing
support for a new mfd chip (Analog Devices ADP5585) with several sub
drivers.

Thanks go to Andrew Kreimer, Clark Wang, Conor Dooley, David Lechner,
Dmitry Rokosov, Frank Li, Geert Uytterhoeven, George Stark, Jiapeng
Chong, Krzysztof Kozlowski, Laurent Pinchart, Liao Chen, Liu Ying, Rob
Herring and Wolfram Sang for code contributions and reviews and to Lee
Jones for preparing the above mentioned immutable branch"

* tag 'pwm/for-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux: (21 commits)
pwm: stm32: Fix a typo
dt-bindings: pwm: amlogic: Add new bindings for meson A1 PWM
dt-bindings: pwm: amlogic: Add optional power-domains
pwm: Switch back to struct platform_driver::remove()
dt-bindings: pwm: allwinner,sun4i-a10-pwm: add top-level constraints
pwm: axi-pwmgen: use shared macro for version reg
pwm: atmel-hlcdc: Drop trailing comma
pwm: atmel-hlcdc: Enable module autoloading
pwm: omap-dmtimer: Use of_property_read_bool()
pwm: adp5585: Set OSC_EN bit to 1 when PWM state is enabled
pwm: lp3943: Fix an incorrect type in lp3943_pwm_parse_dt()
pwm: Simplify pwm_capture()
pwm: lp3943: Use of_property_count_u32_elems() to get property length
pwm: Don't export pwm_capture()
pwm: Make info in traces about affected pwm more useful
dt-bindings: pwm: renesas,tpu: Add r8a779h0 support
dt-bindings: pwm: renesas,pwm-rcar: Add r8a779h0 support
pwm: adp5585: Add Analog Devices ADP5585 support
gpio: adp5585: Add Analog Devices ADP5585 support
mfd: adp5585: Add Analog Devices ADP5585 core support
...

+939 -56
+92
Documentation/devicetree/bindings/mfd/adi,adp5585.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/adi,adp5585.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Analog Devices ADP5585 Keypad Decoder and I/O Expansion 8 + 9 + maintainers: 10 + - Laurent Pinchart <laurent.pinchart@ideasonboard.com> 11 + 12 + description: 13 + The ADP5585 is a 10/11 input/output port expander with a built in keypad 14 + matrix decoder, programmable logic, reset generator, and PWM generator. 15 + 16 + properties: 17 + compatible: 18 + items: 19 + - enum: 20 + - adi,adp5585-00 # Default 21 + - adi,adp5585-01 # 11 GPIOs 22 + - adi,adp5585-02 # No pull-up resistors by default on special pins 23 + - adi,adp5585-03 # Alternate I2C address 24 + - adi,adp5585-04 # Pull-down resistors on all pins by default 25 + - const: adi,adp5585 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + interrupts: 31 + maxItems: 1 32 + 33 + vdd-supply: true 34 + 35 + gpio-controller: true 36 + 37 + '#gpio-cells': 38 + const: 2 39 + 40 + gpio-reserved-ranges: true 41 + 42 + "#pwm-cells": 43 + const: 3 44 + 45 + required: 46 + - compatible 47 + - reg 48 + - gpio-controller 49 + - "#gpio-cells" 50 + - "#pwm-cells" 51 + 52 + allOf: 53 + - if: 54 + properties: 55 + compatible: 56 + contains: 57 + const: adi,adp5585-01 58 + then: 59 + properties: 60 + gpio-reserved-ranges: false 61 + else: 62 + properties: 63 + gpio-reserved-ranges: 64 + maxItems: 1 65 + items: 66 + items: 67 + - const: 5 68 + - const: 1 69 + 70 + additionalProperties: false 71 + 72 + examples: 73 + - | 74 + i2c { 75 + #address-cells = <1>; 76 + #size-cells = <0>; 77 + 78 + io-expander@34 { 79 + compatible = "adi,adp5585-00", "adi,adp5585"; 80 + reg = <0x34>; 81 + 82 + vdd-supply = <&reg_3v3>; 83 + 84 + gpio-controller; 85 + #gpio-cells = <2>; 86 + gpio-reserved-ranges = <5 1>; 87 + 88 + #pwm-cells = <3>; 89 + }; 90 + }; 91 + 92 + ...
+5 -4
Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml
··· 46 46 - description: Module Clock 47 47 - description: Bus Clock 48 48 49 - # Even though it only applies to subschemas under the conditionals, 50 - # not listing them here will trigger a warning because of the 51 - # additionalsProperties set to false. 52 - clock-names: true 49 + clock-names: 50 + minItems: 1 51 + items: 52 + - const: mod 53 + - const: bus 53 54 54 55 resets: 55 56 maxItems: 1
+17
Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
··· 39 39 - amlogic,meson-s4-pwm 40 40 - items: 41 41 - enum: 42 + - amlogic,meson-a1-pwm 43 + - const: amlogic,meson-s4-pwm 44 + - items: 45 + - enum: 42 46 - amlogic,meson8b-pwm-v2 43 47 - amlogic,meson-gxbb-pwm-v2 44 48 - amlogic,meson-axg-pwm-v2 ··· 59 55 clock-names: 60 56 minItems: 1 61 57 maxItems: 2 58 + 59 + power-domains: 60 + maxItems: 1 62 61 63 62 "#pwm-cells": 64 63 const: 3 ··· 142 135 clock-names: false 143 136 required: 144 137 - clocks 138 + 139 + - if: 140 + properties: 141 + compatible: 142 + contains: 143 + enum: 144 + - amlogic,meson-a1-pwm 145 + then: 146 + required: 147 + - power-domains 145 148 146 149 additionalProperties: false 147 150
+1
Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
··· 37 37 - renesas,pwm-r8a77995 # R-Car D3 38 38 - renesas,pwm-r8a779a0 # R-Car V3U 39 39 - renesas,pwm-r8a779g0 # R-Car V4H 40 + - renesas,pwm-r8a779h0 # R-Car V4M 40 41 - const: renesas,pwm-rcar 41 42 42 43 reg:
+1
Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.yaml
··· 41 41 - renesas,tpu-r8a77980 # R-Car V3H 42 42 - renesas,tpu-r8a779a0 # R-Car V3U 43 43 - renesas,tpu-r8a779g0 # R-Car V4H 44 + - renesas,tpu-r8a779h0 # R-Car V4M 44 45 - const: renesas,tpu 45 46 46 47 reg:
-4
Documentation/devicetree/bindings/trivial-devices.yaml
··· 38 38 - ad,adm9240 39 39 # AD5110 - Nonvolatile Digital Potentiometer 40 40 - adi,ad5110 41 - # Analog Devices ADP5585 Keypad Decoder and I/O Expansion 42 - - adi,adp5585 43 - # Analog Devices ADP5585 Keypad Decoder and I/O Expansion with support for Row5 44 - - adi,adp5585-02 45 41 # Analog Devices ADP5589 Keypad Decoder and I/O Expansion 46 42 - adi,adp5589 47 43 # Analog Devices LT7182S Dual Channel 6A, 20V PolyPhase Step-Down Silent Switcher
+11
MAINTAINERS
··· 538 538 F: drivers/mfd/adp5520.c 539 539 F: drivers/video/backlight/adp5520_bl.c 540 540 541 + ADP5585 GPIO EXPANDER, PWM AND KEYPAD CONTROLLER DRIVER 542 + M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 543 + L: linux-gpio@vger.kernel.org 544 + L: linux-pwm@vger.kernel.org 545 + S: Maintained 546 + F: Documentation/devicetree/bindings/*/adi,adp5585*.yaml 547 + F: drivers/gpio/gpio-adp5585.c 548 + F: drivers/mfd/adp5585.c 549 + F: drivers/pwm/pwm-adp5585.c 550 + F: include/linux/mfd/adp5585.h 551 + 541 552 ADP5588 QWERTY KEYPAD AND IO EXPANDER DRIVER (ADP5588/ADP5587) 542 553 M: Michael Hennerich <michael.hennerich@analog.com> 543 554 S: Supported
+7
drivers/gpio/Kconfig
··· 1233 1233 This option enables support for on-chip GPIO found 1234 1234 on Analog Devices ADP5520 PMICs. 1235 1235 1236 + config GPIO_ADP5585 1237 + tristate "GPIO Support for ADP5585" 1238 + depends on MFD_ADP5585 1239 + help 1240 + This option enables support for the GPIO function found in the Analog 1241 + Devices ADP5585. 1242 + 1236 1243 config GPIO_ALTERA_A10SR 1237 1244 tristate "Altera Arria10 System Resource GPIO" 1238 1245 depends on MFD_ALTERA_A10SR
+1
drivers/gpio/Makefile
··· 26 26 obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o 27 27 obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o 28 28 obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o 29 + obj-$(CONFIG_GPIO_ADP5585) += gpio-adp5585.o 29 30 obj-$(CONFIG_GPIO_AGGREGATOR) += gpio-aggregator.o 30 31 obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o 31 32 obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
+229
drivers/gpio/gpio-adp5585.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Analog Devices ADP5585 GPIO driver 4 + * 5 + * Copyright 2022 NXP 6 + * Copyright 2024 Ideas on Board Oy 7 + */ 8 + 9 + #include <linux/device.h> 10 + #include <linux/gpio/driver.h> 11 + #include <linux/mfd/adp5585.h> 12 + #include <linux/module.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regmap.h> 15 + #include <linux/types.h> 16 + 17 + #define ADP5585_GPIO_MAX 11 18 + 19 + struct adp5585_gpio_dev { 20 + struct gpio_chip gpio_chip; 21 + struct regmap *regmap; 22 + }; 23 + 24 + static int adp5585_gpio_get_direction(struct gpio_chip *chip, unsigned int off) 25 + { 26 + struct adp5585_gpio_dev *adp5585_gpio = gpiochip_get_data(chip); 27 + unsigned int bank = ADP5585_BANK(off); 28 + unsigned int bit = ADP5585_BIT(off); 29 + unsigned int val; 30 + 31 + regmap_read(adp5585_gpio->regmap, ADP5585_GPIO_DIRECTION_A + bank, &val); 32 + 33 + return val & bit ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; 34 + } 35 + 36 + static int adp5585_gpio_direction_input(struct gpio_chip *chip, unsigned int off) 37 + { 38 + struct adp5585_gpio_dev *adp5585_gpio = gpiochip_get_data(chip); 39 + unsigned int bank = ADP5585_BANK(off); 40 + unsigned int bit = ADP5585_BIT(off); 41 + 42 + return regmap_clear_bits(adp5585_gpio->regmap, 43 + ADP5585_GPIO_DIRECTION_A + bank, bit); 44 + } 45 + 46 + static int adp5585_gpio_direction_output(struct gpio_chip *chip, unsigned int off, int val) 47 + { 48 + struct adp5585_gpio_dev *adp5585_gpio = gpiochip_get_data(chip); 49 + unsigned int bank = ADP5585_BANK(off); 50 + unsigned int bit = ADP5585_BIT(off); 51 + int ret; 52 + 53 + ret = regmap_update_bits(adp5585_gpio->regmap, 54 + ADP5585_GPO_DATA_OUT_A + bank, bit, 55 + val ? bit : 0); 56 + if (ret) 57 + return ret; 58 + 59 + return regmap_set_bits(adp5585_gpio->regmap, 60 + ADP5585_GPIO_DIRECTION_A + bank, bit); 61 + } 62 + 63 + static int adp5585_gpio_get_value(struct gpio_chip *chip, unsigned int off) 64 + { 65 + struct adp5585_gpio_dev *adp5585_gpio = gpiochip_get_data(chip); 66 + unsigned int bank = ADP5585_BANK(off); 67 + unsigned int bit = ADP5585_BIT(off); 68 + unsigned int reg; 69 + unsigned int val; 70 + 71 + /* 72 + * The input status register doesn't reflect the pin state when the 73 + * GPIO is configured as an output. Check the direction, and read the 74 + * input status from GPI_STATUS or output value from GPO_DATA_OUT 75 + * accordingly. 76 + * 77 + * We don't need any locking, as concurrent access to the same GPIO 78 + * isn't allowed by the GPIO API, so there's no risk of the 79 + * .direction_input(), .direction_output() or .set() operations racing 80 + * with this. 81 + */ 82 + regmap_read(adp5585_gpio->regmap, ADP5585_GPIO_DIRECTION_A + bank, &val); 83 + reg = val & bit ? ADP5585_GPO_DATA_OUT_A : ADP5585_GPI_STATUS_A; 84 + regmap_read(adp5585_gpio->regmap, reg + bank, &val); 85 + 86 + return !!(val & bit); 87 + } 88 + 89 + static void adp5585_gpio_set_value(struct gpio_chip *chip, unsigned int off, int val) 90 + { 91 + struct adp5585_gpio_dev *adp5585_gpio = gpiochip_get_data(chip); 92 + unsigned int bank = ADP5585_BANK(off); 93 + unsigned int bit = ADP5585_BIT(off); 94 + 95 + regmap_update_bits(adp5585_gpio->regmap, ADP5585_GPO_DATA_OUT_A + bank, 96 + bit, val ? bit : 0); 97 + } 98 + 99 + static int adp5585_gpio_set_bias(struct adp5585_gpio_dev *adp5585_gpio, 100 + unsigned int off, unsigned int bias) 101 + { 102 + unsigned int bit, reg, mask, val; 103 + 104 + /* 105 + * The bias configuration fields are 2 bits wide and laid down in 106 + * consecutive registers ADP5585_RPULL_CONFIG_*, with a hole of 4 bits 107 + * after R5. 108 + */ 109 + bit = off * 2 + (off > 5 ? 4 : 0); 110 + reg = ADP5585_RPULL_CONFIG_A + bit / 8; 111 + mask = ADP5585_Rx_PULL_CFG_MASK << (bit % 8); 112 + val = bias << (bit % 8); 113 + 114 + return regmap_update_bits(adp5585_gpio->regmap, reg, mask, val); 115 + } 116 + 117 + static int adp5585_gpio_set_drive(struct adp5585_gpio_dev *adp5585_gpio, 118 + unsigned int off, enum pin_config_param drive) 119 + { 120 + unsigned int bank = ADP5585_BANK(off); 121 + unsigned int bit = ADP5585_BIT(off); 122 + 123 + return regmap_update_bits(adp5585_gpio->regmap, 124 + ADP5585_GPO_OUT_MODE_A + bank, bit, 125 + drive == PIN_CONFIG_DRIVE_OPEN_DRAIN ? bit : 0); 126 + } 127 + 128 + static int adp5585_gpio_set_debounce(struct adp5585_gpio_dev *adp5585_gpio, 129 + unsigned int off, unsigned int debounce) 130 + { 131 + unsigned int bank = ADP5585_BANK(off); 132 + unsigned int bit = ADP5585_BIT(off); 133 + 134 + return regmap_update_bits(adp5585_gpio->regmap, 135 + ADP5585_DEBOUNCE_DIS_A + bank, bit, 136 + debounce ? 0 : bit); 137 + } 138 + 139 + static int adp5585_gpio_set_config(struct gpio_chip *chip, unsigned int off, 140 + unsigned long config) 141 + { 142 + struct adp5585_gpio_dev *adp5585_gpio = gpiochip_get_data(chip); 143 + enum pin_config_param param = pinconf_to_config_param(config); 144 + u32 arg = pinconf_to_config_argument(config); 145 + 146 + switch (param) { 147 + case PIN_CONFIG_BIAS_DISABLE: 148 + return adp5585_gpio_set_bias(adp5585_gpio, off, 149 + ADP5585_Rx_PULL_CFG_DISABLE); 150 + 151 + case PIN_CONFIG_BIAS_PULL_DOWN: 152 + return adp5585_gpio_set_bias(adp5585_gpio, off, arg ? 153 + ADP5585_Rx_PULL_CFG_PD_300K : 154 + ADP5585_Rx_PULL_CFG_DISABLE); 155 + 156 + case PIN_CONFIG_BIAS_PULL_UP: 157 + return adp5585_gpio_set_bias(adp5585_gpio, off, arg ? 158 + ADP5585_Rx_PULL_CFG_PU_300K : 159 + ADP5585_Rx_PULL_CFG_DISABLE); 160 + 161 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 162 + case PIN_CONFIG_DRIVE_PUSH_PULL: 163 + return adp5585_gpio_set_drive(adp5585_gpio, off, param); 164 + 165 + case PIN_CONFIG_INPUT_DEBOUNCE: 166 + return adp5585_gpio_set_debounce(adp5585_gpio, off, arg); 167 + 168 + default: 169 + return -ENOTSUPP; 170 + }; 171 + } 172 + 173 + static int adp5585_gpio_probe(struct platform_device *pdev) 174 + { 175 + struct adp5585_dev *adp5585 = dev_get_drvdata(pdev->dev.parent); 176 + struct adp5585_gpio_dev *adp5585_gpio; 177 + struct device *dev = &pdev->dev; 178 + struct gpio_chip *gc; 179 + int ret; 180 + 181 + adp5585_gpio = devm_kzalloc(dev, sizeof(*adp5585_gpio), GFP_KERNEL); 182 + if (!adp5585_gpio) 183 + return -ENOMEM; 184 + 185 + adp5585_gpio->regmap = adp5585->regmap; 186 + 187 + device_set_of_node_from_dev(dev, dev->parent); 188 + 189 + gc = &adp5585_gpio->gpio_chip; 190 + gc->parent = dev; 191 + gc->get_direction = adp5585_gpio_get_direction; 192 + gc->direction_input = adp5585_gpio_direction_input; 193 + gc->direction_output = adp5585_gpio_direction_output; 194 + gc->get = adp5585_gpio_get_value; 195 + gc->set = adp5585_gpio_set_value; 196 + gc->set_config = adp5585_gpio_set_config; 197 + gc->can_sleep = true; 198 + 199 + gc->base = -1; 200 + gc->ngpio = ADP5585_GPIO_MAX; 201 + gc->label = pdev->name; 202 + gc->owner = THIS_MODULE; 203 + 204 + ret = devm_gpiochip_add_data(dev, &adp5585_gpio->gpio_chip, 205 + adp5585_gpio); 206 + if (ret) 207 + return dev_err_probe(dev, ret, "failed to add GPIO chip\n"); 208 + 209 + return 0; 210 + } 211 + 212 + static const struct platform_device_id adp5585_gpio_id_table[] = { 213 + { "adp5585-gpio" }, 214 + { /* Sentinel */ } 215 + }; 216 + MODULE_DEVICE_TABLE(platform, adp5585_gpio_id_table); 217 + 218 + static struct platform_driver adp5585_gpio_driver = { 219 + .driver = { 220 + .name = "adp5585-gpio", 221 + }, 222 + .probe = adp5585_gpio_probe, 223 + .id_table = adp5585_gpio_id_table, 224 + }; 225 + module_platform_driver(adp5585_gpio_driver); 226 + 227 + MODULE_AUTHOR("Haibo Chen <haibo.chen@nxp.com>"); 228 + MODULE_DESCRIPTION("GPIO ADP5585 Driver"); 229 + MODULE_LICENSE("GPL");
+12
drivers/mfd/Kconfig
··· 20 20 This is the core driver for CS5535/CS5536 MFD functions. This is 21 21 necessary for using the board's GPIO and MFGPT functionality. 22 22 23 + config MFD_ADP5585 24 + tristate "Analog Devices ADP5585 keypad decoder and I/O expander driver" 25 + select MFD_CORE 26 + select REGMAP_I2C 27 + depends on I2C 28 + depends on OF || COMPILE_TEST 29 + help 30 + Say yes here to add support for the Analog Devices ADP5585 GPIO 31 + expander, PWM and keypad controller. This includes the I2C driver and 32 + the core APIs _only_, you have to select individual components like 33 + the GPIO and PWM functions under the corresponding menus. 34 + 23 35 config MFD_ALTERA_A10SR 24 36 bool "Altera Arria10 DevKit System Resource chip" 25 37 depends on ARCH_INTEL_SOCFPGA && SPI_MASTER=y && OF
+1
drivers/mfd/Makefile
··· 193 193 obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 194 194 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 195 195 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 196 + obj-$(CONFIG_MFD_ADP5585) += adp5585.o 196 197 obj-$(CONFIG_MFD_KEMPLD) += kempld-core.o 197 198 obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO) += intel_quark_i2c_gpio.o 198 199 obj-$(CONFIG_LPC_SCH) += lpc_sch.o
+205
drivers/mfd/adp5585.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Analog Devices ADP5585 I/O expander, PWM controller and keypad controller 4 + * 5 + * Copyright 2022 NXP 6 + * Copyright 2024 Ideas on Board Oy 7 + */ 8 + 9 + #include <linux/array_size.h> 10 + #include <linux/device.h> 11 + #include <linux/err.h> 12 + #include <linux/i2c.h> 13 + #include <linux/mfd/adp5585.h> 14 + #include <linux/mfd/core.h> 15 + #include <linux/mod_devicetable.h> 16 + #include <linux/module.h> 17 + #include <linux/regmap.h> 18 + #include <linux/types.h> 19 + 20 + static const struct mfd_cell adp5585_devs[] = { 21 + { .name = "adp5585-gpio", }, 22 + { .name = "adp5585-pwm", }, 23 + }; 24 + 25 + static const struct regmap_range adp5585_volatile_ranges[] = { 26 + regmap_reg_range(ADP5585_ID, ADP5585_GPI_STATUS_B), 27 + }; 28 + 29 + static const struct regmap_access_table adp5585_volatile_regs = { 30 + .yes_ranges = adp5585_volatile_ranges, 31 + .n_yes_ranges = ARRAY_SIZE(adp5585_volatile_ranges), 32 + }; 33 + 34 + /* 35 + * Chip variants differ in the default configuration of pull-up and pull-down 36 + * resistors, and therefore have different default register values: 37 + * 38 + * - The -00, -01 and -03 variants (collectively referred to as 39 + * ADP5585_REGMAP_00) have pull-up on all GPIO pins by default. 40 + * - The -02 variant has no default pull-up or pull-down resistors. 41 + * - The -04 variant has default pull-down resistors on all GPIO pins. 42 + */ 43 + 44 + static const u8 adp5585_regmap_defaults_00[ADP5585_MAX_REG + 1] = { 45 + /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 + /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 + /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 + /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 + /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 + /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 + /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 + /* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 53 + }; 54 + 55 + static const u8 adp5585_regmap_defaults_02[ADP5585_MAX_REG + 1] = { 56 + /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 + /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 + /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 59 + /* 0x18 */ 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 60 + /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 + /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 + /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 + /* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 64 + }; 65 + 66 + static const u8 adp5585_regmap_defaults_04[ADP5585_MAX_REG + 1] = { 67 + /* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 + /* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 + /* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 70 + /* 0x18 */ 0x05, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 71 + /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 + /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 + /* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 + /* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 75 + }; 76 + 77 + enum adp5585_regmap_type { 78 + ADP5585_REGMAP_00, 79 + ADP5585_REGMAP_02, 80 + ADP5585_REGMAP_04, 81 + }; 82 + 83 + static const struct regmap_config adp5585_regmap_configs[] = { 84 + [ADP5585_REGMAP_00] = { 85 + .reg_bits = 8, 86 + .val_bits = 8, 87 + .max_register = ADP5585_MAX_REG, 88 + .volatile_table = &adp5585_volatile_regs, 89 + .cache_type = REGCACHE_MAPLE, 90 + .reg_defaults_raw = adp5585_regmap_defaults_00, 91 + .num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_00), 92 + }, 93 + [ADP5585_REGMAP_02] = { 94 + .reg_bits = 8, 95 + .val_bits = 8, 96 + .max_register = ADP5585_MAX_REG, 97 + .volatile_table = &adp5585_volatile_regs, 98 + .cache_type = REGCACHE_MAPLE, 99 + .reg_defaults_raw = adp5585_regmap_defaults_02, 100 + .num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_02), 101 + }, 102 + [ADP5585_REGMAP_04] = { 103 + .reg_bits = 8, 104 + .val_bits = 8, 105 + .max_register = ADP5585_MAX_REG, 106 + .volatile_table = &adp5585_volatile_regs, 107 + .cache_type = REGCACHE_MAPLE, 108 + .reg_defaults_raw = adp5585_regmap_defaults_04, 109 + .num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_04), 110 + }, 111 + }; 112 + 113 + static int adp5585_i2c_probe(struct i2c_client *i2c) 114 + { 115 + const struct regmap_config *regmap_config; 116 + struct adp5585_dev *adp5585; 117 + unsigned int id; 118 + int ret; 119 + 120 + adp5585 = devm_kzalloc(&i2c->dev, sizeof(*adp5585), GFP_KERNEL); 121 + if (!adp5585) 122 + return -ENOMEM; 123 + 124 + i2c_set_clientdata(i2c, adp5585); 125 + 126 + regmap_config = i2c_get_match_data(i2c); 127 + adp5585->regmap = devm_regmap_init_i2c(i2c, regmap_config); 128 + if (IS_ERR(adp5585->regmap)) 129 + return dev_err_probe(&i2c->dev, PTR_ERR(adp5585->regmap), 130 + "Failed to initialize register map\n"); 131 + 132 + ret = regmap_read(adp5585->regmap, ADP5585_ID, &id); 133 + if (ret) 134 + return dev_err_probe(&i2c->dev, ret, 135 + "Failed to read device ID\n"); 136 + 137 + if ((id & ADP5585_MAN_ID_MASK) != ADP5585_MAN_ID_VALUE) 138 + return dev_err_probe(&i2c->dev, -ENODEV, 139 + "Invalid device ID 0x%02x\n", id); 140 + 141 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, 142 + adp5585_devs, ARRAY_SIZE(adp5585_devs), 143 + NULL, 0, NULL); 144 + if (ret) 145 + return dev_err_probe(&i2c->dev, ret, 146 + "Failed to add child devices\n"); 147 + 148 + return 0; 149 + } 150 + 151 + static int adp5585_suspend(struct device *dev) 152 + { 153 + struct adp5585_dev *adp5585 = dev_get_drvdata(dev); 154 + 155 + regcache_cache_only(adp5585->regmap, true); 156 + 157 + return 0; 158 + } 159 + 160 + static int adp5585_resume(struct device *dev) 161 + { 162 + struct adp5585_dev *adp5585 = dev_get_drvdata(dev); 163 + 164 + regcache_cache_only(adp5585->regmap, false); 165 + regcache_mark_dirty(adp5585->regmap); 166 + 167 + return regcache_sync(adp5585->regmap); 168 + } 169 + 170 + static DEFINE_SIMPLE_DEV_PM_OPS(adp5585_pm, adp5585_suspend, adp5585_resume); 171 + 172 + static const struct of_device_id adp5585_of_match[] = { 173 + { 174 + .compatible = "adi,adp5585-00", 175 + .data = &adp5585_regmap_configs[ADP5585_REGMAP_00], 176 + }, { 177 + .compatible = "adi,adp5585-01", 178 + .data = &adp5585_regmap_configs[ADP5585_REGMAP_00], 179 + }, { 180 + .compatible = "adi,adp5585-02", 181 + .data = &adp5585_regmap_configs[ADP5585_REGMAP_02], 182 + }, { 183 + .compatible = "adi,adp5585-03", 184 + .data = &adp5585_regmap_configs[ADP5585_REGMAP_00], 185 + }, { 186 + .compatible = "adi,adp5585-04", 187 + .data = &adp5585_regmap_configs[ADP5585_REGMAP_04], 188 + }, 189 + { /* sentinel */ } 190 + }; 191 + MODULE_DEVICE_TABLE(of, adp5585_of_match); 192 + 193 + static struct i2c_driver adp5585_i2c_driver = { 194 + .driver = { 195 + .name = "adp5585", 196 + .of_match_table = adp5585_of_match, 197 + .pm = pm_sleep_ptr(&adp5585_pm), 198 + }, 199 + .probe = adp5585_i2c_probe, 200 + }; 201 + module_i2c_driver(adp5585_i2c_driver); 202 + 203 + MODULE_DESCRIPTION("ADP5585 core driver"); 204 + MODULE_AUTHOR("Haibo Chen <haibo.chen@nxp.com>"); 205 + MODULE_LICENSE("GPL");
+7
drivers/pwm/Kconfig
··· 47 47 To compile this driver as a module, choose M here: the module 48 48 will be called pwm-ab8500. 49 49 50 + config PWM_ADP5585 51 + tristate "ADP5585 PWM support" 52 + depends on MFD_ADP5585 53 + help 54 + This option enables support for the PWM function found in the Analog 55 + Devices ADP5585. 56 + 50 57 config PWM_APPLE 51 58 tristate "Apple SoC PWM support" 52 59 depends on ARCH_APPLE || COMPILE_TEST
+1
drivers/pwm/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_PWM) += core.o 3 3 obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o 4 + obj-$(CONFIG_PWM_ADP5585) += pwm-adp5585.o 4 5 obj-$(CONFIG_PWM_APPLE) += pwm-apple.o 5 6 obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o 6 7 obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o
+6 -7
drivers/pwm/core.c
··· 325 325 * 326 326 * Returns: 0 on success or a negative error code on failure. 327 327 */ 328 - int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, 329 - unsigned long timeout) 328 + static int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, 329 + unsigned long timeout) 330 330 { 331 - if (!pwm || !pwm->chip->ops) 332 - return -EINVAL; 331 + struct pwm_chip *chip = pwm->chip; 332 + const struct pwm_ops *ops = chip->ops; 333 333 334 - if (!pwm->chip->ops->capture) 334 + if (!ops->capture) 335 335 return -ENOSYS; 336 336 337 337 guard(mutex)(&pwm_lock); 338 338 339 - return pwm->chip->ops->capture(pwm->chip, pwm, result, timeout); 339 + return ops->capture(chip, pwm, result, timeout); 340 340 } 341 - EXPORT_SYMBOL_GPL(pwm_capture); 342 341 343 342 static struct pwm_chip *pwmchip_find_by_name(const char *name) 344 343 {
+188
drivers/pwm/pwm-adp5585.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Analog Devices ADP5585 PWM driver 4 + * 5 + * Copyright 2022 NXP 6 + * Copyright 2024 Ideas on Board Oy 7 + * 8 + * Limitations: 9 + * - The .apply() operation executes atomically, but may not wait for the 10 + * period to complete (this is not documented and would need to be tested). 11 + * - Disabling the PWM drives the output pin to a low level immediately. 12 + * - The hardware can only generate normal polarity output. 13 + */ 14 + 15 + #include <asm/byteorder.h> 16 + 17 + #include <linux/device.h> 18 + #include <linux/err.h> 19 + #include <linux/math64.h> 20 + #include <linux/mfd/adp5585.h> 21 + #include <linux/minmax.h> 22 + #include <linux/module.h> 23 + #include <linux/platform_device.h> 24 + #include <linux/pwm.h> 25 + #include <linux/regmap.h> 26 + #include <linux/time.h> 27 + #include <linux/types.h> 28 + 29 + #define ADP5585_PWM_CHAN_NUM 1 30 + 31 + #define ADP5585_PWM_OSC_FREQ_HZ 1000000U 32 + #define ADP5585_PWM_MIN_PERIOD_NS (2ULL * NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ) 33 + #define ADP5585_PWM_MAX_PERIOD_NS (2ULL * 0xffff * NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ) 34 + 35 + static int pwm_adp5585_request(struct pwm_chip *chip, struct pwm_device *pwm) 36 + { 37 + struct regmap *regmap = pwmchip_get_drvdata(chip); 38 + 39 + /* Configure the R3 pin as PWM output. */ 40 + return regmap_update_bits(regmap, ADP5585_PIN_CONFIG_C, 41 + ADP5585_R3_EXTEND_CFG_MASK, 42 + ADP5585_R3_EXTEND_CFG_PWM_OUT); 43 + } 44 + 45 + static void pwm_adp5585_free(struct pwm_chip *chip, struct pwm_device *pwm) 46 + { 47 + struct regmap *regmap = pwmchip_get_drvdata(chip); 48 + 49 + regmap_update_bits(regmap, ADP5585_PIN_CONFIG_C, 50 + ADP5585_R3_EXTEND_CFG_MASK, 51 + ADP5585_R3_EXTEND_CFG_GPIO4); 52 + } 53 + 54 + static int pwm_adp5585_apply(struct pwm_chip *chip, 55 + struct pwm_device *pwm, 56 + const struct pwm_state *state) 57 + { 58 + struct regmap *regmap = pwmchip_get_drvdata(chip); 59 + u64 period, duty_cycle; 60 + u32 on, off; 61 + __le16 val; 62 + int ret; 63 + 64 + if (!state->enabled) { 65 + regmap_clear_bits(regmap, ADP5585_GENERAL_CFG, ADP5585_OSC_EN); 66 + regmap_clear_bits(regmap, ADP5585_PWM_CFG, ADP5585_PWM_EN); 67 + return 0; 68 + } 69 + 70 + if (state->polarity != PWM_POLARITY_NORMAL) 71 + return -EINVAL; 72 + 73 + if (state->period < ADP5585_PWM_MIN_PERIOD_NS) 74 + return -EINVAL; 75 + 76 + period = min(state->period, ADP5585_PWM_MAX_PERIOD_NS); 77 + duty_cycle = min(state->duty_cycle, period); 78 + 79 + /* 80 + * Compute the on and off time. As the internal oscillator frequency is 81 + * 1MHz, the calculation can be simplified without loss of precision. 82 + */ 83 + on = div_u64(duty_cycle, NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ); 84 + off = div_u64(period, NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ) - on; 85 + 86 + val = cpu_to_le16(off); 87 + ret = regmap_bulk_write(regmap, ADP5585_PWM_OFFT_LOW, &val, 2); 88 + if (ret) 89 + return ret; 90 + 91 + val = cpu_to_le16(on); 92 + ret = regmap_bulk_write(regmap, ADP5585_PWM_ONT_LOW, &val, 2); 93 + if (ret) 94 + return ret; 95 + 96 + /* Enable PWM in continuous mode and no external AND'ing. */ 97 + ret = regmap_update_bits(regmap, ADP5585_PWM_CFG, 98 + ADP5585_PWM_IN_AND | ADP5585_PWM_MODE | 99 + ADP5585_PWM_EN, ADP5585_PWM_EN); 100 + if (ret) 101 + return ret; 102 + 103 + ret = regmap_set_bits(regmap, ADP5585_GENERAL_CFG, ADP5585_OSC_EN); 104 + if (ret) 105 + return ret; 106 + 107 + return regmap_set_bits(regmap, ADP5585_PWM_CFG, ADP5585_PWM_EN); 108 + } 109 + 110 + static int pwm_adp5585_get_state(struct pwm_chip *chip, 111 + struct pwm_device *pwm, 112 + struct pwm_state *state) 113 + { 114 + struct regmap *regmap = pwmchip_get_drvdata(chip); 115 + unsigned int on, off; 116 + unsigned int val; 117 + __le16 on_off; 118 + int ret; 119 + 120 + ret = regmap_bulk_read(regmap, ADP5585_PWM_OFFT_LOW, &on_off, 2); 121 + if (ret) 122 + return ret; 123 + off = le16_to_cpu(on_off); 124 + 125 + ret = regmap_bulk_read(regmap, ADP5585_PWM_ONT_LOW, &on_off, 2); 126 + if (ret) 127 + return ret; 128 + on = le16_to_cpu(on_off); 129 + 130 + state->duty_cycle = on * (NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ); 131 + state->period = (on + off) * (NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ); 132 + 133 + state->polarity = PWM_POLARITY_NORMAL; 134 + 135 + regmap_read(regmap, ADP5585_PWM_CFG, &val); 136 + state->enabled = !!(val & ADP5585_PWM_EN); 137 + 138 + return 0; 139 + } 140 + 141 + static const struct pwm_ops adp5585_pwm_ops = { 142 + .request = pwm_adp5585_request, 143 + .free = pwm_adp5585_free, 144 + .apply = pwm_adp5585_apply, 145 + .get_state = pwm_adp5585_get_state, 146 + }; 147 + 148 + static int adp5585_pwm_probe(struct platform_device *pdev) 149 + { 150 + struct device *dev = &pdev->dev; 151 + struct adp5585_dev *adp5585 = dev_get_drvdata(dev->parent); 152 + struct pwm_chip *chip; 153 + int ret; 154 + 155 + chip = devm_pwmchip_alloc(dev, ADP5585_PWM_CHAN_NUM, 0); 156 + if (IS_ERR(chip)) 157 + return PTR_ERR(chip); 158 + 159 + device_set_of_node_from_dev(dev, dev->parent); 160 + 161 + pwmchip_set_drvdata(chip, adp5585->regmap); 162 + chip->ops = &adp5585_pwm_ops; 163 + 164 + ret = devm_pwmchip_add(dev, chip); 165 + if (ret) 166 + return dev_err_probe(dev, ret, "failed to add PWM chip\n"); 167 + 168 + return 0; 169 + } 170 + 171 + static const struct platform_device_id adp5585_pwm_id_table[] = { 172 + { "adp5585-pwm" }, 173 + { /* Sentinel */ } 174 + }; 175 + MODULE_DEVICE_TABLE(platform, adp5585_pwm_id_table); 176 + 177 + static struct platform_driver adp5585_pwm_driver = { 178 + .driver = { 179 + .name = "adp5585-pwm", 180 + }, 181 + .probe = adp5585_pwm_probe, 182 + .id_table = adp5585_pwm_id_table, 183 + }; 184 + module_platform_driver(adp5585_pwm_driver); 185 + 186 + MODULE_AUTHOR("Xiaoning Wang <xiaoning.wang@nxp.com>"); 187 + MODULE_DESCRIPTION("ADP5585 PWM Driver"); 188 + MODULE_LICENSE("GPL");
+4 -3
drivers/pwm/pwm-atmel-hlcdc.c
··· 234 234 .data = &atmel_hlcdc_pwm_sama5d3_errata, 235 235 }, 236 236 { .compatible = "microchip,sam9x60-hlcdc", }, 237 - { /* sentinel */ }, 237 + { /* sentinel */ } 238 238 }; 239 239 MODULE_DEVICE_TABLE(of, atmel_hlcdc_dt_ids); 240 240 ··· 288 288 289 289 static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = { 290 290 { .compatible = "atmel,hlcdc-pwm" }, 291 - { /* sentinel */ }, 291 + { /* sentinel */ } 292 292 }; 293 + MODULE_DEVICE_TABLE(of, atmel_hlcdc_pwm_dt_ids); 293 294 294 295 static struct platform_driver atmel_hlcdc_pwm_driver = { 295 296 .driver = { ··· 299 298 .pm = pm_ptr(&atmel_hlcdc_pwm_pm_ops), 300 299 }, 301 300 .probe = atmel_hlcdc_pwm_probe, 302 - .remove_new = atmel_hlcdc_pwm_remove, 301 + .remove = atmel_hlcdc_pwm_remove, 303 302 }; 304 303 module_platform_driver(atmel_hlcdc_pwm_driver); 305 304
+1 -1
drivers/pwm/pwm-atmel-tcb.c
··· 527 527 .pm = pm_ptr(&atmel_tcb_pwm_pm_ops), 528 528 }, 529 529 .probe = atmel_tcb_pwm_probe, 530 - .remove_new = atmel_tcb_pwm_remove, 530 + .remove = atmel_tcb_pwm_remove, 531 531 }; 532 532 module_platform_driver(atmel_tcb_pwm_driver); 533 533
+1 -2
drivers/pwm/pwm-axi-pwmgen.c
··· 29 29 #include <linux/regmap.h> 30 30 #include <linux/slab.h> 31 31 32 - #define AXI_PWMGEN_REG_CORE_VERSION 0x00 33 32 #define AXI_PWMGEN_REG_ID 0x04 34 33 #define AXI_PWMGEN_REG_SCRATCHPAD 0x08 35 34 #define AXI_PWMGEN_REG_CORE_MAGIC 0x0C ··· 144 145 "failed to read expected value from register: got %08x, expected %08x\n", 145 146 val, AXI_PWMGEN_REG_CORE_MAGIC_VAL); 146 147 147 - ret = regmap_read(regmap, AXI_PWMGEN_REG_CORE_VERSION, &val); 148 + ret = regmap_read(regmap, ADI_AXI_REG_VERSION, &val); 148 149 if (ret) 149 150 return ret; 150 151
+1 -1
drivers/pwm/pwm-clk.c
··· 130 130 .of_match_table = pwm_clk_dt_ids, 131 131 }, 132 132 .probe = pwm_clk_probe, 133 - .remove_new = pwm_clk_remove, 133 + .remove = pwm_clk_remove, 134 134 }; 135 135 module_platform_driver(pwm_clk_driver); 136 136
+1 -1
drivers/pwm/pwm-hibvt.c
··· 276 276 .of_match_table = hibvt_pwm_of_match, 277 277 }, 278 278 .probe = hibvt_pwm_probe, 279 - .remove_new = hibvt_pwm_remove, 279 + .remove = hibvt_pwm_remove, 280 280 }; 281 281 module_platform_driver(hibvt_pwm_driver); 282 282
+1 -1
drivers/pwm/pwm-img.c
··· 416 416 .of_match_table = img_pwm_of_match, 417 417 }, 418 418 .probe = img_pwm_probe, 419 - .remove_new = img_pwm_remove, 419 + .remove = img_pwm_remove, 420 420 }; 421 421 module_platform_driver(img_pwm_driver); 422 422
+3 -7
drivers/pwm/pwm-lp3943.c
··· 218 218 struct lp3943_platform_data *pdata; 219 219 struct lp3943_pwm_map *pwm_map; 220 220 enum lp3943_pwm_output *output; 221 - int i, err, proplen, count = 0; 222 - u32 num_outputs; 221 + int i, err, num_outputs, count = 0; 223 222 224 223 if (!node) 225 224 return -EINVAL; ··· 233 234 */ 234 235 235 236 for (i = 0; i < LP3943_NUM_PWMS; i++) { 236 - if (!of_get_property(node, name[i], &proplen)) 237 - continue; 238 - 239 - num_outputs = proplen / sizeof(u32); 240 - if (num_outputs == 0) 237 + num_outputs = of_property_count_u32_elems(node, name[i]); 238 + if (num_outputs <= 0) 241 239 continue; 242 240 243 241 output = devm_kcalloc(dev, num_outputs, sizeof(*output),
+1 -1
drivers/pwm/pwm-lpc18xx-sct.c
··· 446 446 .of_match_table = lpc18xx_pwm_of_match, 447 447 }, 448 448 .probe = lpc18xx_pwm_probe, 449 - .remove_new = lpc18xx_pwm_remove, 449 + .remove = lpc18xx_pwm_remove, 450 450 }; 451 451 module_platform_driver(lpc18xx_pwm_driver); 452 452
+2 -2
drivers/pwm/pwm-omap-dmtimer.c
··· 355 355 goto err_platdata; 356 356 } 357 357 358 - if (!of_get_property(timer, "ti,timer-pwm", NULL)) { 358 + if (!of_property_read_bool(timer, "ti,timer-pwm")) { 359 359 dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); 360 360 ret = -ENODEV; 361 361 goto err_timer_property; ··· 455 455 .of_match_table = pwm_omap_dmtimer_of_match, 456 456 }, 457 457 .probe = pwm_omap_dmtimer_probe, 458 - .remove_new = pwm_omap_dmtimer_remove, 458 + .remove = pwm_omap_dmtimer_remove, 459 459 }; 460 460 module_platform_driver(pwm_omap_dmtimer_driver); 461 461
+1 -1
drivers/pwm/pwm-rcar.c
··· 253 253 254 254 static struct platform_driver rcar_pwm_driver = { 255 255 .probe = rcar_pwm_probe, 256 - .remove_new = rcar_pwm_remove, 256 + .remove = rcar_pwm_remove, 257 257 .driver = { 258 258 .name = "pwm-rcar", 259 259 .of_match_table = rcar_pwm_of_table,
+1 -1
drivers/pwm/pwm-rockchip.c
··· 386 386 .of_match_table = rockchip_pwm_dt_ids, 387 387 }, 388 388 .probe = rockchip_pwm_probe, 389 - .remove_new = rockchip_pwm_remove, 389 + .remove = rockchip_pwm_remove, 390 390 }; 391 391 module_platform_driver(rockchip_pwm_driver); 392 392
+1 -1
drivers/pwm/pwm-sifive.c
··· 336 336 337 337 static struct platform_driver pwm_sifive_driver = { 338 338 .probe = pwm_sifive_probe, 339 - .remove_new = pwm_sifive_remove, 339 + .remove = pwm_sifive_remove, 340 340 .driver = { 341 341 .name = "pwm-sifive", 342 342 .of_match_table = pwm_sifive_of_match,
+1 -1
drivers/pwm/pwm-stm32.c
··· 222 222 223 223 scale = max_arr / min(max_arr, raw_prd); 224 224 } else { 225 - scale = priv->max_arr; /* bellow resolution, use max scale */ 225 + scale = priv->max_arr; /* below resolution, use max scale */ 226 226 } 227 227 228 228 if (psc && scale > 1) {
+1 -1
drivers/pwm/pwm-sun4i.c
··· 493 493 .of_match_table = sun4i_pwm_dt_ids, 494 494 }, 495 495 .probe = sun4i_pwm_probe, 496 - .remove_new = sun4i_pwm_remove, 496 + .remove = sun4i_pwm_remove, 497 497 }; 498 498 module_platform_driver(sun4i_pwm_driver); 499 499
+1 -1
drivers/pwm/pwm-tegra.c
··· 432 432 .pm = &tegra_pwm_pm_ops, 433 433 }, 434 434 .probe = tegra_pwm_probe, 435 - .remove_new = tegra_pwm_remove, 435 + .remove = tegra_pwm_remove, 436 436 }; 437 437 438 438 module_platform_driver(tegra_pwm_driver);
+1 -1
drivers/pwm/pwm-tiecap.c
··· 324 324 .pm = pm_ptr(&ecap_pwm_pm_ops), 325 325 }, 326 326 .probe = ecap_pwm_probe, 327 - .remove_new = ecap_pwm_remove, 327 + .remove = ecap_pwm_remove, 328 328 }; 329 329 module_platform_driver(ecap_pwm_driver); 330 330
+1 -1
drivers/pwm/pwm-tiehrpwm.c
··· 603 603 .pm = pm_ptr(&ehrpwm_pwm_pm_ops), 604 604 }, 605 605 .probe = ehrpwm_pwm_probe, 606 - .remove_new = ehrpwm_pwm_remove, 606 + .remove = ehrpwm_pwm_remove, 607 607 }; 608 608 module_platform_driver(ehrpwm_pwm_driver); 609 609
+126
include/linux/mfd/adp5585.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Analog Devices ADP5585 I/O expander, PWM controller and keypad controller 4 + * 5 + * Copyright 2022 NXP 6 + * Copyright 2024 Ideas on Board Oy 7 + */ 8 + 9 + #ifndef __MFD_ADP5585_H_ 10 + #define __MFD_ADP5585_H_ 11 + 12 + #include <linux/bits.h> 13 + 14 + #define ADP5585_ID 0x00 15 + #define ADP5585_MAN_ID_VALUE 0x20 16 + #define ADP5585_MAN_ID_MASK GENMASK(7, 4) 17 + #define ADP5585_INT_STATUS 0x01 18 + #define ADP5585_STATUS 0x02 19 + #define ADP5585_FIFO_1 0x03 20 + #define ADP5585_FIFO_2 0x04 21 + #define ADP5585_FIFO_3 0x05 22 + #define ADP5585_FIFO_4 0x06 23 + #define ADP5585_FIFO_5 0x07 24 + #define ADP5585_FIFO_6 0x08 25 + #define ADP5585_FIFO_7 0x09 26 + #define ADP5585_FIFO_8 0x0a 27 + #define ADP5585_FIFO_9 0x0b 28 + #define ADP5585_FIFO_10 0x0c 29 + #define ADP5585_FIFO_11 0x0d 30 + #define ADP5585_FIFO_12 0x0e 31 + #define ADP5585_FIFO_13 0x0f 32 + #define ADP5585_FIFO_14 0x10 33 + #define ADP5585_FIFO_15 0x11 34 + #define ADP5585_FIFO_16 0x12 35 + #define ADP5585_GPI_INT_STAT_A 0x13 36 + #define ADP5585_GPI_INT_STAT_B 0x14 37 + #define ADP5585_GPI_STATUS_A 0x15 38 + #define ADP5585_GPI_STATUS_B 0x16 39 + #define ADP5585_RPULL_CONFIG_A 0x17 40 + #define ADP5585_RPULL_CONFIG_B 0x18 41 + #define ADP5585_RPULL_CONFIG_C 0x19 42 + #define ADP5585_RPULL_CONFIG_D 0x1a 43 + #define ADP5585_Rx_PULL_CFG_PU_300K 0 44 + #define ADP5585_Rx_PULL_CFG_PD_300K 1 45 + #define ADP5585_Rx_PULL_CFG_PU_100K 2 46 + #define ADP5585_Rx_PULL_CFG_DISABLE 3 47 + #define ADP5585_Rx_PULL_CFG_MASK 3 48 + #define ADP5585_GPI_INT_LEVEL_A 0x1b 49 + #define ADP5585_GPI_INT_LEVEL_B 0x1c 50 + #define ADP5585_GPI_EVENT_EN_A 0x1d 51 + #define ADP5585_GPI_EVENT_EN_B 0x1e 52 + #define ADP5585_GPI_INTERRUPT_EN_A 0x1f 53 + #define ADP5585_GPI_INTERRUPT_EN_B 0x20 54 + #define ADP5585_DEBOUNCE_DIS_A 0x21 55 + #define ADP5585_DEBOUNCE_DIS_B 0x22 56 + #define ADP5585_GPO_DATA_OUT_A 0x23 57 + #define ADP5585_GPO_DATA_OUT_B 0x24 58 + #define ADP5585_GPO_OUT_MODE_A 0x25 59 + #define ADP5585_GPO_OUT_MODE_B 0x26 60 + #define ADP5585_GPIO_DIRECTION_A 0x27 61 + #define ADP5585_GPIO_DIRECTION_B 0x28 62 + #define ADP5585_RESET1_EVENT_A 0x29 63 + #define ADP5585_RESET1_EVENT_B 0x2a 64 + #define ADP5585_RESET1_EVENT_C 0x2b 65 + #define ADP5585_RESET2_EVENT_A 0x2c 66 + #define ADP5585_RESET2_EVENT_B 0x2d 67 + #define ADP5585_RESET_CFG 0x2e 68 + #define ADP5585_PWM_OFFT_LOW 0x2f 69 + #define ADP5585_PWM_OFFT_HIGH 0x30 70 + #define ADP5585_PWM_ONT_LOW 0x31 71 + #define ADP5585_PWM_ONT_HIGH 0x32 72 + #define ADP5585_PWM_CFG 0x33 73 + #define ADP5585_PWM_IN_AND BIT(2) 74 + #define ADP5585_PWM_MODE BIT(1) 75 + #define ADP5585_PWM_EN BIT(0) 76 + #define ADP5585_LOGIC_CFG 0x34 77 + #define ADP5585_LOGIC_FF_CFG 0x35 78 + #define ADP5585_LOGIC_INT_EVENT_EN 0x36 79 + #define ADP5585_POLL_PTIME_CFG 0x37 80 + #define ADP5585_PIN_CONFIG_A 0x38 81 + #define ADP5585_PIN_CONFIG_B 0x39 82 + #define ADP5585_PIN_CONFIG_C 0x3a 83 + #define ADP5585_PULL_SELECT BIT(7) 84 + #define ADP5585_C4_EXTEND_CFG_GPIO11 (0U << 6) 85 + #define ADP5585_C4_EXTEND_CFG_RESET2 (1U << 6) 86 + #define ADP5585_C4_EXTEND_CFG_MASK GENMASK(6, 6) 87 + #define ADP5585_R4_EXTEND_CFG_GPIO5 (0U << 5) 88 + #define ADP5585_R4_EXTEND_CFG_RESET1 (1U << 5) 89 + #define ADP5585_R4_EXTEND_CFG_MASK GENMASK(5, 5) 90 + #define ADP5585_R3_EXTEND_CFG_GPIO4 (0U << 2) 91 + #define ADP5585_R3_EXTEND_CFG_LC (1U << 2) 92 + #define ADP5585_R3_EXTEND_CFG_PWM_OUT (2U << 2) 93 + #define ADP5585_R3_EXTEND_CFG_MASK GENMASK(3, 2) 94 + #define ADP5585_R0_EXTEND_CFG_GPIO1 (0U << 0) 95 + #define ADP5585_R0_EXTEND_CFG_LY (1U << 0) 96 + #define ADP5585_R0_EXTEND_CFG_MASK GENMASK(0, 0) 97 + #define ADP5585_GENERAL_CFG 0x3b 98 + #define ADP5585_OSC_EN BIT(7) 99 + #define ADP5585_OSC_FREQ_50KHZ (0U << 5) 100 + #define ADP5585_OSC_FREQ_100KHZ (1U << 5) 101 + #define ADP5585_OSC_FREQ_200KHZ (2U << 5) 102 + #define ADP5585_OSC_FREQ_500KHZ (3U << 5) 103 + #define ADP5585_OSC_FREQ_MASK GENMASK(6, 5) 104 + #define ADP5585_INT_CFG BIT(1) 105 + #define ADP5585_RST_CFG BIT(0) 106 + #define ADP5585_INT_EN 0x3c 107 + 108 + #define ADP5585_MAX_REG ADP5585_INT_EN 109 + 110 + /* 111 + * Bank 0 covers pins "GPIO 1/R0" to "GPIO 6/R5", numbered 0 to 5 by the 112 + * driver, and bank 1 covers pins "GPIO 7/C0" to "GPIO 11/C4", numbered 6 to 113 + * 10. Some variants of the ADP5585 don't support "GPIO 6/R5". As the driver 114 + * uses identical GPIO numbering for all variants to avoid confusion, GPIO 5 is 115 + * marked as reserved in the device tree for variants that don't support it. 116 + */ 117 + #define ADP5585_BANK(n) ((n) >= 6 ? 1 : 0) 118 + #define ADP5585_BIT(n) ((n) >= 6 ? BIT((n) - 6) : BIT(n)) 119 + 120 + struct regmap; 121 + 122 + struct adp5585_dev { 123 + struct regmap *regmap; 124 + }; 125 + 126 + #endif
-10
include/linux/pwm.h
··· 394 394 } 395 395 396 396 /* PWM provider APIs */ 397 - int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, 398 - unsigned long timeout); 399 - 400 397 void pwmchip_put(struct pwm_chip *chip); 401 398 struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv); 402 399 struct pwm_chip *devm_pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv); ··· 457 460 static inline void pwm_disable(struct pwm_device *pwm) 458 461 { 459 462 might_sleep(); 460 - } 461 - 462 - static inline int pwm_capture(struct pwm_device *pwm, 463 - struct pwm_capture *result, 464 - unsigned long timeout) 465 - { 466 - return -EINVAL; 467 463 } 468 464 469 465 static inline void pwmchip_put(struct pwm_chip *chip)
+6 -4
include/trace/events/pwm.h
··· 15 15 TP_ARGS(pwm, state, err), 16 16 17 17 TP_STRUCT__entry( 18 - __field(struct pwm_device *, pwm) 18 + __field(unsigned int, chipid) 19 + __field(unsigned int, hwpwm) 19 20 __field(u64, period) 20 21 __field(u64, duty_cycle) 21 22 __field(enum pwm_polarity, polarity) ··· 25 24 ), 26 25 27 26 TP_fast_assign( 28 - __entry->pwm = pwm; 27 + __entry->chipid = pwm->chip->id; 28 + __entry->hwpwm = pwm->hwpwm; 29 29 __entry->period = state->period; 30 30 __entry->duty_cycle = state->duty_cycle; 31 31 __entry->polarity = state->polarity; ··· 34 32 __entry->err = err; 35 33 ), 36 34 37 - TP_printk("%p: period=%llu duty_cycle=%llu polarity=%d enabled=%d err=%d", 38 - __entry->pwm, __entry->period, __entry->duty_cycle, 35 + TP_printk("pwmchip%u.%u: period=%llu duty_cycle=%llu polarity=%d enabled=%d err=%d", 36 + __entry->chipid, __entry->hwpwm, __entry->period, __entry->duty_cycle, 39 37 __entry->polarity, __entry->enabled, __entry->err) 40 38 41 39 );