488 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W2014 * Copyright (C) 2011 Jean Delvare <jdelvare@suse.de>5 */6 7#include <linux/module.h>8#include <linux/init.h>9#include <linux/slab.h>10#include <linux/jiffies.h>11#include <linux/i2c.h>12#include <linux/hwmon.h>13#include <linux/hwmon-sysfs.h>14#include <linux/err.h>15#include <linux/mutex.h>16 17/*18 * Addresses to scan19 */20 21static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };22 23/*24 * The EMC6W201 registers25 */26 27#define EMC6W201_REG_IN(nr) (0x20 + (nr))28#define EMC6W201_REG_TEMP(nr) (0x26 + (nr))29#define EMC6W201_REG_FAN(nr) (0x2C + (nr) * 2)30#define EMC6W201_REG_COMPANY 0x3E31#define EMC6W201_REG_VERSTEP 0x3F32#define EMC6W201_REG_CONFIG 0x4033#define EMC6W201_REG_IN_LOW(nr) (0x4A + (nr) * 2)34#define EMC6W201_REG_IN_HIGH(nr) (0x4B + (nr) * 2)35#define EMC6W201_REG_TEMP_LOW(nr) (0x56 + (nr) * 2)36#define EMC6W201_REG_TEMP_HIGH(nr) (0x57 + (nr) * 2)37#define EMC6W201_REG_FAN_MIN(nr) (0x62 + (nr) * 2)38 39enum subfeature { input, min, max };40 41/*42 * Per-device data43 */44 45struct emc6w201_data {46 struct i2c_client *client;47 struct mutex update_lock;48 bool valid; /* false until following fields are valid */49 unsigned long last_updated; /* in jiffies */50 51 /* registers values */52 u8 in[3][6];53 s8 temp[3][6];54 u16 fan[2][5];55};56 57/*58 * Combine LSB and MSB registers in a single value59 * Locking: must be called with data->update_lock held60 */61static u16 emc6w201_read16(struct i2c_client *client, u8 reg)62{63 int lsb, msb;64 65 lsb = i2c_smbus_read_byte_data(client, reg);66 msb = i2c_smbus_read_byte_data(client, reg + 1);67 if (unlikely(lsb < 0 || msb < 0)) {68 dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",69 16, "read", reg);70 return 0xFFFF; /* Arbitrary value */71 }72 73 return (msb << 8) | lsb;74}75 76/*77 * Write 16-bit value to LSB and MSB registers78 * Locking: must be called with data->update_lock held79 */80static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)81{82 int err;83 84 err = i2c_smbus_write_byte_data(client, reg, val & 0xff);85 if (likely(!err))86 err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);87 if (unlikely(err < 0))88 dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",89 16, "write", reg);90 91 return err;92}93 94/* Read 8-bit value from register */95static u8 emc6w201_read8(struct i2c_client *client, u8 reg)96{97 int val;98 99 val = i2c_smbus_read_byte_data(client, reg);100 if (unlikely(val < 0)) {101 dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",102 8, "read", reg);103 return 0x00; /* Arbitrary value */104 }105 106 return val;107}108 109/* Write 8-bit value to register */110static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)111{112 int err;113 114 err = i2c_smbus_write_byte_data(client, reg, val);115 if (unlikely(err < 0))116 dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",117 8, "write", reg);118 119 return err;120}121 122static struct emc6w201_data *emc6w201_update_device(struct device *dev)123{124 struct emc6w201_data *data = dev_get_drvdata(dev);125 struct i2c_client *client = data->client;126 int nr;127 128 mutex_lock(&data->update_lock);129 130 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {131 for (nr = 0; nr < 6; nr++) {132 data->in[input][nr] =133 emc6w201_read8(client,134 EMC6W201_REG_IN(nr));135 data->in[min][nr] =136 emc6w201_read8(client,137 EMC6W201_REG_IN_LOW(nr));138 data->in[max][nr] =139 emc6w201_read8(client,140 EMC6W201_REG_IN_HIGH(nr));141 }142 143 for (nr = 0; nr < 6; nr++) {144 data->temp[input][nr] =145 emc6w201_read8(client,146 EMC6W201_REG_TEMP(nr));147 data->temp[min][nr] =148 emc6w201_read8(client,149 EMC6W201_REG_TEMP_LOW(nr));150 data->temp[max][nr] =151 emc6w201_read8(client,152 EMC6W201_REG_TEMP_HIGH(nr));153 }154 155 for (nr = 0; nr < 5; nr++) {156 data->fan[input][nr] =157 emc6w201_read16(client,158 EMC6W201_REG_FAN(nr));159 data->fan[min][nr] =160 emc6w201_read16(client,161 EMC6W201_REG_FAN_MIN(nr));162 }163 164 data->last_updated = jiffies;165 data->valid = true;166 }167 168 mutex_unlock(&data->update_lock);169 170 return data;171}172 173/*174 * Sysfs callback functions175 */176 177static const s16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 };178 179static ssize_t in_show(struct device *dev, struct device_attribute *devattr,180 char *buf)181{182 struct emc6w201_data *data = emc6w201_update_device(dev);183 int sf = to_sensor_dev_attr_2(devattr)->index;184 int nr = to_sensor_dev_attr_2(devattr)->nr;185 186 return sprintf(buf, "%u\n",187 (unsigned)data->in[sf][nr] * nominal_mv[nr] / 0xC0);188}189 190static ssize_t in_store(struct device *dev, struct device_attribute *devattr,191 const char *buf, size_t count)192{193 struct emc6w201_data *data = dev_get_drvdata(dev);194 struct i2c_client *client = data->client;195 int sf = to_sensor_dev_attr_2(devattr)->index;196 int nr = to_sensor_dev_attr_2(devattr)->nr;197 int err;198 long val;199 u8 reg;200 201 err = kstrtol(buf, 10, &val);202 if (err < 0)203 return err;204 205 val = clamp_val(val, 0, 255 * nominal_mv[nr] / 192);206 val = DIV_ROUND_CLOSEST(val * 192, nominal_mv[nr]);207 reg = (sf == min) ? EMC6W201_REG_IN_LOW(nr)208 : EMC6W201_REG_IN_HIGH(nr);209 210 mutex_lock(&data->update_lock);211 data->in[sf][nr] = val;212 err = emc6w201_write8(client, reg, data->in[sf][nr]);213 mutex_unlock(&data->update_lock);214 215 return err < 0 ? err : count;216}217 218static ssize_t temp_show(struct device *dev, struct device_attribute *devattr,219 char *buf)220{221 struct emc6w201_data *data = emc6w201_update_device(dev);222 int sf = to_sensor_dev_attr_2(devattr)->index;223 int nr = to_sensor_dev_attr_2(devattr)->nr;224 225 return sprintf(buf, "%d\n", (int)data->temp[sf][nr] * 1000);226}227 228static ssize_t temp_store(struct device *dev,229 struct device_attribute *devattr, const char *buf,230 size_t count)231{232 struct emc6w201_data *data = dev_get_drvdata(dev);233 struct i2c_client *client = data->client;234 int sf = to_sensor_dev_attr_2(devattr)->index;235 int nr = to_sensor_dev_attr_2(devattr)->nr;236 int err;237 long val;238 u8 reg;239 240 err = kstrtol(buf, 10, &val);241 if (err < 0)242 return err;243 244 val = clamp_val(val, -127000, 127000);245 val = DIV_ROUND_CLOSEST(val, 1000);246 reg = (sf == min) ? EMC6W201_REG_TEMP_LOW(nr)247 : EMC6W201_REG_TEMP_HIGH(nr);248 249 mutex_lock(&data->update_lock);250 data->temp[sf][nr] = val;251 err = emc6w201_write8(client, reg, data->temp[sf][nr]);252 mutex_unlock(&data->update_lock);253 254 return err < 0 ? err : count;255}256 257static ssize_t fan_show(struct device *dev, struct device_attribute *devattr,258 char *buf)259{260 struct emc6w201_data *data = emc6w201_update_device(dev);261 int sf = to_sensor_dev_attr_2(devattr)->index;262 int nr = to_sensor_dev_attr_2(devattr)->nr;263 unsigned rpm;264 265 if (data->fan[sf][nr] == 0 || data->fan[sf][nr] == 0xFFFF)266 rpm = 0;267 else268 rpm = 5400000U / data->fan[sf][nr];269 270 return sprintf(buf, "%u\n", rpm);271}272 273static ssize_t fan_store(struct device *dev, struct device_attribute *devattr,274 const char *buf, size_t count)275{276 struct emc6w201_data *data = dev_get_drvdata(dev);277 struct i2c_client *client = data->client;278 int sf = to_sensor_dev_attr_2(devattr)->index;279 int nr = to_sensor_dev_attr_2(devattr)->nr;280 int err;281 unsigned long val;282 283 err = kstrtoul(buf, 10, &val);284 if (err < 0)285 return err;286 287 if (val == 0) {288 val = 0xFFFF;289 } else {290 val = DIV_ROUND_CLOSEST(5400000U, val);291 val = clamp_val(val, 0, 0xFFFE);292 }293 294 mutex_lock(&data->update_lock);295 data->fan[sf][nr] = val;296 err = emc6w201_write16(client, EMC6W201_REG_FAN_MIN(nr),297 data->fan[sf][nr]);298 mutex_unlock(&data->update_lock);299 300 return err < 0 ? err : count;301}302 303static SENSOR_DEVICE_ATTR_2_RO(in0_input, in, 0, input);304static SENSOR_DEVICE_ATTR_2_RW(in0_min, in, 0, min);305static SENSOR_DEVICE_ATTR_2_RW(in0_max, in, 0, max);306static SENSOR_DEVICE_ATTR_2_RO(in1_input, in, 1, input);307static SENSOR_DEVICE_ATTR_2_RW(in1_min, in, 1, min);308static SENSOR_DEVICE_ATTR_2_RW(in1_max, in, 1, max);309static SENSOR_DEVICE_ATTR_2_RO(in2_input, in, 2, input);310static SENSOR_DEVICE_ATTR_2_RW(in2_min, in, 2, min);311static SENSOR_DEVICE_ATTR_2_RW(in2_max, in, 2, max);312static SENSOR_DEVICE_ATTR_2_RO(in3_input, in, 3, input);313static SENSOR_DEVICE_ATTR_2_RW(in3_min, in, 3, min);314static SENSOR_DEVICE_ATTR_2_RW(in3_max, in, 3, max);315static SENSOR_DEVICE_ATTR_2_RO(in4_input, in, 4, input);316static SENSOR_DEVICE_ATTR_2_RW(in4_min, in, 4, min);317static SENSOR_DEVICE_ATTR_2_RW(in4_max, in, 4, max);318static SENSOR_DEVICE_ATTR_2_RO(in5_input, in, 5, input);319static SENSOR_DEVICE_ATTR_2_RW(in5_min, in, 5, min);320static SENSOR_DEVICE_ATTR_2_RW(in5_max, in, 5, max);321 322static SENSOR_DEVICE_ATTR_2_RO(temp1_input, temp, 0, input);323static SENSOR_DEVICE_ATTR_2_RW(temp1_min, temp, 0, min);324static SENSOR_DEVICE_ATTR_2_RW(temp1_max, temp, 0, max);325static SENSOR_DEVICE_ATTR_2_RO(temp2_input, temp, 1, input);326static SENSOR_DEVICE_ATTR_2_RW(temp2_min, temp, 1, min);327static SENSOR_DEVICE_ATTR_2_RW(temp2_max, temp, 1, max);328static SENSOR_DEVICE_ATTR_2_RO(temp3_input, temp, 2, input);329static SENSOR_DEVICE_ATTR_2_RW(temp3_min, temp, 2, min);330static SENSOR_DEVICE_ATTR_2_RW(temp3_max, temp, 2, max);331static SENSOR_DEVICE_ATTR_2_RO(temp4_input, temp, 3, input);332static SENSOR_DEVICE_ATTR_2_RW(temp4_min, temp, 3, min);333static SENSOR_DEVICE_ATTR_2_RW(temp4_max, temp, 3, max);334static SENSOR_DEVICE_ATTR_2_RO(temp5_input, temp, 4, input);335static SENSOR_DEVICE_ATTR_2_RW(temp5_min, temp, 4, min);336static SENSOR_DEVICE_ATTR_2_RW(temp5_max, temp, 4, max);337static SENSOR_DEVICE_ATTR_2_RO(temp6_input, temp, 5, input);338static SENSOR_DEVICE_ATTR_2_RW(temp6_min, temp, 5, min);339static SENSOR_DEVICE_ATTR_2_RW(temp6_max, temp, 5, max);340 341static SENSOR_DEVICE_ATTR_2_RO(fan1_input, fan, 0, input);342static SENSOR_DEVICE_ATTR_2_RW(fan1_min, fan, 0, min);343static SENSOR_DEVICE_ATTR_2_RO(fan2_input, fan, 1, input);344static SENSOR_DEVICE_ATTR_2_RW(fan2_min, fan, 1, min);345static SENSOR_DEVICE_ATTR_2_RO(fan3_input, fan, 2, input);346static SENSOR_DEVICE_ATTR_2_RW(fan3_min, fan, 2, min);347static SENSOR_DEVICE_ATTR_2_RO(fan4_input, fan, 3, input);348static SENSOR_DEVICE_ATTR_2_RW(fan4_min, fan, 3, min);349static SENSOR_DEVICE_ATTR_2_RO(fan5_input, fan, 4, input);350static SENSOR_DEVICE_ATTR_2_RW(fan5_min, fan, 4, min);351 352static struct attribute *emc6w201_attrs[] = {353 &sensor_dev_attr_in0_input.dev_attr.attr,354 &sensor_dev_attr_in0_min.dev_attr.attr,355 &sensor_dev_attr_in0_max.dev_attr.attr,356 &sensor_dev_attr_in1_input.dev_attr.attr,357 &sensor_dev_attr_in1_min.dev_attr.attr,358 &sensor_dev_attr_in1_max.dev_attr.attr,359 &sensor_dev_attr_in2_input.dev_attr.attr,360 &sensor_dev_attr_in2_min.dev_attr.attr,361 &sensor_dev_attr_in2_max.dev_attr.attr,362 &sensor_dev_attr_in3_input.dev_attr.attr,363 &sensor_dev_attr_in3_min.dev_attr.attr,364 &sensor_dev_attr_in3_max.dev_attr.attr,365 &sensor_dev_attr_in4_input.dev_attr.attr,366 &sensor_dev_attr_in4_min.dev_attr.attr,367 &sensor_dev_attr_in4_max.dev_attr.attr,368 &sensor_dev_attr_in5_input.dev_attr.attr,369 &sensor_dev_attr_in5_min.dev_attr.attr,370 &sensor_dev_attr_in5_max.dev_attr.attr,371 372 &sensor_dev_attr_temp1_input.dev_attr.attr,373 &sensor_dev_attr_temp1_min.dev_attr.attr,374 &sensor_dev_attr_temp1_max.dev_attr.attr,375 &sensor_dev_attr_temp2_input.dev_attr.attr,376 &sensor_dev_attr_temp2_min.dev_attr.attr,377 &sensor_dev_attr_temp2_max.dev_attr.attr,378 &sensor_dev_attr_temp3_input.dev_attr.attr,379 &sensor_dev_attr_temp3_min.dev_attr.attr,380 &sensor_dev_attr_temp3_max.dev_attr.attr,381 &sensor_dev_attr_temp4_input.dev_attr.attr,382 &sensor_dev_attr_temp4_min.dev_attr.attr,383 &sensor_dev_attr_temp4_max.dev_attr.attr,384 &sensor_dev_attr_temp5_input.dev_attr.attr,385 &sensor_dev_attr_temp5_min.dev_attr.attr,386 &sensor_dev_attr_temp5_max.dev_attr.attr,387 &sensor_dev_attr_temp6_input.dev_attr.attr,388 &sensor_dev_attr_temp6_min.dev_attr.attr,389 &sensor_dev_attr_temp6_max.dev_attr.attr,390 391 &sensor_dev_attr_fan1_input.dev_attr.attr,392 &sensor_dev_attr_fan1_min.dev_attr.attr,393 &sensor_dev_attr_fan2_input.dev_attr.attr,394 &sensor_dev_attr_fan2_min.dev_attr.attr,395 &sensor_dev_attr_fan3_input.dev_attr.attr,396 &sensor_dev_attr_fan3_min.dev_attr.attr,397 &sensor_dev_attr_fan4_input.dev_attr.attr,398 &sensor_dev_attr_fan4_min.dev_attr.attr,399 &sensor_dev_attr_fan5_input.dev_attr.attr,400 &sensor_dev_attr_fan5_min.dev_attr.attr,401 NULL402};403 404ATTRIBUTE_GROUPS(emc6w201);405 406/*407 * Driver interface408 */409 410/* Return 0 if detection is successful, -ENODEV otherwise */411static int emc6w201_detect(struct i2c_client *client,412 struct i2c_board_info *info)413{414 struct i2c_adapter *adapter = client->adapter;415 int company, verstep, config;416 417 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))418 return -ENODEV;419 420 /* Identification */421 company = i2c_smbus_read_byte_data(client, EMC6W201_REG_COMPANY);422 if (company != 0x5C)423 return -ENODEV;424 verstep = i2c_smbus_read_byte_data(client, EMC6W201_REG_VERSTEP);425 if (verstep < 0 || (verstep & 0xF0) != 0xB0)426 return -ENODEV;427 if ((verstep & 0x0F) > 2) {428 dev_dbg(&client->dev, "Unknown EMC6W201 stepping %d\n",429 verstep & 0x0F);430 return -ENODEV;431 }432 433 /* Check configuration */434 config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);435 if (config < 0 || (config & 0xF4) != 0x04)436 return -ENODEV;437 if (!(config & 0x01)) {438 dev_err(&client->dev, "Monitoring not enabled\n");439 return -ENODEV;440 }441 442 strscpy(info->type, "emc6w201", I2C_NAME_SIZE);443 444 return 0;445}446 447static int emc6w201_probe(struct i2c_client *client)448{449 struct device *dev = &client->dev;450 struct emc6w201_data *data;451 struct device *hwmon_dev;452 453 data = devm_kzalloc(dev, sizeof(struct emc6w201_data), GFP_KERNEL);454 if (!data)455 return -ENOMEM;456 457 data->client = client;458 mutex_init(&data->update_lock);459 460 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,461 data,462 emc6w201_groups);463 return PTR_ERR_OR_ZERO(hwmon_dev);464}465 466static const struct i2c_device_id emc6w201_id[] = {467 { "emc6w201" },468 { }469};470MODULE_DEVICE_TABLE(i2c, emc6w201_id);471 472static struct i2c_driver emc6w201_driver = {473 .class = I2C_CLASS_HWMON,474 .driver = {475 .name = "emc6w201",476 },477 .probe = emc6w201_probe,478 .id_table = emc6w201_id,479 .detect = emc6w201_detect,480 .address_list = normal_i2c,481};482 483module_i2c_driver(emc6w201_driver);484 485MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");486MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver");487MODULE_LICENSE("GPL");488