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 enum cec_pin_state { 16 /* CEC is off */ 17 CEC_ST_OFF, 18 /* CEC is idle, waiting for Rx or Tx */ 19 CEC_ST_IDLE, 20 21 /* Tx states */ 22 23 /* Pending Tx, waiting for Signal Free Time to expire */ 24 CEC_ST_TX_WAIT, 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, 55 /* 56 * Wait for start of sample time to check for Ack bit or first 57 * four initiator bits to check for Arbitration Lost. 58 */ 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, 74 /* Start low drive */ 75 CEC_ST_TX_LOW_DRIVE, 76 77 /* Rx states */ 78 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 */ 90 CEC_ST_RX_ACK_LOW, 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 */ 96 CEC_ST_RX_ACK_FINISH, 97 /* Start low drive */ 98 CEC_ST_RX_LOW_DRIVE, 99 100 /* Monitor pin using interrupts */ 101 CEC_ST_RX_IRQ, 102 103 /* Total number of pin states */ 104 CEC_PIN_STATES 105 }; 106 107 /* Error Injection */ 108 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 115 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 123 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 138 139 #define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX 0 140 #define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX 1 141 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 149 150 /* Special CEC op values */ 151 #define CEC_ERROR_INJ_OP_ANY 0x00000100 152 153 /* The default for the low/high time of the custom pulse */ 154 #define CEC_TIM_CUSTOM_DEFAULT 1000 155 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) 159 160 #define CEC_PIN_IRQ_UNCHANGED 0 161 #define CEC_PIN_IRQ_DISABLE 1 162 #define CEC_PIN_IRQ_ENABLE 2 163 164 struct cec_pin { 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; 170 ktime_t ts; 171 unsigned int wait_usecs; 172 u16 la_mask; 173 bool monitor_all; 174 bool rx_eom; 175 bool enable_irq_failed; 176 enum cec_pin_state state; 177 struct cec_msg tx_msg; 178 u32 tx_bit; 179 bool tx_nacked; 180 u32 tx_signal_free_time; 181 bool tx_toggle; 182 struct cec_msg rx_msg; 183 u32 rx_bit; 184 bool rx_toggle; 185 u32 rx_start_bit_low_too_short_cnt; 186 u64 rx_start_bit_low_too_short_ts; 187 u32 rx_start_bit_low_too_short_delta; 188 u32 rx_start_bit_too_short_cnt; 189 u64 rx_start_bit_too_short_ts; 190 u32 rx_start_bit_too_short_delta; 191 u32 rx_start_bit_too_long_cnt; 192 u32 rx_data_bit_too_short_cnt; 193 u64 rx_data_bit_too_short_ts; 194 u32 rx_data_bit_too_short_delta; 195 u32 rx_data_bit_too_long_cnt; 196 u32 rx_low_drive_cnt; 197 198 struct cec_msg work_rx_msg; 199 u8 work_tx_status; 200 ktime_t work_tx_ts; 201 atomic_t work_irq_change; 202 atomic_t work_pin_num_events; 203 unsigned int work_pin_events_wr; 204 unsigned int work_pin_events_rd; 205 ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS]; 206 u8 work_pin_events[CEC_NUM_PIN_EVENTS]; 207 bool work_pin_events_dropped; 208 u32 work_pin_events_dropped_cnt; 209 ktime_t timer_ts; 210 u32 timer_cnt; 211 u32 timer_100us_overruns; 212 u32 timer_300us_overruns; 213 u32 timer_max_overrun; 214 u32 timer_sum_overrun; 215 216 u32 tx_custom_low_usecs; 217 u32 tx_custom_high_usecs; 218 bool tx_ignore_nack_until_eom; 219 bool tx_custom_pulse; 220 bool tx_generated_poll; 221 bool tx_post_eom; 222 u8 tx_extra_bytes; 223 u32 tx_low_drive_cnt; 224 #ifdef CONFIG_CEC_PIN_ERROR_INJ 225 u64 error_inj[CEC_ERROR_INJ_OP_ANY + 1]; 226 u8 error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS]; 227 #endif 228 }; 229 230 void cec_pin_start_timer(struct cec_pin *pin); 231 232 #ifdef CONFIG_CEC_PIN_ERROR_INJ 233 bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line); 234 int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf); 235 236 u16 cec_pin_rx_error_inj(struct cec_pin *pin); 237 u16 cec_pin_tx_error_inj(struct cec_pin *pin); 238 #endif 239 240 #endif 241