1*44566e61SJonas Jelonek // SPDX-License-Identifier: GPL-2.0-or-later
2*44566e61SJonas Jelonek /*
3*44566e61SJonas Jelonek * Driver for the microcontroller (MCU) fronting PSE silicon on various
4*44566e61SJonas Jelonek * Realtek-based managed switches. The MCU speaks a 12-byte fixed-frame
5*44566e61SJonas Jelonek * management protocol; this driver covers two generations of the
6*44566e61SJonas Jelonek * protocol via a per-dialect opcode table and response parsers.
7*44566e61SJonas Jelonek *
8*44566e61SJonas Jelonek * Many PoE switch designs put a dedicated microcontroller in front of the
9*44566e61SJonas Jelonek * actual PSE silicon: the host CPU talks to the MCU over I2C/SMBus or
10*44566e61SJonas Jelonek * UART, and the MCU in turn manages the PSE chips on the board. The MCU
11*44566e61SJonas Jelonek * speaks a small message-based protocol. The PSE chips themselves are not
12*44566e61SJonas Jelonek * accessed directly; everything goes through MCU commands.
13*44566e61SJonas Jelonek *
14*44566e61SJonas Jelonek * This driver targets that architecture for the Realtek-family protocol.
15*44566e61SJonas Jelonek * Two generations are supported: Gen1 being used on older switches where
16*44566e61SJonas Jelonek * the MCU fronts and manages Broadcom PSE silicon; Gen2 being used with
17*44566e61SJonas Jelonek * Realtek PSE silicon. The two share frame format and a sum-mod-256
18*44566e61SJonas Jelonek * checksum but diverge on opcode numbers and on a few response layouts;
19*44566e61SJonas Jelonek * this is handled by the per-dialect opcode table and parser hooks.
20*44566e61SJonas Jelonek *
21*44566e61SJonas Jelonek * Out of scope: PSE chips that are interfaced directly from the host
22*44566e61SJonas Jelonek * without a management MCU, MCU designs that speak an unrelated protocol
23*44566e61SJonas Jelonek * family, and "dumb PSE" modes where no host control is wired up at all.
24*44566e61SJonas Jelonek *
25*44566e61SJonas Jelonek * This core module implements the protocol, decoding/encoding of MCU
26*44566e61SJonas Jelonek * responses, and the pse_controller_ops integration. Transport modules
27*44566e61SJonas Jelonek * (realtek-pse-mcu-i2c, realtek-pse-mcu-uart) provide the send/recv
28*44566e61SJonas Jelonek * callbacks.
29*44566e61SJonas Jelonek */
30*44566e61SJonas Jelonek
31*44566e61SJonas Jelonek #include <linux/bitfield.h>
32*44566e61SJonas Jelonek #include <linux/cleanup.h>
33*44566e61SJonas Jelonek #include <linux/container_of.h>
34*44566e61SJonas Jelonek #include <linux/delay.h>
35*44566e61SJonas Jelonek #include <linux/gpio/consumer.h>
36*44566e61SJonas Jelonek #include <linux/jiffies.h>
37*44566e61SJonas Jelonek #include <linux/minmax.h>
38*44566e61SJonas Jelonek #include <linux/module.h>
39*44566e61SJonas Jelonek #include <linux/property.h>
40*44566e61SJonas Jelonek #include <linux/pse-pd/pse.h>
41*44566e61SJonas Jelonek #include <linux/unaligned.h>
42*44566e61SJonas Jelonek
43*44566e61SJonas Jelonek #include "realtek-pse-mcu.h"
44*44566e61SJonas Jelonek
45*44566e61SJonas Jelonek #define RTPSE_MCU_DEVICE_ID_RTL8238B 0x0138
46*44566e61SJonas Jelonek #define RTPSE_MCU_DEVICE_ID_RTL8239 0x0039
47*44566e61SJonas Jelonek #define RTPSE_MCU_DEVICE_ID_RTL8239C 0x0139
48*44566e61SJonas Jelonek #define RTPSE_MCU_DEVICE_ID_BCM59111 0xe111
49*44566e61SJonas Jelonek #define RTPSE_MCU_DEVICE_ID_BCM59121 0xe121
50*44566e61SJonas Jelonek
51*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_DISABLED 0x00
52*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_SEARCHING 0x01
53*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_DELIVERING 0x02
54*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_TEST 0x03 /* Gen1-only; reserved on Gen2 */
55*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_FAULT 0x04
56*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_OTHER_FAULT 0x05 /* Gen1-only; reserved on Gen2 */
57*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_STS_REQUESTING 0x06
58*44566e61SJonas Jelonek
59*44566e61SJonas Jelonek /* RTPSE_MCU_PORT_SET_POWER_LIMIT_TYPE values */
60*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_PW_LIMIT_TYPE_USER 0x02
61*44566e61SJonas Jelonek
62*44566e61SJonas Jelonek #define RTPSE_MCU_MAX_PORTS 48
63*44566e61SJonas Jelonek #define RTPSE_MCU_PORT_MAX_PRIORITY 3
64*44566e61SJonas Jelonek
65*44566e61SJonas Jelonek /* Bounded resends when the MCU replies NOT_READY (busy). */
66*44566e61SJonas Jelonek #define RTPSE_MCU_NOT_READY_RETRIES 3
67*44566e61SJonas Jelonek
68*44566e61SJonas Jelonek /* Nominal PSE rail; 802.3at/bt operating range. */
69*44566e61SJonas Jelonek #define RTPSE_MCU_PSE_VOLTAGE_UV 54000000
70*44566e61SJonas Jelonek
71*44566e61SJonas Jelonek enum rtpse_mcu_cmd {
72*44566e61SJonas Jelonek RTPSE_MCU_CMD_SET_GLOBAL_STATE,
73*44566e61SJonas Jelonek RTPSE_MCU_CMD_GET_SYSTEM_INFO,
74*44566e61SJonas Jelonek RTPSE_MCU_CMD_GET_EXT_CONFIG,
75*44566e61SJonas Jelonek
76*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_ENABLE,
77*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE,
78*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT,
79*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_EXT,
80*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_SET_PRIORITY,
81*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_GET_STATUS,
82*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_GET_POWER_STATS,
83*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_GET_CONFIG,
84*44566e61SJonas Jelonek RTPSE_MCU_CMD_PORT_GET_EXT_CONFIG,
85*44566e61SJonas Jelonek
86*44566e61SJonas Jelonek RTPSE_MCU_NUM_CMDS,
87*44566e61SJonas Jelonek };
88*44566e61SJonas Jelonek
89*44566e61SJonas Jelonek struct rtpse_mcu_opcode {
90*44566e61SJonas Jelonek u8 op;
91*44566e61SJonas Jelonek bool valid;
92*44566e61SJonas Jelonek };
93*44566e61SJonas Jelonek
94*44566e61SJonas Jelonek /* Shorthand for the designated-initializer entries in dialect opcode tables. */
95*44566e61SJonas Jelonek #define RTPSE_MCU_OP(opc) { .op = (opc), .valid = true }
96*44566e61SJonas Jelonek
97*44566e61SJonas Jelonek /* Parsed MCU response structures (decoded from rtpse_mcu_msg replies) */
98*44566e61SJonas Jelonek
99*44566e61SJonas Jelonek struct rtpse_mcu_info {
100*44566e61SJonas Jelonek u8 max_ports;
101*44566e61SJonas Jelonek bool system_enable;
102*44566e61SJonas Jelonek u16 device_id;
103*44566e61SJonas Jelonek u8 mcu_type;
104*44566e61SJonas Jelonek };
105*44566e61SJonas Jelonek
106*44566e61SJonas Jelonek struct rtpse_mcu_ext_config {
107*44566e61SJonas Jelonek u8 num_of_pses;
108*44566e61SJonas Jelonek };
109*44566e61SJonas Jelonek
110*44566e61SJonas Jelonek struct rtpse_mcu_port_status {
111*44566e61SJonas Jelonek u8 sts1;
112*44566e61SJonas Jelonek u8 sts2;
113*44566e61SJonas Jelonek u8 sts3;
114*44566e61SJonas Jelonek };
115*44566e61SJonas Jelonek
116*44566e61SJonas Jelonek struct rtpse_mcu_port_measurement {
117*44566e61SJonas Jelonek u16 voltage_raw; /* 64.45mV/LSB */
118*44566e61SJonas Jelonek u16 current_raw; /* 1mA/LSB */
119*44566e61SJonas Jelonek u16 temperature_raw; /* T(mC) = 1250 * (220 - raw) */
120*44566e61SJonas Jelonek u16 power_raw; /* 100mW/LSB */
121*44566e61SJonas Jelonek };
122*44566e61SJonas Jelonek
123*44566e61SJonas Jelonek struct rtpse_mcu_port_config {
124*44566e61SJonas Jelonek bool enable;
125*44566e61SJonas Jelonek };
126*44566e61SJonas Jelonek
127*44566e61SJonas Jelonek struct rtpse_mcu_port_ext_config {
128*44566e61SJonas Jelonek u8 max_power;
129*44566e61SJonas Jelonek u8 priority;
130*44566e61SJonas Jelonek };
131*44566e61SJonas Jelonek
132*44566e61SJonas Jelonek struct rtpse_mcu_dialect {
133*44566e61SJonas Jelonek struct rtpse_mcu_opcode opcode[RTPSE_MCU_NUM_CMDS];
134*44566e61SJonas Jelonek
135*44566e61SJonas Jelonek /*
136*44566e61SJonas Jelonek * Response parsers for the fields that differ between dialects; each
137*44566e61SJonas Jelonek * dialect supplies its own. Other responses share one layout and are
138*44566e61SJonas Jelonek * decoded directly - a dialect that diverges there must add a hook,
139*44566e61SJonas Jelonek * as a mismatched layout cannot be detected (the checksum still passes).
140*44566e61SJonas Jelonek */
141*44566e61SJonas Jelonek void (*parse_system_info)(const u8 *payload, struct rtpse_mcu_info *info);
142*44566e61SJonas Jelonek int (*parse_port_class)(const struct rtpse_mcu_port_status *status);
143*44566e61SJonas Jelonek const char *(*mcu_type_str)(unsigned int mcu_type);
144*44566e61SJonas Jelonek };
145*44566e61SJonas Jelonek
146*44566e61SJonas Jelonek struct rtpse_mcu_chip_info {
147*44566e61SJonas Jelonek const char *name;
148*44566e61SJonas Jelonek u32 max_mW_per_port;
149*44566e61SJonas Jelonek enum rtpse_mcu_cmd pw_set_cmd; /* command used by set_pw_limit */
150*44566e61SJonas Jelonek u32 pw_set_lsb_mW; /* LSB of pw_set_cmd value, in mW */
151*44566e61SJonas Jelonek u32 pw_read_lsb_mW; /* LSB of ext_config.max_power read-back, in mW */
152*44566e61SJonas Jelonek };
153*44566e61SJonas Jelonek
154*44566e61SJonas Jelonek static const struct rtpse_mcu_chip_info rtl8238b_info = {
155*44566e61SJonas Jelonek .max_mW_per_port = 30000,
156*44566e61SJonas Jelonek .name = "RTL8238B",
157*44566e61SJonas Jelonek .pw_read_lsb_mW = 200,
158*44566e61SJonas Jelonek .pw_set_cmd = RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT,
159*44566e61SJonas Jelonek .pw_set_lsb_mW = 200,
160*44566e61SJonas Jelonek };
161*44566e61SJonas Jelonek
162*44566e61SJonas Jelonek static const struct rtpse_mcu_chip_info rtl8239_info = {
163*44566e61SJonas Jelonek .max_mW_per_port = 90000,
164*44566e61SJonas Jelonek .name = "RTL8239",
165*44566e61SJonas Jelonek .pw_read_lsb_mW = 400,
166*44566e61SJonas Jelonek .pw_set_cmd = RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_EXT,
167*44566e61SJonas Jelonek .pw_set_lsb_mW = 400,
168*44566e61SJonas Jelonek };
169*44566e61SJonas Jelonek
170*44566e61SJonas Jelonek static const struct rtpse_mcu_chip_info rtl8239c_info = {
171*44566e61SJonas Jelonek .max_mW_per_port = 90000,
172*44566e61SJonas Jelonek .name = "RTL8239C",
173*44566e61SJonas Jelonek .pw_read_lsb_mW = 400,
174*44566e61SJonas Jelonek .pw_set_cmd = RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_EXT,
175*44566e61SJonas Jelonek .pw_set_lsb_mW = 400,
176*44566e61SJonas Jelonek };
177*44566e61SJonas Jelonek
178*44566e61SJonas Jelonek static const struct rtpse_mcu_chip_info bcm59111_info = {
179*44566e61SJonas Jelonek .max_mW_per_port = 30000,
180*44566e61SJonas Jelonek .name = "BCM59111",
181*44566e61SJonas Jelonek .pw_read_lsb_mW = 200,
182*44566e61SJonas Jelonek .pw_set_cmd = RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT,
183*44566e61SJonas Jelonek .pw_set_lsb_mW = 200,
184*44566e61SJonas Jelonek };
185*44566e61SJonas Jelonek
186*44566e61SJonas Jelonek static const struct rtpse_mcu_chip_info bcm59121_info = {
187*44566e61SJonas Jelonek /*
188*44566e61SJonas Jelonek * BCM59121 is a 60W Type-3 part, but known boards run it at 802.3at
189*44566e61SJonas Jelonek * and the Gen1 dialect has only the 8-bit/0.2W set command (<=51W);
190*44566e61SJonas Jelonek * cap at the 30W the hardware actually offers.
191*44566e61SJonas Jelonek */
192*44566e61SJonas Jelonek .max_mW_per_port = 30000,
193*44566e61SJonas Jelonek .name = "BCM59121",
194*44566e61SJonas Jelonek .pw_read_lsb_mW = 200,
195*44566e61SJonas Jelonek .pw_set_cmd = RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT,
196*44566e61SJonas Jelonek .pw_set_lsb_mW = 200,
197*44566e61SJonas Jelonek };
198*44566e61SJonas Jelonek
199*44566e61SJonas Jelonek /* Helpers and basic functions */
200*44566e61SJonas Jelonek
to_rtpse_mcu_ctrl(struct pse_controller_dev * pcdev)201*44566e61SJonas Jelonek static struct rtpse_mcu_ctrl *to_rtpse_mcu_ctrl(struct pse_controller_dev *pcdev)
202*44566e61SJonas Jelonek {
203*44566e61SJonas Jelonek return container_of(pcdev, struct rtpse_mcu_ctrl, pcdev);
204*44566e61SJonas Jelonek }
205*44566e61SJonas Jelonek
rtpse_mcu_msg_init(struct rtpse_mcu_msg * msg,u8 opcode)206*44566e61SJonas Jelonek static void rtpse_mcu_msg_init(struct rtpse_mcu_msg *msg, u8 opcode)
207*44566e61SJonas Jelonek {
208*44566e61SJonas Jelonek memset(msg, 0xff, sizeof(*msg));
209*44566e61SJonas Jelonek msg->opcode = opcode;
210*44566e61SJonas Jelonek }
211*44566e61SJonas Jelonek
rtpse_mcu_checksum(const u8 * buf,size_t len)212*44566e61SJonas Jelonek static u8 rtpse_mcu_checksum(const u8 *buf, size_t len)
213*44566e61SJonas Jelonek {
214*44566e61SJonas Jelonek u8 sum = 0;
215*44566e61SJonas Jelonek
216*44566e61SJonas Jelonek while (len--)
217*44566e61SJonas Jelonek sum += *buf++;
218*44566e61SJonas Jelonek return sum;
219*44566e61SJonas Jelonek }
220*44566e61SJonas Jelonek
rtpse_mcu_do_xfer(struct rtpse_mcu_ctrl * pse,struct rtpse_mcu_msg * req,struct rtpse_mcu_msg * resp)221*44566e61SJonas Jelonek static int rtpse_mcu_do_xfer(struct rtpse_mcu_ctrl *pse, struct rtpse_mcu_msg *req,
222*44566e61SJonas Jelonek struct rtpse_mcu_msg *resp)
223*44566e61SJonas Jelonek {
224*44566e61SJonas Jelonek unsigned int tries;
225*44566e61SJonas Jelonek int ret;
226*44566e61SJonas Jelonek
227*44566e61SJonas Jelonek for (tries = 0; ; tries++) {
228*44566e61SJonas Jelonek scoped_guard(mutex, &pse->mutex) {
229*44566e61SJonas Jelonek /* Rolling seq_num (skip 0) so a stale/all-zero reply can't match. */
230*44566e61SJonas Jelonek if (++pse->seq == 0)
231*44566e61SJonas Jelonek pse->seq = 1;
232*44566e61SJonas Jelonek req->seq_num = pse->seq;
233*44566e61SJonas Jelonek req->checksum = rtpse_mcu_checksum((u8 *)req, RTPSE_MCU_MSG_SIZE - 1);
234*44566e61SJonas Jelonek
235*44566e61SJonas Jelonek ret = pse->transport->send(pse, req);
236*44566e61SJonas Jelonek if (ret)
237*44566e61SJonas Jelonek return ret;
238*44566e61SJonas Jelonek
239*44566e61SJonas Jelonek /* Pace the base reply delay; the transport waits its own way. */
240*44566e61SJonas Jelonek msleep(RTPSE_MCU_RESPONSE_MS);
241*44566e61SJonas Jelonek
242*44566e61SJonas Jelonek memset(resp, 0, sizeof(*resp));
243*44566e61SJonas Jelonek ret = pse->transport->recv(pse, req, resp);
244*44566e61SJonas Jelonek if (ret)
245*44566e61SJonas Jelonek return ret;
246*44566e61SJonas Jelonek }
247*44566e61SJonas Jelonek
248*44566e61SJonas Jelonek /* NOT_READY: MCU busy, wants the command resent; bounded retry. */
249*44566e61SJonas Jelonek if (resp->opcode != RTPSE_MCU_OPCODE_NOT_READY ||
250*44566e61SJonas Jelonek tries >= RTPSE_MCU_NOT_READY_RETRIES)
251*44566e61SJonas Jelonek break;
252*44566e61SJonas Jelonek msleep(RTPSE_MCU_RESPONSE_MS);
253*44566e61SJonas Jelonek }
254*44566e61SJonas Jelonek
255*44566e61SJonas Jelonek /* Explicit MCU error opcodes (Gen1); map to a meaningful errno. */
256*44566e61SJonas Jelonek switch (resp->opcode) {
257*44566e61SJonas Jelonek case RTPSE_MCU_OPCODE_INCOMPLETE:
258*44566e61SJonas Jelonek return -EBADE;
259*44566e61SJonas Jelonek case RTPSE_MCU_OPCODE_BAD_CSUM:
260*44566e61SJonas Jelonek return -EBADMSG;
261*44566e61SJonas Jelonek case RTPSE_MCU_OPCODE_NOT_READY:
262*44566e61SJonas Jelonek return -EAGAIN;
263*44566e61SJonas Jelonek }
264*44566e61SJonas Jelonek
265*44566e61SJonas Jelonek if (resp->opcode != req->opcode ||
266*44566e61SJonas Jelonek resp->seq_num != req->seq_num ||
267*44566e61SJonas Jelonek resp->checksum != rtpse_mcu_checksum((u8 *)resp, RTPSE_MCU_MSG_SIZE - 1))
268*44566e61SJonas Jelonek return -EBADMSG;
269*44566e61SJonas Jelonek
270*44566e61SJonas Jelonek return 0;
271*44566e61SJonas Jelonek }
272*44566e61SJonas Jelonek
rtpse_mcu_port_query(struct rtpse_mcu_ctrl * pse,unsigned int port,u8 opcode,struct rtpse_mcu_msg * resp)273*44566e61SJonas Jelonek static int rtpse_mcu_port_query(struct rtpse_mcu_ctrl *pse, unsigned int port, u8 opcode,
274*44566e61SJonas Jelonek struct rtpse_mcu_msg *resp)
275*44566e61SJonas Jelonek {
276*44566e61SJonas Jelonek struct rtpse_mcu_msg req;
277*44566e61SJonas Jelonek int ret;
278*44566e61SJonas Jelonek
279*44566e61SJonas Jelonek rtpse_mcu_msg_init(&req, opcode);
280*44566e61SJonas Jelonek req.payload[0] = port;
281*44566e61SJonas Jelonek
282*44566e61SJonas Jelonek ret = rtpse_mcu_do_xfer(pse, &req, resp);
283*44566e61SJonas Jelonek if (ret)
284*44566e61SJonas Jelonek return ret;
285*44566e61SJonas Jelonek
286*44566e61SJonas Jelonek if (resp->payload[0] != port)
287*44566e61SJonas Jelonek return -EIO;
288*44566e61SJonas Jelonek
289*44566e61SJonas Jelonek return 0;
290*44566e61SJonas Jelonek }
291*44566e61SJonas Jelonek
rtpse_mcu_port_cmd(struct rtpse_mcu_ctrl * pse,unsigned int port,u8 opcode,u8 arg)292*44566e61SJonas Jelonek static int rtpse_mcu_port_cmd(struct rtpse_mcu_ctrl *pse, unsigned int port, u8 opcode, u8 arg)
293*44566e61SJonas Jelonek {
294*44566e61SJonas Jelonek struct rtpse_mcu_msg req, resp;
295*44566e61SJonas Jelonek int ret;
296*44566e61SJonas Jelonek
297*44566e61SJonas Jelonek rtpse_mcu_msg_init(&req, opcode);
298*44566e61SJonas Jelonek req.payload[0] = port;
299*44566e61SJonas Jelonek req.payload[1] = arg;
300*44566e61SJonas Jelonek
301*44566e61SJonas Jelonek ret = rtpse_mcu_do_xfer(pse, &req, &resp);
302*44566e61SJonas Jelonek if (ret)
303*44566e61SJonas Jelonek return ret;
304*44566e61SJonas Jelonek
305*44566e61SJonas Jelonek if (resp.payload[0] != port || resp.payload[1] != 0)
306*44566e61SJonas Jelonek return -EIO;
307*44566e61SJonas Jelonek
308*44566e61SJonas Jelonek return 0;
309*44566e61SJonas Jelonek }
310*44566e61SJonas Jelonek
311*44566e61SJonas Jelonek /* Global operations */
312*44566e61SJonas Jelonek
rtpse_mcu_get_info(struct rtpse_mcu_ctrl * pse,struct rtpse_mcu_info * info)313*44566e61SJonas Jelonek static int rtpse_mcu_get_info(struct rtpse_mcu_ctrl *pse, struct rtpse_mcu_info *info)
314*44566e61SJonas Jelonek {
315*44566e61SJonas Jelonek struct rtpse_mcu_msg req, resp;
316*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
317*44566e61SJonas Jelonek int ret;
318*44566e61SJonas Jelonek
319*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_GET_SYSTEM_INFO];
320*44566e61SJonas Jelonek if (!opc->valid)
321*44566e61SJonas Jelonek return -EOPNOTSUPP;
322*44566e61SJonas Jelonek
323*44566e61SJonas Jelonek rtpse_mcu_msg_init(&req, opc->op);
324*44566e61SJonas Jelonek ret = rtpse_mcu_do_xfer(pse, &req, &resp);
325*44566e61SJonas Jelonek if (ret)
326*44566e61SJonas Jelonek return ret;
327*44566e61SJonas Jelonek
328*44566e61SJonas Jelonek pse->dialect->parse_system_info(resp.payload, info);
329*44566e61SJonas Jelonek return 0;
330*44566e61SJonas Jelonek }
331*44566e61SJonas Jelonek
rtpse_mcu_get_ext_config(struct rtpse_mcu_ctrl * pse,struct rtpse_mcu_ext_config * config)332*44566e61SJonas Jelonek static int rtpse_mcu_get_ext_config(struct rtpse_mcu_ctrl *pse, struct rtpse_mcu_ext_config *config)
333*44566e61SJonas Jelonek {
334*44566e61SJonas Jelonek struct rtpse_mcu_msg req, resp;
335*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
336*44566e61SJonas Jelonek int ret;
337*44566e61SJonas Jelonek
338*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_GET_EXT_CONFIG];
339*44566e61SJonas Jelonek if (!opc->valid)
340*44566e61SJonas Jelonek return -EOPNOTSUPP;
341*44566e61SJonas Jelonek
342*44566e61SJonas Jelonek rtpse_mcu_msg_init(&req, opc->op);
343*44566e61SJonas Jelonek ret = rtpse_mcu_do_xfer(pse, &req, &resp);
344*44566e61SJonas Jelonek if (ret)
345*44566e61SJonas Jelonek return ret;
346*44566e61SJonas Jelonek
347*44566e61SJonas Jelonek config->num_of_pses = resp.payload[6];
348*44566e61SJonas Jelonek
349*44566e61SJonas Jelonek return 0;
350*44566e61SJonas Jelonek }
351*44566e61SJonas Jelonek
rtpse_mcu_set_global_state(struct rtpse_mcu_ctrl * pse,bool enable)352*44566e61SJonas Jelonek static int rtpse_mcu_set_global_state(struct rtpse_mcu_ctrl *pse, bool enable)
353*44566e61SJonas Jelonek {
354*44566e61SJonas Jelonek struct rtpse_mcu_msg req, resp;
355*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
356*44566e61SJonas Jelonek int ret;
357*44566e61SJonas Jelonek
358*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_SET_GLOBAL_STATE];
359*44566e61SJonas Jelonek if (!opc->valid)
360*44566e61SJonas Jelonek return -EOPNOTSUPP;
361*44566e61SJonas Jelonek
362*44566e61SJonas Jelonek rtpse_mcu_msg_init(&req, opc->op);
363*44566e61SJonas Jelonek req.payload[0] = enable ? 0x1 : 0x0;
364*44566e61SJonas Jelonek
365*44566e61SJonas Jelonek ret = rtpse_mcu_do_xfer(pse, &req, &resp);
366*44566e61SJonas Jelonek if (ret)
367*44566e61SJonas Jelonek return ret;
368*44566e61SJonas Jelonek
369*44566e61SJonas Jelonek return (resp.payload[0] == 0x0) ? 0 : -EIO;
370*44566e61SJonas Jelonek }
371*44566e61SJonas Jelonek
372*44566e61SJonas Jelonek /* Port operations */
373*44566e61SJonas Jelonek
rtpse_mcu_port_get_status(struct rtpse_mcu_ctrl * pse,unsigned int port,struct rtpse_mcu_port_status * status)374*44566e61SJonas Jelonek static int rtpse_mcu_port_get_status(struct rtpse_mcu_ctrl *pse, unsigned int port,
375*44566e61SJonas Jelonek struct rtpse_mcu_port_status *status)
376*44566e61SJonas Jelonek {
377*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
378*44566e61SJonas Jelonek struct rtpse_mcu_msg resp;
379*44566e61SJonas Jelonek int ret;
380*44566e61SJonas Jelonek
381*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_GET_STATUS];
382*44566e61SJonas Jelonek if (!opc->valid)
383*44566e61SJonas Jelonek return -EOPNOTSUPP;
384*44566e61SJonas Jelonek
385*44566e61SJonas Jelonek ret = rtpse_mcu_port_query(pse, port, opc->op, &resp);
386*44566e61SJonas Jelonek if (ret)
387*44566e61SJonas Jelonek return ret;
388*44566e61SJonas Jelonek
389*44566e61SJonas Jelonek status->sts1 = resp.payload[1];
390*44566e61SJonas Jelonek status->sts2 = resp.payload[2];
391*44566e61SJonas Jelonek status->sts3 = resp.payload[3];
392*44566e61SJonas Jelonek
393*44566e61SJonas Jelonek return 0;
394*44566e61SJonas Jelonek }
395*44566e61SJonas Jelonek
rtpse_mcu_port_get_measurement(struct rtpse_mcu_ctrl * pse,unsigned int port,struct rtpse_mcu_port_measurement * measurement)396*44566e61SJonas Jelonek static int rtpse_mcu_port_get_measurement(struct rtpse_mcu_ctrl *pse, unsigned int port,
397*44566e61SJonas Jelonek struct rtpse_mcu_port_measurement *measurement)
398*44566e61SJonas Jelonek {
399*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
400*44566e61SJonas Jelonek struct rtpse_mcu_msg resp;
401*44566e61SJonas Jelonek int ret;
402*44566e61SJonas Jelonek
403*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_GET_POWER_STATS];
404*44566e61SJonas Jelonek if (!opc->valid)
405*44566e61SJonas Jelonek return -EOPNOTSUPP;
406*44566e61SJonas Jelonek
407*44566e61SJonas Jelonek ret = rtpse_mcu_port_query(pse, port, opc->op, &resp);
408*44566e61SJonas Jelonek if (ret)
409*44566e61SJonas Jelonek return ret;
410*44566e61SJonas Jelonek
411*44566e61SJonas Jelonek measurement->voltage_raw = get_unaligned_be16(&resp.payload[1]);
412*44566e61SJonas Jelonek measurement->current_raw = get_unaligned_be16(&resp.payload[3]);
413*44566e61SJonas Jelonek measurement->temperature_raw = get_unaligned_be16(&resp.payload[5]);
414*44566e61SJonas Jelonek measurement->power_raw = get_unaligned_be16(&resp.payload[7]);
415*44566e61SJonas Jelonek
416*44566e61SJonas Jelonek return 0;
417*44566e61SJonas Jelonek }
418*44566e61SJonas Jelonek
rtpse_mcu_port_get_config(struct rtpse_mcu_ctrl * pse,unsigned int port,struct rtpse_mcu_port_config * config)419*44566e61SJonas Jelonek static int rtpse_mcu_port_get_config(struct rtpse_mcu_ctrl *pse, unsigned int port,
420*44566e61SJonas Jelonek struct rtpse_mcu_port_config *config)
421*44566e61SJonas Jelonek {
422*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
423*44566e61SJonas Jelonek struct rtpse_mcu_msg resp;
424*44566e61SJonas Jelonek int ret;
425*44566e61SJonas Jelonek
426*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_GET_CONFIG];
427*44566e61SJonas Jelonek if (!opc->valid)
428*44566e61SJonas Jelonek return -EOPNOTSUPP;
429*44566e61SJonas Jelonek
430*44566e61SJonas Jelonek ret = rtpse_mcu_port_query(pse, port, opc->op, &resp);
431*44566e61SJonas Jelonek if (ret)
432*44566e61SJonas Jelonek return ret;
433*44566e61SJonas Jelonek
434*44566e61SJonas Jelonek config->enable = (resp.payload[1] == 1);
435*44566e61SJonas Jelonek
436*44566e61SJonas Jelonek return 0;
437*44566e61SJonas Jelonek }
438*44566e61SJonas Jelonek
rtpse_mcu_port_get_ext_config(struct rtpse_mcu_ctrl * pse,unsigned int port,struct rtpse_mcu_port_ext_config * config)439*44566e61SJonas Jelonek static int rtpse_mcu_port_get_ext_config(struct rtpse_mcu_ctrl *pse, unsigned int port,
440*44566e61SJonas Jelonek struct rtpse_mcu_port_ext_config *config)
441*44566e61SJonas Jelonek {
442*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
443*44566e61SJonas Jelonek struct rtpse_mcu_msg resp;
444*44566e61SJonas Jelonek int ret;
445*44566e61SJonas Jelonek
446*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_GET_EXT_CONFIG];
447*44566e61SJonas Jelonek if (!opc->valid)
448*44566e61SJonas Jelonek return -EOPNOTSUPP;
449*44566e61SJonas Jelonek
450*44566e61SJonas Jelonek ret = rtpse_mcu_port_query(pse, port, opc->op, &resp);
451*44566e61SJonas Jelonek if (ret)
452*44566e61SJonas Jelonek return ret;
453*44566e61SJonas Jelonek
454*44566e61SJonas Jelonek config->max_power = resp.payload[3];
455*44566e61SJonas Jelonek config->priority = resp.payload[4];
456*44566e61SJonas Jelonek
457*44566e61SJonas Jelonek return 0;
458*44566e61SJonas Jelonek }
459*44566e61SJonas Jelonek
rtpse_mcu_port_set_state(struct rtpse_mcu_ctrl * pse,unsigned int port,bool enable)460*44566e61SJonas Jelonek static int rtpse_mcu_port_set_state(struct rtpse_mcu_ctrl *pse, unsigned int port, bool enable)
461*44566e61SJonas Jelonek {
462*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
463*44566e61SJonas Jelonek
464*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_ENABLE];
465*44566e61SJonas Jelonek if (!opc->valid)
466*44566e61SJonas Jelonek return -EOPNOTSUPP;
467*44566e61SJonas Jelonek
468*44566e61SJonas Jelonek return rtpse_mcu_port_cmd(pse, port, opc->op, enable ? 0x1 : 0x0);
469*44566e61SJonas Jelonek }
470*44566e61SJonas Jelonek
471*44566e61SJonas Jelonek /* PSE controller ops */
472*44566e61SJonas Jelonek
rtpse_mcu_port_get_admin_state(struct pse_controller_dev * pcdev,int id,struct pse_admin_state * admin_state)473*44566e61SJonas Jelonek static int rtpse_mcu_port_get_admin_state(struct pse_controller_dev *pcdev, int id,
474*44566e61SJonas Jelonek struct pse_admin_state *admin_state)
475*44566e61SJonas Jelonek {
476*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
477*44566e61SJonas Jelonek struct rtpse_mcu_port_config config;
478*44566e61SJonas Jelonek int ret;
479*44566e61SJonas Jelonek
480*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_config(pse, id, &config);
481*44566e61SJonas Jelonek if (ret)
482*44566e61SJonas Jelonek return ret;
483*44566e61SJonas Jelonek
484*44566e61SJonas Jelonek admin_state->c33_admin_state = config.enable ? ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED :
485*44566e61SJonas Jelonek ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
486*44566e61SJonas Jelonek return 0;
487*44566e61SJonas Jelonek }
488*44566e61SJonas Jelonek
rtpse_mcu_port_get_pw_status(struct pse_controller_dev * pcdev,int id,struct pse_pw_status * pw_status)489*44566e61SJonas Jelonek static int rtpse_mcu_port_get_pw_status(struct pse_controller_dev *pcdev, int id,
490*44566e61SJonas Jelonek struct pse_pw_status *pw_status)
491*44566e61SJonas Jelonek {
492*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
493*44566e61SJonas Jelonek struct rtpse_mcu_port_status status;
494*44566e61SJonas Jelonek int ret;
495*44566e61SJonas Jelonek
496*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_status(pse, id, &status);
497*44566e61SJonas Jelonek if (ret)
498*44566e61SJonas Jelonek return ret;
499*44566e61SJonas Jelonek
500*44566e61SJonas Jelonek switch (status.sts1) {
501*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_DISABLED:
502*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
503*44566e61SJonas Jelonek break;
504*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_SEARCHING:
505*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_REQUESTING:
506*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
507*44566e61SJonas Jelonek break;
508*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_DELIVERING:
509*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
510*44566e61SJonas Jelonek break;
511*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_TEST:
512*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_TEST;
513*44566e61SJonas Jelonek break;
514*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_FAULT:
515*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
516*44566e61SJonas Jelonek break;
517*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_OTHER_FAULT:
518*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT;
519*44566e61SJonas Jelonek break;
520*44566e61SJonas Jelonek default:
521*44566e61SJonas Jelonek pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_UNKNOWN;
522*44566e61SJonas Jelonek break;
523*44566e61SJonas Jelonek }
524*44566e61SJonas Jelonek
525*44566e61SJonas Jelonek return 0;
526*44566e61SJonas Jelonek }
527*44566e61SJonas Jelonek
rtpse_mcu_port_get_pw_class(struct pse_controller_dev * pcdev,int id)528*44566e61SJonas Jelonek static int rtpse_mcu_port_get_pw_class(struct pse_controller_dev *pcdev, int id)
529*44566e61SJonas Jelonek {
530*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
531*44566e61SJonas Jelonek struct rtpse_mcu_port_status status;
532*44566e61SJonas Jelonek int ret;
533*44566e61SJonas Jelonek
534*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_status(pse, id, &status);
535*44566e61SJonas Jelonek if (ret)
536*44566e61SJonas Jelonek return ret;
537*44566e61SJonas Jelonek
538*44566e61SJonas Jelonek /*
539*44566e61SJonas Jelonek * As per datasheet, the classification result is only valid when in
540*44566e61SJonas Jelonek * one of those operational modes, otherwise not.
541*44566e61SJonas Jelonek */
542*44566e61SJonas Jelonek switch (status.sts1) {
543*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_DISABLED:
544*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_SEARCHING:
545*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_DELIVERING:
546*44566e61SJonas Jelonek case RTPSE_MCU_PORT_STS_REQUESTING:
547*44566e61SJonas Jelonek return pse->dialect->parse_port_class(&status);
548*44566e61SJonas Jelonek default:
549*44566e61SJonas Jelonek /*
550*44566e61SJonas Jelonek * No class to report, return 0 instead. This is indistinguishable
551*44566e61SJonas Jelonek * from a real class-0 PD but userspace disambiguates via the
552*44566e61SJonas Jelonek * power status.
553*44566e61SJonas Jelonek */
554*44566e61SJonas Jelonek return 0;
555*44566e61SJonas Jelonek }
556*44566e61SJonas Jelonek }
557*44566e61SJonas Jelonek
rtpse_mcu_port_get_actual_pw(struct pse_controller_dev * pcdev,int id)558*44566e61SJonas Jelonek static int rtpse_mcu_port_get_actual_pw(struct pse_controller_dev *pcdev, int id)
559*44566e61SJonas Jelonek {
560*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
561*44566e61SJonas Jelonek struct rtpse_mcu_port_measurement measurement;
562*44566e61SJonas Jelonek int ret;
563*44566e61SJonas Jelonek
564*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_measurement(pse, id, &measurement);
565*44566e61SJonas Jelonek if (ret)
566*44566e61SJonas Jelonek return ret;
567*44566e61SJonas Jelonek
568*44566e61SJonas Jelonek /* 100mW per LSB */
569*44566e61SJonas Jelonek return measurement.power_raw * 100U;
570*44566e61SJonas Jelonek }
571*44566e61SJonas Jelonek
rtpse_mcu_port_get_voltage(struct pse_controller_dev * pcdev,int id)572*44566e61SJonas Jelonek static int rtpse_mcu_port_get_voltage(struct pse_controller_dev *pcdev, int id)
573*44566e61SJonas Jelonek {
574*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
575*44566e61SJonas Jelonek struct rtpse_mcu_port_measurement measurement;
576*44566e61SJonas Jelonek int ret;
577*44566e61SJonas Jelonek u32 uV;
578*44566e61SJonas Jelonek
579*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_measurement(pse, id, &measurement);
580*44566e61SJonas Jelonek if (ret)
581*44566e61SJonas Jelonek return ret;
582*44566e61SJonas Jelonek
583*44566e61SJonas Jelonek /* 64.45mV per LSB */
584*44566e61SJonas Jelonek uV = measurement.voltage_raw * 64450U;
585*44566e61SJonas Jelonek
586*44566e61SJonas Jelonek /*
587*44566e61SJonas Jelonek * Idle ports measure 0V, which the core rejects when turning a power
588*44566e61SJonas Jelonek * limit into a current limit. Fall back to the nominal rail so a limit
589*44566e61SJonas Jelonek * can be set before a PD is attached.
590*44566e61SJonas Jelonek */
591*44566e61SJonas Jelonek if (!uV)
592*44566e61SJonas Jelonek return RTPSE_MCU_PSE_VOLTAGE_UV;
593*44566e61SJonas Jelonek
594*44566e61SJonas Jelonek return min_t(u32, uV, INT_MAX);
595*44566e61SJonas Jelonek }
596*44566e61SJonas Jelonek
rtpse_mcu_port_enable(struct pse_controller_dev * pcdev,int id)597*44566e61SJonas Jelonek static int rtpse_mcu_port_enable(struct pse_controller_dev *pcdev, int id)
598*44566e61SJonas Jelonek {
599*44566e61SJonas Jelonek return rtpse_mcu_port_set_state(to_rtpse_mcu_ctrl(pcdev), id, true);
600*44566e61SJonas Jelonek }
601*44566e61SJonas Jelonek
rtpse_mcu_port_disable(struct pse_controller_dev * pcdev,int id)602*44566e61SJonas Jelonek static int rtpse_mcu_port_disable(struct pse_controller_dev *pcdev, int id)
603*44566e61SJonas Jelonek {
604*44566e61SJonas Jelonek return rtpse_mcu_port_set_state(to_rtpse_mcu_ctrl(pcdev), id, false);
605*44566e61SJonas Jelonek }
606*44566e61SJonas Jelonek
rtpse_mcu_port_get_pw_limit(struct pse_controller_dev * pcdev,int id)607*44566e61SJonas Jelonek static int rtpse_mcu_port_get_pw_limit(struct pse_controller_dev *pcdev, int id)
608*44566e61SJonas Jelonek {
609*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
610*44566e61SJonas Jelonek struct rtpse_mcu_port_ext_config config;
611*44566e61SJonas Jelonek int ret;
612*44566e61SJonas Jelonek
613*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_ext_config(pse, id, &config);
614*44566e61SJonas Jelonek if (ret)
615*44566e61SJonas Jelonek return ret;
616*44566e61SJonas Jelonek
617*44566e61SJonas Jelonek /*
618*44566e61SJonas Jelonek * The MCU's raw max_power byte can scale above the chip's rated cap;
619*44566e61SJonas Jelonek * clamp to the same bound set_pw_limit() and the advertised range use.
620*44566e61SJonas Jelonek */
621*44566e61SJonas Jelonek return min_t(u32, config.max_power * pse->chip->pw_read_lsb_mW,
622*44566e61SJonas Jelonek pse->chip->max_mW_per_port);
623*44566e61SJonas Jelonek }
624*44566e61SJonas Jelonek
rtpse_mcu_port_set_pw_limit(struct pse_controller_dev * pcdev,int id,int max_mW)625*44566e61SJonas Jelonek static int rtpse_mcu_port_set_pw_limit(struct pse_controller_dev *pcdev, int id, int max_mW)
626*44566e61SJonas Jelonek {
627*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *type_opc, *val_opc;
628*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
629*44566e61SJonas Jelonek const struct rtpse_mcu_chip_info *chip = pse->chip;
630*44566e61SJonas Jelonek u8 prg_val;
631*44566e61SJonas Jelonek int ret;
632*44566e61SJonas Jelonek
633*44566e61SJonas Jelonek if (max_mW < 0 || max_mW > chip->max_mW_per_port)
634*44566e61SJonas Jelonek return -ERANGE;
635*44566e61SJonas Jelonek
636*44566e61SJonas Jelonek type_opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE];
637*44566e61SJonas Jelonek val_opc = &pse->dialect->opcode[chip->pw_set_cmd];
638*44566e61SJonas Jelonek /* pw_set_lsb_mW is the divisor below; reject a chip that lacks it. */
639*44566e61SJonas Jelonek if (!type_opc->valid || !val_opc->valid || !chip->pw_set_lsb_mW)
640*44566e61SJonas Jelonek return -EOPNOTSUPP;
641*44566e61SJonas Jelonek
642*44566e61SJonas Jelonek /*
643*44566e61SJonas Jelonek * Round up so a sub-LSB request maps to one LSB, not silently to 0;
644*44566e61SJonas Jelonek * an explicit 0 still yields 0, and LSB-aligned maxima can't overshoot.
645*44566e61SJonas Jelonek */
646*44566e61SJonas Jelonek prg_val = min_t(unsigned int, DIV_ROUND_UP(max_mW, chip->pw_set_lsb_mW), U8_MAX);
647*44566e61SJonas Jelonek
648*44566e61SJonas Jelonek /*
649*44566e61SJonas Jelonek * Program the value before switching to user-defined mode. The two
650*44566e61SJonas Jelonek * commands aren't atomic, but this order never leaves a stale cap: a
651*44566e61SJonas Jelonek * failure keeps the previous cap, or (already user mode) the requested.
652*44566e61SJonas Jelonek */
653*44566e61SJonas Jelonek ret = rtpse_mcu_port_cmd(pse, id, val_opc->op, prg_val);
654*44566e61SJonas Jelonek if (ret)
655*44566e61SJonas Jelonek return ret;
656*44566e61SJonas Jelonek
657*44566e61SJonas Jelonek return rtpse_mcu_port_cmd(pse, id, type_opc->op, RTPSE_MCU_PORT_PW_LIMIT_TYPE_USER);
658*44566e61SJonas Jelonek }
659*44566e61SJonas Jelonek
rtpse_mcu_port_get_pw_limit_ranges(struct pse_controller_dev * pcdev,int id,struct pse_pw_limit_ranges * out)660*44566e61SJonas Jelonek static int rtpse_mcu_port_get_pw_limit_ranges(struct pse_controller_dev *pcdev, int id,
661*44566e61SJonas Jelonek struct pse_pw_limit_ranges *out)
662*44566e61SJonas Jelonek {
663*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
664*44566e61SJonas Jelonek struct ethtool_c33_pse_pw_limit_range *range;
665*44566e61SJonas Jelonek
666*44566e61SJonas Jelonek range = kzalloc_obj(*range);
667*44566e61SJonas Jelonek if (!range)
668*44566e61SJonas Jelonek return -ENOMEM;
669*44566e61SJonas Jelonek
670*44566e61SJonas Jelonek range[0].min = 0;
671*44566e61SJonas Jelonek range[0].max = pse->chip->max_mW_per_port;
672*44566e61SJonas Jelonek
673*44566e61SJonas Jelonek out->c33_pw_limit_ranges = range;
674*44566e61SJonas Jelonek return 1;
675*44566e61SJonas Jelonek }
676*44566e61SJonas Jelonek
rtpse_mcu_port_get_prio(struct pse_controller_dev * pcdev,int id)677*44566e61SJonas Jelonek static int rtpse_mcu_port_get_prio(struct pse_controller_dev *pcdev, int id)
678*44566e61SJonas Jelonek {
679*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
680*44566e61SJonas Jelonek struct rtpse_mcu_port_ext_config config;
681*44566e61SJonas Jelonek int ret;
682*44566e61SJonas Jelonek
683*44566e61SJonas Jelonek ret = rtpse_mcu_port_get_ext_config(pse, id, &config);
684*44566e61SJonas Jelonek if (ret)
685*44566e61SJonas Jelonek return ret;
686*44566e61SJonas Jelonek
687*44566e61SJonas Jelonek /* Clamp to the advertised max; set_prio() and pis_prio_max use the same bound. */
688*44566e61SJonas Jelonek return min_t(u8, config.priority, RTPSE_MCU_PORT_MAX_PRIORITY);
689*44566e61SJonas Jelonek }
690*44566e61SJonas Jelonek
rtpse_mcu_port_set_prio(struct pse_controller_dev * pcdev,int id,unsigned int prio)691*44566e61SJonas Jelonek static int rtpse_mcu_port_set_prio(struct pse_controller_dev *pcdev, int id, unsigned int prio)
692*44566e61SJonas Jelonek {
693*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = to_rtpse_mcu_ctrl(pcdev);
694*44566e61SJonas Jelonek const struct rtpse_mcu_opcode *opc;
695*44566e61SJonas Jelonek
696*44566e61SJonas Jelonek if (prio > RTPSE_MCU_PORT_MAX_PRIORITY)
697*44566e61SJonas Jelonek return -ERANGE;
698*44566e61SJonas Jelonek
699*44566e61SJonas Jelonek opc = &pse->dialect->opcode[RTPSE_MCU_CMD_PORT_SET_PRIORITY];
700*44566e61SJonas Jelonek if (!opc->valid)
701*44566e61SJonas Jelonek return -EOPNOTSUPP;
702*44566e61SJonas Jelonek
703*44566e61SJonas Jelonek return rtpse_mcu_port_cmd(pse, id, opc->op, prio);
704*44566e61SJonas Jelonek }
705*44566e61SJonas Jelonek
706*44566e61SJonas Jelonek static const struct pse_controller_ops rtpse_mcu_ops = {
707*44566e61SJonas Jelonek .pi_get_admin_state = rtpse_mcu_port_get_admin_state,
708*44566e61SJonas Jelonek .pi_get_pw_status = rtpse_mcu_port_get_pw_status,
709*44566e61SJonas Jelonek .pi_get_pw_class = rtpse_mcu_port_get_pw_class,
710*44566e61SJonas Jelonek .pi_get_actual_pw = rtpse_mcu_port_get_actual_pw,
711*44566e61SJonas Jelonek .pi_enable = rtpse_mcu_port_enable,
712*44566e61SJonas Jelonek .pi_disable = rtpse_mcu_port_disable,
713*44566e61SJonas Jelonek .pi_get_voltage = rtpse_mcu_port_get_voltage,
714*44566e61SJonas Jelonek .pi_get_pw_limit = rtpse_mcu_port_get_pw_limit,
715*44566e61SJonas Jelonek .pi_set_pw_limit = rtpse_mcu_port_set_pw_limit,
716*44566e61SJonas Jelonek .pi_get_pw_limit_ranges = rtpse_mcu_port_get_pw_limit_ranges,
717*44566e61SJonas Jelonek .pi_get_prio = rtpse_mcu_port_get_prio,
718*44566e61SJonas Jelonek .pi_set_prio = rtpse_mcu_port_set_prio,
719*44566e61SJonas Jelonek };
720*44566e61SJonas Jelonek
rtpse_mcu_discover(struct rtpse_mcu_ctrl * pse,struct rtpse_mcu_info * info)721*44566e61SJonas Jelonek static int rtpse_mcu_discover(struct rtpse_mcu_ctrl *pse, struct rtpse_mcu_info *info)
722*44566e61SJonas Jelonek {
723*44566e61SJonas Jelonek struct rtpse_mcu_ext_config ext_config;
724*44566e61SJonas Jelonek unsigned long deadline;
725*44566e61SJonas Jelonek int ret;
726*44566e61SJonas Jelonek
727*44566e61SJonas Jelonek /*
728*44566e61SJonas Jelonek * A booting MCU may stay silent (-ETIMEDOUT), not ACK its address
729*44566e61SJonas Jelonek * (-ENXIO / -EREMOTEIO), report not-ready (-EAGAIN), or emit a
730*44566e61SJonas Jelonek * corrupt/partial frame (-EBADMSG / -EBADE). Retry those within a
731*44566e61SJonas Jelonek * bounded window; other errors (e.g. -EOPNOTSUPP) are fatal and fail
732*44566e61SJonas Jelonek * immediately.
733*44566e61SJonas Jelonek */
734*44566e61SJonas Jelonek deadline = jiffies + msecs_to_jiffies(RTPSE_MCU_BOOT_TIMEOUT_MS);
735*44566e61SJonas Jelonek do {
736*44566e61SJonas Jelonek ret = rtpse_mcu_get_info(pse, info);
737*44566e61SJonas Jelonek if (ret != -ETIMEDOUT && ret != -ENXIO && ret != -EREMOTEIO &&
738*44566e61SJonas Jelonek ret != -EAGAIN && ret != -EBADMSG && ret != -EBADE)
739*44566e61SJonas Jelonek break;
740*44566e61SJonas Jelonek msleep(RTPSE_MCU_BOOT_RETRY_MS);
741*44566e61SJonas Jelonek } while (time_before(jiffies, deadline));
742*44566e61SJonas Jelonek if (ret)
743*44566e61SJonas Jelonek return dev_err_probe(pse->dev, ret, "failed to read MCU info\n");
744*44566e61SJonas Jelonek
745*44566e61SJonas Jelonek switch (info->device_id) {
746*44566e61SJonas Jelonek case RTPSE_MCU_DEVICE_ID_RTL8238B:
747*44566e61SJonas Jelonek pse->chip = &rtl8238b_info;
748*44566e61SJonas Jelonek break;
749*44566e61SJonas Jelonek case RTPSE_MCU_DEVICE_ID_RTL8239:
750*44566e61SJonas Jelonek pse->chip = &rtl8239_info;
751*44566e61SJonas Jelonek break;
752*44566e61SJonas Jelonek case RTPSE_MCU_DEVICE_ID_RTL8239C:
753*44566e61SJonas Jelonek pse->chip = &rtl8239c_info;
754*44566e61SJonas Jelonek break;
755*44566e61SJonas Jelonek case RTPSE_MCU_DEVICE_ID_BCM59111:
756*44566e61SJonas Jelonek pse->chip = &bcm59111_info;
757*44566e61SJonas Jelonek break;
758*44566e61SJonas Jelonek case RTPSE_MCU_DEVICE_ID_BCM59121:
759*44566e61SJonas Jelonek pse->chip = &bcm59121_info;
760*44566e61SJonas Jelonek break;
761*44566e61SJonas Jelonek default:
762*44566e61SJonas Jelonek return dev_err_probe(pse->dev, -EINVAL, "unknown PSE id 0x%x\n",
763*44566e61SJonas Jelonek info->device_id);
764*44566e61SJonas Jelonek }
765*44566e61SJonas Jelonek
766*44566e61SJonas Jelonek if (!info->max_ports || info->max_ports > RTPSE_MCU_MAX_PORTS)
767*44566e61SJonas Jelonek return dev_err_probe(pse->dev, -EINVAL,
768*44566e61SJonas Jelonek "MCU reports invalid port count %u\n", info->max_ports);
769*44566e61SJonas Jelonek
770*44566e61SJonas Jelonek ret = rtpse_mcu_get_ext_config(pse, &ext_config);
771*44566e61SJonas Jelonek if (ret)
772*44566e61SJonas Jelonek return dev_err_probe(pse->dev, ret, "failed to read MCU ext config\n");
773*44566e61SJonas Jelonek
774*44566e61SJonas Jelonek dev_info(pse->dev, "%s MCU, %s (id 0x%04x), %u ports across %u PSE chip(s)\n",
775*44566e61SJonas Jelonek pse->dialect->mcu_type_str(info->mcu_type), pse->chip->name,
776*44566e61SJonas Jelonek info->device_id, info->max_ports, ext_config.num_of_pses);
777*44566e61SJonas Jelonek return 0;
778*44566e61SJonas Jelonek }
779*44566e61SJonas Jelonek
rtpse_mcu_global_disable(void * data)780*44566e61SJonas Jelonek static void rtpse_mcu_global_disable(void *data)
781*44566e61SJonas Jelonek {
782*44566e61SJonas Jelonek struct rtpse_mcu_ctrl *pse = data;
783*44566e61SJonas Jelonek
784*44566e61SJonas Jelonek rtpse_mcu_set_global_state(pse, false);
785*44566e61SJonas Jelonek }
786*44566e61SJonas Jelonek
rtpse_mcu_register(struct rtpse_mcu_ctrl * pse)787*44566e61SJonas Jelonek int rtpse_mcu_register(struct rtpse_mcu_ctrl *pse)
788*44566e61SJonas Jelonek {
789*44566e61SJonas Jelonek const struct rtpse_mcu_match_data *match;
790*44566e61SJonas Jelonek struct rtpse_mcu_info info;
791*44566e61SJonas Jelonek struct gpio_desc *gpiod;
792*44566e61SJonas Jelonek int ret;
793*44566e61SJonas Jelonek
794*44566e61SJonas Jelonek BUILD_BUG_ON(sizeof(struct rtpse_mcu_msg) != RTPSE_MCU_MSG_SIZE);
795*44566e61SJonas Jelonek
796*44566e61SJonas Jelonek ret = devm_mutex_init(pse->dev, &pse->mutex);
797*44566e61SJonas Jelonek if (ret)
798*44566e61SJonas Jelonek return ret;
799*44566e61SJonas Jelonek
800*44566e61SJonas Jelonek match = device_get_match_data(pse->dev);
801*44566e61SJonas Jelonek if (!match)
802*44566e61SJonas Jelonek return dev_err_probe(pse->dev, -ENODEV, "missing match data\n");
803*44566e61SJonas Jelonek pse->dialect = match->dialect;
804*44566e61SJonas Jelonek
805*44566e61SJonas Jelonek /*
806*44566e61SJonas Jelonek * Catch a dialect that forgot to set one of the required hooks at
807*44566e61SJonas Jelonek * probe time, rather than NULL-deref'ing later from a fast path.
808*44566e61SJonas Jelonek */
809*44566e61SJonas Jelonek if (!pse->dialect ||
810*44566e61SJonas Jelonek !pse->dialect->parse_system_info ||
811*44566e61SJonas Jelonek !pse->dialect->parse_port_class ||
812*44566e61SJonas Jelonek !pse->dialect->mcu_type_str)
813*44566e61SJonas Jelonek return dev_err_probe(pse->dev, -EINVAL,
814*44566e61SJonas Jelonek "dialect for chip is incomplete\n");
815*44566e61SJonas Jelonek
816*44566e61SJonas Jelonek /*
817*44566e61SJonas Jelonek * Release the MCU from reset before the first transaction; the
818*44566e61SJonas Jelonek * boot-retry loop in discover() waits for it to answer.
819*44566e61SJonas Jelonek */
820*44566e61SJonas Jelonek gpiod = devm_gpiod_get_optional(pse->dev, "reset", GPIOD_OUT_LOW);
821*44566e61SJonas Jelonek if (IS_ERR(gpiod))
822*44566e61SJonas Jelonek return dev_err_probe(pse->dev, PTR_ERR(gpiod),
823*44566e61SJonas Jelonek "failed to get reset gpio\n");
824*44566e61SJonas Jelonek
825*44566e61SJonas Jelonek ret = rtpse_mcu_discover(pse, &info);
826*44566e61SJonas Jelonek if (ret)
827*44566e61SJonas Jelonek return ret;
828*44566e61SJonas Jelonek
829*44566e61SJonas Jelonek /*
830*44566e61SJonas Jelonek * Some boards gate all ports through a hardware line; deassert it only
831*44566e61SJonas Jelonek * after the MCU is confirmed, so a discover failure never ungates the
832*44566e61SJonas Jelonek * ports. It is then left to the MCU - not re-gated on unbind or a later
833*44566e61SJonas Jelonek * probe error - so a driver reload doesn't black out PoE.
834*44566e61SJonas Jelonek */
835*44566e61SJonas Jelonek gpiod = devm_gpiod_get_optional(pse->dev, "disable-ports", GPIOD_OUT_LOW);
836*44566e61SJonas Jelonek if (IS_ERR(gpiod))
837*44566e61SJonas Jelonek return dev_err_probe(pse->dev, PTR_ERR(gpiod),
838*44566e61SJonas Jelonek "failed to get disable-ports gpio\n");
839*44566e61SJonas Jelonek
840*44566e61SJonas Jelonek if (!info.system_enable) {
841*44566e61SJonas Jelonek ret = rtpse_mcu_set_global_state(pse, true);
842*44566e61SJonas Jelonek /* Dialects without a global-state concept (e.g. Gen1) return
843*44566e61SJonas Jelonek * -EOPNOTSUPP; treat that as "no separate enable required".
844*44566e61SJonas Jelonek */
845*44566e61SJonas Jelonek if (ret && ret != -EOPNOTSUPP)
846*44566e61SJonas Jelonek return dev_err_probe(pse->dev, ret,
847*44566e61SJonas Jelonek "failed to enable PSE system\n");
848*44566e61SJonas Jelonek if (!ret) {
849*44566e61SJonas Jelonek ret = devm_add_action_or_reset(pse->dev,
850*44566e61SJonas Jelonek rtpse_mcu_global_disable, pse);
851*44566e61SJonas Jelonek if (ret)
852*44566e61SJonas Jelonek return ret;
853*44566e61SJonas Jelonek }
854*44566e61SJonas Jelonek }
855*44566e61SJonas Jelonek
856*44566e61SJonas Jelonek /*
857*44566e61SJonas Jelonek * Depending on the MCU firmware configuration (which might be different
858*44566e61SJonas Jelonek * for every board), it isn't known whether the PoE subsystem is active or
859*44566e61SJonas Jelonek * inactive by default. At this stage, the PSE chips might already deliver
860*44566e61SJonas Jelonek * power to PDs without any explicit enable.
861*44566e61SJonas Jelonek */
862*44566e61SJonas Jelonek
863*44566e61SJonas Jelonek /* pcdev.owner is set by the transport, so the registered controller
864*44566e61SJonas Jelonek * pins the transport module that owns the live device, not the core.
865*44566e61SJonas Jelonek */
866*44566e61SJonas Jelonek pse->pcdev.ops = &rtpse_mcu_ops;
867*44566e61SJonas Jelonek pse->pcdev.dev = pse->dev;
868*44566e61SJonas Jelonek pse->pcdev.types = ETHTOOL_PSE_C33;
869*44566e61SJonas Jelonek pse->pcdev.nr_lines = info.max_ports;
870*44566e61SJonas Jelonek pse->pcdev.pis_prio_max = RTPSE_MCU_PORT_MAX_PRIORITY;
871*44566e61SJonas Jelonek pse->pcdev.supp_budget_eval_strategies = PSE_BUDGET_EVAL_STRAT_DYNAMIC;
872*44566e61SJonas Jelonek
873*44566e61SJonas Jelonek return devm_pse_controller_register(pse->dev, &pse->pcdev);
874*44566e61SJonas Jelonek }
875*44566e61SJonas Jelonek EXPORT_SYMBOL_GPL(rtpse_mcu_register);
876*44566e61SJonas Jelonek
rtpse_mcu_gen2_parse_system_info(const u8 * payload,struct rtpse_mcu_info * info)877*44566e61SJonas Jelonek static void rtpse_mcu_gen2_parse_system_info(const u8 *payload, struct rtpse_mcu_info *info)
878*44566e61SJonas Jelonek {
879*44566e61SJonas Jelonek info->max_ports = payload[1];
880*44566e61SJonas Jelonek info->system_enable = (payload[2] == 0x1);
881*44566e61SJonas Jelonek info->device_id = get_unaligned_be16(&payload[3]);
882*44566e61SJonas Jelonek info->mcu_type = payload[6];
883*44566e61SJonas Jelonek }
884*44566e61SJonas Jelonek
rtpse_mcu_gen2_parse_port_class(const struct rtpse_mcu_port_status * status)885*44566e61SJonas Jelonek static int rtpse_mcu_gen2_parse_port_class(const struct rtpse_mcu_port_status *status)
886*44566e61SJonas Jelonek {
887*44566e61SJonas Jelonek /* Class lives in the upper nibble of sts2. */
888*44566e61SJonas Jelonek return FIELD_GET(GENMASK(7, 4), status->sts2);
889*44566e61SJonas Jelonek }
890*44566e61SJonas Jelonek
rtpse_mcu_gen2_mcu_type_str(unsigned int mcu_type)891*44566e61SJonas Jelonek static const char *rtpse_mcu_gen2_mcu_type_str(unsigned int mcu_type)
892*44566e61SJonas Jelonek {
893*44566e61SJonas Jelonek switch (mcu_type) {
894*44566e61SJonas Jelonek case 0x00: return "GigaDevice GD32F310";
895*44566e61SJonas Jelonek case 0x01: return "GigaDevice GD32F230";
896*44566e61SJonas Jelonek case 0x02: return "GigaDevice GD32F303";
897*44566e61SJonas Jelonek case 0x03: return "GigaDevice GD32F103";
898*44566e61SJonas Jelonek case 0x04: return "GigaDevice GD32E103";
899*44566e61SJonas Jelonek case 0x10: return "Nuvoton M0516";
900*44566e61SJonas Jelonek case 0x11: return "Nuvoton M0564";
901*44566e61SJonas Jelonek case 0x12: return "Nuvoton NUC029";
902*44566e61SJonas Jelonek default: return "unknown";
903*44566e61SJonas Jelonek }
904*44566e61SJonas Jelonek }
905*44566e61SJonas Jelonek
rtpse_mcu_gen1_parse_system_info(const u8 * payload,struct rtpse_mcu_info * info)906*44566e61SJonas Jelonek static void rtpse_mcu_gen1_parse_system_info(const u8 *payload, struct rtpse_mcu_info *info)
907*44566e61SJonas Jelonek {
908*44566e61SJonas Jelonek info->max_ports = payload[1];
909*44566e61SJonas Jelonek /* Gen1 has no explicit system_enable byte; the closest analog is the
910*44566e61SJonas Jelonek * "remote enable" bit in the system-status flags at payload[7].
911*44566e61SJonas Jelonek */
912*44566e61SJonas Jelonek info->system_enable = !!(payload[7] & BIT(2));
913*44566e61SJonas Jelonek info->device_id = get_unaligned_be16(&payload[3]);
914*44566e61SJonas Jelonek info->mcu_type = payload[6];
915*44566e61SJonas Jelonek }
916*44566e61SJonas Jelonek
rtpse_mcu_gen1_parse_port_class(const struct rtpse_mcu_port_status * status)917*44566e61SJonas Jelonek static int rtpse_mcu_gen1_parse_port_class(const struct rtpse_mcu_port_status *status)
918*44566e61SJonas Jelonek {
919*44566e61SJonas Jelonek /* Gen1 puts the detected class in payload[3] (== sts3) directly.
920*44566e61SJonas Jelonek * Mask to the low nibble; class is 0..8 and any high bits would be
921*44566e61SJonas Jelonek * noise.
922*44566e61SJonas Jelonek */
923*44566e61SJonas Jelonek return status->sts3 & 0x0f;
924*44566e61SJonas Jelonek }
925*44566e61SJonas Jelonek
rtpse_mcu_gen1_mcu_type_str(unsigned int mcu_type)926*44566e61SJonas Jelonek static const char *rtpse_mcu_gen1_mcu_type_str(unsigned int mcu_type)
927*44566e61SJonas Jelonek {
928*44566e61SJonas Jelonek switch (mcu_type) {
929*44566e61SJonas Jelonek case 0x00: return "ST Micro ST32F100";
930*44566e61SJonas Jelonek case 0x01: return "Nuvoton M05xx LAN";
931*44566e61SJonas Jelonek case 0x02: return "ST Micro STF030C8";
932*44566e61SJonas Jelonek case 0x03: return "Nuvoton M058SAN";
933*44566e61SJonas Jelonek case 0x04: return "Nuvoton NUC122";
934*44566e61SJonas Jelonek default: return "unknown";
935*44566e61SJonas Jelonek }
936*44566e61SJonas Jelonek }
937*44566e61SJonas Jelonek
938*44566e61SJonas Jelonek /* Map each logical command the core issues to its per-dialect opcode. */
939*44566e61SJonas Jelonek static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen2 = {
940*44566e61SJonas Jelonek .parse_system_info = rtpse_mcu_gen2_parse_system_info,
941*44566e61SJonas Jelonek .parse_port_class = rtpse_mcu_gen2_parse_port_class,
942*44566e61SJonas Jelonek .mcu_type_str = rtpse_mcu_gen2_mcu_type_str,
943*44566e61SJonas Jelonek .opcode = {
944*44566e61SJonas Jelonek [RTPSE_MCU_CMD_SET_GLOBAL_STATE] = RTPSE_MCU_OP(0x00),
945*44566e61SJonas Jelonek [RTPSE_MCU_CMD_GET_SYSTEM_INFO] = RTPSE_MCU_OP(0x40),
946*44566e61SJonas Jelonek [RTPSE_MCU_CMD_GET_EXT_CONFIG] = RTPSE_MCU_OP(0x4a),
947*44566e61SJonas Jelonek
948*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_ENABLE] = RTPSE_MCU_OP(0x01),
949*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x12),
950*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT] = RTPSE_MCU_OP(0x13),
951*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_EXT] = RTPSE_MCU_OP(0x14),
952*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_PRIORITY] = RTPSE_MCU_OP(0x15),
953*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_STATUS] = RTPSE_MCU_OP(0x42),
954*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_POWER_STATS] = RTPSE_MCU_OP(0x44),
955*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_CONFIG] = RTPSE_MCU_OP(0x48),
956*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_EXT_CONFIG] = RTPSE_MCU_OP(0x49),
957*44566e61SJonas Jelonek },
958*44566e61SJonas Jelonek };
959*44566e61SJonas Jelonek
960*44566e61SJonas Jelonek static const struct rtpse_mcu_dialect rtpse_mcu_dialect_gen1 = {
961*44566e61SJonas Jelonek .parse_system_info = rtpse_mcu_gen1_parse_system_info,
962*44566e61SJonas Jelonek .parse_port_class = rtpse_mcu_gen1_parse_port_class,
963*44566e61SJonas Jelonek .mcu_type_str = rtpse_mcu_gen1_mcu_type_str,
964*44566e61SJonas Jelonek .opcode = {
965*44566e61SJonas Jelonek [RTPSE_MCU_CMD_GET_SYSTEM_INFO] = RTPSE_MCU_OP(0x20),
966*44566e61SJonas Jelonek [RTPSE_MCU_CMD_GET_EXT_CONFIG] = RTPSE_MCU_OP(0x2b),
967*44566e61SJonas Jelonek
968*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_ENABLE] = RTPSE_MCU_OP(0x00),
969*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT_TYPE] = RTPSE_MCU_OP(0x15),
970*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_POWER_LIMIT] = RTPSE_MCU_OP(0x16),
971*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_SET_PRIORITY] = RTPSE_MCU_OP(0x1a),
972*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_STATUS] = RTPSE_MCU_OP(0x21),
973*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_POWER_STATS] = RTPSE_MCU_OP(0x30),
974*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_CONFIG] = RTPSE_MCU_OP(0x25),
975*44566e61SJonas Jelonek [RTPSE_MCU_CMD_PORT_GET_EXT_CONFIG] = RTPSE_MCU_OP(0x26),
976*44566e61SJonas Jelonek },
977*44566e61SJonas Jelonek };
978*44566e61SJonas Jelonek
979*44566e61SJonas Jelonek const struct rtpse_mcu_match_data rtpse_mcu_gen1_data = {
980*44566e61SJonas Jelonek .dialect = &rtpse_mcu_dialect_gen1,
981*44566e61SJonas Jelonek };
982*44566e61SJonas Jelonek EXPORT_SYMBOL_GPL(rtpse_mcu_gen1_data);
983*44566e61SJonas Jelonek
984*44566e61SJonas Jelonek const struct rtpse_mcu_match_data rtpse_mcu_gen2_data = {
985*44566e61SJonas Jelonek .dialect = &rtpse_mcu_dialect_gen2,
986*44566e61SJonas Jelonek };
987*44566e61SJonas Jelonek EXPORT_SYMBOL_GPL(rtpse_mcu_gen2_data);
988*44566e61SJonas Jelonek
989*44566e61SJonas Jelonek /* Same dialect as gen2, but the MCU expects raw-I2C framing. */
990*44566e61SJonas Jelonek const struct rtpse_mcu_match_data rtpse_mcu_gen2_i2c_data = {
991*44566e61SJonas Jelonek .dialect = &rtpse_mcu_dialect_gen2,
992*44566e61SJonas Jelonek .native_i2c = true,
993*44566e61SJonas Jelonek };
994*44566e61SJonas Jelonek EXPORT_SYMBOL_GPL(rtpse_mcu_gen2_i2c_data);
995*44566e61SJonas Jelonek
996*44566e61SJonas Jelonek MODULE_AUTHOR("Jonas Jelonek <jelonek.jonas@gmail.com>");
997*44566e61SJonas Jelonek MODULE_DESCRIPTION("Realtek PSE MCU driver (core)");
998*44566e61SJonas Jelonek MODULE_LICENSE("GPL");
999