0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/device.h>
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/slab.h>
0015 #include <linux/jiffies.h>
0016 #include <linux/hwmon.h>
0017 #include <linux/err.h>
0018 #include <linux/mutex.h>
0019 #include <linux/delay.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/regmap.h>
0022
0023 #include "adt7x10.h"
0024
0025
0026
0027
0028 #define ADT7X10_STAT_T_LOW (1 << 4)
0029 #define ADT7X10_STAT_T_HIGH (1 << 5)
0030 #define ADT7X10_STAT_T_CRIT (1 << 6)
0031 #define ADT7X10_STAT_NOT_RDY (1 << 7)
0032
0033
0034
0035
0036 #define ADT7X10_FAULT_QUEUE_MASK (1 << 0 | 1 << 1)
0037 #define ADT7X10_CT_POLARITY (1 << 2)
0038 #define ADT7X10_INT_POLARITY (1 << 3)
0039 #define ADT7X10_EVENT_MODE (1 << 4)
0040 #define ADT7X10_MODE_MASK (1 << 5 | 1 << 6)
0041 #define ADT7X10_FULL (0 << 5 | 0 << 6)
0042 #define ADT7X10_PD (1 << 5 | 1 << 6)
0043 #define ADT7X10_RESOLUTION (1 << 7)
0044
0045
0046
0047
0048 #define ADT7X10_T13_VALUE_MASK 0xFFF8
0049 #define ADT7X10_T_HYST_MASK 0xF
0050
0051
0052 #define ADT7X10_TEMP_MIN (-55000)
0053 #define ADT7X10_TEMP_MAX 150000
0054
0055
0056 struct adt7x10_data {
0057 struct regmap *regmap;
0058 struct mutex update_lock;
0059 u8 config;
0060 u8 oldconfig;
0061 bool valid;
0062 };
0063
0064 enum {
0065 adt7x10_temperature = 0,
0066 adt7x10_t_alarm_high,
0067 adt7x10_t_alarm_low,
0068 adt7x10_t_crit,
0069 };
0070
0071 static const u8 ADT7X10_REG_TEMP[] = {
0072 [adt7x10_temperature] = ADT7X10_TEMPERATURE,
0073 [adt7x10_t_alarm_high] = ADT7X10_T_ALARM_HIGH,
0074 [adt7x10_t_alarm_low] = ADT7X10_T_ALARM_LOW,
0075 [adt7x10_t_crit] = ADT7X10_T_CRIT,
0076 };
0077
0078 static irqreturn_t adt7x10_irq_handler(int irq, void *private)
0079 {
0080 struct device *dev = private;
0081 struct adt7x10_data *d = dev_get_drvdata(dev);
0082 unsigned int status;
0083 int ret;
0084
0085 ret = regmap_read(d->regmap, ADT7X10_STATUS, &status);
0086 if (ret < 0)
0087 return IRQ_HANDLED;
0088
0089 if (status & ADT7X10_STAT_T_HIGH)
0090 hwmon_notify_event(dev, hwmon_temp, hwmon_temp_max_alarm, 0);
0091 if (status & ADT7X10_STAT_T_LOW)
0092 hwmon_notify_event(dev, hwmon_temp, hwmon_temp_min_alarm, 0);
0093 if (status & ADT7X10_STAT_T_CRIT)
0094 hwmon_notify_event(dev, hwmon_temp, hwmon_temp_crit_alarm, 0);
0095
0096 return IRQ_HANDLED;
0097 }
0098
0099 static int adt7x10_temp_ready(struct regmap *regmap)
0100 {
0101 unsigned int status;
0102 int i, ret;
0103
0104 for (i = 0; i < 6; i++) {
0105 ret = regmap_read(regmap, ADT7X10_STATUS, &status);
0106 if (ret < 0)
0107 return ret;
0108 if (!(status & ADT7X10_STAT_NOT_RDY))
0109 return 0;
0110 msleep(60);
0111 }
0112 return -ETIMEDOUT;
0113 }
0114
0115 static s16 ADT7X10_TEMP_TO_REG(long temp)
0116 {
0117 return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7X10_TEMP_MIN,
0118 ADT7X10_TEMP_MAX) * 128, 1000);
0119 }
0120
0121 static int ADT7X10_REG_TO_TEMP(struct adt7x10_data *data, s16 reg)
0122 {
0123
0124 if (!(data->config & ADT7X10_RESOLUTION))
0125 reg &= ADT7X10_T13_VALUE_MASK;
0126
0127
0128
0129
0130 return DIV_ROUND_CLOSEST(reg * 1000, 128);
0131 }
0132
0133
0134
0135 static int adt7x10_temp_read(struct adt7x10_data *data, int index, long *val)
0136 {
0137 unsigned int regval;
0138 int ret;
0139
0140 mutex_lock(&data->update_lock);
0141 if (index == adt7x10_temperature && !data->valid) {
0142
0143 ret = adt7x10_temp_ready(data->regmap);
0144 if (ret) {
0145 mutex_unlock(&data->update_lock);
0146 return ret;
0147 }
0148 data->valid = true;
0149 }
0150 mutex_unlock(&data->update_lock);
0151
0152 ret = regmap_read(data->regmap, ADT7X10_REG_TEMP[index], ®val);
0153 if (ret)
0154 return ret;
0155
0156 *val = ADT7X10_REG_TO_TEMP(data, regval);
0157 return 0;
0158 }
0159
0160 static int adt7x10_temp_write(struct adt7x10_data *data, int index, long temp)
0161 {
0162 int ret;
0163
0164 mutex_lock(&data->update_lock);
0165 ret = regmap_write(data->regmap, ADT7X10_REG_TEMP[index],
0166 ADT7X10_TEMP_TO_REG(temp));
0167 mutex_unlock(&data->update_lock);
0168 return ret;
0169 }
0170
0171 static int adt7x10_hyst_read(struct adt7x10_data *data, int index, long *val)
0172 {
0173 int hyst, temp, ret;
0174
0175 mutex_lock(&data->update_lock);
0176 ret = regmap_read(data->regmap, ADT7X10_T_HYST, &hyst);
0177 if (ret) {
0178 mutex_unlock(&data->update_lock);
0179 return ret;
0180 }
0181
0182 ret = regmap_read(data->regmap, ADT7X10_REG_TEMP[index], &temp);
0183 mutex_unlock(&data->update_lock);
0184 if (ret)
0185 return ret;
0186
0187 hyst = (hyst & ADT7X10_T_HYST_MASK) * 1000;
0188
0189
0190
0191
0192
0193
0194 if (index == adt7x10_t_alarm_low)
0195 hyst = -hyst;
0196
0197 *val = ADT7X10_REG_TO_TEMP(data, temp) - hyst;
0198 return 0;
0199 }
0200
0201 static int adt7x10_hyst_write(struct adt7x10_data *data, long hyst)
0202 {
0203 unsigned int regval;
0204 int limit, ret;
0205
0206 mutex_lock(&data->update_lock);
0207
0208
0209 ret = regmap_read(data->regmap, ADT7X10_T_ALARM_HIGH, ®val);
0210 if (ret < 0)
0211 goto abort;
0212
0213 limit = ADT7X10_REG_TO_TEMP(data, regval);
0214
0215 hyst = clamp_val(hyst, ADT7X10_TEMP_MIN, ADT7X10_TEMP_MAX);
0216 regval = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), 0,
0217 ADT7X10_T_HYST_MASK);
0218 ret = regmap_write(data->regmap, ADT7X10_T_HYST, regval);
0219 abort:
0220 mutex_unlock(&data->update_lock);
0221 return ret;
0222 }
0223
0224 static int adt7x10_alarm_read(struct adt7x10_data *data, int index, long *val)
0225 {
0226 unsigned int status;
0227 int ret;
0228
0229 ret = regmap_read(data->regmap, ADT7X10_STATUS, &status);
0230 if (ret < 0)
0231 return ret;
0232
0233 *val = !!(status & index);
0234
0235 return 0;
0236 }
0237
0238 static umode_t adt7x10_is_visible(const void *data,
0239 enum hwmon_sensor_types type,
0240 u32 attr, int channel)
0241 {
0242 switch (attr) {
0243 case hwmon_temp_max:
0244 case hwmon_temp_min:
0245 case hwmon_temp_crit:
0246 case hwmon_temp_max_hyst:
0247 return 0644;
0248 case hwmon_temp_input:
0249 case hwmon_temp_min_alarm:
0250 case hwmon_temp_max_alarm:
0251 case hwmon_temp_crit_alarm:
0252 case hwmon_temp_min_hyst:
0253 case hwmon_temp_crit_hyst:
0254 return 0444;
0255 default:
0256 break;
0257 }
0258
0259 return 0;
0260 }
0261
0262 static int adt7x10_read(struct device *dev, enum hwmon_sensor_types type,
0263 u32 attr, int channel, long *val)
0264 {
0265 struct adt7x10_data *data = dev_get_drvdata(dev);
0266
0267 switch (attr) {
0268 case hwmon_temp_input:
0269 return adt7x10_temp_read(data, adt7x10_temperature, val);
0270 case hwmon_temp_max:
0271 return adt7x10_temp_read(data, adt7x10_t_alarm_high, val);
0272 case hwmon_temp_min:
0273 return adt7x10_temp_read(data, adt7x10_t_alarm_low, val);
0274 case hwmon_temp_crit:
0275 return adt7x10_temp_read(data, adt7x10_t_crit, val);
0276 case hwmon_temp_max_hyst:
0277 return adt7x10_hyst_read(data, adt7x10_t_alarm_high, val);
0278 case hwmon_temp_min_hyst:
0279 return adt7x10_hyst_read(data, adt7x10_t_alarm_low, val);
0280 case hwmon_temp_crit_hyst:
0281 return adt7x10_hyst_read(data, adt7x10_t_crit, val);
0282 case hwmon_temp_min_alarm:
0283 return adt7x10_alarm_read(data, ADT7X10_STAT_T_LOW, val);
0284 case hwmon_temp_max_alarm:
0285 return adt7x10_alarm_read(data, ADT7X10_STAT_T_HIGH, val);
0286 case hwmon_temp_crit_alarm:
0287 return adt7x10_alarm_read(data, ADT7X10_STAT_T_CRIT, val);
0288 default:
0289 return -EOPNOTSUPP;
0290 }
0291 }
0292
0293 static int adt7x10_write(struct device *dev, enum hwmon_sensor_types type,
0294 u32 attr, int channel, long val)
0295 {
0296 struct adt7x10_data *data = dev_get_drvdata(dev);
0297
0298 switch (attr) {
0299 case hwmon_temp_max:
0300 return adt7x10_temp_write(data, adt7x10_t_alarm_high, val);
0301 case hwmon_temp_min:
0302 return adt7x10_temp_write(data, adt7x10_t_alarm_low, val);
0303 case hwmon_temp_crit:
0304 return adt7x10_temp_write(data, adt7x10_t_crit, val);
0305 case hwmon_temp_max_hyst:
0306 return adt7x10_hyst_write(data, val);
0307 default:
0308 return -EOPNOTSUPP;
0309 }
0310 }
0311
0312 static const struct hwmon_channel_info *adt7x10_info[] = {
0313 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN |
0314 HWMON_T_CRIT | HWMON_T_MAX_HYST | HWMON_T_MIN_HYST |
0315 HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
0316 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM),
0317 NULL,
0318 };
0319
0320 static const struct hwmon_ops adt7x10_hwmon_ops = {
0321 .is_visible = adt7x10_is_visible,
0322 .read = adt7x10_read,
0323 .write = adt7x10_write,
0324 };
0325
0326 static const struct hwmon_chip_info adt7x10_chip_info = {
0327 .ops = &adt7x10_hwmon_ops,
0328 .info = adt7x10_info,
0329 };
0330
0331 static void adt7x10_restore_config(void *private)
0332 {
0333 struct adt7x10_data *data = private;
0334
0335 regmap_write(data->regmap, ADT7X10_CONFIG, data->oldconfig);
0336 }
0337
0338 int adt7x10_probe(struct device *dev, const char *name, int irq,
0339 struct regmap *regmap)
0340 {
0341 struct adt7x10_data *data;
0342 unsigned int config;
0343 struct device *hdev;
0344 int ret;
0345
0346 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0347 if (!data)
0348 return -ENOMEM;
0349
0350 data->regmap = regmap;
0351
0352 dev_set_drvdata(dev, data);
0353 mutex_init(&data->update_lock);
0354
0355
0356 ret = regmap_read(regmap, ADT7X10_CONFIG, &config);
0357 if (ret < 0) {
0358 dev_dbg(dev, "Can't read config? %d\n", ret);
0359 return ret;
0360 }
0361 data->oldconfig = config;
0362
0363
0364
0365
0366 data->config = data->oldconfig;
0367 data->config &= ~(ADT7X10_MODE_MASK | ADT7X10_CT_POLARITY |
0368 ADT7X10_INT_POLARITY);
0369 data->config |= ADT7X10_FULL | ADT7X10_RESOLUTION | ADT7X10_EVENT_MODE;
0370
0371 if (data->config != data->oldconfig) {
0372 ret = regmap_write(regmap, ADT7X10_CONFIG, data->config);
0373 if (ret)
0374 return ret;
0375 ret = devm_add_action_or_reset(dev, adt7x10_restore_config, data);
0376 if (ret)
0377 return ret;
0378 }
0379 dev_dbg(dev, "Config %02x\n", data->config);
0380
0381 hdev = devm_hwmon_device_register_with_info(dev, name, data,
0382 &adt7x10_chip_info, NULL);
0383 if (IS_ERR(hdev))
0384 return PTR_ERR(hdev);
0385
0386 if (irq > 0) {
0387 ret = devm_request_threaded_irq(dev, irq, NULL,
0388 adt7x10_irq_handler,
0389 IRQF_TRIGGER_FALLING |
0390 IRQF_ONESHOT,
0391 dev_name(dev), hdev);
0392 if (ret)
0393 return ret;
0394 }
0395
0396 return 0;
0397 }
0398 EXPORT_SYMBOL_GPL(adt7x10_probe);
0399
0400 #ifdef CONFIG_PM_SLEEP
0401
0402 static int adt7x10_suspend(struct device *dev)
0403 {
0404 struct adt7x10_data *data = dev_get_drvdata(dev);
0405
0406 return regmap_write(data->regmap, ADT7X10_CONFIG,
0407 data->config | ADT7X10_PD);
0408 }
0409
0410 static int adt7x10_resume(struct device *dev)
0411 {
0412 struct adt7x10_data *data = dev_get_drvdata(dev);
0413
0414 return regmap_write(data->regmap, ADT7X10_CONFIG, data->config);
0415 }
0416
0417 SIMPLE_DEV_PM_OPS(adt7x10_dev_pm_ops, adt7x10_suspend, adt7x10_resume);
0418 EXPORT_SYMBOL_GPL(adt7x10_dev_pm_ops);
0419
0420 #endif
0421
0422 MODULE_AUTHOR("Hartmut Knaack");
0423 MODULE_DESCRIPTION("ADT7410/ADT7420, ADT7310/ADT7320 common code");
0424 MODULE_LICENSE("GPL");