1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * w1-uart - UART 1-Wire bus driver
4 *
5 * Uses the UART interface (via Serial Device Bus) to create the 1-Wire
6 * timing patterns. Implements the following 1-Wire master interface:
7 *
8 * - reset_bus: requests baud-rate 9600
9 *
10 * - touch_bit: requests baud-rate 115200
11 *
12 * Author: Christoph Winklhofer <cj.winklhofer@gmail.com>
13 */
14
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/jiffies.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/of.h>
21#include <linux/serdev.h>
22#include <linux/w1.h>
23
24/* UART packet contains start and stop bit */
25#define W1_UART_BITS_PER_PACKET (BITS_PER_BYTE + 2)
26
27/* Timeout to wait for completion of serdev-receive */
28#define W1_UART_TIMEOUT msecs_to_jiffies(500)
29
30/**
31 * struct w1_uart_config - configuration for 1-Wire operation
32 * @baudrate: baud-rate returned from serdev
33 * @delay_us: delay to complete a 1-Wire cycle (in us)
34 * @tx_byte: byte to generate 1-Wire timing pattern
35 */
36struct w1_uart_config {
37 unsigned int baudrate;
38 unsigned int delay_us;
39 u8 tx_byte;
40};
41
42/**
43 * struct w1_uart_device - 1-Wire UART device structure
44 * @serdev: serial device
45 * @bus: w1-bus master
46 * @cfg_reset: config for 1-Wire reset
47 * @cfg_touch_0: config for 1-Wire write-0 cycle
48 * @cfg_touch_1: config for 1-Wire write-1 and read cycle
49 * @rx_byte_received: completion for serdev receive
50 * @rx_mutex: mutex to protect rx_err and rx_byte
51 * @rx_err: indicates an error in serdev-receive
52 * @rx_byte: result byte from serdev-receive
53 */
54struct w1_uart_device {
55 struct serdev_device *serdev;
56 struct w1_bus_master bus;
57
58 struct w1_uart_config cfg_reset;
59 struct w1_uart_config cfg_touch_0;
60 struct w1_uart_config cfg_touch_1;
61
62 struct completion rx_byte_received;
63 /*
64 * protect rx_err and rx_byte from concurrent access in
65 * w1-callbacks and serdev-receive.
66 */
67 struct mutex rx_mutex;
68 int rx_err;
69 u8 rx_byte;
70};
71
72/**
73 * struct w1_uart_limits - limits for 1-Wire operations
74 * @baudrate: Requested baud-rate to create 1-Wire timing pattern
75 * @bit_min_us: minimum time for a bit (in us)
76 * @bit_max_us: maximum time for a bit (in us)
77 * @sample_us: timespan to sample 1-Wire response
78 * @cycle_us: duration of the 1-Wire cycle
79 */
80struct w1_uart_limits {
81 unsigned int baudrate;
82 unsigned int bit_min_us;
83 unsigned int bit_max_us;
84 unsigned int sample_us;
85 unsigned int cycle_us;
86};
87
88static inline unsigned int baud_to_bit_ns(unsigned int baud)
89{
90 return NSEC_PER_SEC / baud;
91}
92
93static inline unsigned int to_ns(unsigned int us)
94{
95 return us * NSEC_PER_USEC;
96}
97
98/*
99 * Set baud-rate, delay and tx-byte to create a 1-Wire pulse and adapt
100 * the tx-byte according to the actual baud-rate.
101 *
102 * Reject when:
103 * - time for a bit outside min/max range
104 * - a 1-Wire response is not detectable for sent byte
105 */
106static int w1_uart_set_config(struct serdev_device *serdev,
107 const struct w1_uart_limits *limits,
108 struct w1_uart_config *w1cfg)
109{
110 unsigned int packet_ns;
111 unsigned int bits_low;
112 unsigned int bit_ns;
113 unsigned int low_ns;
114
115 w1cfg->baudrate = serdev_device_set_baudrate(serdev, limits->baudrate);
116 if (w1cfg->baudrate == 0)
117 return -EINVAL;
118
119 /* Compute in nanoseconds for accuracy */
120 bit_ns = baud_to_bit_ns(baud: w1cfg->baudrate);
121 bits_low = to_ns(us: limits->bit_min_us) / bit_ns;
122 /* start bit is always low */
123 low_ns = bit_ns * (bits_low + 1);
124
125 if (low_ns < to_ns(us: limits->bit_min_us))
126 return -EINVAL;
127
128 if (low_ns > to_ns(us: limits->bit_max_us))
129 return -EINVAL;
130
131 /* 1-Wire response detectable for sent byte */
132 if (limits->sample_us > 0 &&
133 bit_ns * BITS_PER_BYTE < low_ns + to_ns(us: limits->sample_us))
134 return -EINVAL;
135
136 /* delay: 1-Wire cycle takes longer than the UART packet */
137 packet_ns = bit_ns * W1_UART_BITS_PER_PACKET;
138 w1cfg->delay_us = 0;
139 if (to_ns(us: limits->cycle_us) > packet_ns)
140 w1cfg->delay_us =
141 (to_ns(us: limits->cycle_us) - packet_ns) / NSEC_PER_USEC;
142
143 /* byte to create 1-Wire pulse */
144 w1cfg->tx_byte = 0xff << bits_low;
145
146 return 0;
147}
148
149/*
150 * Configuration for reset and presence detect
151 * - bit_min_us is 480us, add margin and use 485us
152 * - limits for sample time 60us-75us, use 65us
153 */
154static int w1_uart_set_config_reset(struct w1_uart_device *w1dev)
155{
156 struct serdev_device *serdev = w1dev->serdev;
157 struct device_node *np = serdev->dev.of_node;
158
159 struct w1_uart_limits limits = { .baudrate = 9600,
160 .bit_min_us = 485,
161 .bit_max_us = 640,
162 .sample_us = 65,
163 .cycle_us = 960 };
164
165 of_property_read_u32(np, propname: "reset-bps", out_value: &limits.baudrate);
166
167 return w1_uart_set_config(serdev, limits: &limits, w1cfg: &w1dev->cfg_reset);
168}
169
170/*
171 * Configuration for write-0 cycle (touch bit 0)
172 * - bit_min_us is 60us, add margin and use 65us
173 * - no sampling required, sample_us = 0
174 */
175static int w1_uart_set_config_touch_0(struct w1_uart_device *w1dev)
176{
177 struct serdev_device *serdev = w1dev->serdev;
178 struct device_node *np = serdev->dev.of_node;
179
180 struct w1_uart_limits limits = { .baudrate = 115200,
181 .bit_min_us = 65,
182 .bit_max_us = 120,
183 .sample_us = 0,
184 .cycle_us = 70 };
185
186 of_property_read_u32(np, propname: "write-0-bps", out_value: &limits.baudrate);
187
188 return w1_uart_set_config(serdev, limits: &limits, w1cfg: &w1dev->cfg_touch_0);
189}
190
191/*
192 * Configuration for write-1 and read cycle (touch bit 1)
193 * - bit_min_us is 5us, add margin and use 6us
194 * - limits for sample time 5us-15us, use 15us
195 */
196static int w1_uart_set_config_touch_1(struct w1_uart_device *w1dev)
197{
198 struct serdev_device *serdev = w1dev->serdev;
199 struct device_node *np = serdev->dev.of_node;
200
201 struct w1_uart_limits limits = { .baudrate = 115200,
202 .bit_min_us = 6,
203 .bit_max_us = 15,
204 .sample_us = 15,
205 .cycle_us = 70 };
206
207 of_property_read_u32(np, propname: "write-1-bps", out_value: &limits.baudrate);
208
209 return w1_uart_set_config(serdev, limits: &limits, w1cfg: &w1dev->cfg_touch_1);
210}
211
212/*
213 * Configure and open the serial device
214 */
215static int w1_uart_serdev_open(struct w1_uart_device *w1dev)
216{
217 struct serdev_device *serdev = w1dev->serdev;
218 struct device *dev = &serdev->dev;
219 int ret;
220
221 ret = devm_serdev_device_open(dev, serdev);
222 if (ret < 0)
223 return ret;
224
225 ret = serdev_device_set_parity(serdev, parity: SERDEV_PARITY_NONE);
226 if (ret < 0) {
227 dev_err(dev, "set parity failed\n");
228 return ret;
229 }
230
231 ret = w1_uart_set_config_reset(w1dev);
232 if (ret < 0) {
233 dev_err(dev, "config for reset failed\n");
234 return ret;
235 }
236
237 ret = w1_uart_set_config_touch_0(w1dev);
238 if (ret < 0) {
239 dev_err(dev, "config for touch-0 failed\n");
240 return ret;
241 }
242
243 ret = w1_uart_set_config_touch_1(w1dev);
244 if (ret < 0) {
245 dev_err(dev, "config for touch-1 failed\n");
246 return ret;
247 }
248
249 serdev_device_set_flow_control(serdev, false);
250
251 return 0;
252}
253
254/*
255 * Send one byte (tx_byte) and read one byte (rx_byte) via serdev.
256 */
257static int w1_uart_serdev_tx_rx(struct w1_uart_device *w1dev,
258 const struct w1_uart_config *w1cfg, u8 *rx_byte)
259{
260 struct serdev_device *serdev = w1dev->serdev;
261 int ret;
262
263 serdev_device_write_flush(serdev);
264 serdev_device_set_baudrate(serdev, w1cfg->baudrate);
265
266 /* write and immediately read one byte */
267 reinit_completion(x: &w1dev->rx_byte_received);
268 ret = serdev_device_write_buf(serdev, &w1cfg->tx_byte, 1);
269 if (ret != 1)
270 return -EIO;
271 ret = wait_for_completion_interruptible_timeout(
272 x: &w1dev->rx_byte_received, W1_UART_TIMEOUT);
273 if (ret <= 0)
274 return -EIO;
275
276 /* locking could fail when serdev is unexpectedly receiving. */
277 if (!mutex_trylock(lock: &w1dev->rx_mutex))
278 return -EIO;
279
280 ret = w1dev->rx_err;
281 if (ret == 0)
282 *rx_byte = w1dev->rx_byte;
283
284 mutex_unlock(lock: &w1dev->rx_mutex);
285
286 if (w1cfg->delay_us > 0)
287 fsleep(usecs: w1cfg->delay_us);
288
289 return ret;
290}
291
292static size_t w1_uart_serdev_receive_buf(struct serdev_device *serdev,
293 const u8 *buf, size_t count)
294{
295 struct w1_uart_device *w1dev = serdev_device_get_drvdata(serdev);
296
297 mutex_lock(&w1dev->rx_mutex);
298
299 /* sent a single byte and receive one single byte */
300 if (count == 1) {
301 w1dev->rx_byte = buf[0];
302 w1dev->rx_err = 0;
303 } else {
304 w1dev->rx_err = -EIO;
305 }
306
307 mutex_unlock(lock: &w1dev->rx_mutex);
308 complete(&w1dev->rx_byte_received);
309
310 return count;
311}
312
313static const struct serdev_device_ops w1_uart_serdev_ops = {
314 .receive_buf = w1_uart_serdev_receive_buf,
315 .write_wakeup = serdev_device_write_wakeup,
316};
317
318/*
319 * 1-wire reset and presence detect: A present slave will manipulate
320 * the received byte by pulling the 1-Wire low.
321 */
322static u8 w1_uart_reset_bus(void *data)
323{
324 struct w1_uart_device *w1dev = data;
325 const struct w1_uart_config *w1cfg = &w1dev->cfg_reset;
326 int ret;
327 u8 val;
328
329 ret = w1_uart_serdev_tx_rx(w1dev, w1cfg, rx_byte: &val);
330 if (ret < 0)
331 return -1;
332
333 /* Device present (0) or no device (1) */
334 return val != w1cfg->tx_byte ? 0 : 1;
335}
336
337/*
338 * 1-Wire read and write cycle: Only the read-0 manipulates the
339 * received byte, all others left the line untouched.
340 */
341static u8 w1_uart_touch_bit(void *data, u8 bit)
342{
343 struct w1_uart_device *w1dev = data;
344 const struct w1_uart_config *w1cfg = bit ? &w1dev->cfg_touch_1 :
345 &w1dev->cfg_touch_0;
346 int ret;
347 u8 val;
348
349 ret = w1_uart_serdev_tx_rx(w1dev, w1cfg, rx_byte: &val);
350
351 /* return inactive bus state on error */
352 if (ret < 0)
353 return 1;
354
355 return val == w1cfg->tx_byte ? 1 : 0;
356}
357
358static int w1_uart_probe(struct serdev_device *serdev)
359{
360 struct device *dev = &serdev->dev;
361 struct w1_uart_device *w1dev;
362 int ret;
363
364 w1dev = devm_kzalloc(dev, size: sizeof(*w1dev), GFP_KERNEL);
365 if (!w1dev)
366 return -ENOMEM;
367 w1dev->bus.data = w1dev;
368 w1dev->bus.reset_bus = w1_uart_reset_bus;
369 w1dev->bus.touch_bit = w1_uart_touch_bit;
370 w1dev->serdev = serdev;
371
372 init_completion(x: &w1dev->rx_byte_received);
373 mutex_init(&w1dev->rx_mutex);
374
375 ret = w1_uart_serdev_open(w1dev);
376 if (ret < 0)
377 return ret;
378 serdev_device_set_drvdata(serdev, data: w1dev);
379 serdev_device_set_client_ops(serdev, ops: &w1_uart_serdev_ops);
380
381 return w1_add_master_device(master: &w1dev->bus);
382}
383
384static void w1_uart_remove(struct serdev_device *serdev)
385{
386 struct w1_uart_device *w1dev = serdev_device_get_drvdata(serdev);
387
388 /*
389 * Waits until w1-uart callbacks are finished, serdev is closed
390 * and its device data released automatically by devres (waits
391 * until serdev-receive is finished).
392 */
393 w1_remove_master_device(master: &w1dev->bus);
394}
395
396static const struct of_device_id w1_uart_of_match[] = {
397 { .compatible = "w1-uart" },
398 {},
399};
400MODULE_DEVICE_TABLE(of, w1_uart_of_match);
401
402static struct serdev_device_driver w1_uart_driver = {
403 .driver = {
404 .name = "w1-uart",
405 .of_match_table = w1_uart_of_match,
406 },
407 .probe = w1_uart_probe,
408 .remove = w1_uart_remove,
409};
410
411module_serdev_device_driver(w1_uart_driver);
412
413MODULE_DESCRIPTION("UART w1 bus driver");
414MODULE_AUTHOR("Christoph Winklhofer <cj.winklhofer@gmail.com>");
415MODULE_LICENSE("GPL");
416

source code of linux/drivers/w1/masters/w1-uart.c