Loading...
Note: File does not exist in v4.17.
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 <kory.maincent@bootlin.com>
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
31enum 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
41struct pd692x0_msg {
42 u8 key;
43 u8 echo;
44 u8 sub[3];
45 u8 data[8];
46 __be16 chksum;
47} __packed;
48
49struct 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
58enum {
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
67enum {
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
84struct 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 */
106static 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
175static 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
193static 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
216static 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
255static 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 */
282static 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
316out_success2:
317 dev_warn(&client->dev, "Communication is back, rtnl is unlocked!");
318out_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
329static 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
360static struct pd692x0_priv *to_pd692x0_priv(struct pse_controller_dev *pcdev)
361{
362 return container_of(pcdev, struct pd692x0_priv, pcdev);
363}
364
365static 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
384static 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
409static 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
434static 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
459struct 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
465static const struct pd692x0_pse_ext_state_mapping
466pd692x0_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
520static void
521pd692x0_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
537struct 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 */
548static const struct pd692x0_class_pw
549pd692x0_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
556static 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
570static 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
615static int
616pd692x0_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
637static 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
707static 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
732struct pd692x0_manager {
733 struct device_node *port_node[PD692X0_MAX_MANAGER_PORTS];
734 int nports;
735};
736
737struct pd692x0_matrix {
738 u8 hw_port_a;
739 u8 hw_port_b;
740};
741
742static int
743pd692x0_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
777out:
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
786static int
787pd692x0_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
831out:
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
844static int
845pd692x0_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
882static int
883pd692x0_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
921static int
922pd692x0_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
949static 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
974out:
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
982static 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
1002static int pd692x0_pi_get_pw_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 ret;
1008
1009 msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
1010 msg.sub[2] = id;
1011 ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1012 if (ret < 0)
1013 return ret;
1014
1015 return pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
1016}
1017
1018static int pd692x0_pi_set_pw_limit(struct pse_controller_dev *pcdev,
1019 int id, int max_mW)
1020{
1021 struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
1022 struct device *dev = &priv->client->dev;
1023 struct pd692x0_msg msg, buf = {0};
1024 int ret;
1025
1026 ret = pd692x0_fw_unavailable(priv);
1027 if (ret)
1028 return ret;
1029
1030 msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
1031 msg.sub[2] = id;
1032 ret = pd692x0_pi_set_pw_from_table(dev, &msg, max_mW);
1033 if (ret)
1034 return ret;
1035
1036 return pd692x0_sendrecv_msg(priv, &msg, &buf);
1037}
1038
1039static const struct pse_controller_ops pd692x0_ops = {
1040 .setup_pi_matrix = pd692x0_setup_pi_matrix,
1041 .ethtool_get_status = pd692x0_ethtool_get_status,
1042 .pi_enable = pd692x0_pi_enable,
1043 .pi_disable = pd692x0_pi_disable,
1044 .pi_is_enabled = pd692x0_pi_is_enabled,
1045 .pi_get_voltage = pd692x0_pi_get_voltage,
1046 .pi_get_pw_limit = pd692x0_pi_get_pw_limit,
1047 .pi_set_pw_limit = pd692x0_pi_set_pw_limit,
1048};
1049
1050#define PD692X0_FW_LINE_MAX_SZ 0xff
1051static int pd692x0_fw_get_next_line(const u8 *data,
1052 char *line, size_t size)
1053{
1054 size_t line_size;
1055 int i;
1056
1057 line_size = min_t(size_t, size, PD692X0_FW_LINE_MAX_SZ);
1058
1059 memset(line, 0, PD692X0_FW_LINE_MAX_SZ);
1060 for (i = 0; i < line_size - 1; i++) {
1061 if (*data == '\r' && *(data + 1) == '\n') {
1062 line[i] = '\r';
1063 line[i + 1] = '\n';
1064 return i + 2;
1065 }
1066 line[i] = *data;
1067 data++;
1068 }
1069
1070 return -EIO;
1071}
1072
1073static enum fw_upload_err
1074pd692x0_fw_recv_resp(const struct i2c_client *client, unsigned long ms_timeout,
1075 const char *msg_ok, unsigned int msg_size)
1076{
1077 /* Maximum controller response size */
1078 char fw_msg_buf[5] = {0};
1079 unsigned long timeout;
1080 int ret;
1081
1082 if (msg_size > sizeof(fw_msg_buf))
1083 return FW_UPLOAD_ERR_RW_ERROR;
1084
1085 /* Read until we get something */
1086 timeout = msecs_to_jiffies(ms_timeout) + jiffies;
1087 while (true) {
1088 if (time_is_before_jiffies(timeout))
1089 return FW_UPLOAD_ERR_TIMEOUT;
1090
1091 ret = i2c_master_recv(client, fw_msg_buf, 1);
1092 if (ret < 0 || *fw_msg_buf == 0) {
1093 usleep_range(1000, 2000);
1094 continue;
1095 } else {
1096 break;
1097 }
1098 }
1099
1100 /* Read remaining characters */
1101 ret = i2c_master_recv(client, fw_msg_buf + 1, msg_size - 1);
1102 if (strncmp(fw_msg_buf, msg_ok, msg_size)) {
1103 dev_err(&client->dev,
1104 "Wrong FW download process answer (%*pE)\n",
1105 msg_size, fw_msg_buf);
1106 return FW_UPLOAD_ERR_HW_ERROR;
1107 }
1108
1109 return FW_UPLOAD_ERR_NONE;
1110}
1111
1112static int pd692x0_fw_write_line(const struct i2c_client *client,
1113 const char line[PD692X0_FW_LINE_MAX_SZ],
1114 const bool last_line)
1115{
1116 int ret;
1117
1118 while (*line != 0) {
1119 ret = i2c_master_send(client, line, 1);
1120 if (ret < 0)
1121 return FW_UPLOAD_ERR_RW_ERROR;
1122 line++;
1123 }
1124
1125 if (last_line) {
1126 ret = pd692x0_fw_recv_resp(client, 100, "TP\r\n",
1127 sizeof("TP\r\n") - 1);
1128 if (ret)
1129 return ret;
1130 } else {
1131 ret = pd692x0_fw_recv_resp(client, 100, "T*\r\n",
1132 sizeof("T*\r\n") - 1);
1133 if (ret)
1134 return ret;
1135 }
1136
1137 return FW_UPLOAD_ERR_NONE;
1138}
1139
1140static enum fw_upload_err pd692x0_fw_reset(const struct i2c_client *client)
1141{
1142 const struct pd692x0_msg zero = {0};
1143 struct pd692x0_msg buf = {0};
1144 unsigned long timeout;
1145 char cmd[] = "RST";
1146 int ret;
1147
1148 ret = i2c_master_send(client, cmd, strlen(cmd));
1149 if (ret < 0) {
1150 dev_err(&client->dev,
1151 "Failed to reset the controller (%pe)\n",
1152 ERR_PTR(ret));
1153 return ret;
1154 }
1155
1156 timeout = msecs_to_jiffies(10000) + jiffies;
1157 while (true) {
1158 if (time_is_before_jiffies(timeout))
1159 return FW_UPLOAD_ERR_TIMEOUT;
1160
1161 ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
1162 if (ret < 0 ||
1163 !memcmp(&buf, &zero, sizeof(buf)))
1164 usleep_range(1000, 2000);
1165 else
1166 break;
1167 }
1168
1169 /* Is the reply a successful report message */
1170 if (buf.key != PD692X0_KEY_TLM || buf.echo != 0xff ||
1171 buf.sub[0] & 0x01) {
1172 dev_err(&client->dev, "PSE controller error\n");
1173 return FW_UPLOAD_ERR_HW_ERROR;
1174 }
1175
1176 /* Is the firmware operational */
1177 if (buf.sub[0] & 0x02) {
1178 dev_err(&client->dev,
1179 "PSE firmware error. Please update it.\n");
1180 return FW_UPLOAD_ERR_HW_ERROR;
1181 }
1182
1183 return FW_UPLOAD_ERR_NONE;
1184}
1185
1186static enum fw_upload_err pd692x0_fw_prepare(struct fw_upload *fwl,
1187 const u8 *data, u32 size)
1188{
1189 struct pd692x0_priv *priv = fwl->dd_handle;
1190 const struct i2c_client *client = priv->client;
1191 enum pd692x0_fw_state last_fw_state;
1192 int ret;
1193
1194 priv->cancel_request = false;
1195 last_fw_state = priv->fw_state;
1196
1197 priv->fw_state = PD692X0_FW_PREPARE;
1198
1199 /* Enter program mode */
1200 if (last_fw_state == PD692X0_FW_BROKEN) {
1201 const char *msg = "ENTR";
1202 const char *c;
1203
1204 c = msg;
1205 do {
1206 ret = i2c_master_send(client, c, 1);
1207 if (ret < 0)
1208 return FW_UPLOAD_ERR_RW_ERROR;
1209 if (*(c + 1))
1210 usleep_range(10000, 20000);
1211 } while (*(++c));
1212 } else {
1213 struct pd692x0_msg msg, buf;
1214
1215 msg = pd692x0_msg_template_list[PD692X0_MSG_DOWNLOAD_CMD];
1216 ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1217 if (ret < 0) {
1218 dev_err(&client->dev,
1219 "Failed to enter programming mode (%pe)\n",
1220 ERR_PTR(ret));
1221 return FW_UPLOAD_ERR_RW_ERROR;
1222 }
1223 }
1224
1225 ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1226 if (ret)
1227 goto err_out;
1228
1229 if (priv->cancel_request) {
1230 ret = FW_UPLOAD_ERR_CANCELED;
1231 goto err_out;
1232 }
1233
1234 return FW_UPLOAD_ERR_NONE;
1235
1236err_out:
1237 pd692x0_fw_reset(priv->client);
1238 priv->fw_state = last_fw_state;
1239 return ret;
1240}
1241
1242static enum fw_upload_err pd692x0_fw_write(struct fw_upload *fwl,
1243 const u8 *data, u32 offset,
1244 u32 size, u32 *written)
1245{
1246 struct pd692x0_priv *priv = fwl->dd_handle;
1247 char line[PD692X0_FW_LINE_MAX_SZ];
1248 const struct i2c_client *client;
1249 int ret, i;
1250 char cmd;
1251
1252 client = priv->client;
1253 priv->fw_state = PD692X0_FW_WRITE;
1254
1255 /* Erase */
1256 cmd = 'E';
1257 ret = i2c_master_send(client, &cmd, 1);
1258 if (ret < 0) {
1259 dev_err(&client->dev,
1260 "Failed to boot programming mode (%pe)\n",
1261 ERR_PTR(ret));
1262 return FW_UPLOAD_ERR_RW_ERROR;
1263 }
1264
1265 ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1);
1266 if (ret)
1267 return ret;
1268
1269 ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1);
1270 if (ret)
1271 dev_warn(&client->dev,
1272 "Failed to erase internal memory, however still try to write Firmware\n");
1273
1274 ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1275 if (ret)
1276 dev_warn(&client->dev,
1277 "Failed to erase internal memory, however still try to write Firmware\n");
1278
1279 if (priv->cancel_request)
1280 return FW_UPLOAD_ERR_CANCELED;
1281
1282 /* Program */
1283 cmd = 'P';
1284 ret = i2c_master_send(client, &cmd, sizeof(char));
1285 if (ret < 0) {
1286 dev_err(&client->dev,
1287 "Failed to boot programming mode (%pe)\n",
1288 ERR_PTR(ret));
1289 return ret;
1290 }
1291
1292 ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1);
1293 if (ret)
1294 return ret;
1295
1296 i = 0;
1297 while (i < size) {
1298 ret = pd692x0_fw_get_next_line(data, line, size - i);
1299 if (ret < 0) {
1300 ret = FW_UPLOAD_ERR_FW_INVALID;
1301 goto err;
1302 }
1303
1304 i += ret;
1305 data += ret;
1306 if (line[0] == 'S' && line[1] == '0') {
1307 continue;
1308 } else if (line[0] == 'S' && line[1] == '7') {
1309 ret = pd692x0_fw_write_line(client, line, true);
1310 if (ret)
1311 goto err;
1312 } else {
1313 ret = pd692x0_fw_write_line(client, line, false);
1314 if (ret)
1315 goto err;
1316 }
1317
1318 if (priv->cancel_request) {
1319 ret = FW_UPLOAD_ERR_CANCELED;
1320 goto err;
1321 }
1322 }
1323 *written = i;
1324
1325 msleep(400);
1326
1327 return FW_UPLOAD_ERR_NONE;
1328
1329err:
1330 strscpy_pad(line, "S7\r\n", sizeof(line));
1331 pd692x0_fw_write_line(client, line, true);
1332 return ret;
1333}
1334
1335static enum fw_upload_err pd692x0_fw_poll_complete(struct fw_upload *fwl)
1336{
1337 struct pd692x0_priv *priv = fwl->dd_handle;
1338 const struct i2c_client *client = priv->client;
1339 struct pd692x0_msg_ver ver;
1340 int ret;
1341
1342 priv->fw_state = PD692X0_FW_COMPLETE;
1343
1344 ret = pd692x0_fw_reset(client);
1345 if (ret)
1346 return ret;
1347
1348 ver = pd692x0_get_sw_version(priv);
1349 if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {
1350 dev_err(&client->dev,
1351 "Too old firmware version. Please update it\n");
1352 priv->fw_state = PD692X0_FW_NEED_UPDATE;
1353 return FW_UPLOAD_ERR_FW_INVALID;
1354 }
1355
1356 ret = pd692x0_setup_pi_matrix(&priv->pcdev);
1357 if (ret < 0) {
1358 dev_err(&client->dev, "Error configuring ports matrix (%pe)\n",
1359 ERR_PTR(ret));
1360 priv->fw_state = PD692X0_FW_NEED_UPDATE;
1361 return FW_UPLOAD_ERR_HW_ERROR;
1362 }
1363
1364 priv->fw_state = PD692X0_FW_OK;
1365 return FW_UPLOAD_ERR_NONE;
1366}
1367
1368static void pd692x0_fw_cancel(struct fw_upload *fwl)
1369{
1370 struct pd692x0_priv *priv = fwl->dd_handle;
1371
1372 priv->cancel_request = true;
1373}
1374
1375static void pd692x0_fw_cleanup(struct fw_upload *fwl)
1376{
1377 struct pd692x0_priv *priv = fwl->dd_handle;
1378
1379 switch (priv->fw_state) {
1380 case PD692X0_FW_WRITE:
1381 pd692x0_fw_reset(priv->client);
1382 fallthrough;
1383 case PD692X0_FW_COMPLETE:
1384 priv->fw_state = PD692X0_FW_BROKEN;
1385 break;
1386 default:
1387 break;
1388 }
1389}
1390
1391static const struct fw_upload_ops pd692x0_fw_ops = {
1392 .prepare = pd692x0_fw_prepare,
1393 .write = pd692x0_fw_write,
1394 .poll_complete = pd692x0_fw_poll_complete,
1395 .cancel = pd692x0_fw_cancel,
1396 .cleanup = pd692x0_fw_cleanup,
1397};
1398
1399static int pd692x0_i2c_probe(struct i2c_client *client)
1400{
1401 struct pd692x0_msg msg, buf = {0}, zero = {0};
1402 struct device *dev = &client->dev;
1403 struct pd692x0_msg_ver ver;
1404 struct pd692x0_priv *priv;
1405 struct fw_upload *fwl;
1406 int ret;
1407
1408 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1409 dev_err(dev, "i2c check functionality failed\n");
1410 return -ENXIO;
1411 }
1412
1413 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1414 if (!priv)
1415 return -ENOMEM;
1416
1417 priv->client = client;
1418 i2c_set_clientdata(client, priv);
1419
1420 ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
1421 if (ret != sizeof(buf)) {
1422 dev_err(dev, "Failed to get device status\n");
1423 return -EIO;
1424 }
1425
1426 /* Probe has been already run and the status dumped */
1427 if (!memcmp(&buf, &zero, sizeof(buf))) {
1428 /* Ask again the controller status */
1429 msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SYS_STATUS];
1430 ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1431 if (ret < 0) {
1432 dev_err(dev, "Failed to get device status\n");
1433 return ret;
1434 }
1435 }
1436
1437 if (buf.key != 0x03 || buf.sub[0] & 0x01) {
1438 dev_err(dev, "PSE controller error\n");
1439 return -EIO;
1440 }
1441 if (buf.sub[0] & 0x02) {
1442 dev_err(dev, "PSE firmware error. Please update it.\n");
1443 priv->fw_state = PD692X0_FW_BROKEN;
1444 } else {
1445 ver = pd692x0_get_sw_version(priv);
1446 dev_info(&client->dev, "Software version %d.%02d.%d.%d\n",
1447 ver.prod, ver.maj_sw_ver, ver.min_sw_ver,
1448 ver.pa_sw_ver);
1449
1450 if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {
1451 dev_err(dev, "Too old firmware version. Please update it\n");
1452 priv->fw_state = PD692X0_FW_NEED_UPDATE;
1453 } else {
1454 priv->fw_state = PD692X0_FW_OK;
1455 }
1456 }
1457
1458 priv->np = dev->of_node;
1459 priv->pcdev.nr_lines = PD692X0_MAX_PIS;
1460 priv->pcdev.owner = THIS_MODULE;
1461 priv->pcdev.ops = &pd692x0_ops;
1462 priv->pcdev.dev = dev;
1463 priv->pcdev.types = ETHTOOL_PSE_C33;
1464 ret = devm_pse_controller_register(dev, &priv->pcdev);
1465 if (ret)
1466 return dev_err_probe(dev, ret,
1467 "failed to register PSE controller\n");
1468
1469 fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),
1470 &pd692x0_fw_ops, priv);
1471 if (IS_ERR(fwl))
1472 return dev_err_probe(dev, PTR_ERR(fwl),
1473 "failed to register to the Firmware Upload API\n");
1474 priv->fwl = fwl;
1475
1476 return 0;
1477}
1478
1479static void pd692x0_i2c_remove(struct i2c_client *client)
1480{
1481 struct pd692x0_priv *priv = i2c_get_clientdata(client);
1482
1483 firmware_upload_unregister(priv->fwl);
1484}
1485
1486static const struct i2c_device_id pd692x0_id[] = {
1487 { PD692X0_PSE_NAME },
1488 { }
1489};
1490MODULE_DEVICE_TABLE(i2c, pd692x0_id);
1491
1492static const struct of_device_id pd692x0_of_match[] = {
1493 { .compatible = "microchip,pd69200", },
1494 { .compatible = "microchip,pd69210", },
1495 { .compatible = "microchip,pd69220", },
1496 { },
1497};
1498MODULE_DEVICE_TABLE(of, pd692x0_of_match);
1499
1500static struct i2c_driver pd692x0_driver = {
1501 .probe = pd692x0_i2c_probe,
1502 .remove = pd692x0_i2c_remove,
1503 .id_table = pd692x0_id,
1504 .driver = {
1505 .name = PD692X0_PSE_NAME,
1506 .of_match_table = pd692x0_of_match,
1507 },
1508};
1509module_i2c_driver(pd692x0_driver);
1510
1511MODULE_AUTHOR("Kory Maincent <kory.maincent@bootlin.com>");
1512MODULE_DESCRIPTION("Microchip PD692x0 PoE PSE Controller driver");
1513MODULE_LICENSE("GPL");