Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Arnaud Ebalard and committed by
Guenter Roeck
594fbe71 31e7ad74

+1309
+47
Documentation/devicetree/bindings/hwmon/g762.txt
··· 1 + GMT G762/G763 PWM Fan controller 2 + 3 + Required node properties: 4 + 5 + - "compatible": must be either "gmt,g762" or "gmt,g763" 6 + - "reg": I2C bus address of the device 7 + - "clocks": a fixed clock providing input clock frequency 8 + on CLK pin of the chip. 9 + 10 + Optional properties: 11 + 12 + - "fan_startv": fan startup voltage. Accepted values are 0, 1, 2 and 3. 13 + The higher the more. 14 + 15 + - "pwm_polarity": pwm polarity. Accepted values are 0 (positive duty) 16 + and 1 (negative duty). 17 + 18 + - "fan_gear_mode": fan gear mode. Supported values are 0, 1 and 2. 19 + 20 + If an optional property is not set in .dts file, then current value is kept 21 + unmodified (e.g. u-boot installed value). 22 + 23 + Additional information on operational parameters for the device is available 24 + in Documentation/hwmon/g762. A detailed datasheet for the device is available 25 + at http://natisbad.org/NAS/refs/GMT_EDS-762_763-080710-0.2.pdf. 26 + 27 + Example g762 node: 28 + 29 + clocks { 30 + #address-cells = <1>; 31 + #size-cells = <0>; 32 + 33 + g762_clk: fixedclk { 34 + compatible = "fixed-clock"; 35 + #clock-cells = <0>; 36 + clock-frequency = <8192>; 37 + } 38 + } 39 + 40 + g762: g762@3e { 41 + compatible = "gmt,g762"; 42 + reg = <0x3e>; 43 + clocks = <&g762_clk> 44 + fan_gear_mode = <0>; /* chip default */ 45 + fan_startv = <1>; /* chip default */ 46 + pwm_polarity = <0>; /* chip default */ 47 + };
+65
Documentation/hwmon/g762
··· 1 + Kernel driver g762 2 + ================== 3 + 4 + The GMT G762 Fan Speed PWM Controller is connected directly to a fan 5 + and performs closed-loop or open-loop control of the fan speed. Two 6 + modes - PWM or DC - are supported by the device. 7 + 8 + For additional information, a detailed datasheet is available at 9 + http://natisbad.org/NAS/ref/GMT_EDS-762_763-080710-0.2.pdf. sysfs 10 + bindings are described in Documentation/hwmon/sysfs-interface. 11 + 12 + The following entries are available to the user in a subdirectory of 13 + /sys/bus/i2c/drivers/g762/ to control the operation of the device. 14 + This can be done manually using the following entries but is usually 15 + done via a userland daemon like fancontrol. 16 + 17 + Note that those entries do not provide ways to setup the specific 18 + hardware characteristics of the system (reference clock, pulses per 19 + fan revolution, ...); Those can be modified via devicetree bindings 20 + documented in Documentation/devicetree/bindings/hwmon/g762.txt or 21 + using a specific platform_data structure in board initialization 22 + file (see include/linux/platform_data/g762.h). 23 + 24 + fan1_target: set desired fan speed. This only makes sense in closed-loop 25 + fan speed control (i.e. when pwm1_enable is set to 2). 26 + 27 + fan1_input: provide current fan rotation value in RPM as reported by 28 + the fan to the device. 29 + 30 + fan1_div: fan clock divisor. Supported value are 1, 2, 4 and 8. 31 + 32 + fan1_pulses: number of pulses per fan revolution. Supported values 33 + are 2 and 4. 34 + 35 + fan1_fault: reports fan failure, i.e. no transition on fan gear pin for 36 + about 0.7s (if the fan is not voluntarily set off). 37 + 38 + fan1_alarm: in closed-loop control mode, if fan RPM value is 25% out 39 + of the programmed value for over 6 seconds 'fan1_alarm' is 40 + set to 1. 41 + 42 + pwm1_enable: set current fan speed control mode i.e. 1 for manual fan 43 + speed control (open-loop) via pwm1 described below, 2 for 44 + automatic fan speed control (closed-loop) via fan1_target 45 + above. 46 + 47 + pwm1_mode: set or get fan driving mode: 1 for PWM mode, 0 for DC mode. 48 + 49 + pwm1: get or set PWM fan control value in open-loop mode. This is an 50 + integer value between 0 and 255. 0 stops the fan, 255 makes 51 + it run at full speed. 52 + 53 + Both in PWM mode ('pwm1_mode' set to 1) and DC mode ('pwm1_mode' set to 0), 54 + when current fan speed control mode is open-loop ('pwm1_enable' set to 1), 55 + the fan speed is programmed by setting a value between 0 and 255 via 'pwm1' 56 + entry (0 stops the fan, 255 makes it run at full speed). In closed-loop mode 57 + ('pwm1_enable' set to 2), the expected rotation speed in RPM can be passed to 58 + the chip via 'fan1_target'. In closed-loop mode, the target speed is compared 59 + with current speed (available via 'fan1_input') by the device and a feedback 60 + is performed to match that target value. The fan speed value is computed 61 + based on the parameters associated with the physical characteristics of the 62 + system: a reference clock source frequency, a number of pulses per fan 63 + revolution, etc. 64 + 65 + Note that the driver will update its values at most once per second.
+10
drivers/hwmon/Kconfig
··· 461 461 This driver can also be built as a module. If so, the module 462 462 will be called g760a. 463 463 464 + config SENSORS_G762 465 + tristate "GMT G762 and G763" 466 + depends on I2C 467 + help 468 + If you say yes here you get support for Global Mixed-mode 469 + Technology Inc G762 and G763 fan speed PWM controller chips. 470 + 471 + This driver can also be built as a module. If so, the module 472 + will be called g762. 473 + 464 474 config SENSORS_GL518SM 465 475 tristate "Genesys Logic GL518SM" 466 476 depends on I2C
+1
drivers/hwmon/Makefile
··· 60 60 obj-$(CONFIG_SENSORS_FAM15H_POWER) += fam15h_power.o 61 61 obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o 62 62 obj-$(CONFIG_SENSORS_G760A) += g760a.o 63 + obj-$(CONFIG_SENSORS_G762) += g762.o 63 64 obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o 64 65 obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o 65 66 obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o
+1149
drivers/hwmon/g762.c
··· 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 + 60 + static const struct i2c_device_id g762_id[] = { 61 + { "g762", 0 }, 62 + { "g763", 0 }, 63 + { } 64 + }; 65 + MODULE_DEVICE_TABLE(i2c, g762_id); 66 + 67 + enum 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 + 130 + struct 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 + */ 183 + static 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 + */ 196 + static 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 */ 207 + static 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 + */ 267 + static 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) */ 283 + static 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. */ 314 + static 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. */ 355 + static 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. */ 392 + static 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). */ 423 + static 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) */ 465 + static 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 + */ 499 + static 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 + */ 520 + static 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. */ 543 + static 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 589 + static 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 + */ 602 + static 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 + 645 + static 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 + 656 + static 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 + 678 + static 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 700 + static int g762_of_prop_import(struct i2c_client *client) 701 + { 702 + return 0; 703 + } 704 + 705 + static int g762_of_clock_enable(struct i2c_client *client) 706 + { 707 + return 0; 708 + } 709 + 710 + static 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 + 718 + static 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 + */ 749 + static 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 + */ 775 + static 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 + 787 + static 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 + */ 807 + static 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 + 818 + static 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 + */ 839 + static 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 + 850 + static 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 + */ 881 + static 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 + 893 + static 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 + */ 915 + static 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 + 926 + static 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 + */ 953 + static 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 + 972 + static 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. */ 989 + static 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 + */ 1004 + static 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 + 1015 + static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); 1016 + static DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, get_pwm_mode, set_pwm_mode); 1017 + static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 1018 + get_pwm_enable, set_pwm_enable); 1019 + static DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL); 1020 + static DEVICE_ATTR(fan1_alarm, S_IRUGO, get_fan_ooc, NULL); 1021 + static DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_failure, NULL); 1022 + static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, 1023 + get_fan_target, set_fan_target); 1024 + static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_fan_div, set_fan_div); 1025 + static DEVICE_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, 1026 + get_fan_pulses, set_fan_pulses); 1027 + 1028 + /* Driver data */ 1029 + static 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 + 1042 + static 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 + */ 1051 + static 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 + 1067 + static 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 + 1123 + static 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 + 1134 + static 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 + 1145 + module_i2c_driver(g762_driver); 1146 + 1147 + MODULE_AUTHOR("Arnaud EBALARD <arno@natisbad.org>"); 1148 + MODULE_DESCRIPTION("GMT G762/G763 driver"); 1149 + MODULE_LICENSE("GPL");
+37
include/linux/platform_data/g762.h
··· 1 + /* 2 + * Platform data structure for g762 fan controller driver 3 + * 4 + * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef __LINUX_PLATFORM_DATA_G762_H__ 21 + #define __LINUX_PLATFORM_DATA_G762_H__ 22 + 23 + /* 24 + * Following structure can be used to set g762 driver platform specific data 25 + * during board init. Note that passing a sparse structure is possible but 26 + * will result in non-specified attributes to be set to default value, hence 27 + * overloading those installed during boot (e.g. by u-boot). 28 + */ 29 + 30 + struct g762_platform_data { 31 + u32 fan_startv; 32 + u32 fan_gear_mode; 33 + u32 pwm_polarity; 34 + u32 clk_freq; 35 + }; 36 + 37 + #endif /* __LINUX_PLATFORM_DATA_G762_H__ */