drivers/media/cec/platform/cec-gpio/cec-gpio.c

Source file repositories/reference/linux-study-clean/drivers/media/cec/platform/cec-gpio/cec-gpio.c

File Facts

System
Linux kernel
Corpus path
drivers/media/cec/platform/cec-gpio/cec-gpio.c
Extension
.c
Size
6985 bytes
Lines
297
Domain
Driver Families
Bucket
drivers/media
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 cec_gpio {
	struct cec_adapter	*adap;
	struct cec_notifier	*notifier;
	struct device		*dev;

	struct gpio_desc	*cec_gpio;
	int			cec_irq;
	bool			cec_is_low;

	struct gpio_desc	*hpd_gpio;
	int			hpd_irq;
	bool			hpd_is_high;
	ktime_t			hpd_ts;

	struct gpio_desc	*v5_gpio;
	int			v5_irq;
	bool			v5_is_high;
	ktime_t			v5_ts;
};

static int cec_gpio_read(struct cec_adapter *adap)
{
	struct cec_gpio *cec = cec_get_drvdata(adap);

	if (cec->cec_is_low)
		return 0;
	return gpiod_get_value(cec->cec_gpio);
}

static void cec_gpio_high(struct cec_adapter *adap)
{
	struct cec_gpio *cec = cec_get_drvdata(adap);

	if (!cec->cec_is_low)
		return;
	cec->cec_is_low = false;
	gpiod_set_value(cec->cec_gpio, 1);
}

static void cec_gpio_low(struct cec_adapter *adap)
{
	struct cec_gpio *cec = cec_get_drvdata(adap);

	if (cec->cec_is_low)
		return;
	cec->cec_is_low = true;
	gpiod_set_value(cec->cec_gpio, 0);
}

static irqreturn_t cec_gpio_5v_irq_handler_thread(int irq, void *priv)
{
	struct cec_gpio *cec = priv;
	int val = gpiod_get_value_cansleep(cec->v5_gpio);
	bool is_high = val > 0;

	if (val < 0 || is_high == cec->v5_is_high)
		return IRQ_HANDLED;

	cec->v5_is_high = is_high;
	cec_queue_pin_5v_event(cec->adap, cec->v5_is_high, cec->v5_ts);
	return IRQ_HANDLED;
}

static irqreturn_t cec_gpio_5v_irq_handler(int irq, void *priv)
{
	struct cec_gpio *cec = priv;

	cec->v5_ts = ktime_get();
	return IRQ_WAKE_THREAD;
}

static irqreturn_t cec_gpio_hpd_irq_handler_thread(int irq, void *priv)
{
	struct cec_gpio *cec = priv;
	int val = gpiod_get_value_cansleep(cec->hpd_gpio);
	bool is_high = val > 0;

	if (val < 0 || is_high == cec->hpd_is_high)
		return IRQ_HANDLED;

	cec->hpd_is_high = is_high;
	cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
	return IRQ_HANDLED;
}

static irqreturn_t cec_gpio_hpd_irq_handler(int irq, void *priv)
{
	struct cec_gpio *cec = priv;

	cec->hpd_ts = ktime_get();

Annotation

Implementation Notes