linux/drivers/hwmon/gsc-hwmon.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Driver for Gateworks System Controller Hardware Monitor module
   4 *
   5 * Copyright (C) 2020 Gateworks Corporation
   6 */
   7#include <linux/hwmon.h>
   8#include <linux/hwmon-sysfs.h>
   9#include <linux/mfd/gsc.h>
  10#include <linux/module.h>
  11#include <linux/of.h>
  12#include <linux/platform_device.h>
  13#include <linux/regmap.h>
  14#include <linux/slab.h>
  15
  16#include <linux/platform_data/gsc_hwmon.h>
  17
  18#define GSC_HWMON_MAX_TEMP_CH   16
  19#define GSC_HWMON_MAX_IN_CH     16
  20#define GSC_HWMON_MAX_FAN_CH    16
  21
  22#define GSC_HWMON_RESOLUTION    12
  23#define GSC_HWMON_VREF          2500
  24
  25struct gsc_hwmon_data {
  26        struct gsc_dev *gsc;
  27        struct gsc_hwmon_platform_data *pdata;
  28        struct regmap *regmap;
  29        const struct gsc_hwmon_channel *temp_ch[GSC_HWMON_MAX_TEMP_CH];
  30        const struct gsc_hwmon_channel *in_ch[GSC_HWMON_MAX_IN_CH];
  31        const struct gsc_hwmon_channel *fan_ch[GSC_HWMON_MAX_FAN_CH];
  32        u32 temp_config[GSC_HWMON_MAX_TEMP_CH + 1];
  33        u32 in_config[GSC_HWMON_MAX_IN_CH + 1];
  34        u32 fan_config[GSC_HWMON_MAX_FAN_CH + 1];
  35        struct hwmon_channel_info temp_info;
  36        struct hwmon_channel_info in_info;
  37        struct hwmon_channel_info fan_info;
  38        const struct hwmon_channel_info *info[4];
  39        struct hwmon_chip_info chip;
  40};
  41
  42static struct regmap_bus gsc_hwmon_regmap_bus = {
  43        .reg_read = gsc_read,
  44        .reg_write = gsc_write,
  45};
  46
  47static const struct regmap_config gsc_hwmon_regmap_config = {
  48        .reg_bits = 8,
  49        .val_bits = 8,
  50        .cache_type = REGCACHE_NONE,
  51};
  52
  53static ssize_t pwm_auto_point_temp_show(struct device *dev,
  54                                        struct device_attribute *devattr,
  55                                        char *buf)
  56{
  57        struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
  58        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  59        u8 reg = hwmon->pdata->fan_base + (2 * attr->index);
  60        u8 regs[2];
  61        int ret;
  62
  63        ret = regmap_bulk_read(hwmon->regmap, reg, regs, 2);
  64        if (ret)
  65                return ret;
  66
  67        ret = regs[0] | regs[1] << 8;
  68        return sprintf(buf, "%d\n", ret * 10);
  69}
  70
  71static ssize_t pwm_auto_point_temp_store(struct device *dev,
  72                                         struct device_attribute *devattr,
  73                                         const char *buf, size_t count)
  74{
  75        struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
  76        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  77        u8 reg = hwmon->pdata->fan_base + (2 * attr->index);
  78        u8 regs[2];
  79        long temp;
  80        int err;
  81
  82        if (kstrtol(buf, 10, &temp))
  83                return -EINVAL;
  84
  85        temp = clamp_val(temp, 0, 10000);
  86        temp = DIV_ROUND_CLOSEST(temp, 10);
  87
  88        regs[0] = temp & 0xff;
  89        regs[1] = (temp >> 8) & 0xff;
  90        err = regmap_bulk_write(hwmon->regmap, reg, regs, 2);
  91        if (err)
  92                return err;
  93
  94        return count;
  95}
  96
  97static ssize_t pwm_auto_point_pwm_show(struct device *dev,
  98                                       struct device_attribute *devattr,
  99                                       char *buf)
 100{
 101        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 102
 103        return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100);
 104}
 105
 106static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
 107static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_temp, pwm_auto_point_temp, 0);
 108
 109static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point2_pwm, pwm_auto_point_pwm, 1);
 110static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_temp, pwm_auto_point_temp, 1);
 111
 112static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point3_pwm, pwm_auto_point_pwm, 2);
 113static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_temp, pwm_auto_point_temp, 2);
 114
 115static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point4_pwm, pwm_auto_point_pwm, 3);
 116static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_temp, pwm_auto_point_temp, 3);
 117
 118static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point5_pwm, pwm_auto_point_pwm, 4);
 119static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point5_temp, pwm_auto_point_temp, 4);
 120
 121static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point6_pwm, pwm_auto_point_pwm, 5);
 122static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point6_temp, pwm_auto_point_temp, 5);
 123
 124static struct attribute *gsc_hwmon_attributes[] = {
 125        &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
 126        &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
 127        &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
 128        &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
 129        &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
 130        &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
 131        &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
 132        &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
 133        &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr,
 134        &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr,
 135        &sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr,
 136        &sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr,
 137        NULL
 138};
 139
 140static const struct attribute_group gsc_hwmon_group = {
 141        .attrs = gsc_hwmon_attributes,
 142};
 143__ATTRIBUTE_GROUPS(gsc_hwmon);
 144
 145static int
 146gsc_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 147               int channel, long *val)
 148{
 149        struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
 150        const struct gsc_hwmon_channel *ch;
 151        int sz, ret;
 152        long tmp;
 153        u8 buf[3];
 154
 155        switch (type) {
 156        case hwmon_in:
 157                ch = hwmon->in_ch[channel];
 158                break;
 159        case hwmon_temp:
 160                ch = hwmon->temp_ch[channel];
 161                break;
 162        case hwmon_fan:
 163                ch = hwmon->fan_ch[channel];
 164                break;
 165        default:
 166                return -EOPNOTSUPP;
 167        }
 168
 169        sz = (ch->mode == mode_voltage_24bit) ? 3 : 2;
 170        ret = regmap_bulk_read(hwmon->regmap, ch->reg, buf, sz);
 171        if (ret)
 172                return ret;
 173
 174        tmp = 0;
 175        while (sz-- > 0)
 176                tmp |= (buf[sz] << (8 * sz));
 177
 178        switch (ch->mode) {
 179        case mode_temperature:
 180                if (tmp > 0x8000)
 181                        tmp -= 0xffff;
 182                tmp *= 100; /* convert to millidegrees celsius */
 183                break;
 184        case mode_voltage_raw:
 185                tmp = clamp_val(tmp, 0, BIT(GSC_HWMON_RESOLUTION));
 186                /* scale based on ref voltage and ADC resolution */
 187                tmp *= GSC_HWMON_VREF;
 188                tmp >>= GSC_HWMON_RESOLUTION;
 189                /* scale based on optional voltage divider */
 190                if (ch->vdiv[0] && ch->vdiv[1]) {
 191                        tmp *= (ch->vdiv[0] + ch->vdiv[1]);
 192                        tmp /= ch->vdiv[1];
 193                }
 194                /* adjust by uV offset */
 195                tmp += ch->mvoffset;
 196                break;
 197        case mode_fan:
 198                tmp *= 30; /* convert to revolutions per minute */
 199                break;
 200        case mode_voltage_24bit:
 201        case mode_voltage_16bit:
 202                /* no adjustment needed */
 203                break;
 204        }
 205
 206        *val = tmp;
 207
 208        return 0;
 209}
 210
 211static int
 212gsc_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
 213                      u32 attr, int channel, const char **buf)
 214{
 215        struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
 216
 217        switch (type) {
 218        case hwmon_in:
 219                *buf = hwmon->in_ch[channel]->name;
 220                break;
 221        case hwmon_temp:
 222                *buf = hwmon->temp_ch[channel]->name;
 223                break;
 224        case hwmon_fan:
 225                *buf = hwmon->fan_ch[channel]->name;
 226                break;
 227        default:
 228                return -ENOTSUPP;
 229        }
 230
 231        return 0;
 232}
 233
 234static umode_t
 235gsc_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type, u32 attr,
 236                     int ch)
 237{
 238        return 0444;
 239}
 240
 241static const struct hwmon_ops gsc_hwmon_ops = {
 242        .is_visible = gsc_hwmon_is_visible,
 243        .read = gsc_hwmon_read,
 244        .read_string = gsc_hwmon_read_string,
 245};
 246
 247static struct gsc_hwmon_platform_data *
 248gsc_hwmon_get_devtree_pdata(struct device *dev)
 249{
 250        struct gsc_hwmon_platform_data *pdata;
 251        struct gsc_hwmon_channel *ch;
 252        struct fwnode_handle *child;
 253        struct device_node *fan;
 254        int nchannels;
 255
 256        nchannels = device_get_child_node_count(dev);
 257        if (nchannels == 0)
 258                return ERR_PTR(-ENODEV);
 259
 260        pdata = devm_kzalloc(dev,
 261                             sizeof(*pdata) + nchannels * sizeof(*ch),
 262                             GFP_KERNEL);
 263        if (!pdata)
 264                return ERR_PTR(-ENOMEM);
 265        ch = (struct gsc_hwmon_channel *)(pdata + 1);
 266        pdata->channels = ch;
 267        pdata->nchannels = nchannels;
 268
 269        /* fan controller base address */
 270        fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan");
 271        if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) {
 272                dev_err(dev, "fan node without base\n");
 273                return ERR_PTR(-EINVAL);
 274        }
 275
 276        /* allocate structures for channels and count instances of each type */
 277        device_for_each_child_node(dev, child) {
 278                if (fwnode_property_read_string(child, "label", &ch->name)) {
 279                        dev_err(dev, "channel without label\n");
 280                        fwnode_handle_put(child);
 281                        return ERR_PTR(-EINVAL);
 282                }
 283                if (fwnode_property_read_u32(child, "reg", &ch->reg)) {
 284                        dev_err(dev, "channel without reg\n");
 285                        fwnode_handle_put(child);
 286                        return ERR_PTR(-EINVAL);
 287                }
 288                if (fwnode_property_read_u32(child, "gw,mode", &ch->mode)) {
 289                        dev_err(dev, "channel without mode\n");
 290                        fwnode_handle_put(child);
 291                        return ERR_PTR(-EINVAL);
 292                }
 293                if (ch->mode > mode_max) {
 294                        dev_err(dev, "invalid channel mode\n");
 295                        fwnode_handle_put(child);
 296                        return ERR_PTR(-EINVAL);
 297                }
 298
 299                if (!fwnode_property_read_u32(child,
 300                                              "gw,voltage-offset-microvolt",
 301                                              &ch->mvoffset))
 302                        ch->mvoffset /= 1000;
 303                fwnode_property_read_u32_array(child,
 304                                               "gw,voltage-divider-ohms",
 305                                               ch->vdiv, ARRAY_SIZE(ch->vdiv));
 306                ch++;
 307        }
 308
 309        return pdata;
 310}
 311
 312static int gsc_hwmon_probe(struct platform_device *pdev)
 313{
 314        struct gsc_dev *gsc = dev_get_drvdata(pdev->dev.parent);
 315        struct device *dev = &pdev->dev;
 316        struct device *hwmon_dev;
 317        struct gsc_hwmon_platform_data *pdata = dev_get_platdata(dev);
 318        struct gsc_hwmon_data *hwmon;
 319        const struct attribute_group **groups;
 320        int i, i_in, i_temp, i_fan;
 321
 322        if (!pdata) {
 323                pdata = gsc_hwmon_get_devtree_pdata(dev);
 324                if (IS_ERR(pdata))
 325                        return PTR_ERR(pdata);
 326        }
 327
 328        hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
 329        if (!hwmon)
 330                return -ENOMEM;
 331        hwmon->gsc = gsc;
 332        hwmon->pdata = pdata;
 333
 334        hwmon->regmap = devm_regmap_init(dev, &gsc_hwmon_regmap_bus,
 335                                         gsc->i2c_hwmon,
 336                                         &gsc_hwmon_regmap_config);
 337        if (IS_ERR(hwmon->regmap))
 338                return PTR_ERR(hwmon->regmap);
 339
 340        for (i = 0, i_in = 0, i_temp = 0, i_fan = 0; i < hwmon->pdata->nchannels; i++) {
 341                const struct gsc_hwmon_channel *ch = &pdata->channels[i];
 342
 343                switch (ch->mode) {
 344                case mode_temperature:
 345                        if (i_temp == GSC_HWMON_MAX_TEMP_CH) {
 346                                dev_err(gsc->dev, "too many temp channels\n");
 347                                return -EINVAL;
 348                        }
 349                        hwmon->temp_ch[i_temp] = ch;
 350                        hwmon->temp_config[i_temp] = HWMON_T_INPUT |
 351                                                     HWMON_T_LABEL;
 352                        i_temp++;
 353                        break;
 354                case mode_fan:
 355                        if (i_fan == GSC_HWMON_MAX_FAN_CH) {
 356                                dev_err(gsc->dev, "too many fan channels\n");
 357                                return -EINVAL;
 358                        }
 359                        hwmon->fan_ch[i_fan] = ch;
 360                        hwmon->fan_config[i_fan] = HWMON_F_INPUT |
 361                                                   HWMON_F_LABEL;
 362                        i_fan++;
 363                        break;
 364                case mode_voltage_24bit:
 365                case mode_voltage_16bit:
 366                case mode_voltage_raw:
 367                        if (i_in == GSC_HWMON_MAX_IN_CH) {
 368                                dev_err(gsc->dev, "too many input channels\n");
 369                                return -EINVAL;
 370                        }
 371                        hwmon->in_ch[i_in] = ch;
 372                        hwmon->in_config[i_in] =
 373                                HWMON_I_INPUT | HWMON_I_LABEL;
 374                        i_in++;
 375                        break;
 376                default:
 377                        dev_err(gsc->dev, "invalid mode: %d\n", ch->mode);
 378                        return -EINVAL;
 379                }
 380        }
 381
 382        /* setup config structures */
 383        hwmon->chip.ops = &gsc_hwmon_ops;
 384        hwmon->chip.info = hwmon->info;
 385        hwmon->info[0] = &hwmon->temp_info;
 386        hwmon->info[1] = &hwmon->in_info;
 387        hwmon->info[2] = &hwmon->fan_info;
 388        hwmon->temp_info.type = hwmon_temp;
 389        hwmon->temp_info.config = hwmon->temp_config;
 390        hwmon->in_info.type = hwmon_in;
 391        hwmon->in_info.config = hwmon->in_config;
 392        hwmon->fan_info.type = hwmon_fan;
 393        hwmon->fan_info.config = hwmon->fan_config;
 394
 395        groups = pdata->fan_base ? gsc_hwmon_groups : NULL;
 396        hwmon_dev = devm_hwmon_device_register_with_info(dev,
 397                                                         KBUILD_MODNAME, hwmon,
 398                                                         &hwmon->chip, groups);
 399        return PTR_ERR_OR_ZERO(hwmon_dev);
 400}
 401
 402static const struct of_device_id gsc_hwmon_of_match[] = {
 403        { .compatible = "gw,gsc-adc", },
 404        {}
 405};
 406
 407static struct platform_driver gsc_hwmon_driver = {
 408        .driver = {
 409                .name = "gsc-hwmon",
 410                .of_match_table = gsc_hwmon_of_match,
 411        },
 412        .probe = gsc_hwmon_probe,
 413};
 414
 415module_platform_driver(gsc_hwmon_driver);
 416
 417MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>");
 418MODULE_DESCRIPTION("GSC hardware monitor driver");
 419MODULE_LICENSE("GPL v2");
 420