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  
26  enum 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  #define CEC_NUM_PIN_EVENTS				128
168  #define CEC_PIN_EVENT_FL_IS_HIGH			(1 << 0)
169  #define CEC_PIN_EVENT_FL_DROPPED			(1 << 1)
170  
171  #define CEC_PIN_IRQ_UNCHANGED	0
172  #define CEC_PIN_IRQ_DISABLE	1
173  #define CEC_PIN_IRQ_ENABLE	2
174  
175  struct cec_pin {
176  	struct cec_adapter		*adap;
177  	const struct cec_pin_ops	*ops;
178  	struct task_struct		*kthread;
179  	wait_queue_head_t		kthread_waitq;
180  	struct hrtimer			timer;
181  	ktime_t				ts;
182  	unsigned int			wait_usecs;
183  	u16				la_mask;
184  	bool				monitor_all;
185  	bool				rx_eom;
186  	bool				enabled_irq;
187  	bool				enable_irq_failed;
188  	enum cec_pin_state		state;
189  	struct cec_msg			tx_msg;
190  	u32				tx_bit;
191  	bool				tx_nacked;
192  	u32				tx_signal_free_time;
193  	bool				tx_toggle;
194  	struct cec_msg			rx_msg;
195  	u32				rx_bit;
196  	bool				rx_toggle;
197  	u32				rx_start_bit_low_too_short_cnt;
198  	u64				rx_start_bit_low_too_short_ts;
199  	u32				rx_start_bit_low_too_short_delta;
200  	u32				rx_start_bit_too_short_cnt;
201  	u64				rx_start_bit_too_short_ts;
202  	u32				rx_start_bit_too_short_delta;
203  	u32				rx_start_bit_too_long_cnt;
204  	u32				rx_data_bit_too_short_cnt;
205  	u64				rx_data_bit_too_short_ts;
206  	u32				rx_data_bit_too_short_delta;
207  	u32				rx_data_bit_too_long_cnt;
208  	u32				rx_low_drive_cnt;
209  
210  	struct cec_msg			work_rx_msg;
211  	u8				work_tx_status;
212  	ktime_t				work_tx_ts;
213  	atomic_t			work_irq_change;
214  	atomic_t			work_pin_num_events;
215  	unsigned int			work_pin_events_wr;
216  	unsigned int			work_pin_events_rd;
217  	ktime_t				work_pin_ts[CEC_NUM_PIN_EVENTS];
218  	u8				work_pin_events[CEC_NUM_PIN_EVENTS];
219  	bool				work_pin_events_dropped;
220  	u32				work_pin_events_dropped_cnt;
221  	ktime_t				timer_ts;
222  	u32				timer_cnt;
223  	u32				timer_100us_overruns;
224  	u32				timer_300us_overruns;
225  	u32				timer_max_overrun;
226  	u32				timer_sum_overrun;
227  
228  	u32				tx_custom_low_usecs;
229  	u32				tx_custom_high_usecs;
230  	bool				tx_ignore_nack_until_eom;
231  	bool				tx_custom_pulse;
232  	bool				tx_generated_poll;
233  	bool				tx_post_eom;
234  	u8				tx_extra_bytes;
235  	u32				tx_low_drive_cnt;
236  #ifdef CONFIG_CEC_PIN_ERROR_INJ
237  	u64				error_inj[CEC_ERROR_INJ_OP_ANY + 1];
238  	u8				error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
239  #endif
240  };
241  
242  void cec_pin_start_timer(struct cec_pin *pin);
243  
244  #ifdef CONFIG_CEC_PIN_ERROR_INJ
245  bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
246  int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
247  
248  u16 cec_pin_rx_error_inj(struct cec_pin *pin);
249  u16 cec_pin_tx_error_inj(struct cec_pin *pin);
250  #endif
251  
252  #endif
253