aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-04-30 18:15:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-30 18:15:24 -0400
commit151173e8ce9b95bbbbd7eedb9035cfaffbdb7cb2 (patch)
treebca02f40bdd054fa2e30f4923e1513d40873c4d9 /drivers/hwmon
parent30945669593df14692e933c557d00c4bb2727857 (diff)
parent6b170807cd5cac8dc6353f47a88ccb14bbf76c4f (diff)
Merge tag 'for-v3.10' of git://git.infradead.org/battery-2.6
Pull battery updates from Anton Vorontsov: "Highlights: - OpenFirmware/DeviceTree support for the Power Supply core: the core now automatically populates supplied_from hierarchy from the device tree. With these patches chargers and batteries can now lookup each other without the board files support shim. Rhyland Klein at NVIDIA did the work - New ST-Ericsson ABX500 hwmon driver. The driver is heavily using the AB85xx core and depends on some recent changes to it, so that is why the driver comes through the battery tree. It has an appropriate ack from the hwmon maintainer (i.e. Guenter Roeck). Martin Persson at ST-Ericsson and Hongbo Zhang at Linaro authored the driver - Final bits to sync AB85xx ST-Ericsson changes into mainline. The changes touch mfd parts, but these were acked by the appropriate MFD maintainer (ie Samuel Ortiz). Lee Jones at Linaro did most of the work and lead the submission process. Minor changes, but still worth mentioning: - Battery temperature reporting fix for Nokia N900 phones - Versatile Express poweroff driver moved into drivers/power/reset/ - Tree-wide: use devm_kzalloc() where appropriate - Tree-wide: dev_pm_ops cleanups/fixes" * tag 'for-v3.10' of git://git.infradead.org/battery-2.6: (112 commits) pm2301-charger: Fix suspend/resume charger-manager: Use kmemdup instead of kzalloc + memcpy power_supply: Populate supplied_from hierarchy from the device tree power_supply: Add core support for supplied_from power_supply: Define Binding for power-supplies rx51_battery: Fix reporting temperature hwmon: Add ST-Ericsson ABX500 hwmon driver ab8500_bmdata: Export abx500_res_to_temp tables for hwmon ab8500_{bmdata,fg}: Add const attributes to some data arrays ab8500_bmdata: Eliminate CamelCase warning of some variables ab8500_btemp: Make ab8500_btemp_get* interfaces public goldfish_battery: Use resource_size() lp8788-charger: Use PAGE_SIZE for the sysfs read operation max8925_power: Use devm_kzalloc() da9030_battery: Use devm_kzalloc() da9052-battery: Use devm_kzalloc() ds2760_battery: Use devm_kzalloc() ds2780_battery: Use devm_kzalloc() gpio-charger: Use devm_kzalloc() isp1704_charger: Use devm_kzalloc() ...
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig13
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ab8500.c206
-rw-r--r--drivers/hwmon/abx500.c491
-rw-r--r--drivers/hwmon/abx500.h69
5 files changed, 780 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index f61d98a62967..9c333d471433 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -39,6 +39,19 @@ config HWMON_DEBUG_CHIP
39 39
40comment "Native drivers" 40comment "Native drivers"
41 41
42config SENSORS_AB8500
43 tristate "AB8500 thermal monitoring"
44 depends on AB8500_GPADC && AB8500_BM
45 default n
46 help
47 If you say yes here you get support for the thermal sensor part
48 of the AB8500 chip. The driver includes thermal management for
49 AB8500 die and two GPADC channels. The GPADC channel are preferably
50 used to access sensors outside the AB8500 chip.
51
52 This driver can also be built as a module. If so, the module
53 will be called abx500-temp.
54
42config SENSORS_ABITUGURU 55config SENSORS_ABITUGURU
43 tristate "Abit uGuru (rev 1 & 2)" 56 tristate "Abit uGuru (rev 1 & 2)"
44 depends on X86 && DMI 57 depends on X86 && DMI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index c51b0dc35dc8..d17d3e64f9f4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SENSORS_W83795) += w83795.o
19obj-$(CONFIG_SENSORS_W83781D) += w83781d.o 19obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
20obj-$(CONFIG_SENSORS_W83791D) += w83791d.o 20obj-$(CONFIG_SENSORS_W83791D) += w83791d.o
21 21
22obj-$(CONFIG_SENSORS_AB8500) += abx500.o ab8500.o
22obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o 23obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o
23obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o 24obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o
24obj-$(CONFIG_SENSORS_AD7314) += ad7314.o 25obj-$(CONFIG_SENSORS_AD7314) += ad7314.o
diff --git a/drivers/hwmon/ab8500.c b/drivers/hwmon/ab8500.c
new file mode 100644
index 000000000000..d844dc806853
--- /dev/null
+++ b/drivers/hwmon/ab8500.c
@@ -0,0 +1,206 @@
1/*
2 * Copyright (C) ST-Ericsson 2010 - 2013
3 * Author: Martin Persson <martin.persson@stericsson.com>
4 * Hongbo Zhang <hongbo.zhang@linaro.org>
5 * License Terms: GNU General Public License v2
6 *
7 * When the AB8500 thermal warning temperature is reached (threshold cannot
8 * be changed by SW), an interrupt is set, and if no further action is taken
9 * within a certain time frame, pm_power off will be called.
10 *
11 * When AB8500 thermal shutdown temperature is reached a hardware shutdown of
12 * the AB8500 will occur.
13 */
14
15#include <linux/err.h>
16#include <linux/hwmon.h>
17#include <linux/hwmon-sysfs.h>
18#include <linux/mfd/abx500.h>
19#include <linux/mfd/abx500/ab8500-bm.h>
20#include <linux/mfd/abx500/ab8500-gpadc.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/power/ab8500.h>
24#include <linux/slab.h>
25#include <linux/sysfs.h>
26#include "abx500.h"
27
28#define DEFAULT_POWER_OFF_DELAY (HZ * 10)
29#define THERMAL_VCC 1800
30#define PULL_UP_RESISTOR 47000
31/* Number of monitored sensors should not greater than NUM_SENSORS */
32#define NUM_MONITORED_SENSORS 4
33
34struct ab8500_gpadc_cfg {
35 const struct abx500_res_to_temp *temp_tbl;
36 int tbl_sz;
37 int vcc;
38 int r_up;
39};
40
41struct ab8500_temp {
42 struct ab8500_gpadc *gpadc;
43 struct ab8500_btemp *btemp;
44 struct delayed_work power_off_work;
45 struct ab8500_gpadc_cfg cfg;
46 struct abx500_temp *abx500_data;
47};
48
49/*
50 * The hardware connection is like this:
51 * VCC----[ R_up ]-----[ NTC ]----GND
52 * where R_up is pull-up resistance, and GPADC measures voltage on NTC.
53 * and res_to_temp table is strictly sorted by falling resistance values.
54 */
55static int ab8500_voltage_to_temp(struct ab8500_gpadc_cfg *cfg,
56 int v_ntc, int *temp)
57{
58 int r_ntc, i = 0, tbl_sz = cfg->tbl_sz;
59 const struct abx500_res_to_temp *tbl = cfg->temp_tbl;
60
61 if (cfg->vcc < 0 || v_ntc >= cfg->vcc)
62 return -EINVAL;
63
64 r_ntc = v_ntc * cfg->r_up / (cfg->vcc - v_ntc);
65 if (r_ntc > tbl[0].resist || r_ntc < tbl[tbl_sz - 1].resist)
66 return -EINVAL;
67
68 while (!(r_ntc <= tbl[i].resist && r_ntc > tbl[i + 1].resist) &&
69 i < tbl_sz - 2)
70 i++;
71
72 /* return milli-Celsius */
73 *temp = tbl[i].temp * 1000 + ((tbl[i + 1].temp - tbl[i].temp) * 1000 *
74 (r_ntc - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist);
75
76 return 0;
77}
78
79static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp)
80{
81 int voltage, ret;
82 struct ab8500_temp *ab8500_data = data->plat_data;
83
84 if (sensor == BAT_CTRL) {
85 *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp);
86 } else if (sensor == BTEMP_BALL) {
87 *temp = ab8500_btemp_get_temp(ab8500_data->btemp);
88 } else {
89 voltage = ab8500_gpadc_convert(ab8500_data->gpadc, sensor);
90 if (voltage < 0)
91 return voltage;
92
93 ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp);
94 if (ret < 0)
95 return ret;
96 }
97
98 return 0;
99}
100
101static void ab8500_thermal_power_off(struct work_struct *work)
102{
103 struct ab8500_temp *ab8500_data = container_of(work,
104 struct ab8500_temp, power_off_work.work);
105 struct abx500_temp *abx500_data = ab8500_data->abx500_data;
106
107 dev_warn(&abx500_data->pdev->dev, "Power off due to critical temp\n");
108
109 pm_power_off();
110}
111
112static ssize_t ab8500_show_name(struct device *dev,
113 struct device_attribute *devattr, char *buf)
114{
115 return sprintf(buf, "ab8500\n");
116}
117
118static ssize_t ab8500_show_label(struct device *dev,
119 struct device_attribute *devattr, char *buf)
120{
121 char *label;
122 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
123 int index = attr->index;
124
125 switch (index) {
126 case 1:
127 label = "ext_adc1";
128 break;
129 case 2:
130 label = "ext_adc2";
131 break;
132 case 3:
133 label = "bat_temp";
134 break;
135 case 4:
136 label = "bat_ctrl";
137 break;
138 default:
139 return -EINVAL;
140 }
141
142 return sprintf(buf, "%s\n", label);
143}
144
145static int ab8500_temp_irq_handler(int irq, struct abx500_temp *data)
146{
147 struct ab8500_temp *ab8500_data = data->plat_data;
148
149 dev_warn(&data->pdev->dev, "Power off in %d s\n",
150 DEFAULT_POWER_OFF_DELAY / HZ);
151
152 schedule_delayed_work(&ab8500_data->power_off_work,
153 DEFAULT_POWER_OFF_DELAY);
154 return 0;
155}
156
157int abx500_hwmon_init(struct abx500_temp *data)
158{
159 struct ab8500_temp *ab8500_data;
160
161 ab8500_data = devm_kzalloc(&data->pdev->dev, sizeof(*ab8500_data),
162 GFP_KERNEL);
163 if (!ab8500_data)
164 return -ENOMEM;
165
166 ab8500_data->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
167 if (IS_ERR(ab8500_data->gpadc))
168 return PTR_ERR(ab8500_data->gpadc);
169
170 ab8500_data->btemp = ab8500_btemp_get();
171 if (IS_ERR(ab8500_data->btemp))
172 return PTR_ERR(ab8500_data->btemp);
173
174 INIT_DELAYED_WORK(&ab8500_data->power_off_work,
175 ab8500_thermal_power_off);
176
177 ab8500_data->cfg.vcc = THERMAL_VCC;
178 ab8500_data->cfg.r_up = PULL_UP_RESISTOR;
179 ab8500_data->cfg.temp_tbl = ab8500_temp_tbl_a_thermistor;
180 ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size;
181
182 data->plat_data = ab8500_data;
183
184 /*
185 * ADC_AUX1 and ADC_AUX2, connected to external NTC
186 * BTEMP_BALL and BAT_CTRL, fixed usage
187 */
188 data->gpadc_addr[0] = ADC_AUX1;
189 data->gpadc_addr[1] = ADC_AUX2;
190 data->gpadc_addr[2] = BTEMP_BALL;
191 data->gpadc_addr[3] = BAT_CTRL;
192 data->monitored_sensors = NUM_MONITORED_SENSORS;
193
194 data->ops.read_sensor = ab8500_read_sensor;
195 data->ops.irq_handler = ab8500_temp_irq_handler;
196 data->ops.show_name = ab8500_show_name;
197 data->ops.show_label = ab8500_show_label;
198 data->ops.is_visible = NULL;
199
200 return 0;
201}
202EXPORT_SYMBOL(abx500_hwmon_init);
203
204MODULE_AUTHOR("Hongbo Zhang <hongbo.zhang@linaro.org>");
205MODULE_DESCRIPTION("AB8500 temperature driver");
206MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/abx500.c b/drivers/hwmon/abx500.c
new file mode 100644
index 000000000000..b4ad87b31a37
--- /dev/null
+++ b/drivers/hwmon/abx500.c
@@ -0,0 +1,491 @@
1/*
2 * Copyright (C) ST-Ericsson 2010 - 2013
3 * Author: Martin Persson <martin.persson@stericsson.com>
4 * Hongbo Zhang <hongbo.zhang@linaro.org>
5 * License Terms: GNU General Public License v2
6 *
7 * ABX500 does not provide auto ADC, so to monitor the required temperatures,
8 * a periodic work is used. It is more important to not wake up the CPU than
9 * to perform this job, hence the use of a deferred delay.
10 *
11 * A deferred delay for thermal monitor is considered safe because:
12 * If the chip gets too hot during a sleep state it's most likely due to
13 * external factors, such as the surrounding temperature. I.e. no SW decisions
14 * will make any difference.
15 */
16
17#include <linux/err.h>
18#include <linux/hwmon.h>
19#include <linux/hwmon-sysfs.h>
20#include <linux/interrupt.h>
21#include <linux/jiffies.h>
22#include <linux/module.h>
23#include <linux/mutex.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <linux/pm.h>
27#include <linux/slab.h>
28#include <linux/sysfs.h>
29#include <linux/workqueue.h>
30#include "abx500.h"
31
32#define DEFAULT_MONITOR_DELAY HZ
33#define DEFAULT_MAX_TEMP 130
34
35static inline void schedule_monitor(struct abx500_temp *data)
36{
37 data->work_active = true;
38 schedule_delayed_work(&data->work, DEFAULT_MONITOR_DELAY);
39}
40
41static void threshold_updated(struct abx500_temp *data)
42{
43 int i;
44 for (i = 0; i < data->monitored_sensors; i++)
45 if (data->max[i] != 0 || data->min[i] != 0) {
46 schedule_monitor(data);
47 return;
48 }
49
50 dev_dbg(&data->pdev->dev, "No active thresholds.\n");
51 cancel_delayed_work_sync(&data->work);
52 data->work_active = false;
53}
54
55static void gpadc_monitor(struct work_struct *work)
56{
57 int temp, i, ret;
58 char alarm_node[30];
59 bool updated_min_alarm, updated_max_alarm;
60 struct abx500_temp *data;
61
62 data = container_of(work, struct abx500_temp, work.work);
63 mutex_lock(&data->lock);
64
65 for (i = 0; i < data->monitored_sensors; i++) {
66 /* Thresholds are considered inactive if set to 0 */
67 if (data->max[i] == 0 && data->min[i] == 0)
68 continue;
69
70 if (data->max[i] < data->min[i])
71 continue;
72
73 ret = data->ops.read_sensor(data, data->gpadc_addr[i], &temp);
74 if (ret < 0) {
75 dev_err(&data->pdev->dev, "GPADC read failed\n");
76 continue;
77 }
78
79 updated_min_alarm = false;
80 updated_max_alarm = false;
81
82 if (data->min[i] != 0) {
83 if (temp < data->min[i]) {
84 if (data->min_alarm[i] == false) {
85 data->min_alarm[i] = true;
86 updated_min_alarm = true;
87 }
88 } else {
89 if (data->min_alarm[i] == true) {
90 data->min_alarm[i] = false;
91 updated_min_alarm = true;
92 }
93 }
94 }
95 if (data->max[i] != 0) {
96 if (temp > data->max[i]) {
97 if (data->max_alarm[i] == false) {
98 data->max_alarm[i] = true;
99 updated_max_alarm = true;
100 }
101 } else if (temp < data->max[i] - data->max_hyst[i]) {
102 if (data->max_alarm[i] == true) {
103 data->max_alarm[i] = false;
104 updated_max_alarm = true;
105 }
106 }
107 }
108
109 if (updated_min_alarm) {
110 ret = sprintf(alarm_node, "temp%d_min_alarm", i + 1);
111 sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node);
112 }
113 if (updated_max_alarm) {
114 ret = sprintf(alarm_node, "temp%d_max_alarm", i + 1);
115 sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node);
116 }
117 }
118
119 schedule_monitor(data);
120 mutex_unlock(&data->lock);
121}
122
123/* HWMON sysfs interfaces */
124static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
125 char *buf)
126{
127 struct abx500_temp *data = dev_get_drvdata(dev);
128 /* Show chip name */
129 return data->ops.show_name(dev, devattr, buf);
130}
131
132static ssize_t show_label(struct device *dev,
133 struct device_attribute *devattr, char *buf)
134{
135 struct abx500_temp *data = dev_get_drvdata(dev);
136 /* Show each sensor label */
137 return data->ops.show_label(dev, devattr, buf);
138}
139
140static ssize_t show_input(struct device *dev,
141 struct device_attribute *devattr, char *buf)
142{
143 int ret, temp;
144 struct abx500_temp *data = dev_get_drvdata(dev);
145 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
146 u8 gpadc_addr = data->gpadc_addr[attr->index];
147
148 ret = data->ops.read_sensor(data, gpadc_addr, &temp);
149 if (ret < 0)
150 return ret;
151
152 return sprintf(buf, "%d\n", temp);
153}
154
155/* Set functions (RW nodes) */
156static ssize_t set_min(struct device *dev, struct device_attribute *devattr,
157 const char *buf, size_t count)
158{
159 unsigned long val;
160 struct abx500_temp *data = dev_get_drvdata(dev);
161 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
162 int res = kstrtol(buf, 10, &val);
163 if (res < 0)
164 return res;
165
166 val = clamp_val(val, 0, DEFAULT_MAX_TEMP);
167
168 mutex_lock(&data->lock);
169 data->min[attr->index] = val;
170 threshold_updated(data);
171 mutex_unlock(&data->lock);
172
173 return count;
174}
175
176static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
177 const char *buf, size_t count)
178{
179 unsigned long val;
180 struct abx500_temp *data = dev_get_drvdata(dev);
181 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
182 int res = kstrtol(buf, 10, &val);
183 if (res < 0)
184 return res;
185
186 val = clamp_val(val, 0, DEFAULT_MAX_TEMP);
187
188 mutex_lock(&data->lock);
189 data->max[attr->index] = val;
190 threshold_updated(data);
191 mutex_unlock(&data->lock);
192
193 return count;
194}
195
196static ssize_t set_max_hyst(struct device *dev,
197 struct device_attribute *devattr,
198 const char *buf, size_t count)
199{
200 unsigned long val;
201 struct abx500_temp *data = dev_get_drvdata(dev);
202 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
203 int res = kstrtoul(buf, 10, &val);
204 if (res < 0)
205 return res;
206
207 val = clamp_val(val, 0, DEFAULT_MAX_TEMP);
208
209 mutex_lock(&data->lock);
210 data->max_hyst[attr->index] = val;
211 threshold_updated(data);
212 mutex_unlock(&data->lock);
213
214 return count;
215}
216
217/* Show functions (RO nodes) */
218static ssize_t show_min(struct device *dev,
219 struct device_attribute *devattr, char *buf)
220{
221 struct abx500_temp *data = dev_get_drvdata(dev);
222 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
223
224 return sprintf(buf, "%ld\n", data->min[attr->index]);
225}
226
227static ssize_t show_max(struct device *dev,
228 struct device_attribute *devattr, char *buf)
229{
230 struct abx500_temp *data = dev_get_drvdata(dev);
231 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
232
233 return sprintf(buf, "%ld\n", data->max[attr->index]);
234}
235
236static ssize_t show_max_hyst(struct device *dev,
237 struct device_attribute *devattr, char *buf)
238{
239 struct abx500_temp *data = dev_get_drvdata(dev);
240 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
241
242 return sprintf(buf, "%ld\n", data->max_hyst[attr->index]);
243}
244
245static ssize_t show_min_alarm(struct device *dev,
246 struct device_attribute *devattr, char *buf)
247{
248 struct abx500_temp *data = dev_get_drvdata(dev);
249 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
250
251 return sprintf(buf, "%d\n", data->min_alarm[attr->index]);
252}
253
254static ssize_t show_max_alarm(struct device *dev,
255 struct device_attribute *devattr, char *buf)
256{
257 struct abx500_temp *data = dev_get_drvdata(dev);
258 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
259
260 return sprintf(buf, "%d\n", data->max_alarm[attr->index]);
261}
262
263static mode_t abx500_attrs_visible(struct kobject *kobj,
264 struct attribute *attr, int n)
265{
266 struct device *dev = container_of(kobj, struct device, kobj);
267 struct abx500_temp *data = dev_get_drvdata(dev);
268
269 if (data->ops.is_visible)
270 return data->ops.is_visible(attr, n);
271
272 return attr->mode;
273}
274
275/* Chip name, required by hwmon */
276static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
277
278/* GPADC - SENSOR1 */
279static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL, 0);
280static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0);
281static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_min, set_min, 0);
282static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_max, set_max, 0);
283static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
284 show_max_hyst, set_max_hyst, 0);
285static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_min_alarm, NULL, 0);
286static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_max_alarm, NULL, 0);
287
288/* GPADC - SENSOR2 */
289static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, 1);
290static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 1);
291static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min, 1);
292static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max, 1);
293static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IWUSR | S_IRUGO,
294 show_max_hyst, set_max_hyst, 1);
295static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_min_alarm, NULL, 1);
296static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_max_alarm, NULL, 1);
297
298/* GPADC - SENSOR3 */
299static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_label, NULL, 2);
300static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 2);
301static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min, 2);
302static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max, 2);
303static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IWUSR | S_IRUGO,
304 show_max_hyst, set_max_hyst, 2);
305static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_min_alarm, NULL, 2);
306static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_max_alarm, NULL, 2);
307
308/* GPADC - SENSOR4 */
309static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_label, NULL, 3);
310static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_input, NULL, 3);
311static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_min, set_min, 3);
312static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_max, set_max, 3);
313static SENSOR_DEVICE_ATTR(temp4_max_hyst, S_IWUSR | S_IRUGO,
314 show_max_hyst, set_max_hyst, 3);
315static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO, show_min_alarm, NULL, 3);
316static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_max_alarm, NULL, 3);
317
318struct attribute *abx500_temp_attributes[] = {
319 &sensor_dev_attr_name.dev_attr.attr,
320
321 &sensor_dev_attr_temp1_label.dev_attr.attr,
322 &sensor_dev_attr_temp1_input.dev_attr.attr,
323 &sensor_dev_attr_temp1_min.dev_attr.attr,
324 &sensor_dev_attr_temp1_max.dev_attr.attr,
325 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
326 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
327 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
328
329 &sensor_dev_attr_temp2_label.dev_attr.attr,
330 &sensor_dev_attr_temp2_input.dev_attr.attr,
331 &sensor_dev_attr_temp2_min.dev_attr.attr,
332 &sensor_dev_attr_temp2_max.dev_attr.attr,
333 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
334 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
335 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
336
337 &sensor_dev_attr_temp3_label.dev_attr.attr,
338 &sensor_dev_attr_temp3_input.dev_attr.attr,
339 &sensor_dev_attr_temp3_min.dev_attr.attr,
340 &sensor_dev_attr_temp3_max.dev_attr.attr,
341 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
342 &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
343 &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
344
345 &sensor_dev_attr_temp4_label.dev_attr.attr,
346 &sensor_dev_attr_temp4_input.dev_attr.attr,
347 &sensor_dev_attr_temp4_min.dev_attr.attr,
348 &sensor_dev_attr_temp4_max.dev_attr.attr,
349 &sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
350 &sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
351 &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
352 NULL
353};
354
355static const struct attribute_group abx500_temp_group = {
356 .attrs = abx500_temp_attributes,
357 .is_visible = abx500_attrs_visible,
358};
359
360static irqreturn_t abx500_temp_irq_handler(int irq, void *irq_data)
361{
362 struct platform_device *pdev = irq_data;
363 struct abx500_temp *data = platform_get_drvdata(pdev);
364
365 data->ops.irq_handler(irq, data);
366 return IRQ_HANDLED;
367}
368
369static int setup_irqs(struct platform_device *pdev)
370{
371 int ret;
372 int irq = platform_get_irq_byname(pdev, "ABX500_TEMP_WARM");
373
374 if (irq < 0) {
375 dev_err(&pdev->dev, "Get irq by name failed\n");
376 return irq;
377 }
378
379 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
380 abx500_temp_irq_handler, IRQF_NO_SUSPEND, "abx500-temp", pdev);
381 if (ret < 0)
382 dev_err(&pdev->dev, "Request threaded irq failed (%d)\n", ret);
383
384 return ret;
385}
386
387static int abx500_temp_probe(struct platform_device *pdev)
388{
389 struct abx500_temp *data;
390 int err;
391
392 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
393 if (!data)
394 return -ENOMEM;
395
396 data->pdev = pdev;
397 mutex_init(&data->lock);
398
399 /* Chip specific initialization */
400 err = abx500_hwmon_init(data);
401 if (err < 0 || !data->ops.read_sensor || !data->ops.show_name ||
402 !data->ops.show_label)
403 return err;
404
405 INIT_DEFERRABLE_WORK(&data->work, gpadc_monitor);
406
407 platform_set_drvdata(pdev, data);
408
409 err = sysfs_create_group(&pdev->dev.kobj, &abx500_temp_group);
410 if (err < 0) {
411 dev_err(&pdev->dev, "Create sysfs group failed (%d)\n", err);
412 return err;
413 }
414
415 data->hwmon_dev = hwmon_device_register(&pdev->dev);
416 if (IS_ERR(data->hwmon_dev)) {
417 err = PTR_ERR(data->hwmon_dev);
418 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
419 goto exit_sysfs_group;
420 }
421
422 if (data->ops.irq_handler) {
423 err = setup_irqs(pdev);
424 if (err < 0)
425 goto exit_hwmon_reg;
426 }
427 return 0;
428
429exit_hwmon_reg:
430 hwmon_device_unregister(data->hwmon_dev);
431exit_sysfs_group:
432 sysfs_remove_group(&pdev->dev.kobj, &abx500_temp_group);
433 return err;
434}
435
436static int abx500_temp_remove(struct platform_device *pdev)
437{
438 struct abx500_temp *data = platform_get_drvdata(pdev);
439
440 cancel_delayed_work_sync(&data->work);
441 hwmon_device_unregister(data->hwmon_dev);
442 sysfs_remove_group(&pdev->dev.kobj, &abx500_temp_group);
443
444 return 0;
445}
446
447static int abx500_temp_suspend(struct platform_device *pdev,
448 pm_message_t state)
449{
450 struct abx500_temp *data = platform_get_drvdata(pdev);
451
452 if (data->work_active)
453 cancel_delayed_work_sync(&data->work);
454
455 return 0;
456}
457
458static int abx500_temp_resume(struct platform_device *pdev)
459{
460 struct abx500_temp *data = platform_get_drvdata(pdev);
461
462 if (data->work_active)
463 schedule_monitor(data);
464
465 return 0;
466}
467
468#ifdef CONFIG_OF
469static const struct of_device_id abx500_temp_match[] = {
470 { .compatible = "stericsson,abx500-temp" },
471 {},
472};
473#endif
474
475static struct platform_driver abx500_temp_driver = {
476 .driver = {
477 .owner = THIS_MODULE,
478 .name = "abx500-temp",
479 .of_match_table = of_match_ptr(abx500_temp_match),
480 },
481 .suspend = abx500_temp_suspend,
482 .resume = abx500_temp_resume,
483 .probe = abx500_temp_probe,
484 .remove = abx500_temp_remove,
485};
486
487module_platform_driver(abx500_temp_driver);
488
489MODULE_AUTHOR("Martin Persson <martin.persson@stericsson.com>");
490MODULE_DESCRIPTION("ABX500 temperature driver");
491MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/abx500.h b/drivers/hwmon/abx500.h
new file mode 100644
index 000000000000..9b295e684d0e
--- /dev/null
+++ b/drivers/hwmon/abx500.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) ST-Ericsson 2010 - 2013
3 * License terms: GNU General Public License v2
4 * Author: Martin Persson <martin.persson@stericsson.com>
5 * Hongbo Zhang <hongbo.zhang@linaro.com>
6 */
7
8#ifndef _ABX500_H
9#define _ABX500_H
10
11#define NUM_SENSORS 5
12
13struct abx500_temp;
14
15/*
16 * struct abx500_temp_ops - abx500 chip specific ops
17 * @read_sensor: reads gpadc output
18 * @irq_handler: irq handler
19 * @show_name: hwmon device name
20 * @show_label: hwmon attribute label
21 * @is_visible: is attribute visible
22 */
23struct abx500_temp_ops {
24 int (*read_sensor)(struct abx500_temp *, u8, int *);
25 int (*irq_handler)(int, struct abx500_temp *);
26 ssize_t (*show_name)(struct device *,
27 struct device_attribute *, char *);
28 ssize_t (*show_label) (struct device *,
29 struct device_attribute *, char *);
30 int (*is_visible)(struct attribute *, int);
31};
32
33/*
34 * struct abx500_temp - representation of temp mon device
35 * @pdev: platform device
36 * @hwmon_dev: hwmon device
37 * @ops: abx500 chip specific ops
38 * @gpadc_addr: gpadc channel address
39 * @min: sensor temperature min value
40 * @max: sensor temperature max value
41 * @max_hyst: sensor temperature hysteresis value for max limit
42 * @min_alarm: sensor temperature min alarm
43 * @max_alarm: sensor temperature max alarm
44 * @work: delayed work scheduled to monitor temperature periodically
45 * @work_active: True if work is active
46 * @lock: mutex
47 * @monitored_sensors: number of monitored sensors
48 * @plat_data: private usage, usually points to platform specific data
49 */
50struct abx500_temp {
51 struct platform_device *pdev;
52 struct device *hwmon_dev;
53 struct abx500_temp_ops ops;
54 u8 gpadc_addr[NUM_SENSORS];
55 unsigned long min[NUM_SENSORS];
56 unsigned long max[NUM_SENSORS];
57 unsigned long max_hyst[NUM_SENSORS];
58 bool min_alarm[NUM_SENSORS];
59 bool max_alarm[NUM_SENSORS];
60 struct delayed_work work;
61 bool work_active;
62 struct mutex lock;
63 int monitored_sensors;
64 void *plat_data;
65};
66
67int abx500_hwmon_init(struct abx500_temp *data);
68
69#endif /* _ABX500_H */