1 From 38798884cb3ccd05b2a82299db865aeb7e7c059b Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Thu, 5 May 2022 15:46:07 +0100
4 Subject: [PATCH] hwmon: emc2305: fixups for driver submitted to mailing lists
6 The driver had a number of issues, checkpatch warnings/errors,
7 and other limitations, so fix these up to make it usable.
9 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
12 hwmon: emc2305: Add calls to initialise of cooling maps
14 Commit 46ef9d4ed26b ("hwmon: emc2305: fixups for driver submitted to
15 mailing lists") missed adding the call to thermal_of_cooling_device_register
16 required to configure any cooling maps for the device, hence stopping it
17 from actually ever changing speed.
19 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
21 hwmon: emc2305: Change OF properties pwm-min & pwm-max to u8
23 There is no DT binding for emc2305 as mainline are still
24 discussing how to do a generic fan binding.
25 The 5.15 driver was reading the "emc2305," properties
26 "cooling-levels", "pwm-max", "pwm-min", and "pwm-channel" as u8.
27 The overlay was writing them as u16 (;) so it was working.
29 The 6.1 driver was reading as u32, which failed as there is
32 As this is all downstream only, revert to u8 to match 5.15.
34 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
36 drivers/hwmon/emc2305.c | 95 +++++++++++++++++++++++++++++++++++++----
37 1 file changed, 87 insertions(+), 8 deletions(-)
39 --- a/drivers/hwmon/emc2305.c
40 +++ b/drivers/hwmon/emc2305.c
42 #include <linux/platform_data/emc2305.h>
43 #include <linux/thermal.h>
45 +#define EMC2305_REG_FAN_STATUS 0x24
46 +#define EMC2305_REG_FAN_STALL_STATUS 0x25
47 #define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
48 #define EMC2305_REG_VENDOR 0xfe
49 #define EMC2305_FAN_MAX 0xff
50 #define EMC2305_FAN_MIN 0x00
51 #define EMC2305_FAN_MAX_STATE 10
52 -#define EMC2305_DEVICE 0x34
53 #define EMC2305_VENDOR 0x5d
54 #define EMC2305_REG_PRODUCT_ID 0xfd
55 #define EMC2305_TACH_REGS_UNUSE_BITS 3
57 #define EMC2305_RPM_FACTOR 3932160
59 #define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n))
60 +#define EMC2305_REG_FAN_CFG(n) (0x32 + 0x10 * (n))
61 #define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n))
62 #define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n))
64 @@ -55,6 +57,15 @@ static const struct i2c_device_id emc230
66 MODULE_DEVICE_TABLE(i2c, emc2305_ids);
68 +static const struct of_device_id emc2305_dt_ids[] = {
69 + { .compatible = "microchip,emc2305" },
70 + { .compatible = "microchip,emc2303" },
71 + { .compatible = "microchip,emc2302" },
72 + { .compatible = "microchip,emc2301" },
75 +MODULE_DEVICE_TABLE(of, emc2305_dt_ids);
78 * struct emc2305_cdev_data - device-specific cooling device state
79 * @cdev: cooling device
80 @@ -100,6 +111,7 @@ struct emc2305_data {
83 u8 pwm_min[EMC2305_PWM_MAX];
85 struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
88 @@ -272,7 +284,7 @@ static int emc2305_set_pwm(struct device
89 struct i2c_client *client = data->client;
92 - if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
93 + if (val < data->pwm_min[channel] || val > data->pwm_max)
96 ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
97 @@ -283,6 +295,49 @@ static int emc2305_set_pwm(struct device
101 +static int emc2305_get_tz_of(struct device *dev)
103 + struct device_node *np = dev->of_node;
104 + struct emc2305_data *data = dev_get_drvdata(dev);
109 + /* OF parameters are optional - overwrite default setting
110 + * if some of them are provided.
113 + ret = of_property_read_u8(np, "emc2305,cooling-levels", &val);
115 + data->max_state = val;
116 + else if (ret != -EINVAL)
119 + ret = of_property_read_u8(np, "emc2305,pwm-max", &val);
121 + data->pwm_max = val;
122 + else if (ret != -EINVAL)
125 + ret = of_property_read_u8(np, "emc2305,pwm-min", &val);
127 + for (i = 0; i < EMC2305_PWM_MAX; i++)
128 + data->pwm_min[i] = val;
129 + else if (ret != -EINVAL)
132 + /* Not defined or 0 means one thermal zone over all cooling devices.
133 + * Otherwise - separated thermal zones for each PWM channel.
135 + ret = of_property_read_u8(np, "emc2305,pwm-channel", &val);
137 + data->pwm_separate = (val != 0);
138 + else if (ret != -EINVAL)
144 static int emc2305_set_single_tz(struct device *dev, int idx)
146 struct emc2305_data *data = dev_get_drvdata(dev);
147 @@ -292,9 +347,17 @@ static int emc2305_set_single_tz(struct
148 cdev_idx = (idx) ? idx - 1 : 0;
149 pwm = data->pwm_min[cdev_idx];
151 - data->cdev_data[cdev_idx].cdev =
152 - thermal_cooling_device_register(emc2305_fan_name[idx], data,
153 - &emc2305_cooling_ops);
155 + data->cdev_data[cdev_idx].cdev =
156 + devm_thermal_of_cooling_device_register(dev, dev->of_node,
157 + emc2305_fan_name[idx],
159 + &emc2305_cooling_ops);
161 + data->cdev_data[cdev_idx].cdev =
162 + thermal_cooling_device_register(emc2305_fan_name[idx],
164 + &emc2305_cooling_ops);
166 if (IS_ERR(data->cdev_data[cdev_idx].cdev)) {
167 dev_err(dev, "Failed to register cooling device %s\n", emc2305_fan_name[idx]);
168 @@ -347,9 +410,11 @@ static void emc2305_unset_tz(struct devi
171 /* Unregister cooling device. */
172 - for (i = 0; i < EMC2305_PWM_MAX; i++)
173 - if (data->cdev_data[i].cdev)
174 - thermal_cooling_device_unregister(data->cdev_data[i].cdev);
175 + if (!dev->of_node) {
176 + for (i = 0; i < EMC2305_PWM_MAX; i++)
177 + if (data->cdev_data[i].cdev)
178 + thermal_cooling_device_unregister(data->cdev_data[i].cdev);
183 @@ -571,11 +636,18 @@ static int emc2305_probe(struct i2c_clie
184 data->pwm_separate = pdata->pwm_separate;
185 for (i = 0; i < EMC2305_PWM_MAX; i++)
186 data->pwm_min[i] = pdata->pwm_min[i];
187 + data->pwm_max = EMC2305_FAN_MAX;
189 data->max_state = EMC2305_FAN_MAX_STATE;
190 data->pwm_separate = false;
191 for (i = 0; i < EMC2305_PWM_MAX; i++)
192 data->pwm_min[i] = EMC2305_FAN_MIN;
193 + data->pwm_max = EMC2305_FAN_MAX;
194 + if (dev->of_node) {
195 + ret = emc2305_get_tz_of(dev);
201 data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data,
202 @@ -596,6 +668,12 @@ static int emc2305_probe(struct i2c_clie
206 + /* Acknowledge any existing faults. Stops the device responding on the
207 + * SMBus alert address.
209 + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STALL_STATUS);
210 + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STATUS);
215 @@ -610,6 +688,7 @@ static void emc2305_remove(struct i2c_cl
216 static struct i2c_driver emc2305_driver = {
219 + .of_match_table = emc2305_dt_ids,
221 .probe = emc2305_probe,
222 .remove = emc2305_remove,