Re: [PATCH v5 2/2] hwmon: (nct7802) Make temperature/voltage sensors configurable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Changes since "PATCH v4 2/2" as requested in the review:
- Changed device tree node name from "signal" to "channel".
- Removed unrelated changes to replace literal values with #defines.
- Fixed formatting issues by running clang-format.
- Removed unneccessary check for reg >= 1 && reg <= 3.
- nct7802_get_channel_config is now returning an error value.
- nct7802_configure_channels now stops processing the device tree on
the first error.
- Simplified logic for LTD default configuration in nct7802_configure_channels.

On Sat, Oct 9, 2021 at 2:53 PM Oskar Senft <osk@xxxxxxxxxx> wrote:
>
> This change allows LTD and RTD inputs to be configured via
> device tree bindings. If the DT bindings are not present or
> invalid, the input configuration is not modified and left at
> HW defaults.
>
> Signed-off-by: Oskar Senft <osk@xxxxxxxxxx>
> ---
>  drivers/hwmon/nct7802.c | 133 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 129 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c
> index 604af2f6103a..e28f8eaf9f0f 100644
> --- a/drivers/hwmon/nct7802.c
> +++ b/drivers/hwmon/nct7802.c
> @@ -51,6 +51,23 @@ static const u8 REG_VOLTAGE_LIMIT_MSB_SHIFT[2][5] = {
>  #define REG_CHIP_ID            0xfe
>  #define REG_VERSION_ID         0xff
>
> +/*
> + * Resistance temperature detector (RTD) modes according to 7.2.32 Mode
> + * Selection Register
> + */
> +#define RTD_MODE_CURRENT       0x1
> +#define RTD_MODE_THERMISTOR    0x2
> +#define RTD_MODE_VOLTAGE       0x3
> +
> +#define MODE_RTD_MASK          0x3
> +#define MODE_LTD_EN            0x40
> +
> +/*
> + * Bit offset for sensors modes in REG_MODE.
> + * Valid for index 0..2, indicating RTD1..3.
> + */
> +#define MODE_BIT_OFFSET_RTD(index) ((index) * 2)
> +
>  /*
>   * Data structures and manipulation thereof
>   */
> @@ -1038,7 +1055,116 @@ static const struct regmap_config nct7802_regmap_config = {
>         .volatile_reg = nct7802_regmap_is_volatile,
>  };
>
> -static int nct7802_init_chip(struct nct7802_data *data)
> +static int nct7802_get_channel_config(struct device *dev,
> +                                     struct device_node *node, u8 *mode_mask,
> +                                     u8 *mode_val)
> +{
> +       u32 reg;
> +       const char *type_str, *md_str;
> +       u8 md;
> +
> +       if (!node->name || of_node_cmp(node->name, "channel"))
> +               return 0;
> +
> +       if (of_property_read_u32(node, "reg", &reg)) {
> +               dev_err(dev, "Could not read reg value for '%s'\n",
> +                       node->full_name);
> +               return -EINVAL;
> +       }
> +
> +       if (reg > 3) {
> +               dev_err(dev, "Invalid reg (%u) in '%s'\n", reg,
> +                       node->full_name);
> +               return -EINVAL;
> +       }
> +
> +       if (reg == 0) {
> +               if (!of_device_is_available(node))
> +                       *mode_val &= ~MODE_LTD_EN;
> +               else
> +                       *mode_val |= MODE_LTD_EN;
> +               *mode_mask |= MODE_LTD_EN;
> +               return 0;
> +       }
> +
> +       /* At this point we have reg >= 1 && reg <= 3 */
> +
> +       if (!of_device_is_available(node)) {
> +               *mode_val &= ~(MODE_RTD_MASK << MODE_BIT_OFFSET_RTD(reg - 1));
> +               *mode_mask |= MODE_RTD_MASK << MODE_BIT_OFFSET_RTD(reg - 1);
> +               return 0;
> +       }
> +
> +       if (of_property_read_string(node, "sensor-type", &type_str)) {
> +               dev_err(dev, "No type for '%s'\n", node->full_name);
> +               return -EINVAL;
> +       }
> +
> +       if (!strcmp(type_str, "voltage")) {
> +               *mode_val |= (RTD_MODE_VOLTAGE & MODE_RTD_MASK)
> +                            << MODE_BIT_OFFSET_RTD(reg - 1);
> +               *mode_mask |= MODE_RTD_MASK << MODE_BIT_OFFSET_RTD(reg - 1);
> +               return 0;
> +       }
> +
> +       if (strcmp(type_str, "temperature")) {
> +               dev_err(dev, "Invalid type '%s' for '%s'\n", type_str,
> +                       node->full_name);
> +               return -EINVAL;
> +       }
> +
> +       if (reg == 3) {
> +               /* RTD3 only supports thermistor mode */
> +               md = RTD_MODE_THERMISTOR;
> +       } else {
> +               if (of_property_read_string(node, "temperature-mode",
> +                                           &md_str)) {
> +                       dev_err(dev, "No mode for '%s'\n", node->full_name);
> +                       return -EINVAL;
> +               }
> +
> +               if (!strcmp(md_str, "thermal-diode"))
> +                       md = RTD_MODE_CURRENT;
> +               else if (!strcmp(md_str, "thermistor"))
> +                       md = RTD_MODE_THERMISTOR;
> +               else {
> +                       dev_err(dev, "Invalid mode '%s' for '%s'\n", md_str,
> +                               node->full_name);
> +                       return -EINVAL;
> +               }
> +       }
> +
> +       *mode_val |= (md & MODE_RTD_MASK) << MODE_BIT_OFFSET_RTD(reg - 1);
> +       *mode_mask |= MODE_RTD_MASK << MODE_BIT_OFFSET_RTD(reg - 1);
> +
> +       return 0;
> +}
> +
> +static int nct7802_configure_channels(struct device *dev,
> +                                     struct nct7802_data *data)
> +{
> +       bool found_channel_config = false;
> +       u8 mode_mask = 0, mode_val = 0;
> +       struct device_node *node;
> +       int err;
> +
> +       /* Enable local temperature sensor by default */
> +       mode_val |= MODE_LTD_EN;
> +       mode_mask |= MODE_LTD_EN;
> +
> +       if (dev->of_node) {
> +               for_each_child_of_node(dev->of_node, node) {
> +                       err = nct7802_get_channel_config(dev, node, &mode_mask,
> +                                                        &mode_val);
> +                       if (err)
> +                               return err;
> +               }
> +       }
> +
> +       return regmap_update_bits(data->regmap, REG_MODE, mode_mask, mode_val);
> +}
> +
> +static int nct7802_init_chip(struct device *dev, struct nct7802_data *data)
>  {
>         int err;
>
> @@ -1047,8 +1173,7 @@ static int nct7802_init_chip(struct nct7802_data *data)
>         if (err)
>                 return err;
>
> -       /* Enable local temperature sensor */
> -       err = regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40);
> +       err = nct7802_configure_channels(dev, data);
>         if (err)
>                 return err;
>
> @@ -1074,7 +1199,7 @@ static int nct7802_probe(struct i2c_client *client)
>         mutex_init(&data->access_lock);
>         mutex_init(&data->in_alarm_lock);
>
> -       ret = nct7802_init_chip(data);
> +       ret = nct7802_init_chip(dev, data);
>         if (ret < 0)
>                 return ret;
>
> --
> 2.33.0.882.g93a45727a2-goog
>



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux