Lines Matching full:pin
10 #include <media/cec-pin.h>
11 #include "cec-pin-priv.h"
111 static void cec_pin_update(struct cec_pin *pin, bool v, bool force) in cec_pin_update() argument
113 if (!force && v == pin->adap->cec_pin_is_high) in cec_pin_update()
116 pin->adap->cec_pin_is_high = v; in cec_pin_update()
117 if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) { in cec_pin_update()
120 if (pin->work_pin_events_dropped) { in cec_pin_update()
121 pin->work_pin_events_dropped = false; in cec_pin_update()
124 pin->work_pin_events[pin->work_pin_events_wr] = ev; in cec_pin_update()
125 pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get(); in cec_pin_update()
126 pin->work_pin_events_wr = in cec_pin_update()
127 (pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS; in cec_pin_update()
128 atomic_inc(&pin->work_pin_num_events); in cec_pin_update()
130 pin->work_pin_events_dropped = true; in cec_pin_update()
131 pin->work_pin_events_dropped_cnt++; in cec_pin_update()
133 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_update()
136 static bool cec_pin_read(struct cec_pin *pin) in cec_pin_read() argument
138 bool v = call_pin_op(pin, read); in cec_pin_read()
140 cec_pin_update(pin, v, false); in cec_pin_read()
144 static void cec_pin_low(struct cec_pin *pin) in cec_pin_low() argument
146 call_void_pin_op(pin, low); in cec_pin_low()
147 cec_pin_update(pin, false, false); in cec_pin_low()
150 static bool cec_pin_high(struct cec_pin *pin) in cec_pin_high() argument
152 call_void_pin_op(pin, high); in cec_pin_high()
153 return cec_pin_read(pin); in cec_pin_high()
156 static bool rx_error_inj(struct cec_pin *pin, unsigned int mode_offset, in rx_error_inj() argument
160 u16 cmd = cec_pin_rx_error_inj(pin); in rx_error_inj()
161 u64 e = pin->error_inj[cmd]; in rx_error_inj()
165 u8 pos = pin->error_inj_args[cmd][arg_idx]; in rx_error_inj()
169 else if (pos != pin->rx_bit) in rx_error_inj()
175 pin->error_inj[cmd] &= in rx_error_inj()
181 return pin->rx_toggle; in rx_error_inj()
190 static bool rx_nack(struct cec_pin *pin) in rx_nack() argument
192 return rx_error_inj(pin, CEC_ERROR_INJ_RX_NACK_OFFSET, -1, NULL); in rx_nack()
195 static bool rx_low_drive(struct cec_pin *pin) in rx_low_drive() argument
197 return rx_error_inj(pin, CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET, in rx_low_drive()
201 static bool rx_add_byte(struct cec_pin *pin) in rx_add_byte() argument
203 return rx_error_inj(pin, CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, NULL); in rx_add_byte()
206 static bool rx_remove_byte(struct cec_pin *pin) in rx_remove_byte() argument
208 return rx_error_inj(pin, CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, NULL); in rx_remove_byte()
211 static bool rx_arb_lost(struct cec_pin *pin, u8 *poll) in rx_arb_lost() argument
213 return pin->tx_msg.len == 0 && in rx_arb_lost()
214 rx_error_inj(pin, CEC_ERROR_INJ_RX_ARB_LOST_OFFSET, in rx_arb_lost()
218 static bool tx_error_inj(struct cec_pin *pin, unsigned int mode_offset, in tx_error_inj() argument
222 u16 cmd = cec_pin_tx_error_inj(pin); in tx_error_inj()
223 u64 e = pin->error_inj[cmd]; in tx_error_inj()
227 u8 pos = pin->error_inj_args[cmd][arg_idx]; in tx_error_inj()
231 else if (pos != pin->tx_bit) in tx_error_inj()
237 pin->error_inj[cmd] &= in tx_error_inj()
243 return pin->tx_toggle; in tx_error_inj()
252 static bool tx_no_eom(struct cec_pin *pin) in tx_no_eom() argument
254 return tx_error_inj(pin, CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, NULL); in tx_no_eom()
257 static bool tx_early_eom(struct cec_pin *pin) in tx_early_eom() argument
259 return tx_error_inj(pin, CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, NULL); in tx_early_eom()
262 static bool tx_short_bit(struct cec_pin *pin) in tx_short_bit() argument
264 return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET, in tx_short_bit()
268 static bool tx_long_bit(struct cec_pin *pin) in tx_long_bit() argument
270 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_BIT_OFFSET, in tx_long_bit()
274 static bool tx_custom_bit(struct cec_pin *pin) in tx_custom_bit() argument
276 return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET, in tx_custom_bit()
280 static bool tx_short_start(struct cec_pin *pin) in tx_short_start() argument
282 return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, NULL); in tx_short_start()
285 static bool tx_long_start(struct cec_pin *pin) in tx_long_start() argument
287 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, NULL); in tx_long_start()
290 static bool tx_custom_start(struct cec_pin *pin) in tx_custom_start() argument
292 return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, in tx_custom_start()
296 static bool tx_last_bit(struct cec_pin *pin) in tx_last_bit() argument
298 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LAST_BIT_OFFSET, in tx_last_bit()
302 static u8 tx_add_bytes(struct cec_pin *pin) in tx_add_bytes() argument
306 if (tx_error_inj(pin, CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET, in tx_add_bytes()
312 static bool tx_remove_byte(struct cec_pin *pin) in tx_remove_byte() argument
314 return tx_error_inj(pin, CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, NULL); in tx_remove_byte()
317 static bool tx_low_drive(struct cec_pin *pin) in tx_low_drive() argument
319 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET, in tx_low_drive()
323 static void cec_pin_to_idle(struct cec_pin *pin) in cec_pin_to_idle() argument
329 pin->rx_bit = pin->tx_bit = 0; in cec_pin_to_idle()
330 pin->rx_msg.len = 0; in cec_pin_to_idle()
331 memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); in cec_pin_to_idle()
332 pin->ts = ns_to_ktime(0); in cec_pin_to_idle()
333 pin->tx_generated_poll = false; in cec_pin_to_idle()
334 pin->tx_post_eom = false; in cec_pin_to_idle()
335 if (pin->state >= CEC_ST_TX_WAIT && in cec_pin_to_idle()
336 pin->state <= CEC_ST_TX_LOW_DRIVE) in cec_pin_to_idle()
337 pin->tx_toggle ^= 1; in cec_pin_to_idle()
338 if (pin->state >= CEC_ST_RX_START_BIT_LOW && in cec_pin_to_idle()
339 pin->state <= CEC_ST_RX_LOW_DRIVE) in cec_pin_to_idle()
340 pin->rx_toggle ^= 1; in cec_pin_to_idle()
341 pin->state = CEC_ST_IDLE; in cec_pin_to_idle()
370 static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) in cec_pin_tx_states() argument
375 switch (pin->state) { in cec_pin_tx_states()
377 if (cec_pin_read(pin)) in cec_pin_tx_states()
378 cec_pin_to_idle(pin); in cec_pin_tx_states()
382 if (tx_short_start(pin)) { in cec_pin_tx_states()
387 pin->state = CEC_ST_TX_START_BIT_HIGH_SHORT; in cec_pin_tx_states()
388 } else if (tx_long_start(pin)) { in cec_pin_tx_states()
393 pin->state = CEC_ST_TX_START_BIT_HIGH_LONG; in cec_pin_tx_states()
395 pin->state = CEC_ST_TX_START_BIT_HIGH; in cec_pin_tx_states()
398 cec_pin_high(pin); in cec_pin_tx_states()
402 pin->state = CEC_ST_TX_START_BIT_HIGH_CUSTOM; in cec_pin_tx_states()
404 cec_pin_high(pin); in cec_pin_tx_states()
410 if (pin->tx_nacked) { in cec_pin_tx_states()
411 cec_pin_to_idle(pin); in cec_pin_tx_states()
412 pin->tx_msg.len = 0; in cec_pin_tx_states()
413 if (pin->tx_generated_poll) in cec_pin_tx_states()
415 pin->work_tx_ts = ts; in cec_pin_tx_states()
416 pin->work_tx_status = CEC_TX_STATUS_NACK; in cec_pin_tx_states()
417 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
433 * the pin can actually be low in that case. in cec_pin_tx_states()
435 if (!cec_pin_read(pin) && !pin->tx_generated_poll) { in cec_pin_tx_states()
440 pin->tx_msg.len = 0; in cec_pin_tx_states()
441 pin->state = CEC_ST_TX_WAIT_FOR_HIGH; in cec_pin_tx_states()
442 pin->work_tx_ts = ts; in cec_pin_tx_states()
443 pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; in cec_pin_tx_states()
444 pin->tx_low_drive_cnt++; in cec_pin_tx_states()
445 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
450 if (tx_last_bit(pin)) { in cec_pin_tx_states()
452 cec_pin_to_idle(pin); in cec_pin_tx_states()
453 pin->tx_msg.len = 0; in cec_pin_tx_states()
454 if (pin->tx_generated_poll) in cec_pin_tx_states()
456 pin->work_tx_ts = ts; in cec_pin_tx_states()
457 pin->work_tx_status = CEC_TX_STATUS_OK; in cec_pin_tx_states()
458 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
461 pin->tx_bit++; in cec_pin_tx_states()
467 if (tx_low_drive(pin)) { in cec_pin_tx_states()
469 cec_pin_low(pin); in cec_pin_tx_states()
470 pin->state = CEC_ST_TX_LOW_DRIVE; in cec_pin_tx_states()
471 pin->tx_msg.len = 0; in cec_pin_tx_states()
472 if (pin->tx_generated_poll) in cec_pin_tx_states()
474 pin->work_tx_ts = ts; in cec_pin_tx_states()
475 pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; in cec_pin_tx_states()
476 pin->tx_low_drive_cnt++; in cec_pin_tx_states()
477 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
480 if (pin->tx_bit / 10 >= pin->tx_msg.len + pin->tx_extra_bytes) { in cec_pin_tx_states()
481 cec_pin_to_idle(pin); in cec_pin_tx_states()
482 pin->tx_msg.len = 0; in cec_pin_tx_states()
483 if (pin->tx_generated_poll) in cec_pin_tx_states()
485 pin->work_tx_ts = ts; in cec_pin_tx_states()
486 pin->work_tx_status = CEC_TX_STATUS_OK; in cec_pin_tx_states()
487 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
491 switch (pin->tx_bit % 10) { in cec_pin_tx_states()
495 * extra bytes, so pin->tx_bit / 10 can become >= 16. in cec_pin_tx_states()
499 unsigned int idx = (pin->tx_bit / 10); in cec_pin_tx_states()
502 if (idx < pin->tx_msg.len) in cec_pin_tx_states()
503 val = pin->tx_msg.msg[idx]; in cec_pin_tx_states()
504 v = val & (1 << (7 - (pin->tx_bit % 10))); in cec_pin_tx_states()
506 pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : in cec_pin_tx_states()
511 unsigned int tot_len = pin->tx_msg.len + in cec_pin_tx_states()
512 pin->tx_extra_bytes; in cec_pin_tx_states()
513 unsigned int tx_byte_idx = pin->tx_bit / 10; in cec_pin_tx_states()
515 v = !pin->tx_post_eom && tx_byte_idx == tot_len - 1; in cec_pin_tx_states()
517 tx_early_eom(pin)) { in cec_pin_tx_states()
520 pin->tx_post_eom = true; in cec_pin_tx_states()
521 } else if (v && tx_no_eom(pin)) { in cec_pin_tx_states()
525 pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : in cec_pin_tx_states()
530 pin->state = CEC_ST_TX_DATA_BIT_1_LOW; in cec_pin_tx_states()
533 if (tx_custom_bit(pin)) in cec_pin_tx_states()
534 pin->state = CEC_ST_TX_DATA_BIT_LOW_CUSTOM; in cec_pin_tx_states()
535 cec_pin_low(pin); in cec_pin_tx_states()
540 v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW; in cec_pin_tx_states()
541 is_ack_bit = pin->tx_bit % 10 == ACK_BIT; in cec_pin_tx_states()
542 if (v && (pin->tx_bit < 4 || is_ack_bit)) { in cec_pin_tx_states()
543 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE; in cec_pin_tx_states()
544 } else if (!is_ack_bit && tx_short_bit(pin)) { in cec_pin_tx_states()
546 pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_SHORT : in cec_pin_tx_states()
548 } else if (!is_ack_bit && tx_long_bit(pin)) { in cec_pin_tx_states()
550 pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_LONG : in cec_pin_tx_states()
553 pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH : in cec_pin_tx_states()
556 cec_pin_high(pin); in cec_pin_tx_states()
560 pin->state = CEC_ST_TX_DATA_BIT_HIGH_CUSTOM; in cec_pin_tx_states()
561 cec_pin_high(pin); in cec_pin_tx_states()
566 v = cec_pin_read(pin); in cec_pin_tx_states()
567 is_ack_bit = pin->tx_bit % 10 == ACK_BIT; in cec_pin_tx_states()
576 if (!v && !is_ack_bit && !pin->tx_generated_poll) { in cec_pin_tx_states()
577 pin->tx_msg.len = 0; in cec_pin_tx_states()
578 pin->work_tx_ts = ts; in cec_pin_tx_states()
579 pin->work_tx_status = CEC_TX_STATUS_ARB_LOST; in cec_pin_tx_states()
580 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
581 pin->rx_bit = pin->tx_bit; in cec_pin_tx_states()
582 pin->tx_bit = 0; in cec_pin_tx_states()
583 memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); in cec_pin_tx_states()
584 pin->rx_msg.msg[0] = pin->tx_msg.msg[0]; in cec_pin_tx_states()
585 pin->rx_msg.msg[0] &= (0xff << (8 - pin->rx_bit)); in cec_pin_tx_states()
586 pin->rx_msg.len = 0; in cec_pin_tx_states()
587 pin->ts = ktime_sub_us(ts, CEC_TIM_DATA_BIT_SAMPLE); in cec_pin_tx_states()
588 pin->state = CEC_ST_RX_DATA_POST_SAMPLE; in cec_pin_tx_states()
589 pin->rx_bit++; in cec_pin_tx_states()
592 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE; in cec_pin_tx_states()
593 if (!is_ack_bit && tx_short_bit(pin)) { in cec_pin_tx_states()
595 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT; in cec_pin_tx_states()
596 } else if (!is_ack_bit && tx_long_bit(pin)) { in cec_pin_tx_states()
598 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG; in cec_pin_tx_states()
603 ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v; in cec_pin_tx_states()
604 if (!ack && (!pin->tx_ignore_nack_until_eom || in cec_pin_tx_states()
605 pin->tx_bit / 10 == pin->tx_msg.len - 1) && in cec_pin_tx_states()
606 !pin->tx_post_eom) { in cec_pin_tx_states()
619 pin->tx_nacked = true; in cec_pin_tx_states()
624 cec_pin_high(pin); in cec_pin_tx_states()
625 pin->state = CEC_ST_TX_PULSE_HIGH_CUSTOM; in cec_pin_tx_states()
629 cec_pin_to_idle(pin); in cec_pin_tx_states()
652 static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) in cec_pin_rx_states() argument
661 switch (pin->state) { in cec_pin_rx_states()
664 v = cec_pin_read(pin); in cec_pin_rx_states()
667 pin->state = CEC_ST_RX_START_BIT_HIGH; in cec_pin_rx_states()
668 delta = ktime_us_delta(ts, pin->ts); in cec_pin_rx_states()
671 if (!pin->rx_start_bit_low_too_short_cnt++) { in cec_pin_rx_states()
672 pin->rx_start_bit_low_too_short_ts = ktime_to_ns(pin->ts); in cec_pin_rx_states()
673 pin->rx_start_bit_low_too_short_delta = delta; in cec_pin_rx_states()
675 cec_pin_to_idle(pin); in cec_pin_rx_states()
678 if (rx_arb_lost(pin, &poll)) { in cec_pin_rx_states()
679 cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf); in cec_pin_rx_states()
680 pin->tx_generated_poll = true; in cec_pin_rx_states()
681 pin->tx_extra_bytes = 0; in cec_pin_rx_states()
682 pin->state = CEC_ST_TX_START_BIT_HIGH; in cec_pin_rx_states()
683 pin->ts = ts; in cec_pin_rx_states()
688 v = cec_pin_read(pin); in cec_pin_rx_states()
689 delta = ktime_us_delta(ts, pin->ts); in cec_pin_rx_states()
695 pin->rx_start_bit_too_long_cnt++; in cec_pin_rx_states()
696 cec_pin_to_idle(pin); in cec_pin_rx_states()
703 if (!pin->rx_start_bit_too_short_cnt++) { in cec_pin_rx_states()
704 pin->rx_start_bit_too_short_ts = ktime_to_ns(pin->ts); in cec_pin_rx_states()
705 pin->rx_start_bit_too_short_delta = delta; in cec_pin_rx_states()
707 cec_pin_to_idle(pin); in cec_pin_rx_states()
710 if (rx_low_drive(pin)) { in cec_pin_rx_states()
712 cec_pin_low(pin); in cec_pin_rx_states()
713 pin->state = CEC_ST_RX_LOW_DRIVE; in cec_pin_rx_states()
714 pin->rx_low_drive_cnt++; in cec_pin_rx_states()
717 pin->state = CEC_ST_RX_DATA_SAMPLE; in cec_pin_rx_states()
718 pin->ts = ts; in cec_pin_rx_states()
719 pin->rx_eom = false; in cec_pin_rx_states()
723 v = cec_pin_read(pin); in cec_pin_rx_states()
724 pin->state = CEC_ST_RX_DATA_POST_SAMPLE; in cec_pin_rx_states()
725 switch (pin->rx_bit % 10) { in cec_pin_rx_states()
727 if (pin->rx_bit / 10 < CEC_MAX_MSG_SIZE) in cec_pin_rx_states()
728 pin->rx_msg.msg[pin->rx_bit / 10] |= in cec_pin_rx_states()
729 v << (7 - (pin->rx_bit % 10)); in cec_pin_rx_states()
732 pin->rx_eom = v; in cec_pin_rx_states()
733 pin->rx_msg.len = pin->rx_bit / 10 + 1; in cec_pin_rx_states()
738 pin->rx_bit++; in cec_pin_rx_states()
742 pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW; in cec_pin_rx_states()
746 v = cec_pin_read(pin); in cec_pin_rx_states()
747 delta = ktime_us_delta(ts, pin->ts); in cec_pin_rx_states()
753 pin->rx_data_bit_too_long_cnt++; in cec_pin_rx_states()
754 cec_pin_to_idle(pin); in cec_pin_rx_states()
760 if (rx_low_drive(pin)) { in cec_pin_rx_states()
762 cec_pin_low(pin); in cec_pin_rx_states()
763 pin->state = CEC_ST_RX_LOW_DRIVE; in cec_pin_rx_states()
764 pin->rx_low_drive_cnt++; in cec_pin_rx_states()
773 if (!pin->rx_data_bit_too_short_cnt++) { in cec_pin_rx_states()
774 pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts); in cec_pin_rx_states()
775 pin->rx_data_bit_too_short_delta = delta; in cec_pin_rx_states()
777 cec_pin_low(pin); in cec_pin_rx_states()
778 pin->state = CEC_ST_RX_LOW_DRIVE; in cec_pin_rx_states()
779 pin->rx_low_drive_cnt++; in cec_pin_rx_states()
782 pin->ts = ts; in cec_pin_rx_states()
783 if (pin->rx_bit % 10 != 9) { in cec_pin_rx_states()
784 pin->state = CEC_ST_RX_DATA_SAMPLE; in cec_pin_rx_states()
788 dest = cec_msg_destination(&pin->rx_msg); in cec_pin_rx_states()
791 for_us = bcast || (pin->la_mask & (1 << dest)); in cec_pin_rx_states()
795 if (for_us && rx_nack(pin)) { in cec_pin_rx_states()
802 pin->state = CEC_ST_RX_ACK_HIGH_POST; in cec_pin_rx_states()
805 cec_pin_low(pin); in cec_pin_rx_states()
806 pin->state = CEC_ST_RX_ACK_LOW; in cec_pin_rx_states()
810 cec_pin_high(pin); in cec_pin_rx_states()
811 pin->state = CEC_ST_RX_ACK_LOW_POST; in cec_pin_rx_states()
816 v = cec_pin_read(pin); in cec_pin_rx_states()
817 if (v && pin->rx_eom) { in cec_pin_rx_states()
818 pin->work_rx_msg = pin->rx_msg; in cec_pin_rx_states()
819 pin->work_rx_msg.rx_ts = ktime_to_ns(ts); in cec_pin_rx_states()
820 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_rx_states()
821 pin->ts = ts; in cec_pin_rx_states()
822 pin->state = CEC_ST_RX_ACK_FINISH; in cec_pin_rx_states()
825 pin->rx_bit++; in cec_pin_rx_states()
826 pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW; in cec_pin_rx_states()
830 cec_pin_to_idle(pin); in cec_pin_rx_states()
844 struct cec_pin *pin = container_of(timer, struct cec_pin, timer); in cec_pin_timer() local
845 struct cec_adapter *adap = pin->adap; in cec_pin_timer()
851 if (ktime_to_ns(pin->timer_ts)) { in cec_pin_timer()
852 delta = ktime_us_delta(ts, pin->timer_ts); in cec_pin_timer()
853 pin->timer_cnt++; in cec_pin_timer()
854 if (delta > 100 && pin->state != CEC_ST_IDLE) { in cec_pin_timer()
856 pin->timer_sum_overrun += delta; in cec_pin_timer()
857 pin->timer_100us_overruns++; in cec_pin_timer()
859 pin->timer_300us_overruns++; in cec_pin_timer()
860 if (delta > pin->timer_max_overrun) in cec_pin_timer()
861 pin->timer_max_overrun = delta; in cec_pin_timer()
865 cec_pin_read(pin); in cec_pin_timer()
867 if (pin->wait_usecs) { in cec_pin_timer()
869 * If we are monitoring the pin, then we have to in cec_pin_timer()
872 if (pin->wait_usecs > 150) { in cec_pin_timer()
873 pin->wait_usecs -= 100; in cec_pin_timer()
874 pin->timer_ts = ktime_add_us(ts, 100); in cec_pin_timer()
878 if (pin->wait_usecs > 100) { in cec_pin_timer()
879 pin->wait_usecs /= 2; in cec_pin_timer()
880 pin->timer_ts = ktime_add_us(ts, pin->wait_usecs); in cec_pin_timer()
882 ns_to_ktime(pin->wait_usecs * 1000)); in cec_pin_timer()
885 pin->timer_ts = ktime_add_us(ts, pin->wait_usecs); in cec_pin_timer()
887 ns_to_ktime(pin->wait_usecs * 1000)); in cec_pin_timer()
888 pin->wait_usecs = 0; in cec_pin_timer()
892 switch (pin->state) { in cec_pin_timer()
917 cec_pin_tx_states(pin, ts); in cec_pin_timer()
930 cec_pin_rx_states(pin, ts); in cec_pin_timer()
935 if (!cec_pin_high(pin)) { in cec_pin_timer()
937 pin->ts = ts; in cec_pin_timer()
938 pin->state = CEC_ST_RX_START_BIT_LOW; in cec_pin_timer()
946 if (pin->tx_msg.len && pin->tx_signal_free_time > in cec_pin_timer()
948 pin->tx_signal_free_time = in cec_pin_timer()
952 if (ktime_to_ns(pin->ts) == 0) in cec_pin_timer()
953 pin->ts = ts; in cec_pin_timer()
954 if (pin->tx_msg.len) { in cec_pin_timer()
959 delta = ktime_us_delta(ts, pin->ts); in cec_pin_timer()
961 pin->tx_signal_free_time) { in cec_pin_timer()
962 pin->tx_nacked = false; in cec_pin_timer()
963 if (tx_custom_start(pin)) in cec_pin_timer()
964 pin->state = CEC_ST_TX_START_BIT_LOW_CUSTOM; in cec_pin_timer()
966 pin->state = CEC_ST_TX_START_BIT_LOW; in cec_pin_timer()
968 cec_pin_low(pin); in cec_pin_timer()
972 pin->tx_signal_free_time - 1) in cec_pin_timer()
973 pin->state = CEC_ST_TX_WAIT; in cec_pin_timer()
976 if (pin->tx_custom_pulse && pin->state == CEC_ST_IDLE) { in cec_pin_timer()
977 pin->tx_custom_pulse = false; in cec_pin_timer()
979 cec_pin_low(pin); in cec_pin_timer()
980 pin->state = CEC_ST_TX_PULSE_LOW_CUSTOM; in cec_pin_timer()
983 if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL || in cec_pin_timer()
984 pin->enable_irq_failed || adap->is_configuring || in cec_pin_timer()
988 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_ENABLE); in cec_pin_timer()
989 pin->state = CEC_ST_RX_IRQ; in cec_pin_timer()
990 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_timer()
995 cec_pin_high(pin); in cec_pin_timer()
996 cec_pin_to_idle(pin); in cec_pin_timer()
1003 switch (pin->state) { in cec_pin_timer()
1007 usecs = pin->tx_custom_low_usecs; in cec_pin_timer()
1012 usecs = pin->tx_custom_high_usecs; in cec_pin_timer()
1015 usecs = states[pin->state].usecs; in cec_pin_timer()
1020 pin->wait_usecs = 0; in cec_pin_timer()
1021 pin->timer_ts = ktime_add_us(ts, usecs); in cec_pin_timer()
1026 pin->wait_usecs = usecs - 100; in cec_pin_timer()
1027 pin->timer_ts = ktime_add_us(ts, 100); in cec_pin_timer()
1035 struct cec_pin *pin = adap->pin; in cec_pin_thread_func() local
1037 pin->enabled_irq = false; in cec_pin_thread_func()
1038 pin->enable_irq_failed = false; in cec_pin_thread_func()
1040 wait_event_interruptible(pin->kthread_waitq, in cec_pin_thread_func()
1042 pin->work_rx_msg.len || in cec_pin_thread_func()
1043 pin->work_tx_status || in cec_pin_thread_func()
1044 atomic_read(&pin->work_irq_change) || in cec_pin_thread_func()
1045 atomic_read(&pin->work_pin_num_events)); in cec_pin_thread_func()
1050 if (pin->work_rx_msg.len) { in cec_pin_thread_func()
1051 struct cec_msg *msg = &pin->work_rx_msg; in cec_pin_thread_func()
1054 rx_add_byte(pin)) { in cec_pin_thread_func()
1058 if (msg->len > 2 && rx_remove_byte(pin)) { in cec_pin_thread_func()
1065 ns_to_ktime(pin->work_rx_msg.rx_ts)); in cec_pin_thread_func()
1069 if (pin->work_tx_status) { in cec_pin_thread_func()
1070 unsigned int tx_status = pin->work_tx_status; in cec_pin_thread_func()
1072 pin->work_tx_status = 0; in cec_pin_thread_func()
1074 pin->work_tx_ts); in cec_pin_thread_func()
1077 while (atomic_read(&pin->work_pin_num_events)) { in cec_pin_thread_func()
1078 unsigned int idx = pin->work_pin_events_rd; in cec_pin_thread_func()
1079 u8 v = pin->work_pin_events[idx]; in cec_pin_thread_func()
1084 pin->work_pin_ts[idx]); in cec_pin_thread_func()
1085 pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; in cec_pin_thread_func()
1086 atomic_dec(&pin->work_pin_num_events); in cec_pin_thread_func()
1089 switch (atomic_xchg(&pin->work_irq_change, in cec_pin_thread_func()
1092 if (pin->enabled_irq) { in cec_pin_thread_func()
1093 pin->ops->disable_irq(adap); in cec_pin_thread_func()
1094 pin->enabled_irq = false; in cec_pin_thread_func()
1095 pin->enable_irq_failed = false; in cec_pin_thread_func()
1097 cec_pin_high(pin); in cec_pin_thread_func()
1098 if (pin->state == CEC_ST_OFF) in cec_pin_thread_func()
1100 cec_pin_to_idle(pin); in cec_pin_thread_func()
1101 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_thread_func()
1105 if (pin->enabled_irq || !pin->ops->enable_irq || in cec_pin_thread_func()
1106 pin->adap->devnode.unregistered) in cec_pin_thread_func()
1108 pin->enable_irq_failed = !pin->ops->enable_irq(adap); in cec_pin_thread_func()
1109 if (pin->enable_irq_failed) { in cec_pin_thread_func()
1110 cec_pin_to_idle(pin); in cec_pin_thread_func()
1111 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_thread_func()
1114 pin->enabled_irq = true; in cec_pin_thread_func()
1122 if (pin->enabled_irq) { in cec_pin_thread_func()
1123 pin->ops->disable_irq(pin->adap); in cec_pin_thread_func()
1124 pin->enabled_irq = false; in cec_pin_thread_func()
1125 pin->enable_irq_failed = false; in cec_pin_thread_func()
1126 cec_pin_high(pin); in cec_pin_thread_func()
1133 struct cec_pin *pin = adap->pin; in cec_pin_adap_enable() local
1136 cec_pin_read(pin); in cec_pin_adap_enable()
1137 cec_pin_to_idle(pin); in cec_pin_adap_enable()
1138 pin->tx_msg.len = 0; in cec_pin_adap_enable()
1139 pin->timer_ts = ns_to_ktime(0); in cec_pin_adap_enable()
1140 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); in cec_pin_adap_enable()
1141 if (!pin->kthread) { in cec_pin_adap_enable()
1142 pin->kthread = kthread_run(cec_pin_thread_func, adap, in cec_pin_adap_enable()
1143 "cec-pin"); in cec_pin_adap_enable()
1144 if (IS_ERR(pin->kthread)) { in cec_pin_adap_enable()
1145 int err = PTR_ERR(pin->kthread); in cec_pin_adap_enable()
1147 pr_err("cec-pin: kernel_thread() failed\n"); in cec_pin_adap_enable()
1148 pin->kthread = NULL; in cec_pin_adap_enable()
1152 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_adap_enable()
1154 } else if (pin->kthread) { in cec_pin_adap_enable()
1155 hrtimer_cancel(&pin->timer); in cec_pin_adap_enable()
1156 cec_pin_high(pin); in cec_pin_adap_enable()
1157 cec_pin_to_idle(pin); in cec_pin_adap_enable()
1158 pin->state = CEC_ST_OFF; in cec_pin_adap_enable()
1159 pin->work_tx_status = 0; in cec_pin_adap_enable()
1160 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_adap_enable()
1161 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_adap_enable()
1168 struct cec_pin *pin = adap->pin; in cec_pin_adap_log_addr() local
1171 pin->la_mask = 0; in cec_pin_adap_log_addr()
1173 pin->la_mask |= (1 << log_addr); in cec_pin_adap_log_addr()
1177 void cec_pin_start_timer(struct cec_pin *pin) in cec_pin_start_timer() argument
1179 if (pin->state != CEC_ST_RX_IRQ) in cec_pin_start_timer()
1182 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_start_timer()
1183 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_start_timer()
1189 struct cec_pin *pin = adap->pin; in cec_pin_adap_transmit() local
1196 if (pin->state != CEC_ST_IDLE && in cec_pin_adap_transmit()
1200 pin->tx_signal_free_time = signal_free_time; in cec_pin_adap_transmit()
1201 pin->tx_extra_bytes = 0; in cec_pin_adap_transmit()
1202 pin->tx_msg = *msg; in cec_pin_adap_transmit()
1205 pin->tx_extra_bytes = tx_add_bytes(pin); in cec_pin_adap_transmit()
1207 if (msg->len > 2 && tx_remove_byte(pin)) { in cec_pin_adap_transmit()
1209 pin->tx_msg.len--; in cec_pin_adap_transmit()
1211 pin->work_tx_status = 0; in cec_pin_adap_transmit()
1212 pin->tx_bit = 0; in cec_pin_adap_transmit()
1213 cec_pin_start_timer(pin); in cec_pin_adap_transmit()
1220 struct cec_pin *pin = adap->pin; in cec_pin_adap_status() local
1222 seq_printf(file, "state: %s\n", states[pin->state].name); in cec_pin_adap_status()
1223 seq_printf(file, "tx_bit: %d\n", pin->tx_bit); in cec_pin_adap_status()
1224 seq_printf(file, "rx_bit: %d\n", pin->rx_bit); in cec_pin_adap_status()
1225 seq_printf(file, "cec pin: %d\n", call_pin_op(pin, read)); in cec_pin_adap_status()
1226 seq_printf(file, "cec pin events dropped: %u\n", in cec_pin_adap_status()
1227 pin->work_pin_events_dropped_cnt); in cec_pin_adap_status()
1228 if (pin->ops->enable_irq) in cec_pin_adap_status()
1229 seq_printf(file, "irq %s\n", pin->enabled_irq ? "enabled" : in cec_pin_adap_status()
1230 (pin->enable_irq_failed ? "failed" : "disabled")); in cec_pin_adap_status()
1231 if (pin->timer_100us_overruns) { in cec_pin_adap_status()
1233 pin->timer_100us_overruns, pin->timer_cnt); in cec_pin_adap_status()
1235 pin->timer_300us_overruns, pin->timer_cnt); in cec_pin_adap_status()
1237 pin->timer_max_overrun); in cec_pin_adap_status()
1239 pin->timer_sum_overrun / pin->timer_100us_overruns); in cec_pin_adap_status()
1241 if (pin->rx_start_bit_low_too_short_cnt) in cec_pin_adap_status()
1244 pin->rx_start_bit_low_too_short_cnt, in cec_pin_adap_status()
1245 pin->rx_start_bit_low_too_short_delta, in cec_pin_adap_status()
1246 pin->rx_start_bit_low_too_short_ts); in cec_pin_adap_status()
1247 if (pin->rx_start_bit_too_short_cnt) in cec_pin_adap_status()
1250 pin->rx_start_bit_too_short_cnt, in cec_pin_adap_status()
1251 pin->rx_start_bit_too_short_delta, in cec_pin_adap_status()
1252 pin->rx_start_bit_too_short_ts); in cec_pin_adap_status()
1253 if (pin->rx_start_bit_too_long_cnt) in cec_pin_adap_status()
1255 pin->rx_start_bit_too_long_cnt); in cec_pin_adap_status()
1256 if (pin->rx_data_bit_too_short_cnt) in cec_pin_adap_status()
1259 pin->rx_data_bit_too_short_cnt, in cec_pin_adap_status()
1260 pin->rx_data_bit_too_short_delta, in cec_pin_adap_status()
1261 pin->rx_data_bit_too_short_ts); in cec_pin_adap_status()
1262 if (pin->rx_data_bit_too_long_cnt) in cec_pin_adap_status()
1264 pin->rx_data_bit_too_long_cnt); in cec_pin_adap_status()
1265 seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt); in cec_pin_adap_status()
1266 seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt); in cec_pin_adap_status()
1267 pin->work_pin_events_dropped_cnt = 0; in cec_pin_adap_status()
1268 pin->timer_cnt = 0; in cec_pin_adap_status()
1269 pin->timer_100us_overruns = 0; in cec_pin_adap_status()
1270 pin->timer_300us_overruns = 0; in cec_pin_adap_status()
1271 pin->timer_max_overrun = 0; in cec_pin_adap_status()
1272 pin->timer_sum_overrun = 0; in cec_pin_adap_status()
1273 pin->rx_start_bit_low_too_short_cnt = 0; in cec_pin_adap_status()
1274 pin->rx_start_bit_too_short_cnt = 0; in cec_pin_adap_status()
1275 pin->rx_start_bit_too_long_cnt = 0; in cec_pin_adap_status()
1276 pin->rx_data_bit_too_short_cnt = 0; in cec_pin_adap_status()
1277 pin->rx_data_bit_too_long_cnt = 0; in cec_pin_adap_status()
1278 pin->rx_low_drive_cnt = 0; in cec_pin_adap_status()
1279 pin->tx_low_drive_cnt = 0; in cec_pin_adap_status()
1280 call_void_pin_op(pin, status, file); in cec_pin_adap_status()
1286 struct cec_pin *pin = adap->pin; in cec_pin_adap_monitor_all_enable() local
1288 pin->monitor_all = enable; in cec_pin_adap_monitor_all_enable()
1294 struct cec_pin *pin = adap->pin; in cec_pin_adap_free() local
1296 if (pin->kthread) in cec_pin_adap_free()
1297 kthread_stop(pin->kthread); in cec_pin_adap_free()
1298 pin->kthread = NULL; in cec_pin_adap_free()
1299 if (pin->ops->free) in cec_pin_adap_free()
1300 pin->ops->free(adap); in cec_pin_adap_free()
1301 adap->pin = NULL; in cec_pin_adap_free()
1302 kfree(pin); in cec_pin_adap_free()
1307 struct cec_pin *pin = adap->pin; in cec_pin_received() local
1309 if (pin->ops->received && !adap->devnode.unregistered) in cec_pin_received()
1310 return pin->ops->received(adap, msg); in cec_pin_received()
1316 struct cec_pin *pin = adap->pin; in cec_pin_changed() local
1318 cec_pin_update(pin, value, false); in cec_pin_changed()
1321 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_changed()
1343 struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL); in cec_pin_allocate_adapter() local
1345 if (pin == NULL) in cec_pin_allocate_adapter()
1347 pin->ops = pin_ops; in cec_pin_allocate_adapter()
1348 hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in cec_pin_allocate_adapter()
1349 atomic_set(&pin->work_pin_num_events, 0); in cec_pin_allocate_adapter()
1350 pin->timer.function = cec_pin_timer; in cec_pin_allocate_adapter()
1351 init_waitqueue_head(&pin->kthread_waitq); in cec_pin_allocate_adapter()
1352 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; in cec_pin_allocate_adapter()
1353 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT; in cec_pin_allocate_adapter()
1360 kfree(pin); in cec_pin_allocate_adapter()
1364 adap->pin = pin; in cec_pin_allocate_adapter()
1365 pin->adap = adap; in cec_pin_allocate_adapter()
1366 cec_pin_update(pin, cec_pin_high(pin), true); in cec_pin_allocate_adapter()