123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * cec-pin-priv.h - internal cec-pin header
- *
- * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
- #ifndef LINUX_CEC_PIN_PRIV_H
- #define LINUX_CEC_PIN_PRIV_H
- #include <linux/types.h>
- #include <linux/atomic.h>
- #include <media/cec-pin.h>
- enum cec_pin_state {
- /* CEC is off */
- CEC_ST_OFF,
- /* CEC is idle, waiting for Rx or Tx */
- CEC_ST_IDLE,
- /* Tx states */
- /* Pending Tx, waiting for Signal Free Time to expire */
- CEC_ST_TX_WAIT,
- /* Low-drive was detected, wait for bus to go high */
- CEC_ST_TX_WAIT_FOR_HIGH,
- /* Drive CEC low for the start bit */
- CEC_ST_TX_START_BIT_LOW,
- /* Drive CEC high for the start bit */
- CEC_ST_TX_START_BIT_HIGH,
- /* Generate a start bit period that is too short */
- CEC_ST_TX_START_BIT_HIGH_SHORT,
- /* Generate a start bit period that is too long */
- CEC_ST_TX_START_BIT_HIGH_LONG,
- /* Drive CEC low for the start bit using the custom timing */
- CEC_ST_TX_START_BIT_LOW_CUSTOM,
- /* Drive CEC high for the start bit using the custom timing */
- CEC_ST_TX_START_BIT_HIGH_CUSTOM,
- /* Drive CEC low for the 0 bit */
- CEC_ST_TX_DATA_BIT_0_LOW,
- /* Drive CEC high for the 0 bit */
- CEC_ST_TX_DATA_BIT_0_HIGH,
- /* Generate a bit period that is too short */
- CEC_ST_TX_DATA_BIT_0_HIGH_SHORT,
- /* Generate a bit period that is too long */
- CEC_ST_TX_DATA_BIT_0_HIGH_LONG,
- /* Drive CEC low for the 1 bit */
- CEC_ST_TX_DATA_BIT_1_LOW,
- /* Drive CEC high for the 1 bit */
- CEC_ST_TX_DATA_BIT_1_HIGH,
- /* Generate a bit period that is too short */
- CEC_ST_TX_DATA_BIT_1_HIGH_SHORT,
- /* Generate a bit period that is too long */
- CEC_ST_TX_DATA_BIT_1_HIGH_LONG,
- /*
- * Wait for start of sample time to check for Ack bit or first
- * four initiator bits to check for Arbitration Lost.
- */
- CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
- /* Wait for end of bit period after sampling */
- CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
- /* Generate a bit period that is too short */
- CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT,
- /* Generate a bit period that is too long */
- CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG,
- /* Drive CEC low for a data bit using the custom timing */
- CEC_ST_TX_DATA_BIT_LOW_CUSTOM,
- /* Drive CEC high for a data bit using the custom timing */
- CEC_ST_TX_DATA_BIT_HIGH_CUSTOM,
- /* Drive CEC low for a standalone pulse using the custom timing */
- CEC_ST_TX_PULSE_LOW_CUSTOM,
- /* Drive CEC high for a standalone pulse using the custom timing */
- CEC_ST_TX_PULSE_HIGH_CUSTOM,
- /* Start low drive */
- CEC_ST_TX_LOW_DRIVE,
- /* Rx states */
- /* Start bit low detected */
- CEC_ST_RX_START_BIT_LOW,
- /* Start bit high detected */
- CEC_ST_RX_START_BIT_HIGH,
- /* Wait for bit sample time */
- CEC_ST_RX_DATA_SAMPLE,
- /* Wait for earliest end of bit period after sampling */
- CEC_ST_RX_DATA_POST_SAMPLE,
- /* Wait for CEC to go low (i.e. end of bit period) */
- CEC_ST_RX_DATA_WAIT_FOR_LOW,
- /* Drive CEC low to send 0 Ack bit */
- CEC_ST_RX_ACK_LOW,
- /* End of 0 Ack time, wait for earliest end of bit period */
- CEC_ST_RX_ACK_LOW_POST,
- /* Wait for CEC to go high (i.e. end of bit period */
- CEC_ST_RX_ACK_HIGH_POST,
- /* Wait for earliest end of bit period and end of message */
- CEC_ST_RX_ACK_FINISH,
- /* Start low drive */
- CEC_ST_RX_LOW_DRIVE,
- /* Monitor pin using interrupts */
- CEC_ST_RX_IRQ,
- /* Total number of pin states */
- CEC_PIN_STATES
- };
- /* Error Injection */
- /* Error injection modes */
- #define CEC_ERROR_INJ_MODE_OFF 0
- #define CEC_ERROR_INJ_MODE_ONCE 1
- #define CEC_ERROR_INJ_MODE_ALWAYS 2
- #define CEC_ERROR_INJ_MODE_TOGGLE 3
- #define CEC_ERROR_INJ_MODE_MASK 3ULL
- /* Receive error injection options */
- #define CEC_ERROR_INJ_RX_NACK_OFFSET 0
- #define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET 2
- #define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET 4
- #define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET 6
- #define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET 8
- #define CEC_ERROR_INJ_RX_MASK 0xffffULL
- /* Transmit error injection options */
- #define CEC_ERROR_INJ_TX_NO_EOM_OFFSET 16
- #define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET 18
- #define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET 20
- #define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET 22
- #define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET 24
- #define CEC_ERROR_INJ_TX_SHORT_START_OFFSET 26
- #define CEC_ERROR_INJ_TX_LONG_START_OFFSET 28
- #define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET 30
- #define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET 32
- #define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET 34
- #define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET 36
- #define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET 38
- #define CEC_ERROR_INJ_TX_MASK 0xffffffffffff0000ULL
- #define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX 0
- #define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX 1
- #define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX 2
- #define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX 3
- #define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX 4
- #define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX 5
- #define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX 6
- #define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX 7
- #define CEC_ERROR_INJ_NUM_ARGS 8
- /* Special CEC op values */
- #define CEC_ERROR_INJ_OP_ANY 0x00000100
- /* The default for the low/high time of the custom pulse */
- #define CEC_TIM_CUSTOM_DEFAULT 1000
- #define CEC_NUM_PIN_EVENTS 128
- #define CEC_PIN_EVENT_FL_IS_HIGH (1 << 0)
- #define CEC_PIN_EVENT_FL_DROPPED (1 << 1)
- #define CEC_PIN_IRQ_UNCHANGED 0
- #define CEC_PIN_IRQ_DISABLE 1
- #define CEC_PIN_IRQ_ENABLE 2
- struct cec_pin {
- struct cec_adapter *adap;
- const struct cec_pin_ops *ops;
- struct task_struct *kthread;
- wait_queue_head_t kthread_waitq;
- struct hrtimer timer;
- ktime_t ts;
- unsigned int wait_usecs;
- u16 la_mask;
- bool enabled;
- bool monitor_all;
- bool rx_eom;
- bool enable_irq_failed;
- enum cec_pin_state state;
- struct cec_msg tx_msg;
- u32 tx_bit;
- bool tx_nacked;
- u32 tx_signal_free_time;
- bool tx_toggle;
- struct cec_msg rx_msg;
- u32 rx_bit;
- bool rx_toggle;
- u32 rx_start_bit_low_too_short_cnt;
- u64 rx_start_bit_low_too_short_ts;
- u32 rx_start_bit_low_too_short_delta;
- u32 rx_start_bit_too_short_cnt;
- u64 rx_start_bit_too_short_ts;
- u32 rx_start_bit_too_short_delta;
- u32 rx_start_bit_too_long_cnt;
- u32 rx_data_bit_too_short_cnt;
- u64 rx_data_bit_too_short_ts;
- u32 rx_data_bit_too_short_delta;
- u32 rx_data_bit_too_long_cnt;
- u32 rx_low_drive_cnt;
- struct cec_msg work_rx_msg;
- u8 work_tx_status;
- ktime_t work_tx_ts;
- atomic_t work_irq_change;
- atomic_t work_pin_num_events;
- unsigned int work_pin_events_wr;
- unsigned int work_pin_events_rd;
- ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS];
- u8 work_pin_events[CEC_NUM_PIN_EVENTS];
- bool work_pin_events_dropped;
- u32 work_pin_events_dropped_cnt;
- ktime_t timer_ts;
- u32 timer_cnt;
- u32 timer_100ms_overruns;
- u32 timer_300ms_overruns;
- u32 timer_max_overrun;
- u32 timer_sum_overrun;
- u32 tx_custom_low_usecs;
- u32 tx_custom_high_usecs;
- bool tx_ignore_nack_until_eom;
- bool tx_custom_pulse;
- bool tx_generated_poll;
- bool tx_post_eom;
- u8 tx_extra_bytes;
- u32 tx_low_drive_cnt;
- #ifdef CONFIG_CEC_PIN_ERROR_INJ
- u64 error_inj[CEC_ERROR_INJ_OP_ANY + 1];
- u8 error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
- #endif
- };
- void cec_pin_start_timer(struct cec_pin *pin);
- #ifdef CONFIG_CEC_PIN_ERROR_INJ
- bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
- int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
- u16 cec_pin_rx_error_inj(struct cec_pin *pin);
- u16 cec_pin_tx_error_inj(struct cec_pin *pin);
- #endif
- #endif
|