431 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * thmc50.c - Part of lm_sensors, Linux kernel modules for hardware4 * monitoring5 * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>6 * Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and7 * Philip Edelbrock <phil@netroedge.com>8 */9 10#include <linux/module.h>11#include <linux/init.h>12#include <linux/slab.h>13#include <linux/i2c.h>14#include <linux/hwmon.h>15#include <linux/hwmon-sysfs.h>16#include <linux/err.h>17#include <linux/mutex.h>18#include <linux/jiffies.h>19 20MODULE_LICENSE("GPL");21 22/* Addresses to scan */23static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };24 25/* Insmod parameters */26enum chips { thmc50, adm1022 };27 28static unsigned short adm1022_temp3[16];29static unsigned int adm1022_temp3_num;30module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0);31MODULE_PARM_DESC(adm1022_temp3,32 "List of adapter,address pairs to enable 3rd temperature (ADM1022 only)");33 34/* Many THMC50 constants specified below */35 36/* The THMC50 registers */37#define THMC50_REG_CONF 0x4038#define THMC50_REG_COMPANY_ID 0x3E39#define THMC50_REG_DIE_CODE 0x3F40#define THMC50_REG_ANALOG_OUT 0x1941/*42 * The mirror status register cannot be used as43 * reading it does not clear alarms.44 */45#define THMC50_REG_INTR 0x4146 47static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };48static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };49static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };50static const u8 THMC50_REG_TEMP_CRITICAL[] = { 0x13, 0x14, 0x14 };51static const u8 THMC50_REG_TEMP_DEFAULT[] = { 0x17, 0x18, 0x18 };52 53#define THMC50_REG_CONF_nFANOFF 0x2054#define THMC50_REG_CONF_PROGRAMMED 0x0855 56/* Each client has this additional data */57struct thmc50_data {58 struct i2c_client *client;59 const struct attribute_group *groups[3];60 61 struct mutex update_lock;62 enum chips type;63 unsigned long last_updated; /* In jiffies */64 char has_temp3; /* !=0 if it is ADM1022 in temp3 mode */65 bool valid; /* true if following fields are valid */66 67 /* Register values */68 s8 temp_input[3];69 s8 temp_max[3];70 s8 temp_min[3];71 s8 temp_critical[3];72 u8 analog_out;73 u8 alarms;74};75 76static struct thmc50_data *thmc50_update_device(struct device *dev)77{78 struct thmc50_data *data = dev_get_drvdata(dev);79 struct i2c_client *client = data->client;80 int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);81 82 mutex_lock(&data->update_lock);83 84 if (time_after(jiffies, data->last_updated + timeout)85 || !data->valid) {86 87 int temps = data->has_temp3 ? 3 : 2;88 int i;89 int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);90 91 prog &= THMC50_REG_CONF_PROGRAMMED;92 93 for (i = 0; i < temps; i++) {94 data->temp_input[i] = i2c_smbus_read_byte_data(client,95 THMC50_REG_TEMP[i]);96 data->temp_max[i] = i2c_smbus_read_byte_data(client,97 THMC50_REG_TEMP_MAX[i]);98 data->temp_min[i] = i2c_smbus_read_byte_data(client,99 THMC50_REG_TEMP_MIN[i]);100 data->temp_critical[i] =101 i2c_smbus_read_byte_data(client,102 prog ? THMC50_REG_TEMP_CRITICAL[i]103 : THMC50_REG_TEMP_DEFAULT[i]);104 }105 data->analog_out =106 i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);107 data->alarms =108 i2c_smbus_read_byte_data(client, THMC50_REG_INTR);109 data->last_updated = jiffies;110 data->valid = true;111 }112 113 mutex_unlock(&data->update_lock);114 115 return data;116}117 118static ssize_t analog_out_show(struct device *dev,119 struct device_attribute *attr, char *buf)120{121 struct thmc50_data *data = thmc50_update_device(dev);122 return sprintf(buf, "%d\n", data->analog_out);123}124 125static ssize_t analog_out_store(struct device *dev,126 struct device_attribute *attr,127 const char *buf, size_t count)128{129 struct thmc50_data *data = dev_get_drvdata(dev);130 struct i2c_client *client = data->client;131 int config;132 unsigned long tmp;133 int err;134 135 err = kstrtoul(buf, 10, &tmp);136 if (err)137 return err;138 139 mutex_lock(&data->update_lock);140 data->analog_out = clamp_val(tmp, 0, 255);141 i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,142 data->analog_out);143 144 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);145 if (data->analog_out == 0)146 config &= ~THMC50_REG_CONF_nFANOFF;147 else148 config |= THMC50_REG_CONF_nFANOFF;149 i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);150 151 mutex_unlock(&data->update_lock);152 return count;153}154 155/* There is only one PWM mode = DC */156static ssize_t pwm_mode_show(struct device *dev,157 struct device_attribute *attr, char *buf)158{159 return sprintf(buf, "0\n");160}161 162/* Temperatures */163static ssize_t temp_show(struct device *dev, struct device_attribute *attr,164 char *buf)165{166 int nr = to_sensor_dev_attr(attr)->index;167 struct thmc50_data *data = thmc50_update_device(dev);168 return sprintf(buf, "%d\n", data->temp_input[nr] * 1000);169}170 171static ssize_t temp_min_show(struct device *dev,172 struct device_attribute *attr, char *buf)173{174 int nr = to_sensor_dev_attr(attr)->index;175 struct thmc50_data *data = thmc50_update_device(dev);176 return sprintf(buf, "%d\n", data->temp_min[nr] * 1000);177}178 179static ssize_t temp_min_store(struct device *dev,180 struct device_attribute *attr, const char *buf,181 size_t count)182{183 int nr = to_sensor_dev_attr(attr)->index;184 struct thmc50_data *data = dev_get_drvdata(dev);185 struct i2c_client *client = data->client;186 long val;187 int err;188 189 err = kstrtol(buf, 10, &val);190 if (err)191 return err;192 193 mutex_lock(&data->update_lock);194 data->temp_min[nr] = clamp_val(val / 1000, -128, 127);195 i2c_smbus_write_byte_data(client, THMC50_REG_TEMP_MIN[nr],196 data->temp_min[nr]);197 mutex_unlock(&data->update_lock);198 return count;199}200 201static ssize_t temp_max_show(struct device *dev,202 struct device_attribute *attr, char *buf)203{204 int nr = to_sensor_dev_attr(attr)->index;205 struct thmc50_data *data = thmc50_update_device(dev);206 return sprintf(buf, "%d\n", data->temp_max[nr] * 1000);207}208 209static ssize_t temp_max_store(struct device *dev,210 struct device_attribute *attr, const char *buf,211 size_t count)212{213 int nr = to_sensor_dev_attr(attr)->index;214 struct thmc50_data *data = dev_get_drvdata(dev);215 struct i2c_client *client = data->client;216 long val;217 int err;218 219 err = kstrtol(buf, 10, &val);220 if (err)221 return err;222 223 mutex_lock(&data->update_lock);224 data->temp_max[nr] = clamp_val(val / 1000, -128, 127);225 i2c_smbus_write_byte_data(client, THMC50_REG_TEMP_MAX[nr],226 data->temp_max[nr]);227 mutex_unlock(&data->update_lock);228 return count;229}230 231static ssize_t temp_critical_show(struct device *dev,232 struct device_attribute *attr, char *buf)233{234 int nr = to_sensor_dev_attr(attr)->index;235 struct thmc50_data *data = thmc50_update_device(dev);236 return sprintf(buf, "%d\n", data->temp_critical[nr] * 1000);237}238 239static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,240 char *buf)241{242 int index = to_sensor_dev_attr(attr)->index;243 struct thmc50_data *data = thmc50_update_device(dev);244 245 return sprintf(buf, "%u\n", (data->alarms >> index) & 1);246}247 248static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);249static SENSOR_DEVICE_ATTR_RW(temp1_min, temp_min, 0);250static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);251static SENSOR_DEVICE_ATTR_RO(temp1_crit, temp_critical, 0);252static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);253static SENSOR_DEVICE_ATTR_RW(temp2_min, temp_min, 1);254static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);255static SENSOR_DEVICE_ATTR_RO(temp2_crit, temp_critical, 1);256static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);257static SENSOR_DEVICE_ATTR_RW(temp3_min, temp_min, 2);258static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);259static SENSOR_DEVICE_ATTR_RO(temp3_crit, temp_critical, 2);260 261static SENSOR_DEVICE_ATTR_RO(temp1_alarm, alarm, 0);262static SENSOR_DEVICE_ATTR_RO(temp2_alarm, alarm, 5);263static SENSOR_DEVICE_ATTR_RO(temp3_alarm, alarm, 1);264static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 7);265static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 2);266 267static SENSOR_DEVICE_ATTR_RW(pwm1, analog_out, 0);268static SENSOR_DEVICE_ATTR_RO(pwm1_mode, pwm_mode, 0);269 270static struct attribute *thmc50_attributes[] = {271 &sensor_dev_attr_temp1_max.dev_attr.attr,272 &sensor_dev_attr_temp1_min.dev_attr.attr,273 &sensor_dev_attr_temp1_input.dev_attr.attr,274 &sensor_dev_attr_temp1_crit.dev_attr.attr,275 &sensor_dev_attr_temp1_alarm.dev_attr.attr,276 &sensor_dev_attr_temp2_max.dev_attr.attr,277 &sensor_dev_attr_temp2_min.dev_attr.attr,278 &sensor_dev_attr_temp2_input.dev_attr.attr,279 &sensor_dev_attr_temp2_crit.dev_attr.attr,280 &sensor_dev_attr_temp2_alarm.dev_attr.attr,281 &sensor_dev_attr_temp2_fault.dev_attr.attr,282 &sensor_dev_attr_pwm1.dev_attr.attr,283 &sensor_dev_attr_pwm1_mode.dev_attr.attr,284 NULL285};286 287static const struct attribute_group thmc50_group = {288 .attrs = thmc50_attributes,289};290 291/* for ADM1022 3rd temperature mode */292static struct attribute *temp3_attributes[] = {293 &sensor_dev_attr_temp3_max.dev_attr.attr,294 &sensor_dev_attr_temp3_min.dev_attr.attr,295 &sensor_dev_attr_temp3_input.dev_attr.attr,296 &sensor_dev_attr_temp3_crit.dev_attr.attr,297 &sensor_dev_attr_temp3_alarm.dev_attr.attr,298 &sensor_dev_attr_temp3_fault.dev_attr.attr,299 NULL300};301 302static const struct attribute_group temp3_group = {303 .attrs = temp3_attributes,304};305 306/* Return 0 if detection is successful, -ENODEV otherwise */307static int thmc50_detect(struct i2c_client *client,308 struct i2c_board_info *info)309{310 unsigned company;311 unsigned revision;312 unsigned config;313 struct i2c_adapter *adapter = client->adapter;314 const char *type_name;315 316 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {317 pr_debug("thmc50: detect failed, smbus byte data not supported!\n");318 return -ENODEV;319 }320 321 pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",322 client->addr, i2c_adapter_id(client->adapter));323 324 company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID);325 revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE);326 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);327 if (revision < 0xc0 || (config & 0x10))328 return -ENODEV;329 330 if (company == 0x41) {331 int id = i2c_adapter_id(client->adapter);332 int i;333 334 type_name = "adm1022";335 for (i = 0; i + 1 < adm1022_temp3_num; i += 2)336 if (adm1022_temp3[i] == id &&337 adm1022_temp3[i + 1] == client->addr) {338 /* enable 2nd remote temp */339 config |= (1 << 7);340 i2c_smbus_write_byte_data(client,341 THMC50_REG_CONF,342 config);343 break;344 }345 } else if (company == 0x49) {346 type_name = "thmc50";347 } else {348 pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");349 return -ENODEV;350 }351 352 pr_debug("thmc50: Detected %s (version %x, revision %x)\n",353 type_name, (revision >> 4) - 0xc, revision & 0xf);354 355 strscpy(info->type, type_name, I2C_NAME_SIZE);356 357 return 0;358}359 360static void thmc50_init_client(struct thmc50_data *data)361{362 struct i2c_client *client = data->client;363 int config;364 365 data->analog_out = i2c_smbus_read_byte_data(client,366 THMC50_REG_ANALOG_OUT);367 /* set up to at least 1 */368 if (data->analog_out == 0) {369 data->analog_out = 1;370 i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,371 data->analog_out);372 }373 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);374 config |= 0x1; /* start the chip if it is in standby mode */375 if (data->type == adm1022 && (config & (1 << 7)))376 data->has_temp3 = 1;377 i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);378}379 380static int thmc50_probe(struct i2c_client *client)381{382 struct device *dev = &client->dev;383 struct thmc50_data *data;384 struct device *hwmon_dev;385 int idx = 0;386 387 data = devm_kzalloc(dev, sizeof(struct thmc50_data), GFP_KERNEL);388 if (!data)389 return -ENOMEM;390 391 data->client = client;392 data->type = (uintptr_t)i2c_get_match_data(client);393 mutex_init(&data->update_lock);394 395 thmc50_init_client(data);396 397 /* sysfs hooks */398 data->groups[idx++] = &thmc50_group;399 400 /* Register additional ADM1022 sysfs hooks */401 if (data->has_temp3)402 data->groups[idx++] = &temp3_group;403 404 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,405 data, data->groups);406 return PTR_ERR_OR_ZERO(hwmon_dev);407}408 409static const struct i2c_device_id thmc50_id[] = {410 { "adm1022", adm1022 },411 { "thmc50", thmc50 },412 { }413};414MODULE_DEVICE_TABLE(i2c, thmc50_id);415 416static struct i2c_driver thmc50_driver = {417 .class = I2C_CLASS_HWMON,418 .driver = {419 .name = "thmc50",420 },421 .probe = thmc50_probe,422 .id_table = thmc50_id,423 .detect = thmc50_detect,424 .address_list = normal_i2c,425};426 427module_i2c_driver(thmc50_driver);428 429MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");430MODULE_DESCRIPTION("THMC50 driver");431