GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / media / cec / core / cec-pin-priv.h
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                            enable_irq_failed;
187         enum cec_pin_state              state;
188         struct cec_msg                  tx_msg;
189         u32                             tx_bit;
190         bool                            tx_nacked;
191         u32                             tx_signal_free_time;
192         bool                            tx_toggle;
193         struct cec_msg                  rx_msg;
194         u32                             rx_bit;
195         bool                            rx_toggle;
196         u32                             rx_start_bit_low_too_short_cnt;
197         u64                             rx_start_bit_low_too_short_ts;
198         u32                             rx_start_bit_low_too_short_delta;
199         u32                             rx_start_bit_too_short_cnt;
200         u64                             rx_start_bit_too_short_ts;
201         u32                             rx_start_bit_too_short_delta;
202         u32                             rx_start_bit_too_long_cnt;
203         u32                             rx_data_bit_too_short_cnt;
204         u64                             rx_data_bit_too_short_ts;
205         u32                             rx_data_bit_too_short_delta;
206         u32                             rx_data_bit_too_long_cnt;
207         u32                             rx_low_drive_cnt;
208
209         struct cec_msg                  work_rx_msg;
210         u8                              work_tx_status;
211         ktime_t                         work_tx_ts;
212         atomic_t                        work_irq_change;
213         atomic_t                        work_pin_num_events;
214         unsigned int                    work_pin_events_wr;
215         unsigned int                    work_pin_events_rd;
216         ktime_t                         work_pin_ts[CEC_NUM_PIN_EVENTS];
217         u8                              work_pin_events[CEC_NUM_PIN_EVENTS];
218         bool                            work_pin_events_dropped;
219         u32                             work_pin_events_dropped_cnt;
220         ktime_t                         timer_ts;
221         u32                             timer_cnt;
222         u32                             timer_100us_overruns;
223         u32                             timer_300us_overruns;
224         u32                             timer_max_overrun;
225         u32                             timer_sum_overrun;
226
227         u32                             tx_custom_low_usecs;
228         u32                             tx_custom_high_usecs;
229         bool                            tx_ignore_nack_until_eom;
230         bool                            tx_custom_pulse;
231         bool                            tx_generated_poll;
232         bool                            tx_post_eom;
233         u8                              tx_extra_bytes;
234         u32                             tx_low_drive_cnt;
235 #ifdef CONFIG_CEC_PIN_ERROR_INJ
236         u64                             error_inj[CEC_ERROR_INJ_OP_ANY + 1];
237         u8                              error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
238 #endif
239 };
240
241 void cec_pin_start_timer(struct cec_pin *pin);
242
243 #ifdef CONFIG_CEC_PIN_ERROR_INJ
244 bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
245 int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
246
247 u16 cec_pin_rx_error_inj(struct cec_pin *pin);
248 u16 cec_pin_tx_error_inj(struct cec_pin *pin);
249 #endif
250
251 #endif