2 * Copyright (C) rockchip 2014
3 * Author:zhangqing <zhangqing@rock-chips.com>
5 * License Terms: GNU General Public License v2
7 * rockchip tsadc does not provide auto tsADC, 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.
13 #include <linux/err.h>
14 #include <linux/hwmon.h>
15 #include <linux/hwmon-sysfs.h>
16 #include <linux/interrupt.h>
17 #include <linux/jiffies.h>
18 #include <linux/module.h>
19 #include <linux/mutex.h>
21 #include <linux/platform_device.h>
23 #include <linux/slab.h>
24 #include <linux/sysfs.h>
25 #include <linux/workqueue.h>
26 #include "hwmon-rockchip.h"
29 #define DEFAULT_MONITOR_DELAY HZ
30 #define DEFAULT_MAX_TEMP 130
32 static inline void schedule_monitor(struct rockchip_temp *data)
34 data->work_active = true;
35 schedule_delayed_work(&data->work, DEFAULT_MONITOR_DELAY);
38 static void threshold_updated(struct rockchip_temp *data)
41 for (i = 0; i < data->monitored_sensors; i++)
42 if (data->max[i] != 0 || data->min[i] != 0) {
43 schedule_monitor(data);
47 dev_dbg(&data->pdev->dev, "No active thresholds.\n");
48 cancel_delayed_work_sync(&data->work);
49 data->work_active = false;
52 static void tsadc_monitor(struct work_struct *work)
56 bool updated_min_alarm, updated_max_alarm;
57 struct rockchip_temp *data;
59 data = container_of(work, struct rockchip_temp, work.work);
60 mutex_lock(&data->lock);
62 for (i = 0; i < data->monitored_sensors; i++) {
63 /* Thresholds are considered inactive if set to 0 */
64 if (data->max[i] == 0 && data->min[i] == 0)
67 if (data->max[i] < data->min[i])
70 temp = data->ops.read_sensor(i);
72 dev_err(&data->pdev->dev, "TSADC read failed\n");
76 updated_min_alarm = false;
77 updated_max_alarm = false;
79 if (data->min[i] != 0) {
80 if (temp < data->min[i]) {
81 if (data->min_alarm[i] == false) {
82 data->min_alarm[i] = true;
83 updated_min_alarm = true;
86 if (data->min_alarm[i] == true) {
87 data->min_alarm[i] = false;
88 updated_min_alarm = true;
92 if (data->max[i] != 0) {
93 if (temp > data->max[i]) {
94 if (data->max_alarm[i] == false) {
95 data->max_alarm[i] = true;
96 updated_max_alarm = true;
98 } else if (temp < data->max[i] - data->max_hyst[i]) {
99 if (data->max_alarm[i] == true) {
100 data->max_alarm[i] = false;
101 updated_max_alarm = true;
106 if (updated_min_alarm) {
107 ret = sprintf(alarm_node, "temp%d_min_alarm", i + 1);
108 sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node);
110 if (updated_max_alarm) {
111 ret = sprintf(alarm_node, "temp%d_max_alarm", i + 1);
112 sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node);
116 schedule_monitor(data);
117 mutex_unlock(&data->lock);
120 /* HWMON sysfs interfaces */
121 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
124 struct rockchip_temp *data = dev_get_drvdata(dev);
126 return data->ops.show_name(dev, devattr, buf);
129 static ssize_t show_label(struct device *dev,
130 struct device_attribute *devattr, char *buf)
132 struct rockchip_temp *data = dev_get_drvdata(dev);
133 /* Show each sensor label */
134 return data->ops.show_label(dev, devattr, buf);
137 static ssize_t show_input(struct device *dev,
138 struct device_attribute *devattr, char *buf)
141 struct rockchip_temp *data = dev_get_drvdata(dev);
142 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
144 temp = data->ops.read_sensor(attr->index);
146 return sprintf(buf, "%d\n", temp);
149 /* Set functions (RW nodes) */
150 static ssize_t set_min(struct device *dev, struct device_attribute *devattr,
151 const char *buf, size_t count)
154 struct rockchip_temp *data = dev_get_drvdata(dev);
155 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
156 int res = kstrtol(buf, 10, &val);
160 val = clamp_val(val, 0, DEFAULT_MAX_TEMP);
162 mutex_lock(&data->lock);
163 data->min[attr->index] = val;
164 threshold_updated(data);
165 mutex_unlock(&data->lock);
170 static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
171 const char *buf, size_t count)
174 struct rockchip_temp *data = dev_get_drvdata(dev);
175 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
176 int res = kstrtol(buf, 10, &val);
180 val = clamp_val(val, 0, DEFAULT_MAX_TEMP);
182 mutex_lock(&data->lock);
183 data->max[attr->index] = val;
184 threshold_updated(data);
185 mutex_unlock(&data->lock);
190 static ssize_t set_max_hyst(struct device *dev,
191 struct device_attribute *devattr,
192 const char *buf, size_t count)
195 struct rockchip_temp *data = dev_get_drvdata(dev);
196 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
197 int res = kstrtoul(buf, 10, &val);
201 val = clamp_val(val, 0, DEFAULT_MAX_TEMP);
203 mutex_lock(&data->lock);
204 data->max_hyst[attr->index] = val;
205 threshold_updated(data);
206 mutex_unlock(&data->lock);
211 /* Show functions (RO nodes) */
212 static ssize_t show_min(struct device *dev,
213 struct device_attribute *devattr, char *buf)
215 struct rockchip_temp *data = dev_get_drvdata(dev);
216 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
218 return sprintf(buf, "%ld\n", data->min[attr->index]);
221 static ssize_t show_max(struct device *dev,
222 struct device_attribute *devattr, char *buf)
224 struct rockchip_temp *data = dev_get_drvdata(dev);
225 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
227 return sprintf(buf, "%ld\n", data->max[attr->index]);
230 static ssize_t show_max_hyst(struct device *dev,
231 struct device_attribute *devattr, char *buf)
233 struct rockchip_temp *data = dev_get_drvdata(dev);
234 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
236 return sprintf(buf, "%ld\n", data->max_hyst[attr->index]);
239 static ssize_t show_min_alarm(struct device *dev,
240 struct device_attribute *devattr, char *buf)
242 struct rockchip_temp *data = dev_get_drvdata(dev);
243 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
245 return sprintf(buf, "%d\n", data->min_alarm[attr->index]);
248 static ssize_t show_max_alarm(struct device *dev,
249 struct device_attribute *devattr, char *buf)
251 struct rockchip_temp *data = dev_get_drvdata(dev);
252 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
254 return sprintf(buf, "%d\n", data->max_alarm[attr->index]);
257 static umode_t rockchip_attrs_visible(struct kobject *kobj,
258 struct attribute *attr, int n)
260 struct device *dev = container_of(kobj, struct device, kobj);
261 struct rockchip_temp *data = dev_get_drvdata(dev);
263 if (data->ops.is_visible)
264 return data->ops.is_visible(attr, n);
269 /* Chip name, required by hwmon */
270 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
272 /* GPADC - SENSOR0 */
273 static SENSOR_DEVICE_ATTR(temp0_label, S_IRUGO, show_label, NULL, 0);
274 static SENSOR_DEVICE_ATTR(temp0_input, S_IRUGO, show_input, NULL, 0);
275 static SENSOR_DEVICE_ATTR(temp0_min, S_IWUSR | S_IRUGO, show_min, set_min, 0);
276 static SENSOR_DEVICE_ATTR(temp0_max, S_IWUSR | S_IRUGO, show_max, set_max, 0);
277 static SENSOR_DEVICE_ATTR(temp0_max_hyst, S_IWUSR | S_IRUGO,
278 show_max_hyst, set_max_hyst, 0);
279 static SENSOR_DEVICE_ATTR(temp0_min_alarm, S_IRUGO, show_min_alarm, NULL, 0);
280 static SENSOR_DEVICE_ATTR(temp0_max_alarm, S_IRUGO, show_max_alarm, NULL, 0);
282 /* GPADC - SENSOR1 */
283 static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL, 1);
284 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 1);
285 static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_min, set_min, 1);
286 static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_max, set_max, 1);
287 static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
288 show_max_hyst, set_max_hyst, 1);
289 static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_min_alarm, NULL, 1);
290 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_max_alarm, NULL, 1);
292 /* GPADC - SENSOR2 */
293 static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, 2);
294 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2);
295 static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min, 2);
296 static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max, 2);
297 static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IWUSR | S_IRUGO,
298 show_max_hyst, set_max_hyst, 2);
299 static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_min_alarm, NULL, 2);
300 static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_max_alarm, NULL, 2);
302 /* GPADC - SENSOR3 */
303 static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_label, NULL, 3);
304 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 3);
305 static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min, 3);
306 static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max, 3);
307 static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IWUSR | S_IRUGO,
308 show_max_hyst, set_max_hyst, 3);
309 static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_min_alarm, NULL, 3);
310 static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_max_alarm, NULL, 3);
313 struct attribute *rockchip_temp_attributes[] = {
314 &sensor_dev_attr_name.dev_attr.attr,
316 &sensor_dev_attr_temp0_label.dev_attr.attr,
317 &sensor_dev_attr_temp0_input.dev_attr.attr,
318 &sensor_dev_attr_temp0_min.dev_attr.attr,
319 &sensor_dev_attr_temp0_max.dev_attr.attr,
320 &sensor_dev_attr_temp0_max_hyst.dev_attr.attr,
321 &sensor_dev_attr_temp0_min_alarm.dev_attr.attr,
322 &sensor_dev_attr_temp0_max_alarm.dev_attr.attr,
324 &sensor_dev_attr_temp1_label.dev_attr.attr,
325 &sensor_dev_attr_temp1_input.dev_attr.attr,
326 &sensor_dev_attr_temp1_min.dev_attr.attr,
327 &sensor_dev_attr_temp1_max.dev_attr.attr,
328 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
329 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
330 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
332 &sensor_dev_attr_temp2_label.dev_attr.attr,
333 &sensor_dev_attr_temp2_input.dev_attr.attr,
334 &sensor_dev_attr_temp2_min.dev_attr.attr,
335 &sensor_dev_attr_temp2_max.dev_attr.attr,
336 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
337 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
338 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
340 &sensor_dev_attr_temp3_label.dev_attr.attr,
341 &sensor_dev_attr_temp3_input.dev_attr.attr,
342 &sensor_dev_attr_temp3_min.dev_attr.attr,
343 &sensor_dev_attr_temp3_max.dev_attr.attr,
344 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
345 &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
346 &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
352 static const struct attribute_group rockchip_temp_group = {
353 .attrs = rockchip_temp_attributes,
354 .is_visible = rockchip_attrs_visible,
357 static int rockchip_temp_probe(struct platform_device *pdev)
359 struct rockchip_temp *data;
361 printk("%s,line=%d\n", __func__,__LINE__);
363 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
367 mutex_init(&data->lock);
369 /* Chip specific initialization */
370 err = rockchip_hwmon_init(data);
371 if (err < 0 || !data->ops.read_sensor || !data->ops.show_name ||
372 !data->ops.show_label)
375 INIT_DEFERRABLE_WORK(&data->work, tsadc_monitor);
376 platform_set_drvdata(pdev, data);
378 err = sysfs_create_group(&pdev->dev.kobj, &rockchip_temp_group);
380 dev_err(&pdev->dev, "Create sysfs group failed (%d)\n", err);
383 data->hwmon_dev = hwmon_device_register(&pdev->dev);
384 if (IS_ERR(data->hwmon_dev)) {
385 err = PTR_ERR(data->hwmon_dev);
386 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
387 goto exit_sysfs_group;
392 sysfs_remove_group(&pdev->dev.kobj, &rockchip_temp_group);
396 static int rockchip_temp_remove(struct platform_device *pdev)
398 struct rockchip_temp *data = platform_get_drvdata(pdev);
400 cancel_delayed_work_sync(&data->work);
401 hwmon_device_unregister(data->hwmon_dev);
402 sysfs_remove_group(&pdev->dev.kobj, &rockchip_temp_group);
407 static int rockchip_temp_suspend(struct platform_device *pdev,
410 struct rockchip_temp *data = platform_get_drvdata(pdev);
412 if (data->work_active)
413 cancel_delayed_work_sync(&data->work);
418 static int rockchip_temp_resume(struct platform_device *pdev)
420 struct rockchip_temp *data = platform_get_drvdata(pdev);
422 if (data->work_active)
423 schedule_monitor(data);
429 static const struct of_device_id rockchip_temp_match[] = {
430 { .compatible = "rockchip,tsadc" },
435 static struct platform_driver rockchip_temp_driver = {
437 .owner = THIS_MODULE,
439 .of_match_table = of_match_ptr(rockchip_temp_match),
441 .suspend = rockchip_temp_suspend,
442 .resume = rockchip_temp_resume,
443 .probe = rockchip_temp_probe,
444 .remove = rockchip_temp_remove,
447 module_platform_driver(rockchip_temp_driver);
449 MODULE_AUTHOR("<rockchip>");
450 MODULE_DESCRIPTION("rockchip temperature driver");
451 MODULE_LICENSE("GPL");