linux/drivers/hwmon/pmbus/ltc2978.c
<<
>>
Prefs
   1/*
   2 * Hardware monitoring driver for LTC2974, LTC2977, LTC2978, LTC3880,
   3 * LTC3883, and LTM4676
   4 *
   5 * Copyright (c) 2011 Ericsson AB.
   6 * Copyright (c) 2013, 2014 Guenter Roeck
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/init.h>
  22#include <linux/err.h>
  23#include <linux/slab.h>
  24#include <linux/i2c.h>
  25#include <linux/regulator/driver.h>
  26#include "pmbus.h"
  27
  28enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883, ltm4676 };
  29
  30/* Common for all chips */
  31#define LTC2978_MFR_VOUT_PEAK           0xdd
  32#define LTC2978_MFR_VIN_PEAK            0xde
  33#define LTC2978_MFR_TEMPERATURE_PEAK    0xdf
  34#define LTC2978_MFR_SPECIAL_ID          0xe7
  35
  36/* LTC2974, LCT2977, and LTC2978 */
  37#define LTC2978_MFR_VOUT_MIN            0xfb
  38#define LTC2978_MFR_VIN_MIN             0xfc
  39#define LTC2978_MFR_TEMPERATURE_MIN     0xfd
  40
  41/* LTC2974 only */
  42#define LTC2974_MFR_IOUT_PEAK           0xd7
  43#define LTC2974_MFR_IOUT_MIN            0xd8
  44
  45/* LTC3880, LTC3883, and LTM4676 */
  46#define LTC3880_MFR_IOUT_PEAK           0xd7
  47#define LTC3880_MFR_CLEAR_PEAKS         0xe3
  48#define LTC3880_MFR_TEMPERATURE2_PEAK   0xf4
  49
  50/* LTC3883 only */
  51#define LTC3883_MFR_IIN_PEAK            0xe1
  52
  53#define LTC2974_ID_REV1                 0x0212
  54#define LTC2974_ID_REV2                 0x0213
  55#define LTC2977_ID                      0x0130
  56#define LTC2978_ID_REV1                 0x0121
  57#define LTC2978_ID_REV2                 0x0122
  58#define LTC2978A_ID                     0x0124
  59#define LTC3880_ID                      0x4000
  60#define LTC3880_ID_MASK                 0xff00
  61#define LTC3883_ID                      0x4300
  62#define LTC3883_ID_MASK                 0xff00
  63#define LTM4676_ID                      0x4480  /* datasheet claims 0x440X */
  64#define LTM4676_ID_MASK                 0xfff0
  65
  66#define LTC2974_NUM_PAGES               4
  67#define LTC2978_NUM_PAGES               8
  68#define LTC3880_NUM_PAGES               2
  69#define LTC3883_NUM_PAGES               1
  70
  71/*
  72 * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
  73 * happens pretty much each time chip data is updated. Raw peak data therefore
  74 * does not provide much value. To be able to provide useful peak data, keep an
  75 * internal cache of measured peak data, which is only cleared if an explicit
  76 * "clear peak" command is executed for the sensor in question.
  77 */
  78
  79struct ltc2978_data {
  80        enum chips id;
  81        u16 vin_min, vin_max;
  82        u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES];
  83        u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES];
  84        u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES];
  85        u16 iin_max;
  86        u16 temp2_max;
  87        struct pmbus_driver_info info;
  88};
  89
  90#define to_ltc2978_data(x)  container_of(x, struct ltc2978_data, info)
  91
  92static inline int lin11_to_val(int data)
  93{
  94        s16 e = ((s16)data) >> 11;
  95        s32 m = (((s16)(data << 5)) >> 5);
  96
  97        /*
  98         * mantissa is 10 bit + sign, exponent adds up to 15 bit.
  99         * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
 100         */
 101        e += 6;
 102        return (e < 0 ? m >> -e : m << e);
 103}
 104
 105static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
 106                                         int reg)
 107{
 108        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 109        struct ltc2978_data *data = to_ltc2978_data(info);
 110        int ret;
 111
 112        switch (reg) {
 113        case PMBUS_VIRT_READ_VIN_MAX:
 114                ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK);
 115                if (ret >= 0) {
 116                        if (lin11_to_val(ret) > lin11_to_val(data->vin_max))
 117                                data->vin_max = ret;
 118                        ret = data->vin_max;
 119                }
 120                break;
 121        case PMBUS_VIRT_READ_VOUT_MAX:
 122                ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK);
 123                if (ret >= 0) {
 124                        /*
 125                         * VOUT is 16 bit unsigned with fixed exponent,
 126                         * so we can compare it directly
 127                         */
 128                        if (ret > data->vout_max[page])
 129                                data->vout_max[page] = ret;
 130                        ret = data->vout_max[page];
 131                }
 132                break;
 133        case PMBUS_VIRT_READ_TEMP_MAX:
 134                ret = pmbus_read_word_data(client, page,
 135                                           LTC2978_MFR_TEMPERATURE_PEAK);
 136                if (ret >= 0) {
 137                        if (lin11_to_val(ret)
 138                            > lin11_to_val(data->temp_max[page]))
 139                                data->temp_max[page] = ret;
 140                        ret = data->temp_max[page];
 141                }
 142                break;
 143        case PMBUS_VIRT_RESET_VOUT_HISTORY:
 144        case PMBUS_VIRT_RESET_VIN_HISTORY:
 145        case PMBUS_VIRT_RESET_TEMP_HISTORY:
 146                ret = 0;
 147                break;
 148        default:
 149                ret = -ENODATA;
 150                break;
 151        }
 152        return ret;
 153}
 154
 155static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
 156{
 157        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 158        struct ltc2978_data *data = to_ltc2978_data(info);
 159        int ret;
 160
 161        switch (reg) {
 162        case PMBUS_VIRT_READ_VIN_MIN:
 163                ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
 164                if (ret >= 0) {
 165                        if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
 166                                data->vin_min = ret;
 167                        ret = data->vin_min;
 168                }
 169                break;
 170        case PMBUS_VIRT_READ_VOUT_MIN:
 171                ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
 172                if (ret >= 0) {
 173                        /*
 174                         * VOUT_MIN is known to not be supported on some lots
 175                         * of LTC2978 revision 1, and will return the maximum
 176                         * possible voltage if read. If VOUT_MAX is valid and
 177                         * lower than the reading of VOUT_MIN, use it instead.
 178                         */
 179                        if (data->vout_max[page] && ret > data->vout_max[page])
 180                                ret = data->vout_max[page];
 181                        if (ret < data->vout_min[page])
 182                                data->vout_min[page] = ret;
 183                        ret = data->vout_min[page];
 184                }
 185                break;
 186        case PMBUS_VIRT_READ_TEMP_MIN:
 187                ret = pmbus_read_word_data(client, page,
 188                                           LTC2978_MFR_TEMPERATURE_MIN);
 189                if (ret >= 0) {
 190                        if (lin11_to_val(ret)
 191                            < lin11_to_val(data->temp_min[page]))
 192                                data->temp_min[page] = ret;
 193                        ret = data->temp_min[page];
 194                }
 195                break;
 196        case PMBUS_VIRT_READ_IOUT_MAX:
 197        case PMBUS_VIRT_RESET_IOUT_HISTORY:
 198        case PMBUS_VIRT_READ_TEMP2_MAX:
 199        case PMBUS_VIRT_RESET_TEMP2_HISTORY:
 200                ret = -ENXIO;
 201                break;
 202        default:
 203                ret = ltc2978_read_word_data_common(client, page, reg);
 204                break;
 205        }
 206        return ret;
 207}
 208
 209static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg)
 210{
 211        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 212        struct ltc2978_data *data = to_ltc2978_data(info);
 213        int ret;
 214
 215        switch (reg) {
 216        case PMBUS_VIRT_READ_IOUT_MAX:
 217                ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK);
 218                if (ret >= 0) {
 219                        if (lin11_to_val(ret)
 220                            > lin11_to_val(data->iout_max[page]))
 221                                data->iout_max[page] = ret;
 222                        ret = data->iout_max[page];
 223                }
 224                break;
 225        case PMBUS_VIRT_READ_IOUT_MIN:
 226                ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN);
 227                if (ret >= 0) {
 228                        if (lin11_to_val(ret)
 229                            < lin11_to_val(data->iout_min[page]))
 230                                data->iout_min[page] = ret;
 231                        ret = data->iout_min[page];
 232                }
 233                break;
 234        case PMBUS_VIRT_RESET_IOUT_HISTORY:
 235                ret = 0;
 236                break;
 237        default:
 238                ret = ltc2978_read_word_data(client, page, reg);
 239                break;
 240        }
 241        return ret;
 242}
 243
 244static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
 245{
 246        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 247        struct ltc2978_data *data = to_ltc2978_data(info);
 248        int ret;
 249
 250        switch (reg) {
 251        case PMBUS_VIRT_READ_IOUT_MAX:
 252                ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
 253                if (ret >= 0) {
 254                        if (lin11_to_val(ret)
 255                            > lin11_to_val(data->iout_max[page]))
 256                                data->iout_max[page] = ret;
 257                        ret = data->iout_max[page];
 258                }
 259                break;
 260        case PMBUS_VIRT_READ_TEMP2_MAX:
 261                ret = pmbus_read_word_data(client, page,
 262                                           LTC3880_MFR_TEMPERATURE2_PEAK);
 263                if (ret >= 0) {
 264                        if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
 265                                data->temp2_max = ret;
 266                        ret = data->temp2_max;
 267                }
 268                break;
 269        case PMBUS_VIRT_READ_VIN_MIN:
 270        case PMBUS_VIRT_READ_VOUT_MIN:
 271        case PMBUS_VIRT_READ_TEMP_MIN:
 272                ret = -ENXIO;
 273                break;
 274        case PMBUS_VIRT_RESET_IOUT_HISTORY:
 275        case PMBUS_VIRT_RESET_TEMP2_HISTORY:
 276                ret = 0;
 277                break;
 278        default:
 279                ret = ltc2978_read_word_data_common(client, page, reg);
 280                break;
 281        }
 282        return ret;
 283}
 284
 285static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg)
 286{
 287        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 288        struct ltc2978_data *data = to_ltc2978_data(info);
 289        int ret;
 290
 291        switch (reg) {
 292        case PMBUS_VIRT_READ_IIN_MAX:
 293                ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK);
 294                if (ret >= 0) {
 295                        if (lin11_to_val(ret)
 296                            > lin11_to_val(data->iin_max))
 297                                data->iin_max = ret;
 298                        ret = data->iin_max;
 299                }
 300                break;
 301        case PMBUS_VIRT_RESET_IIN_HISTORY:
 302                ret = 0;
 303                break;
 304        default:
 305                ret = ltc3880_read_word_data(client, page, reg);
 306                break;
 307        }
 308        return ret;
 309}
 310
 311static int ltc2978_clear_peaks(struct i2c_client *client, int page,
 312                               enum chips id)
 313{
 314        int ret;
 315
 316        if (id == ltc3880 || id == ltc3883)
 317                ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS);
 318        else
 319                ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
 320
 321        return ret;
 322}
 323
 324static int ltc2978_write_word_data(struct i2c_client *client, int page,
 325                                    int reg, u16 word)
 326{
 327        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 328        struct ltc2978_data *data = to_ltc2978_data(info);
 329        int ret;
 330
 331        switch (reg) {
 332        case PMBUS_VIRT_RESET_IIN_HISTORY:
 333                data->iin_max = 0x7c00;
 334                ret = ltc2978_clear_peaks(client, page, data->id);
 335                break;
 336        case PMBUS_VIRT_RESET_IOUT_HISTORY:
 337                data->iout_max[page] = 0x7c00;
 338                data->iout_min[page] = 0xfbff;
 339                ret = ltc2978_clear_peaks(client, page, data->id);
 340                break;
 341        case PMBUS_VIRT_RESET_TEMP2_HISTORY:
 342                data->temp2_max = 0x7c00;
 343                ret = ltc2978_clear_peaks(client, page, data->id);
 344                break;
 345        case PMBUS_VIRT_RESET_VOUT_HISTORY:
 346                data->vout_min[page] = 0xffff;
 347                data->vout_max[page] = 0;
 348                ret = ltc2978_clear_peaks(client, page, data->id);
 349                break;
 350        case PMBUS_VIRT_RESET_VIN_HISTORY:
 351                data->vin_min = 0x7bff;
 352                data->vin_max = 0x7c00;
 353                ret = ltc2978_clear_peaks(client, page, data->id);
 354                break;
 355        case PMBUS_VIRT_RESET_TEMP_HISTORY:
 356                data->temp_min[page] = 0x7bff;
 357                data->temp_max[page] = 0x7c00;
 358                ret = ltc2978_clear_peaks(client, page, data->id);
 359                break;
 360        default:
 361                ret = -ENODATA;
 362                break;
 363        }
 364        return ret;
 365}
 366
 367static const struct i2c_device_id ltc2978_id[] = {
 368        {"ltc2974", ltc2974},
 369        {"ltc2977", ltc2977},
 370        {"ltc2978", ltc2978},
 371        {"ltc3880", ltc3880},
 372        {"ltc3883", ltc3883},
 373        {"ltm4676", ltm4676},
 374        {}
 375};
 376MODULE_DEVICE_TABLE(i2c, ltc2978_id);
 377
 378#if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR)
 379static const struct regulator_desc ltc2978_reg_desc[] = {
 380        PMBUS_REGULATOR("vout", 0),
 381        PMBUS_REGULATOR("vout", 1),
 382        PMBUS_REGULATOR("vout", 2),
 383        PMBUS_REGULATOR("vout", 3),
 384        PMBUS_REGULATOR("vout", 4),
 385        PMBUS_REGULATOR("vout", 5),
 386        PMBUS_REGULATOR("vout", 6),
 387        PMBUS_REGULATOR("vout", 7),
 388};
 389#endif /* CONFIG_SENSORS_LTC2978_REGULATOR */
 390
 391static int ltc2978_probe(struct i2c_client *client,
 392                         const struct i2c_device_id *id)
 393{
 394        int chip_id, i;
 395        struct ltc2978_data *data;
 396        struct pmbus_driver_info *info;
 397
 398        if (!i2c_check_functionality(client->adapter,
 399                                     I2C_FUNC_SMBUS_READ_WORD_DATA))
 400                return -ENODEV;
 401
 402        data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
 403                            GFP_KERNEL);
 404        if (!data)
 405                return -ENOMEM;
 406
 407        chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID);
 408        if (chip_id < 0)
 409                return chip_id;
 410
 411        if (chip_id == LTC2974_ID_REV1 || chip_id == LTC2974_ID_REV2) {
 412                data->id = ltc2974;
 413        } else if (chip_id == LTC2977_ID) {
 414                data->id = ltc2977;
 415        } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 ||
 416                   chip_id == LTC2978A_ID) {
 417                data->id = ltc2978;
 418        } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) {
 419                data->id = ltc3880;
 420        } else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID) {
 421                data->id = ltc3883;
 422        } else if ((chip_id & LTM4676_ID_MASK) == LTM4676_ID) {
 423                data->id = ltm4676;
 424        } else {
 425                dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
 426                return -ENODEV;
 427        }
 428        if (data->id != id->driver_data)
 429                dev_warn(&client->dev,
 430                         "Device mismatch: Configured %s, detected %s\n",
 431                         id->name,
 432                         ltc2978_id[data->id].name);
 433
 434        info = &data->info;
 435        info->write_word_data = ltc2978_write_word_data;
 436
 437        data->vin_min = 0x7bff;
 438        data->vin_max = 0x7c00;
 439        for (i = 0; i < ARRAY_SIZE(data->vout_min); i++)
 440                data->vout_min[i] = 0xffff;
 441        for (i = 0; i < ARRAY_SIZE(data->iout_min); i++)
 442                data->iout_min[i] = 0xfbff;
 443        for (i = 0; i < ARRAY_SIZE(data->iout_max); i++)
 444                data->iout_max[i] = 0x7c00;
 445        for (i = 0; i < ARRAY_SIZE(data->temp_min); i++)
 446                data->temp_min[i] = 0x7bff;
 447        for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
 448                data->temp_max[i] = 0x7c00;
 449        data->temp2_max = 0x7c00;
 450
 451        switch (data->id) {
 452        case ltc2974:
 453                info->read_word_data = ltc2974_read_word_data;
 454                info->pages = LTC2974_NUM_PAGES;
 455                info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
 456                  | PMBUS_HAVE_TEMP2;
 457                for (i = 0; i < info->pages; i++) {
 458                        info->func[i] |= PMBUS_HAVE_VOUT
 459                          | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
 460                          | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
 461                          | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
 462                }
 463                break;
 464        case ltc2977:
 465        case ltc2978:
 466                info->read_word_data = ltc2978_read_word_data;
 467                info->pages = LTC2978_NUM_PAGES;
 468                info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
 469                  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
 470                  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 471                for (i = 1; i < LTC2978_NUM_PAGES; i++) {
 472                        info->func[i] = PMBUS_HAVE_VOUT
 473                          | PMBUS_HAVE_STATUS_VOUT;
 474                }
 475                break;
 476        case ltc3880:
 477        case ltm4676:
 478                info->read_word_data = ltc3880_read_word_data;
 479                info->pages = LTC3880_NUM_PAGES;
 480                info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
 481                  | PMBUS_HAVE_STATUS_INPUT
 482                  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
 483                  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
 484                  | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
 485                  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
 486                info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
 487                  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
 488                  | PMBUS_HAVE_POUT
 489                  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 490                break;
 491        case ltc3883:
 492                info->read_word_data = ltc3883_read_word_data;
 493                info->pages = LTC3883_NUM_PAGES;
 494                info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
 495                  | PMBUS_HAVE_STATUS_INPUT
 496                  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
 497                  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
 498                  | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
 499                  | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
 500                break;
 501        default:
 502                return -ENODEV;
 503        }
 504
 505#if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR)
 506        info->num_regulators = info->pages;
 507        info->reg_desc = ltc2978_reg_desc;
 508        if (info->num_regulators > ARRAY_SIZE(ltc2978_reg_desc)) {
 509                dev_err(&client->dev, "num_regulators too large!");
 510                info->num_regulators = ARRAY_SIZE(ltc2978_reg_desc);
 511        }
 512#endif
 513
 514        return pmbus_do_probe(client, id, info);
 515}
 516
 517#ifdef CONFIG_OF
 518static const struct of_device_id ltc2978_of_match[] = {
 519        { .compatible = "lltc,ltc2974" },
 520        { .compatible = "lltc,ltc2977" },
 521        { .compatible = "lltc,ltc2978" },
 522        { .compatible = "lltc,ltc3880" },
 523        { .compatible = "lltc,ltc3883" },
 524        { .compatible = "lltc,ltm4676" },
 525        { }
 526};
 527MODULE_DEVICE_TABLE(of, ltc2978_of_match);
 528#endif
 529
 530static struct i2c_driver ltc2978_driver = {
 531        .driver = {
 532                   .name = "ltc2978",
 533                   .of_match_table = of_match_ptr(ltc2978_of_match),
 534                   },
 535        .probe = ltc2978_probe,
 536        .remove = pmbus_do_remove,
 537        .id_table = ltc2978_id,
 538};
 539
 540module_i2c_driver(ltc2978_driver);
 541
 542MODULE_AUTHOR("Guenter Roeck");
 543MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, LTC3883, and LTM4676");
 544MODULE_LICENSE("GPL");
 545