453b052824efd4ab5d473234825388ecdc43ce21
[openwrt/staging/stintel.git] /
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
5
6 The driver had a number of issues, checkpatch warnings/errors,
7 and other limitations, so fix these up to make it usable.
8
9 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
11
12 hwmon: emc2305: Add calls to initialise of cooling maps
13
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.
18
19 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
20
21 hwmon: emc2305: Change OF properties pwm-min & pwm-max to u8
22
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.
28
29 The 6.1 driver was reading as u32, which failed as there is
30 insufficient data.
31
32 As this is all downstream only, revert to u8 to match 5.15.
33
34 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
35 ---
36 drivers/hwmon/emc2305.c | 95 +++++++++++++++++++++++++++++++++++++----
37 1 file changed, 87 insertions(+), 8 deletions(-)
38
39 --- a/drivers/hwmon/emc2305.c
40 +++ b/drivers/hwmon/emc2305.c
41 @@ -12,12 +12,13 @@
42 #include <linux/platform_data/emc2305.h>
43 #include <linux/thermal.h>
44
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
56 @@ -36,6 +37,7 @@
57 #define EMC2305_RPM_FACTOR 3932160
58
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))
63
64 @@ -55,6 +57,15 @@ static const struct i2c_device_id emc230
65 };
66 MODULE_DEVICE_TABLE(i2c, emc2305_ids);
67
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" },
73 + { }
74 +};
75 +MODULE_DEVICE_TABLE(of, emc2305_dt_ids);
76 +
77 /**
78 * struct emc2305_cdev_data - device-specific cooling device state
79 * @cdev: cooling device
80 @@ -100,6 +111,7 @@ struct emc2305_data {
81 u8 pwm_num;
82 bool pwm_separate;
83 u8 pwm_min[EMC2305_PWM_MAX];
84 + u8 pwm_max;
85 struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
86 };
87
88 @@ -272,7 +284,7 @@ static int emc2305_set_pwm(struct device
89 struct i2c_client *client = data->client;
90 int ret;
91
92 - if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
93 + if (val < data->pwm_min[channel] || val > data->pwm_max)
94 return -EINVAL;
95
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
98 return 0;
99 }
100
101 +static int emc2305_get_tz_of(struct device *dev)
102 +{
103 + struct device_node *np = dev->of_node;
104 + struct emc2305_data *data = dev_get_drvdata(dev);
105 + int ret = 0;
106 + u8 val;
107 + int i;
108 +
109 + /* OF parameters are optional - overwrite default setting
110 + * if some of them are provided.
111 + */
112 +
113 + ret = of_property_read_u8(np, "emc2305,cooling-levels", &val);
114 + if (!ret)
115 + data->max_state = val;
116 + else if (ret != -EINVAL)
117 + return ret;
118 +
119 + ret = of_property_read_u8(np, "emc2305,pwm-max", &val);
120 + if (!ret)
121 + data->pwm_max = val;
122 + else if (ret != -EINVAL)
123 + return ret;
124 +
125 + ret = of_property_read_u8(np, "emc2305,pwm-min", &val);
126 + if (!ret)
127 + for (i = 0; i < EMC2305_PWM_MAX; i++)
128 + data->pwm_min[i] = val;
129 + else if (ret != -EINVAL)
130 + return ret;
131 +
132 + /* Not defined or 0 means one thermal zone over all cooling devices.
133 + * Otherwise - separated thermal zones for each PWM channel.
134 + */
135 + ret = of_property_read_u8(np, "emc2305,pwm-channel", &val);
136 + if (!ret)
137 + data->pwm_separate = (val != 0);
138 + else if (ret != -EINVAL)
139 + return ret;
140 +
141 + return 0;
142 +}
143 +
144 static int emc2305_set_single_tz(struct device *dev, int idx)
145 {
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];
150
151 - data->cdev_data[cdev_idx].cdev =
152 - thermal_cooling_device_register(emc2305_fan_name[idx], data,
153 - &emc2305_cooling_ops);
154 + if (dev->of_node)
155 + data->cdev_data[cdev_idx].cdev =
156 + devm_thermal_of_cooling_device_register(dev, dev->of_node,
157 + emc2305_fan_name[idx],
158 + data,
159 + &emc2305_cooling_ops);
160 + else
161 + data->cdev_data[cdev_idx].cdev =
162 + thermal_cooling_device_register(emc2305_fan_name[idx],
163 + data,
164 + &emc2305_cooling_ops);
165
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
169 int i;
170
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);
179 + }
180 }
181
182 static umode_t
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;
188 } else {
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);
196 + if (ret < 0)
197 + return ret;
198 + }
199 }
200
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
203 return ret;
204 }
205
206 + /* Acknowledge any existing faults. Stops the device responding on the
207 + * SMBus alert address.
208 + */
209 + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STALL_STATUS);
210 + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STATUS);
211 +
212 return 0;
213 }
214
215 @@ -610,6 +688,7 @@ static void emc2305_remove(struct i2c_cl
216 static struct i2c_driver emc2305_driver = {
217 .driver = {
218 .name = "emc2305",
219 + .of_match_table = emc2305_dt_ids,
220 },
221 .probe = emc2305_probe,
222 .remove = emc2305_remove,