drivers/gpio/gpio-line-mux.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-line-mux.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-line-mux.c
Extension
.c
Size
3014 bytes
Lines
117
Domain
Driver Families
Bucket
drivers/gpio
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 gpio_lmux {
	struct gpio_chip gc;
	struct mux_control *mux;
	struct gpio_desc *muxed_gpio;

	u32 num_gpio_mux_states;
	unsigned int gpio_mux_states[] __counted_by(num_gpio_mux_states);
};

static int gpio_lmux_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_lmux *glm = gpiochip_get_data(gc);
	int ret;

	ret = mux_control_select_delay(glm->mux, glm->gpio_mux_states[offset],
				       MUX_SELECT_DELAY_US);
	if (ret < 0)
		return ret;

	ret = gpiod_get_raw_value_cansleep(glm->muxed_gpio);
	mux_control_deselect(glm->mux);
	return ret;
}

static int gpio_lmux_gpio_get_direction(struct gpio_chip *gc,
					unsigned int offset)
{
	return GPIO_LINE_DIRECTION_IN;
}

static int gpio_lmux_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct gpio_lmux *glm;
	unsigned int ngpio;
	size_t size;
	int ret;

	ngpio = device_property_count_u32(dev, "gpio-line-mux-states");
	if (!ngpio)
		return -EINVAL;

	size = struct_size(glm, gpio_mux_states, ngpio);
	glm = devm_kzalloc(dev, size, GFP_KERNEL);
	if (!glm)
		return -ENOMEM;

	glm->gc.base = -1;
	glm->gc.can_sleep = true;
	glm->gc.fwnode = dev_fwnode(dev);
	glm->gc.label = dev_name(dev);
	glm->gc.ngpio = ngpio;
	glm->gc.owner = THIS_MODULE;
	glm->gc.parent = dev;

	glm->gc.get = gpio_lmux_gpio_get;
	glm->gc.get_direction = gpio_lmux_gpio_get_direction;

	glm->mux = devm_mux_control_get(dev, NULL);
	if (IS_ERR(glm->mux))
		return dev_err_probe(dev, PTR_ERR(glm->mux),
				     "could not get mux controller\n");

	glm->muxed_gpio = devm_gpiod_get(dev, "muxed", GPIOD_IN);
	if (IS_ERR(glm->muxed_gpio))
		return dev_err_probe(dev, PTR_ERR(glm->muxed_gpio),
				     "could not get muxed-gpio\n");

	glm->num_gpio_mux_states = ngpio;
	ret = device_property_read_u32_array(dev, "gpio-line-mux-states",
					     &glm->gpio_mux_states[0], ngpio);
	if (ret)
		return dev_err_probe(dev, ret, "could not get mux states\n");

	ret = devm_gpiochip_add_data(dev, &glm->gc, glm);
	if (ret)
		return dev_err_probe(dev, ret, "failed to add gpiochip\n");

	return 0;
}

static const struct of_device_id gpio_lmux_of_match[] = {
	{ .compatible = "gpio-line-mux" },
	{ }
};
MODULE_DEVICE_TABLE(of, gpio_lmux_of_match);

static struct platform_driver gpio_lmux_driver = {
	.driver = {
		.name = "gpio-line-mux",

Annotation

Implementation Notes