]> Git Repo - J-linux.git/blob - drivers/net/pse-pd/pd692x0.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / pse-pd / pd692x0.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for the Microchip PD692X0 PoE PSE Controller driver (I2C bus)
4  *
5  * Copyright (c) 2023 Bootlin, Kory Maincent <[email protected]>
6  */
7
8 #include <linux/delay.h>
9 #include <linux/firmware.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/pse-pd/pse.h>
15
16 #define PD692X0_PSE_NAME "pd692x0_pse"
17
18 #define PD692X0_MAX_PIS 48
19 #define PD692X0_MAX_MANAGERS            12
20 #define PD692X0_MAX_MANAGER_PORTS       8
21 #define PD692X0_MAX_HW_PORTS    (PD692X0_MAX_MANAGERS * PD692X0_MAX_MANAGER_PORTS)
22
23 #define PD69200_BT_PROD_VER     24
24 #define PD69210_BT_PROD_VER     26
25 #define PD69220_BT_PROD_VER     29
26
27 #define PD692X0_FW_MAJ_VER      3
28 #define PD692X0_FW_MIN_VER      5
29 #define PD692X0_FW_PATCH_VER    5
30
31 enum pd692x0_fw_state {
32         PD692X0_FW_UNKNOWN,
33         PD692X0_FW_OK,
34         PD692X0_FW_BROKEN,
35         PD692X0_FW_NEED_UPDATE,
36         PD692X0_FW_PREPARE,
37         PD692X0_FW_WRITE,
38         PD692X0_FW_COMPLETE,
39 };
40
41 struct pd692x0_msg {
42         u8 key;
43         u8 echo;
44         u8 sub[3];
45         u8 data[8];
46         __be16 chksum;
47 } __packed;
48
49 struct pd692x0_msg_ver {
50         u8 prod;
51         u8 maj_sw_ver;
52         u8 min_sw_ver;
53         u8 pa_sw_ver;
54         u8 param;
55         u8 build;
56 };
57
58 enum {
59         PD692X0_KEY_CMD,
60         PD692X0_KEY_PRG,
61         PD692X0_KEY_REQ,
62         PD692X0_KEY_TLM,
63         PD692X0_KEY_TEST,
64         PD692X0_KEY_REPORT = 0x52
65 };
66
67 enum {
68         PD692X0_MSG_RESET,
69         PD692X0_MSG_GET_SYS_STATUS,
70         PD692X0_MSG_GET_SW_VER,
71         PD692X0_MSG_SET_TMP_PORT_MATRIX,
72         PD692X0_MSG_PRG_PORT_MATRIX,
73         PD692X0_MSG_SET_PORT_PARAM,
74         PD692X0_MSG_GET_PORT_STATUS,
75         PD692X0_MSG_DOWNLOAD_CMD,
76         PD692X0_MSG_GET_PORT_CLASS,
77         PD692X0_MSG_GET_PORT_MEAS,
78         PD692X0_MSG_GET_PORT_PARAM,
79
80         /* add new message above here */
81         PD692X0_MSG_CNT
82 };
83
84 struct pd692x0_priv {
85         struct i2c_client *client;
86         struct pse_controller_dev pcdev;
87         struct device_node *np;
88
89         enum pd692x0_fw_state fw_state;
90         struct fw_upload *fwl;
91         bool cancel_request;
92
93         u8 msg_id;
94         bool last_cmd_key;
95         unsigned long last_cmd_key_time;
96
97         enum ethtool_c33_pse_admin_state admin_state[PD692X0_MAX_PIS];
98 };
99
100 /* Template list of communication messages. The non-null bytes defined here
101  * constitute the fixed portion of the messages. The remaining bytes will
102  * be configured later within the functions. Refer to the "PD692x0 BT Serial
103  * Communication Protocol User Guide" for comprehensive details on messages
104  * content.
105  */
106 static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
107         [PD692X0_MSG_RESET] = {
108                 .key = PD692X0_KEY_CMD,
109                 .sub = {0x07, 0x55, 0x00},
110                 .data = {0x55, 0x00, 0x55, 0x4e,
111                          0x4e, 0x4e, 0x4e, 0x4e},
112         },
113         [PD692X0_MSG_GET_SYS_STATUS] = {
114                 .key = PD692X0_KEY_REQ,
115                 .sub = {0x07, 0xd0, 0x4e},
116                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
117                          0x4e, 0x4e, 0x4e, 0x4e},
118         },
119         [PD692X0_MSG_GET_SW_VER] = {
120                 .key = PD692X0_KEY_REQ,
121                 .sub = {0x07, 0x1e, 0x21},
122                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
123                          0x4e, 0x4e, 0x4e, 0x4e},
124         },
125         [PD692X0_MSG_SET_TMP_PORT_MATRIX] = {
126                 .key = PD692X0_KEY_CMD,
127                 .sub     = {0x05, 0x43},
128                 .data = {   0, 0x4e, 0x4e, 0x4e,
129                          0x4e, 0x4e, 0x4e, 0x4e},
130         },
131         [PD692X0_MSG_PRG_PORT_MATRIX] = {
132                 .key = PD692X0_KEY_CMD,
133                 .sub = {0x07, 0x43, 0x4e},
134                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
135                          0x4e, 0x4e, 0x4e, 0x4e},
136         },
137         [PD692X0_MSG_SET_PORT_PARAM] = {
138                 .key = PD692X0_KEY_CMD,
139                 .sub = {0x05, 0xc0},
140                 .data = { 0xf, 0xff, 0xff, 0xff,
141                          0x4e, 0x4e, 0x4e, 0x4e},
142         },
143         [PD692X0_MSG_GET_PORT_STATUS] = {
144                 .key = PD692X0_KEY_REQ,
145                 .sub = {0x05, 0xc1},
146                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
147                          0x4e, 0x4e, 0x4e, 0x4e},
148         },
149         [PD692X0_MSG_DOWNLOAD_CMD] = {
150                 .key = PD692X0_KEY_PRG,
151                 .sub = {0xff, 0x99, 0x15},
152                 .data = {0x16, 0x16, 0x99, 0x4e,
153                          0x4e, 0x4e, 0x4e, 0x4e},
154         },
155         [PD692X0_MSG_GET_PORT_CLASS] = {
156                 .key = PD692X0_KEY_REQ,
157                 .sub = {0x05, 0xc4},
158                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
159                          0x4e, 0x4e, 0x4e, 0x4e},
160         },
161         [PD692X0_MSG_GET_PORT_MEAS] = {
162                 .key = PD692X0_KEY_REQ,
163                 .sub = {0x05, 0xc5},
164                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
165                          0x4e, 0x4e, 0x4e, 0x4e},
166         },
167         [PD692X0_MSG_GET_PORT_PARAM] = {
168                 .key = PD692X0_KEY_REQ,
169                 .sub = {0x05, 0xc0},
170                 .data = {0x4e, 0x4e, 0x4e, 0x4e,
171                          0x4e, 0x4e, 0x4e, 0x4e},
172         },
173 };
174
175 static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
176 {
177         u8 *data = (u8 *)msg;
178         u16 chksum = 0;
179         int i;
180
181         msg->echo = echo++;
182         if (echo == 0xff)
183                 echo = 0;
184
185         for (i = 0; i < sizeof(*msg) - sizeof(msg->chksum); i++)
186                 chksum += data[i];
187
188         msg->chksum = cpu_to_be16(chksum);
189
190         return echo;
191 }
192
193 static int pd692x0_send_msg(struct pd692x0_priv *priv, struct pd692x0_msg *msg)
194 {
195         const struct i2c_client *client = priv->client;
196         int ret;
197
198         if (msg->key == PD692X0_KEY_CMD && priv->last_cmd_key) {
199                 int cmd_msleep;
200
201                 cmd_msleep = 30 - jiffies_to_msecs(jiffies - priv->last_cmd_key_time);
202                 if (cmd_msleep > 0)
203                         msleep(cmd_msleep);
204         }
205
206         /* Add echo and checksum bytes to the message */
207         priv->msg_id = pd692x0_build_msg(msg, priv->msg_id);
208
209         ret = i2c_master_send(client, (u8 *)msg, sizeof(*msg));
210         if (ret != sizeof(*msg))
211                 return -EIO;
212
213         return 0;
214 }
215
216 static int pd692x0_reset(struct pd692x0_priv *priv)
217 {
218         const struct i2c_client *client = priv->client;
219         struct pd692x0_msg msg, buf = {0};
220         int ret;
221
222         msg = pd692x0_msg_template_list[PD692X0_MSG_RESET];
223         ret = pd692x0_send_msg(priv, &msg);
224         if (ret) {
225                 dev_err(&client->dev,
226                         "Failed to reset the controller (%pe)\n", ERR_PTR(ret));
227                 return ret;
228         }
229
230         msleep(30);
231
232         ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
233         if (ret != sizeof(buf))
234                 return ret < 0 ? ret : -EIO;
235
236         /* Is the reply a successful report message */
237         if (buf.key != PD692X0_KEY_REPORT || buf.sub[0] || buf.sub[1])
238                 return -EIO;
239
240         msleep(300);
241
242         ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
243         if (ret != sizeof(buf))
244                 return ret < 0 ? ret : -EIO;
245
246         /* Is the boot status without error */
247         if (buf.key != 0x03 || buf.echo != 0xff || buf.sub[0] & 0x1) {
248                 dev_err(&client->dev, "PSE controller error\n");
249                 return -EIO;
250         }
251
252         return 0;
253 }
254
255 static bool pd692x0_try_recv_msg(const struct i2c_client *client,
256                                  struct pd692x0_msg *msg,
257                                  struct pd692x0_msg *buf)
258 {
259         /* Wait 30ms before readback as mandated by the protocol */
260         msleep(30);
261
262         memset(buf, 0, sizeof(*buf));
263         i2c_master_recv(client, (u8 *)buf, sizeof(*buf));
264         if (buf->key)
265                 return 0;
266
267         msleep(100);
268
269         memset(buf, 0, sizeof(*buf));
270         i2c_master_recv(client, (u8 *)buf, sizeof(*buf));
271         if (buf->key)
272                 return 0;
273
274         return 1;
275 }
276
277 /* Implementation of I2C communication, specifically addressing scenarios
278  * involving communication loss. Refer to the "Synchronization During
279  * Communication Loss" section in the Communication Protocol document for
280  * further details.
281  */
282 static int pd692x0_recv_msg(struct pd692x0_priv *priv,
283                             struct pd692x0_msg *msg,
284                             struct pd692x0_msg *buf)
285 {
286         const struct i2c_client *client = priv->client;
287         int ret;
288
289         ret = pd692x0_try_recv_msg(client, msg, buf);
290         if (!ret)
291                 goto out_success;
292
293         dev_warn(&client->dev,
294                  "Communication lost, rtnl is locked until communication is back!");
295
296         ret = pd692x0_send_msg(priv, msg);
297         if (ret)
298                 return ret;
299
300         ret = pd692x0_try_recv_msg(client, msg, buf);
301         if (!ret)
302                 goto out_success2;
303
304         msleep(10000);
305
306         ret = pd692x0_send_msg(priv, msg);
307         if (ret)
308                 return ret;
309
310         ret = pd692x0_try_recv_msg(client, msg, buf);
311         if (!ret)
312                 goto out_success2;
313
314         return pd692x0_reset(priv);
315
316 out_success2:
317         dev_warn(&client->dev, "Communication is back, rtnl is unlocked!");
318 out_success:
319         if (msg->key == PD692X0_KEY_CMD) {
320                 priv->last_cmd_key = true;
321                 priv->last_cmd_key_time = jiffies;
322         } else {
323                 priv->last_cmd_key = false;
324         }
325
326         return 0;
327 }
328
329 static int pd692x0_sendrecv_msg(struct pd692x0_priv *priv,
330                                 struct pd692x0_msg *msg,
331                                 struct pd692x0_msg *buf)
332 {
333         struct device *dev = &priv->client->dev;
334         int ret;
335
336         ret = pd692x0_send_msg(priv, msg);
337         if (ret)
338                 return ret;
339
340         ret = pd692x0_recv_msg(priv, msg, buf);
341         if (ret)
342                 return ret;
343
344         if (msg->echo != buf->echo) {
345                 dev_err(dev,
346                         "Wrong match in message ID, expect %d received %d.\n",
347                         msg->echo, buf->echo);
348                 return -EIO;
349         }
350
351         /* If the reply is a report message is it successful */
352         if (buf->key == PD692X0_KEY_REPORT &&
353             (buf->sub[0] || buf->sub[1])) {
354                 return -EIO;
355         }
356
357         return 0;
358 }
359
360 static struct pd692x0_priv *to_pd692x0_priv(struct pse_controller_dev *pcdev)
361 {
362         return container_of(pcdev, struct pd692x0_priv, pcdev);
363 }
364
365 static int pd692x0_fw_unavailable(struct pd692x0_priv *priv)
366 {
367         switch (priv->fw_state) {
368         case PD692X0_FW_OK:
369                 return 0;
370         case PD692X0_FW_PREPARE:
371         case PD692X0_FW_WRITE:
372         case PD692X0_FW_COMPLETE:
373                 dev_err(&priv->client->dev, "Firmware update in progress!\n");
374                 return -EBUSY;
375         case PD692X0_FW_BROKEN:
376         case PD692X0_FW_NEED_UPDATE:
377         default:
378                 dev_err(&priv->client->dev,
379                         "Firmware issue. Please update it!\n");
380                 return -EOPNOTSUPP;
381         }
382 }
383
384 static int pd692x0_pi_enable(struct pse_controller_dev *pcdev, int id)
385 {
386         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
387         struct pd692x0_msg msg, buf = {0};
388         int ret;
389
390         ret = pd692x0_fw_unavailable(priv);
391         if (ret)
392                 return ret;
393
394         if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED)
395                 return 0;
396
397         msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
398         msg.data[0] = 0x1;
399         msg.sub[2] = id;
400         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
401         if (ret < 0)
402                 return ret;
403
404         priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
405
406         return 0;
407 }
408
409 static int pd692x0_pi_disable(struct pse_controller_dev *pcdev, int id)
410 {
411         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
412         struct pd692x0_msg msg, buf = {0};
413         int ret;
414
415         ret = pd692x0_fw_unavailable(priv);
416         if (ret)
417                 return ret;
418
419         if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED)
420                 return 0;
421
422         msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
423         msg.data[0] = 0x0;
424         msg.sub[2] = id;
425         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
426         if (ret < 0)
427                 return ret;
428
429         priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
430
431         return 0;
432 }
433
434 static int pd692x0_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
435 {
436         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
437         struct pd692x0_msg msg, buf = {0};
438         int ret;
439
440         ret = pd692x0_fw_unavailable(priv);
441         if (ret)
442                 return ret;
443
444         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
445         msg.sub[2] = id;
446         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
447         if (ret < 0)
448                 return ret;
449
450         if (buf.sub[1]) {
451                 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
452                 return 1;
453         } else {
454                 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
455                 return 0;
456         }
457 }
458
459 struct pd692x0_pse_ext_state_mapping {
460         u32 status_code;
461         enum ethtool_c33_pse_ext_state pse_ext_state;
462         u32 pse_ext_substate;
463 };
464
465 static const struct pd692x0_pse_ext_state_mapping
466 pd692x0_pse_ext_state_map[] = {
467         {0x06, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
468                 ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE},
469         {0x07, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
470                 ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE},
471         {0x08, ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
472                 ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE},
473         {0x0C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
474                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT},
475         {0x11, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
476                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT},
477         {0x12, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
478                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT},
479         {0x1B, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
480                 ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS},
481         {0x1C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
482                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
483         {0x1E, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
484                 ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD},
485         {0x1F, ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED,
486                 ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD},
487         {0x20, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
488                 ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED},
489         {0x21, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
490                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT},
491         {0x22, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
492                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE},
493         {0x24, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
494                 ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION},
495         {0x25, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
496                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
497         {0x34, ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED,
498                 ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION},
499         {0x35, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
500                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP},
501         {0x36, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
502                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP},
503         {0x37, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
504                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
505         {0x3C, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
506                 ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET},
507         {0x3D, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
508                 ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT},
509         {0x41, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
510                 ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT},
511         {0x43, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
512                 ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
513         {0xA7, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
514                 ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR},
515         {0xA8, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
516                 ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN},
517         { /* sentinel */ }
518 };
519
520 static void
521 pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info,
522                       u32 status_code)
523 {
524         const struct pd692x0_pse_ext_state_mapping *ext_state_map;
525
526         ext_state_map = pd692x0_pse_ext_state_map;
527         while (ext_state_map->status_code) {
528                 if (ext_state_map->status_code == status_code) {
529                         c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state;
530                         c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate;
531                         return;
532                 }
533                 ext_state_map++;
534         }
535 }
536
537 struct pd692x0_class_pw {
538         int class;
539         int class_cfg_value;
540         int class_pw;
541         int max_added_class_pw;
542 };
543
544 #define PD692X0_CLASS_PW_TABLE_SIZE 4
545 /* 4/2 pairs class configuration power table in compliance mode.
546  * Need to be arranged in ascending order of power support.
547  */
548 static const struct pd692x0_class_pw
549 pd692x0_class_pw_table[PD692X0_CLASS_PW_TABLE_SIZE] = {
550         {.class = 3, .class_cfg_value = 0x3, .class_pw = 15000, .max_added_class_pw = 3100},
551         {.class = 4, .class_cfg_value = 0x2, .class_pw = 30000, .max_added_class_pw = 8000},
552         {.class = 6, .class_cfg_value = 0x1, .class_pw = 60000, .max_added_class_pw = 5000},
553         {.class = 8, .class_cfg_value = 0x0, .class_pw = 90000, .max_added_class_pw = 7500},
554 };
555
556 static int pd692x0_pi_get_pw_from_table(int op_mode, int added_pw)
557 {
558         const struct pd692x0_class_pw *pw_table;
559         int i;
560
561         pw_table = pd692x0_class_pw_table;
562         for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
563                 if (pw_table->class_cfg_value == op_mode)
564                         return pw_table->class_pw + added_pw * 100;
565         }
566
567         return -ERANGE;
568 }
569
570 static int pd692x0_pi_set_pw_from_table(struct device *dev,
571                                         struct pd692x0_msg *msg, int pw)
572 {
573         const struct pd692x0_class_pw *pw_table;
574         int i;
575
576         pw_table = pd692x0_class_pw_table;
577         if (pw < pw_table->class_pw) {
578                 dev_err(dev,
579                         "Power limit %dmW not supported. Ranges minimal available: [%d-%d]\n",
580                         pw,
581                         pw_table->class_pw,
582                         pw_table->class_pw + pw_table->max_added_class_pw);
583                 return -ERANGE;
584         }
585
586         for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
587                 if (pw > (pw_table->class_pw + pw_table->max_added_class_pw))
588                         continue;
589
590                 if (pw < pw_table->class_pw) {
591                         dev_err(dev,
592                                 "Power limit %dmW not supported. Ranges available: [%d-%d] or [%d-%d]\n",
593                                 pw,
594                                 (pw_table - 1)->class_pw,
595                                 (pw_table - 1)->class_pw + (pw_table - 1)->max_added_class_pw,
596                                 pw_table->class_pw,
597                                 pw_table->class_pw + pw_table->max_added_class_pw);
598                         return -ERANGE;
599                 }
600
601                 msg->data[2] = pw_table->class_cfg_value;
602                 msg->data[3] = (pw - pw_table->class_pw) / 100;
603                 return 0;
604         }
605
606         pw_table--;
607         dev_warn(dev,
608                  "Power limit %dmW not supported. Set to highest power limit %dmW\n",
609                  pw, pw_table->class_pw + pw_table->max_added_class_pw);
610         msg->data[2] = pw_table->class_cfg_value;
611         msg->data[3] = pw_table->max_added_class_pw / 100;
612         return 0;
613 }
614
615 static int
616 pd692x0_pi_get_pw_ranges(struct pse_control_status *st)
617 {
618         const struct pd692x0_class_pw *pw_table;
619         int i;
620
621         pw_table = pd692x0_class_pw_table;
622         st->c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
623                                           sizeof(struct ethtool_c33_pse_pw_limit_range),
624                                           GFP_KERNEL);
625         if (!st->c33_pw_limit_ranges)
626                 return -ENOMEM;
627
628         for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
629                 st->c33_pw_limit_ranges[i].min = pw_table->class_pw;
630                 st->c33_pw_limit_ranges[i].max = pw_table->class_pw + pw_table->max_added_class_pw;
631         }
632
633         st->c33_pw_limit_nb_ranges = i;
634         return 0;
635 }
636
637 static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
638                                       unsigned long id,
639                                       struct netlink_ext_ack *extack,
640                                       struct pse_control_status *status)
641 {
642         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
643         struct pd692x0_msg msg, buf = {0};
644         u32 class;
645         int ret;
646
647         ret = pd692x0_fw_unavailable(priv);
648         if (ret)
649                 return ret;
650
651         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
652         msg.sub[2] = id;
653         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
654         if (ret < 0)
655                 return ret;
656
657         /* Compare Port Status (Communication Protocol Document par. 7.1) */
658         if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90)
659                 status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
660         else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22)
661                 status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
662         else if (buf.sub[0] == 0x12)
663                 status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
664         else
665                 status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
666
667         if (buf.sub[1])
668                 status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
669         else
670                 status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
671
672         priv->admin_state[id] = status->c33_admin_state;
673
674         pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]);
675         status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100;
676
677         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
678         msg.sub[2] = id;
679         memset(&buf, 0, sizeof(buf));
680         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
681         if (ret < 0)
682                 return ret;
683
684         ret = pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
685         if (ret < 0)
686                 return ret;
687         status->c33_avail_pw_limit = ret;
688
689         memset(&buf, 0, sizeof(buf));
690         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
691         msg.sub[2] = id;
692         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
693         if (ret < 0)
694                 return ret;
695
696         class = buf.data[3] >> 4;
697         if (class <= 8)
698                 status->c33_pw_class = class;
699
700         ret = pd692x0_pi_get_pw_ranges(status);
701         if (ret < 0)
702                 return ret;
703
704         return 0;
705 }
706
707 static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv)
708 {
709         struct device *dev = &priv->client->dev;
710         struct pd692x0_msg msg, buf = {0};
711         struct pd692x0_msg_ver ver = {0};
712         int ret;
713
714         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SW_VER];
715         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
716         if (ret < 0) {
717                 dev_err(dev, "Failed to get PSE version (%pe)\n", ERR_PTR(ret));
718                 return ver;
719         }
720
721         /* Extract version from the message */
722         ver.prod = buf.sub[2];
723         ver.maj_sw_ver = (buf.data[0] << 8 | buf.data[1]) / 100;
724         ver.min_sw_ver = ((buf.data[0] << 8 | buf.data[1]) / 10) % 10;
725         ver.pa_sw_ver = (buf.data[0] << 8 | buf.data[1]) % 10;
726         ver.param = buf.data[2];
727         ver.build = buf.data[3];
728
729         return ver;
730 }
731
732 struct pd692x0_manager {
733         struct device_node *port_node[PD692X0_MAX_MANAGER_PORTS];
734         int nports;
735 };
736
737 struct pd692x0_matrix {
738         u8 hw_port_a;
739         u8 hw_port_b;
740 };
741
742 static int
743 pd692x0_of_get_ports_manager(struct pd692x0_priv *priv,
744                              struct pd692x0_manager *manager,
745                              struct device_node *np)
746 {
747         struct device_node *node;
748         int ret, nports, i;
749
750         nports = 0;
751         for_each_child_of_node(np, node) {
752                 u32 port;
753
754                 if (!of_node_name_eq(node, "port"))
755                         continue;
756
757                 ret = of_property_read_u32(node, "reg", &port);
758                 if (ret)
759                         goto out;
760
761                 if (port >= PD692X0_MAX_MANAGER_PORTS || port != nports) {
762                         dev_err(&priv->client->dev,
763                                 "wrong number or order of manager ports (%d)\n",
764                                 port);
765                         ret = -EINVAL;
766                         goto out;
767                 }
768
769                 of_node_get(node);
770                 manager->port_node[port] = node;
771                 nports++;
772         }
773
774         manager->nports = nports;
775         return 0;
776
777 out:
778         for (i = 0; i < nports; i++) {
779                 of_node_put(manager->port_node[i]);
780                 manager->port_node[i] = NULL;
781         }
782         of_node_put(node);
783         return ret;
784 }
785
786 static int
787 pd692x0_of_get_managers(struct pd692x0_priv *priv,
788                         struct pd692x0_manager manager[PD692X0_MAX_MANAGERS])
789 {
790         struct device_node *managers_node, *node;
791         int ret, nmanagers, i, j;
792
793         if (!priv->np)
794                 return -EINVAL;
795
796         nmanagers = 0;
797         managers_node = of_get_child_by_name(priv->np, "managers");
798         if (!managers_node)
799                 return -EINVAL;
800
801         for_each_child_of_node(managers_node, node) {
802                 u32 manager_id;
803
804                 if (!of_node_name_eq(node, "manager"))
805                         continue;
806
807                 ret = of_property_read_u32(node, "reg", &manager_id);
808                 if (ret)
809                         goto out;
810
811                 if (manager_id >= PD692X0_MAX_MANAGERS ||
812                     manager_id != nmanagers) {
813                         dev_err(&priv->client->dev,
814                                 "wrong number or order of managers (%d)\n",
815                                 manager_id);
816                         ret = -EINVAL;
817                         goto out;
818                 }
819
820                 ret = pd692x0_of_get_ports_manager(priv, &manager[manager_id],
821                                                    node);
822                 if (ret)
823                         goto out;
824
825                 nmanagers++;
826         }
827
828         of_node_put(managers_node);
829         return nmanagers;
830
831 out:
832         for (i = 0; i < nmanagers; i++) {
833                 for (j = 0; j < manager[i].nports; j++) {
834                         of_node_put(manager[i].port_node[j]);
835                         manager[i].port_node[j] = NULL;
836                 }
837         }
838
839         of_node_put(node);
840         of_node_put(managers_node);
841         return ret;
842 }
843
844 static int
845 pd692x0_set_port_matrix(const struct pse_pi_pairset *pairset,
846                         const struct pd692x0_manager *manager,
847                         int nmanagers, struct pd692x0_matrix *port_matrix)
848 {
849         int i, j, port_cnt;
850         bool found = false;
851
852         if (!pairset->np)
853                 return 0;
854
855         /* Look on every managers */
856         port_cnt = 0;
857         for (i = 0; i < nmanagers; i++) {
858                 /* Look on every ports of the manager */
859                 for (j = 0; j < manager[i].nports; j++) {
860                         if (pairset->np == manager[i].port_node[j]) {
861                                 found = true;
862                                 break;
863                         }
864                 }
865                 port_cnt += j;
866
867                 if (found)
868                         break;
869         }
870
871         if (!found)
872                 return -ENODEV;
873
874         if (pairset->pinout == ALTERNATIVE_A)
875                 port_matrix->hw_port_a = port_cnt;
876         else if (pairset->pinout == ALTERNATIVE_B)
877                 port_matrix->hw_port_b = port_cnt;
878
879         return 0;
880 }
881
882 static int
883 pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
884                          const struct pd692x0_manager *manager,
885                          int nmanagers,
886                          struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
887 {
888         struct pse_controller_dev *pcdev = &priv->pcdev;
889         int i, ret;
890
891         /* Init Matrix */
892         for (i = 0; i < PD692X0_MAX_PIS; i++) {
893                 port_matrix[i].hw_port_a = 0xff;
894                 port_matrix[i].hw_port_b = 0xff;
895         }
896
897         /* Update with values for every PSE PIs */
898         for (i = 0; i < pcdev->nr_lines; i++) {
899                 ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[0],
900                                               manager, nmanagers,
901                                               &port_matrix[i]);
902                 if (ret) {
903                         dev_err(&priv->client->dev,
904                                 "unable to configure pi %d pairset 0", i);
905                         return ret;
906                 }
907
908                 ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[1],
909                                               manager, nmanagers,
910                                               &port_matrix[i]);
911                 if (ret) {
912                         dev_err(&priv->client->dev,
913                                 "unable to configure pi %d pairset 1", i);
914                         return ret;
915                 }
916         }
917
918         return 0;
919 }
920
921 static int
922 pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
923                            const struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
924 {
925         struct pd692x0_msg msg, buf;
926         int ret, i;
927
928         /* Write temporary Matrix */
929         msg = pd692x0_msg_template_list[PD692X0_MSG_SET_TMP_PORT_MATRIX];
930         for (i = 0; i < PD692X0_MAX_PIS; i++) {
931                 msg.sub[2] = i;
932                 msg.data[0] = port_matrix[i].hw_port_b;
933                 msg.data[1] = port_matrix[i].hw_port_a;
934
935                 ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
936                 if (ret < 0)
937                         return ret;
938         }
939
940         /* Program Matrix */
941         msg = pd692x0_msg_template_list[PD692X0_MSG_PRG_PORT_MATRIX];
942         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
943         if (ret < 0)
944                 return ret;
945
946         return 0;
947 }
948
949 static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
950 {
951         struct pd692x0_manager manager[PD692X0_MAX_MANAGERS] = {0};
952         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
953         struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
954         int ret, i, j, nmanagers;
955
956         /* Should we flash the port matrix */
957         if (priv->fw_state != PD692X0_FW_OK &&
958             priv->fw_state != PD692X0_FW_COMPLETE)
959                 return 0;
960
961         ret = pd692x0_of_get_managers(priv, manager);
962         if (ret < 0)
963                 return ret;
964
965         nmanagers = ret;
966         ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
967         if (ret)
968                 goto out;
969
970         ret = pd692x0_write_ports_matrix(priv, port_matrix);
971         if (ret)
972                 goto out;
973
974 out:
975         for (i = 0; i < nmanagers; i++) {
976                 for (j = 0; j < manager[i].nports; j++)
977                         of_node_put(manager[i].port_node[j]);
978         }
979         return ret;
980 }
981
982 static int pd692x0_pi_get_voltage(struct pse_controller_dev *pcdev, int id)
983 {
984         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
985         struct pd692x0_msg msg, buf = {0};
986         int ret;
987
988         ret = pd692x0_fw_unavailable(priv);
989         if (ret)
990                 return ret;
991
992         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_MEAS];
993         msg.sub[2] = id;
994         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
995         if (ret < 0)
996                 return ret;
997
998         /* Convert 0.1V unit to uV */
999         return (buf.sub[0] << 8 | buf.sub[1]) * 100000;
1000 }
1001
1002 static int pd692x0_pi_get_current_limit(struct pse_controller_dev *pcdev,
1003                                         int id)
1004 {
1005         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
1006         struct pd692x0_msg msg, buf = {0};
1007         int mW, uV, uA, ret;
1008         s64 tmp_64;
1009
1010         msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
1011         msg.sub[2] = id;
1012         ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1013         if (ret < 0)
1014                 return ret;
1015
1016         ret = pd692x0_pi_get_pw_from_table(buf.data[2], buf.data[3]);
1017         if (ret < 0)
1018                 return ret;
1019         mW = ret;
1020
1021         ret = pd692x0_pi_get_voltage(pcdev, id);
1022         if (ret < 0)
1023                 return ret;
1024         uV = ret;
1025
1026         tmp_64 = mW;
1027         tmp_64 *= 1000000000ull;
1028         /* uA = mW * 1000000000 / uV */
1029         uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
1030         return uA;
1031 }
1032
1033 static int pd692x0_pi_set_current_limit(struct pse_controller_dev *pcdev,
1034                                         int id, int max_uA)
1035 {
1036         struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
1037         struct device *dev = &priv->client->dev;
1038         struct pd692x0_msg msg, buf = {0};
1039         int uV, ret, mW;
1040         s64 tmp_64;
1041
1042         ret = pd692x0_fw_unavailable(priv);
1043         if (ret)
1044                 return ret;
1045
1046         ret = pd692x0_pi_get_voltage(pcdev, id);
1047         if (ret < 0)
1048                 return ret;
1049         uV = ret;
1050
1051         msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
1052         msg.sub[2] = id;
1053         tmp_64 = uV;
1054         tmp_64 *= max_uA;
1055         /* mW = uV * uA / 1000000000 */
1056         mW = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
1057         ret = pd692x0_pi_set_pw_from_table(dev, &msg, mW);
1058         if (ret)
1059                 return ret;
1060
1061         return pd692x0_sendrecv_msg(priv, &msg, &buf);
1062 }
1063
1064 static const struct pse_controller_ops pd692x0_ops = {
1065         .setup_pi_matrix = pd692x0_setup_pi_matrix,
1066         .ethtool_get_status = pd692x0_ethtool_get_status,
1067         .pi_enable = pd692x0_pi_enable,
1068         .pi_disable = pd692x0_pi_disable,
1069         .pi_is_enabled = pd692x0_pi_is_enabled,
1070         .pi_get_voltage = pd692x0_pi_get_voltage,
1071         .pi_get_current_limit = pd692x0_pi_get_current_limit,
1072         .pi_set_current_limit = pd692x0_pi_set_current_limit,
1073 };
1074
1075 #define PD692X0_FW_LINE_MAX_SZ 0xff
1076 static int pd692x0_fw_get_next_line(const u8 *data,
1077                                     char *line, size_t size)
1078 {
1079         size_t line_size;
1080         int i;
1081
1082         line_size = min_t(size_t, size, PD692X0_FW_LINE_MAX_SZ);
1083
1084         memset(line, 0, PD692X0_FW_LINE_MAX_SZ);
1085         for (i = 0; i < line_size - 1; i++) {
1086                 if (*data == '\r' && *(data + 1) == '\n') {
1087                         line[i] = '\r';
1088                         line[i + 1] = '\n';
1089                         return i + 2;
1090                 }
1091                 line[i] = *data;
1092                 data++;
1093         }
1094
1095         return -EIO;
1096 }
1097
1098 static enum fw_upload_err
1099 pd692x0_fw_recv_resp(const struct i2c_client *client, unsigned long ms_timeout,
1100                      const char *msg_ok, unsigned int msg_size)
1101 {
1102         /* Maximum controller response size */
1103         char fw_msg_buf[5] = {0};
1104         unsigned long timeout;
1105         int ret;
1106
1107         if (msg_size > sizeof(fw_msg_buf))
1108                 return FW_UPLOAD_ERR_RW_ERROR;
1109
1110         /* Read until we get something */
1111         timeout = msecs_to_jiffies(ms_timeout) + jiffies;
1112         while (true) {
1113                 if (time_is_before_jiffies(timeout))
1114                         return FW_UPLOAD_ERR_TIMEOUT;
1115
1116                 ret = i2c_master_recv(client, fw_msg_buf, 1);
1117                 if (ret < 0 || *fw_msg_buf == 0) {
1118                         usleep_range(1000, 2000);
1119                         continue;
1120                 } else {
1121                         break;
1122                 }
1123         }
1124
1125         /* Read remaining characters */
1126         ret = i2c_master_recv(client, fw_msg_buf + 1, msg_size - 1);
1127         if (strncmp(fw_msg_buf, msg_ok, msg_size)) {
1128                 dev_err(&client->dev,
1129                         "Wrong FW download process answer (%*pE)\n",
1130                         msg_size, fw_msg_buf);
1131                 return FW_UPLOAD_ERR_HW_ERROR;
1132         }
1133
1134         return FW_UPLOAD_ERR_NONE;
1135 }
1136
1137 static int pd692x0_fw_write_line(const struct i2c_client *client,
1138                                  const char line[PD692X0_FW_LINE_MAX_SZ],
1139                                  const bool last_line)
1140 {
1141         int ret;
1142
1143         while (*line != 0) {
1144                 ret = i2c_master_send(client, line, 1);
1145                 if (ret < 0)
1146                         return FW_UPLOAD_ERR_RW_ERROR;
1147                 line++;
1148         }
1149
1150         if (last_line) {
1151                 ret = pd692x0_fw_recv_resp(client, 100, "TP\r\n",
1152                                            sizeof("TP\r\n") - 1);
1153                 if (ret)
1154                         return ret;
1155         } else {
1156                 ret = pd692x0_fw_recv_resp(client, 100, "T*\r\n",
1157                                            sizeof("T*\r\n") - 1);
1158                 if (ret)
1159                         return ret;
1160         }
1161
1162         return FW_UPLOAD_ERR_NONE;
1163 }
1164
1165 static enum fw_upload_err pd692x0_fw_reset(const struct i2c_client *client)
1166 {
1167         const struct pd692x0_msg zero = {0};
1168         struct pd692x0_msg buf = {0};
1169         unsigned long timeout;
1170         char cmd[] = "RST";
1171         int ret;
1172
1173         ret = i2c_master_send(client, cmd, strlen(cmd));
1174         if (ret < 0) {
1175                 dev_err(&client->dev,
1176                         "Failed to reset the controller (%pe)\n",
1177                         ERR_PTR(ret));
1178                 return ret;
1179         }
1180
1181         timeout = msecs_to_jiffies(10000) + jiffies;
1182         while (true) {
1183                 if (time_is_before_jiffies(timeout))
1184                         return FW_UPLOAD_ERR_TIMEOUT;
1185
1186                 ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
1187                 if (ret < 0 ||
1188                     !memcmp(&buf, &zero, sizeof(buf)))
1189                         usleep_range(1000, 2000);
1190                 else
1191                         break;
1192         }
1193
1194         /* Is the reply a successful report message */
1195         if (buf.key != PD692X0_KEY_TLM || buf.echo != 0xff ||
1196             buf.sub[0] & 0x01) {
1197                 dev_err(&client->dev, "PSE controller error\n");
1198                 return FW_UPLOAD_ERR_HW_ERROR;
1199         }
1200
1201         /* Is the firmware operational */
1202         if (buf.sub[0] & 0x02) {
1203                 dev_err(&client->dev,
1204                         "PSE firmware error. Please update it.\n");
1205                 return FW_UPLOAD_ERR_HW_ERROR;
1206         }
1207
1208         return FW_UPLOAD_ERR_NONE;
1209 }
1210
1211 static enum fw_upload_err pd692x0_fw_prepare(struct fw_upload *fwl,
1212                                              const u8 *data, u32 size)
1213 {
1214         struct pd692x0_priv *priv = fwl->dd_handle;
1215         const struct i2c_client *client = priv->client;
1216         enum pd692x0_fw_state last_fw_state;
1217         int ret;
1218
1219         priv->cancel_request = false;
1220         last_fw_state = priv->fw_state;
1221
1222         priv->fw_state = PD692X0_FW_PREPARE;
1223
1224         /* Enter program mode */
1225         if (last_fw_state == PD692X0_FW_BROKEN) {
1226                 const char *msg = "ENTR";
1227                 const char *c;
1228
1229                 c = msg;
1230                 do {
1231                         ret = i2c_master_send(client, c, 1);
1232                         if (ret < 0)
1233                                 return FW_UPLOAD_ERR_RW_ERROR;
1234                         if (*(c + 1))
1235                                 usleep_range(10000, 20000);
1236                 } while (*(++c));
1237         } else {
1238                 struct pd692x0_msg msg, buf;
1239
1240                 msg = pd692x0_msg_template_list[PD692X0_MSG_DOWNLOAD_CMD];
1241                 ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1242                 if (ret < 0) {
1243                         dev_err(&client->dev,
1244                                 "Failed to enter programming mode (%pe)\n",
1245                                 ERR_PTR(ret));
1246                         return FW_UPLOAD_ERR_RW_ERROR;
1247                 }
1248         }
1249
1250         ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1251         if (ret)
1252                 goto err_out;
1253
1254         if (priv->cancel_request) {
1255                 ret = FW_UPLOAD_ERR_CANCELED;
1256                 goto err_out;
1257         }
1258
1259         return FW_UPLOAD_ERR_NONE;
1260
1261 err_out:
1262         pd692x0_fw_reset(priv->client);
1263         priv->fw_state = last_fw_state;
1264         return ret;
1265 }
1266
1267 static enum fw_upload_err pd692x0_fw_write(struct fw_upload *fwl,
1268                                            const u8 *data, u32 offset,
1269                                            u32 size, u32 *written)
1270 {
1271         struct pd692x0_priv *priv = fwl->dd_handle;
1272         char line[PD692X0_FW_LINE_MAX_SZ];
1273         const struct i2c_client *client;
1274         int ret, i;
1275         char cmd;
1276
1277         client = priv->client;
1278         priv->fw_state = PD692X0_FW_WRITE;
1279
1280         /* Erase */
1281         cmd = 'E';
1282         ret = i2c_master_send(client, &cmd, 1);
1283         if (ret < 0) {
1284                 dev_err(&client->dev,
1285                         "Failed to boot programming mode (%pe)\n",
1286                         ERR_PTR(ret));
1287                 return FW_UPLOAD_ERR_RW_ERROR;
1288         }
1289
1290         ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1);
1291         if (ret)
1292                 return ret;
1293
1294         ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1);
1295         if (ret)
1296                 dev_warn(&client->dev,
1297                          "Failed to erase internal memory, however still try to write Firmware\n");
1298
1299         ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1300         if (ret)
1301                 dev_warn(&client->dev,
1302                          "Failed to erase internal memory, however still try to write Firmware\n");
1303
1304         if (priv->cancel_request)
1305                 return FW_UPLOAD_ERR_CANCELED;
1306
1307         /* Program */
1308         cmd = 'P';
1309         ret = i2c_master_send(client, &cmd, sizeof(char));
1310         if (ret < 0) {
1311                 dev_err(&client->dev,
1312                         "Failed to boot programming mode (%pe)\n",
1313                         ERR_PTR(ret));
1314                 return ret;
1315         }
1316
1317         ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1);
1318         if (ret)
1319                 return ret;
1320
1321         i = 0;
1322         while (i < size) {
1323                 ret = pd692x0_fw_get_next_line(data, line, size - i);
1324                 if (ret < 0) {
1325                         ret = FW_UPLOAD_ERR_FW_INVALID;
1326                         goto err;
1327                 }
1328
1329                 i += ret;
1330                 data += ret;
1331                 if (line[0] == 'S' && line[1] == '0') {
1332                         continue;
1333                 } else if (line[0] == 'S' && line[1] == '7') {
1334                         ret = pd692x0_fw_write_line(client, line, true);
1335                         if (ret)
1336                                 goto err;
1337                 } else {
1338                         ret = pd692x0_fw_write_line(client, line, false);
1339                         if (ret)
1340                                 goto err;
1341                 }
1342
1343                 if (priv->cancel_request) {
1344                         ret = FW_UPLOAD_ERR_CANCELED;
1345                         goto err;
1346                 }
1347         }
1348         *written = i;
1349
1350         msleep(400);
1351
1352         return FW_UPLOAD_ERR_NONE;
1353
1354 err:
1355         strscpy_pad(line, "S7\r\n", sizeof(line));
1356         pd692x0_fw_write_line(client, line, true);
1357         return ret;
1358 }
1359
1360 static enum fw_upload_err pd692x0_fw_poll_complete(struct fw_upload *fwl)
1361 {
1362         struct pd692x0_priv *priv = fwl->dd_handle;
1363         const struct i2c_client *client = priv->client;
1364         struct pd692x0_msg_ver ver;
1365         int ret;
1366
1367         priv->fw_state = PD692X0_FW_COMPLETE;
1368
1369         ret = pd692x0_fw_reset(client);
1370         if (ret)
1371                 return ret;
1372
1373         ver = pd692x0_get_sw_version(priv);
1374         if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {
1375                 dev_err(&client->dev,
1376                         "Too old firmware version. Please update it\n");
1377                 priv->fw_state = PD692X0_FW_NEED_UPDATE;
1378                 return FW_UPLOAD_ERR_FW_INVALID;
1379         }
1380
1381         ret = pd692x0_setup_pi_matrix(&priv->pcdev);
1382         if (ret < 0) {
1383                 dev_err(&client->dev, "Error configuring ports matrix (%pe)\n",
1384                         ERR_PTR(ret));
1385                 priv->fw_state = PD692X0_FW_NEED_UPDATE;
1386                 return FW_UPLOAD_ERR_HW_ERROR;
1387         }
1388
1389         priv->fw_state = PD692X0_FW_OK;
1390         return FW_UPLOAD_ERR_NONE;
1391 }
1392
1393 static void pd692x0_fw_cancel(struct fw_upload *fwl)
1394 {
1395         struct pd692x0_priv *priv = fwl->dd_handle;
1396
1397         priv->cancel_request = true;
1398 }
1399
1400 static void pd692x0_fw_cleanup(struct fw_upload *fwl)
1401 {
1402         struct pd692x0_priv *priv = fwl->dd_handle;
1403
1404         switch (priv->fw_state) {
1405         case PD692X0_FW_WRITE:
1406                 pd692x0_fw_reset(priv->client);
1407                 fallthrough;
1408         case PD692X0_FW_COMPLETE:
1409                 priv->fw_state = PD692X0_FW_BROKEN;
1410                 break;
1411         default:
1412                 break;
1413         }
1414 }
1415
1416 static const struct fw_upload_ops pd692x0_fw_ops = {
1417         .prepare = pd692x0_fw_prepare,
1418         .write = pd692x0_fw_write,
1419         .poll_complete = pd692x0_fw_poll_complete,
1420         .cancel = pd692x0_fw_cancel,
1421         .cleanup = pd692x0_fw_cleanup,
1422 };
1423
1424 static int pd692x0_i2c_probe(struct i2c_client *client)
1425 {
1426         struct pd692x0_msg msg, buf = {0}, zero = {0};
1427         struct device *dev = &client->dev;
1428         struct pd692x0_msg_ver ver;
1429         struct pd692x0_priv *priv;
1430         struct fw_upload *fwl;
1431         int ret;
1432
1433         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1434                 dev_err(dev, "i2c check functionality failed\n");
1435                 return -ENXIO;
1436         }
1437
1438         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1439         if (!priv)
1440                 return -ENOMEM;
1441
1442         priv->client = client;
1443         i2c_set_clientdata(client, priv);
1444
1445         ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
1446         if (ret != sizeof(buf)) {
1447                 dev_err(dev, "Failed to get device status\n");
1448                 return -EIO;
1449         }
1450
1451         /* Probe has been already run and the status dumped */
1452         if (!memcmp(&buf, &zero, sizeof(buf))) {
1453                 /* Ask again the controller status */
1454                 msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SYS_STATUS];
1455                 ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1456                 if (ret < 0) {
1457                         dev_err(dev, "Failed to get device status\n");
1458                         return ret;
1459                 }
1460         }
1461
1462         if (buf.key != 0x03 || buf.sub[0] & 0x01) {
1463                 dev_err(dev, "PSE controller error\n");
1464                 return -EIO;
1465         }
1466         if (buf.sub[0] & 0x02) {
1467                 dev_err(dev, "PSE firmware error. Please update it.\n");
1468                 priv->fw_state = PD692X0_FW_BROKEN;
1469         } else {
1470                 ver = pd692x0_get_sw_version(priv);
1471                 dev_info(&client->dev, "Software version %d.%02d.%d.%d\n",
1472                          ver.prod, ver.maj_sw_ver, ver.min_sw_ver,
1473                          ver.pa_sw_ver);
1474
1475                 if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {
1476                         dev_err(dev, "Too old firmware version. Please update it\n");
1477                         priv->fw_state = PD692X0_FW_NEED_UPDATE;
1478                 } else {
1479                         priv->fw_state = PD692X0_FW_OK;
1480                 }
1481         }
1482
1483         priv->np = dev->of_node;
1484         priv->pcdev.nr_lines = PD692X0_MAX_PIS;
1485         priv->pcdev.owner = THIS_MODULE;
1486         priv->pcdev.ops = &pd692x0_ops;
1487         priv->pcdev.dev = dev;
1488         priv->pcdev.types = ETHTOOL_PSE_C33;
1489         ret = devm_pse_controller_register(dev, &priv->pcdev);
1490         if (ret)
1491                 return dev_err_probe(dev, ret,
1492                                      "failed to register PSE controller\n");
1493
1494         fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),
1495                                        &pd692x0_fw_ops, priv);
1496         if (IS_ERR(fwl))
1497                 return dev_err_probe(dev, PTR_ERR(fwl),
1498                                      "failed to register to the Firmware Upload API\n");
1499         priv->fwl = fwl;
1500
1501         return 0;
1502 }
1503
1504 static void pd692x0_i2c_remove(struct i2c_client *client)
1505 {
1506         struct pd692x0_priv *priv = i2c_get_clientdata(client);
1507
1508         firmware_upload_unregister(priv->fwl);
1509 }
1510
1511 static const struct i2c_device_id pd692x0_id[] = {
1512         { PD692X0_PSE_NAME },
1513         { }
1514 };
1515 MODULE_DEVICE_TABLE(i2c, pd692x0_id);
1516
1517 static const struct of_device_id pd692x0_of_match[] = {
1518         { .compatible = "microchip,pd69200", },
1519         { .compatible = "microchip,pd69210", },
1520         { .compatible = "microchip,pd69220", },
1521         { },
1522 };
1523 MODULE_DEVICE_TABLE(of, pd692x0_of_match);
1524
1525 static struct i2c_driver pd692x0_driver = {
1526         .probe          = pd692x0_i2c_probe,
1527         .remove         = pd692x0_i2c_remove,
1528         .id_table       = pd692x0_id,
1529         .driver         = {
1530                 .name           = PD692X0_PSE_NAME,
1531                 .of_match_table = pd692x0_of_match,
1532         },
1533 };
1534 module_i2c_driver(pd692x0_driver);
1535
1536 MODULE_AUTHOR("Kory Maincent <[email protected]>");
1537 MODULE_DESCRIPTION("Microchip PD692x0 PoE PSE Controller driver");
1538 MODULE_LICENSE("GPL");
This page took 0.110094 seconds and 4 git commands to generate.