Skip to content

Commit 20005cc

Browse files
MikeLooijmansgroeck
authored andcommitted
hwmon: (max6650) Allow fan shutdown and initial rpm target
The fan can be stopped by writing "3" to pwm1_enable in sysfs. Add devicetree property for early initialization of the fan controller to prevent overheating, for example when resetting the board while the fan was completely turned off. Also improve error reporting, I2C failures were ignored while writing new values. Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent a6cdeef commit 20005cc

File tree

2 files changed

+68
-41
lines changed

2 files changed

+68
-41
lines changed

Documentation/hwmon/max6650

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fan3_input ro "
3434
fan4_input ro "
3535
fan1_target rw desired fan speed in RPM (closed loop mode only)
3636
pwm1_enable rw regulator mode, 0=full on, 1=open loop, 2=closed loop
37+
3=off
3738
pwm1 rw relative speed (0-255), 255=max. speed.
3839
Used in open loop mode only.
3940
fan1_div rw sets the speed range the inputs can handle. Legal

drivers/hwmon/max6650.c

Lines changed: 67 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,30 @@ static struct max6650_data *max6650_update_device(struct device *dev)
185185
return data;
186186
}
187187

188+
/*
189+
* Change the operating mode of the chip (if needed).
190+
* mode is one of the MAX6650_CFG_MODE_* values.
191+
*/
192+
static int max6650_set_operating_mode(struct max6650_data *data, u8 mode)
193+
{
194+
int result;
195+
u8 config = data->config;
196+
197+
if (mode == (config & MAX6650_CFG_MODE_MASK))
198+
return 0;
199+
200+
config = (config & ~MAX6650_CFG_MODE_MASK) | mode;
201+
202+
result = i2c_smbus_write_byte_data(data->client, MAX6650_REG_CONFIG,
203+
config);
204+
if (result < 0)
205+
return result;
206+
207+
data->config = config;
208+
209+
return 0;
210+
}
211+
188212
static ssize_t get_fan(struct device *dev, struct device_attribute *devattr,
189213
char *buf)
190214
{
@@ -266,18 +290,12 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr,
266290
return sprintf(buf, "%d\n", rpm);
267291
}
268292

269-
static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
270-
const char *buf, size_t count)
293+
static int max6650_set_target(struct max6650_data *data, unsigned long rpm)
271294
{
272-
struct max6650_data *data = dev_get_drvdata(dev);
273-
struct i2c_client *client = data->client;
274295
int kscale, ktach;
275-
unsigned long rpm;
276-
int err;
277296

278-
err = kstrtoul(buf, 10, &rpm);
279-
if (err)
280-
return err;
297+
if (rpm == 0)
298+
return max6650_set_operating_mode(data, MAX6650_CFG_MODE_OFF);
281299

282300
rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
283301

@@ -288,8 +306,6 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
288306
* KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1
289307
*/
290308

291-
mutex_lock(&data->update_lock);
292-
293309
kscale = DIV_FROM_REG(data->config);
294310
ktach = ((clock * kscale) / (256 * rpm / 60)) - 1;
295311
if (ktach < 0)
@@ -298,10 +314,30 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
298314
ktach = 255;
299315
data->speed = ktach;
300316

301-
i2c_smbus_write_byte_data(client, MAX6650_REG_SPEED, data->speed);
317+
return i2c_smbus_write_byte_data(data->client, MAX6650_REG_SPEED,
318+
data->speed);
319+
}
320+
321+
static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
322+
const char *buf, size_t count)
323+
{
324+
struct max6650_data *data = dev_get_drvdata(dev);
325+
unsigned long rpm;
326+
int err;
327+
328+
err = kstrtoul(buf, 10, &rpm);
329+
if (err)
330+
return err;
331+
332+
mutex_lock(&data->update_lock);
333+
334+
err = max6650_set_target(data, rpm);
302335

303336
mutex_unlock(&data->update_lock);
304337

338+
if (err < 0)
339+
return err;
340+
305341
return count;
306342
}
307343

@@ -355,12 +391,11 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
355391
data->dac = 180 - (180 * pwm)/255;
356392
else
357393
data->dac = 76 - (76 * pwm)/255;
358-
359-
i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac);
394+
err = i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac);
360395

361396
mutex_unlock(&data->update_lock);
362397

363-
return count;
398+
return err < 0 ? err : count;
364399
}
365400

366401
/*
@@ -369,14 +404,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
369404
* 0 = Fan always on
370405
* 1 = Open loop, Voltage is set according to speed, not regulated.
371406
* 2 = Closed loop, RPM for all fans regulated by fan1 tachometer
407+
* 3 = Fan off
372408
*/
373-
374409
static ssize_t get_enable(struct device *dev, struct device_attribute *devattr,
375410
char *buf)
376411
{
377412
struct max6650_data *data = max6650_update_device(dev);
378413
int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4;
379-
int sysfs_modes[4] = {0, 1, 2, 1};
414+
int sysfs_modes[4] = {0, 3, 2, 1};
380415

381416
return sprintf(buf, "%d\n", sysfs_modes[mode]);
382417
}
@@ -385,25 +420,25 @@ static ssize_t set_enable(struct device *dev, struct device_attribute *devattr,
385420
const char *buf, size_t count)
386421
{
387422
struct max6650_data *data = dev_get_drvdata(dev);
388-
struct i2c_client *client = data->client;
389-
int max6650_modes[3] = {0, 3, 2};
390423
unsigned long mode;
391424
int err;
425+
const u8 max6650_modes[] = {
426+
MAX6650_CFG_MODE_ON,
427+
MAX6650_CFG_MODE_OPEN_LOOP,
428+
MAX6650_CFG_MODE_CLOSED_LOOP,
429+
MAX6650_CFG_MODE_OFF,
430+
};
392431

393432
err = kstrtoul(buf, 10, &mode);
394433
if (err)
395434
return err;
396435

397-
if (mode > 2)
436+
if (mode >= ARRAY_SIZE(max6650_modes))
398437
return -EINVAL;
399438

400439
mutex_lock(&data->update_lock);
401440

402-
data->config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG);
403-
data->config = (data->config & ~MAX6650_CFG_MODE_MASK)
404-
| (max6650_modes[mode] << 4);
405-
406-
i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, data->config);
441+
max6650_set_operating_mode(data, max6650_modes[mode]);
407442

408443
mutex_unlock(&data->update_lock);
409444

@@ -582,6 +617,7 @@ static int max6650_init_client(struct max6650_data *data,
582617
int err = -EIO;
583618
u32 voltage;
584619
u32 prescale;
620+
u32 target_rpm;
585621

586622
if (of_property_read_u32(dev->of_node, "maxim,fan-microvolt",
587623
&voltage))
@@ -642,22 +678,6 @@ static int max6650_init_client(struct max6650_data *data,
642678
(config & MAX6650_CFG_V12) ? 12 : 5,
643679
1 << (config & MAX6650_CFG_PRESCALER_MASK));
644680

645-
/*
646-
* If mode is set to "full off", we change it to "open loop" and
647-
* set DAC to 255, which has the same effect. We do this because
648-
* there's no "full off" mode defined in hwmon specifications.
649-
*/
650-
651-
if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) {
652-
dev_dbg(dev, "Change mode to open loop, full off.\n");
653-
config = (config & ~MAX6650_CFG_MODE_MASK)
654-
| MAX6650_CFG_MODE_OPEN_LOOP;
655-
if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) {
656-
dev_err(dev, "DAC write error, aborting.\n");
657-
return err;
658-
}
659-
}
660-
661681
if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) {
662682
dev_err(dev, "Config write error, aborting.\n");
663683
return err;
@@ -666,6 +686,12 @@ static int max6650_init_client(struct max6650_data *data,
666686
data->config = config;
667687
data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT);
668688

689+
if (!of_property_read_u32(client->dev.of_node, "maxim,fan-target-rpm",
690+
&target_rpm)) {
691+
max6650_set_target(data, target_rpm);
692+
max6650_set_operating_mode(data, MAX6650_CFG_MODE_CLOSED_LOOP);
693+
}
694+
669695
return 0;
670696
}
671697

0 commit comments

Comments
 (0)