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
1039 wait_event_interruptible(pin->kthread_waitq, in cec_pin_thread_func()
1041 pin->work_rx_msg.len || in cec_pin_thread_func()
1042 pin->work_tx_status || in cec_pin_thread_func()
1043 atomic_read(&pin->work_irq_change) || in cec_pin_thread_func()
1044 atomic_read(&pin->work_pin_num_events)); in cec_pin_thread_func()
1049 if (pin->work_rx_msg.len) { in cec_pin_thread_func()
1050 struct cec_msg *msg = &pin->work_rx_msg; in cec_pin_thread_func()
1053 rx_add_byte(pin)) { in cec_pin_thread_func()
1057 if (msg->len > 2 && rx_remove_byte(pin)) { in cec_pin_thread_func()
1064 ns_to_ktime(pin->work_rx_msg.rx_ts)); in cec_pin_thread_func()
1068 if (pin->work_tx_status) { in cec_pin_thread_func()
1069 unsigned int tx_status = pin->work_tx_status; in cec_pin_thread_func()
1071 pin->work_tx_status = 0; in cec_pin_thread_func()
1073 pin->work_tx_ts); in cec_pin_thread_func()
1076 while (atomic_read(&pin->work_pin_num_events)) { in cec_pin_thread_func()
1077 unsigned int idx = pin->work_pin_events_rd; in cec_pin_thread_func()
1078 u8 v = pin->work_pin_events[idx]; in cec_pin_thread_func()
1083 pin->work_pin_ts[idx]); in cec_pin_thread_func()
1084 pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; in cec_pin_thread_func()
1085 atomic_dec(&pin->work_pin_num_events); in cec_pin_thread_func()
1088 switch (atomic_xchg(&pin->work_irq_change, in cec_pin_thread_func()
1092 call_void_pin_op(pin, disable_irq); in cec_pin_thread_func()
1095 cec_pin_high(pin); in cec_pin_thread_func()
1096 if (pin->state == CEC_ST_OFF) in cec_pin_thread_func()
1098 cec_pin_to_idle(pin); in cec_pin_thread_func()
1099 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_thread_func()
1105 pin->enable_irq_failed = !call_pin_op(pin, enable_irq); in cec_pin_thread_func()
1106 if (pin->enable_irq_failed) { in cec_pin_thread_func()
1107 cec_pin_to_idle(pin); in cec_pin_thread_func()
1108 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_thread_func()
1123 struct cec_pin *pin = adap->pin; in cec_pin_adap_enable() local
1126 cec_pin_read(pin); in cec_pin_adap_enable()
1127 cec_pin_to_idle(pin); in cec_pin_adap_enable()
1128 pin->tx_msg.len = 0; in cec_pin_adap_enable()
1129 pin->timer_ts = ns_to_ktime(0); in cec_pin_adap_enable()
1130 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); in cec_pin_adap_enable()
1131 if (!pin->kthread) { in cec_pin_adap_enable()
1132 pin->kthread = kthread_run(cec_pin_thread_func, adap, in cec_pin_adap_enable()
1133 "cec-pin"); in cec_pin_adap_enable()
1134 if (IS_ERR(pin->kthread)) { in cec_pin_adap_enable()
1135 int err = PTR_ERR(pin->kthread); in cec_pin_adap_enable()
1137 pr_err("cec-pin: kernel_thread() failed\n"); in cec_pin_adap_enable()
1138 pin->kthread = NULL; in cec_pin_adap_enable()
1142 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_adap_enable()
1144 } else if (pin->kthread) { in cec_pin_adap_enable()
1145 hrtimer_cancel(&pin->timer); in cec_pin_adap_enable()
1146 cec_pin_high(pin); in cec_pin_adap_enable()
1147 cec_pin_to_idle(pin); in cec_pin_adap_enable()
1148 pin->state = CEC_ST_OFF; in cec_pin_adap_enable()
1149 pin->work_tx_status = 0; in cec_pin_adap_enable()
1150 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_adap_enable()
1151 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_adap_enable()
1158 struct cec_pin *pin = adap->pin; in cec_pin_adap_log_addr() local
1161 pin->la_mask = 0; in cec_pin_adap_log_addr()
1163 pin->la_mask |= (1 << log_addr); in cec_pin_adap_log_addr()
1167 void cec_pin_start_timer(struct cec_pin *pin) in cec_pin_start_timer() argument
1169 if (pin->state != CEC_ST_RX_IRQ) in cec_pin_start_timer()
1172 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_start_timer()
1173 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_start_timer()
1179 struct cec_pin *pin = adap->pin; in cec_pin_adap_transmit() local
1186 if (pin->state != CEC_ST_IDLE && in cec_pin_adap_transmit()
1190 pin->tx_signal_free_time = signal_free_time; in cec_pin_adap_transmit()
1191 pin->tx_extra_bytes = 0; in cec_pin_adap_transmit()
1192 pin->tx_msg = *msg; in cec_pin_adap_transmit()
1195 pin->tx_extra_bytes = tx_add_bytes(pin); in cec_pin_adap_transmit()
1197 if (msg->len > 2 && tx_remove_byte(pin)) { in cec_pin_adap_transmit()
1199 pin->tx_msg.len--; in cec_pin_adap_transmit()
1201 pin->work_tx_status = 0; in cec_pin_adap_transmit()
1202 pin->tx_bit = 0; in cec_pin_adap_transmit()
1203 cec_pin_start_timer(pin); in cec_pin_adap_transmit()
1210 struct cec_pin *pin = adap->pin; in cec_pin_adap_status() local
1212 seq_printf(file, "state: %s\n", states[pin->state].name); in cec_pin_adap_status()
1213 seq_printf(file, "tx_bit: %d\n", pin->tx_bit); in cec_pin_adap_status()
1214 seq_printf(file, "rx_bit: %d\n", pin->rx_bit); in cec_pin_adap_status()
1215 seq_printf(file, "cec pin: %d\n", call_pin_op(pin, read)); in cec_pin_adap_status()
1216 seq_printf(file, "cec pin events dropped: %u\n", in cec_pin_adap_status()
1217 pin->work_pin_events_dropped_cnt); in cec_pin_adap_status()
1218 seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed); in cec_pin_adap_status()
1219 if (pin->timer_100us_overruns) { in cec_pin_adap_status()
1221 pin->timer_100us_overruns, pin->timer_cnt); in cec_pin_adap_status()
1223 pin->timer_300us_overruns, pin->timer_cnt); in cec_pin_adap_status()
1225 pin->timer_max_overrun); in cec_pin_adap_status()
1227 pin->timer_sum_overrun / pin->timer_100us_overruns); in cec_pin_adap_status()
1229 if (pin->rx_start_bit_low_too_short_cnt) in cec_pin_adap_status()
1232 pin->rx_start_bit_low_too_short_cnt, in cec_pin_adap_status()
1233 pin->rx_start_bit_low_too_short_delta, in cec_pin_adap_status()
1234 pin->rx_start_bit_low_too_short_ts); in cec_pin_adap_status()
1235 if (pin->rx_start_bit_too_short_cnt) in cec_pin_adap_status()
1238 pin->rx_start_bit_too_short_cnt, in cec_pin_adap_status()
1239 pin->rx_start_bit_too_short_delta, in cec_pin_adap_status()
1240 pin->rx_start_bit_too_short_ts); in cec_pin_adap_status()
1241 if (pin->rx_start_bit_too_long_cnt) in cec_pin_adap_status()
1243 pin->rx_start_bit_too_long_cnt); in cec_pin_adap_status()
1244 if (pin->rx_data_bit_too_short_cnt) in cec_pin_adap_status()
1247 pin->rx_data_bit_too_short_cnt, in cec_pin_adap_status()
1248 pin->rx_data_bit_too_short_delta, in cec_pin_adap_status()
1249 pin->rx_data_bit_too_short_ts); in cec_pin_adap_status()
1250 if (pin->rx_data_bit_too_long_cnt) in cec_pin_adap_status()
1252 pin->rx_data_bit_too_long_cnt); in cec_pin_adap_status()
1253 seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt); in cec_pin_adap_status()
1254 seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt); in cec_pin_adap_status()
1255 pin->work_pin_events_dropped_cnt = 0; in cec_pin_adap_status()
1256 pin->timer_cnt = 0; in cec_pin_adap_status()
1257 pin->timer_100us_overruns = 0; in cec_pin_adap_status()
1258 pin->timer_300us_overruns = 0; in cec_pin_adap_status()
1259 pin->timer_max_overrun = 0; in cec_pin_adap_status()
1260 pin->timer_sum_overrun = 0; in cec_pin_adap_status()
1261 pin->rx_start_bit_low_too_short_cnt = 0; in cec_pin_adap_status()
1262 pin->rx_start_bit_too_short_cnt = 0; in cec_pin_adap_status()
1263 pin->rx_start_bit_too_long_cnt = 0; in cec_pin_adap_status()
1264 pin->rx_data_bit_too_short_cnt = 0; in cec_pin_adap_status()
1265 pin->rx_data_bit_too_long_cnt = 0; in cec_pin_adap_status()
1266 pin->rx_low_drive_cnt = 0; in cec_pin_adap_status()
1267 pin->tx_low_drive_cnt = 0; in cec_pin_adap_status()
1268 call_void_pin_op(pin, status, file); in cec_pin_adap_status()
1274 struct cec_pin *pin = adap->pin; in cec_pin_adap_monitor_all_enable() local
1276 pin->monitor_all = enable; in cec_pin_adap_monitor_all_enable()
1282 struct cec_pin *pin = adap->pin; in cec_pin_adap_free() local
1284 if (pin->kthread) in cec_pin_adap_free()
1285 kthread_stop(pin->kthread); in cec_pin_adap_free()
1286 pin->kthread = NULL; in cec_pin_adap_free()
1287 if (pin->ops->free) in cec_pin_adap_free()
1288 pin->ops->free(adap); in cec_pin_adap_free()
1289 adap->pin = NULL; in cec_pin_adap_free()
1290 kfree(pin); in cec_pin_adap_free()
1295 struct cec_pin *pin = adap->pin; in cec_pin_received() local
1297 if (pin->ops->received && !adap->devnode.unregistered) in cec_pin_received()
1298 return pin->ops->received(adap, msg); in cec_pin_received()
1304 struct cec_pin *pin = adap->pin; in cec_pin_changed() local
1306 cec_pin_update(pin, value, false); in cec_pin_changed()
1309 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_changed()
1331 struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL); in cec_pin_allocate_adapter() local
1333 if (pin == NULL) in cec_pin_allocate_adapter()
1335 pin->ops = pin_ops; in cec_pin_allocate_adapter()
1336 hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in cec_pin_allocate_adapter()
1337 atomic_set(&pin->work_pin_num_events, 0); in cec_pin_allocate_adapter()
1338 pin->timer.function = cec_pin_timer; in cec_pin_allocate_adapter()
1339 init_waitqueue_head(&pin->kthread_waitq); in cec_pin_allocate_adapter()
1340 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; in cec_pin_allocate_adapter()
1341 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT; in cec_pin_allocate_adapter()
1348 kfree(pin); in cec_pin_allocate_adapter()
1352 adap->pin = pin; in cec_pin_allocate_adapter()
1353 pin->adap = adap; in cec_pin_allocate_adapter()
1354 cec_pin_update(pin, cec_pin_high(pin), true); in cec_pin_allocate_adapter()