1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for the Microchip PD692X0 PoE PSE Controller driver (I2C bus)
5 * Copyright (c) 2023 Bootlin, Kory Maincent <kory.maincent@bootlin.com>
8 #include <linux/delay.h>
9 #include <linux/firmware.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/pse-pd/pse.h>
16 #define PD692X0_PSE_NAME "pd692x0_pse"
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)
23 #define PD69200_BT_PROD_VER 24
24 #define PD69210_BT_PROD_VER 26
25 #define PD69220_BT_PROD_VER 29
27 #define PD692X0_FW_MAJ_VER 3
28 #define PD692X0_FW_MIN_VER 5
29 #define PD692X0_FW_PATCH_VER 5
31 enum pd692x0_fw_state
{
35 PD692X0_FW_NEED_UPDATE
,
49 struct pd692x0_msg_ver
{
64 PD692X0_KEY_REPORT
= 0x52
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
,
80 /* add new message above here */
85 struct i2c_client
*client
;
86 struct pse_controller_dev pcdev
;
87 struct device_node
*np
;
89 enum pd692x0_fw_state fw_state
;
90 struct fw_upload
*fwl
;
95 unsigned long last_cmd_key_time
;
97 enum ethtool_c33_pse_admin_state admin_state
[PD692X0_MAX_PIS
];
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
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},
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},
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},
125 [PD692X0_MSG_SET_TMP_PORT_MATRIX
] = {
126 .key
= PD692X0_KEY_CMD
,
128 .data
= { 0, 0x4e, 0x4e, 0x4e,
129 0x4e, 0x4e, 0x4e, 0x4e},
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},
137 [PD692X0_MSG_SET_PORT_PARAM
] = {
138 .key
= PD692X0_KEY_CMD
,
140 .data
= { 0xf, 0xff, 0xff, 0xff,
141 0x4e, 0x4e, 0x4e, 0x4e},
143 [PD692X0_MSG_GET_PORT_STATUS
] = {
144 .key
= PD692X0_KEY_REQ
,
146 .data
= {0x4e, 0x4e, 0x4e, 0x4e,
147 0x4e, 0x4e, 0x4e, 0x4e},
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},
155 [PD692X0_MSG_GET_PORT_CLASS
] = {
156 .key
= PD692X0_KEY_REQ
,
158 .data
= {0x4e, 0x4e, 0x4e, 0x4e,
159 0x4e, 0x4e, 0x4e, 0x4e},
161 [PD692X0_MSG_GET_PORT_MEAS
] = {
162 .key
= PD692X0_KEY_REQ
,
164 .data
= {0x4e, 0x4e, 0x4e, 0x4e,
165 0x4e, 0x4e, 0x4e, 0x4e},
167 [PD692X0_MSG_GET_PORT_PARAM
] = {
168 .key
= PD692X0_KEY_REQ
,
170 .data
= {0x4e, 0x4e, 0x4e, 0x4e,
171 0x4e, 0x4e, 0x4e, 0x4e},
175 static u8
pd692x0_build_msg(struct pd692x0_msg
*msg
, u8 echo
)
177 u8
*data
= (u8
*)msg
;
185 for (i
= 0; i
< sizeof(*msg
) - sizeof(msg
->chksum
); i
++)
188 msg
->chksum
= cpu_to_be16(chksum
);
193 static int pd692x0_send_msg(struct pd692x0_priv
*priv
, struct pd692x0_msg
*msg
)
195 const struct i2c_client
*client
= priv
->client
;
198 if (msg
->key
== PD692X0_KEY_CMD
&& priv
->last_cmd_key
) {
201 cmd_msleep
= 30 - jiffies_to_msecs(jiffies
- priv
->last_cmd_key_time
);
206 /* Add echo and checksum bytes to the message */
207 priv
->msg_id
= pd692x0_build_msg(msg
, priv
->msg_id
);
209 ret
= i2c_master_send(client
, (u8
*)msg
, sizeof(*msg
));
210 if (ret
!= sizeof(*msg
))
216 static int pd692x0_reset(struct pd692x0_priv
*priv
)
218 const struct i2c_client
*client
= priv
->client
;
219 struct pd692x0_msg msg
, buf
= {0};
222 msg
= pd692x0_msg_template_list
[PD692X0_MSG_RESET
];
223 ret
= pd692x0_send_msg(priv
, &msg
);
225 dev_err(&client
->dev
,
226 "Failed to reset the controller (%pe)\n", ERR_PTR(ret
));
232 ret
= i2c_master_recv(client
, (u8
*)&buf
, sizeof(buf
));
233 if (ret
!= sizeof(buf
))
234 return ret
< 0 ? ret
: -EIO
;
236 /* Is the reply a successful report message */
237 if (buf
.key
!= PD692X0_KEY_REPORT
|| buf
.sub
[0] || buf
.sub
[1])
242 ret
= i2c_master_recv(client
, (u8
*)&buf
, sizeof(buf
));
243 if (ret
!= sizeof(buf
))
244 return ret
< 0 ? ret
: -EIO
;
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");
255 static bool pd692x0_try_recv_msg(const struct i2c_client
*client
,
256 struct pd692x0_msg
*msg
,
257 struct pd692x0_msg
*buf
)
259 /* Wait 30ms before readback as mandated by the protocol */
262 memset(buf
, 0, sizeof(*buf
));
263 i2c_master_recv(client
, (u8
*)buf
, sizeof(*buf
));
269 memset(buf
, 0, sizeof(*buf
));
270 i2c_master_recv(client
, (u8
*)buf
, sizeof(*buf
));
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
282 static int pd692x0_recv_msg(struct pd692x0_priv
*priv
,
283 struct pd692x0_msg
*msg
,
284 struct pd692x0_msg
*buf
)
286 const struct i2c_client
*client
= priv
->client
;
289 ret
= pd692x0_try_recv_msg(client
, msg
, buf
);
293 dev_warn(&client
->dev
,
294 "Communication lost, rtnl is locked until communication is back!");
296 ret
= pd692x0_send_msg(priv
, msg
);
300 ret
= pd692x0_try_recv_msg(client
, msg
, buf
);
306 ret
= pd692x0_send_msg(priv
, msg
);
310 ret
= pd692x0_try_recv_msg(client
, msg
, buf
);
314 return pd692x0_reset(priv
);
317 dev_warn(&client
->dev
, "Communication is back, rtnl is unlocked!");
319 if (msg
->key
== PD692X0_KEY_CMD
) {
320 priv
->last_cmd_key
= true;
321 priv
->last_cmd_key_time
= jiffies
;
323 priv
->last_cmd_key
= false;
329 static int pd692x0_sendrecv_msg(struct pd692x0_priv
*priv
,
330 struct pd692x0_msg
*msg
,
331 struct pd692x0_msg
*buf
)
333 struct device
*dev
= &priv
->client
->dev
;
336 ret
= pd692x0_send_msg(priv
, msg
);
340 ret
= pd692x0_recv_msg(priv
, msg
, buf
);
344 if (msg
->echo
!= buf
->echo
) {
346 "Wrong match in message ID, expect %d received %d.\n",
347 msg
->echo
, buf
->echo
);
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])) {
360 static struct pd692x0_priv
*to_pd692x0_priv(struct pse_controller_dev
*pcdev
)
362 return container_of(pcdev
, struct pd692x0_priv
, pcdev
);
365 static int pd692x0_fw_unavailable(struct pd692x0_priv
*priv
)
367 switch (priv
->fw_state
) {
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");
375 case PD692X0_FW_BROKEN
:
376 case PD692X0_FW_NEED_UPDATE
:
378 dev_err(&priv
->client
->dev
,
379 "Firmware issue. Please update it!\n");
384 static int pd692x0_pi_enable(struct pse_controller_dev
*pcdev
, int id
)
386 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
387 struct pd692x0_msg msg
, buf
= {0};
390 ret
= pd692x0_fw_unavailable(priv
);
394 if (priv
->admin_state
[id
] == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED
)
397 msg
= pd692x0_msg_template_list
[PD692X0_MSG_SET_PORT_PARAM
];
400 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
404 priv
->admin_state
[id
] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED
;
409 static int pd692x0_pi_disable(struct pse_controller_dev
*pcdev
, int id
)
411 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
412 struct pd692x0_msg msg
, buf
= {0};
415 ret
= pd692x0_fw_unavailable(priv
);
419 if (priv
->admin_state
[id
] == ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED
)
422 msg
= pd692x0_msg_template_list
[PD692X0_MSG_SET_PORT_PARAM
];
425 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
429 priv
->admin_state
[id
] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED
;
434 static int pd692x0_pi_is_enabled(struct pse_controller_dev
*pcdev
, int id
)
436 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
437 struct pd692x0_msg msg
, buf
= {0};
440 ret
= pd692x0_fw_unavailable(priv
);
444 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_PORT_STATUS
];
446 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
451 priv
->admin_state
[id
] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED
;
454 priv
->admin_state
[id
] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED
;
459 struct pd692x0_pse_ext_state_mapping
{
461 enum ethtool_c33_pse_ext_state pse_ext_state
;
462 u32 pse_ext_substate
;
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
},
521 pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info
*c33_ext_state_info
,
524 const struct pd692x0_pse_ext_state_mapping
*ext_state_map
;
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
;
537 struct pd692x0_class_pw
{
541 int max_added_class_pw
;
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.
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},
556 static int pd692x0_pi_get_pw_from_table(int op_mode
, int added_pw
)
558 const struct pd692x0_class_pw
*pw_table
;
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;
570 static int pd692x0_pi_set_pw_from_table(struct device
*dev
,
571 struct pd692x0_msg
*msg
, int pw
)
573 const struct pd692x0_class_pw
*pw_table
;
576 pw_table
= pd692x0_class_pw_table
;
577 if (pw
< pw_table
->class_pw
) {
579 "Power limit %dmW not supported. Ranges minimal available: [%d-%d]\n",
582 pw_table
->class_pw
+ pw_table
->max_added_class_pw
);
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
))
590 if (pw
< pw_table
->class_pw
) {
592 "Power limit %dmW not supported. Ranges available: [%d-%d] or [%d-%d]\n",
594 (pw_table
- 1)->class_pw
,
595 (pw_table
- 1)->class_pw
+ (pw_table
- 1)->max_added_class_pw
,
597 pw_table
->class_pw
+ pw_table
->max_added_class_pw
);
601 msg
->data
[2] = pw_table
->class_cfg_value
;
602 msg
->data
[3] = (pw
- pw_table
->class_pw
) / 100;
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;
616 pd692x0_pi_get_pw_ranges(struct pse_control_status
*st
)
618 const struct pd692x0_class_pw
*pw_table
;
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
),
625 if (!st
->c33_pw_limit_ranges
)
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
;
633 st
->c33_pw_limit_nb_ranges
= i
;
637 static int pd692x0_ethtool_get_status(struct pse_controller_dev
*pcdev
,
639 struct netlink_ext_ack
*extack
,
640 struct pse_control_status
*status
)
642 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
643 struct pd692x0_msg msg
, buf
= {0};
647 ret
= pd692x0_fw_unavailable(priv
);
651 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_PORT_STATUS
];
653 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
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
;
665 status
->c33_pw_status
= ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED
;
668 status
->c33_admin_state
= ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED
;
670 status
->c33_admin_state
= ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED
;
672 priv
->admin_state
[id
] = status
->c33_admin_state
;
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;
677 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_PORT_PARAM
];
679 memset(&buf
, 0, sizeof(buf
));
680 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
684 ret
= pd692x0_pi_get_pw_from_table(buf
.data
[0], buf
.data
[1]);
687 status
->c33_avail_pw_limit
= ret
;
689 memset(&buf
, 0, sizeof(buf
));
690 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_PORT_CLASS
];
692 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
696 class = buf
.data
[3] >> 4;
698 status
->c33_pw_class
= class;
700 ret
= pd692x0_pi_get_pw_ranges(status
);
707 static struct pd692x0_msg_ver
pd692x0_get_sw_version(struct pd692x0_priv
*priv
)
709 struct device
*dev
= &priv
->client
->dev
;
710 struct pd692x0_msg msg
, buf
= {0};
711 struct pd692x0_msg_ver ver
= {0};
714 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_SW_VER
];
715 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
717 dev_err(dev
, "Failed to get PSE version (%pe)\n", ERR_PTR(ret
));
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];
732 struct pd692x0_manager
{
733 struct device_node
*port_node
[PD692X0_MAX_MANAGER_PORTS
];
737 struct pd692x0_matrix
{
743 pd692x0_of_get_ports_manager(struct pd692x0_priv
*priv
,
744 struct pd692x0_manager
*manager
,
745 struct device_node
*np
)
747 struct device_node
*node
;
751 for_each_child_of_node(np
, node
) {
754 if (!of_node_name_eq(node
, "port"))
757 ret
= of_property_read_u32(node
, "reg", &port
);
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",
770 manager
->port_node
[port
] = node
;
774 manager
->nports
= nports
;
778 for (i
= 0; i
< nports
; i
++) {
779 of_node_put(manager
->port_node
[i
]);
780 manager
->port_node
[i
] = NULL
;
787 pd692x0_of_get_managers(struct pd692x0_priv
*priv
,
788 struct pd692x0_manager manager
[PD692X0_MAX_MANAGERS
])
790 struct device_node
*managers_node
, *node
;
791 int ret
, nmanagers
, i
, j
;
797 managers_node
= of_get_child_by_name(priv
->np
, "managers");
801 for_each_child_of_node(managers_node
, node
) {
804 if (!of_node_name_eq(node
, "manager"))
807 ret
= of_property_read_u32(node
, "reg", &manager_id
);
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",
820 ret
= pd692x0_of_get_ports_manager(priv
, &manager
[manager_id
],
828 of_node_put(managers_node
);
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
;
840 of_node_put(managers_node
);
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
)
855 /* Look on every managers */
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
]) {
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
;
883 pd692x0_set_ports_matrix(struct pd692x0_priv
*priv
,
884 const struct pd692x0_manager
*manager
,
886 struct pd692x0_matrix port_matrix
[PD692X0_MAX_PIS
])
888 struct pse_controller_dev
*pcdev
= &priv
->pcdev
;
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;
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],
903 dev_err(&priv
->client
->dev
,
904 "unable to configure pi %d pairset 0", i
);
908 ret
= pd692x0_set_port_matrix(&pcdev
->pi
[i
].pairset
[1],
912 dev_err(&priv
->client
->dev
,
913 "unable to configure pi %d pairset 1", i
);
922 pd692x0_write_ports_matrix(struct pd692x0_priv
*priv
,
923 const struct pd692x0_matrix port_matrix
[PD692X0_MAX_PIS
])
925 struct pd692x0_msg msg
, buf
;
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
++) {
932 msg
.data
[0] = port_matrix
[i
].hw_port_b
;
933 msg
.data
[1] = port_matrix
[i
].hw_port_a
;
935 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
941 msg
= pd692x0_msg_template_list
[PD692X0_MSG_PRG_PORT_MATRIX
];
942 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
949 static int pd692x0_setup_pi_matrix(struct pse_controller_dev
*pcdev
)
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
;
956 /* Should we flash the port matrix */
957 if (priv
->fw_state
!= PD692X0_FW_OK
&&
958 priv
->fw_state
!= PD692X0_FW_COMPLETE
)
961 ret
= pd692x0_of_get_managers(priv
, manager
);
966 ret
= pd692x0_set_ports_matrix(priv
, manager
, nmanagers
, port_matrix
);
970 ret
= pd692x0_write_ports_matrix(priv
, port_matrix
);
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
]);
982 static int pd692x0_pi_get_voltage(struct pse_controller_dev
*pcdev
, int id
)
984 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
985 struct pd692x0_msg msg
, buf
= {0};
988 ret
= pd692x0_fw_unavailable(priv
);
992 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_PORT_MEAS
];
994 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
998 /* Convert 0.1V unit to uV */
999 return (buf
.sub
[0] << 8 | buf
.sub
[1]) * 100000;
1002 static int pd692x0_pi_get_current_limit(struct pse_controller_dev
*pcdev
,
1005 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
1006 struct pd692x0_msg msg
, buf
= {0};
1007 int mW
, uV
, uA
, ret
;
1010 msg
= pd692x0_msg_template_list
[PD692X0_MSG_GET_PORT_PARAM
];
1012 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
1016 ret
= pd692x0_pi_get_pw_from_table(buf
.data
[2], buf
.data
[3]);
1021 ret
= pd692x0_pi_get_voltage(pcdev
, id
);
1027 tmp_64
*= 1000000000ull;
1028 /* uA = mW * 1000000000 / uV */
1029 uA
= DIV_ROUND_CLOSEST_ULL(tmp_64
, uV
);
1033 static int pd692x0_pi_set_current_limit(struct pse_controller_dev
*pcdev
,
1036 struct pd692x0_priv
*priv
= to_pd692x0_priv(pcdev
);
1037 struct device
*dev
= &priv
->client
->dev
;
1038 struct pd692x0_msg msg
, buf
= {0};
1042 ret
= pd692x0_fw_unavailable(priv
);
1046 ret
= pd692x0_pi_get_voltage(pcdev
, id
);
1051 msg
= pd692x0_msg_template_list
[PD692X0_MSG_SET_PORT_PARAM
];
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
);
1061 return pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
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
,
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
)
1082 line_size
= min_t(size_t, size
, PD692X0_FW_LINE_MAX_SZ
);
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') {
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
)
1102 /* Maximum controller response size */
1103 char fw_msg_buf
[5] = {0};
1104 unsigned long timeout
;
1107 if (msg_size
> sizeof(fw_msg_buf
))
1108 return FW_UPLOAD_ERR_RW_ERROR
;
1110 /* Read until we get something */
1111 timeout
= msecs_to_jiffies(ms_timeout
) + jiffies
;
1113 if (time_is_before_jiffies(timeout
))
1114 return FW_UPLOAD_ERR_TIMEOUT
;
1116 ret
= i2c_master_recv(client
, fw_msg_buf
, 1);
1117 if (ret
< 0 || *fw_msg_buf
== 0) {
1118 usleep_range(1000, 2000);
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
;
1134 return FW_UPLOAD_ERR_NONE
;
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
)
1143 while (*line
!= 0) {
1144 ret
= i2c_master_send(client
, line
, 1);
1146 return FW_UPLOAD_ERR_RW_ERROR
;
1151 ret
= pd692x0_fw_recv_resp(client
, 100, "TP\r\n",
1152 sizeof("TP\r\n") - 1);
1156 ret
= pd692x0_fw_recv_resp(client
, 100, "T*\r\n",
1157 sizeof("T*\r\n") - 1);
1162 return FW_UPLOAD_ERR_NONE
;
1165 static enum fw_upload_err
pd692x0_fw_reset(const struct i2c_client
*client
)
1167 const struct pd692x0_msg zero
= {0};
1168 struct pd692x0_msg buf
= {0};
1169 unsigned long timeout
;
1173 ret
= i2c_master_send(client
, cmd
, strlen(cmd
));
1175 dev_err(&client
->dev
,
1176 "Failed to reset the controller (%pe)\n",
1181 timeout
= msecs_to_jiffies(10000) + jiffies
;
1183 if (time_is_before_jiffies(timeout
))
1184 return FW_UPLOAD_ERR_TIMEOUT
;
1186 ret
= i2c_master_recv(client
, (u8
*)&buf
, sizeof(buf
));
1188 !memcmp(&buf
, &zero
, sizeof(buf
)))
1189 usleep_range(1000, 2000);
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
;
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
;
1208 return FW_UPLOAD_ERR_NONE
;
1211 static enum fw_upload_err
pd692x0_fw_prepare(struct fw_upload
*fwl
,
1212 const u8
*data
, u32 size
)
1214 struct pd692x0_priv
*priv
= fwl
->dd_handle
;
1215 const struct i2c_client
*client
= priv
->client
;
1216 enum pd692x0_fw_state last_fw_state
;
1219 priv
->cancel_request
= false;
1220 last_fw_state
= priv
->fw_state
;
1222 priv
->fw_state
= PD692X0_FW_PREPARE
;
1224 /* Enter program mode */
1225 if (last_fw_state
== PD692X0_FW_BROKEN
) {
1226 const char *msg
= "ENTR";
1231 ret
= i2c_master_send(client
, c
, 1);
1233 return FW_UPLOAD_ERR_RW_ERROR
;
1235 usleep_range(10000, 20000);
1238 struct pd692x0_msg msg
, buf
;
1240 msg
= pd692x0_msg_template_list
[PD692X0_MSG_DOWNLOAD_CMD
];
1241 ret
= pd692x0_sendrecv_msg(priv
, &msg
, &buf
);
1243 dev_err(&client
->dev
,
1244 "Failed to enter programming mode (%pe)\n",
1246 return FW_UPLOAD_ERR_RW_ERROR
;
1250 ret
= pd692x0_fw_recv_resp(client
, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1254 if (priv
->cancel_request
) {
1255 ret
= FW_UPLOAD_ERR_CANCELED
;
1259 return FW_UPLOAD_ERR_NONE
;
1262 pd692x0_fw_reset(priv
->client
);
1263 priv
->fw_state
= last_fw_state
;
1267 static enum fw_upload_err
pd692x0_fw_write(struct fw_upload
*fwl
,
1268 const u8
*data
, u32 offset
,
1269 u32 size
, u32
*written
)
1271 struct pd692x0_priv
*priv
= fwl
->dd_handle
;
1272 char line
[PD692X0_FW_LINE_MAX_SZ
];
1273 const struct i2c_client
*client
;
1277 client
= priv
->client
;
1278 priv
->fw_state
= PD692X0_FW_WRITE
;
1282 ret
= i2c_master_send(client
, &cmd
, 1);
1284 dev_err(&client
->dev
,
1285 "Failed to boot programming mode (%pe)\n",
1287 return FW_UPLOAD_ERR_RW_ERROR
;
1290 ret
= pd692x0_fw_recv_resp(client
, 100, "TOE\r\n", sizeof("TOE\r\n") - 1);
1294 ret
= pd692x0_fw_recv_resp(client
, 5000, "TE\r\n", sizeof("TE\r\n") - 1);
1296 dev_warn(&client
->dev
,
1297 "Failed to erase internal memory, however still try to write Firmware\n");
1299 ret
= pd692x0_fw_recv_resp(client
, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1301 dev_warn(&client
->dev
,
1302 "Failed to erase internal memory, however still try to write Firmware\n");
1304 if (priv
->cancel_request
)
1305 return FW_UPLOAD_ERR_CANCELED
;
1309 ret
= i2c_master_send(client
, &cmd
, sizeof(char));
1311 dev_err(&client
->dev
,
1312 "Failed to boot programming mode (%pe)\n",
1317 ret
= pd692x0_fw_recv_resp(client
, 100, "TOP\r\n", sizeof("TOP\r\n") - 1);
1323 ret
= pd692x0_fw_get_next_line(data
, line
, size
- i
);
1325 ret
= FW_UPLOAD_ERR_FW_INVALID
;
1331 if (line
[0] == 'S' && line
[1] == '0') {
1333 } else if (line
[0] == 'S' && line
[1] == '7') {
1334 ret
= pd692x0_fw_write_line(client
, line
, true);
1338 ret
= pd692x0_fw_write_line(client
, line
, false);
1343 if (priv
->cancel_request
) {
1344 ret
= FW_UPLOAD_ERR_CANCELED
;
1352 return FW_UPLOAD_ERR_NONE
;
1355 strscpy_pad(line
, "S7\r\n", sizeof(line
));
1356 pd692x0_fw_write_line(client
, line
, true);
1360 static enum fw_upload_err
pd692x0_fw_poll_complete(struct fw_upload
*fwl
)
1362 struct pd692x0_priv
*priv
= fwl
->dd_handle
;
1363 const struct i2c_client
*client
= priv
->client
;
1364 struct pd692x0_msg_ver ver
;
1367 priv
->fw_state
= PD692X0_FW_COMPLETE
;
1369 ret
= pd692x0_fw_reset(client
);
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
;
1381 ret
= pd692x0_setup_pi_matrix(&priv
->pcdev
);
1383 dev_err(&client
->dev
, "Error configuring ports matrix (%pe)\n",
1385 priv
->fw_state
= PD692X0_FW_NEED_UPDATE
;
1386 return FW_UPLOAD_ERR_HW_ERROR
;
1389 priv
->fw_state
= PD692X0_FW_OK
;
1390 return FW_UPLOAD_ERR_NONE
;
1393 static void pd692x0_fw_cancel(struct fw_upload
*fwl
)
1395 struct pd692x0_priv
*priv
= fwl
->dd_handle
;
1397 priv
->cancel_request
= true;
1400 static void pd692x0_fw_cleanup(struct fw_upload
*fwl
)
1402 struct pd692x0_priv
*priv
= fwl
->dd_handle
;
1404 switch (priv
->fw_state
) {
1405 case PD692X0_FW_WRITE
:
1406 pd692x0_fw_reset(priv
->client
);
1408 case PD692X0_FW_COMPLETE
:
1409 priv
->fw_state
= PD692X0_FW_BROKEN
;
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
,
1424 static int pd692x0_i2c_probe(struct i2c_client
*client
)
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
;
1433 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
1434 dev_err(dev
, "i2c check functionality failed\n");
1438 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
1442 priv
->client
= client
;
1443 i2c_set_clientdata(client
, priv
);
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");
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
);
1457 dev_err(dev
, "Failed to get device status\n");
1462 if (buf
.key
!= 0x03 || buf
.sub
[0] & 0x01) {
1463 dev_err(dev
, "PSE controller error\n");
1466 if (buf
.sub
[0] & 0x02) {
1467 dev_err(dev
, "PSE firmware error. Please update it.\n");
1468 priv
->fw_state
= PD692X0_FW_BROKEN
;
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
,
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
;
1479 priv
->fw_state
= PD692X0_FW_OK
;
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
);
1491 return dev_err_probe(dev
, ret
,
1492 "failed to register PSE controller\n");
1494 fwl
= firmware_upload_register(THIS_MODULE
, dev
, dev_name(dev
),
1495 &pd692x0_fw_ops
, priv
);
1497 return dev_err_probe(dev
, PTR_ERR(fwl
),
1498 "failed to register to the Firmware Upload API\n");
1504 static void pd692x0_i2c_remove(struct i2c_client
*client
)
1506 struct pd692x0_priv
*priv
= i2c_get_clientdata(client
);
1508 firmware_upload_unregister(priv
->fwl
);
1511 static const struct i2c_device_id pd692x0_id
[] = {
1512 { PD692X0_PSE_NAME
},
1515 MODULE_DEVICE_TABLE(i2c
, pd692x0_id
);
1517 static const struct of_device_id pd692x0_of_match
[] = {
1518 { .compatible
= "microchip,pd69200", },
1519 { .compatible
= "microchip,pd69210", },
1520 { .compatible
= "microchip,pd69220", },
1523 MODULE_DEVICE_TABLE(of
, pd692x0_of_match
);
1525 static struct i2c_driver pd692x0_driver
= {
1526 .probe
= pd692x0_i2c_probe
,
1527 .remove
= pd692x0_i2c_remove
,
1528 .id_table
= pd692x0_id
,
1530 .name
= PD692X0_PSE_NAME
,
1531 .of_match_table
= pd692x0_of_match
,
1534 module_i2c_driver(pd692x0_driver
);
1536 MODULE_AUTHOR("Kory Maincent <kory.maincent@bootlin.com>");
1537 MODULE_DESCRIPTION("Microchip PD692x0 PoE PSE Controller driver");
1538 MODULE_LICENSE("GPL");