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