From: Kamel Bouhara <kamel.bouhara@bootlin.com>
Add driver for Maxim Integrated MAX7360 PWM controller, supporting up to
8 independent PWM outputs.
Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
Co-developed-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/pwm/Kconfig | 10 +++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-max7360.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 220 insertions(+)
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index f00ce973dddf..f2b1ce47de7f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -432,6 +432,16 @@ config PWM_LPSS_PLATFORM
To compile this driver as a module, choose M here: the module
will be called pwm-lpss-platform.
+config PWM_MAX7360
+ tristate "MAX7360 PWMs"
+ depends on MFD_MAX7360
+ help
+ PWM driver for Maxim Integrated MAX7360 multifunction device, with
+ support for up to 8 PWM outputs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-max7360.
+
config PWM_MC33XS2410
tristate "MC33XS2410 PWM support"
depends on OF
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index ff4f47e5fb7a..dfa8b4966ee1 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o
obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
+obj-$(CONFIG_PWM_MAX7360) += pwm-max7360.o
obj-$(CONFIG_PWM_MC33XS2410) += pwm-mc33xs2410.o
obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
obj-$(CONFIG_PWM_MESON) += pwm-meson.o
diff --git a/drivers/pwm/pwm-max7360.c b/drivers/pwm/pwm-max7360.c
new file mode 100644
index 000000000000..ebf93a7aee5b
--- /dev/null
+++ b/drivers/pwm/pwm-max7360.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2025 Bootlin
+ *
+ * Author: Kamel BOUHARA <kamel.bouhara@bootlin.com>
+ * Author: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
+ *
+ * PWM functionality of the MAX7360 multi-function device.
+ * https://www.analog.com/media/en/technical-documentation/data-sheets/MAX7360.pdf
+ *
+ * Limitations:
+ * - Only supports normal polarity.
+ * - The period is fixed to 2 ms.
+ * - Only the duty cycle can be changed, new values are applied at the beginning
+ * of the next cycle.
+ * - When disabled, the output is put in Hi-Z immediately.
+ */
+#include <linux/bits.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/math64.h>
+#include <linux/mfd/max7360.h>
+#include <linux/minmax.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#define MAX7360_NUM_PWMS 8
+#define MAX7360_PWM_MAX 255
+#define MAX7360_PWM_STEPS 256
+#define MAX7360_PWM_PERIOD_NS (2 * NSEC_PER_MSEC)
+
+struct max7360_pwm_waveform {
+ u8 duty_steps;
+ bool enabled;
+};
+
+static int max7360_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct regmap *regmap = pwmchip_get_drvdata(chip);
+
+ /*
+ * Make sure we use the individual PWM configuration register and not
+ * the global one.
+ * We never need to use the global one, so there is no need to revert
+ * that in the .free() callback.
+ */
+ return regmap_write_bits(regmap, MAX7360_REG_PWMCFG(pwm->hwpwm),
+ MAX7360_PORT_CFG_COMMON_PWM, 0);
+}
+
+static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const struct pwm_waveform *wf,
+ void *_wfhw)
+{
+ struct max7360_pwm_waveform *wfhw = _wfhw;
+ u64 duty_steps;
+
+ /*
+ * Ignore user provided values for period_length_ns and duty_offset_ns:
+ * we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0.
+ * Values from 0 to 254 as duty_steps will provide duty cycles of 0/256
+ * to 254/256, while value 255 will provide a duty cycle of 100%.
+ */
+ if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) {
+ duty_steps = MAX7360_PWM_MAX;
+ } else {
+ duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_STEPS / MAX7360_PWM_PERIOD_NS;
+ if (duty_steps == MAX7360_PWM_MAX)
+ duty_steps = MAX7360_PWM_MAX - 1;
+ }
+
+ wfhw->duty_steps = min(MAX7360_PWM_MAX, duty_steps);
+ wfhw->enabled = !!wf->period_length_ns;
+
+ if (wf->period_length_ns && wf->period_length_ns < MAX7360_PWM_PERIOD_NS)
+ return 1;
+ else
+ return 0;
+}
+
+static int max7360_pwm_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm,
+ const void *_wfhw, struct pwm_waveform *wf)
+{
+ const struct max7360_pwm_waveform *wfhw = _wfhw;
+
+ wf->period_length_ns = wfhw->enabled ? MAX7360_PWM_PERIOD_NS : 0;
+ wf->duty_offset_ns = 0;
+
+ if (wfhw->enabled) {
+ if (wfhw->duty_steps == MAX7360_PWM_MAX)
+ wf->duty_length_ns = MAX7360_PWM_PERIOD_NS;
+ else
+ wf->duty_length_ns = DIV_ROUND_UP(wfhw->duty_steps * MAX7360_PWM_PERIOD_NS,
+ MAX7360_PWM_STEPS);
+ } else {
+ wf->duty_length_ns = 0;
+ }
+
+ return 0;
+}
+
+static int max7360_pwm_write_waveform(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const void *_wfhw)
+{
+ struct regmap *regmap = pwmchip_get_drvdata(chip);
+ const struct max7360_pwm_waveform *wfhw = _wfhw;
+ unsigned int val;
+ int ret;
+
+ if (wfhw->enabled) {
+ ret = regmap_write(regmap, MAX7360_REG_PWM(pwm->hwpwm), wfhw->duty_steps);
+ if (ret)
+ return ret;
+ }
+
+ val = wfhw->enabled ? BIT(pwm->hwpwm) : 0;
+ return regmap_write_bits(regmap, MAX7360_REG_GPIOCTRL, BIT(pwm->hwpwm), val);
+}
+
+static int max7360_pwm_read_waveform(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ void *_wfhw)
+{
+ struct regmap *regmap = pwmchip_get_drvdata(chip);
+ struct max7360_pwm_waveform *wfhw = _wfhw;
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(regmap, MAX7360_REG_GPIOCTRL, &val);
+ if (ret)
+ return ret;
+
+ if (val & BIT(pwm->hwpwm)) {
+ wfhw->enabled = true;
+ ret = regmap_read(regmap, MAX7360_REG_PWM(pwm->hwpwm), &val);
+ if (ret)
+ return ret;
+
+ wfhw->duty_steps = val;
+ } else {
+ wfhw->enabled = false;
+ wfhw->duty_steps = 0;
+ }
+
+ return 0;
+}
+
+static const struct pwm_ops max7360_pwm_ops = {
+ .request = max7360_pwm_request,
+ .round_waveform_tohw = max7360_pwm_round_waveform_tohw,
+ .round_waveform_fromhw = max7360_pwm_round_waveform_fromhw,
+ .read_waveform = max7360_pwm_read_waveform,
+ .write_waveform = max7360_pwm_write_waveform,
+};
+
+static int max7360_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pwm_chip *chip;
+ struct regmap *regmap;
+ int ret;
+
+ regmap = dev_get_regmap(dev->parent, NULL);
+ if (!regmap)
+ return dev_err_probe(dev, -ENODEV, "Could not get parent regmap\n");
+
+ /*
+ * This MFD sub-device does not have any associated device tree node:
+ * properties are stored in the device node of the parent (MFD) device
+ * and this same node is used in phandles of client devices.
+ * Reuse this device tree node here, as otherwise the PWM subsystem
+ * would be confused by this topology.
+ */
+ device_set_of_node_from_dev(dev, dev->parent);
+
+ chip = devm_pwmchip_alloc(dev, MAX7360_NUM_PWMS, 0);
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+ chip->ops = &max7360_pwm_ops;
+
+ pwmchip_set_drvdata(chip, regmap);
+
+ ret = devm_pwmchip_add(dev, chip);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add PWM chip\n");
+
+ return 0;
+}
+
+static struct platform_driver max7360_pwm_driver = {
+ .driver = {
+ .name = "max7360-pwm",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .probe = max7360_pwm_probe,
+};
+module_platform_driver(max7360_pwm_driver);
+
+MODULE_DESCRIPTION("MAX7360 PWM driver");
+MODULE_AUTHOR("Kamel BOUHARA <kamel.bouhara@bootlin.com>");
+MODULE_AUTHOR("Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>");
+MODULE_LICENSE("GPL");
--
2.39.5
On Sun, Aug 24, 2025 at 01:57:23PM +0200, Mathieu Dubois-Briand wrote: > +static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip, > + struct pwm_device *pwm, > + const struct pwm_waveform *wf, > + void *_wfhw) > +{ > + struct max7360_pwm_waveform *wfhw = _wfhw; > + u64 duty_steps; > + > + /* > + * Ignore user provided values for period_length_ns and duty_offset_ns: > + * we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0. > + * Values from 0 to 254 as duty_steps will provide duty cycles of 0/256 > + * to 254/256, while value 255 will provide a duty cycle of 100%. > + */ > + if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) { > + duty_steps = MAX7360_PWM_MAX; > + } else { > + duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_STEPS / MAX7360_PWM_PERIOD_NS; > + if (duty_steps == MAX7360_PWM_MAX) > + duty_steps = MAX7360_PWM_MAX - 1; > + } > + > + wfhw->duty_steps = min(MAX7360_PWM_MAX, duty_steps); duty_steps is never bigger than MAX7360_PWM_MAX, isn't it? Then this can be simplified to just wfhw->duty_steps = duty_steps; Otherwise looks fine to me. To get this series forward, it's OK for me to apply the series as is via Lee's MFD tree and cope for this minor optimisation later. So: Acked-by: Uwe Kleine-König <ukleinek@kernel.org> Best regards Uwe
On Fri Sep 12, 2025 at 10:57 AM CEST, Uwe Kleine-König wrote: > On Sun, Aug 24, 2025 at 01:57:23PM +0200, Mathieu Dubois-Briand wrote: >> +static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip, >> + struct pwm_device *pwm, >> + const struct pwm_waveform *wf, >> + void *_wfhw) >> +{ >> + struct max7360_pwm_waveform *wfhw = _wfhw; >> + u64 duty_steps; >> + >> + /* >> + * Ignore user provided values for period_length_ns and duty_offset_ns: >> + * we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0. >> + * Values from 0 to 254 as duty_steps will provide duty cycles of 0/256 >> + * to 254/256, while value 255 will provide a duty cycle of 100%. >> + */ >> + if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) { >> + duty_steps = MAX7360_PWM_MAX; >> + } else { >> + duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_STEPS / MAX7360_PWM_PERIOD_NS; >> + if (duty_steps == MAX7360_PWM_MAX) >> + duty_steps = MAX7360_PWM_MAX - 1; >> + } >> + >> + wfhw->duty_steps = min(MAX7360_PWM_MAX, duty_steps); > > duty_steps is never bigger than MAX7360_PWM_MAX, isn't it? Then this can > be simplified to just > > wfhw->duty_steps = duty_steps; > Ok, I reviewed this section and I do agree with you. I will prepare a new patch to fix this line and will send it separately. > Otherwise looks fine to me. > > To get this series forward, it's OK for me to apply the series as is via > Lee's MFD tree and cope for this minor optimisation later. So: > > Acked-by: Uwe Kleine-König <ukleinek@kernel.org> > > Best regards > Uwe Thanks, Mathieu -- Mathieu Dubois-Briand, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
On Sun Aug 24, 2025 at 1:57 PM CEST, Mathieu Dubois-Briand wrote: > From: Kamel Bouhara <kamel.bouhara@bootlin.com> > > Add driver for Maxim Integrated MAX7360 PWM controller, supporting up to > 8 independent PWM outputs. > > Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com> > Co-developed-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> > Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > --- > drivers/pwm/Kconfig | 10 +++ > drivers/pwm/Makefile | 1 + > drivers/pwm/pwm-max7360.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 220 insertions(+) > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > index f00ce973dddf..f2b1ce47de7f 100644 > --- a/drivers/pwm/Kconfig > +++ b/drivers/pwm/Kconfig > @@ -432,6 +432,16 @@ config PWM_LPSS_PLATFORM > To compile this driver as a module, choose M here: the module > will be called pwm-lpss-platform. > > +config PWM_MAX7360 > + tristate "MAX7360 PWMs" > + depends on MFD_MAX7360 > + help > + PWM driver for Maxim Integrated MAX7360 multifunction device, with > + support for up to 8 PWM outputs. > + > + To compile this driver as a module, choose M here: the module > + will be called pwm-max7360. > + > config PWM_MC33XS2410 > tristate "MC33XS2410 PWM support" > depends on OF > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > index ff4f47e5fb7a..dfa8b4966ee1 100644 > --- a/drivers/pwm/Makefile > +++ b/drivers/pwm/Makefile > @@ -38,6 +38,7 @@ obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o > obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o > obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o > obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o > +obj-$(CONFIG_PWM_MAX7360) += pwm-max7360.o > obj-$(CONFIG_PWM_MC33XS2410) += pwm-mc33xs2410.o > obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o > obj-$(CONFIG_PWM_MESON) += pwm-meson.o > diff --git a/drivers/pwm/pwm-max7360.c b/drivers/pwm/pwm-max7360.c > new file mode 100644 > index 000000000000..ebf93a7aee5b > --- /dev/null > +++ b/drivers/pwm/pwm-max7360.c > @@ -0,0 +1,209 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright 2025 Bootlin > + * > + * Author: Kamel BOUHARA <kamel.bouhara@bootlin.com> > + * Author: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> > + * > + * PWM functionality of the MAX7360 multi-function device. > + * https://www.analog.com/media/en/technical-documentation/data-sheets/MAX7360.pdf > + * > + * Limitations: > + * - Only supports normal polarity. > + * - The period is fixed to 2 ms. > + * - Only the duty cycle can be changed, new values are applied at the beginning > + * of the next cycle. > + * - When disabled, the output is put in Hi-Z immediately. > + */ > +#include <linux/bits.h> > +#include <linux/dev_printk.h> > +#include <linux/err.h> > +#include <linux/math64.h> > +#include <linux/mfd/max7360.h> > +#include <linux/minmax.h> > +#include <linux/mod_devicetable.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/pwm.h> > +#include <linux/regmap.h> > +#include <linux/time.h> > +#include <linux/types.h> > + > +#define MAX7360_NUM_PWMS 8 > +#define MAX7360_PWM_MAX 255 > +#define MAX7360_PWM_STEPS 256 > +#define MAX7360_PWM_PERIOD_NS (2 * NSEC_PER_MSEC) > + > +struct max7360_pwm_waveform { > + u8 duty_steps; > + bool enabled; > +}; > + > +static int max7360_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) > +{ > + struct regmap *regmap = pwmchip_get_drvdata(chip); > + > + /* > + * Make sure we use the individual PWM configuration register and not > + * the global one. > + * We never need to use the global one, so there is no need to revert > + * that in the .free() callback. > + */ > + return regmap_write_bits(regmap, MAX7360_REG_PWMCFG(pwm->hwpwm), > + MAX7360_PORT_CFG_COMMON_PWM, 0); > +} > + > +static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip, > + struct pwm_device *pwm, > + const struct pwm_waveform *wf, > + void *_wfhw) > +{ > + struct max7360_pwm_waveform *wfhw = _wfhw; > + u64 duty_steps; > + > + /* > + * Ignore user provided values for period_length_ns and duty_offset_ns: > + * we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0. > + * Values from 0 to 254 as duty_steps will provide duty cycles of 0/256 > + * to 254/256, while value 255 will provide a duty cycle of 100%. > + */ > + if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) { > + duty_steps = MAX7360_PWM_MAX; > + } else { > + duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_STEPS / MAX7360_PWM_PERIOD_NS; > + if (duty_steps == MAX7360_PWM_MAX) > + duty_steps = MAX7360_PWM_MAX - 1; > + } > + > + wfhw->duty_steps = min(MAX7360_PWM_MAX, duty_steps); > + wfhw->enabled = !!wf->period_length_ns; > + > + if (wf->period_length_ns && wf->period_length_ns < MAX7360_PWM_PERIOD_NS) > + return 1; > + else > + return 0; > +} > + > +static int max7360_pwm_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm, > + const void *_wfhw, struct pwm_waveform *wf) > +{ > + const struct max7360_pwm_waveform *wfhw = _wfhw; > + > + wf->period_length_ns = wfhw->enabled ? MAX7360_PWM_PERIOD_NS : 0; > + wf->duty_offset_ns = 0; > + > + if (wfhw->enabled) { > + if (wfhw->duty_steps == MAX7360_PWM_MAX) > + wf->duty_length_ns = MAX7360_PWM_PERIOD_NS; > + else > + wf->duty_length_ns = DIV_ROUND_UP(wfhw->duty_steps * MAX7360_PWM_PERIOD_NS, > + MAX7360_PWM_STEPS); > + } else { > + wf->duty_length_ns = 0; > + } > + > + return 0; > +} > + > +static int max7360_pwm_write_waveform(struct pwm_chip *chip, > + struct pwm_device *pwm, > + const void *_wfhw) > +{ > + struct regmap *regmap = pwmchip_get_drvdata(chip); > + const struct max7360_pwm_waveform *wfhw = _wfhw; > + unsigned int val; > + int ret; > + > + if (wfhw->enabled) { > + ret = regmap_write(regmap, MAX7360_REG_PWM(pwm->hwpwm), wfhw->duty_steps); > + if (ret) > + return ret; > + } > + > + val = wfhw->enabled ? BIT(pwm->hwpwm) : 0; > + return regmap_write_bits(regmap, MAX7360_REG_GPIOCTRL, BIT(pwm->hwpwm), val); > +} > + > +static int max7360_pwm_read_waveform(struct pwm_chip *chip, > + struct pwm_device *pwm, > + void *_wfhw) > +{ > + struct regmap *regmap = pwmchip_get_drvdata(chip); > + struct max7360_pwm_waveform *wfhw = _wfhw; > + unsigned int val; > + int ret; > + > + ret = regmap_read(regmap, MAX7360_REG_GPIOCTRL, &val); > + if (ret) > + return ret; > + > + if (val & BIT(pwm->hwpwm)) { > + wfhw->enabled = true; > + ret = regmap_read(regmap, MAX7360_REG_PWM(pwm->hwpwm), &val); > + if (ret) > + return ret; > + > + wfhw->duty_steps = val; > + } else { > + wfhw->enabled = false; > + wfhw->duty_steps = 0; > + } > + > + return 0; > +} > + > +static const struct pwm_ops max7360_pwm_ops = { > + .request = max7360_pwm_request, > + .round_waveform_tohw = max7360_pwm_round_waveform_tohw, > + .round_waveform_fromhw = max7360_pwm_round_waveform_fromhw, > + .read_waveform = max7360_pwm_read_waveform, > + .write_waveform = max7360_pwm_write_waveform, > +}; > + > +static int max7360_pwm_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct pwm_chip *chip; > + struct regmap *regmap; > + int ret; > + > + regmap = dev_get_regmap(dev->parent, NULL); > + if (!regmap) > + return dev_err_probe(dev, -ENODEV, "Could not get parent regmap\n"); > + > + /* > + * This MFD sub-device does not have any associated device tree node: > + * properties are stored in the device node of the parent (MFD) device > + * and this same node is used in phandles of client devices. > + * Reuse this device tree node here, as otherwise the PWM subsystem > + * would be confused by this topology. > + */ > + device_set_of_node_from_dev(dev, dev->parent); > + > + chip = devm_pwmchip_alloc(dev, MAX7360_NUM_PWMS, 0); > + if (IS_ERR(chip)) > + return PTR_ERR(chip); > + chip->ops = &max7360_pwm_ops; > + > + pwmchip_set_drvdata(chip, regmap); > + > + ret = devm_pwmchip_add(dev, chip); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); > + > + return 0; > +} > + > +static struct platform_driver max7360_pwm_driver = { > + .driver = { > + .name = "max7360-pwm", > + .probe_type = PROBE_PREFER_ASYNCHRONOUS, > + }, > + .probe = max7360_pwm_probe, > +}; > +module_platform_driver(max7360_pwm_driver); > + > +MODULE_DESCRIPTION("MAX7360 PWM driver"); > +MODULE_AUTHOR("Kamel BOUHARA <kamel.bouhara@bootlin.com>"); > +MODULE_AUTHOR("Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>"); > +MODULE_LICENSE("GPL"); Hi Uwe, Any thought about this new version? I believe I fixed all the points we have been discussing previously. Thanks, Mathieu -- Mathieu Dubois-Briand, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
© 2016 - 2025 Red Hat, Inc.