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