Lines Matching +full:delay +full:- +full:us
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * w1-uart - UART 1-Wire bus driver
5 * Uses the UART interface (via Serial Device Bus) to create the 1-Wire
6 * timing patterns. Implements the following 1-Wire master interface:
8 * - reset_bus: requests baud-rate 9600
10 * - touch_bit: requests baud-rate 115200
16 #include <linux/delay.h>
27 /* Timeout to wait for completion of serdev-receive */
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
43 * struct w1_uart_device - 1-Wire UART device structure
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
51 * @rx_err: indicates an error in serdev-receive
52 * @rx_byte: result byte from serdev-receive
65 * w1-callbacks and serdev-receive.
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
93 static inline unsigned int to_ns(unsigned int us) in to_ns() argument
95 return us * NSEC_PER_USEC; in to_ns()
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.
103 * - time for a bit outside min/max range
104 * - a 1-Wire response is not detectable for sent byte
115 w1cfg->baudrate = serdev_device_set_baudrate(serdev, limits->baudrate); in w1_uart_set_config()
116 if (w1cfg->baudrate == 0) in w1_uart_set_config()
117 return -EINVAL; in w1_uart_set_config()
120 bit_ns = baud_to_bit_ns(w1cfg->baudrate); in w1_uart_set_config()
121 bits_low = to_ns(limits->bit_min_us) / bit_ns; in w1_uart_set_config()
125 if (low_ns < to_ns(limits->bit_min_us)) in w1_uart_set_config()
126 return -EINVAL; in w1_uart_set_config()
128 if (low_ns > to_ns(limits->bit_max_us)) in w1_uart_set_config()
129 return -EINVAL; in w1_uart_set_config()
131 /* 1-Wire response detectable for sent byte */ in w1_uart_set_config()
132 if (limits->sample_us > 0 && in w1_uart_set_config()
133 bit_ns * BITS_PER_BYTE < low_ns + to_ns(limits->sample_us)) in w1_uart_set_config()
134 return -EINVAL; in w1_uart_set_config()
136 /* delay: 1-Wire cycle takes longer than the UART packet */ in w1_uart_set_config()
138 w1cfg->delay_us = 0; in w1_uart_set_config()
139 if (to_ns(limits->cycle_us) > packet_ns) in w1_uart_set_config()
140 w1cfg->delay_us = in w1_uart_set_config()
141 (to_ns(limits->cycle_us) - packet_ns) / NSEC_PER_USEC; in w1_uart_set_config()
143 /* byte to create 1-Wire pulse */ in w1_uart_set_config()
144 w1cfg->tx_byte = 0xff << bits_low; in w1_uart_set_config()
151 * - bit_min_us is 480us, add margin and use 485us
152 * - limits for sample time 60us-75us, use 65us
156 struct serdev_device *serdev = w1dev->serdev; in w1_uart_set_config_reset()
157 struct device_node *np = serdev->dev.of_node; in w1_uart_set_config_reset()
165 of_property_read_u32(np, "reset-bps", &limits.baudrate); in w1_uart_set_config_reset()
167 return w1_uart_set_config(serdev, &limits, &w1dev->cfg_reset); in w1_uart_set_config_reset()
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
177 struct serdev_device *serdev = w1dev->serdev; in w1_uart_set_config_touch_0()
178 struct device_node *np = serdev->dev.of_node; in w1_uart_set_config_touch_0()
186 of_property_read_u32(np, "write-0-bps", &limits.baudrate); in w1_uart_set_config_touch_0()
188 return w1_uart_set_config(serdev, &limits, &w1dev->cfg_touch_0); in w1_uart_set_config_touch_0()
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
198 struct serdev_device *serdev = w1dev->serdev; in w1_uart_set_config_touch_1()
199 struct device_node *np = serdev->dev.of_node; in w1_uart_set_config_touch_1()
207 of_property_read_u32(np, "write-1-bps", &limits.baudrate); in w1_uart_set_config_touch_1()
209 return w1_uart_set_config(serdev, &limits, &w1dev->cfg_touch_1); in w1_uart_set_config_touch_1()
217 struct serdev_device *serdev = w1dev->serdev; in w1_uart_serdev_open()
218 struct device *dev = &serdev->dev; in w1_uart_serdev_open()
239 dev_err(dev, "config for touch-0 failed\n"); in w1_uart_serdev_open()
245 dev_err(dev, "config for touch-1 failed\n"); in w1_uart_serdev_open()
260 struct serdev_device *serdev = w1dev->serdev; in w1_uart_serdev_tx_rx()
264 serdev_device_set_baudrate(serdev, w1cfg->baudrate); in w1_uart_serdev_tx_rx()
267 reinit_completion(&w1dev->rx_byte_received); in w1_uart_serdev_tx_rx()
268 ret = serdev_device_write_buf(serdev, &w1cfg->tx_byte, 1); in w1_uart_serdev_tx_rx()
270 return -EIO; in w1_uart_serdev_tx_rx()
272 &w1dev->rx_byte_received, W1_UART_TIMEOUT); in w1_uart_serdev_tx_rx()
274 return -EIO; in w1_uart_serdev_tx_rx()
277 if (!mutex_trylock(&w1dev->rx_mutex)) in w1_uart_serdev_tx_rx()
278 return -EIO; in w1_uart_serdev_tx_rx()
280 ret = w1dev->rx_err; in w1_uart_serdev_tx_rx()
282 *rx_byte = w1dev->rx_byte; in w1_uart_serdev_tx_rx()
284 mutex_unlock(&w1dev->rx_mutex); in w1_uart_serdev_tx_rx()
286 if (w1cfg->delay_us > 0) in w1_uart_serdev_tx_rx()
287 fsleep(w1cfg->delay_us); in w1_uart_serdev_tx_rx()
297 mutex_lock(&w1dev->rx_mutex); in w1_uart_serdev_receive_buf()
301 w1dev->rx_byte = buf[0]; in w1_uart_serdev_receive_buf()
302 w1dev->rx_err = 0; in w1_uart_serdev_receive_buf()
304 w1dev->rx_err = -EIO; in w1_uart_serdev_receive_buf()
307 mutex_unlock(&w1dev->rx_mutex); in w1_uart_serdev_receive_buf()
308 complete(&w1dev->rx_byte_received); in w1_uart_serdev_receive_buf()
319 * 1-wire reset and presence detect: A present slave will manipulate
320 * the received byte by pulling the 1-Wire low.
325 const struct w1_uart_config *w1cfg = &w1dev->cfg_reset; in w1_uart_reset_bus()
331 return -1; in w1_uart_reset_bus()
334 return val != w1cfg->tx_byte ? 0 : 1; in w1_uart_reset_bus()
338 * 1-Wire read and write cycle: Only the read-0 manipulates the
344 const struct w1_uart_config *w1cfg = bit ? &w1dev->cfg_touch_1 : in w1_uart_touch_bit()
345 &w1dev->cfg_touch_0; in w1_uart_touch_bit()
355 return val == w1cfg->tx_byte ? 1 : 0; in w1_uart_touch_bit()
360 struct device *dev = &serdev->dev; in w1_uart_probe()
366 return -ENOMEM; in w1_uart_probe()
367 w1dev->bus.data = w1dev; in w1_uart_probe()
368 w1dev->bus.reset_bus = w1_uart_reset_bus; in w1_uart_probe()
369 w1dev->bus.touch_bit = w1_uart_touch_bit; in w1_uart_probe()
370 w1dev->serdev = serdev; in w1_uart_probe()
372 init_completion(&w1dev->rx_byte_received); in w1_uart_probe()
373 mutex_init(&w1dev->rx_mutex); in w1_uart_probe()
381 return w1_add_master_device(&w1dev->bus); in w1_uart_probe()
389 * Waits until w1-uart callbacks are finished, serdev is closed in w1_uart_remove()
391 * until serdev-receive is finished). in w1_uart_remove()
393 w1_remove_master_device(&w1dev->bus); in w1_uart_remove()
397 { .compatible = "w1-uart" },
404 .name = "w1-uart",