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