Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for +/-1 degree C, SMBus-Compatible Remote/Local Temperature Sensor
0004  * with Overtemperature Alarm
0005  *
0006  * Copyright (C) 2011 AppearTV AS
0007  *
0008  * Derived from:
0009  *
0010  *  Based on the max1619 driver.
0011  *  Copyright (C) 2003-2004 Oleksij Rempel <bug-track@fisher-privat.net>
0012  *                          Jean Delvare <jdelvare@suse.de>
0013  *
0014  * The MAX6642 is a sensor chip made by Maxim.
0015  * It reports up to two temperatures (its own plus up to
0016  * one external one). Complete datasheet can be
0017  * obtained from Maxim's website at:
0018  *   http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf
0019  */
0020 
0021 
0022 #include <linux/module.h>
0023 #include <linux/init.h>
0024 #include <linux/slab.h>
0025 #include <linux/jiffies.h>
0026 #include <linux/i2c.h>
0027 #include <linux/hwmon.h>
0028 #include <linux/hwmon-sysfs.h>
0029 #include <linux/err.h>
0030 #include <linux/mutex.h>
0031 #include <linux/sysfs.h>
0032 
0033 static const unsigned short normal_i2c[] = {
0034     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
0035 
0036 /*
0037  * The MAX6642 registers
0038  */
0039 
0040 #define MAX6642_REG_R_MAN_ID        0xFE
0041 #define MAX6642_REG_R_CONFIG        0x03
0042 #define MAX6642_REG_W_CONFIG        0x09
0043 #define MAX6642_REG_R_STATUS        0x02
0044 #define MAX6642_REG_R_LOCAL_TEMP    0x00
0045 #define MAX6642_REG_R_LOCAL_TEMPL   0x11
0046 #define MAX6642_REG_R_LOCAL_HIGH    0x05
0047 #define MAX6642_REG_W_LOCAL_HIGH    0x0B
0048 #define MAX6642_REG_R_REMOTE_TEMP   0x01
0049 #define MAX6642_REG_R_REMOTE_TEMPL  0x10
0050 #define MAX6642_REG_R_REMOTE_HIGH   0x07
0051 #define MAX6642_REG_W_REMOTE_HIGH   0x0D
0052 
0053 /*
0054  * Conversions
0055  */
0056 
0057 static int temp_from_reg10(int val)
0058 {
0059     return val * 250;
0060 }
0061 
0062 static int temp_from_reg(int val)
0063 {
0064     return val * 1000;
0065 }
0066 
0067 static int temp_to_reg(int val)
0068 {
0069     return val / 1000;
0070 }
0071 
0072 /*
0073  * Client data (each client gets its own)
0074  */
0075 
0076 struct max6642_data {
0077     struct i2c_client *client;
0078     struct mutex update_lock;
0079     bool valid; /* zero until following fields are valid */
0080     unsigned long last_updated; /* in jiffies */
0081 
0082     /* registers values */
0083     u16 temp_input[2]; /* local/remote */
0084     u16 temp_high[2]; /* local/remote */
0085     u8 alarms;
0086 };
0087 
0088 /*
0089  * Real code
0090  */
0091 
0092 static void max6642_init_client(struct max6642_data *data,
0093                 struct i2c_client *client)
0094 {
0095     u8 config;
0096 
0097     /*
0098      * Start the conversions.
0099      */
0100     config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG);
0101     if (config & 0x40)
0102         i2c_smbus_write_byte_data(client, MAX6642_REG_W_CONFIG,
0103                       config & 0xBF); /* run */
0104 
0105     data->temp_high[0] = i2c_smbus_read_byte_data(client,
0106                 MAX6642_REG_R_LOCAL_HIGH);
0107     data->temp_high[1] = i2c_smbus_read_byte_data(client,
0108                 MAX6642_REG_R_REMOTE_HIGH);
0109 }
0110 
0111 /* Return 0 if detection is successful, -ENODEV otherwise */
0112 static int max6642_detect(struct i2c_client *client,
0113               struct i2c_board_info *info)
0114 {
0115     struct i2c_adapter *adapter = client->adapter;
0116     u8 reg_config, reg_status, man_id;
0117 
0118     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
0119         return -ENODEV;
0120 
0121     /* identification */
0122     man_id = i2c_smbus_read_byte_data(client, MAX6642_REG_R_MAN_ID);
0123     if (man_id != 0x4D)
0124         return -ENODEV;
0125 
0126     /* sanity check */
0127     if (i2c_smbus_read_byte_data(client, 0x04) != 0x4D
0128         || i2c_smbus_read_byte_data(client, 0x06) != 0x4D
0129         || i2c_smbus_read_byte_data(client, 0xff) != 0x4D)
0130         return -ENODEV;
0131 
0132     /*
0133      * We read the config and status register, the 4 lower bits in the
0134      * config register should be zero and bit 5, 3, 1 and 0 should be
0135      * zero in the status register.
0136      */
0137     reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG);
0138     if ((reg_config & 0x0f) != 0x00)
0139         return -ENODEV;
0140 
0141     /* in between, another round of sanity checks */
0142     if (i2c_smbus_read_byte_data(client, 0x04) != reg_config
0143         || i2c_smbus_read_byte_data(client, 0x06) != reg_config
0144         || i2c_smbus_read_byte_data(client, 0xff) != reg_config)
0145         return -ENODEV;
0146 
0147     reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS);
0148     if ((reg_status & 0x2b) != 0x00)
0149         return -ENODEV;
0150 
0151     strlcpy(info->type, "max6642", I2C_NAME_SIZE);
0152 
0153     return 0;
0154 }
0155 
0156 static struct max6642_data *max6642_update_device(struct device *dev)
0157 {
0158     struct max6642_data *data = dev_get_drvdata(dev);
0159     struct i2c_client *client = data->client;
0160     u16 val, tmp;
0161 
0162     mutex_lock(&data->update_lock);
0163 
0164     if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
0165         dev_dbg(dev, "Updating max6642 data.\n");
0166         val = i2c_smbus_read_byte_data(client,
0167                     MAX6642_REG_R_LOCAL_TEMPL);
0168         tmp = (val >> 6) & 3;
0169         val = i2c_smbus_read_byte_data(client,
0170                     MAX6642_REG_R_LOCAL_TEMP);
0171         val = (val << 2) | tmp;
0172         data->temp_input[0] = val;
0173         val = i2c_smbus_read_byte_data(client,
0174                     MAX6642_REG_R_REMOTE_TEMPL);
0175         tmp = (val >> 6) & 3;
0176         val = i2c_smbus_read_byte_data(client,
0177                     MAX6642_REG_R_REMOTE_TEMP);
0178         val = (val << 2) | tmp;
0179         data->temp_input[1] = val;
0180         data->alarms = i2c_smbus_read_byte_data(client,
0181                     MAX6642_REG_R_STATUS);
0182 
0183         data->last_updated = jiffies;
0184         data->valid = true;
0185     }
0186 
0187     mutex_unlock(&data->update_lock);
0188 
0189     return data;
0190 }
0191 
0192 /*
0193  * Sysfs stuff
0194  */
0195 
0196 static ssize_t temp_max10_show(struct device *dev,
0197                    struct device_attribute *dev_attr, char *buf)
0198 {
0199     struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
0200     struct max6642_data *data = max6642_update_device(dev);
0201 
0202     return sprintf(buf, "%d\n",
0203                temp_from_reg10(data->temp_input[attr->index]));
0204 }
0205 
0206 static ssize_t temp_max_show(struct device *dev,
0207                  struct device_attribute *attr, char *buf)
0208 {
0209     struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
0210     struct max6642_data *data = max6642_update_device(dev);
0211 
0212     return sprintf(buf, "%d\n", temp_from_reg(data->temp_high[attr2->nr]));
0213 }
0214 
0215 static ssize_t temp_max_store(struct device *dev,
0216                   struct device_attribute *attr, const char *buf,
0217                   size_t count)
0218 {
0219     struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
0220     struct max6642_data *data = dev_get_drvdata(dev);
0221     unsigned long val;
0222     int err;
0223 
0224     err = kstrtoul(buf, 10, &val);
0225     if (err < 0)
0226         return err;
0227 
0228     mutex_lock(&data->update_lock);
0229     data->temp_high[attr2->nr] = clamp_val(temp_to_reg(val), 0, 255);
0230     i2c_smbus_write_byte_data(data->client, attr2->index,
0231                   data->temp_high[attr2->nr]);
0232     mutex_unlock(&data->update_lock);
0233     return count;
0234 }
0235 
0236 static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
0237               char *buf)
0238 {
0239     int bitnr = to_sensor_dev_attr(attr)->index;
0240     struct max6642_data *data = max6642_update_device(dev);
0241     return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
0242 }
0243 
0244 static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_max10, 0);
0245 static SENSOR_DEVICE_ATTR_RO(temp2_input, temp_max10, 1);
0246 static SENSOR_DEVICE_ATTR_2_RW(temp1_max, temp_max, 0,
0247                    MAX6642_REG_W_LOCAL_HIGH);
0248 static SENSOR_DEVICE_ATTR_2_RW(temp2_max, temp_max, 1,
0249                    MAX6642_REG_W_REMOTE_HIGH);
0250 static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 2);
0251 static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 6);
0252 static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 4);
0253 
0254 static struct attribute *max6642_attrs[] = {
0255     &sensor_dev_attr_temp1_input.dev_attr.attr,
0256     &sensor_dev_attr_temp2_input.dev_attr.attr,
0257     &sensor_dev_attr_temp1_max.dev_attr.attr,
0258     &sensor_dev_attr_temp2_max.dev_attr.attr,
0259 
0260     &sensor_dev_attr_temp2_fault.dev_attr.attr,
0261     &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
0262     &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
0263     NULL
0264 };
0265 ATTRIBUTE_GROUPS(max6642);
0266 
0267 static int max6642_probe(struct i2c_client *client)
0268 {
0269     struct device *dev = &client->dev;
0270     struct max6642_data *data;
0271     struct device *hwmon_dev;
0272 
0273     data = devm_kzalloc(dev, sizeof(struct max6642_data), GFP_KERNEL);
0274     if (!data)
0275         return -ENOMEM;
0276 
0277     data->client = client;
0278     mutex_init(&data->update_lock);
0279 
0280     /* Initialize the MAX6642 chip */
0281     max6642_init_client(data, client);
0282 
0283     hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
0284                                client->name, data,
0285                                max6642_groups);
0286     return PTR_ERR_OR_ZERO(hwmon_dev);
0287 }
0288 
0289 /*
0290  * Driver data (common to all clients)
0291  */
0292 
0293 static const struct i2c_device_id max6642_id[] = {
0294     { "max6642", 0 },
0295     { }
0296 };
0297 MODULE_DEVICE_TABLE(i2c, max6642_id);
0298 
0299 static struct i2c_driver max6642_driver = {
0300     .class      = I2C_CLASS_HWMON,
0301     .driver = {
0302         .name   = "max6642",
0303     },
0304     .probe_new  = max6642_probe,
0305     .id_table   = max6642_id,
0306     .detect     = max6642_detect,
0307     .address_list   = normal_i2c,
0308 };
0309 
0310 module_i2c_driver(max6642_driver);
0311 
0312 MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>");
0313 MODULE_DESCRIPTION("MAX6642 sensor driver");
0314 MODULE_LICENSE("GPL");