drivers/gpio/gpio-zynqmp-modepin.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-zynqmp-modepin.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-zynqmp-modepin.c
Extension
.c
Size
4256 bytes
Lines
166
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the ps-mode pin configuration.
 *
 * Copyright (c) 2021 Xilinx, Inc.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/firmware/xlnx-zynqmp.h>

/* 4-bit boot mode pins */
#define MODE_PINS			4

/**
 * modepin_gpio_get_value - Get the state of the specified pin of GPIO device
 * @chip:	gpio_chip instance to be worked on
 * @pin:	gpio pin number within the device
 *
 * This function reads the state of the specified pin of the GPIO device.
 *
 * Return: 0 if the pin is low, 1 if pin is high, -EINVAL wrong pin configured
 *         or error value.
 */
static int modepin_gpio_get_value(struct gpio_chip *chip, unsigned int pin)
{
	u32 regval = 0;
	int ret;

	ret = zynqmp_pm_bootmode_read(&regval);
	if (ret)
		return ret;

	/* When [0:3] corresponding bit is set, then read output bit [8:11],
	 * if the bit is clear then read input bit [4:7] for status or value.
	 */
	if (regval & BIT(pin))
		return !!(regval & BIT(pin + 8));
	else
		return !!(regval & BIT(pin + 4));
}

/**
 * modepin_gpio_set_value - Modify the state of the pin with specified value
 * @chip:	gpio_chip instance to be worked on
 * @pin:	gpio pin number within the device
 * @state:	value used to modify the state of the specified pin
 *
 * This function reads the state of the specified pin of the GPIO device, mask
 * with the capture state of GPIO pin, and update pin of GPIO device.
 *
 * Return:	None.
 */
static int modepin_gpio_set_value(struct gpio_chip *chip, unsigned int pin,
				  int state)
{
	u32 bootpin_val = 0;
	int ret;

	zynqmp_pm_bootmode_read(&bootpin_val);

	/* Configure pin as an output by set bit [0:3] */
	bootpin_val |= BIT(pin);

	if (state)
		bootpin_val |= BIT(pin + 8);
	else
		bootpin_val &= ~BIT(pin + 8);

	/* Configure bootpin value */
	ret = zynqmp_pm_bootmode_write(bootpin_val);
	if (ret)
		pr_err("modepin: set value error %d for pin %d\n", ret, pin);

	return ret;
}

/**
 * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input
 * @chip:	gpio_chip instance to be worked on
 * @pin:	gpio pin number within the device
 *
 * Return: 0 always
 */

Annotation

Implementation Notes