Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * cec-pin-priv.h - internal cec-pin header
0004  *
0005  * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
0006  */
0007 
0008 #ifndef LINUX_CEC_PIN_PRIV_H
0009 #define LINUX_CEC_PIN_PRIV_H
0010 
0011 #include <linux/types.h>
0012 #include <linux/atomic.h>
0013 #include <media/cec-pin.h>
0014 
0015 #define call_pin_op(pin, op, arg...)                    \
0016     ((pin && pin->ops->op && !pin->adap->devnode.unregistered) ?    \
0017      pin->ops->op(pin->adap, ## arg) : 0)
0018 
0019 #define call_void_pin_op(pin, op, arg...)               \
0020     do {                                \
0021         if (pin && pin->ops->op &&              \
0022             !pin->adap->devnode.unregistered)           \
0023             pin->ops->op(pin->adap, ## arg);        \
0024     } while (0)
0025 
0026 enum cec_pin_state {
0027     /* CEC is off */
0028     CEC_ST_OFF,
0029     /* CEC is idle, waiting for Rx or Tx */
0030     CEC_ST_IDLE,
0031 
0032     /* Tx states */
0033 
0034     /* Pending Tx, waiting for Signal Free Time to expire */
0035     CEC_ST_TX_WAIT,
0036     /* Low-drive was detected, wait for bus to go high */
0037     CEC_ST_TX_WAIT_FOR_HIGH,
0038     /* Drive CEC low for the start bit */
0039     CEC_ST_TX_START_BIT_LOW,
0040     /* Drive CEC high for the start bit */
0041     CEC_ST_TX_START_BIT_HIGH,
0042     /* Generate a start bit period that is too short */
0043     CEC_ST_TX_START_BIT_HIGH_SHORT,
0044     /* Generate a start bit period that is too long */
0045     CEC_ST_TX_START_BIT_HIGH_LONG,
0046     /* Drive CEC low for the start bit using the custom timing */
0047     CEC_ST_TX_START_BIT_LOW_CUSTOM,
0048     /* Drive CEC high for the start bit using the custom timing */
0049     CEC_ST_TX_START_BIT_HIGH_CUSTOM,
0050     /* Drive CEC low for the 0 bit */
0051     CEC_ST_TX_DATA_BIT_0_LOW,
0052     /* Drive CEC high for the 0 bit */
0053     CEC_ST_TX_DATA_BIT_0_HIGH,
0054     /* Generate a bit period that is too short */
0055     CEC_ST_TX_DATA_BIT_0_HIGH_SHORT,
0056     /* Generate a bit period that is too long */
0057     CEC_ST_TX_DATA_BIT_0_HIGH_LONG,
0058     /* Drive CEC low for the 1 bit */
0059     CEC_ST_TX_DATA_BIT_1_LOW,
0060     /* Drive CEC high for the 1 bit */
0061     CEC_ST_TX_DATA_BIT_1_HIGH,
0062     /* Generate a bit period that is too short */
0063     CEC_ST_TX_DATA_BIT_1_HIGH_SHORT,
0064     /* Generate a bit period that is too long */
0065     CEC_ST_TX_DATA_BIT_1_HIGH_LONG,
0066     /*
0067      * Wait for start of sample time to check for Ack bit or first
0068      * four initiator bits to check for Arbitration Lost.
0069      */
0070     CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
0071     /* Wait for end of bit period after sampling */
0072     CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
0073     /* Generate a bit period that is too short */
0074     CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT,
0075     /* Generate a bit period that is too long */
0076     CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG,
0077     /* Drive CEC low for a data bit using the custom timing */
0078     CEC_ST_TX_DATA_BIT_LOW_CUSTOM,
0079     /* Drive CEC high for a data bit using the custom timing */
0080     CEC_ST_TX_DATA_BIT_HIGH_CUSTOM,
0081     /* Drive CEC low for a standalone pulse using the custom timing */
0082     CEC_ST_TX_PULSE_LOW_CUSTOM,
0083     /* Drive CEC high for a standalone pulse using the custom timing */
0084     CEC_ST_TX_PULSE_HIGH_CUSTOM,
0085     /* Start low drive */
0086     CEC_ST_TX_LOW_DRIVE,
0087 
0088     /* Rx states */
0089 
0090     /* Start bit low detected */
0091     CEC_ST_RX_START_BIT_LOW,
0092     /* Start bit high detected */
0093     CEC_ST_RX_START_BIT_HIGH,
0094     /* Wait for bit sample time */
0095     CEC_ST_RX_DATA_SAMPLE,
0096     /* Wait for earliest end of bit period after sampling */
0097     CEC_ST_RX_DATA_POST_SAMPLE,
0098     /* Wait for CEC to go low (i.e. end of bit period) */
0099     CEC_ST_RX_DATA_WAIT_FOR_LOW,
0100     /* Drive CEC low to send 0 Ack bit */
0101     CEC_ST_RX_ACK_LOW,
0102     /* End of 0 Ack time, wait for earliest end of bit period */
0103     CEC_ST_RX_ACK_LOW_POST,
0104     /* Wait for CEC to go high (i.e. end of bit period */
0105     CEC_ST_RX_ACK_HIGH_POST,
0106     /* Wait for earliest end of bit period and end of message */
0107     CEC_ST_RX_ACK_FINISH,
0108     /* Start low drive */
0109     CEC_ST_RX_LOW_DRIVE,
0110 
0111     /* Monitor pin using interrupts */
0112     CEC_ST_RX_IRQ,
0113 
0114     /* Total number of pin states */
0115     CEC_PIN_STATES
0116 };
0117 
0118 /* Error Injection */
0119 
0120 /* Error injection modes */
0121 #define CEC_ERROR_INJ_MODE_OFF              0
0122 #define CEC_ERROR_INJ_MODE_ONCE             1
0123 #define CEC_ERROR_INJ_MODE_ALWAYS           2
0124 #define CEC_ERROR_INJ_MODE_TOGGLE           3
0125 #define CEC_ERROR_INJ_MODE_MASK             3ULL
0126 
0127 /* Receive error injection options */
0128 #define CEC_ERROR_INJ_RX_NACK_OFFSET            0
0129 #define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET       2
0130 #define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET        4
0131 #define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET     6
0132 #define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET        8
0133 #define CEC_ERROR_INJ_RX_MASK               0xffffULL
0134 
0135 /* Transmit error injection options */
0136 #define CEC_ERROR_INJ_TX_NO_EOM_OFFSET          16
0137 #define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET       18
0138 #define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET       20
0139 #define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET        22
0140 #define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET      24
0141 #define CEC_ERROR_INJ_TX_SHORT_START_OFFSET     26
0142 #define CEC_ERROR_INJ_TX_LONG_START_OFFSET      28
0143 #define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET        30
0144 #define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET        32
0145 #define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET       34
0146 #define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET     36
0147 #define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET       38
0148 #define CEC_ERROR_INJ_TX_MASK               0xffffffffffff0000ULL
0149 
0150 #define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX      0
0151 #define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX       1
0152 
0153 #define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX      2
0154 #define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX      3
0155 #define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX       4
0156 #define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX     5
0157 #define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX       6
0158 #define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX      7
0159 #define CEC_ERROR_INJ_NUM_ARGS              8
0160 
0161 /* Special CEC op values */
0162 #define CEC_ERROR_INJ_OP_ANY                0x00000100
0163 
0164 /* The default for the low/high time of the custom pulse */
0165 #define CEC_TIM_CUSTOM_DEFAULT              1000
0166 
0167 #define CEC_NUM_PIN_EVENTS              128
0168 #define CEC_PIN_EVENT_FL_IS_HIGH            (1 << 0)
0169 #define CEC_PIN_EVENT_FL_DROPPED            (1 << 1)
0170 
0171 #define CEC_PIN_IRQ_UNCHANGED   0
0172 #define CEC_PIN_IRQ_DISABLE 1
0173 #define CEC_PIN_IRQ_ENABLE  2
0174 
0175 struct cec_pin {
0176     struct cec_adapter      *adap;
0177     const struct cec_pin_ops    *ops;
0178     struct task_struct      *kthread;
0179     wait_queue_head_t       kthread_waitq;
0180     struct hrtimer          timer;
0181     ktime_t             ts;
0182     unsigned int            wait_usecs;
0183     u16             la_mask;
0184     bool                monitor_all;
0185     bool                rx_eom;
0186     bool                enable_irq_failed;
0187     enum cec_pin_state      state;
0188     struct cec_msg          tx_msg;
0189     u32             tx_bit;
0190     bool                tx_nacked;
0191     u32             tx_signal_free_time;
0192     bool                tx_toggle;
0193     struct cec_msg          rx_msg;
0194     u32             rx_bit;
0195     bool                rx_toggle;
0196     u32             rx_start_bit_low_too_short_cnt;
0197     u64             rx_start_bit_low_too_short_ts;
0198     u32             rx_start_bit_low_too_short_delta;
0199     u32             rx_start_bit_too_short_cnt;
0200     u64             rx_start_bit_too_short_ts;
0201     u32             rx_start_bit_too_short_delta;
0202     u32             rx_start_bit_too_long_cnt;
0203     u32             rx_data_bit_too_short_cnt;
0204     u64             rx_data_bit_too_short_ts;
0205     u32             rx_data_bit_too_short_delta;
0206     u32             rx_data_bit_too_long_cnt;
0207     u32             rx_low_drive_cnt;
0208 
0209     struct cec_msg          work_rx_msg;
0210     u8              work_tx_status;
0211     ktime_t             work_tx_ts;
0212     atomic_t            work_irq_change;
0213     atomic_t            work_pin_num_events;
0214     unsigned int            work_pin_events_wr;
0215     unsigned int            work_pin_events_rd;
0216     ktime_t             work_pin_ts[CEC_NUM_PIN_EVENTS];
0217     u8              work_pin_events[CEC_NUM_PIN_EVENTS];
0218     bool                work_pin_events_dropped;
0219     u32             work_pin_events_dropped_cnt;
0220     ktime_t             timer_ts;
0221     u32             timer_cnt;
0222     u32             timer_100us_overruns;
0223     u32             timer_300us_overruns;
0224     u32             timer_max_overrun;
0225     u32             timer_sum_overrun;
0226 
0227     u32             tx_custom_low_usecs;
0228     u32             tx_custom_high_usecs;
0229     bool                tx_ignore_nack_until_eom;
0230     bool                tx_custom_pulse;
0231     bool                tx_generated_poll;
0232     bool                tx_post_eom;
0233     u8              tx_extra_bytes;
0234     u32             tx_low_drive_cnt;
0235 #ifdef CONFIG_CEC_PIN_ERROR_INJ
0236     u64             error_inj[CEC_ERROR_INJ_OP_ANY + 1];
0237     u8              error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
0238 #endif
0239 };
0240 
0241 void cec_pin_start_timer(struct cec_pin *pin);
0242 
0243 #ifdef CONFIG_CEC_PIN_ERROR_INJ
0244 bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
0245 int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
0246 
0247 u16 cec_pin_rx_error_inj(struct cec_pin *pin);
0248 u16 cec_pin_tx_error_inj(struct cec_pin *pin);
0249 #endif
0250 
0251 #endif