Skip to content

Commit 46ef9d4

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]>
1 parent 33a045b commit 46ef9d4

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

drivers/hwmon/emc2305.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
static const unsigned short
1616
emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_END };
1717

18+
#define EMC2305_REG_FAN_STATUS 0x24
19+
#define EMC2305_REG_FAN_STALL_STATUS 0x25
1820
#define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
1921
#define EMC2305_REG_VENDOR 0xfe
2022
#define EMC2305_FAN_MAX 0xff
2123
#define EMC2305_FAN_MIN 0x00
2224
#define EMC2305_FAN_MAX_STATE 10
23-
#define EMC2305_DEVICE 0x34
2425
#define EMC2305_VENDOR 0x5d
2526
#define EMC2305_REG_PRODUCT_ID 0xfd
2627
#define EMC2305_TACH_REGS_UNUSE_BITS 3
@@ -39,6 +40,7 @@ emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_EN
3940
#define EMC2305_RPM_FACTOR 3932160
4041

4142
#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n))
43+
#define EMC2305_REG_FAN_CFG(n) (0x32 + 0x10 * (n))
4244
#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n))
4345
#define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n))
4446

@@ -58,6 +60,15 @@ static const struct i2c_device_id emc2305_ids[] = {
5860
};
5961
MODULE_DEVICE_TABLE(i2c, emc2305_ids);
6062

63+
static const struct of_device_id emc2305_dt_ids[] = {
64+
{ .compatible = "microchip,emc2305" },
65+
{ .compatible = "microchip,emc2303" },
66+
{ .compatible = "microchip,emc2302" },
67+
{ .compatible = "microchip,emc2301" },
68+
{ }
69+
};
70+
MODULE_DEVICE_TABLE(of, emc2305_dt_ids);
71+
6172
/**
6273
* @cdev: cooling device;
6374
* @curr_state: cooling current state;
@@ -101,6 +112,7 @@ struct emc2305_data {
101112
u8 pwm_num;
102113
bool pwm_separate;
103114
u8 pwm_min[EMC2305_PWM_MAX];
115+
u8 pwm_max;
104116
struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
105117
};
106118

@@ -273,7 +285,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
273285
struct i2c_client *client = data->client;
274286
int ret;
275287

276-
if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
288+
if (val < data->pwm_min[channel] || val > data->pwm_max)
277289
return -EINVAL;
278290

279291
ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
@@ -284,6 +296,49 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
284296
return 0;
285297
}
286298

299+
static int emc2305_get_tz_of(struct device *dev)
300+
{
301+
struct device_node *np = dev->of_node;
302+
struct emc2305_data *data = dev_get_drvdata(dev);
303+
int ret = 0;
304+
u32 val;
305+
int i;
306+
307+
/* OF parameters are optional - overwrite default setting
308+
* if some of them are provided.
309+
*/
310+
311+
ret = of_property_read_u32(np, "emc2305,cooling-levels", &val);
312+
if (!ret)
313+
data->max_state = (u8)val;
314+
else if (ret != -EINVAL)
315+
return ret;
316+
317+
ret = of_property_read_u32(np, "emc2305,pwm-max", &val);
318+
if (!ret)
319+
data->pwm_max = (u8)val;
320+
else if (ret != -EINVAL)
321+
return ret;
322+
323+
ret = of_property_read_u32(np, "emc2305,pwm-min", &val);
324+
if (!ret)
325+
for (i = 0; i < EMC2305_PWM_MAX; i++)
326+
data->pwm_min[i] = (u8)val;
327+
else if (ret != -EINVAL)
328+
return ret;
329+
330+
/* Not defined or 0 means one thermal zone over all cooling devices.
331+
* Otherwise - separated thermal zones for each PWM channel.
332+
*/
333+
ret = of_property_read_u32(np, "emc2305,pwm-channel", &val);
334+
if (!ret)
335+
data->pwm_separate = (val != 0);
336+
else if (ret != -EINVAL)
337+
return ret;
338+
339+
return 0;
340+
}
341+
287342
static int emc2305_set_single_tz(struct device *dev, int idx)
288343
{
289344
struct emc2305_data *data = dev_get_drvdata(dev);
@@ -572,11 +627,18 @@ static int emc2305_probe(struct i2c_client *client, const struct i2c_device_id *
572627
data->pwm_separate = pdata->pwm_separate;
573628
for (i = 0; i < EMC2305_PWM_MAX; i++)
574629
data->pwm_min[i] = pdata->pwm_min[i];
630+
data->pwm_max = EMC2305_FAN_MAX;
575631
} else {
576632
data->max_state = EMC2305_FAN_MAX_STATE;
577633
data->pwm_separate = false;
578634
for (i = 0; i < EMC2305_PWM_MAX; i++)
579635
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+
}
580642
}
581643

582644
data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data,
@@ -597,6 +659,12 @@ static int emc2305_probe(struct i2c_client *client, const struct i2c_device_id *
597659
return ret;
598660
}
599661

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+
600668
return 0;
601669
}
602670

@@ -612,6 +680,7 @@ static struct i2c_driver emc2305_driver = {
612680
.class = I2C_CLASS_HWMON,
613681
.driver = {
614682
.name = "emc2305",
683+
.of_match_table = emc2305_dt_ids,
615684
},
616685
.probe = emc2305_probe,
617686
.remove = emc2305_remove,

0 commit comments

Comments
 (0)