linux/drivers/hwmon/pmbus/max16601.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Hardware monitoring driver for Maxim MAX16508 and MAX16601.
   4 *
   5 * Implementation notes:
   6 *
   7 * This chip series supports two rails, VCORE and VSA. Telemetry information
   8 * for the two rails is reported in two subsequent I2C addresses. The driver
   9 * instantiates a dummy I2C client at the second I2C address to report
  10 * information for the VSA rail in a single instance of the driver.
  11 * Telemetry for the VSA rail is reported to the PMBus core in PMBus page 2.
  12 *
  13 * The chip reports input current using two separate methods. The input current
  14 * reported with the standard READ_IIN command is derived from the output
  15 * current. The first method is reported to the PMBus core with PMBus page 0,
  16 * the second method is reported with PMBus page 1.
  17 *
  18 * The chip supports reading per-phase temperatures and per-phase input/output
  19 * currents for VCORE. Telemetry is reported in vendor specific registers.
  20 * The driver translates the vendor specific register values to PMBus standard
  21 * register values and reports per-phase information in PMBus page 0.
  22 *
  23 * Copyright 2019, 2020 Google LLC.
  24 */
  25
  26#include <linux/bits.h>
  27#include <linux/i2c.h>
  28#include <linux/init.h>
  29#include <linux/kernel.h>
  30#include <linux/module.h>
  31
  32#include "pmbus.h"
  33
  34enum chips { max16508, max16601 };
  35
  36#define REG_DEFAULT_NUM_POP     0xc4
  37#define REG_SETPT_DVID          0xd1
  38#define  DAC_10MV_MODE          BIT(4)
  39#define REG_IOUT_AVG_PK         0xee
  40#define REG_IIN_SENSOR          0xf1
  41#define REG_TOTAL_INPUT_POWER   0xf2
  42#define REG_PHASE_ID            0xf3
  43#define  CORE_RAIL_INDICATOR    BIT(7)
  44#define REG_PHASE_REPORTING     0xf4
  45
  46#define MAX16601_NUM_PHASES     8
  47
  48struct max16601_data {
  49        enum chips id;
  50        struct pmbus_driver_info info;
  51        struct i2c_client *vsa;
  52        int iout_avg_pkg;
  53};
  54
  55#define to_max16601_data(x) container_of(x, struct max16601_data, info)
  56
  57static int max16601_read_byte(struct i2c_client *client, int page, int reg)
  58{
  59        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
  60        struct max16601_data *data = to_max16601_data(info);
  61
  62        if (page > 0) {
  63                if (page == 2)  /* VSA */
  64                        return i2c_smbus_read_byte_data(data->vsa, reg);
  65                return -EOPNOTSUPP;
  66        }
  67        return -ENODATA;
  68}
  69
  70static int max16601_read_word(struct i2c_client *client, int page, int phase,
  71                              int reg)
  72{
  73        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
  74        struct max16601_data *data = to_max16601_data(info);
  75        u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
  76        int ret;
  77
  78        switch (page) {
  79        case 0:         /* VCORE */
  80                if (phase == 0xff)
  81                        return -ENODATA;
  82                switch (reg) {
  83                case PMBUS_READ_IIN:
  84                case PMBUS_READ_IOUT:
  85                case PMBUS_READ_TEMPERATURE_1:
  86                        ret = i2c_smbus_write_byte_data(client, REG_PHASE_ID,
  87                                                        phase);
  88                        if (ret)
  89                                return ret;
  90                        ret = i2c_smbus_read_block_data(client,
  91                                                        REG_PHASE_REPORTING,
  92                                                        buf);
  93                        if (ret < 0)
  94                                return ret;
  95                        if (ret < 6)
  96                                return -EIO;
  97                        switch (reg) {
  98                        case PMBUS_READ_TEMPERATURE_1:
  99                                return buf[1] << 8 | buf[0];
 100                        case PMBUS_READ_IOUT:
 101                                return buf[3] << 8 | buf[2];
 102                        case PMBUS_READ_IIN:
 103                                return buf[5] << 8 | buf[4];
 104                        default:
 105                                break;
 106                        }
 107                }
 108                return -EOPNOTSUPP;
 109        case 1:         /* VCORE, read IIN/PIN from sensor element */
 110                switch (reg) {
 111                case PMBUS_READ_IIN:
 112                        return i2c_smbus_read_word_data(client, REG_IIN_SENSOR);
 113                case PMBUS_READ_PIN:
 114                        return i2c_smbus_read_word_data(client,
 115                                                        REG_TOTAL_INPUT_POWER);
 116                default:
 117                        break;
 118                }
 119                return -EOPNOTSUPP;
 120        case 2:         /* VSA */
 121                switch (reg) {
 122                case PMBUS_VIRT_READ_IOUT_MAX:
 123                        ret = i2c_smbus_read_word_data(data->vsa,
 124                                                       REG_IOUT_AVG_PK);
 125                        if (ret < 0)
 126                                return ret;
 127                        if (sign_extend32(ret, 10) >
 128                            sign_extend32(data->iout_avg_pkg, 10))
 129                                data->iout_avg_pkg = ret;
 130                        return data->iout_avg_pkg;
 131                case PMBUS_VIRT_RESET_IOUT_HISTORY:
 132                        return 0;
 133                case PMBUS_IOUT_OC_FAULT_LIMIT:
 134                case PMBUS_IOUT_OC_WARN_LIMIT:
 135                case PMBUS_OT_FAULT_LIMIT:
 136                case PMBUS_OT_WARN_LIMIT:
 137                case PMBUS_READ_IIN:
 138                case PMBUS_READ_IOUT:
 139                case PMBUS_READ_TEMPERATURE_1:
 140                case PMBUS_STATUS_WORD:
 141                        return i2c_smbus_read_word_data(data->vsa, reg);
 142                default:
 143                        return -EOPNOTSUPP;
 144                }
 145        default:
 146                return -EOPNOTSUPP;
 147        }
 148}
 149
 150static int max16601_write_byte(struct i2c_client *client, int page, u8 reg)
 151{
 152        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 153        struct max16601_data *data = to_max16601_data(info);
 154
 155        if (page == 2) {
 156                if (reg == PMBUS_CLEAR_FAULTS)
 157                        return i2c_smbus_write_byte(data->vsa, reg);
 158                return -EOPNOTSUPP;
 159        }
 160        return -ENODATA;
 161}
 162
 163static int max16601_write_word(struct i2c_client *client, int page, int reg,
 164                               u16 value)
 165{
 166        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 167        struct max16601_data *data = to_max16601_data(info);
 168
 169        switch (page) {
 170        case 0:         /* VCORE */
 171                return -ENODATA;
 172        case 1:         /* VCORE IIN/PIN from sensor element */
 173        default:
 174                return -EOPNOTSUPP;
 175        case 2:         /* VSA */
 176                switch (reg) {
 177                case PMBUS_VIRT_RESET_IOUT_HISTORY:
 178                        data->iout_avg_pkg = 0xfc00;
 179                        return 0;
 180                case PMBUS_IOUT_OC_FAULT_LIMIT:
 181                case PMBUS_IOUT_OC_WARN_LIMIT:
 182                case PMBUS_OT_FAULT_LIMIT:
 183                case PMBUS_OT_WARN_LIMIT:
 184                        return i2c_smbus_write_word_data(data->vsa, reg, value);
 185                default:
 186                        return -EOPNOTSUPP;
 187                }
 188        }
 189}
 190
 191static int max16601_identify(struct i2c_client *client,
 192                             struct pmbus_driver_info *info)
 193{
 194        struct max16601_data *data = to_max16601_data(info);
 195        int reg;
 196
 197        reg = i2c_smbus_read_byte_data(client, REG_SETPT_DVID);
 198        if (reg < 0)
 199                return reg;
 200        if (reg & DAC_10MV_MODE)
 201                info->vrm_version[0] = vr13;
 202        else
 203                info->vrm_version[0] = vr12;
 204
 205        if (data->id != max16601)
 206                return 0;
 207
 208        reg = i2c_smbus_read_byte_data(client, REG_DEFAULT_NUM_POP);
 209        if (reg < 0)
 210                return reg;
 211
 212        /*
 213         * If REG_DEFAULT_NUM_POP returns 0, we don't know how many phases
 214         * are populated. Stick with the default in that case.
 215         */
 216        reg &= 0x0f;
 217        if (reg && reg <= MAX16601_NUM_PHASES)
 218                info->phases[0] = reg;
 219
 220        return 0;
 221}
 222
 223static struct pmbus_driver_info max16601_info = {
 224        .pages = 3,
 225        .format[PSC_VOLTAGE_IN] = linear,
 226        .format[PSC_VOLTAGE_OUT] = vid,
 227        .format[PSC_CURRENT_IN] = linear,
 228        .format[PSC_CURRENT_OUT] = linear,
 229        .format[PSC_TEMPERATURE] = linear,
 230        .format[PSC_POWER] = linear,
 231        .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
 232                PMBUS_HAVE_STATUS_INPUT |
 233                PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
 234                PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
 235                PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
 236                PMBUS_HAVE_POUT | PMBUS_PAGE_VIRTUAL | PMBUS_PHASE_VIRTUAL,
 237        .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_PAGE_VIRTUAL,
 238        .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT |
 239                PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
 240                PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_PAGE_VIRTUAL,
 241        .phases[0] = MAX16601_NUM_PHASES,
 242        .pfunc[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
 243        .pfunc[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
 244        .pfunc[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
 245        .pfunc[3] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
 246        .pfunc[4] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
 247        .pfunc[5] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
 248        .pfunc[6] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
 249        .pfunc[7] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
 250        .identify = max16601_identify,
 251        .read_byte_data = max16601_read_byte,
 252        .read_word_data = max16601_read_word,
 253        .write_byte = max16601_write_byte,
 254        .write_word_data = max16601_write_word,
 255};
 256
 257static void max16601_remove(void *_data)
 258{
 259        struct max16601_data *data = _data;
 260
 261        i2c_unregister_device(data->vsa);
 262}
 263
 264static const struct i2c_device_id max16601_id[] = {
 265        {"max16508", max16508},
 266        {"max16601", max16601},
 267        {}
 268};
 269MODULE_DEVICE_TABLE(i2c, max16601_id);
 270
 271static int max16601_get_id(struct i2c_client *client)
 272{
 273        struct device *dev = &client->dev;
 274        u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
 275        enum chips id;
 276        int ret;
 277
 278        ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf);
 279        if (ret < 0 || ret < 11)
 280                return -ENODEV;
 281
 282        /*
 283         * PMBUS_IC_DEVICE_ID is expected to return "MAX16601y.xx"
 284         * or "MAX16500y.xx".
 285         */
 286        if (!strncmp(buf, "MAX16500", 8)) {
 287                id = max16508;
 288        } else if (!strncmp(buf, "MAX16601", 8)) {
 289                id = max16601;
 290        } else {
 291                buf[ret] = '\0';
 292                dev_err(dev, "Unsupported chip '%s'\n", buf);
 293                return -ENODEV;
 294        }
 295        return id;
 296}
 297
 298static int max16601_probe(struct i2c_client *client)
 299{
 300        struct device *dev = &client->dev;
 301        const struct i2c_device_id *id;
 302        struct max16601_data *data;
 303        int ret, chip_id;
 304
 305        if (!i2c_check_functionality(client->adapter,
 306                                     I2C_FUNC_SMBUS_READ_BYTE_DATA |
 307                                     I2C_FUNC_SMBUS_READ_BLOCK_DATA))
 308                return -ENODEV;
 309
 310        chip_id = max16601_get_id(client);
 311        if (chip_id < 0)
 312                return chip_id;
 313
 314        id = i2c_match_id(max16601_id, client);
 315        if (chip_id != id->driver_data)
 316                dev_warn(&client->dev,
 317                         "Device mismatch: Configured %s (%d), detected %d\n",
 318                         id->name, (int) id->driver_data, chip_id);
 319
 320        ret = i2c_smbus_read_byte_data(client, REG_PHASE_ID);
 321        if (ret < 0)
 322                return ret;
 323        if (!(ret & CORE_RAIL_INDICATOR)) {
 324                dev_err(dev,
 325                        "Driver must be instantiated on CORE rail I2C address\n");
 326                return -ENODEV;
 327        }
 328
 329        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 330        if (!data)
 331                return -ENOMEM;
 332
 333        data->id = chip_id;
 334        data->iout_avg_pkg = 0xfc00;
 335        data->vsa = i2c_new_dummy_device(client->adapter, client->addr + 1);
 336        if (IS_ERR(data->vsa)) {
 337                dev_err(dev, "Failed to register VSA client\n");
 338                return PTR_ERR(data->vsa);
 339        }
 340        ret = devm_add_action_or_reset(dev, max16601_remove, data);
 341        if (ret)
 342                return ret;
 343
 344        data->info = max16601_info;
 345
 346        return pmbus_do_probe(client, &data->info);
 347}
 348
 349static struct i2c_driver max16601_driver = {
 350        .driver = {
 351                   .name = "max16601",
 352                   },
 353        .probe_new = max16601_probe,
 354        .id_table = max16601_id,
 355};
 356
 357module_i2c_driver(max16601_driver);
 358
 359MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
 360MODULE_DESCRIPTION("PMBus driver for Maxim MAX16601");
 361MODULE_LICENSE("GPL v2");
 362MODULE_IMPORT_NS(PMBUS);
 363