OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 15ae701189744d321d3a1264ff46f8871e8765ee Mon Sep 17 00:00:00 2001 |
2 | From: Christian Lamparter <chunkeey@gmail.com> |
||
3 | Date: Sun, 17 Dec 2017 17:29:13 +0100 |
||
4 | Subject: [PATCH] hwmon: tc654: add thermal_cooling device |
||
5 | |||
6 | This patch adds a thermaL_cooling device to the tc654 driver. |
||
7 | This allows the chip to be used for DT-based cooling. |
||
8 | |||
9 | Signed-off-by: Christian Lamparter <chunkeey@gmail.com> |
||
10 | --- |
||
11 | drivers/hwmon/tc654.c | 103 +++++++++++++++++++++++++++++++++++++++++--------- |
||
12 | 1 file changed, 86 insertions(+), 17 deletions(-) |
||
13 | |||
14 | --- a/drivers/hwmon/tc654.c |
||
15 | +++ b/drivers/hwmon/tc654.c |
||
16 | @@ -24,6 +24,7 @@ |
||
17 | #include <linux/module.h> |
||
18 | #include <linux/mutex.h> |
||
19 | #include <linux/slab.h> |
||
20 | +#include <linux/thermal.h> |
||
21 | #include <linux/util_macros.h> |
||
22 | |||
23 | enum tc654_regs { |
||
24 | @@ -141,6 +142,9 @@ struct tc654_data { |
||
25 | * writable register used to control the duty |
||
26 | * cycle of the V OUT output. |
||
27 | */ |
||
28 | + |
||
29 | + /* optional cooling device */ |
||
30 | + struct thermal_cooling_device *cdev; |
||
31 | }; |
||
32 | |||
33 | /* helper to grab and cache data, at most one time per second */ |
||
34 | @@ -376,36 +380,30 @@ static ssize_t set_pwm_mode(struct devic |
||
35 | static const int tc654_pwm_map[16] = { 77, 88, 102, 112, 124, 136, 148, 160, |
||
36 | 172, 184, 196, 207, 219, 231, 243, 255}; |
||
37 | |||
38 | +static int get_pwm(struct tc654_data *data) |
||
39 | +{ |
||
40 | + if (data->config & TC654_REG_CONFIG_SDM) |
||
41 | + return 0; |
||
42 | + else |
||
43 | + return tc654_pwm_map[data->duty_cycle]; |
||
44 | +} |
||
45 | + |
||
46 | static ssize_t show_pwm(struct device *dev, struct device_attribute *da, |
||
47 | char *buf) |
||
48 | { |
||
49 | struct tc654_data *data = tc654_update_client(dev); |
||
50 | - int pwm; |
||
51 | |||
52 | if (IS_ERR(data)) |
||
53 | return PTR_ERR(data); |
||
54 | |||
55 | - if (data->config & TC654_REG_CONFIG_SDM) |
||
56 | - pwm = 0; |
||
57 | - else |
||
58 | - pwm = tc654_pwm_map[data->duty_cycle]; |
||
59 | - |
||
60 | - return sprintf(buf, "%d\n", pwm); |
||
61 | + return sprintf(buf, "%d\n", get_pwm(data)); |
||
62 | } |
||
63 | |||
64 | -static ssize_t set_pwm(struct device *dev, struct device_attribute *da, |
||
65 | - const char *buf, size_t count) |
||
66 | +static int _set_pwm(struct tc654_data *data, unsigned long val) |
||
67 | { |
||
68 | - struct tc654_data *data = dev_get_drvdata(dev); |
||
69 | struct i2c_client *client = data->client; |
||
70 | - unsigned long val; |
||
71 | int ret; |
||
72 | |||
73 | - if (kstrtoul(buf, 10, &val)) |
||
74 | - return -EINVAL; |
||
75 | - if (val > 255) |
||
76 | - return -EINVAL; |
||
77 | - |
||
78 | mutex_lock(&data->update_lock); |
||
79 | |||
80 | if (val == 0) |
||
81 | @@ -425,6 +423,22 @@ static ssize_t set_pwm(struct device *de |
||
82 | |||
83 | out: |
||
84 | mutex_unlock(&data->update_lock); |
||
85 | + return ret; |
||
86 | +} |
||
87 | + |
||
88 | +static ssize_t set_pwm(struct device *dev, struct device_attribute *da, |
||
89 | + const char *buf, size_t count) |
||
90 | +{ |
||
91 | + struct tc654_data *data = dev_get_drvdata(dev); |
||
92 | + unsigned long val; |
||
93 | + int ret; |
||
94 | + |
||
95 | + if (kstrtoul(buf, 10, &val)) |
||
96 | + return -EINVAL; |
||
97 | + if (val > 255) |
||
98 | + return -EINVAL; |
||
99 | + |
||
100 | + ret = _set_pwm(data, val); |
||
101 | return ret < 0 ? ret : count; |
||
102 | } |
||
103 | |||
104 | @@ -462,6 +476,47 @@ static struct attribute *tc654_attrs[] = |
||
105 | |||
106 | ATTRIBUTE_GROUPS(tc654); |
||
107 | |||
108 | +/* cooling device */ |
||
109 | + |
||
110 | +static int tc654_get_max_state(struct thermal_cooling_device *cdev, |
||
111 | + unsigned long *state) |
||
112 | +{ |
||
113 | + *state = 255; |
||
114 | + return 0; |
||
115 | +} |
||
116 | + |
||
117 | +static int tc654_get_cur_state(struct thermal_cooling_device *cdev, |
||
118 | + unsigned long *state) |
||
119 | +{ |
||
120 | + struct tc654_data *data = tc654_update_client(cdev->devdata); |
||
121 | + |
||
122 | + if (IS_ERR(data)) |
||
123 | + return PTR_ERR(data); |
||
124 | + |
||
125 | + *state = get_pwm(data); |
||
126 | + return 0; |
||
127 | +} |
||
128 | + |
||
129 | +static int tc654_set_cur_state(struct thermal_cooling_device *cdev, |
||
130 | + unsigned long state) |
||
131 | +{ |
||
132 | + struct tc654_data *data = tc654_update_client(cdev->devdata); |
||
133 | + |
||
134 | + if (IS_ERR(data)) |
||
135 | + return PTR_ERR(data); |
||
136 | + |
||
137 | + if (state > 255) |
||
138 | + return -EINVAL; |
||
139 | + |
||
140 | + return _set_pwm(data, state); |
||
141 | +} |
||
142 | + |
||
143 | +static const struct thermal_cooling_device_ops tc654_fan_cool_ops = { |
||
144 | + .get_max_state = tc654_get_max_state, |
||
145 | + .get_cur_state = tc654_get_cur_state, |
||
146 | + .set_cur_state = tc654_set_cur_state, |
||
147 | +}; |
||
148 | + |
||
149 | /* |
||
150 | * device probe and removal |
||
151 | */ |
||
152 | @@ -493,7 +548,21 @@ static int tc654_probe(struct i2c_client |
||
153 | hwmon_dev = |
||
154 | devm_hwmon_device_register_with_groups(dev, client->name, data, |
||
155 | tc654_groups); |
||
156 | - return PTR_ERR_OR_ZERO(hwmon_dev); |
||
157 | + if (IS_ERR(hwmon_dev)) |
||
158 | + return PTR_ERR(hwmon_dev); |
||
159 | + |
||
160 | +#if IS_ENABLED(CONFIG_OF) |
||
161 | + /* Optional cooling device register for Device tree platforms */ |
||
162 | + data->cdev = thermal_of_cooling_device_register(client->dev.of_node, |
||
163 | + "tc654", hwmon_dev, |
||
164 | + &tc654_fan_cool_ops); |
||
165 | +#else /* CONFIG_OF */ |
||
166 | + /* Optional cooling device register for non Device tree platforms */ |
||
167 | + data->cdev = thermal_cooling_device_register("tc654", hwmon_dev, |
||
168 | + &tc654_fan_cool_ops); |
||
169 | +#endif /* CONFIG_OF */ |
||
170 | + |
||
171 | + return PTR_ERR_OR_ZERO(data->cdev); |
||
172 | } |
||
173 | |||
174 | static const struct i2c_device_id tc654_id[] = { |