File Index
Files and directories
Sign in
FILE

cec-pin-priv.h

File preview with syntax highlighting.

linux-6.19.14/drivers/media/cec/core/cec-pin-priv.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * cec-pin-priv.h - internal cec-pin header
  4 *
  5 * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
  6 */
  7
  8#ifndef LINUX_CEC_PIN_PRIV_H
  9#define LINUX_CEC_PIN_PRIV_H
 10
 11#include <linux/types.h>
 12#include <linux/atomic.h>
 13#include <media/cec-pin.h>
 14
 15#define call_pin_op(pin, op, arg...)					\
 16	((pin && pin->ops->op && !pin->adap->devnode.unregistered) ?	\
 17	 pin->ops->op(pin->adap, ## arg) : 0)
 18
 19#define call_void_pin_op(pin, op, arg...)				\
 20	do {								\
 21		if (pin && pin->ops->op &&				\
 22		    !pin->adap->devnode.unregistered)			\
 23			pin->ops->op(pin->adap, ## arg);		\
 24	} while (0)
 25
 26enum cec_pin_state {
 27	/* CEC is off */
 28	CEC_ST_OFF,
 29	/* CEC is idle, waiting for Rx or Tx */
 30	CEC_ST_IDLE,
 31
 32	/* Tx states */
 33
 34	/* Pending Tx, waiting for Signal Free Time to expire */
 35	CEC_ST_TX_WAIT,
 36	/* Low-drive was detected, wait for bus to go high */
 37	CEC_ST_TX_WAIT_FOR_HIGH,
 38	/* Drive CEC low for the start bit */
 39	CEC_ST_TX_START_BIT_LOW,
 40	/* Drive CEC high for the start bit */
 41	CEC_ST_TX_START_BIT_HIGH,
 42	/* Generate a start bit period that is too short */
 43	CEC_ST_TX_START_BIT_HIGH_SHORT,
 44	/* Generate a start bit period that is too long */
 45	CEC_ST_TX_START_BIT_HIGH_LONG,
 46	/* Drive CEC low for the start bit using the custom timing */
 47	CEC_ST_TX_START_BIT_LOW_CUSTOM,
 48	/* Drive CEC high for the start bit using the custom timing */
 49	CEC_ST_TX_START_BIT_HIGH_CUSTOM,
 50	/* Drive CEC low for the 0 bit */
 51	CEC_ST_TX_DATA_BIT_0_LOW,
 52	/* Drive CEC high for the 0 bit */
 53	CEC_ST_TX_DATA_BIT_0_HIGH,
 54	/* Generate a bit period that is too short */
 55	CEC_ST_TX_DATA_BIT_0_HIGH_SHORT,
 56	/* Generate a bit period that is too long */
 57	CEC_ST_TX_DATA_BIT_0_HIGH_LONG,
 58	/* Drive CEC low for the 1 bit */
 59	CEC_ST_TX_DATA_BIT_1_LOW,
 60	/* Drive CEC high for the 1 bit */
 61	CEC_ST_TX_DATA_BIT_1_HIGH,
 62	/* Generate a bit period that is too short */
 63	CEC_ST_TX_DATA_BIT_1_HIGH_SHORT,
 64	/* Generate a bit period that is too long */
 65	CEC_ST_TX_DATA_BIT_1_HIGH_LONG,
 66	/*
 67	 * Wait for start of sample time to check for Ack bit or first
 68	 * four initiator bits to check for Arbitration Lost.
 69	 */
 70	CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
 71	/* Wait for end of bit period after sampling */
 72	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
 73	/* Generate a bit period that is too short */
 74	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT,
 75	/* Generate a bit period that is too long */
 76	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG,
 77	/* Drive CEC low for a data bit using the custom timing */
 78	CEC_ST_TX_DATA_BIT_LOW_CUSTOM,
 79	/* Drive CEC high for a data bit using the custom timing */
 80	CEC_ST_TX_DATA_BIT_HIGH_CUSTOM,
 81	/* Drive CEC low for a standalone pulse using the custom timing */
 82	CEC_ST_TX_PULSE_LOW_CUSTOM,
 83	/* Drive CEC high for a standalone pulse using the custom timing */
 84	CEC_ST_TX_PULSE_HIGH_CUSTOM,
 85	/* Start low drive */
 86	CEC_ST_TX_LOW_DRIVE,
 87
 88	/* Rx states */
 89
 90	/* Start bit low detected */
 91	CEC_ST_RX_START_BIT_LOW,
 92	/* Start bit high detected */
 93	CEC_ST_RX_START_BIT_HIGH,
 94	/* Wait for bit sample time */
 95	CEC_ST_RX_DATA_SAMPLE,
 96	/* Wait for earliest end of bit period after sampling */
 97	CEC_ST_RX_DATA_POST_SAMPLE,
 98	/* Wait for CEC to go low (i.e. end of bit period) */
 99	CEC_ST_RX_DATA_WAIT_FOR_LOW,
100	/* Drive CEC low to send 0 Ack bit */
101	CEC_ST_RX_ACK_LOW,
102	/* End of 0 Ack time, wait for earliest end of bit period */
103	CEC_ST_RX_ACK_LOW_POST,
104	/* Wait for CEC to go high (i.e. end of bit period */
105	CEC_ST_RX_ACK_HIGH_POST,
106	/* Wait for earliest end of bit period and end of message */
107	CEC_ST_RX_ACK_FINISH,
108	/* Start low drive */
109	CEC_ST_RX_LOW_DRIVE,
110
111	/* Monitor pin using interrupts */
112	CEC_ST_RX_IRQ,
113
114	/* Total number of pin states */
115	CEC_PIN_STATES
116};
117
118/* Error Injection */
119
120/* Error injection modes */
121#define CEC_ERROR_INJ_MODE_OFF				0
122#define CEC_ERROR_INJ_MODE_ONCE				1
123#define CEC_ERROR_INJ_MODE_ALWAYS			2
124#define CEC_ERROR_INJ_MODE_TOGGLE			3
125#define CEC_ERROR_INJ_MODE_MASK				3ULL
126
127/* Receive error injection options */
128#define CEC_ERROR_INJ_RX_NACK_OFFSET			0
129#define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET		2
130#define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET		4
131#define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET		6
132#define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET		8
133#define CEC_ERROR_INJ_RX_MASK				0xffffULL
134
135/* Transmit error injection options */
136#define CEC_ERROR_INJ_TX_NO_EOM_OFFSET			16
137#define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET		18
138#define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET		20
139#define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET		22
140#define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET		24
141#define CEC_ERROR_INJ_TX_SHORT_START_OFFSET		26
142#define CEC_ERROR_INJ_TX_LONG_START_OFFSET		28
143#define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET		30
144#define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET		32
145#define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET		34
146#define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET		36
147#define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET		38
148#define CEC_ERROR_INJ_TX_MASK				0xffffffffffff0000ULL
149
150#define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX		0
151#define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX		1
152
153#define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX		2
154#define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX		3
155#define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX		4
156#define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX		5
157#define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX		6
158#define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX		7
159#define CEC_ERROR_INJ_NUM_ARGS				8
160
161/* Special CEC op values */
162#define CEC_ERROR_INJ_OP_ANY				0x00000100
163
164/* The default for the low/high time of the custom pulse */
165#define CEC_TIM_CUSTOM_DEFAULT				1000
166
167/* The default for the low/high time of the glitch pulse */
168#define CEC_TIM_GLITCH_DEFAULT				1
169
170#define CEC_NUM_PIN_EVENTS				128
171#define CEC_PIN_EVENT_FL_IS_HIGH			(1 << 0)
172#define CEC_PIN_EVENT_FL_DROPPED			(1 << 1)
173
174#define CEC_PIN_IRQ_UNCHANGED	0
175#define CEC_PIN_IRQ_DISABLE	1
176#define CEC_PIN_IRQ_ENABLE	2
177
178struct cec_pin {
179	struct cec_adapter		*adap;
180	const struct cec_pin_ops	*ops;
181	struct task_struct		*kthread;
182	wait_queue_head_t		kthread_waitq;
183	struct hrtimer			timer;
184	ktime_t				ts;
185	unsigned int			wait_usecs;
186	u16				la_mask;
187	bool				monitor_all;
188	bool				rx_eom;
189	bool				enabled_irq;
190	bool				enable_irq_failed;
191	enum cec_pin_state		state;
192	struct cec_msg			tx_msg;
193	u32				tx_bit;
194	bool				tx_nacked;
195	u32				tx_signal_free_time;
196	bool				tx_toggle;
197	struct cec_msg			rx_msg;
198	u32				rx_bit;
199	bool				rx_toggle;
200	u32				rx_start_bit_low_too_short_cnt;
201	u64				rx_start_bit_low_too_short_ts;
202	u32				rx_start_bit_low_too_short_delta;
203	u32				rx_start_bit_too_short_cnt;
204	u64				rx_start_bit_too_short_ts;
205	u32				rx_start_bit_too_short_delta;
206	u32				rx_start_bit_too_long_cnt;
207	u32				rx_data_bit_too_short_cnt;
208	u64				rx_data_bit_too_short_ts;
209	u32				rx_data_bit_too_short_delta;
210	u32				rx_data_bit_too_long_cnt;
211	u32				rx_low_drive_cnt;
212
213	struct cec_msg			work_rx_msg;
214	u8				work_tx_status;
215	ktime_t				work_tx_ts;
216	atomic_t			work_irq_change;
217	atomic_t			work_pin_num_events;
218	unsigned int			work_pin_events_wr;
219	unsigned int			work_pin_events_rd;
220	ktime_t				work_pin_ts[CEC_NUM_PIN_EVENTS];
221	u8				work_pin_events[CEC_NUM_PIN_EVENTS];
222	bool				work_pin_events_dropped;
223	u32				work_pin_events_dropped_cnt;
224	ktime_t				timer_ts;
225	u32				timer_cnt;
226	u32				timer_100us_overruns;
227	u32				timer_300us_overruns;
228	u32				timer_max_overrun;
229	u32				timer_sum_overrun;
230
231	bool				rx_no_low_drive;
232	u32				tx_custom_low_usecs;
233	u32				tx_custom_high_usecs;
234	u32				tx_glitch_low_usecs;
235	u32				tx_glitch_high_usecs;
236	bool				tx_ignore_nack_until_eom;
237	bool				tx_custom_pulse;
238	bool				tx_generated_poll;
239	bool				tx_post_eom;
240	bool				tx_glitch_falling_edge;
241	bool				tx_glitch_rising_edge;
242	u8				tx_extra_bytes;
243	u32				tx_low_drive_cnt;
244#ifdef CONFIG_CEC_PIN_ERROR_INJ
245	u64				error_inj[CEC_ERROR_INJ_OP_ANY + 1];
246	u8				error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
247#endif
248};
249
250void cec_pin_start_timer(struct cec_pin *pin);
251
252#ifdef CONFIG_CEC_PIN_ERROR_INJ
253bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
254int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
255
256u16 cec_pin_rx_error_inj(struct cec_pin *pin);
257u16 cec_pin_tx_error_inj(struct cec_pin *pin);
258#endif
259
260#endif
~/ Read-only file preview.