aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/g762.c
diff options
context:
space:
mode:
authorArnaud Ebalard <arno@natisbad.org>2013-06-20 16:21:04 -0400
committerGuenter Roeck <linux@roeck-us.net>2013-06-27 13:31:42 -0400
commit594fbe713bf60073ed884dc317a74dd5b327aba7 (patch)
treea93240b841e0e913efbf000b6b22d6ce29ea467e /drivers/hwmon/g762.c
parent31e7ad74f6044ffec112fd4975c07b797589d89c (diff)
Add support for GMT G762/G763 PWM fan controllers
GMT G762/763 fan speed PWM controller is connected directly to a fan and performs closed-loop or open-loop control of the fan speed. Two modes - PWM or DC - are supported by the chip. Introduced driver provides various knobs to control the operations of the chip (via sysfs interface). Specific characteristics of the system can be passed either using board init code or via DT. Documentation for both the driver and DT bindings are also provided. Signed-off-by: Arnaud Ebalard <arno@natisbad.org> Tested-by: Simon Guinot <simon.guinot@sequanux.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/g762.c')
-rw-r--r--drivers/hwmon/g762.c1149
1 files changed, 1149 insertions, 0 deletions
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c
new file mode 100644
index 000000000000..73adf01b0ef2
--- /dev/null
+++ b/drivers/hwmon/g762.c
@@ -0,0 +1,1149 @@
1/*
2 * g762 - Driver for the Global Mixed-mode Technology Inc. fan speed
3 * PWM controller chips from G762 family, i.e. G762 and G763
4 *
5 * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
6 *
7 * This work is based on a basic version for 2.6.31 kernel developed
8 * by Olivier Mouchet for LaCie. Updates and correction have been
9 * performed to run on recent kernels. Additional features, like the
10 * ability to configure various characteristics via .dts file or
11 * board init file have been added. Detailed datasheet on which this
12 * development is based is available here:
13 *
14 * http://natisbad.org/NAS/refs/GMT_EDS-762_763-080710-0.2.pdf
15 *
16 * Headers from previous developments have been kept below:
17 *
18 * Copyright (c) 2009 LaCie
19 *
20 * Author: Olivier Mouchet <olivier.mouchet@gmail.com>
21 *
22 * based on g760a code written by Herbert Valerio Riedel <hvr@gnu.org>
23 * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
24 *
25 * g762: minimal datasheet available at:
26 * http://www.gmt.com.tw/product/datasheet/EDS-762_3.pdf
27 *
28 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation; either version 2 of the License, or
31 * (at your option) any later version.
32 *
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
37 *
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation.
41 */
42
43#include <linux/device.h>
44#include <linux/module.h>
45#include <linux/init.h>
46#include <linux/jiffies.h>
47#include <linux/i2c.h>
48#include <linux/hwmon.h>
49#include <linux/hwmon-sysfs.h>
50#include <linux/err.h>
51#include <linux/mutex.h>
52#include <linux/kernel.h>
53#include <linux/clk.h>
54#include <linux/of.h>
55#include <linux/of_device.h>
56#include <linux/platform_data/g762.h>
57
58#define DRVNAME "g762"
59
60static const struct i2c_device_id g762_id[] = {
61 { "g762", 0 },
62 { "g763", 0 },
63 { }
64};
65MODULE_DEVICE_TABLE(i2c, g762_id);
66
67enum g762_regs {
68 G762_REG_SET_CNT = 0x00,
69 G762_REG_ACT_CNT = 0x01,
70 G762_REG_FAN_STA = 0x02,
71 G762_REG_SET_OUT = 0x03,
72 G762_REG_FAN_CMD1 = 0x04,
73 G762_REG_FAN_CMD2 = 0x05,
74};
75
76/* Config register bits */
77#define G762_REG_FAN_CMD1_DET_FAN_FAIL 0x80 /* enable fan_fail signal */
78#define G762_REG_FAN_CMD1_DET_FAN_OOC 0x40 /* enable fan_out_of_control */
79#define G762_REG_FAN_CMD1_OUT_MODE 0x20 /* out mode: PWM or DC */
80#define G762_REG_FAN_CMD1_FAN_MODE 0x10 /* fan mode: closed/open-loop */
81#define G762_REG_FAN_CMD1_CLK_DIV_ID1 0x08 /* clock divisor value */
82#define G762_REG_FAN_CMD1_CLK_DIV_ID0 0x04
83#define G762_REG_FAN_CMD1_PWM_POLARITY 0x02 /* PWM polarity */
84#define G762_REG_FAN_CMD1_PULSE_PER_REV 0x01 /* pulse per fan revolution */
85
86#define G762_REG_FAN_CMD2_GEAR_MODE_1 0x08 /* fan gear mode */
87#define G762_REG_FAN_CMD2_GEAR_MODE_0 0x04
88#define G762_REG_FAN_CMD2_FAN_STARTV_1 0x02 /* fan startup voltage */
89#define G762_REG_FAN_CMD2_FAN_STARTV_0 0x01
90
91#define G762_REG_FAN_STA_FAIL 0x02 /* fan fail */
92#define G762_REG_FAN_STA_OOC 0x01 /* fan out of control */
93
94/* Config register values */
95#define G762_OUT_MODE_PWM 1
96#define G762_OUT_MODE_DC 0
97
98#define G762_FAN_MODE_CLOSED_LOOP 2
99#define G762_FAN_MODE_OPEN_LOOP 1
100
101#define G762_PWM_POLARITY_NEGATIVE 1
102#define G762_PWM_POLARITY_POSITIVE 0
103
104/* Register data is read (and cached) at most once per second. */
105#define G762_UPDATE_INTERVAL HZ
106
107/*
108 * Extract pulse count per fan revolution value (2 or 4) from given
109 * FAN_CMD1 register value.
110 */
111#define G762_PULSE_FROM_REG(reg) \
112 ((((reg) & G762_REG_FAN_CMD1_PULSE_PER_REV) + 1) << 1)
113
114/*
115 * Extract fan clock divisor (1, 2, 4 or 8) from given FAN_CMD1
116 * register value.
117 */
118#define G762_CLKDIV_FROM_REG(reg) \
119 (1 << (((reg) & (G762_REG_FAN_CMD1_CLK_DIV_ID0 | \
120 G762_REG_FAN_CMD1_CLK_DIV_ID1)) >> 2))
121
122/*
123 * Extract fan gear mode multiplier value (0, 2 or 4) from given
124 * FAN_CMD2 register value.
125 */
126#define G762_GEARMULT_FROM_REG(reg) \
127 (1 << (((reg) & (G762_REG_FAN_CMD2_GEAR_MODE_0 | \
128 G762_REG_FAN_CMD2_GEAR_MODE_1)) >> 2))
129
130struct g762_data {
131 struct i2c_client *client;
132 struct device *hwmon_dev;
133 struct clk *clk;
134
135 /* update mutex */
136 struct mutex update_lock;
137
138 /* board specific parameters. */
139 u32 clk_freq;
140
141 /* g762 register cache */
142 bool valid;
143 unsigned long last_updated; /* in jiffies */
144
145 u8 set_cnt; /* controls fan rotation speed in closed-loop mode */
146 u8 act_cnt; /* provides access to current fan RPM value */
147 u8 fan_sta; /* bit 0: set when actual fan speed is more than
148 * 25% outside requested fan speed
149 * bit 1: set when no transition occurs on fan
150 * pin for 0.7s
151 */
152 u8 set_out; /* controls fan rotation speed in open-loop mode */
153 u8 fan_cmd1; /* 0: FG_PLS_ID0 FG pulses count per revolution
154 * 0: 2 counts per revolution
155 * 1: 4 counts per revolution
156 * 1: PWM_POLARITY 1: negative_duty
157 * 0: positive_duty
158 * 2,3: [FG_CLOCK_ID0, FG_CLK_ID1]
159 * 00: Divide fan clock by 1
160 * 01: Divide fan clock by 2
161 * 10: Divide fan clock by 4
162 * 11: Divide fan clock by 8
163 * 4: FAN_MODE 1:closed-loop, 0:open-loop
164 * 5: OUT_MODE 1:PWM, 0:DC
165 * 6: DET_FAN_OOC enable "fan ooc" status
166 * 7: DET_FAN_FAIL enable "fan fail" status
167 */
168 u8 fan_cmd2; /* 0,1: FAN_STARTV 0,1,2,3 -> 0,32,64,96 dac_code
169 * 2,3: FG_GEAR_MODE
170 * 00: multiplier = 1
171 * 01: multiplier = 2
172 * 10: multiplier = 4
173 * 4: Mask ALERT# (g763 only)
174 */
175};
176
177/*
178 * Convert count value from fan controller register (FAN_SET_CNT) into fan
179 * speed RPM value. Note that the datasheet documents a basic formula;
180 * influence of additional parameters (fan clock divisor, fan gear mode)
181 * have been infered from examples in the datasheet and tests.
182 */
183static inline unsigned int rpm_from_cnt(u8 cnt, u32 clk_freq, u16 p,
184 u8 clk_div, u8 gear_mult)
185{
186 if (cnt == 0xff) /* setting cnt to 255 stops the fan */
187 return 0;
188
189 return (clk_freq * 30 * gear_mult) / ((cnt ? cnt : 1) * p * clk_div);
190}
191
192/*
193 * Convert fan RPM value from sysfs into count value for fan controller
194 * register (FAN_SET_CNT).
195 */
196static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p,
197 u8 clk_div, u8 gear_mult)
198{
199 if (!rpm) /* to stop the fan, set cnt to 255 */
200 return 0xff;
201
202 return clamp_val(((clk_freq * 30 * gear_mult) / (rpm * p * clk_div)),
203 0, 255);
204}
205
206/* helper to grab and cache data, at most one time per second */
207static struct g762_data *g762_update_client(struct device *dev)
208{
209 struct i2c_client *client = to_i2c_client(dev);
210 struct g762_data *data = i2c_get_clientdata(client);
211 int ret = 0;
212
213 mutex_lock(&data->update_lock);
214 if (time_before(jiffies, data->last_updated + G762_UPDATE_INTERVAL) &&
215 likely(data->valid))
216 goto out;
217
218 ret = i2c_smbus_read_byte_data(client, G762_REG_SET_CNT);
219 if (ret < 0)
220 goto out;
221 data->set_cnt = ret;
222
223 ret = i2c_smbus_read_byte_data(client, G762_REG_ACT_CNT);
224 if (ret < 0)
225 goto out;
226 data->act_cnt = ret;
227
228 ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_STA);
229 if (ret < 0)
230 goto out;
231 data->fan_sta = ret;
232
233 ret = i2c_smbus_read_byte_data(client, G762_REG_SET_OUT);
234 if (ret < 0)
235 goto out;
236 data->set_out = ret;
237
238 ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_CMD1);
239 if (ret < 0)
240 goto out;
241 data->fan_cmd1 = ret;
242
243 ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_CMD2);
244 if (ret < 0)
245 goto out;
246 data->fan_cmd2 = ret;
247
248 data->last_updated = jiffies;
249 data->valid = true;
250 out:
251 mutex_unlock(&data->update_lock);
252
253 if (ret < 0) /* upon error, encode it in return value */
254 data = ERR_PTR(ret);
255
256 return data;
257}
258
259/* helpers for writing hardware parameters */
260
261/*
262 * Set input clock frequency received on CLK pin of the chip. Accepted values
263 * are between 0 and 0xffffff. If zero is given, then default frequency
264 * (32,768Hz) is used. Note that clock frequency is a characteristic of the
265 * system but an internal parameter, i.e. value is not passed to the device.
266 */
267static int do_set_clk_freq(struct device *dev, unsigned long val)
268{
269 struct i2c_client *client = to_i2c_client(dev);
270 struct g762_data *data = i2c_get_clientdata(client);
271
272 if (val > 0xffffff)
273 return -EINVAL;
274 if (!val)
275 val = 32768;
276
277 data->clk_freq = val;
278
279 return 0;
280}
281
282/* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */
283static int do_set_pwm_mode(struct device *dev, unsigned long val)
284{
285 struct i2c_client *client = to_i2c_client(dev);
286 struct g762_data *data = g762_update_client(dev);
287 int ret;
288
289 if (IS_ERR(data))
290 return PTR_ERR(data);
291
292 mutex_lock(&data->update_lock);
293 switch (val) {
294 case G762_OUT_MODE_PWM:
295 data->fan_cmd1 |= G762_REG_FAN_CMD1_OUT_MODE;
296 break;
297 case G762_OUT_MODE_DC:
298 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_OUT_MODE;
299 break;
300 default:
301 ret = -EINVAL;
302 goto out;
303 }
304 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
305 data->fan_cmd1);
306 data->valid = false;
307 out:
308 mutex_unlock(&data->update_lock);
309
310 return ret;
311}
312
313/* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */
314static int do_set_fan_div(struct device *dev, unsigned long val)
315{
316 struct i2c_client *client = to_i2c_client(dev);
317 struct g762_data *data = g762_update_client(dev);
318 int ret;
319
320 if (IS_ERR(data))
321 return PTR_ERR(data);
322
323 mutex_lock(&data->update_lock);
324 switch (val) {
325 case 1:
326 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0;
327 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1;
328 break;
329 case 2:
330 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID0;
331 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1;
332 break;
333 case 4:
334 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0;
335 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID1;
336 break;
337 case 8:
338 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID0;
339 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID1;
340 break;
341 default:
342 ret = -EINVAL;
343 goto out;
344 }
345 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
346 data->fan_cmd1);
347 data->valid = false;
348 out:
349 mutex_unlock(&data->update_lock);
350
351 return ret;
352}
353
354/* Set fan gear mode. Accepts either 0, 1 or 2. */
355static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
356{
357 struct i2c_client *client = to_i2c_client(dev);
358 struct g762_data *data = g762_update_client(dev);
359 int ret;
360
361 if (IS_ERR(data))
362 return PTR_ERR(data);
363
364 mutex_lock(&data->update_lock);
365 switch (val) {
366 case 0:
367 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0;
368 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1;
369 break;
370 case 1:
371 data->fan_cmd2 |= G762_REG_FAN_CMD2_GEAR_MODE_0;
372 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1;
373 break;
374 case 2:
375 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0;
376 data->fan_cmd2 |= G762_REG_FAN_CMD2_GEAR_MODE_1;
377 break;
378 default:
379 ret = -EINVAL;
380 goto out;
381 }
382 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
383 data->fan_cmd2);
384 data->valid = false;
385 out:
386 mutex_unlock(&data->update_lock);
387
388 return ret;
389}
390
391/* Set number of fan pulses per revolution. Accepts either 2 or 4. */
392static int do_set_fan_pulses(struct device *dev, unsigned long val)
393{
394 struct i2c_client *client = to_i2c_client(dev);
395 struct g762_data *data = g762_update_client(dev);
396 int ret;
397
398 if (IS_ERR(data))
399 return PTR_ERR(data);
400
401 mutex_lock(&data->update_lock);
402 switch (val) {
403 case 2:
404 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PULSE_PER_REV;
405 break;
406 case 4:
407 data->fan_cmd1 |= G762_REG_FAN_CMD1_PULSE_PER_REV;
408 break;
409 default:
410 ret = -EINVAL;
411 goto out;
412 }
413 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
414 data->fan_cmd1);
415 data->valid = false;
416 out:
417 mutex_unlock(&data->update_lock);
418
419 return ret;
420}
421
422/* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
423static int do_set_pwm_enable(struct device *dev, unsigned long val)
424{
425 struct i2c_client *client = to_i2c_client(dev);
426 struct g762_data *data = g762_update_client(dev);
427 int ret;
428
429 if (IS_ERR(data))
430 return PTR_ERR(data);
431
432 mutex_lock(&data->update_lock);
433 switch (val) {
434 case G762_FAN_MODE_CLOSED_LOOP:
435 data->fan_cmd1 |= G762_REG_FAN_CMD1_FAN_MODE;
436 break;
437 case G762_FAN_MODE_OPEN_LOOP:
438 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_FAN_MODE;
439 /*
440 * BUG FIX: if SET_CNT register value is 255 then, for some
441 * unknown reason, fan will not rotate as expected, no matter
442 * the value of SET_OUT (to be specific, this seems to happen
443 * only in PWM mode). To workaround this bug, we give SET_CNT
444 * value of 254 if it is 255 when switching to open-loop.
445 */
446 if (data->set_cnt == 0xff)
447 i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
448 254);
449 break;
450 default:
451 ret = -EINVAL;
452 goto out;
453 }
454
455 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
456 data->fan_cmd1);
457 data->valid = false;
458 out:
459 mutex_unlock(&data->update_lock);
460
461 return ret;
462}
463
464/* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */
465static int do_set_pwm_polarity(struct device *dev, unsigned long val)
466{
467 struct i2c_client *client = to_i2c_client(dev);
468 struct g762_data *data = g762_update_client(dev);
469 int ret;
470
471 if (IS_ERR(data))
472 return PTR_ERR(data);
473
474 mutex_lock(&data->update_lock);
475 switch (val) {
476 case G762_PWM_POLARITY_POSITIVE:
477 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PWM_POLARITY;
478 break;
479 case G762_PWM_POLARITY_NEGATIVE:
480 data->fan_cmd1 |= G762_REG_FAN_CMD1_PWM_POLARITY;
481 break;
482 default:
483 ret = -EINVAL;
484 goto out;
485 }
486 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
487 data->fan_cmd1);
488 data->valid = false;
489 out:
490 mutex_unlock(&data->update_lock);
491
492 return ret;
493}
494
495/*
496 * Set pwm value. Accepts values between 0 (stops the fan) and
497 * 255 (full speed). This only makes sense in open-loop mode.
498 */
499static int do_set_pwm(struct device *dev, unsigned long val)
500{
501 struct i2c_client *client = to_i2c_client(dev);
502 struct g762_data *data = i2c_get_clientdata(client);
503 int ret;
504
505 if (val > 255)
506 return -EINVAL;
507
508 mutex_lock(&data->update_lock);
509 ret = i2c_smbus_write_byte_data(client, G762_REG_SET_OUT, val);
510 data->valid = false;
511 mutex_unlock(&data->update_lock);
512
513 return ret;
514}
515
516/*
517 * Set fan RPM value. Can be called both in closed and open-loop mode
518 * but effect will only be seen after closed-loop mode is configured.
519 */
520static int do_set_fan_target(struct device *dev, unsigned long val)
521{
522 struct i2c_client *client = to_i2c_client(dev);
523 struct g762_data *data = g762_update_client(dev);
524 int ret;
525
526 if (IS_ERR(data))
527 return PTR_ERR(data);
528
529 mutex_lock(&data->update_lock);
530 data->set_cnt = cnt_from_rpm(val, data->clk_freq,
531 G762_PULSE_FROM_REG(data->fan_cmd1),
532 G762_CLKDIV_FROM_REG(data->fan_cmd1),
533 G762_GEARMULT_FROM_REG(data->fan_cmd2));
534 ret = i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
535 data->set_cnt);
536 data->valid = false;
537 mutex_unlock(&data->update_lock);
538
539 return ret;
540}
541
542/* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */
543static int do_set_fan_startv(struct device *dev, unsigned long val)
544{
545 struct i2c_client *client = to_i2c_client(dev);
546 struct g762_data *data = g762_update_client(dev);
547 int ret;
548
549 if (IS_ERR(data))
550 return PTR_ERR(data);
551
552 mutex_lock(&data->update_lock);
553 switch (val) {
554 case 0:
555 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0;
556 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1;
557 break;
558 case 1:
559 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_0;
560 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1;
561 break;
562 case 2:
563 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0;
564 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_1;
565 break;
566 case 3:
567 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_0;
568 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_1;
569 break;
570 default:
571 ret = -EINVAL;
572 goto out;
573 }
574 ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
575 data->fan_cmd2);
576 data->valid = false;
577 out:
578 mutex_unlock(&data->update_lock);
579
580 return ret;
581}
582
583/*
584 * Helper to import hardware characteristics from .dts file and push
585 * those to the chip.
586 */
587
588#ifdef CONFIG_OF
589static struct of_device_id g762_dt_match[] = {
590 { .compatible = "gmt,g762" },
591 { .compatible = "gmt,g763" },
592 { },
593};
594
595/*
596 * Grab clock (a required property), enable it, get (fixed) clock frequency
597 * and store it. Note: upon success, clock has been prepared and enabled; it
598 * must later be unprepared and disabled (e.g. during module unloading) by a
599 * call to g762_of_clock_disable(). Note that a reference to clock is kept
600 * in our private data structure to be used in this function.
601 */
602static int g762_of_clock_enable(struct i2c_client *client)
603{
604 struct g762_data *data;
605 unsigned long clk_freq;
606 struct clk *clk;
607 int ret;
608
609 if (!client->dev.of_node)
610 return 0;
611
612 clk = of_clk_get(client->dev.of_node, 0);
613 if (IS_ERR(clk)) {
614 dev_err(&client->dev, "failed to get clock\n");
615 return PTR_ERR(clk);
616 }
617
618 ret = clk_prepare_enable(clk);
619 if (ret) {
620 dev_err(&client->dev, "failed to enable clock\n");
621 goto clk_put;
622 }
623
624 clk_freq = clk_get_rate(clk);
625 ret = do_set_clk_freq(&client->dev, clk_freq);
626 if (ret) {
627 dev_err(&client->dev, "invalid clock freq %lu\n", clk_freq);
628 goto clk_unprep;
629 }
630
631 data = i2c_get_clientdata(client);
632 data->clk = clk;
633
634 return 0;
635
636 clk_unprep:
637 clk_disable_unprepare(clk);
638
639 clk_put:
640 clk_put(clk);
641
642 return ret;
643}
644
645static void g762_of_clock_disable(struct i2c_client *client)
646{
647 struct g762_data *data = i2c_get_clientdata(client);
648
649 if (!data->clk)
650 return;
651
652 clk_disable_unprepare(data->clk);
653 clk_put(data->clk);
654}
655
656static int g762_of_prop_import_one(struct i2c_client *client,
657 const char *pname,
658 int (*psetter)(struct device *dev,
659 unsigned long val))
660{
661 const __be32 *prop;
662 int len, ret;
663 u32 pval;
664
665 prop = of_get_property(client->dev.of_node, pname, &len);
666 if (!prop || len != sizeof(u32))
667 return 0;
668
669 pval = be32_to_cpu(prop[0]);
670 dev_dbg(&client->dev, "found %s (%d)\n", pname, pval);
671 ret = (*psetter)(&client->dev, pval);
672 if (ret)
673 dev_err(&client->dev, "unable to set %s (%d)\n", pname, pval);
674
675 return ret;
676}
677
678static int g762_of_prop_import(struct i2c_client *client)
679{
680 int ret;
681
682 if (!client->dev.of_node)
683 return 0;
684
685 ret = g762_of_prop_import_one(client, "fan_gear_mode",
686 do_set_fan_gear_mode);
687 if (ret)
688 return ret;
689
690 ret = g762_of_prop_import_one(client, "pwm_polarity",
691 do_set_pwm_polarity);
692 if (ret)
693 return ret;
694
695 return g762_of_prop_import_one(client, "fan_startv",
696 do_set_fan_startv);
697}
698
699#else
700static int g762_of_prop_import(struct i2c_client *client)
701{
702 return 0;
703}
704
705static int g762_of_clock_enable(struct i2c_client *client)
706{
707 return 0;
708}
709
710static void g762_of_clock_disable(struct i2c_client *client) { }
711#endif
712
713/*
714 * Helper to import hardware characteristics from .dts file and push
715 * those to the chip.
716 */
717
718static int g762_pdata_prop_import(struct i2c_client *client)
719{
720 struct g762_platform_data *pdata = client->dev.platform_data;
721 int ret;
722
723 if (!pdata)
724 return 0;
725
726 ret = do_set_fan_gear_mode(&client->dev, pdata->fan_gear_mode);
727 if (ret)
728 return ret;
729
730 ret = do_set_pwm_polarity(&client->dev, pdata->pwm_polarity);
731 if (ret)
732 return ret;
733
734 ret = do_set_fan_startv(&client->dev, pdata->fan_startv);
735 if (ret)
736 return ret;
737
738 return do_set_clk_freq(&client->dev, pdata->clk_freq);
739}
740
741/*
742 * sysfs attributes
743 */
744
745/*
746 * Read function for fan1_input sysfs file. Return current fan RPM value, or
747 * 0 if fan is out of control.
748 */
749static ssize_t get_fan_rpm(struct device *dev, struct device_attribute *da,
750 char *buf)
751{
752 struct g762_data *data = g762_update_client(dev);
753 unsigned int rpm = 0;
754
755 if (IS_ERR(data))
756 return PTR_ERR(data);
757
758 mutex_lock(&data->update_lock);
759 /* reverse logic: fan out of control reporting is enabled low */
760 if (data->fan_sta & G762_REG_FAN_STA_OOC) {
761 rpm = rpm_from_cnt(data->act_cnt, data->clk_freq,
762 G762_PULSE_FROM_REG(data->fan_cmd1),
763 G762_CLKDIV_FROM_REG(data->fan_cmd1),
764 G762_GEARMULT_FROM_REG(data->fan_cmd2));
765 }
766 mutex_unlock(&data->update_lock);
767
768 return sprintf(buf, "%u\n", rpm);
769}
770
771/*
772 * Read and write functions for pwm1_mode sysfs file. Get and set fan speed
773 * control mode i.e. PWM (1) or DC (0).
774 */
775static ssize_t get_pwm_mode(struct device *dev, struct device_attribute *da,
776 char *buf)
777{
778 struct g762_data *data = g762_update_client(dev);
779
780 if (IS_ERR(data))
781 return PTR_ERR(data);
782
783 return sprintf(buf, "%d\n",
784 !!(data->fan_cmd1 & G762_REG_FAN_CMD1_OUT_MODE));
785}
786
787static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *da,
788 const char *buf, size_t count)
789{
790 unsigned long val;
791 int ret;
792
793 if (kstrtoul(buf, 10, &val))
794 return -EINVAL;
795
796 ret = do_set_pwm_mode(dev, val);
797 if (ret < 0)
798 return ret;
799
800 return count;
801}
802
803/*
804 * Read and write functions for fan1_div sysfs file. Get and set fan
805 * controller prescaler value
806 */
807static ssize_t get_fan_div(struct device *dev,
808 struct device_attribute *da, char *buf)
809{
810 struct g762_data *data = g762_update_client(dev);
811
812 if (IS_ERR(data))
813 return PTR_ERR(data);
814
815 return sprintf(buf, "%d\n", G762_CLKDIV_FROM_REG(data->fan_cmd1));
816}
817
818static ssize_t set_fan_div(struct device *dev,
819 struct device_attribute *da,
820 const char *buf, size_t count)
821{
822 unsigned long val;
823 int ret;
824
825 if (kstrtoul(buf, 10, &val))
826 return -EINVAL;
827
828 ret = do_set_fan_div(dev, val);
829 if (ret < 0)
830 return ret;
831
832 return count;
833}
834
835/*
836 * Read and write functions for fan1_pulses sysfs file. Get and set number
837 * of tachometer pulses per fan revolution.
838 */
839static ssize_t get_fan_pulses(struct device *dev,
840 struct device_attribute *da, char *buf)
841{
842 struct g762_data *data = g762_update_client(dev);
843
844 if (IS_ERR(data))
845 return PTR_ERR(data);
846
847 return sprintf(buf, "%d\n", G762_PULSE_FROM_REG(data->fan_cmd1));
848}
849
850static ssize_t set_fan_pulses(struct device *dev,
851 struct device_attribute *da,
852 const char *buf, size_t count)
853{
854 unsigned long val;
855 int ret;
856
857 if (kstrtoul(buf, 10, &val))
858 return -EINVAL;
859
860 ret = do_set_fan_pulses(dev, val);
861 if (ret < 0)
862 return ret;
863
864 return count;
865}
866
867/*
868 * Read and write functions for pwm1_enable. Get and set fan speed control mode
869 * (i.e. closed or open-loop).
870 *
871 * Following documentation about hwmon's sysfs interface, a pwm1_enable node
872 * should accept followings:
873 *
874 * 0 : no fan speed control (i.e. fan at full speed)
875 * 1 : manual fan speed control enabled (use pwm[1-*]) (open-loop)
876 * 2+: automatic fan speed control enabled (use fan[1-*]_target) (closed-loop)
877 *
878 * but we do not accept 0 as this mode is not natively supported by the chip
879 * and it is not emulated by g762 driver. -EINVAL is returned in this case.
880 */
881static ssize_t get_pwm_enable(struct device *dev,
882 struct device_attribute *da, char *buf)
883{
884 struct g762_data *data = g762_update_client(dev);
885
886 if (IS_ERR(data))
887 return PTR_ERR(data);
888
889 return sprintf(buf, "%d\n",
890 (!!(data->fan_cmd1 & G762_REG_FAN_CMD1_FAN_MODE)) + 1);
891}
892
893static ssize_t set_pwm_enable(struct device *dev,
894 struct device_attribute *da,
895 const char *buf, size_t count)
896{
897 unsigned long val;
898 int ret;
899
900 if (kstrtoul(buf, 10, &val))
901 return -EINVAL;
902
903 ret = do_set_pwm_enable(dev, val);
904 if (ret < 0)
905 return ret;
906
907 return count;
908}
909
910/*
911 * Read and write functions for pwm1 sysfs file. Get and set pwm value
912 * (which affects fan speed) in open-loop mode. 0 stops the fan and 255
913 * makes it run at full speed.
914 */
915static ssize_t get_pwm(struct device *dev, struct device_attribute *da,
916 char *buf)
917{
918 struct g762_data *data = g762_update_client(dev);
919
920 if (IS_ERR(data))
921 return PTR_ERR(data);
922
923 return sprintf(buf, "%d\n", data->set_out);
924}
925
926static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
927 const char *buf, size_t count)
928{
929 unsigned long val;
930 int ret;
931
932 if (kstrtoul(buf, 10, &val))
933 return -EINVAL;
934
935 ret = do_set_pwm(dev, val);
936 if (ret < 0)
937 return ret;
938
939 return count;
940}
941
942/*
943 * Read and write function for fan1_target sysfs file. Get/set the fan speed in
944 * closed-loop mode. Speed is given as a RPM value; then the chip will regulate
945 * the fan speed using pulses from fan tachometer.
946 *
947 * Refer to rpm_from_cnt() implementation above to get info about count number
948 * calculation.
949 *
950 * Also note that due to rounding errors it is possible that you don't read
951 * back exactly the value you have set.
952 */
953static ssize_t get_fan_target(struct device *dev, struct device_attribute *da,
954 char *buf)
955{
956 struct g762_data *data = g762_update_client(dev);
957 unsigned int rpm;
958
959 if (IS_ERR(data))
960 return PTR_ERR(data);
961
962 mutex_lock(&data->update_lock);
963 rpm = rpm_from_cnt(data->set_cnt, data->clk_freq,
964 G762_PULSE_FROM_REG(data->fan_cmd1),
965 G762_CLKDIV_FROM_REG(data->fan_cmd1),
966 G762_GEARMULT_FROM_REG(data->fan_cmd2));
967 mutex_unlock(&data->update_lock);
968
969 return sprintf(buf, "%u\n", rpm);
970}
971
972static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
973 const char *buf, size_t count)
974{
975 unsigned long val;
976 int ret;
977
978 if (kstrtoul(buf, 10, &val))
979 return -EINVAL;
980
981 ret = do_set_fan_target(dev, val);
982 if (ret < 0)
983 return ret;
984
985 return count;
986}
987
988/* read function for fan1_fault sysfs file. */
989static ssize_t get_fan_failure(struct device *dev, struct device_attribute *da,
990 char *buf)
991{
992 struct g762_data *data = g762_update_client(dev);
993
994 if (IS_ERR(data))
995 return PTR_ERR(data);
996
997 return sprintf(buf, "%u\n", !!(data->fan_sta & G762_REG_FAN_STA_FAIL));
998}
999
1000/*
1001 * read function for fan1_alarm sysfs file. Note that OOC condition is
1002 * enabled low
1003 */
1004static ssize_t get_fan_ooc(struct device *dev, struct device_attribute *da,
1005 char *buf)
1006{
1007 struct g762_data *data = g762_update_client(dev);
1008
1009 if (IS_ERR(data))
1010 return PTR_ERR(data);
1011
1012 return sprintf(buf, "%u\n", !(data->fan_sta & G762_REG_FAN_STA_OOC));
1013}
1014
1015static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
1016static DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, get_pwm_mode, set_pwm_mode);
1017static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
1018 get_pwm_enable, set_pwm_enable);
1019static DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
1020static DEVICE_ATTR(fan1_alarm, S_IRUGO, get_fan_ooc, NULL);
1021static DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_failure, NULL);
1022static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO,
1023 get_fan_target, set_fan_target);
1024static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_fan_div, set_fan_div);
1025static DEVICE_ATTR(fan1_pulses, S_IWUSR | S_IRUGO,
1026 get_fan_pulses, set_fan_pulses);
1027
1028/* Driver data */
1029static struct attribute *g762_attributes[] = {
1030 &dev_attr_fan1_input.attr,
1031 &dev_attr_fan1_alarm.attr,
1032 &dev_attr_fan1_fault.attr,
1033 &dev_attr_fan1_target.attr,
1034 &dev_attr_fan1_div.attr,
1035 &dev_attr_fan1_pulses.attr,
1036 &dev_attr_pwm1.attr,
1037 &dev_attr_pwm1_mode.attr,
1038 &dev_attr_pwm1_enable.attr,
1039 NULL
1040};
1041
1042static const struct attribute_group g762_group = {
1043 .attrs = g762_attributes,
1044};
1045
1046/*
1047 * Enable both fan failure detection and fan out of control protection. The
1048 * function does not protect change/access to data structure; it must thus
1049 * only be called during initialization.
1050 */
1051static inline int g762_fan_init(struct device *dev)
1052{
1053 struct i2c_client *client = to_i2c_client(dev);
1054 struct g762_data *data = g762_update_client(dev);
1055
1056 if (IS_ERR(data))
1057 return PTR_ERR(data);
1058
1059 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL;
1060 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC;
1061 data->valid = false;
1062
1063 return i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
1064 data->fan_cmd1);
1065}
1066
1067static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
1068{
1069 struct g762_data *data;
1070 int ret;
1071
1072 if (!i2c_check_functionality(client->adapter,
1073 I2C_FUNC_SMBUS_BYTE_DATA))
1074 return -ENODEV;
1075
1076 data = devm_kzalloc(&client->dev, sizeof(struct g762_data), GFP_KERNEL);
1077 if (!data)
1078 return -ENOMEM;
1079
1080 i2c_set_clientdata(client, data);
1081 data->client = client;
1082 mutex_init(&data->update_lock);
1083
1084 /* Enable fan failure detection and fan out of control protection */
1085 ret = g762_fan_init(&client->dev);
1086 if (ret)
1087 return ret;
1088
1089 /* Get configuration via DT ... */
1090 ret = g762_of_clock_enable(client);
1091 if (ret)
1092 return ret;
1093 ret = g762_of_prop_import(client);
1094 if (ret)
1095 goto clock_dis;
1096 /* ... or platform_data */
1097 ret = g762_pdata_prop_import(client);
1098 if (ret)
1099 goto clock_dis;
1100
1101 /* Register sysfs hooks */
1102 ret = sysfs_create_group(&client->dev.kobj, &g762_group);
1103 if (ret)
1104 goto clock_dis;
1105
1106 data->hwmon_dev = hwmon_device_register(&client->dev);
1107 if (IS_ERR(data->hwmon_dev)) {
1108 ret = PTR_ERR(data->hwmon_dev);
1109 goto sysfs_rem;
1110 }
1111
1112 return 0;
1113
1114 sysfs_rem:
1115 sysfs_remove_group(&client->dev.kobj, &g762_group);
1116
1117 clock_dis:
1118 g762_of_clock_disable(client);
1119
1120 return ret;
1121}
1122
1123static int g762_remove(struct i2c_client *client)
1124{
1125 struct g762_data *data = i2c_get_clientdata(client);
1126
1127 hwmon_device_unregister(data->hwmon_dev);
1128 sysfs_remove_group(&client->dev.kobj, &g762_group);
1129 g762_of_clock_disable(client);
1130
1131 return 0;
1132}
1133
1134static struct i2c_driver g762_driver = {
1135 .driver = {
1136 .name = DRVNAME,
1137 .owner = THIS_MODULE,
1138 .of_match_table = of_match_ptr(g762_dt_match),
1139 },
1140 .probe = g762_probe,
1141 .remove = g762_remove,
1142 .id_table = g762_id,
1143};
1144
1145module_i2c_driver(g762_driver);
1146
1147MODULE_AUTHOR("Arnaud EBALARD <arno@natisbad.org>");
1148MODULE_DESCRIPTION("GMT G762/G763 driver");
1149MODULE_LICENSE("GPL");