linux/drivers/hwmon/pmbus/lm25066.c
<<
>>
Prefs
   1/*
   2 * Hardware monitoring driver for LM25056 / LM25063 / LM25066 / LM5064 / LM5066
   3 *
   4 * Copyright (c) 2011 Ericsson AB.
   5 * Copyright (c) 2013 Guenter Roeck
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include <linux/bitops.h>
  23#include <linux/kernel.h>
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/err.h>
  27#include <linux/slab.h>
  28#include <linux/i2c.h>
  29#include "pmbus.h"
  30
  31enum chips { lm25056, lm25063, lm25066, lm5064, lm5066, lm5066i };
  32
  33#define LM25066_READ_VAUX               0xd0
  34#define LM25066_MFR_READ_IIN            0xd1
  35#define LM25066_MFR_READ_PIN            0xd2
  36#define LM25066_MFR_IIN_OC_WARN_LIMIT   0xd3
  37#define LM25066_MFR_PIN_OP_WARN_LIMIT   0xd4
  38#define LM25066_READ_PIN_PEAK           0xd5
  39#define LM25066_CLEAR_PIN_PEAK          0xd6
  40#define LM25066_DEVICE_SETUP            0xd9
  41#define LM25066_READ_AVG_VIN            0xdc
  42#define LM25066_READ_AVG_VOUT           0xdd
  43#define LM25066_READ_AVG_IIN            0xde
  44#define LM25066_READ_AVG_PIN            0xdf
  45
  46#define LM25066_DEV_SETUP_CL            BIT(4)  /* Current limit */
  47
  48/* LM25056 only */
  49
  50#define LM25056_VAUX_OV_WARN_LIMIT      0xe3
  51#define LM25056_VAUX_UV_WARN_LIMIT      0xe4
  52
  53#define LM25056_MFR_STS_VAUX_OV_WARN    BIT(1)
  54#define LM25056_MFR_STS_VAUX_UV_WARN    BIT(0)
  55
  56/* LM25063 only */
  57
  58#define LM25063_READ_VOUT_MAX           0xe5
  59#define LM25063_READ_VOUT_MIN           0xe6
  60
  61struct __coeff {
  62        short m, b, R;
  63};
  64
  65#define PSC_CURRENT_IN_L        (PSC_NUM_CLASSES)
  66#define PSC_POWER_L             (PSC_NUM_CLASSES + 1)
  67
  68static struct __coeff lm25066_coeff[6][PSC_NUM_CLASSES + 2] = {
  69        [lm25056] = {
  70                [PSC_VOLTAGE_IN] = {
  71                        .m = 16296,
  72                        .R = -2,
  73                },
  74                [PSC_CURRENT_IN] = {
  75                        .m = 13797,
  76                        .R = -2,
  77                },
  78                [PSC_CURRENT_IN_L] = {
  79                        .m = 6726,
  80                        .R = -2,
  81                },
  82                [PSC_POWER] = {
  83                        .m = 5501,
  84                        .R = -3,
  85                },
  86                [PSC_POWER_L] = {
  87                        .m = 26882,
  88                        .R = -4,
  89                },
  90                [PSC_TEMPERATURE] = {
  91                        .m = 1580,
  92                        .b = -14500,
  93                        .R = -2,
  94                },
  95        },
  96        [lm25066] = {
  97                [PSC_VOLTAGE_IN] = {
  98                        .m = 22070,
  99                        .R = -2,
 100                },
 101                [PSC_VOLTAGE_OUT] = {
 102                        .m = 22070,
 103                        .R = -2,
 104                },
 105                [PSC_CURRENT_IN] = {
 106                        .m = 13661,
 107                        .R = -2,
 108                },
 109                [PSC_CURRENT_IN_L] = {
 110                        .m = 6852,
 111                        .R = -2,
 112                },
 113                [PSC_POWER] = {
 114                        .m = 736,
 115                        .R = -2,
 116                },
 117                [PSC_POWER_L] = {
 118                        .m = 369,
 119                        .R = -2,
 120                },
 121                [PSC_TEMPERATURE] = {
 122                        .m = 16,
 123                },
 124        },
 125        [lm25063] = {
 126                [PSC_VOLTAGE_IN] = {
 127                        .m = 16000,
 128                        .R = -2,
 129                },
 130                [PSC_VOLTAGE_OUT] = {
 131                        .m = 16000,
 132                        .R = -2,
 133                },
 134                [PSC_CURRENT_IN] = {
 135                        .m = 10000,
 136                        .R = -2,
 137                },
 138                [PSC_CURRENT_IN_L] = {
 139                        .m = 10000,
 140                        .R = -2,
 141                },
 142                [PSC_POWER] = {
 143                        .m = 5000,
 144                        .R = -3,
 145                },
 146                [PSC_POWER_L] = {
 147                        .m = 5000,
 148                        .R = -3,
 149                },
 150                [PSC_TEMPERATURE] = {
 151                        .m = 15596,
 152                        .R = -3,
 153                },
 154        },
 155        [lm5064] = {
 156                [PSC_VOLTAGE_IN] = {
 157                        .m = 4611,
 158                        .R = -2,
 159                },
 160                [PSC_VOLTAGE_OUT] = {
 161                        .m = 4621,
 162                        .R = -2,
 163                },
 164                [PSC_CURRENT_IN] = {
 165                        .m = 10742,
 166                        .R = -2,
 167                },
 168                [PSC_CURRENT_IN_L] = {
 169                        .m = 5456,
 170                        .R = -2,
 171                },
 172                [PSC_POWER] = {
 173                        .m = 1204,
 174                        .R = -3,
 175                },
 176                [PSC_POWER_L] = {
 177                        .m = 612,
 178                        .R = -3,
 179                },
 180                [PSC_TEMPERATURE] = {
 181                        .m = 16,
 182                },
 183        },
 184        [lm5066] = {
 185                [PSC_VOLTAGE_IN] = {
 186                        .m = 4587,
 187                        .R = -2,
 188                },
 189                [PSC_VOLTAGE_OUT] = {
 190                        .m = 4587,
 191                        .R = -2,
 192                },
 193                [PSC_CURRENT_IN] = {
 194                        .m = 10753,
 195                        .R = -2,
 196                },
 197                [PSC_CURRENT_IN_L] = {
 198                        .m = 5405,
 199                        .R = -2,
 200                },
 201                [PSC_POWER] = {
 202                        .m = 1204,
 203                        .R = -3,
 204                },
 205                [PSC_POWER_L] = {
 206                        .m = 605,
 207                        .R = -3,
 208                },
 209                [PSC_TEMPERATURE] = {
 210                        .m = 16,
 211                },
 212        },
 213        [lm5066i] = {
 214                [PSC_VOLTAGE_IN] = {
 215                        .m = 4617,
 216                        .b = -140,
 217                        .R = -2,
 218                },
 219                [PSC_VOLTAGE_OUT] = {
 220                        .m = 4602,
 221                        .b = 500,
 222                        .R = -2,
 223                },
 224                [PSC_CURRENT_IN] = {
 225                        .m = 15076,
 226                        .b = -504,
 227                        .R = -2,
 228                },
 229                [PSC_CURRENT_IN_L] = {
 230                        .m = 7645,
 231                        .b = 100,
 232                        .R = -2,
 233                },
 234                [PSC_POWER] = {
 235                        .m = 1701,
 236                        .b = -4000,
 237                        .R = -3,
 238                },
 239                [PSC_POWER_L] = {
 240                        .m = 861,
 241                        .b = -965,
 242                        .R = -3,
 243                },
 244                [PSC_TEMPERATURE] = {
 245                        .m = 16,
 246                },
 247        },
 248};
 249
 250struct lm25066_data {
 251        int id;
 252        u16 rlimit;                     /* Maximum register value */
 253        struct pmbus_driver_info info;
 254};
 255
 256#define to_lm25066_data(x)  container_of(x, struct lm25066_data, info)
 257
 258static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
 259{
 260        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 261        const struct lm25066_data *data = to_lm25066_data(info);
 262        int ret;
 263
 264        switch (reg) {
 265        case PMBUS_VIRT_READ_VMON:
 266                ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX);
 267                if (ret < 0)
 268                        break;
 269                /* Adjust returned value to match VIN coefficients */
 270                switch (data->id) {
 271                case lm25056:
 272                        /* VIN: 6.14 mV VAUX: 293 uV LSB */
 273                        ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
 274                        break;
 275                case lm25063:
 276                        /* VIN: 6.25 mV VAUX: 200.0 uV LSB */
 277                        ret = DIV_ROUND_CLOSEST(ret * 20, 625);
 278                        break;
 279                case lm25066:
 280                        /* VIN: 4.54 mV VAUX: 283.2 uV LSB */
 281                        ret = DIV_ROUND_CLOSEST(ret * 2832, 45400);
 282                        break;
 283                case lm5064:
 284                        /* VIN: 4.53 mV VAUX: 700 uV LSB */
 285                        ret = DIV_ROUND_CLOSEST(ret * 70, 453);
 286                        break;
 287                case lm5066:
 288                case lm5066i:
 289                        /* VIN: 2.18 mV VAUX: 725 uV LSB */
 290                        ret = DIV_ROUND_CLOSEST(ret * 725, 2180);
 291                        break;
 292                }
 293                break;
 294        case PMBUS_READ_IIN:
 295                ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN);
 296                break;
 297        case PMBUS_READ_PIN:
 298                ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN);
 299                break;
 300        case PMBUS_IIN_OC_WARN_LIMIT:
 301                ret = pmbus_read_word_data(client, 0,
 302                                           LM25066_MFR_IIN_OC_WARN_LIMIT);
 303                break;
 304        case PMBUS_PIN_OP_WARN_LIMIT:
 305                ret = pmbus_read_word_data(client, 0,
 306                                           LM25066_MFR_PIN_OP_WARN_LIMIT);
 307                break;
 308        case PMBUS_VIRT_READ_VIN_AVG:
 309                ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN);
 310                break;
 311        case PMBUS_VIRT_READ_VOUT_AVG:
 312                ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT);
 313                break;
 314        case PMBUS_VIRT_READ_IIN_AVG:
 315                ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN);
 316                break;
 317        case PMBUS_VIRT_READ_PIN_AVG:
 318                ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN);
 319                break;
 320        case PMBUS_VIRT_READ_PIN_MAX:
 321                ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK);
 322                break;
 323        case PMBUS_VIRT_RESET_PIN_HISTORY:
 324                ret = 0;
 325                break;
 326        default:
 327                ret = -ENODATA;
 328                break;
 329        }
 330        return ret;
 331}
 332
 333static int lm25063_read_word_data(struct i2c_client *client, int page, int reg)
 334{
 335        int ret;
 336
 337        switch (reg) {
 338        case PMBUS_VIRT_READ_VOUT_MAX:
 339                ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MAX);
 340                break;
 341        case PMBUS_VIRT_READ_VOUT_MIN:
 342                ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MIN);
 343                break;
 344        default:
 345                ret = lm25066_read_word_data(client, page, reg);
 346                break;
 347        }
 348        return ret;
 349}
 350
 351static int lm25056_read_word_data(struct i2c_client *client, int page, int reg)
 352{
 353        int ret;
 354
 355        switch (reg) {
 356        case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
 357                ret = pmbus_read_word_data(client, 0,
 358                                           LM25056_VAUX_UV_WARN_LIMIT);
 359                if (ret < 0)
 360                        break;
 361                /* Adjust returned value to match VIN coefficients */
 362                ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
 363                break;
 364        case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
 365                ret = pmbus_read_word_data(client, 0,
 366                                           LM25056_VAUX_OV_WARN_LIMIT);
 367                if (ret < 0)
 368                        break;
 369                /* Adjust returned value to match VIN coefficients */
 370                ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
 371                break;
 372        default:
 373                ret = lm25066_read_word_data(client, page, reg);
 374                break;
 375        }
 376        return ret;
 377}
 378
 379static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg)
 380{
 381        int ret, s;
 382
 383        switch (reg) {
 384        case PMBUS_VIRT_STATUS_VMON:
 385                ret = pmbus_read_byte_data(client, 0,
 386                                           PMBUS_STATUS_MFR_SPECIFIC);
 387                if (ret < 0)
 388                        break;
 389                s = 0;
 390                if (ret & LM25056_MFR_STS_VAUX_UV_WARN)
 391                        s |= PB_VOLTAGE_UV_WARNING;
 392                if (ret & LM25056_MFR_STS_VAUX_OV_WARN)
 393                        s |= PB_VOLTAGE_OV_WARNING;
 394                ret = s;
 395                break;
 396        default:
 397                ret = -ENODATA;
 398                break;
 399        }
 400        return ret;
 401}
 402
 403static int lm25066_write_word_data(struct i2c_client *client, int page, int reg,
 404                                   u16 word)
 405{
 406        const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 407        const struct lm25066_data *data = to_lm25066_data(info);
 408        int ret;
 409
 410        switch (reg) {
 411        case PMBUS_POUT_OP_FAULT_LIMIT:
 412        case PMBUS_POUT_OP_WARN_LIMIT:
 413        case PMBUS_VOUT_UV_WARN_LIMIT:
 414        case PMBUS_OT_FAULT_LIMIT:
 415        case PMBUS_OT_WARN_LIMIT:
 416        case PMBUS_IIN_OC_FAULT_LIMIT:
 417        case PMBUS_VIN_UV_WARN_LIMIT:
 418        case PMBUS_VIN_UV_FAULT_LIMIT:
 419        case PMBUS_VIN_OV_FAULT_LIMIT:
 420        case PMBUS_VIN_OV_WARN_LIMIT:
 421                word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
 422                ret = pmbus_write_word_data(client, 0, reg, word);
 423                pmbus_clear_cache(client);
 424                break;
 425        case PMBUS_IIN_OC_WARN_LIMIT:
 426                word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
 427                ret = pmbus_write_word_data(client, 0,
 428                                            LM25066_MFR_IIN_OC_WARN_LIMIT,
 429                                            word);
 430                pmbus_clear_cache(client);
 431                break;
 432        case PMBUS_PIN_OP_WARN_LIMIT:
 433                word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
 434                ret = pmbus_write_word_data(client, 0,
 435                                            LM25066_MFR_PIN_OP_WARN_LIMIT,
 436                                            word);
 437                pmbus_clear_cache(client);
 438                break;
 439        case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
 440                /* Adjust from VIN coefficients (for LM25056) */
 441                word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
 442                word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
 443                ret = pmbus_write_word_data(client, 0,
 444                                            LM25056_VAUX_UV_WARN_LIMIT, word);
 445                pmbus_clear_cache(client);
 446                break;
 447        case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
 448                /* Adjust from VIN coefficients (for LM25056) */
 449                word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
 450                word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
 451                ret = pmbus_write_word_data(client, 0,
 452                                            LM25056_VAUX_OV_WARN_LIMIT, word);
 453                pmbus_clear_cache(client);
 454                break;
 455        case PMBUS_VIRT_RESET_PIN_HISTORY:
 456                ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK);
 457                break;
 458        default:
 459                ret = -ENODATA;
 460                break;
 461        }
 462        return ret;
 463}
 464
 465static int lm25066_probe(struct i2c_client *client,
 466                          const struct i2c_device_id *id)
 467{
 468        int config;
 469        struct lm25066_data *data;
 470        struct pmbus_driver_info *info;
 471        struct __coeff *coeff;
 472
 473        if (!i2c_check_functionality(client->adapter,
 474                                     I2C_FUNC_SMBUS_READ_BYTE_DATA))
 475                return -ENODEV;
 476
 477        data = devm_kzalloc(&client->dev, sizeof(struct lm25066_data),
 478                            GFP_KERNEL);
 479        if (!data)
 480                return -ENOMEM;
 481
 482        config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP);
 483        if (config < 0)
 484                return config;
 485
 486        data->id = id->driver_data;
 487        info = &data->info;
 488
 489        info->pages = 1;
 490        info->format[PSC_VOLTAGE_IN] = direct;
 491        info->format[PSC_VOLTAGE_OUT] = direct;
 492        info->format[PSC_CURRENT_IN] = direct;
 493        info->format[PSC_TEMPERATURE] = direct;
 494        info->format[PSC_POWER] = direct;
 495
 496        info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON
 497          | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT
 498          | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 499
 500        if (data->id == lm25056) {
 501                info->func[0] |= PMBUS_HAVE_STATUS_VMON;
 502                info->read_word_data = lm25056_read_word_data;
 503                info->read_byte_data = lm25056_read_byte_data;
 504                data->rlimit = 0x0fff;
 505        } else if (data->id == lm25063) {
 506                info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
 507                  | PMBUS_HAVE_POUT;
 508                info->read_word_data = lm25063_read_word_data;
 509                data->rlimit = 0xffff;
 510        } else {
 511                info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
 512                info->read_word_data = lm25066_read_word_data;
 513                data->rlimit = 0x0fff;
 514        }
 515        info->write_word_data = lm25066_write_word_data;
 516
 517        coeff = &lm25066_coeff[data->id][0];
 518        info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m;
 519        info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b;
 520        info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R;
 521        info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m;
 522        info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b;
 523        info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R;
 524        info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m;
 525        info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b;
 526        info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R;
 527        info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R;
 528        info->R[PSC_POWER] = coeff[PSC_POWER].R;
 529        if (config & LM25066_DEV_SETUP_CL) {
 530                info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m;
 531                info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].b;
 532                info->m[PSC_POWER] = coeff[PSC_POWER_L].m;
 533                info->b[PSC_POWER] = coeff[PSC_POWER_L].b;
 534        } else {
 535                info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m;
 536                info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b;
 537                info->m[PSC_POWER] = coeff[PSC_POWER].m;
 538                info->b[PSC_POWER] = coeff[PSC_POWER].b;
 539        }
 540
 541        return pmbus_do_probe(client, id, info);
 542}
 543
 544static const struct i2c_device_id lm25066_id[] = {
 545        {"lm25056", lm25056},
 546        {"lm25063", lm25063},
 547        {"lm25066", lm25066},
 548        {"lm5064", lm5064},
 549        {"lm5066", lm5066},
 550        {"lm5066i", lm5066i},
 551        { }
 552};
 553
 554MODULE_DEVICE_TABLE(i2c, lm25066_id);
 555
 556/* This is the driver that will be inserted */
 557static struct i2c_driver lm25066_driver = {
 558        .driver = {
 559                   .name = "lm25066",
 560                   },
 561        .probe = lm25066_probe,
 562        .remove = pmbus_do_remove,
 563        .id_table = lm25066_id,
 564};
 565
 566module_i2c_driver(lm25066_driver);
 567
 568MODULE_AUTHOR("Guenter Roeck");
 569MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips");
 570MODULE_LICENSE("GPL");
 571