0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/jiffies.h>
0014 #include <linux/i2c.h>
0015 #include <linux/hwmon.h>
0016 #include <linux/hwmon-sysfs.h>
0017 #include <linux/err.h>
0018 #include <linux/mutex.h>
0019 #include <linux/of_device.h>
0020 #include <linux/delay.h>
0021 #include <linux/slab.h>
0022
0023 #include "lm75.h"
0024
0025 #define DRV_VERSION "0.4"
0026
0027 enum chips { ad7416, ad7417, ad7418 };
0028
0029
0030 #define AD7418_REG_TEMP_IN 0x00
0031 #define AD7418_REG_CONF 0x01
0032 #define AD7418_REG_TEMP_HYST 0x02
0033 #define AD7418_REG_TEMP_OS 0x03
0034 #define AD7418_REG_ADC 0x04
0035 #define AD7418_REG_CONF2 0x05
0036
0037 #define AD7418_REG_ADC_CH(x) ((x) << 5)
0038 #define AD7418_CH_TEMP AD7418_REG_ADC_CH(0)
0039
0040 static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
0041 AD7418_REG_TEMP_HYST,
0042 AD7418_REG_TEMP_OS };
0043
0044 struct ad7418_data {
0045 struct i2c_client *client;
0046 enum chips type;
0047 struct mutex lock;
0048 int adc_max;
0049 bool valid;
0050 unsigned long last_updated;
0051 s16 temp[3];
0052 u16 in[4];
0053 };
0054
0055 static int ad7418_update_device(struct device *dev)
0056 {
0057 struct ad7418_data *data = dev_get_drvdata(dev);
0058 struct i2c_client *client = data->client;
0059 s32 val;
0060
0061 mutex_lock(&data->lock);
0062
0063 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
0064 || !data->valid) {
0065 u8 cfg;
0066 int i, ch;
0067
0068
0069 val = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
0070 if (val < 0)
0071 goto abort;
0072
0073 cfg = val;
0074 cfg &= 0x1F;
0075
0076 val = i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
0077 cfg | AD7418_CH_TEMP);
0078 if (val < 0)
0079 goto abort;
0080
0081 udelay(30);
0082
0083 for (i = 0; i < 3; i++) {
0084 val = i2c_smbus_read_word_swapped(client,
0085 AD7418_REG_TEMP[i]);
0086 if (val < 0)
0087 goto abort;
0088
0089 data->temp[i] = val;
0090 }
0091
0092 for (i = 0, ch = 4; i < data->adc_max; i++, ch--) {
0093 val = i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
0094 cfg | AD7418_REG_ADC_CH(ch));
0095 if (val < 0)
0096 goto abort;
0097
0098 udelay(15);
0099 val = i2c_smbus_read_word_swapped(client,
0100 AD7418_REG_ADC);
0101 if (val < 0)
0102 goto abort;
0103
0104 data->in[data->adc_max - 1 - i] = val;
0105 }
0106
0107
0108 val = i2c_smbus_write_word_swapped(client, AD7418_REG_CONF,
0109 cfg);
0110 if (val < 0)
0111 goto abort;
0112
0113 data->last_updated = jiffies;
0114 data->valid = true;
0115 }
0116
0117 mutex_unlock(&data->lock);
0118 return 0;
0119
0120 abort:
0121 data->valid = false;
0122 mutex_unlock(&data->lock);
0123 return val;
0124 }
0125
0126 static ssize_t temp_show(struct device *dev, struct device_attribute *devattr,
0127 char *buf)
0128 {
0129 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
0130 struct ad7418_data *data = dev_get_drvdata(dev);
0131 int ret;
0132
0133 ret = ad7418_update_device(dev);
0134 if (ret < 0)
0135 return ret;
0136
0137 return sprintf(buf, "%d\n",
0138 LM75_TEMP_FROM_REG(data->temp[attr->index]));
0139 }
0140
0141 static ssize_t adc_show(struct device *dev, struct device_attribute *devattr,
0142 char *buf)
0143 {
0144 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
0145 struct ad7418_data *data = dev_get_drvdata(dev);
0146 int ret;
0147
0148 ret = ad7418_update_device(dev);
0149 if (ret < 0)
0150 return ret;
0151
0152 return sprintf(buf, "%d\n",
0153 ((data->in[attr->index] >> 6) * 2500 + 512) / 1024);
0154 }
0155
0156 static ssize_t temp_store(struct device *dev,
0157 struct device_attribute *devattr, const char *buf,
0158 size_t count)
0159 {
0160 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
0161 struct ad7418_data *data = dev_get_drvdata(dev);
0162 struct i2c_client *client = data->client;
0163 long temp;
0164 int ret = kstrtol(buf, 10, &temp);
0165
0166 if (ret < 0)
0167 return ret;
0168
0169 mutex_lock(&data->lock);
0170 data->temp[attr->index] = LM75_TEMP_TO_REG(temp);
0171 i2c_smbus_write_word_swapped(client,
0172 AD7418_REG_TEMP[attr->index],
0173 data->temp[attr->index]);
0174 mutex_unlock(&data->lock);
0175 return count;
0176 }
0177
0178 static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
0179 static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, temp, 1);
0180 static SENSOR_DEVICE_ATTR_RW(temp1_max, temp, 2);
0181
0182 static SENSOR_DEVICE_ATTR_RO(in1_input, adc, 0);
0183 static SENSOR_DEVICE_ATTR_RO(in2_input, adc, 1);
0184 static SENSOR_DEVICE_ATTR_RO(in3_input, adc, 2);
0185 static SENSOR_DEVICE_ATTR_RO(in4_input, adc, 3);
0186
0187 static struct attribute *ad7416_attrs[] = {
0188 &sensor_dev_attr_temp1_max.dev_attr.attr,
0189 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
0190 &sensor_dev_attr_temp1_input.dev_attr.attr,
0191 NULL
0192 };
0193 ATTRIBUTE_GROUPS(ad7416);
0194
0195 static struct attribute *ad7417_attrs[] = {
0196 &sensor_dev_attr_temp1_max.dev_attr.attr,
0197 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
0198 &sensor_dev_attr_temp1_input.dev_attr.attr,
0199 &sensor_dev_attr_in1_input.dev_attr.attr,
0200 &sensor_dev_attr_in2_input.dev_attr.attr,
0201 &sensor_dev_attr_in3_input.dev_attr.attr,
0202 &sensor_dev_attr_in4_input.dev_attr.attr,
0203 NULL
0204 };
0205 ATTRIBUTE_GROUPS(ad7417);
0206
0207 static struct attribute *ad7418_attrs[] = {
0208 &sensor_dev_attr_temp1_max.dev_attr.attr,
0209 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
0210 &sensor_dev_attr_temp1_input.dev_attr.attr,
0211 &sensor_dev_attr_in1_input.dev_attr.attr,
0212 NULL
0213 };
0214 ATTRIBUTE_GROUPS(ad7418);
0215
0216 static void ad7418_init_client(struct i2c_client *client)
0217 {
0218 struct ad7418_data *data = i2c_get_clientdata(client);
0219
0220 int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
0221 if (reg < 0) {
0222 dev_err(&client->dev, "cannot read configuration register\n");
0223 } else {
0224 dev_info(&client->dev, "configuring for mode 1\n");
0225 i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
0226
0227 if (data->type == ad7417 || data->type == ad7418)
0228 i2c_smbus_write_byte_data(client,
0229 AD7418_REG_CONF2, 0x00);
0230 }
0231 }
0232
0233 static const struct i2c_device_id ad7418_id[];
0234
0235 static int ad7418_probe(struct i2c_client *client)
0236 {
0237 struct device *dev = &client->dev;
0238 struct i2c_adapter *adapter = client->adapter;
0239 struct ad7418_data *data;
0240 struct device *hwmon_dev;
0241 const struct attribute_group **attr_groups = NULL;
0242
0243 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
0244 I2C_FUNC_SMBUS_WORD_DATA))
0245 return -EOPNOTSUPP;
0246
0247 data = devm_kzalloc(dev, sizeof(struct ad7418_data), GFP_KERNEL);
0248 if (!data)
0249 return -ENOMEM;
0250
0251 i2c_set_clientdata(client, data);
0252
0253 mutex_init(&data->lock);
0254 data->client = client;
0255 if (dev->of_node)
0256 data->type = (enum chips)of_device_get_match_data(dev);
0257 else
0258 data->type = i2c_match_id(ad7418_id, client)->driver_data;
0259
0260 switch (data->type) {
0261 case ad7416:
0262 data->adc_max = 0;
0263 attr_groups = ad7416_groups;
0264 break;
0265
0266 case ad7417:
0267 data->adc_max = 4;
0268 attr_groups = ad7417_groups;
0269 break;
0270
0271 case ad7418:
0272 data->adc_max = 1;
0273 attr_groups = ad7418_groups;
0274 break;
0275 }
0276
0277 dev_info(dev, "%s chip found\n", client->name);
0278
0279
0280 ad7418_init_client(client);
0281
0282 hwmon_dev = devm_hwmon_device_register_with_groups(dev,
0283 client->name,
0284 data, attr_groups);
0285 return PTR_ERR_OR_ZERO(hwmon_dev);
0286 }
0287
0288 static const struct i2c_device_id ad7418_id[] = {
0289 { "ad7416", ad7416 },
0290 { "ad7417", ad7417 },
0291 { "ad7418", ad7418 },
0292 { }
0293 };
0294 MODULE_DEVICE_TABLE(i2c, ad7418_id);
0295
0296 static const struct of_device_id ad7418_dt_ids[] = {
0297 { .compatible = "adi,ad7416", .data = (void *)ad7416, },
0298 { .compatible = "adi,ad7417", .data = (void *)ad7417, },
0299 { .compatible = "adi,ad7418", .data = (void *)ad7418, },
0300 { }
0301 };
0302 MODULE_DEVICE_TABLE(of, ad7418_dt_ids);
0303
0304 static struct i2c_driver ad7418_driver = {
0305 .driver = {
0306 .name = "ad7418",
0307 .of_match_table = ad7418_dt_ids,
0308 },
0309 .probe_new = ad7418_probe,
0310 .id_table = ad7418_id,
0311 };
0312
0313 module_i2c_driver(ad7418_driver);
0314
0315 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
0316 MODULE_DESCRIPTION("AD7416/17/18 driver");
0317 MODULE_LICENSE("GPL");
0318 MODULE_VERSION(DRV_VERSION);