1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * cec-pin-priv.h - internal cec-pin header
5 * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8 #ifndef LINUX_CEC_PIN_PRIV_H
9 #define LINUX_CEC_PIN_PRIV_H
11 #include <linux/types.h>
12 #include <linux/atomic.h>
13 #include <media/cec-pin.h>
18 /* CEC is idle, waiting for Rx or Tx */
23 /* Pending Tx, waiting for Signal Free Time to expire */
25 /* Low-drive was detected, wait for bus to go high */
26 CEC_ST_TX_WAIT_FOR_HIGH
,
27 /* Drive CEC low for the start bit */
28 CEC_ST_TX_START_BIT_LOW
,
29 /* Drive CEC high for the start bit */
30 CEC_ST_TX_START_BIT_HIGH
,
31 /* Generate a start bit period that is too short */
32 CEC_ST_TX_START_BIT_HIGH_SHORT
,
33 /* Generate a start bit period that is too long */
34 CEC_ST_TX_START_BIT_HIGH_LONG
,
35 /* Drive CEC low for the start bit using the custom timing */
36 CEC_ST_TX_START_BIT_LOW_CUSTOM
,
37 /* Drive CEC high for the start bit using the custom timing */
38 CEC_ST_TX_START_BIT_HIGH_CUSTOM
,
39 /* Drive CEC low for the 0 bit */
40 CEC_ST_TX_DATA_BIT_0_LOW
,
41 /* Drive CEC high for the 0 bit */
42 CEC_ST_TX_DATA_BIT_0_HIGH
,
43 /* Generate a bit period that is too short */
44 CEC_ST_TX_DATA_BIT_0_HIGH_SHORT
,
45 /* Generate a bit period that is too long */
46 CEC_ST_TX_DATA_BIT_0_HIGH_LONG
,
47 /* Drive CEC low for the 1 bit */
48 CEC_ST_TX_DATA_BIT_1_LOW
,
49 /* Drive CEC high for the 1 bit */
50 CEC_ST_TX_DATA_BIT_1_HIGH
,
51 /* Generate a bit period that is too short */
52 CEC_ST_TX_DATA_BIT_1_HIGH_SHORT
,
53 /* Generate a bit period that is too long */
54 CEC_ST_TX_DATA_BIT_1_HIGH_LONG
,
56 * Wait for start of sample time to check for Ack bit or first
57 * four initiator bits to check for Arbitration Lost.
59 CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE
,
60 /* Wait for end of bit period after sampling */
61 CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE
,
62 /* Generate a bit period that is too short */
63 CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT
,
64 /* Generate a bit period that is too long */
65 CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG
,
66 /* Drive CEC low for a data bit using the custom timing */
67 CEC_ST_TX_DATA_BIT_LOW_CUSTOM
,
68 /* Drive CEC high for a data bit using the custom timing */
69 CEC_ST_TX_DATA_BIT_HIGH_CUSTOM
,
70 /* Drive CEC low for a standalone pulse using the custom timing */
71 CEC_ST_TX_PULSE_LOW_CUSTOM
,
72 /* Drive CEC high for a standalone pulse using the custom timing */
73 CEC_ST_TX_PULSE_HIGH_CUSTOM
,
79 /* Start bit low detected */
80 CEC_ST_RX_START_BIT_LOW
,
81 /* Start bit high detected */
82 CEC_ST_RX_START_BIT_HIGH
,
83 /* Wait for bit sample time */
84 CEC_ST_RX_DATA_SAMPLE
,
85 /* Wait for earliest end of bit period after sampling */
86 CEC_ST_RX_DATA_POST_SAMPLE
,
87 /* Wait for CEC to go low (i.e. end of bit period) */
88 CEC_ST_RX_DATA_WAIT_FOR_LOW
,
89 /* Drive CEC low to send 0 Ack bit */
91 /* End of 0 Ack time, wait for earliest end of bit period */
92 CEC_ST_RX_ACK_LOW_POST
,
93 /* Wait for CEC to go high (i.e. end of bit period */
94 CEC_ST_RX_ACK_HIGH_POST
,
95 /* Wait for earliest end of bit period and end of message */
100 /* Monitor pin using interrupts */
103 /* Total number of pin states */
107 /* Error Injection */
109 /* Error injection modes */
110 #define CEC_ERROR_INJ_MODE_OFF 0
111 #define CEC_ERROR_INJ_MODE_ONCE 1
112 #define CEC_ERROR_INJ_MODE_ALWAYS 2
113 #define CEC_ERROR_INJ_MODE_TOGGLE 3
114 #define CEC_ERROR_INJ_MODE_MASK 3ULL
116 /* Receive error injection options */
117 #define CEC_ERROR_INJ_RX_NACK_OFFSET 0
118 #define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET 2
119 #define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET 4
120 #define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET 6
121 #define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET 8
122 #define CEC_ERROR_INJ_RX_MASK 0xffffULL
124 /* Transmit error injection options */
125 #define CEC_ERROR_INJ_TX_NO_EOM_OFFSET 16
126 #define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET 18
127 #define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET 20
128 #define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET 22
129 #define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET 24
130 #define CEC_ERROR_INJ_TX_SHORT_START_OFFSET 26
131 #define CEC_ERROR_INJ_TX_LONG_START_OFFSET 28
132 #define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET 30
133 #define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET 32
134 #define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET 34
135 #define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET 36
136 #define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET 38
137 #define CEC_ERROR_INJ_TX_MASK 0xffffffffffff0000ULL
139 #define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX 0
140 #define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX 1
142 #define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX 2
143 #define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX 3
144 #define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX 4
145 #define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX 5
146 #define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX 6
147 #define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX 7
148 #define CEC_ERROR_INJ_NUM_ARGS 8
150 /* Special CEC op values */
151 #define CEC_ERROR_INJ_OP_ANY 0x00000100
153 /* The default for the low/high time of the custom pulse */
154 #define CEC_TIM_CUSTOM_DEFAULT 1000
156 #define CEC_NUM_PIN_EVENTS 128
157 #define CEC_PIN_EVENT_FL_IS_HIGH (1 << 0)
158 #define CEC_PIN_EVENT_FL_DROPPED (1 << 1)
160 #define CEC_PIN_IRQ_UNCHANGED 0
161 #define CEC_PIN_IRQ_DISABLE 1
162 #define CEC_PIN_IRQ_ENABLE 2
165 struct cec_adapter
*adap
;
166 const struct cec_pin_ops
*ops
;
167 struct task_struct
*kthread
;
168 wait_queue_head_t kthread_waitq
;
169 struct hrtimer timer
;
171 unsigned int wait_usecs
;
176 bool enable_irq_failed
;
177 enum cec_pin_state state
;
178 struct cec_msg tx_msg
;
181 u32 tx_signal_free_time
;
183 struct cec_msg rx_msg
;
186 u32 rx_start_bit_low_too_short_cnt
;
187 u64 rx_start_bit_low_too_short_ts
;
188 u32 rx_start_bit_low_too_short_delta
;
189 u32 rx_start_bit_too_short_cnt
;
190 u64 rx_start_bit_too_short_ts
;
191 u32 rx_start_bit_too_short_delta
;
192 u32 rx_start_bit_too_long_cnt
;
193 u32 rx_data_bit_too_short_cnt
;
194 u64 rx_data_bit_too_short_ts
;
195 u32 rx_data_bit_too_short_delta
;
196 u32 rx_data_bit_too_long_cnt
;
197 u32 rx_low_drive_cnt
;
199 struct cec_msg work_rx_msg
;
202 atomic_t work_irq_change
;
203 atomic_t work_pin_num_events
;
204 unsigned int work_pin_events_wr
;
205 unsigned int work_pin_events_rd
;
206 ktime_t work_pin_ts
[CEC_NUM_PIN_EVENTS
];
207 u8 work_pin_events
[CEC_NUM_PIN_EVENTS
];
208 bool work_pin_events_dropped
;
209 u32 work_pin_events_dropped_cnt
;
212 u32 timer_100ms_overruns
;
213 u32 timer_300ms_overruns
;
214 u32 timer_max_overrun
;
215 u32 timer_sum_overrun
;
217 u32 tx_custom_low_usecs
;
218 u32 tx_custom_high_usecs
;
219 bool tx_ignore_nack_until_eom
;
220 bool tx_custom_pulse
;
221 bool tx_generated_poll
;
224 u32 tx_low_drive_cnt
;
225 #ifdef CONFIG_CEC_PIN_ERROR_INJ
226 u64 error_inj
[CEC_ERROR_INJ_OP_ANY
+ 1];
227 u8 error_inj_args
[CEC_ERROR_INJ_OP_ANY
+ 1][CEC_ERROR_INJ_NUM_ARGS
];
231 void cec_pin_start_timer(struct cec_pin
*pin
);
233 #ifdef CONFIG_CEC_PIN_ERROR_INJ
234 bool cec_pin_error_inj_parse_line(struct cec_adapter
*adap
, char *line
);
235 int cec_pin_error_inj_show(struct cec_adapter
*adap
, struct seq_file
*sf
);
237 u16
cec_pin_rx_error_inj(struct cec_pin
*pin
);
238 u16
cec_pin_tx_error_inj(struct cec_pin
*pin
);