drivers/w1/masters/w1-uart.c

Source file repositories/reference/linux-study-clean/drivers/w1/masters/w1-uart.c

File Facts

System
Linux kernel
Corpus path
drivers/w1/masters/w1-uart.c
Extension
.c
Size
10614 bytes
Lines
416
Domain
Driver Families
Bucket
drivers/w1
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct w1_uart_config {
	unsigned int baudrate;
	unsigned int delay_us;
	u8 tx_byte;
};

/**
 * struct w1_uart_device - 1-Wire UART device structure
 * @serdev: serial device
 * @bus: w1-bus master
 * @cfg_reset: config for 1-Wire reset
 * @cfg_touch_0: config for 1-Wire write-0 cycle
 * @cfg_touch_1: config for 1-Wire write-1 and read cycle
 * @rx_byte_received: completion for serdev receive
 * @rx_mutex: mutex to protect rx_err and rx_byte
 * @rx_err: indicates an error in serdev-receive
 * @rx_byte: result byte from serdev-receive
 */
struct w1_uart_device {
	struct serdev_device *serdev;
	struct w1_bus_master bus;

	struct w1_uart_config cfg_reset;
	struct w1_uart_config cfg_touch_0;
	struct w1_uart_config cfg_touch_1;

	struct completion rx_byte_received;
	/*
	 * protect rx_err and rx_byte from concurrent access in
	 * w1-callbacks and serdev-receive.
	 */
	struct mutex rx_mutex;
	int rx_err;
	u8 rx_byte;
};

/**
 * struct w1_uart_limits - limits for 1-Wire operations
 * @baudrate: Requested baud-rate to create 1-Wire timing pattern
 * @bit_min_us: minimum time for a bit (in us)
 * @bit_max_us: maximum time for a bit (in us)
 * @sample_us: timespan to sample 1-Wire response
 * @cycle_us: duration of the 1-Wire cycle
 */
struct w1_uart_limits {
	unsigned int baudrate;
	unsigned int bit_min_us;
	unsigned int bit_max_us;
	unsigned int sample_us;
	unsigned int cycle_us;
};

static inline unsigned int baud_to_bit_ns(unsigned int baud)
{
	return NSEC_PER_SEC / baud;
}

static inline unsigned int to_ns(unsigned int us)
{
	return us * NSEC_PER_USEC;
}

/*
 * Set baud-rate, delay and tx-byte to create a 1-Wire pulse and adapt
 * the tx-byte according to the actual baud-rate.
 *
 * Reject when:
 * - time for a bit outside min/max range
 * - a 1-Wire response is not detectable for sent byte
 */
static int w1_uart_set_config(struct serdev_device *serdev,
			      const struct w1_uart_limits *limits,
			      struct w1_uart_config *w1cfg)
{
	unsigned int packet_ns;
	unsigned int bits_low;
	unsigned int bit_ns;
	unsigned int low_ns;

	w1cfg->baudrate = serdev_device_set_baudrate(serdev, limits->baudrate);
	if (w1cfg->baudrate == 0)
		return -EINVAL;

	/* Compute in nanoseconds for accuracy */
	bit_ns = baud_to_bit_ns(w1cfg->baudrate);
	bits_low = to_ns(limits->bit_min_us) / bit_ns;
	/* start bit is always low */
	low_ns = bit_ns * (bits_low + 1);

	if (low_ns < to_ns(limits->bit_min_us))

Annotation

Implementation Notes