root/drivers/hwmon/lineage-pem.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pem_read_block
  2. pem_update_device
  3. pem_get_data
  4. pem_get_input
  5. pem_get_fan
  6. pem_bool_show
  7. pem_data_show
  8. pem_input_show
  9. pem_fan_show
  10. pem_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Driver for Lineage Compact Power Line series of power entry modules.
   4  *
   5  * Copyright (C) 2010, 2011 Ericsson AB.
   6  *
   7  * Documentation:
   8  *  http://www.lineagepower.com/oem/pdf/CPLI2C.pdf
   9  */
  10 
  11 #include <linux/kernel.h>
  12 #include <linux/module.h>
  13 #include <linux/init.h>
  14 #include <linux/err.h>
  15 #include <linux/slab.h>
  16 #include <linux/i2c.h>
  17 #include <linux/hwmon.h>
  18 #include <linux/hwmon-sysfs.h>
  19 #include <linux/jiffies.h>
  20 
  21 /*
  22  * This driver supports various Lineage Compact Power Line DC/DC and AC/DC
  23  * converters such as CP1800, CP2000AC, CP2000DC, CP2100DC, and others.
  24  *
  25  * The devices are nominally PMBus compliant. However, most standard PMBus
  26  * commands are not supported. Specifically, all hardware monitoring and
  27  * status reporting commands are non-standard. For this reason, a standard
  28  * PMBus driver can not be used.
  29  *
  30  * All Lineage CPL devices have a built-in I2C bus master selector (PCA9541).
  31  * To ensure device access, this driver should only be used as client driver
  32  * to the pca9541 I2C master selector driver.
  33  */
  34 
  35 /* Command codes */
  36 #define PEM_OPERATION           0x01
  37 #define PEM_CLEAR_INFO_FLAGS    0x03
  38 #define PEM_VOUT_COMMAND        0x21
  39 #define PEM_VOUT_OV_FAULT_LIMIT 0x40
  40 #define PEM_READ_DATA_STRING    0xd0
  41 #define PEM_READ_INPUT_STRING   0xdc
  42 #define PEM_READ_FIRMWARE_REV   0xdd
  43 #define PEM_READ_RUN_TIMER      0xde
  44 #define PEM_FAN_HI_SPEED        0xdf
  45 #define PEM_FAN_NORMAL_SPEED    0xe0
  46 #define PEM_READ_FAN_SPEED      0xe1
  47 
  48 /* offsets in data string */
  49 #define PEM_DATA_STATUS_2       0
  50 #define PEM_DATA_STATUS_1       1
  51 #define PEM_DATA_ALARM_2        2
  52 #define PEM_DATA_ALARM_1        3
  53 #define PEM_DATA_VOUT_LSB       4
  54 #define PEM_DATA_VOUT_MSB       5
  55 #define PEM_DATA_CURRENT        6
  56 #define PEM_DATA_TEMP           7
  57 
  58 /* Virtual entries, to report constants */
  59 #define PEM_DATA_TEMP_MAX       10
  60 #define PEM_DATA_TEMP_CRIT      11
  61 
  62 /* offsets in input string */
  63 #define PEM_INPUT_VOLTAGE       0
  64 #define PEM_INPUT_POWER_LSB     1
  65 #define PEM_INPUT_POWER_MSB     2
  66 
  67 /* offsets in fan data */
  68 #define PEM_FAN_ADJUSTMENT      0
  69 #define PEM_FAN_FAN1            1
  70 #define PEM_FAN_FAN2            2
  71 #define PEM_FAN_FAN3            3
  72 
  73 /* Status register bits */
  74 #define STS1_OUTPUT_ON          (1 << 0)
  75 #define STS1_LEDS_FLASHING      (1 << 1)
  76 #define STS1_EXT_FAULT          (1 << 2)
  77 #define STS1_SERVICE_LED_ON     (1 << 3)
  78 #define STS1_SHUTDOWN_OCCURRED  (1 << 4)
  79 #define STS1_INT_FAULT          (1 << 5)
  80 #define STS1_ISOLATION_TEST_OK  (1 << 6)
  81 
  82 #define STS2_ENABLE_PIN_HI      (1 << 0)
  83 #define STS2_DATA_OUT_RANGE     (1 << 1)
  84 #define STS2_RESTARTED_OK       (1 << 1)
  85 #define STS2_ISOLATION_TEST_FAIL (1 << 3)
  86 #define STS2_HIGH_POWER_CAP     (1 << 4)
  87 #define STS2_INVALID_INSTR      (1 << 5)
  88 #define STS2_WILL_RESTART       (1 << 6)
  89 #define STS2_PEC_ERR            (1 << 7)
  90 
  91 /* Alarm register bits */
  92 #define ALRM1_VIN_OUT_LIMIT     (1 << 0)
  93 #define ALRM1_VOUT_OUT_LIMIT    (1 << 1)
  94 #define ALRM1_OV_VOLT_SHUTDOWN  (1 << 2)
  95 #define ALRM1_VIN_OVERCURRENT   (1 << 3)
  96 #define ALRM1_TEMP_WARNING      (1 << 4)
  97 #define ALRM1_TEMP_SHUTDOWN     (1 << 5)
  98 #define ALRM1_PRIMARY_FAULT     (1 << 6)
  99 #define ALRM1_POWER_LIMIT       (1 << 7)
 100 
 101 #define ALRM2_5V_OUT_LIMIT      (1 << 1)
 102 #define ALRM2_TEMP_FAULT        (1 << 2)
 103 #define ALRM2_OV_LOW            (1 << 3)
 104 #define ALRM2_DCDC_TEMP_HIGH    (1 << 4)
 105 #define ALRM2_PRI_TEMP_HIGH     (1 << 5)
 106 #define ALRM2_NO_PRIMARY        (1 << 6)
 107 #define ALRM2_FAN_FAULT         (1 << 7)
 108 
 109 #define FIRMWARE_REV_LEN        4
 110 #define DATA_STRING_LEN         9
 111 #define INPUT_STRING_LEN        5       /* 4 for most devices   */
 112 #define FAN_SPEED_LEN           5
 113 
 114 struct pem_data {
 115         struct i2c_client *client;
 116         const struct attribute_group *groups[4];
 117 
 118         struct mutex update_lock;
 119         bool valid;
 120         bool fans_supported;
 121         int input_length;
 122         unsigned long last_updated;     /* in jiffies */
 123 
 124         u8 firmware_rev[FIRMWARE_REV_LEN];
 125         u8 data_string[DATA_STRING_LEN];
 126         u8 input_string[INPUT_STRING_LEN];
 127         u8 fan_speed[FAN_SPEED_LEN];
 128 };
 129 
 130 static int pem_read_block(struct i2c_client *client, u8 command, u8 *data,
 131                           int data_len)
 132 {
 133         u8 block_buffer[I2C_SMBUS_BLOCK_MAX];
 134         int result;
 135 
 136         result = i2c_smbus_read_block_data(client, command, block_buffer);
 137         if (unlikely(result < 0))
 138                 goto abort;
 139         if (unlikely(result == 0xff || result != data_len)) {
 140                 result = -EIO;
 141                 goto abort;
 142         }
 143         memcpy(data, block_buffer, data_len);
 144         result = 0;
 145 abort:
 146         return result;
 147 }
 148 
 149 static struct pem_data *pem_update_device(struct device *dev)
 150 {
 151         struct pem_data *data = dev_get_drvdata(dev);
 152         struct i2c_client *client = data->client;
 153         struct pem_data *ret = data;
 154 
 155         mutex_lock(&data->update_lock);
 156 
 157         if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
 158                 int result;
 159 
 160                 /* Read data string */
 161                 result = pem_read_block(client, PEM_READ_DATA_STRING,
 162                                         data->data_string,
 163                                         sizeof(data->data_string));
 164                 if (unlikely(result < 0)) {
 165                         ret = ERR_PTR(result);
 166                         goto abort;
 167                 }
 168 
 169                 /* Read input string */
 170                 if (data->input_length) {
 171                         result = pem_read_block(client, PEM_READ_INPUT_STRING,
 172                                                 data->input_string,
 173                                                 data->input_length);
 174                         if (unlikely(result < 0)) {
 175                                 ret = ERR_PTR(result);
 176                                 goto abort;
 177                         }
 178                 }
 179 
 180                 /* Read fan speeds */
 181                 if (data->fans_supported) {
 182                         result = pem_read_block(client, PEM_READ_FAN_SPEED,
 183                                                 data->fan_speed,
 184                                                 sizeof(data->fan_speed));
 185                         if (unlikely(result < 0)) {
 186                                 ret = ERR_PTR(result);
 187                                 goto abort;
 188                         }
 189                 }
 190 
 191                 i2c_smbus_write_byte(client, PEM_CLEAR_INFO_FLAGS);
 192 
 193                 data->last_updated = jiffies;
 194                 data->valid = 1;
 195         }
 196 abort:
 197         mutex_unlock(&data->update_lock);
 198         return ret;
 199 }
 200 
 201 static long pem_get_data(u8 *data, int len, int index)
 202 {
 203         long val;
 204 
 205         switch (index) {
 206         case PEM_DATA_VOUT_LSB:
 207                 val = (data[index] + (data[index+1] << 8)) * 5 / 2;
 208                 break;
 209         case PEM_DATA_CURRENT:
 210                 val = data[index] * 200;
 211                 break;
 212         case PEM_DATA_TEMP:
 213                 val = data[index] * 1000;
 214                 break;
 215         case PEM_DATA_TEMP_MAX:
 216                 val = 97 * 1000;        /* 97 degrees C per datasheet */
 217                 break;
 218         case PEM_DATA_TEMP_CRIT:
 219                 val = 107 * 1000;       /* 107 degrees C per datasheet */
 220                 break;
 221         default:
 222                 WARN_ON_ONCE(1);
 223                 val = 0;
 224         }
 225         return val;
 226 }
 227 
 228 static long pem_get_input(u8 *data, int len, int index)
 229 {
 230         long val;
 231 
 232         switch (index) {
 233         case PEM_INPUT_VOLTAGE:
 234                 if (len == INPUT_STRING_LEN)
 235                         val = (data[index] + (data[index+1] << 8) - 75) * 1000;
 236                 else
 237                         val = (data[index] - 75) * 1000;
 238                 break;
 239         case PEM_INPUT_POWER_LSB:
 240                 if (len == INPUT_STRING_LEN)
 241                         index++;
 242                 val = (data[index] + (data[index+1] << 8)) * 1000000L;
 243                 break;
 244         default:
 245                 WARN_ON_ONCE(1);
 246                 val = 0;
 247         }
 248         return val;
 249 }
 250 
 251 static long pem_get_fan(u8 *data, int len, int index)
 252 {
 253         long val;
 254 
 255         switch (index) {
 256         case PEM_FAN_FAN1:
 257         case PEM_FAN_FAN2:
 258         case PEM_FAN_FAN3:
 259                 val = data[index] * 100;
 260                 break;
 261         default:
 262                 WARN_ON_ONCE(1);
 263                 val = 0;
 264         }
 265         return val;
 266 }
 267 
 268 /*
 269  * Show boolean, either a fault or an alarm.
 270  * .nr points to the register, .index is the bit mask to check
 271  */
 272 static ssize_t pem_bool_show(struct device *dev, struct device_attribute *da,
 273                              char *buf)
 274 {
 275         struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
 276         struct pem_data *data = pem_update_device(dev);
 277         u8 status;
 278 
 279         if (IS_ERR(data))
 280                 return PTR_ERR(data);
 281 
 282         status = data->data_string[attr->nr] & attr->index;
 283         return snprintf(buf, PAGE_SIZE, "%d\n", !!status);
 284 }
 285 
 286 static ssize_t pem_data_show(struct device *dev, struct device_attribute *da,
 287                              char *buf)
 288 {
 289         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 290         struct pem_data *data = pem_update_device(dev);
 291         long value;
 292 
 293         if (IS_ERR(data))
 294                 return PTR_ERR(data);
 295 
 296         value = pem_get_data(data->data_string, sizeof(data->data_string),
 297                              attr->index);
 298 
 299         return snprintf(buf, PAGE_SIZE, "%ld\n", value);
 300 }
 301 
 302 static ssize_t pem_input_show(struct device *dev, struct device_attribute *da,
 303                               char *buf)
 304 {
 305         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 306         struct pem_data *data = pem_update_device(dev);
 307         long value;
 308 
 309         if (IS_ERR(data))
 310                 return PTR_ERR(data);
 311 
 312         value = pem_get_input(data->input_string, sizeof(data->input_string),
 313                               attr->index);
 314 
 315         return snprintf(buf, PAGE_SIZE, "%ld\n", value);
 316 }
 317 
 318 static ssize_t pem_fan_show(struct device *dev, struct device_attribute *da,
 319                             char *buf)
 320 {
 321         struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 322         struct pem_data *data = pem_update_device(dev);
 323         long value;
 324 
 325         if (IS_ERR(data))
 326                 return PTR_ERR(data);
 327 
 328         value = pem_get_fan(data->fan_speed, sizeof(data->fan_speed),
 329                             attr->index);
 330 
 331         return snprintf(buf, PAGE_SIZE, "%ld\n", value);
 332 }
 333 
 334 /* Voltages */
 335 static SENSOR_DEVICE_ATTR_RO(in1_input, pem_data, PEM_DATA_VOUT_LSB);
 336 static SENSOR_DEVICE_ATTR_2_RO(in1_alarm, pem_bool, PEM_DATA_ALARM_1,
 337                                ALRM1_VOUT_OUT_LIMIT);
 338 static SENSOR_DEVICE_ATTR_2_RO(in1_crit_alarm, pem_bool, PEM_DATA_ALARM_1,
 339                                ALRM1_OV_VOLT_SHUTDOWN);
 340 static SENSOR_DEVICE_ATTR_RO(in2_input, pem_input, PEM_INPUT_VOLTAGE);
 341 static SENSOR_DEVICE_ATTR_2_RO(in2_alarm, pem_bool, PEM_DATA_ALARM_1,
 342                                ALRM1_VIN_OUT_LIMIT | ALRM1_PRIMARY_FAULT);
 343 
 344 /* Currents */
 345 static SENSOR_DEVICE_ATTR_RO(curr1_input, pem_data, PEM_DATA_CURRENT);
 346 static SENSOR_DEVICE_ATTR_2_RO(curr1_alarm, pem_bool, PEM_DATA_ALARM_1,
 347                                ALRM1_VIN_OVERCURRENT);
 348 
 349 /* Power */
 350 static SENSOR_DEVICE_ATTR_RO(power1_input, pem_input, PEM_INPUT_POWER_LSB);
 351 static SENSOR_DEVICE_ATTR_2_RO(power1_alarm, pem_bool, PEM_DATA_ALARM_1,
 352                                ALRM1_POWER_LIMIT);
 353 
 354 /* Fans */
 355 static SENSOR_DEVICE_ATTR_RO(fan1_input, pem_fan, PEM_FAN_FAN1);
 356 static SENSOR_DEVICE_ATTR_RO(fan2_input, pem_fan, PEM_FAN_FAN2);
 357 static SENSOR_DEVICE_ATTR_RO(fan3_input, pem_fan, PEM_FAN_FAN3);
 358 static SENSOR_DEVICE_ATTR_2_RO(fan1_alarm, pem_bool, PEM_DATA_ALARM_2,
 359                                ALRM2_FAN_FAULT);
 360 
 361 /* Temperatures */
 362 static SENSOR_DEVICE_ATTR_RO(temp1_input, pem_data, PEM_DATA_TEMP);
 363 static SENSOR_DEVICE_ATTR_RO(temp1_max, pem_data, PEM_DATA_TEMP_MAX);
 364 static SENSOR_DEVICE_ATTR_RO(temp1_crit, pem_data, PEM_DATA_TEMP_CRIT);
 365 static SENSOR_DEVICE_ATTR_2_RO(temp1_alarm, pem_bool, PEM_DATA_ALARM_1,
 366                                ALRM1_TEMP_WARNING);
 367 static SENSOR_DEVICE_ATTR_2_RO(temp1_crit_alarm, pem_bool, PEM_DATA_ALARM_1,
 368                                ALRM1_TEMP_SHUTDOWN);
 369 static SENSOR_DEVICE_ATTR_2_RO(temp1_fault, pem_bool, PEM_DATA_ALARM_2,
 370                                ALRM2_TEMP_FAULT);
 371 
 372 static struct attribute *pem_attributes[] = {
 373         &sensor_dev_attr_in1_input.dev_attr.attr,
 374         &sensor_dev_attr_in1_alarm.dev_attr.attr,
 375         &sensor_dev_attr_in1_crit_alarm.dev_attr.attr,
 376         &sensor_dev_attr_in2_alarm.dev_attr.attr,
 377 
 378         &sensor_dev_attr_curr1_alarm.dev_attr.attr,
 379 
 380         &sensor_dev_attr_power1_alarm.dev_attr.attr,
 381 
 382         &sensor_dev_attr_fan1_alarm.dev_attr.attr,
 383 
 384         &sensor_dev_attr_temp1_input.dev_attr.attr,
 385         &sensor_dev_attr_temp1_max.dev_attr.attr,
 386         &sensor_dev_attr_temp1_crit.dev_attr.attr,
 387         &sensor_dev_attr_temp1_alarm.dev_attr.attr,
 388         &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
 389         &sensor_dev_attr_temp1_fault.dev_attr.attr,
 390 
 391         NULL,
 392 };
 393 
 394 static const struct attribute_group pem_group = {
 395         .attrs = pem_attributes,
 396 };
 397 
 398 static struct attribute *pem_input_attributes[] = {
 399         &sensor_dev_attr_in2_input.dev_attr.attr,
 400         &sensor_dev_attr_curr1_input.dev_attr.attr,
 401         &sensor_dev_attr_power1_input.dev_attr.attr,
 402         NULL
 403 };
 404 
 405 static const struct attribute_group pem_input_group = {
 406         .attrs = pem_input_attributes,
 407 };
 408 
 409 static struct attribute *pem_fan_attributes[] = {
 410         &sensor_dev_attr_fan1_input.dev_attr.attr,
 411         &sensor_dev_attr_fan2_input.dev_attr.attr,
 412         &sensor_dev_attr_fan3_input.dev_attr.attr,
 413         NULL
 414 };
 415 
 416 static const struct attribute_group pem_fan_group = {
 417         .attrs = pem_fan_attributes,
 418 };
 419 
 420 static int pem_probe(struct i2c_client *client,
 421                      const struct i2c_device_id *id)
 422 {
 423         struct i2c_adapter *adapter = client->adapter;
 424         struct device *dev = &client->dev;
 425         struct device *hwmon_dev;
 426         struct pem_data *data;
 427         int ret, idx = 0;
 428 
 429         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_DATA
 430                                      | I2C_FUNC_SMBUS_WRITE_BYTE))
 431                 return -ENODEV;
 432 
 433         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 434         if (!data)
 435                 return -ENOMEM;
 436 
 437         data->client = client;
 438         mutex_init(&data->update_lock);
 439 
 440         /*
 441          * We use the next two commands to determine if the device is really
 442          * there.
 443          */
 444         ret = pem_read_block(client, PEM_READ_FIRMWARE_REV,
 445                              data->firmware_rev, sizeof(data->firmware_rev));
 446         if (ret < 0)
 447                 return ret;
 448 
 449         ret = i2c_smbus_write_byte(client, PEM_CLEAR_INFO_FLAGS);
 450         if (ret < 0)
 451                 return ret;
 452 
 453         dev_info(dev, "Firmware revision %d.%d.%d\n",
 454                  data->firmware_rev[0], data->firmware_rev[1],
 455                  data->firmware_rev[2]);
 456 
 457         /* sysfs hooks */
 458         data->groups[idx++] = &pem_group;
 459 
 460         /*
 461          * Check if input readings are supported.
 462          * This is the case if we can read input data,
 463          * and if the returned data is not all zeros.
 464          * Note that input alarms are always supported.
 465          */
 466         ret = pem_read_block(client, PEM_READ_INPUT_STRING,
 467                              data->input_string,
 468                              sizeof(data->input_string) - 1);
 469         if (!ret && (data->input_string[0] || data->input_string[1] ||
 470                      data->input_string[2]))
 471                 data->input_length = sizeof(data->input_string) - 1;
 472         else if (ret < 0) {
 473                 /* Input string is one byte longer for some devices */
 474                 ret = pem_read_block(client, PEM_READ_INPUT_STRING,
 475                                     data->input_string,
 476                                     sizeof(data->input_string));
 477                 if (!ret && (data->input_string[0] || data->input_string[1] ||
 478                             data->input_string[2] || data->input_string[3]))
 479                         data->input_length = sizeof(data->input_string);
 480         }
 481 
 482         if (data->input_length)
 483                 data->groups[idx++] = &pem_input_group;
 484 
 485         /*
 486          * Check if fan speed readings are supported.
 487          * This is the case if we can read fan speed data,
 488          * and if the returned data is not all zeros.
 489          * Note that the fan alarm is always supported.
 490          */
 491         ret = pem_read_block(client, PEM_READ_FAN_SPEED,
 492                              data->fan_speed,
 493                              sizeof(data->fan_speed));
 494         if (!ret && (data->fan_speed[0] || data->fan_speed[1] ||
 495                      data->fan_speed[2] || data->fan_speed[3])) {
 496                 data->fans_supported = true;
 497                 data->groups[idx++] = &pem_fan_group;
 498         }
 499 
 500         hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 501                                                            data, data->groups);
 502         return PTR_ERR_OR_ZERO(hwmon_dev);
 503 }
 504 
 505 static const struct i2c_device_id pem_id[] = {
 506         {"lineage_pem", 0},
 507         {}
 508 };
 509 MODULE_DEVICE_TABLE(i2c, pem_id);
 510 
 511 static struct i2c_driver pem_driver = {
 512         .driver = {
 513                    .name = "lineage_pem",
 514                    },
 515         .probe = pem_probe,
 516         .id_table = pem_id,
 517 };
 518 
 519 module_i2c_driver(pem_driver);
 520 
 521 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
 522 MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver");
 523 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */