xref: /linux/drivers/net/pse-pd/realtek-pse-mcu-uart.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1*5cc93d98SJonas Jelonek // SPDX-License-Identifier: GPL-2.0-or-later
2*5cc93d98SJonas Jelonek 
3*5cc93d98SJonas Jelonek #include <linux/cleanup.h>
4*5cc93d98SJonas Jelonek #include <linux/completion.h>
5*5cc93d98SJonas Jelonek #include <linux/module.h>
6*5cc93d98SJonas Jelonek #include <linux/of.h>
7*5cc93d98SJonas Jelonek #include <linux/pse-pd/pse.h>
8*5cc93d98SJonas Jelonek #include <linux/serdev.h>
9*5cc93d98SJonas Jelonek #include <linux/spinlock.h>
10*5cc93d98SJonas Jelonek #include <linux/string.h>
11*5cc93d98SJonas Jelonek 
12*5cc93d98SJonas Jelonek #include "realtek-pse-mcu.h"
13*5cc93d98SJonas Jelonek 
14*5cc93d98SJonas Jelonek #define RTPSE_MCU_UART_BAUD_DEFAULT	19200
15*5cc93d98SJonas Jelonek #define RTPSE_MCU_UART_TX_TIMEOUT	msecs_to_jiffies(100)
16*5cc93d98SJonas Jelonek #define RTPSE_MCU_UART_RX_TIMEOUT	msecs_to_jiffies(RTPSE_MCU_RESPONSE_MAX_MS)
17*5cc93d98SJonas Jelonek 
18*5cc93d98SJonas Jelonek struct rtpse_mcu_uart {
19*5cc93d98SJonas Jelonek 	struct rtpse_mcu_ctrl pse;
20*5cc93d98SJonas Jelonek 	struct serdev_device *serdev;
21*5cc93d98SJonas Jelonek 	struct completion rx_done;
22*5cc93d98SJonas Jelonek 	spinlock_t rx_lock;		/* protects rx_buf and rx_len */
23*5cc93d98SJonas Jelonek 	size_t rx_len;
24*5cc93d98SJonas Jelonek 	u8 rx_buf[RTPSE_MCU_MSG_SIZE];
25*5cc93d98SJonas Jelonek };
26*5cc93d98SJonas Jelonek 
27*5cc93d98SJonas Jelonek #define to_rtpse_mcu_uart(p)  container_of(p, struct rtpse_mcu_uart, pse)
28*5cc93d98SJonas Jelonek 
29*5cc93d98SJonas Jelonek /*
30*5cc93d98SJonas Jelonek  * No framing is done here: a glitched frame costs one transaction, then
31*5cc93d98SJonas Jelonek  * the next _send re-frames from rx_len 0. Resync works by returning count
32*5cc93d98SJonas Jelonek  * (not take), dropping any overflow so serdev keeps no leftover to bleed
33*5cc93d98SJonas Jelonek  * into the next frame.
34*5cc93d98SJonas Jelonek  */
rtpse_mcu_uart_receive(struct serdev_device * serdev,const u8 * buf,size_t count)35*5cc93d98SJonas Jelonek static size_t rtpse_mcu_uart_receive(struct serdev_device *serdev,
36*5cc93d98SJonas Jelonek 				     const u8 *buf, size_t count)
37*5cc93d98SJonas Jelonek {
38*5cc93d98SJonas Jelonek 	struct rtpse_mcu_uart *ctx = serdev_device_get_drvdata(serdev);
39*5cc93d98SJonas Jelonek 	size_t take;
40*5cc93d98SJonas Jelonek 
41*5cc93d98SJonas Jelonek 	scoped_guard(spinlock_irqsave, &ctx->rx_lock) {
42*5cc93d98SJonas Jelonek 		take = min(count, sizeof(ctx->rx_buf) - ctx->rx_len);
43*5cc93d98SJonas Jelonek 		if (take) {
44*5cc93d98SJonas Jelonek 			memcpy(ctx->rx_buf + ctx->rx_len, buf, take);
45*5cc93d98SJonas Jelonek 			ctx->rx_len += take;
46*5cc93d98SJonas Jelonek 			if (ctx->rx_len == sizeof(ctx->rx_buf))
47*5cc93d98SJonas Jelonek 				complete(&ctx->rx_done);
48*5cc93d98SJonas Jelonek 		}
49*5cc93d98SJonas Jelonek 	}
50*5cc93d98SJonas Jelonek 
51*5cc93d98SJonas Jelonek 	/* consume all to avoid desync/misalignment */
52*5cc93d98SJonas Jelonek 	return count;
53*5cc93d98SJonas Jelonek }
54*5cc93d98SJonas Jelonek 
55*5cc93d98SJonas Jelonek static const struct serdev_device_ops rtpse_mcu_uart_serdev_ops = {
56*5cc93d98SJonas Jelonek 	.receive_buf = rtpse_mcu_uart_receive,
57*5cc93d98SJonas Jelonek 	.write_wakeup = serdev_device_write_wakeup,
58*5cc93d98SJonas Jelonek };
59*5cc93d98SJonas Jelonek 
rtpse_mcu_uart_send(struct rtpse_mcu_ctrl * pse,const struct rtpse_mcu_msg * req)60*5cc93d98SJonas Jelonek static int rtpse_mcu_uart_send(struct rtpse_mcu_ctrl *pse, const struct rtpse_mcu_msg *req)
61*5cc93d98SJonas Jelonek {
62*5cc93d98SJonas Jelonek 	struct rtpse_mcu_uart *ctx = to_rtpse_mcu_uart(pse);
63*5cc93d98SJonas Jelonek 	int written;
64*5cc93d98SJonas Jelonek 
65*5cc93d98SJonas Jelonek 	/* clear any leftover rx state before transmitting */
66*5cc93d98SJonas Jelonek 	scoped_guard(spinlock_irqsave, &ctx->rx_lock) {
67*5cc93d98SJonas Jelonek 		reinit_completion(&ctx->rx_done);
68*5cc93d98SJonas Jelonek 		ctx->rx_len = 0;
69*5cc93d98SJonas Jelonek 	}
70*5cc93d98SJonas Jelonek 
71*5cc93d98SJonas Jelonek 	written = serdev_device_write(ctx->serdev, (const u8 *)req, sizeof(*req),
72*5cc93d98SJonas Jelonek 				      RTPSE_MCU_UART_TX_TIMEOUT);
73*5cc93d98SJonas Jelonek 	if (written < 0)
74*5cc93d98SJonas Jelonek 		return written;
75*5cc93d98SJonas Jelonek 	if (written != sizeof(*req))
76*5cc93d98SJonas Jelonek 		return -EIO;
77*5cc93d98SJonas Jelonek 
78*5cc93d98SJonas Jelonek 	return 0;
79*5cc93d98SJonas Jelonek }
80*5cc93d98SJonas Jelonek 
rtpse_mcu_uart_recv(struct rtpse_mcu_ctrl * pse,const struct rtpse_mcu_msg * req,struct rtpse_mcu_msg * resp)81*5cc93d98SJonas Jelonek static int rtpse_mcu_uart_recv(struct rtpse_mcu_ctrl *pse,
82*5cc93d98SJonas Jelonek 			       const struct rtpse_mcu_msg *req,
83*5cc93d98SJonas Jelonek 			       struct rtpse_mcu_msg *resp)
84*5cc93d98SJonas Jelonek {
85*5cc93d98SJonas Jelonek 	struct rtpse_mcu_uart *ctx = to_rtpse_mcu_uart(pse);
86*5cc93d98SJonas Jelonek 
87*5cc93d98SJonas Jelonek 	if (!wait_for_completion_timeout(&ctx->rx_done, RTPSE_MCU_UART_RX_TIMEOUT))
88*5cc93d98SJonas Jelonek 		return -ETIMEDOUT;
89*5cc93d98SJonas Jelonek 
90*5cc93d98SJonas Jelonek 	scoped_guard(spinlock_irqsave, &ctx->rx_lock) {
91*5cc93d98SJonas Jelonek 		if (ctx->rx_len != sizeof(*resp))
92*5cc93d98SJonas Jelonek 			return -EIO;
93*5cc93d98SJonas Jelonek 
94*5cc93d98SJonas Jelonek 		memcpy(resp, ctx->rx_buf, sizeof(*resp));
95*5cc93d98SJonas Jelonek 	}
96*5cc93d98SJonas Jelonek 	return 0;
97*5cc93d98SJonas Jelonek }
98*5cc93d98SJonas Jelonek 
99*5cc93d98SJonas Jelonek static const struct rtpse_mcu_transport_ops rtpse_mcu_uart_transport_ops = {
100*5cc93d98SJonas Jelonek 	.send = rtpse_mcu_uart_send,
101*5cc93d98SJonas Jelonek 	.recv = rtpse_mcu_uart_recv,
102*5cc93d98SJonas Jelonek };
103*5cc93d98SJonas Jelonek 
rtpse_mcu_uart_probe(struct serdev_device * serdev)104*5cc93d98SJonas Jelonek static int rtpse_mcu_uart_probe(struct serdev_device *serdev)
105*5cc93d98SJonas Jelonek {
106*5cc93d98SJonas Jelonek 	u32 speed = RTPSE_MCU_UART_BAUD_DEFAULT;
107*5cc93d98SJonas Jelonek 	struct device *dev = &serdev->dev;
108*5cc93d98SJonas Jelonek 	struct rtpse_mcu_uart *ctx;
109*5cc93d98SJonas Jelonek 	unsigned int baud;
110*5cc93d98SJonas Jelonek 	int ret;
111*5cc93d98SJonas Jelonek 
112*5cc93d98SJonas Jelonek 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
113*5cc93d98SJonas Jelonek 	if (!ctx)
114*5cc93d98SJonas Jelonek 		return -ENOMEM;
115*5cc93d98SJonas Jelonek 
116*5cc93d98SJonas Jelonek 	ctx->serdev = serdev;
117*5cc93d98SJonas Jelonek 	ctx->pse.dev = dev;
118*5cc93d98SJonas Jelonek 	ctx->pse.pcdev.owner = THIS_MODULE;
119*5cc93d98SJonas Jelonek 	ctx->pse.transport = &rtpse_mcu_uart_transport_ops;
120*5cc93d98SJonas Jelonek 	init_completion(&ctx->rx_done);
121*5cc93d98SJonas Jelonek 	spin_lock_init(&ctx->rx_lock);
122*5cc93d98SJonas Jelonek 
123*5cc93d98SJonas Jelonek 	serdev_device_set_drvdata(serdev, ctx);
124*5cc93d98SJonas Jelonek 	serdev_device_set_client_ops(serdev, &rtpse_mcu_uart_serdev_ops);
125*5cc93d98SJonas Jelonek 
126*5cc93d98SJonas Jelonek 	ret = devm_serdev_device_open(dev, serdev);
127*5cc93d98SJonas Jelonek 	if (ret)
128*5cc93d98SJonas Jelonek 		return dev_err_probe(dev, ret, "failed to open serdev\n");
129*5cc93d98SJonas Jelonek 
130*5cc93d98SJonas Jelonek 	fwnode_property_read_u32(dev_fwnode(dev), "current-speed", &speed);
131*5cc93d98SJonas Jelonek 
132*5cc93d98SJonas Jelonek 	baud = serdev_device_set_baudrate(serdev, speed);
133*5cc93d98SJonas Jelonek 	if (baud != speed)
134*5cc93d98SJonas Jelonek 		dev_warn(dev, "could not set baudrate %u, controller uses %u\n",
135*5cc93d98SJonas Jelonek 			 speed, baud);
136*5cc93d98SJonas Jelonek 
137*5cc93d98SJonas Jelonek 	serdev_device_set_flow_control(serdev, false);
138*5cc93d98SJonas Jelonek 
139*5cc93d98SJonas Jelonek 	ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
140*5cc93d98SJonas Jelonek 	if (ret)
141*5cc93d98SJonas Jelonek 		dev_warn(dev, "could not set parity to none: %d\n", ret);
142*5cc93d98SJonas Jelonek 
143*5cc93d98SJonas Jelonek 	return rtpse_mcu_register(&ctx->pse);
144*5cc93d98SJonas Jelonek }
145*5cc93d98SJonas Jelonek 
146*5cc93d98SJonas Jelonek static const struct of_device_id rtpse_mcu_uart_of_match[] = {
147*5cc93d98SJonas Jelonek 	{ .compatible = "realtek,pse-mcu-gen1", .data = &rtpse_mcu_gen1_data },
148*5cc93d98SJonas Jelonek 	{ .compatible = "realtek,pse-mcu-gen2", .data = &rtpse_mcu_gen2_data },
149*5cc93d98SJonas Jelonek 	{ /* sentinel */ }
150*5cc93d98SJonas Jelonek };
151*5cc93d98SJonas Jelonek MODULE_DEVICE_TABLE(of, rtpse_mcu_uart_of_match);
152*5cc93d98SJonas Jelonek 
153*5cc93d98SJonas Jelonek static struct serdev_device_driver rtpse_mcu_uart_driver = {
154*5cc93d98SJonas Jelonek 	.driver = {
155*5cc93d98SJonas Jelonek 		.name = "realtek-pse-mcu-uart",
156*5cc93d98SJonas Jelonek 		.of_match_table = rtpse_mcu_uart_of_match,
157*5cc93d98SJonas Jelonek 	},
158*5cc93d98SJonas Jelonek 	.probe  = rtpse_mcu_uart_probe,
159*5cc93d98SJonas Jelonek };
160*5cc93d98SJonas Jelonek module_serdev_device_driver(rtpse_mcu_uart_driver);
161*5cc93d98SJonas Jelonek 
162*5cc93d98SJonas Jelonek MODULE_AUTHOR("Jonas Jelonek <jelonek.jonas@gmail.com>");
163*5cc93d98SJonas Jelonek MODULE_DESCRIPTION("Realtek PSE MCU driver (UART transport)");
164*5cc93d98SJonas Jelonek MODULE_LICENSE("GPL");
165