358500854360a21a59816ab5973d11f55f67c3ae
[openwrt/staging/linusw.git] /
1 From 403d49f64c1eed20d19e8b87669b30382be6e006 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 0371/1085] hwmon: emc2305: fixups for driver submitted to
5 mailing lists
6
7 The driver had a number of issues, checkpatch warnings/errors,
8 and other limitations, so fix these up to make it usable.
9
10 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
11 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
12
13 hwmon: emc2305: Add calls to initialise of cooling maps
14
15 Commit 46ef9d4ed26b ("hwmon: emc2305: fixups for driver submitted to
16 mailing lists") missed adding the call to thermal_of_cooling_device_register
17 required to configure any cooling maps for the device, hence stopping it
18 from actually ever changing speed.
19
20 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
21
22 hwmon: emc2305: Change OF properties pwm-min & pwm-max to u8
23
24 There is no DT binding for emc2305 as mainline are still
25 discussing how to do a generic fan binding.
26 The 5.15 driver was reading the "emc2305," properties
27 "cooling-levels", "pwm-max", "pwm-min", and "pwm-channel" as u8.
28 The overlay was writing them as u16 (;) so it was working.
29
30 The 6.1 driver was reading as u32, which failed as there is
31 insufficient data.
32
33 As this is all downstream only, revert to u8 to match 5.15.
34
35 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
36 ---
37 drivers/hwmon/emc2305.c | 95 +++++++++++++++++++++++++++++++++++++----
38 1 file changed, 87 insertions(+), 8 deletions(-)
39
40 --- a/drivers/hwmon/emc2305.c
41 +++ b/drivers/hwmon/emc2305.c
42 @@ -15,12 +15,13 @@
43 static const unsigned short
44 emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_END };
45
46 +#define EMC2305_REG_FAN_STATUS 0x24
47 +#define EMC2305_REG_FAN_STALL_STATUS 0x25
48 #define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
49 #define EMC2305_REG_VENDOR 0xfe
50 #define EMC2305_FAN_MAX 0xff
51 #define EMC2305_FAN_MIN 0x00
52 #define EMC2305_FAN_MAX_STATE 10
53 -#define EMC2305_DEVICE 0x34
54 #define EMC2305_VENDOR 0x5d
55 #define EMC2305_REG_PRODUCT_ID 0xfd
56 #define EMC2305_TACH_REGS_UNUSE_BITS 3
57 @@ -39,6 +40,7 @@ emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2
58 #define EMC2305_RPM_FACTOR 3932160
59
60 #define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n))
61 +#define EMC2305_REG_FAN_CFG(n) (0x32 + 0x10 * (n))
62 #define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n))
63 #define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n))
64
65 @@ -58,6 +60,15 @@ static const struct i2c_device_id emc230
66 };
67 MODULE_DEVICE_TABLE(i2c, emc2305_ids);
68
69 +static const struct of_device_id emc2305_dt_ids[] = {
70 + { .compatible = "microchip,emc2305" },
71 + { .compatible = "microchip,emc2303" },
72 + { .compatible = "microchip,emc2302" },
73 + { .compatible = "microchip,emc2301" },
74 + { }
75 +};
76 +MODULE_DEVICE_TABLE(of, emc2305_dt_ids);
77 +
78 /**
79 * struct emc2305_cdev_data - device-specific cooling device state
80 * @cdev: cooling device
81 @@ -103,6 +114,7 @@ struct emc2305_data {
82 u8 pwm_num;
83 bool pwm_separate;
84 u8 pwm_min[EMC2305_PWM_MAX];
85 + u8 pwm_max;
86 struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
87 };
88
89 @@ -275,7 +287,7 @@ static int emc2305_set_pwm(struct device
90 struct i2c_client *client = data->client;
91 int ret;
92
93 - if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
94 + if (val < data->pwm_min[channel] || val > data->pwm_max)
95 return -EINVAL;
96
97 ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
98 @@ -286,6 +298,49 @@ static int emc2305_set_pwm(struct device
99 return 0;
100 }
101
102 +static int emc2305_get_tz_of(struct device *dev)
103 +{
104 + struct device_node *np = dev->of_node;
105 + struct emc2305_data *data = dev_get_drvdata(dev);
106 + int ret = 0;
107 + u8 val;
108 + int i;
109 +
110 + /* OF parameters are optional - overwrite default setting
111 + * if some of them are provided.
112 + */
113 +
114 + ret = of_property_read_u8(np, "emc2305,cooling-levels", &val);
115 + if (!ret)
116 + data->max_state = val;
117 + else if (ret != -EINVAL)
118 + return ret;
119 +
120 + ret = of_property_read_u8(np, "emc2305,pwm-max", &val);
121 + if (!ret)
122 + data->pwm_max = val;
123 + else if (ret != -EINVAL)
124 + return ret;
125 +
126 + ret = of_property_read_u8(np, "emc2305,pwm-min", &val);
127 + if (!ret)
128 + for (i = 0; i < EMC2305_PWM_MAX; i++)
129 + data->pwm_min[i] = val;
130 + else if (ret != -EINVAL)
131 + return ret;
132 +
133 + /* Not defined or 0 means one thermal zone over all cooling devices.
134 + * Otherwise - separated thermal zones for each PWM channel.
135 + */
136 + ret = of_property_read_u8(np, "emc2305,pwm-channel", &val);
137 + if (!ret)
138 + data->pwm_separate = (val != 0);
139 + else if (ret != -EINVAL)
140 + return ret;
141 +
142 + return 0;
143 +}
144 +
145 static int emc2305_set_single_tz(struct device *dev, int idx)
146 {
147 struct emc2305_data *data = dev_get_drvdata(dev);
148 @@ -295,9 +350,17 @@ static int emc2305_set_single_tz(struct
149 cdev_idx = (idx) ? idx - 1 : 0;
150 pwm = data->pwm_min[cdev_idx];
151
152 - data->cdev_data[cdev_idx].cdev =
153 - thermal_cooling_device_register(emc2305_fan_name[idx], data,
154 - &emc2305_cooling_ops);
155 + if (dev->of_node)
156 + data->cdev_data[cdev_idx].cdev =
157 + devm_thermal_of_cooling_device_register(dev, dev->of_node,
158 + emc2305_fan_name[idx],
159 + data,
160 + &emc2305_cooling_ops);
161 + else
162 + data->cdev_data[cdev_idx].cdev =
163 + thermal_cooling_device_register(emc2305_fan_name[idx],
164 + data,
165 + &emc2305_cooling_ops);
166
167 if (IS_ERR(data->cdev_data[cdev_idx].cdev)) {
168 dev_err(dev, "Failed to register cooling device %s\n", emc2305_fan_name[idx]);
169 @@ -350,9 +413,11 @@ static void emc2305_unset_tz(struct devi
170 int i;
171
172 /* Unregister cooling device. */
173 - for (i = 0; i < EMC2305_PWM_MAX; i++)
174 - if (data->cdev_data[i].cdev)
175 - thermal_cooling_device_unregister(data->cdev_data[i].cdev);
176 + if (!dev->of_node) {
177 + for (i = 0; i < EMC2305_PWM_MAX; i++)
178 + if (data->cdev_data[i].cdev)
179 + thermal_cooling_device_unregister(data->cdev_data[i].cdev);
180 + }
181 }
182
183 static umode_t
184 @@ -574,11 +639,18 @@ static int emc2305_probe(struct i2c_clie
185 data->pwm_separate = pdata->pwm_separate;
186 for (i = 0; i < EMC2305_PWM_MAX; i++)
187 data->pwm_min[i] = pdata->pwm_min[i];
188 + data->pwm_max = EMC2305_FAN_MAX;
189 } else {
190 data->max_state = EMC2305_FAN_MAX_STATE;
191 data->pwm_separate = false;
192 for (i = 0; i < EMC2305_PWM_MAX; i++)
193 data->pwm_min[i] = EMC2305_FAN_MIN;
194 + data->pwm_max = EMC2305_FAN_MAX;
195 + if (dev->of_node) {
196 + ret = emc2305_get_tz_of(dev);
197 + if (ret < 0)
198 + return ret;
199 + }
200 }
201
202 data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data,
203 @@ -599,6 +671,12 @@ static int emc2305_probe(struct i2c_clie
204 return ret;
205 }
206
207 + /* Acknowledge any existing faults. Stops the device responding on the
208 + * SMBus alert address.
209 + */
210 + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STALL_STATUS);
211 + i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STATUS);
212 +
213 return 0;
214 }
215
216 @@ -614,6 +692,7 @@ static struct i2c_driver emc2305_driver
217 .class = I2C_CLASS_HWMON,
218 .driver = {
219 .name = "emc2305",
220 + .of_match_table = emc2305_dt_ids,
221 },
222 .probe = emc2305_probe,
223 .remove = emc2305_remove,