Re: [PATCH v7 11/11] pwm: Add Raspberry Pi Firmware based PWM bus
From: Uwe Kleine-König <hidden>
Date: 2021-03-10 11:51:34
Also in:
linux-arm-kernel, linux-clk, linux-gpio, linux-input, linux-pwm, lkml
Hello Nicolas, On Mon, Jan 18, 2021 at 01:32:44PM +0100, Nicolas Saenz Julienne wrote:
quoted hunk ↗ jump to hunk
diff --git a/drivers/pwm/pwm-raspberrypi-poe.c b/drivers/pwm/pwm-raspberrypi-poe.c new file mode 100644 index 000000000000..ca845e8fabe6 --- /dev/null +++ b/drivers/pwm/pwm-raspberrypi-poe.c@@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de> + * For more information on Raspberry Pi's PoE hat see: + * https://www.raspberrypi.org/products/poe-hat/ + * + * Limitations: + * - No disable bit, so a disabled PWM is simulated by duty_cycle 0 + * - Only normal polarity + * - Fixed 12.5 kHz period + * + * The current period is completed when HW is reconfigured.
nice.
+ */
+
[...]
+static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ struct raspberrypi_pwm *rpipwm = raspberrypi_pwm_from_chip(chip);
+ unsigned int duty_cycle;
+ int ret;
+
+ if (state->period < RPI_PWM_PERIOD_NS ||
+ state->polarity != PWM_POLARITY_NORMAL)
+ return -EINVAL;
+
+ if (!state->enabled)
+ duty_cycle = 0;
+ else if (state->duty_cycle < RPI_PWM_PERIOD_NS)
+ duty_cycle = DIV_ROUND_DOWN_ULL(state->duty_cycle * RPI_PWM_MAX_DUTY,
+ RPI_PWM_PERIOD_NS);
+ else
+ duty_cycle = RPI_PWM_MAX_DUTY;
+
+ if (duty_cycle == rpipwm->duty_cycle)
+ return 0;
+
+ ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG,
+ duty_cycle);
+ if (ret) {
+ dev_err(chip->dev, "Failed to set duty cycle: %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+
+ /*
+ * This sets the default duty cycle after resetting the board, we
+ * updated it every time to mimic Raspberry Pi's downstream's driver
+ * behaviour.
+ */
+ ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_DEF_DUTY_REG,
+ duty_cycle);
+ if (ret) {
+ dev_err(chip->dev, "Failed to set default duty cycle: %pe\n",
+ ERR_PTR(ret));
+ return ret;This only has an effect for the next reboot, right? If so I wonder if it is a good idea in general. (Think: The current PWM setting enables a motor that makes a self-driving car move at 100 km/h. Consider the rpi crashes, do I want to car to pick up driving 100 km/h at power up even before Linux is up again?) And if we agree it's a good idea: Should raspberrypi_pwm_apply return 0 if setting the duty cycle succeeded and only setting the default didn't? Other than that the patch looks fine. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |
Attachments
- signature.asc [application/pgp-signature] 488 bytes