Skip to content

Commit 576481e

Browse files
pelwellpopcornmix
authored andcommitted
hwmon: emc2305: fixups for driver submitted to mailing lists
The driver had a number of issues, checkpatch warnings/errors, and other limitations, so fix these up to make it usable. Signed-off-by: Phil Elwell <[email protected]> Signed-off-by: Dave Stevenson <[email protected]> hwmon: emc2305: Add calls to initialise of cooling maps Commit 46ef9d4 ("hwmon: emc2305: fixups for driver submitted to mailing lists") missed adding the call to thermal_of_cooling_device_register required to configure any cooling maps for the device, hence stopping it from actually ever changing speed. Signed-off-by: Dave Stevenson <[email protected]> hwmon: emc2305: Change OF properties pwm-min & pwm-max to u8 There is no DT binding for emc2305 as mainline are still discussing how to do a generic fan binding. The 5.15 driver was reading the "emc2305," properties "cooling-levels", "pwm-max", "pwm-min", and "pwm-channel" as u8. The overlay was writing them as u16 (;) so it was working. The 6.1 driver was reading as u32, which failed as there is insufficient data. As this is all downstream only, revert to u8 to match 5.15. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 9cdd77f commit 576481e

File tree

1 file changed

+103
-6
lines changed

1 file changed

+103
-6
lines changed

drivers/hwmon/emc2305.c

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
#include <linux/platform_data/emc2305.h>
1313
#include <linux/thermal.h>
1414

15+
#define EMC2305_REG_FAN_STATUS 0x24
16+
#define EMC2305_REG_FAN_STALL_STATUS 0x25
1517
#define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
1618
#define EMC2305_REG_VENDOR 0xfe
1719
#define EMC2305_FAN_MAX 0xff
1820
#define EMC2305_FAN_MIN 0x00
1921
#define EMC2305_FAN_MAX_STATE 10
20-
#define EMC2305_DEVICE 0x34
2122
#define EMC2305_VENDOR 0x5d
2223
#define EMC2305_REG_PRODUCT_ID 0xfd
2324
#define EMC2305_TACH_REGS_UNUSE_BITS 3
@@ -36,6 +37,7 @@
3637
#define EMC2305_RPM_FACTOR 3932160
3738

3839
#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n))
40+
#define EMC2305_REG_FAN_CFG(n) (0x32 + 0x10 * (n))
3941
#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n))
4042
#define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n))
4143

@@ -100,6 +102,7 @@ struct emc2305_data {
100102
u8 pwm_num;
101103
bool pwm_separate;
102104
u8 pwm_min[EMC2305_PWM_MAX];
105+
u8 pwm_max;
103106
struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
104107
};
105108

@@ -112,6 +115,8 @@ static char *emc2305_fan_name[] = {
112115
"emc2305_fan5",
113116
};
114117

118+
static void emc2305_unset_tz(struct device *dev);
119+
115120
static int emc2305_get_max_channel(const struct emc2305_data *data)
116121
{
117122
return data->pwm_num;
@@ -270,7 +275,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
270275
struct i2c_client *client = data->client;
271276
int ret;
272277

273-
if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
278+
if (val < data->pwm_min[channel] || val > data->pwm_max)
274279
return -EINVAL;
275280

276281
ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
@@ -281,6 +286,49 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
281286
return 0;
282287
}
283288

289+
static int emc2305_get_tz_of(struct device *dev)
290+
{
291+
struct device_node *np = dev->of_node;
292+
struct emc2305_data *data = dev_get_drvdata(dev);
293+
int ret = 0;
294+
u8 val;
295+
int i;
296+
297+
/* OF parameters are optional - overwrite default setting
298+
* if some of them are provided.
299+
*/
300+
301+
ret = of_property_read_u8(np, "emc2305,cooling-levels", &val);
302+
if (!ret)
303+
data->max_state = val;
304+
else if (ret != -EINVAL)
305+
return ret;
306+
307+
ret = of_property_read_u8(np, "emc2305,pwm-max", &val);
308+
if (!ret)
309+
data->pwm_max = val;
310+
else if (ret != -EINVAL)
311+
return ret;
312+
313+
ret = of_property_read_u8(np, "emc2305,pwm-min", &val);
314+
if (!ret)
315+
for (i = 0; i < EMC2305_PWM_MAX; i++)
316+
data->pwm_min[i] = val;
317+
else if (ret != -EINVAL)
318+
return ret;
319+
320+
/* Not defined or 0 means one thermal zone over all cooling devices.
321+
* Otherwise - separated thermal zones for each PWM channel.
322+
*/
323+
ret = of_property_read_u8(np, "emc2305,pwm-channel", &val);
324+
if (!ret)
325+
data->pwm_separate = (val != 0);
326+
else if (ret != -EINVAL)
327+
return ret;
328+
329+
return 0;
330+
}
331+
284332
static int emc2305_set_single_tz(struct device *dev, int idx)
285333
{
286334
struct emc2305_data *data = dev_get_drvdata(dev);
@@ -290,9 +338,16 @@ static int emc2305_set_single_tz(struct device *dev, int idx)
290338
cdev_idx = (idx) ? idx - 1 : 0;
291339
pwm = data->pwm_min[cdev_idx];
292340

293-
data->cdev_data[cdev_idx].cdev =
294-
devm_thermal_of_cooling_device_register(dev, dev->of_node,
295-
emc2305_fan_name[idx], data,
341+
if (dev->of_node)
342+
data->cdev_data[cdev_idx].cdev =
343+
devm_thermal_of_cooling_device_register(dev, dev->of_node,
344+
emc2305_fan_name[idx],
345+
data,
346+
&emc2305_cooling_ops);
347+
else
348+
data->cdev_data[cdev_idx].cdev =
349+
thermal_cooling_device_register(emc2305_fan_name[idx],
350+
data,
296351
&emc2305_cooling_ops);
297352

298353
if (IS_ERR(data->cdev_data[cdev_idx].cdev)) {
@@ -331,9 +386,26 @@ static int emc2305_set_tz(struct device *dev)
331386
for (i = 0; i < data->pwm_num; i++) {
332387
ret = emc2305_set_single_tz(dev, i + 1);
333388
if (ret)
334-
return ret;
389+
goto thermal_cooling_device_register_fail;
335390
}
336391
return 0;
392+
393+
thermal_cooling_device_register_fail:
394+
emc2305_unset_tz(dev);
395+
return ret;
396+
}
397+
398+
static void emc2305_unset_tz(struct device *dev)
399+
{
400+
struct emc2305_data *data = dev_get_drvdata(dev);
401+
int i;
402+
403+
/* Unregister cooling device. */
404+
if (!dev->of_node) {
405+
for (i = 0; i < EMC2305_PWM_MAX; i++)
406+
if (data->cdev_data[i].cdev)
407+
thermal_cooling_device_unregister(data->cdev_data[i].cdev);
408+
}
337409
}
338410

339411
static umode_t
@@ -555,11 +627,18 @@ static int emc2305_probe(struct i2c_client *client)
555627
data->pwm_separate = pdata->pwm_separate;
556628
for (i = 0; i < EMC2305_PWM_MAX; i++)
557629
data->pwm_min[i] = pdata->pwm_min[i];
630+
data->pwm_max = EMC2305_FAN_MAX;
558631
} else {
559632
data->max_state = EMC2305_FAN_MAX_STATE;
560633
data->pwm_separate = false;
561634
for (i = 0; i < EMC2305_PWM_MAX; i++)
562635
data->pwm_min[i] = EMC2305_FAN_MIN;
636+
data->pwm_max = EMC2305_FAN_MAX;
637+
if (dev->of_node) {
638+
ret = emc2305_get_tz_of(dev);
639+
if (ret < 0)
640+
return ret;
641+
}
563642
}
564643

565644
data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data,
@@ -580,21 +659,39 @@ static int emc2305_probe(struct i2c_client *client)
580659
return ret;
581660
}
582661

662+
/* Acknowledge any existing faults. Stops the device responding on the
663+
* SMBus alert address.
664+
*/
665+
i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STALL_STATUS);
666+
i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STATUS);
667+
583668
return 0;
584669
}
585670

586671
static const struct of_device_id of_emc2305_match_table[] = {
587672
{ .compatible = "microchip,emc2305", },
673+
{ .compatible = "microchip,emc2303", },
674+
{ .compatible = "microchip,emc2302", },
675+
{ .compatible = "microchip,emc2301", },
588676
{},
589677
};
590678
MODULE_DEVICE_TABLE(of, of_emc2305_match_table);
591679

680+
static void emc2305_remove(struct i2c_client *client)
681+
{
682+
struct device *dev = &client->dev;
683+
684+
if (IS_REACHABLE(CONFIG_THERMAL))
685+
emc2305_unset_tz(dev);
686+
}
687+
592688
static struct i2c_driver emc2305_driver = {
593689
.driver = {
594690
.name = "emc2305",
595691
.of_match_table = of_emc2305_match_table,
596692
},
597693
.probe = emc2305_probe,
694+
.remove = emc2305_remove,
598695
.id_table = emc2305_ids,
599696
};
600697

0 commit comments

Comments
 (0)