1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 28d5d45fbSJean Delvare /* 38d5d45fbSJean Delvare * lm83.c - Part of lm_sensors, Linux kernel modules for hardware 48d5d45fbSJean Delvare * monitoring 57c81c60fSJean Delvare * Copyright (C) 2003-2009 Jean Delvare <jdelvare@suse.de> 68d5d45fbSJean Delvare * 78d5d45fbSJean Delvare * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is 88d5d45fbSJean Delvare * a sensor chip made by National Semiconductor. It reports up to four 98d5d45fbSJean Delvare * temperatures (its own plus up to three external ones) with a 1 deg 108d5d45fbSJean Delvare * resolution and a 3-4 deg accuracy. Complete datasheet can be obtained 118d5d45fbSJean Delvare * from National's website at: 128d5d45fbSJean Delvare * http://www.national.com/pf/LM/LM83.html 138d5d45fbSJean Delvare * Since the datasheet omits to give the chip stepping code, I give it 148d5d45fbSJean Delvare * here: 0x03 (at register 0xff). 158d5d45fbSJean Delvare * 1643cb7ebeSJordan Crouse * Also supports the LM82 temp sensor, which is basically a stripped down 1743cb7ebeSJordan Crouse * model of the LM83. Datasheet is here: 1843cb7ebeSJordan Crouse * http://www.national.com/pf/LM/LM82.html 198d5d45fbSJean Delvare */ 208d5d45fbSJean Delvare 21943b0830SMark M. Hoffman #include <linux/err.h> 227c68c2c7SGuenter Roeck #include <linux/i2c.h> 237c68c2c7SGuenter Roeck #include <linux/init.h> 247c68c2c7SGuenter Roeck #include <linux/jiffies.h> 257c68c2c7SGuenter Roeck #include <linux/hwmon.h> 267c68c2c7SGuenter Roeck #include <linux/hwmon-sysfs.h> 277c68c2c7SGuenter Roeck #include <linux/module.h> 289a61bf63SIngo Molnar #include <linux/mutex.h> 297c68c2c7SGuenter Roeck #include <linux/slab.h> 300e39e01cSJean Delvare #include <linux/sysfs.h> 318d5d45fbSJean Delvare 328d5d45fbSJean Delvare /* 338d5d45fbSJean Delvare * Addresses to scan 348d5d45fbSJean Delvare * Address is selected using 2 three-level pins, resulting in 9 possible 358d5d45fbSJean Delvare * addresses. 368d5d45fbSJean Delvare */ 378d5d45fbSJean Delvare 3825e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 3925e9c86dSMark M. Hoffman 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; 408d5d45fbSJean Delvare 41e5e9f44cSJean Delvare enum chips { lm83, lm82 }; 428d5d45fbSJean Delvare 438d5d45fbSJean Delvare /* 448d5d45fbSJean Delvare * The LM83 registers 458d5d45fbSJean Delvare * Manufacturer ID is 0x01 for National Semiconductor. 468d5d45fbSJean Delvare */ 478d5d45fbSJean Delvare 488d5d45fbSJean Delvare #define LM83_REG_R_MAN_ID 0xFE 498d5d45fbSJean Delvare #define LM83_REG_R_CHIP_ID 0xFF 508d5d45fbSJean Delvare #define LM83_REG_R_CONFIG 0x03 518d5d45fbSJean Delvare #define LM83_REG_W_CONFIG 0x09 528d5d45fbSJean Delvare #define LM83_REG_R_STATUS1 0x02 538d5d45fbSJean Delvare #define LM83_REG_R_STATUS2 0x35 548d5d45fbSJean Delvare #define LM83_REG_R_LOCAL_TEMP 0x00 558d5d45fbSJean Delvare #define LM83_REG_R_LOCAL_HIGH 0x05 568d5d45fbSJean Delvare #define LM83_REG_W_LOCAL_HIGH 0x0B 578d5d45fbSJean Delvare #define LM83_REG_R_REMOTE1_TEMP 0x30 588d5d45fbSJean Delvare #define LM83_REG_R_REMOTE1_HIGH 0x38 598d5d45fbSJean Delvare #define LM83_REG_W_REMOTE1_HIGH 0x50 608d5d45fbSJean Delvare #define LM83_REG_R_REMOTE2_TEMP 0x01 618d5d45fbSJean Delvare #define LM83_REG_R_REMOTE2_HIGH 0x07 628d5d45fbSJean Delvare #define LM83_REG_W_REMOTE2_HIGH 0x0D 638d5d45fbSJean Delvare #define LM83_REG_R_REMOTE3_TEMP 0x31 648d5d45fbSJean Delvare #define LM83_REG_R_REMOTE3_HIGH 0x3A 658d5d45fbSJean Delvare #define LM83_REG_W_REMOTE3_HIGH 0x52 668d5d45fbSJean Delvare #define LM83_REG_R_TCRIT 0x42 678d5d45fbSJean Delvare #define LM83_REG_W_TCRIT 0x5A 688d5d45fbSJean Delvare 698d5d45fbSJean Delvare /* 708d5d45fbSJean Delvare * Conversions and various macros 718d5d45fbSJean Delvare * The LM83 uses signed 8-bit values with LSB = 1 degree Celsius. 728d5d45fbSJean Delvare */ 738d5d45fbSJean Delvare 748d5d45fbSJean Delvare #define TEMP_FROM_REG(val) ((val) * 1000) 758d5d45fbSJean Delvare #define TEMP_TO_REG(val) ((val) <= -128000 ? -128 : \ 768d5d45fbSJean Delvare (val) >= 127000 ? 127 : \ 778d5d45fbSJean Delvare (val) < 0 ? ((val) - 500) / 1000 : \ 788d5d45fbSJean Delvare ((val) + 500) / 1000) 798d5d45fbSJean Delvare 808d5d45fbSJean Delvare static const u8 LM83_REG_R_TEMP[] = { 818d5d45fbSJean Delvare LM83_REG_R_LOCAL_TEMP, 828d5d45fbSJean Delvare LM83_REG_R_REMOTE1_TEMP, 838d5d45fbSJean Delvare LM83_REG_R_REMOTE2_TEMP, 848d5d45fbSJean Delvare LM83_REG_R_REMOTE3_TEMP, 858d5d45fbSJean Delvare LM83_REG_R_LOCAL_HIGH, 868d5d45fbSJean Delvare LM83_REG_R_REMOTE1_HIGH, 878d5d45fbSJean Delvare LM83_REG_R_REMOTE2_HIGH, 888d5d45fbSJean Delvare LM83_REG_R_REMOTE3_HIGH, 898d5d45fbSJean Delvare LM83_REG_R_TCRIT, 908d5d45fbSJean Delvare }; 918d5d45fbSJean Delvare 928d5d45fbSJean Delvare static const u8 LM83_REG_W_HIGH[] = { 938d5d45fbSJean Delvare LM83_REG_W_LOCAL_HIGH, 948d5d45fbSJean Delvare LM83_REG_W_REMOTE1_HIGH, 958d5d45fbSJean Delvare LM83_REG_W_REMOTE2_HIGH, 968d5d45fbSJean Delvare LM83_REG_W_REMOTE3_HIGH, 978d5d45fbSJean Delvare LM83_REG_W_TCRIT, 988d5d45fbSJean Delvare }; 998d5d45fbSJean Delvare 1008d5d45fbSJean Delvare /* 1018d5d45fbSJean Delvare * Client data (each client gets its own) 1028d5d45fbSJean Delvare */ 1038d5d45fbSJean Delvare 1048d5d45fbSJean Delvare struct lm83_data { 105a0ac840dSGuenter Roeck struct i2c_client *client; 106a0ac840dSGuenter Roeck const struct attribute_group *groups[3]; 1079a61bf63SIngo Molnar struct mutex update_lock; 108952a11caSPaul Fertser bool valid; /* false until following fields are valid */ 1098d5d45fbSJean Delvare unsigned long last_updated; /* in jiffies */ 1108d5d45fbSJean Delvare 1118d5d45fbSJean Delvare /* registers values */ 1128d5d45fbSJean Delvare s8 temp[9]; /* 0..3: input 1-4, 1138d5d45fbSJean Delvare 4..7: high limit 1-4, 1148d5d45fbSJean Delvare 8 : critical limit */ 1158d5d45fbSJean Delvare u16 alarms; /* bitvector, combined */ 1168d5d45fbSJean Delvare }; 1178d5d45fbSJean Delvare 11841936370SGuenter Roeck static struct lm83_data *lm83_update_device(struct device *dev) 11941936370SGuenter Roeck { 120a0ac840dSGuenter Roeck struct lm83_data *data = dev_get_drvdata(dev); 121a0ac840dSGuenter Roeck struct i2c_client *client = data->client; 12241936370SGuenter Roeck 12341936370SGuenter Roeck mutex_lock(&data->update_lock); 12441936370SGuenter Roeck 12541936370SGuenter Roeck if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { 12641936370SGuenter Roeck int nr; 12741936370SGuenter Roeck 12841936370SGuenter Roeck dev_dbg(&client->dev, "Updating lm83 data.\n"); 12941936370SGuenter Roeck for (nr = 0; nr < 9; nr++) { 13041936370SGuenter Roeck data->temp[nr] = 13141936370SGuenter Roeck i2c_smbus_read_byte_data(client, 13241936370SGuenter Roeck LM83_REG_R_TEMP[nr]); 13341936370SGuenter Roeck } 13441936370SGuenter Roeck data->alarms = 13541936370SGuenter Roeck i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) 13641936370SGuenter Roeck + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) 13741936370SGuenter Roeck << 8); 13841936370SGuenter Roeck 13941936370SGuenter Roeck data->last_updated = jiffies; 140952a11caSPaul Fertser data->valid = true; 14141936370SGuenter Roeck } 14241936370SGuenter Roeck 14341936370SGuenter Roeck mutex_unlock(&data->update_lock); 14441936370SGuenter Roeck 14541936370SGuenter Roeck return data; 14641936370SGuenter Roeck } 14741936370SGuenter Roeck 1488d5d45fbSJean Delvare /* 1498d5d45fbSJean Delvare * Sysfs stuff 1508d5d45fbSJean Delvare */ 1518d5d45fbSJean Delvare 152a9283c8fSGuenter Roeck static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, 1538d5d45fbSJean Delvare char *buf) 1548d5d45fbSJean Delvare { 1558d5d45fbSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1568d5d45fbSJean Delvare struct lm83_data *data = lm83_update_device(dev); 1578d5d45fbSJean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])); 1588d5d45fbSJean Delvare } 1598d5d45fbSJean Delvare 160a9283c8fSGuenter Roeck static ssize_t temp_store(struct device *dev, 161a9283c8fSGuenter Roeck struct device_attribute *devattr, const char *buf, 162a9283c8fSGuenter Roeck size_t count) 1638d5d45fbSJean Delvare { 1648d5d45fbSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 165a0ac840dSGuenter Roeck struct lm83_data *data = dev_get_drvdata(dev); 166a0ac840dSGuenter Roeck struct i2c_client *client = data->client; 167b3789a0dSFrans Meulenbroeks long val; 1688d5d45fbSJean Delvare int nr = attr->index; 169b3789a0dSFrans Meulenbroeks int err; 170b3789a0dSFrans Meulenbroeks 171b3789a0dSFrans Meulenbroeks err = kstrtol(buf, 10, &val); 172b3789a0dSFrans Meulenbroeks if (err < 0) 173b3789a0dSFrans Meulenbroeks return err; 1748d5d45fbSJean Delvare 1759a61bf63SIngo Molnar mutex_lock(&data->update_lock); 1768d5d45fbSJean Delvare data->temp[nr] = TEMP_TO_REG(val); 1778d5d45fbSJean Delvare i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr - 4], 1788d5d45fbSJean Delvare data->temp[nr]); 1799a61bf63SIngo Molnar mutex_unlock(&data->update_lock); 1808d5d45fbSJean Delvare return count; 1818d5d45fbSJean Delvare } 1828d5d45fbSJean Delvare 18314c05198SJulia Lawall static ssize_t alarms_show(struct device *dev, struct device_attribute *dummy, 1848d5d45fbSJean Delvare char *buf) 1858d5d45fbSJean Delvare { 1868d5d45fbSJean Delvare struct lm83_data *data = lm83_update_device(dev); 1878d5d45fbSJean Delvare return sprintf(buf, "%d\n", data->alarms); 1888d5d45fbSJean Delvare } 1898d5d45fbSJean Delvare 190a9283c8fSGuenter Roeck static ssize_t alarm_show(struct device *dev, 191a9283c8fSGuenter Roeck struct device_attribute *devattr, char *buf) 1922d45771eSJean Delvare { 1932d45771eSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1942d45771eSJean Delvare struct lm83_data *data = lm83_update_device(dev); 1952d45771eSJean Delvare int bitnr = attr->index; 1962d45771eSJean Delvare 1972d45771eSJean Delvare return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); 1982d45771eSJean Delvare } 1992d45771eSJean Delvare 200a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0); 201a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1); 202a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2); 203a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp4_input, temp, 3); 204a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_max, temp, 4); 205a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_max, temp, 5); 206a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_max, temp, 6); 207a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp4_max, temp, 7); 208a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_crit, temp, 8); 209a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_crit, temp, 8); 210a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_crit, temp, 8); 211a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp4_crit, temp, 8); 2122d45771eSJean Delvare 2132d45771eSJean Delvare /* Individual alarm files */ 214a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 0); 215a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, 1); 216a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 2); 217a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, alarm, 4); 218a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 6); 219a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 8); 220a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp4_crit_alarm, alarm, 9); 221a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp4_fault, alarm, 10); 222a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp4_max_alarm, alarm, 12); 223a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 13); 224a9283c8fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 15); 2252d45771eSJean Delvare /* Raw alarm file for compatibility */ 22614c05198SJulia Lawall static DEVICE_ATTR_RO(alarms); 2278d5d45fbSJean Delvare 2280e39e01cSJean Delvare static struct attribute *lm83_attributes[] = { 2290e39e01cSJean Delvare &sensor_dev_attr_temp1_input.dev_attr.attr, 2300e39e01cSJean Delvare &sensor_dev_attr_temp3_input.dev_attr.attr, 2310e39e01cSJean Delvare &sensor_dev_attr_temp1_max.dev_attr.attr, 2320e39e01cSJean Delvare &sensor_dev_attr_temp3_max.dev_attr.attr, 2330e39e01cSJean Delvare &sensor_dev_attr_temp1_crit.dev_attr.attr, 2340e39e01cSJean Delvare &sensor_dev_attr_temp3_crit.dev_attr.attr, 2350e39e01cSJean Delvare 2360e39e01cSJean Delvare &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 2370e39e01cSJean Delvare &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, 2387817a39eSJean Delvare &sensor_dev_attr_temp3_fault.dev_attr.attr, 2390e39e01cSJean Delvare &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, 2400e39e01cSJean Delvare &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 2410e39e01cSJean Delvare &dev_attr_alarms.attr, 2420e39e01cSJean Delvare NULL 2430e39e01cSJean Delvare }; 2440e39e01cSJean Delvare 2450e39e01cSJean Delvare static const struct attribute_group lm83_group = { 2460e39e01cSJean Delvare .attrs = lm83_attributes, 2470e39e01cSJean Delvare }; 2480e39e01cSJean Delvare 2490e39e01cSJean Delvare static struct attribute *lm83_attributes_opt[] = { 2500e39e01cSJean Delvare &sensor_dev_attr_temp2_input.dev_attr.attr, 2510e39e01cSJean Delvare &sensor_dev_attr_temp4_input.dev_attr.attr, 2520e39e01cSJean Delvare &sensor_dev_attr_temp2_max.dev_attr.attr, 2530e39e01cSJean Delvare &sensor_dev_attr_temp4_max.dev_attr.attr, 2540e39e01cSJean Delvare &sensor_dev_attr_temp2_crit.dev_attr.attr, 2550e39e01cSJean Delvare &sensor_dev_attr_temp4_crit.dev_attr.attr, 2560e39e01cSJean Delvare 2570e39e01cSJean Delvare &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, 2580e39e01cSJean Delvare &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, 2597817a39eSJean Delvare &sensor_dev_attr_temp4_fault.dev_attr.attr, 2600e39e01cSJean Delvare &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, 2617817a39eSJean Delvare &sensor_dev_attr_temp2_fault.dev_attr.attr, 2620e39e01cSJean Delvare &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, 2630e39e01cSJean Delvare NULL 2640e39e01cSJean Delvare }; 2650e39e01cSJean Delvare 2660e39e01cSJean Delvare static const struct attribute_group lm83_group_opt = { 2670e39e01cSJean Delvare .attrs = lm83_attributes_opt, 2680e39e01cSJean Delvare }; 2690e39e01cSJean Delvare 2708d5d45fbSJean Delvare /* 2718d5d45fbSJean Delvare * Real code 2728d5d45fbSJean Delvare */ 2738d5d45fbSJean Delvare 274b6aacdceSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */ 275*81de0eeaSGuenter Roeck static int lm83_detect(struct i2c_client *client, 276b6aacdceSJean Delvare struct i2c_board_info *info) 2778d5d45fbSJean Delvare { 278*81de0eeaSGuenter Roeck struct i2c_adapter *adapter = client->adapter; 279b57dc394SJean Delvare const char *name; 280b57dc394SJean Delvare u8 man_id, chip_id; 2818d5d45fbSJean Delvare 2828d5d45fbSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 283b6aacdceSJean Delvare return -ENODEV; 2848d5d45fbSJean Delvare 285b57dc394SJean Delvare /* Detection */ 286*81de0eeaSGuenter Roeck if ((i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) & 0xA8) || 287*81de0eeaSGuenter Roeck (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) & 0x48) || 288*81de0eeaSGuenter Roeck (i2c_smbus_read_byte_data(client, LM83_REG_R_CONFIG) & 0x41)) { 289b57dc394SJean Delvare dev_dbg(&adapter->dev, "LM83 detection failed at 0x%02x\n", 290*81de0eeaSGuenter Roeck client->addr); 291b6aacdceSJean Delvare return -ENODEV; 2928d5d45fbSJean Delvare } 2938d5d45fbSJean Delvare 294b57dc394SJean Delvare /* Identification */ 295*81de0eeaSGuenter Roeck man_id = i2c_smbus_read_byte_data(client, LM83_REG_R_MAN_ID); 296b57dc394SJean Delvare if (man_id != 0x01) /* National Semiconductor */ 297b6aacdceSJean Delvare return -ENODEV; 2988d5d45fbSJean Delvare 299*81de0eeaSGuenter Roeck chip_id = i2c_smbus_read_byte_data(client, LM83_REG_R_CHIP_ID); 300b57dc394SJean Delvare switch (chip_id) { 301b57dc394SJean Delvare case 0x03: 3028d5d45fbSJean Delvare name = "lm83"; 303b57dc394SJean Delvare break; 304b57dc394SJean Delvare case 0x01: 30543cb7ebeSJordan Crouse name = "lm82"; 306b57dc394SJean Delvare break; 307b57dc394SJean Delvare default: 308b57dc394SJean Delvare /* identification failed */ 309b57dc394SJean Delvare dev_info(&adapter->dev, 310b57dc394SJean Delvare "Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n", 311b57dc394SJean Delvare man_id, chip_id); 312b57dc394SJean Delvare return -ENODEV; 3138d5d45fbSJean Delvare } 3148d5d45fbSJean Delvare 315b6aacdceSJean Delvare strlcpy(info->type, name, I2C_NAME_SIZE); 316b6aacdceSJean Delvare 317b6aacdceSJean Delvare return 0; 318b6aacdceSJean Delvare } 319b6aacdceSJean Delvare 32011e3377bSGuenter Roeck static const struct i2c_device_id lm83_id[] = { 32111e3377bSGuenter Roeck { "lm83", lm83 }, 32211e3377bSGuenter Roeck { "lm82", lm82 }, 32311e3377bSGuenter Roeck { } 32411e3377bSGuenter Roeck }; 32511e3377bSGuenter Roeck MODULE_DEVICE_TABLE(i2c, lm83_id); 32667487038SStephen Kitt 327*81de0eeaSGuenter Roeck static int lm83_probe(struct i2c_client *client) 328b6aacdceSJean Delvare { 329a0ac840dSGuenter Roeck struct device *hwmon_dev; 330b6aacdceSJean Delvare struct lm83_data *data; 331b6aacdceSJean Delvare 332*81de0eeaSGuenter Roeck data = devm_kzalloc(&client->dev, sizeof(struct lm83_data), 333c087f73aSGuenter Roeck GFP_KERNEL); 334c087f73aSGuenter Roeck if (!data) 335c087f73aSGuenter Roeck return -ENOMEM; 336b6aacdceSJean Delvare 337*81de0eeaSGuenter Roeck data->client = client; 3389a61bf63SIngo Molnar mutex_init(&data->update_lock); 3398d5d45fbSJean Delvare 3408d5d45fbSJean Delvare /* 3410e39e01cSJean Delvare * Register sysfs hooks 34243cb7ebeSJordan Crouse * The LM82 can only monitor one external diode which is 34343cb7ebeSJordan Crouse * at the same register as the LM83 temp3 entry - so we 34443cb7ebeSJordan Crouse * declare 1 and 3 common, and then 2 and 4 only for the LM83. 34543cb7ebeSJordan Crouse */ 346a0ac840dSGuenter Roeck data->groups[0] = &lm83_group; 347*81de0eeaSGuenter Roeck if (i2c_match_id(lm83_id, client)->driver_data == lm83) 348a0ac840dSGuenter Roeck data->groups[1] = &lm83_group_opt; 34943cb7ebeSJordan Crouse 350*81de0eeaSGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, 351*81de0eeaSGuenter Roeck client->name, 352a0ac840dSGuenter Roeck data, data->groups); 353a0ac840dSGuenter Roeck return PTR_ERR_OR_ZERO(hwmon_dev); 3548d5d45fbSJean Delvare } 3558d5d45fbSJean Delvare 35641936370SGuenter Roeck /* 35741936370SGuenter Roeck * Driver data (common to all clients) 35841936370SGuenter Roeck */ 3598d5d45fbSJean Delvare 36041936370SGuenter Roeck static struct i2c_driver lm83_driver = { 36141936370SGuenter Roeck .class = I2C_CLASS_HWMON, 36241936370SGuenter Roeck .driver = { 36341936370SGuenter Roeck .name = "lm83", 36441936370SGuenter Roeck }, 36567487038SStephen Kitt .probe_new = lm83_probe, 36641936370SGuenter Roeck .id_table = lm83_id, 36741936370SGuenter Roeck .detect = lm83_detect, 36841936370SGuenter Roeck .address_list = normal_i2c, 36941936370SGuenter Roeck }; 3708d5d45fbSJean Delvare 371f0967eeaSAxel Lin module_i2c_driver(lm83_driver); 3728d5d45fbSJean Delvare 3737c81c60fSJean Delvare MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); 3748d5d45fbSJean Delvare MODULE_DESCRIPTION("LM83 driver"); 3758d5d45fbSJean Delvare MODULE_LICENSE("GPL"); 376