0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/module.h>
0019 #include <linux/jiffies.h>
0020 #include <linux/i2c.h>
0021 #include <linux/hwmon.h>
0022 #include <linux/hwmon-sysfs.h>
0023 #include <linux/err.h>
0024 #include <linux/mutex.h>
0025 #include <linux/sysfs.h>
0026 #include <linux/slab.h>
0027
0028
0029
0030 #define AD7414_REG_TEMP 0x00
0031 #define AD7414_REG_CONF 0x01
0032 #define AD7414_REG_T_HIGH 0x02
0033 #define AD7414_REG_T_LOW 0x03
0034
0035 static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW };
0036
0037 struct ad7414_data {
0038 struct i2c_client *client;
0039 struct mutex lock;
0040 bool valid;
0041 unsigned long next_update;
0042 s16 temp_input;
0043 s8 temps[ARRAY_SIZE(AD7414_REG_LIMIT)];
0044 };
0045
0046
0047 static inline int ad7414_temp_from_reg(s16 reg)
0048 {
0049
0050
0051
0052
0053 return ((int)reg / 64) * 250;
0054 }
0055
0056 static inline int ad7414_read(struct i2c_client *client, u8 reg)
0057 {
0058 if (reg == AD7414_REG_TEMP)
0059 return i2c_smbus_read_word_swapped(client, reg);
0060 else
0061 return i2c_smbus_read_byte_data(client, reg);
0062 }
0063
0064 static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
0065 {
0066 return i2c_smbus_write_byte_data(client, reg, value);
0067 }
0068
0069 static struct ad7414_data *ad7414_update_device(struct device *dev)
0070 {
0071 struct ad7414_data *data = dev_get_drvdata(dev);
0072 struct i2c_client *client = data->client;
0073
0074 mutex_lock(&data->lock);
0075
0076 if (time_after(jiffies, data->next_update) || !data->valid) {
0077 int value, i;
0078
0079 dev_dbg(&client->dev, "starting ad7414 update\n");
0080
0081 value = ad7414_read(client, AD7414_REG_TEMP);
0082 if (value < 0)
0083 dev_dbg(&client->dev, "AD7414_REG_TEMP err %d\n",
0084 value);
0085 else
0086 data->temp_input = value;
0087
0088 for (i = 0; i < ARRAY_SIZE(AD7414_REG_LIMIT); ++i) {
0089 value = ad7414_read(client, AD7414_REG_LIMIT[i]);
0090 if (value < 0)
0091 dev_dbg(&client->dev, "AD7414 reg %d err %d\n",
0092 AD7414_REG_LIMIT[i], value);
0093 else
0094 data->temps[i] = value;
0095 }
0096
0097 data->next_update = jiffies + HZ + HZ / 2;
0098 data->valid = true;
0099 }
0100
0101 mutex_unlock(&data->lock);
0102
0103 return data;
0104 }
0105
0106 static ssize_t temp_input_show(struct device *dev,
0107 struct device_attribute *attr, char *buf)
0108 {
0109 struct ad7414_data *data = ad7414_update_device(dev);
0110 return sprintf(buf, "%d\n", ad7414_temp_from_reg(data->temp_input));
0111 }
0112 static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_input, 0);
0113
0114 static ssize_t max_min_show(struct device *dev, struct device_attribute *attr,
0115 char *buf)
0116 {
0117 int index = to_sensor_dev_attr(attr)->index;
0118 struct ad7414_data *data = ad7414_update_device(dev);
0119 return sprintf(buf, "%d\n", data->temps[index] * 1000);
0120 }
0121
0122 static ssize_t max_min_store(struct device *dev,
0123 struct device_attribute *attr, const char *buf,
0124 size_t count)
0125 {
0126 struct ad7414_data *data = dev_get_drvdata(dev);
0127 struct i2c_client *client = data->client;
0128 int index = to_sensor_dev_attr(attr)->index;
0129 u8 reg = AD7414_REG_LIMIT[index];
0130 long temp;
0131 int ret = kstrtol(buf, 10, &temp);
0132
0133 if (ret < 0)
0134 return ret;
0135
0136 temp = clamp_val(temp, -40000, 85000);
0137 temp = (temp + (temp < 0 ? -500 : 500)) / 1000;
0138
0139 mutex_lock(&data->lock);
0140 data->temps[index] = temp;
0141 ad7414_write(client, reg, temp);
0142 mutex_unlock(&data->lock);
0143 return count;
0144 }
0145
0146 static SENSOR_DEVICE_ATTR_RW(temp1_max, max_min, 0);
0147 static SENSOR_DEVICE_ATTR_RW(temp1_min, max_min, 1);
0148
0149 static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
0150 char *buf)
0151 {
0152 int bitnr = to_sensor_dev_attr(attr)->index;
0153 struct ad7414_data *data = ad7414_update_device(dev);
0154 int value = (data->temp_input >> bitnr) & 1;
0155 return sprintf(buf, "%d\n", value);
0156 }
0157
0158 static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, alarm, 3);
0159 static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 4);
0160
0161 static struct attribute *ad7414_attrs[] = {
0162 &sensor_dev_attr_temp1_input.dev_attr.attr,
0163 &sensor_dev_attr_temp1_max.dev_attr.attr,
0164 &sensor_dev_attr_temp1_min.dev_attr.attr,
0165 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
0166 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
0167 NULL
0168 };
0169
0170 ATTRIBUTE_GROUPS(ad7414);
0171
0172 static int ad7414_probe(struct i2c_client *client)
0173 {
0174 struct device *dev = &client->dev;
0175 struct ad7414_data *data;
0176 struct device *hwmon_dev;
0177 int conf;
0178
0179 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
0180 I2C_FUNC_SMBUS_READ_WORD_DATA))
0181 return -EOPNOTSUPP;
0182
0183 data = devm_kzalloc(dev, sizeof(struct ad7414_data), GFP_KERNEL);
0184 if (!data)
0185 return -ENOMEM;
0186
0187 data->client = client;
0188 mutex_init(&data->lock);
0189
0190 dev_info(&client->dev, "chip found\n");
0191
0192
0193 conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF);
0194 if (conf < 0)
0195 dev_warn(dev, "ad7414_probe unable to read config register.\n");
0196 else {
0197 conf &= ~(1 << 7);
0198 i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf);
0199 }
0200
0201 hwmon_dev = devm_hwmon_device_register_with_groups(dev,
0202 client->name,
0203 data, ad7414_groups);
0204 return PTR_ERR_OR_ZERO(hwmon_dev);
0205 }
0206
0207 static const struct i2c_device_id ad7414_id[] = {
0208 { "ad7414", 0 },
0209 {}
0210 };
0211 MODULE_DEVICE_TABLE(i2c, ad7414_id);
0212
0213 static const struct of_device_id __maybe_unused ad7414_of_match[] = {
0214 { .compatible = "ad,ad7414" },
0215 { },
0216 };
0217 MODULE_DEVICE_TABLE(of, ad7414_of_match);
0218
0219 static struct i2c_driver ad7414_driver = {
0220 .driver = {
0221 .name = "ad7414",
0222 .of_match_table = of_match_ptr(ad7414_of_match),
0223 },
0224 .probe_new = ad7414_probe,
0225 .id_table = ad7414_id,
0226 };
0227
0228 module_i2c_driver(ad7414_driver);
0229
0230 MODULE_AUTHOR("Stefan Roese <sr at denx.de>, "
0231 "Frank Edelhaeuser <frank.edelhaeuser at spansion.com>");
0232
0233 MODULE_DESCRIPTION("AD7414 driver");
0234 MODULE_LICENSE("GPL");