Re: [PATCH 02/10] pwm: Add SI-EN SN3112 PWM support

From: Konrad Dybcio
Date: Wed Apr 24 2024 - 15:37:43 EST




On 4/24/24 17:29, Xilin Wu via B4 Relay wrote:
From: Junhao Xie <bigfoot@xxxxxxxxxxx>

Add a new driver for the SI-EN SN3112 12-channel 8-bit PWM LED controller.

Signed-off-by: Junhao Xie <bigfoot@xxxxxxxxxxx>
---

[...]

+static int sn3112_set_en_reg(struct sn3112 *priv, unsigned int channel,
+ bool enabled, bool write)
+{
+ unsigned int reg, bit;
+
+ if (channel >= SN3112_CHANNELS)
+ return -EINVAL;
+
+ /* LED_EN1: BIT5:BIT3 = OUT3:OUT1 */
+ if (channel >= 0 && channel <= 2)
+ reg = 0, bit = channel + 3;
+ /* LED_EN2: BIT5:BIT0 = OUT9:OUT4 */
+ else if (channel >= 3 && channel <= 8)
+ reg = 1, bit = channel - 3;
+ /* LED_EN3: BIT2:BIT0 = OUT12:OUT10 */
+ else if (channel >= 9 && channel <= 11)
+ reg = 2, bit = channel - 9;
+ else
+ return -EINVAL;
+
+ dev_dbg(priv->pdev, "channel %u enabled %u\n", channel, enabled);
+ dev_dbg(priv->pdev, "reg %u bit %u\n", reg, bit);
+ if (enabled)
+ set_bit(bit, (ulong *)&priv->pwm_en_reg[reg]);
+ else
+ clear_bit(bit, (ulong *)&priv->pwm_en_reg[reg]);
+ dev_dbg(priv->pdev, "set enable reg %u to %u\n", reg,
+ priv->pwm_en_reg[reg]);
+
+ if (!write)
+ return 0;
+ return sn3112_write_reg(priv, SN3112_REG_PWM_EN + reg,
+ priv->pwm_en_reg[reg]);

This looks like a weird reimplementation of regmap_update_bits


+}
+
+static int sn3112_set_val_reg(struct sn3112 *priv, unsigned int channel,
+ uint8_t val, bool write)
+{
+ if (channel >= SN3112_CHANNELS)
+ return -EINVAL;
+ priv->pwm_val[channel] = val;
+ dev_dbg(priv->pdev, "set value reg %u to %u\n", channel,
+ priv->pwm_val[channel]);
+
+ if (!write)
+ return 0;

There's only a single call, with write == true

+ return sn3112_write_reg(priv, SN3112_REG_PWM_VAL + channel,
+ priv->pwm_val[channel]);
+}
+
+static int sn3112_write_all(struct sn3112 *priv)
+{
+ int i, ret;
+
+ /* regenerate enable register values */
+ for (i = 0; i < SN3112_CHANNELS; i++) {
+ ret = sn3112_set_en_reg(priv, i, priv->pwm_en[i], false);
+ if (ret != 0)
+ return ret;
+ }
+
+ /* use random value to clear all registers */
+ ret = sn3112_write_reg(priv, SN3112_REG_RESET, 0x66);
+ if (ret != 0)

if (ret) is the same as if (ret != 0)

[...]

+
+ /* use random value to apply changes */
+ ret = sn3112_write_reg(priv, SN3112_REG_APPLY, 0x66);

"a random value"? sounds suspicious..

+ if (ret != 0)
+ return ret;
+
+ dev_dbg(priv->pdev, "reinitialized\n");

Please remove such "got here" messages once you're done with testing
the driver locally

[...]

+
+#if IS_ENABLED(CONFIG_GPIOLIB)

I'm not sure this would be ever disabled on any embedded system nowadays.
Especially with I2C.

[...]

+
+ dev_info(&client->dev,
+ "Found SI-EN SN3112 12-channel 8-bit PWM LED controller\n");

This sort of message only makes sense if there's a CHIP_ID register that
you can actually validate. If you bind this driver to a device at the same
expected address, it will say it's there even if it's not.


+ return 0;
+}
+
+static void sn3112_pwm_remove(struct i2c_client *client)
+{
+ struct pwm_chip *chip = i2c_get_clientdata(client);
+ struct sn3112 *priv = pwmchip_get_drvdata(chip);
+
+ dev_dbg(priv->pdev, "remove\n");
+
+ /* set software enable register */
+ sn3112_write_reg(priv, SN3112_REG_ENABLE, 0);
+
+ /* use random value to apply changes */
+ sn3112_write_reg(priv, SN3112_REG_APPLY, 0x66);
+
+#if IS_ENABLED(CONFIG_GPIOLIB)
+ /* enable hardware shutdown pin */
+ if (priv->sdb)
+ gpiod_set_value(priv->sdb, 1);
+#endif
+
+ /* power-off sn5112 power vdd */
+ regulator_disable(priv->vdd);
+
+ pwmchip_remove(chip);

devm_pwmchip_add?

Konrad