On 4/24/24 17:29, Xilin Wu via B4 Relay wrote:
From: Junhao Xie <bigf...@classfun.cn>

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

Signed-off-by: Junhao Xie <bigf...@classfun.cn>
---

[...]

+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

Reply via email to