max6642.c (8366B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Driver for +/-1 degree C, SMBus-Compatible Remote/Local Temperature Sensor 4 * with Overtemperature Alarm 5 * 6 * Copyright (C) 2011 AppearTV AS 7 * 8 * Derived from: 9 * 10 * Based on the max1619 driver. 11 * Copyright (C) 2003-2004 Oleksij Rempel <bug-track@fisher-privat.net> 12 * Jean Delvare <jdelvare@suse.de> 13 * 14 * The MAX6642 is a sensor chip made by Maxim. 15 * It reports up to two temperatures (its own plus up to 16 * one external one). Complete datasheet can be 17 * obtained from Maxim's website at: 18 * http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf 19 */ 20 21 22#include <linux/module.h> 23#include <linux/init.h> 24#include <linux/slab.h> 25#include <linux/jiffies.h> 26#include <linux/i2c.h> 27#include <linux/hwmon.h> 28#include <linux/hwmon-sysfs.h> 29#include <linux/err.h> 30#include <linux/mutex.h> 31#include <linux/sysfs.h> 32 33static const unsigned short normal_i2c[] = { 34 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 35 36/* 37 * The MAX6642 registers 38 */ 39 40#define MAX6642_REG_R_MAN_ID 0xFE 41#define MAX6642_REG_R_CONFIG 0x03 42#define MAX6642_REG_W_CONFIG 0x09 43#define MAX6642_REG_R_STATUS 0x02 44#define MAX6642_REG_R_LOCAL_TEMP 0x00 45#define MAX6642_REG_R_LOCAL_TEMPL 0x11 46#define MAX6642_REG_R_LOCAL_HIGH 0x05 47#define MAX6642_REG_W_LOCAL_HIGH 0x0B 48#define MAX6642_REG_R_REMOTE_TEMP 0x01 49#define MAX6642_REG_R_REMOTE_TEMPL 0x10 50#define MAX6642_REG_R_REMOTE_HIGH 0x07 51#define MAX6642_REG_W_REMOTE_HIGH 0x0D 52 53/* 54 * Conversions 55 */ 56 57static int temp_from_reg10(int val) 58{ 59 return val * 250; 60} 61 62static int temp_from_reg(int val) 63{ 64 return val * 1000; 65} 66 67static int temp_to_reg(int val) 68{ 69 return val / 1000; 70} 71 72/* 73 * Client data (each client gets its own) 74 */ 75 76struct max6642_data { 77 struct i2c_client *client; 78 struct mutex update_lock; 79 bool valid; /* zero until following fields are valid */ 80 unsigned long last_updated; /* in jiffies */ 81 82 /* registers values */ 83 u16 temp_input[2]; /* local/remote */ 84 u16 temp_high[2]; /* local/remote */ 85 u8 alarms; 86}; 87 88/* 89 * Real code 90 */ 91 92static void max6642_init_client(struct max6642_data *data, 93 struct i2c_client *client) 94{ 95 u8 config; 96 97 /* 98 * Start the conversions. 99 */ 100 config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG); 101 if (config & 0x40) 102 i2c_smbus_write_byte_data(client, MAX6642_REG_W_CONFIG, 103 config & 0xBF); /* run */ 104 105 data->temp_high[0] = i2c_smbus_read_byte_data(client, 106 MAX6642_REG_R_LOCAL_HIGH); 107 data->temp_high[1] = i2c_smbus_read_byte_data(client, 108 MAX6642_REG_R_REMOTE_HIGH); 109} 110 111/* Return 0 if detection is successful, -ENODEV otherwise */ 112static int max6642_detect(struct i2c_client *client, 113 struct i2c_board_info *info) 114{ 115 struct i2c_adapter *adapter = client->adapter; 116 u8 reg_config, reg_status, man_id; 117 118 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 119 return -ENODEV; 120 121 /* identification */ 122 man_id = i2c_smbus_read_byte_data(client, MAX6642_REG_R_MAN_ID); 123 if (man_id != 0x4D) 124 return -ENODEV; 125 126 /* sanity check */ 127 if (i2c_smbus_read_byte_data(client, 0x04) != 0x4D 128 || i2c_smbus_read_byte_data(client, 0x06) != 0x4D 129 || i2c_smbus_read_byte_data(client, 0xff) != 0x4D) 130 return -ENODEV; 131 132 /* 133 * We read the config and status register, the 4 lower bits in the 134 * config register should be zero and bit 5, 3, 1 and 0 should be 135 * zero in the status register. 136 */ 137 reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG); 138 if ((reg_config & 0x0f) != 0x00) 139 return -ENODEV; 140 141 /* in between, another round of sanity checks */ 142 if (i2c_smbus_read_byte_data(client, 0x04) != reg_config 143 || i2c_smbus_read_byte_data(client, 0x06) != reg_config 144 || i2c_smbus_read_byte_data(client, 0xff) != reg_config) 145 return -ENODEV; 146 147 reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS); 148 if ((reg_status & 0x2b) != 0x00) 149 return -ENODEV; 150 151 strlcpy(info->type, "max6642", I2C_NAME_SIZE); 152 153 return 0; 154} 155 156static struct max6642_data *max6642_update_device(struct device *dev) 157{ 158 struct max6642_data *data = dev_get_drvdata(dev); 159 struct i2c_client *client = data->client; 160 u16 val, tmp; 161 162 mutex_lock(&data->update_lock); 163 164 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 165 dev_dbg(dev, "Updating max6642 data.\n"); 166 val = i2c_smbus_read_byte_data(client, 167 MAX6642_REG_R_LOCAL_TEMPL); 168 tmp = (val >> 6) & 3; 169 val = i2c_smbus_read_byte_data(client, 170 MAX6642_REG_R_LOCAL_TEMP); 171 val = (val << 2) | tmp; 172 data->temp_input[0] = val; 173 val = i2c_smbus_read_byte_data(client, 174 MAX6642_REG_R_REMOTE_TEMPL); 175 tmp = (val >> 6) & 3; 176 val = i2c_smbus_read_byte_data(client, 177 MAX6642_REG_R_REMOTE_TEMP); 178 val = (val << 2) | tmp; 179 data->temp_input[1] = val; 180 data->alarms = i2c_smbus_read_byte_data(client, 181 MAX6642_REG_R_STATUS); 182 183 data->last_updated = jiffies; 184 data->valid = true; 185 } 186 187 mutex_unlock(&data->update_lock); 188 189 return data; 190} 191 192/* 193 * Sysfs stuff 194 */ 195 196static ssize_t temp_max10_show(struct device *dev, 197 struct device_attribute *dev_attr, char *buf) 198{ 199 struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 200 struct max6642_data *data = max6642_update_device(dev); 201 202 return sprintf(buf, "%d\n", 203 temp_from_reg10(data->temp_input[attr->index])); 204} 205 206static ssize_t temp_max_show(struct device *dev, 207 struct device_attribute *attr, char *buf) 208{ 209 struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); 210 struct max6642_data *data = max6642_update_device(dev); 211 212 return sprintf(buf, "%d\n", temp_from_reg(data->temp_high[attr2->nr])); 213} 214 215static ssize_t temp_max_store(struct device *dev, 216 struct device_attribute *attr, const char *buf, 217 size_t count) 218{ 219 struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); 220 struct max6642_data *data = dev_get_drvdata(dev); 221 unsigned long val; 222 int err; 223 224 err = kstrtoul(buf, 10, &val); 225 if (err < 0) 226 return err; 227 228 mutex_lock(&data->update_lock); 229 data->temp_high[attr2->nr] = clamp_val(temp_to_reg(val), 0, 255); 230 i2c_smbus_write_byte_data(data->client, attr2->index, 231 data->temp_high[attr2->nr]); 232 mutex_unlock(&data->update_lock); 233 return count; 234} 235 236static ssize_t alarm_show(struct device *dev, struct device_attribute *attr, 237 char *buf) 238{ 239 int bitnr = to_sensor_dev_attr(attr)->index; 240 struct max6642_data *data = max6642_update_device(dev); 241 return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); 242} 243 244static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_max10, 0); 245static SENSOR_DEVICE_ATTR_RO(temp2_input, temp_max10, 1); 246static SENSOR_DEVICE_ATTR_2_RW(temp1_max, temp_max, 0, 247 MAX6642_REG_W_LOCAL_HIGH); 248static SENSOR_DEVICE_ATTR_2_RW(temp2_max, temp_max, 1, 249 MAX6642_REG_W_REMOTE_HIGH); 250static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 2); 251static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 6); 252static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 4); 253 254static struct attribute *max6642_attrs[] = { 255 &sensor_dev_attr_temp1_input.dev_attr.attr, 256 &sensor_dev_attr_temp2_input.dev_attr.attr, 257 &sensor_dev_attr_temp1_max.dev_attr.attr, 258 &sensor_dev_attr_temp2_max.dev_attr.attr, 259 260 &sensor_dev_attr_temp2_fault.dev_attr.attr, 261 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 262 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, 263 NULL 264}; 265ATTRIBUTE_GROUPS(max6642); 266 267static int max6642_probe(struct i2c_client *client) 268{ 269 struct device *dev = &client->dev; 270 struct max6642_data *data; 271 struct device *hwmon_dev; 272 273 data = devm_kzalloc(dev, sizeof(struct max6642_data), GFP_KERNEL); 274 if (!data) 275 return -ENOMEM; 276 277 data->client = client; 278 mutex_init(&data->update_lock); 279 280 /* Initialize the MAX6642 chip */ 281 max6642_init_client(data, client); 282 283 hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, 284 client->name, data, 285 max6642_groups); 286 return PTR_ERR_OR_ZERO(hwmon_dev); 287} 288 289/* 290 * Driver data (common to all clients) 291 */ 292 293static const struct i2c_device_id max6642_id[] = { 294 { "max6642", 0 }, 295 { } 296}; 297MODULE_DEVICE_TABLE(i2c, max6642_id); 298 299static struct i2c_driver max6642_driver = { 300 .class = I2C_CLASS_HWMON, 301 .driver = { 302 .name = "max6642", 303 }, 304 .probe_new = max6642_probe, 305 .id_table = max6642_id, 306 .detect = max6642_detect, 307 .address_list = normal_i2c, 308}; 309 310module_i2c_driver(max6642_driver); 311 312MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>"); 313MODULE_DESCRIPTION("MAX6642 sensor driver"); 314MODULE_LICENSE("GPL");