drivers/gpu/drm/amd/display/dc/gpio/hw_gpio.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/gpio/hw_gpio.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/gpio/hw_gpio.c
Extension
.c
Size
5287 bytes
Lines
205
Domain
Driver Families
Bucket
drivers/gpu
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

#include "dm_services.h"
#include "include/gpio_types.h"
#include "hw_gpio.h"

#include "reg_helper.h"
#include "gpio_regs.h"

#undef FN
#define FN(reg_name, field_name) \
	gpio_reg_shift(gpio->regs->field_name ## _shift), gpio->regs->field_name ## _mask

#define CTX \
	gpio->base.ctx
#define REG(reg)\
	(gpio->regs->reg)

static void store_registers(
	struct hw_gpio *gpio)
{
	REG_GET(MASK_reg, MASK, &gpio->store.mask);
	REG_GET(A_reg, A, &gpio->store.a);
	REG_GET(EN_reg, EN, &gpio->store.en);
	/* TODO store GPIO_MUX_CONTROL if we ever use it */
}

static void restore_registers(
	struct hw_gpio *gpio)
{
	REG_UPDATE(MASK_reg, MASK, gpio->store.mask);
	REG_UPDATE(A_reg, A, gpio->store.a);
	REG_UPDATE(EN_reg, EN, gpio->store.en);
	/* TODO restore GPIO_MUX_CONTROL if we ever use it */
}

bool dal_hw_gpio_open(
	struct hw_gpio_pin *ptr,
	enum gpio_mode mode)
{
	struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);

	store_registers(pin);

	ptr->opened = (dal_hw_gpio_config_mode(pin, mode) == GPIO_RESULT_OK);

	return ptr->opened;
}

enum gpio_result dal_hw_gpio_get_value(
	const struct hw_gpio_pin *ptr,
	uint32_t *value)
{
	const struct hw_gpio *gpio = FROM_HW_GPIO_PIN(ptr);

	enum gpio_result result = GPIO_RESULT_OK;

	switch (ptr->mode) {
	case GPIO_MODE_INPUT:
	case GPIO_MODE_OUTPUT:
	case GPIO_MODE_HARDWARE:
	case GPIO_MODE_FAST_OUTPUT:
		REG_GET(Y_reg, Y, value);
		break;
	default:
		result = GPIO_RESULT_NON_SPECIFIC_ERROR;
	}

	return result;
}

enum gpio_result dal_hw_gpio_set_value(
	const struct hw_gpio_pin *ptr,
	uint32_t value)
{
	struct hw_gpio *gpio = FROM_HW_GPIO_PIN(ptr);

	/* This is the public interface
	 * where the input comes from client, not shifted yet
	 * (because client does not know the shifts). */

	switch (ptr->mode) {
	case GPIO_MODE_OUTPUT:
		REG_UPDATE(A_reg, A, value);
		return GPIO_RESULT_OK;
	case GPIO_MODE_FAST_OUTPUT:
		/* We use (EN) to faster switch (used in DDC GPIO).
		 * So (A) is grounded, output is driven by (EN = 0)
		 * to pull the line down (output == 0) and (EN=1)
		 * then output is tri-state */
		REG_UPDATE(EN_reg, EN, ~value);
		return GPIO_RESULT_OK;

Annotation

Implementation Notes