drivers/media/cec/core/cec-pin.c

Source file repositories/reference/linux-study-clean/drivers/media/cec/core/cec-pin.c

File Facts

System
Linux kernel
Corpus path
drivers/media/cec/core/cec-pin.c
Extension
.c
Size
39255 bytes
Lines
1398
Domain
Driver Families
Bucket
drivers/media
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 cec_state {
	const char * const name;
	unsigned int usecs;
};

static const struct cec_state states[CEC_PIN_STATES] = {
	{ "Off",		   0 },
	{ "Idle",		   CEC_TIM_IDLE_SAMPLE },
	{ "Tx Wait",		   CEC_TIM_SAMPLE },
	{ "Tx Wait for High",	   CEC_TIM_IDLE_SAMPLE },
	{ "Tx Start Bit Low",	   CEC_TIM_START_BIT_LOW },
	{ "Tx Start Bit High",	   CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW },
	{ "Tx Start Bit High Short", CEC_TIM_START_BIT_TOTAL_SHORT - CEC_TIM_START_BIT_LOW },
	{ "Tx Start Bit High Long", CEC_TIM_START_BIT_TOTAL_LONG - CEC_TIM_START_BIT_LOW },
	{ "Tx Start Bit Low Custom", 0 },
	{ "Tx Start Bit High Custom", 0 },
	{ "Tx Data 0 Low",	   CEC_TIM_DATA_BIT_0_LOW },
	{ "Tx Data 0 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW },
	{ "Tx Data 0 High Short",  CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_0_LOW },
	{ "Tx Data 0 High Long",   CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_0_LOW },
	{ "Tx Data 1 Low",	   CEC_TIM_DATA_BIT_1_LOW },
	{ "Tx Data 1 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW },
	{ "Tx Data 1 High Short",  CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_1_LOW },
	{ "Tx Data 1 High Long",   CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_1_LOW },
	{ "Tx Data 1 High Pre Sample", CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW },
	{ "Tx Data 1 High Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE },
	{ "Tx Data 1 High Post Sample Short", CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_SAMPLE },
	{ "Tx Data 1 High Post Sample Long", CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_SAMPLE },
	{ "Tx Data Bit Low Custom", 0 },
	{ "Tx Data Bit High Custom", 0 },
	{ "Tx Pulse Low Custom",   0 },
	{ "Tx Pulse High Custom",  0 },
	{ "Tx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
	{ "Rx Start Bit Low",	   CEC_TIM_SAMPLE },
	{ "Rx Start Bit High",	   CEC_TIM_SAMPLE },
	{ "Rx Data Sample",	   CEC_TIM_DATA_BIT_SAMPLE },
	{ "Rx Data Post Sample",   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE },
	{ "Rx Data Wait for Low",  CEC_TIM_SAMPLE },
	{ "Rx Ack Low",		   CEC_TIM_DATA_BIT_0_LOW },
	{ "Rx Ack Low Post",	   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW },
	{ "Rx Ack High Post",	   CEC_TIM_DATA_BIT_HIGH },
	{ "Rx Ack Finish",	   CEC_TIM_DATA_BIT_TOTAL_MIN - CEC_TIM_DATA_BIT_HIGH },
	{ "Rx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
	{ "Rx Irq",		   0 },
};

static void cec_pin_update(struct cec_pin *pin, bool v, bool force)
{
	if (!force && v == pin->adap->cec_pin_is_high)
		return;

	pin->adap->cec_pin_is_high = v;
	if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) {
		u8 ev = v;

		if (pin->work_pin_events_dropped) {
			pin->work_pin_events_dropped = false;
			ev |= CEC_PIN_EVENT_FL_DROPPED;
		}
		pin->work_pin_events[pin->work_pin_events_wr] = ev;
		pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get();
		pin->work_pin_events_wr =
			(pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS;
		atomic_inc(&pin->work_pin_num_events);
	} else {
		pin->work_pin_events_dropped = true;
		pin->work_pin_events_dropped_cnt++;
	}
	wake_up_interruptible(&pin->kthread_waitq);
}

static bool cec_pin_read(struct cec_pin *pin)
{
	bool v = call_pin_op(pin, read);

	cec_pin_update(pin, v, false);
	return v;
}

static void cec_pin_insert_glitch(struct cec_pin *pin, bool rising_edge)
{
	/*
	 * Insert a short glitch after the falling or rising edge to
	 * simulate reflections on the CEC line. This can be used to
	 * test deglitch filters, which should be present in CEC devices
	 * to deal with noise on the line.
	 */
	if (!pin->tx_glitch_high_usecs || !pin->tx_glitch_low_usecs)
		return;
	if (rising_edge) {

Annotation

Implementation Notes