drivers/tty/serial/serial_mctrl_gpio.c

Source file repositories/reference/linux-study-clean/drivers/tty/serial/serial_mctrl_gpio.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/serial/serial_mctrl_gpio.c
Extension
.c
Size
8885 bytes
Lines
384
Domain
Driver Families
Bucket
drivers/tty
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 mctrl_gpios {
	struct uart_port *port;
	struct gpio_desc *gpio[UART_GPIO_MAX];
	int irq[UART_GPIO_MAX];
	unsigned int mctrl_prev;
	bool mctrl_on;
};

static const struct {
	const char *name;
	unsigned int mctrl;
	enum gpiod_flags flags;
} mctrl_gpios_desc[UART_GPIO_MAX] = {
	{ "cts", TIOCM_CTS, GPIOD_IN, },
	{ "dsr", TIOCM_DSR, GPIOD_IN, },
	{ "dcd", TIOCM_CD,  GPIOD_IN, },
	{ "rng", TIOCM_RNG, GPIOD_IN, },
	{ "rts", TIOCM_RTS, GPIOD_OUT_LOW, },
	{ "dtr", TIOCM_DTR, GPIOD_OUT_LOW, },
};

static bool mctrl_gpio_flags_is_dir_out(unsigned int idx)
{
	return mctrl_gpios_desc[idx].flags & GPIOD_FLAGS_BIT_DIR_OUT;
}

/**
 * mctrl_gpio_set - set gpios according to mctrl state
 * @gpios: gpios to set
 * @mctrl: state to set
 *
 * Set the gpios according to the mctrl state.
 */
void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
{
	enum mctrl_gpio_idx i;
	struct gpio_desc *desc_array[UART_GPIO_MAX];
	DECLARE_BITMAP(values, UART_GPIO_MAX);
	unsigned int count = 0;

	if (gpios == NULL)
		return;

	for (i = 0; i < UART_GPIO_MAX; i++)
		if (gpios->gpio[i] && mctrl_gpio_flags_is_dir_out(i)) {
			desc_array[count] = gpios->gpio[i];
			__assign_bit(count, values,
				     mctrl & mctrl_gpios_desc[i].mctrl);
			count++;
		}
	gpiod_set_array_value(count, desc_array, NULL, values);
}
EXPORT_SYMBOL_GPL(mctrl_gpio_set);

/**
 * mctrl_gpio_to_gpiod - obtain gpio_desc of modem line index
 * @gpios: gpios to look into
 * @gidx: index of the modem line
 * Returns: the gpio_desc structure associated to the modem line index
 */
struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios,
				      enum mctrl_gpio_idx gidx)
{
	if (gpios == NULL)
		return NULL;

	return gpios->gpio[gidx];
}
EXPORT_SYMBOL_GPL(mctrl_gpio_to_gpiod);

/**
 * mctrl_gpio_get - update mctrl with the gpios values.
 * @gpios: gpios to get the info from
 * @mctrl: mctrl to set
 * Returns: modified mctrl (the same value as in @mctrl)
 *
 * Update mctrl with the gpios values.
 */
unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl)
{
	enum mctrl_gpio_idx i;

	if (gpios == NULL)
		return *mctrl;

	for (i = 0; i < UART_GPIO_MAX; i++) {
		if (gpios->gpio[i] && !mctrl_gpio_flags_is_dir_out(i)) {
			if (gpiod_get_value(gpios->gpio[i]))
				*mctrl |= mctrl_gpios_desc[i].mctrl;
			else

Annotation

Implementation Notes