Lines Matching full:pin

11 #include <media/cec-pin.h>
12 #include "cec-pin-priv.h"
112 static void cec_pin_update(struct cec_pin *pin, bool v, bool force) in cec_pin_update() argument
114 if (!force && v == pin->adap->cec_pin_is_high) in cec_pin_update()
117 pin->adap->cec_pin_is_high = v; in cec_pin_update()
118 if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) { in cec_pin_update()
121 if (pin->work_pin_events_dropped) { in cec_pin_update()
122 pin->work_pin_events_dropped = false; in cec_pin_update()
125 pin->work_pin_events[pin->work_pin_events_wr] = ev; in cec_pin_update()
126 pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get(); in cec_pin_update()
127 pin->work_pin_events_wr = in cec_pin_update()
128 (pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS; in cec_pin_update()
129 atomic_inc(&pin->work_pin_num_events); in cec_pin_update()
131 pin->work_pin_events_dropped = true; in cec_pin_update()
132 pin->work_pin_events_dropped_cnt++; in cec_pin_update()
134 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_update()
137 static bool cec_pin_read(struct cec_pin *pin) in cec_pin_read() argument
139 bool v = call_pin_op(pin, read); in cec_pin_read()
141 cec_pin_update(pin, v, false); in cec_pin_read()
145 static void cec_pin_low(struct cec_pin *pin) in cec_pin_low() argument
147 call_void_pin_op(pin, low); in cec_pin_low()
148 cec_pin_update(pin, false, false); in cec_pin_low()
151 static bool cec_pin_high(struct cec_pin *pin) in cec_pin_high() argument
153 call_void_pin_op(pin, high); in cec_pin_high()
154 return cec_pin_read(pin); in cec_pin_high()
157 static bool rx_error_inj(struct cec_pin *pin, unsigned int mode_offset, in rx_error_inj() argument
161 u16 cmd = cec_pin_rx_error_inj(pin); in rx_error_inj()
162 u64 e = pin->error_inj[cmd]; in rx_error_inj()
166 u8 pos = pin->error_inj_args[cmd][arg_idx]; in rx_error_inj()
170 else if (pos != pin->rx_bit) in rx_error_inj()
176 pin->error_inj[cmd] &= in rx_error_inj()
182 return pin->rx_toggle; in rx_error_inj()
191 static bool rx_nack(struct cec_pin *pin) in rx_nack() argument
193 return rx_error_inj(pin, CEC_ERROR_INJ_RX_NACK_OFFSET, -1, NULL); in rx_nack()
196 static bool rx_low_drive(struct cec_pin *pin) in rx_low_drive() argument
198 return rx_error_inj(pin, CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET, in rx_low_drive()
202 static bool rx_add_byte(struct cec_pin *pin) in rx_add_byte() argument
204 return rx_error_inj(pin, CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, NULL); in rx_add_byte()
207 static bool rx_remove_byte(struct cec_pin *pin) in rx_remove_byte() argument
209 return rx_error_inj(pin, CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, NULL); in rx_remove_byte()
212 static bool rx_arb_lost(struct cec_pin *pin, u8 *poll) in rx_arb_lost() argument
214 return pin->tx_msg.len == 0 && in rx_arb_lost()
215 rx_error_inj(pin, CEC_ERROR_INJ_RX_ARB_LOST_OFFSET, in rx_arb_lost()
219 static bool tx_error_inj(struct cec_pin *pin, unsigned int mode_offset, in tx_error_inj() argument
223 u16 cmd = cec_pin_tx_error_inj(pin); in tx_error_inj()
224 u64 e = pin->error_inj[cmd]; in tx_error_inj()
228 u8 pos = pin->error_inj_args[cmd][arg_idx]; in tx_error_inj()
232 else if (pos != pin->tx_bit) in tx_error_inj()
238 pin->error_inj[cmd] &= in tx_error_inj()
244 return pin->tx_toggle; in tx_error_inj()
253 static bool tx_no_eom(struct cec_pin *pin) in tx_no_eom() argument
255 return tx_error_inj(pin, CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, NULL); in tx_no_eom()
258 static bool tx_early_eom(struct cec_pin *pin) in tx_early_eom() argument
260 return tx_error_inj(pin, CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, NULL); in tx_early_eom()
263 static bool tx_short_bit(struct cec_pin *pin) in tx_short_bit() argument
265 return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET, in tx_short_bit()
269 static bool tx_long_bit(struct cec_pin *pin) in tx_long_bit() argument
271 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_BIT_OFFSET, in tx_long_bit()
275 static bool tx_custom_bit(struct cec_pin *pin) in tx_custom_bit() argument
277 return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET, in tx_custom_bit()
281 static bool tx_short_start(struct cec_pin *pin) in tx_short_start() argument
283 return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, NULL); in tx_short_start()
286 static bool tx_long_start(struct cec_pin *pin) in tx_long_start() argument
288 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, NULL); in tx_long_start()
291 static bool tx_custom_start(struct cec_pin *pin) in tx_custom_start() argument
293 return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, in tx_custom_start()
297 static bool tx_last_bit(struct cec_pin *pin) in tx_last_bit() argument
299 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LAST_BIT_OFFSET, in tx_last_bit()
303 static u8 tx_add_bytes(struct cec_pin *pin) in tx_add_bytes() argument
307 if (tx_error_inj(pin, CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET, in tx_add_bytes()
313 static bool tx_remove_byte(struct cec_pin *pin) in tx_remove_byte() argument
315 return tx_error_inj(pin, CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, NULL); in tx_remove_byte()
318 static bool tx_low_drive(struct cec_pin *pin) in tx_low_drive() argument
320 return tx_error_inj(pin, CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET, in tx_low_drive()
324 static void cec_pin_to_idle(struct cec_pin *pin) in cec_pin_to_idle() argument
330 pin->rx_bit = pin->tx_bit = 0; in cec_pin_to_idle()
331 pin->rx_msg.len = 0; in cec_pin_to_idle()
332 memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); in cec_pin_to_idle()
333 pin->ts = ns_to_ktime(0); in cec_pin_to_idle()
334 pin->tx_generated_poll = false; in cec_pin_to_idle()
335 pin->tx_post_eom = false; in cec_pin_to_idle()
336 if (pin->state >= CEC_ST_TX_WAIT && in cec_pin_to_idle()
337 pin->state <= CEC_ST_TX_LOW_DRIVE) in cec_pin_to_idle()
338 pin->tx_toggle ^= 1; in cec_pin_to_idle()
339 if (pin->state >= CEC_ST_RX_START_BIT_LOW && in cec_pin_to_idle()
340 pin->state <= CEC_ST_RX_LOW_DRIVE) in cec_pin_to_idle()
341 pin->rx_toggle ^= 1; in cec_pin_to_idle()
342 pin->state = CEC_ST_IDLE; in cec_pin_to_idle()
371 static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) in cec_pin_tx_states() argument
376 switch (pin->state) { in cec_pin_tx_states()
378 if (cec_pin_read(pin)) in cec_pin_tx_states()
379 cec_pin_to_idle(pin); in cec_pin_tx_states()
383 if (tx_short_start(pin)) { in cec_pin_tx_states()
388 pin->state = CEC_ST_TX_START_BIT_HIGH_SHORT; in cec_pin_tx_states()
389 } else if (tx_long_start(pin)) { in cec_pin_tx_states()
394 pin->state = CEC_ST_TX_START_BIT_HIGH_LONG; in cec_pin_tx_states()
396 pin->state = CEC_ST_TX_START_BIT_HIGH; in cec_pin_tx_states()
399 cec_pin_high(pin); in cec_pin_tx_states()
403 pin->state = CEC_ST_TX_START_BIT_HIGH_CUSTOM; in cec_pin_tx_states()
405 cec_pin_high(pin); in cec_pin_tx_states()
411 if (pin->tx_nacked) { in cec_pin_tx_states()
412 cec_pin_to_idle(pin); in cec_pin_tx_states()
413 pin->tx_msg.len = 0; in cec_pin_tx_states()
414 if (pin->tx_generated_poll) in cec_pin_tx_states()
416 pin->work_tx_ts = ts; in cec_pin_tx_states()
417 pin->work_tx_status = CEC_TX_STATUS_NACK; in cec_pin_tx_states()
418 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
434 * the pin can actually be low in that case. in cec_pin_tx_states()
436 if (!cec_pin_read(pin) && !pin->tx_generated_poll) { in cec_pin_tx_states()
441 pin->tx_msg.len = 0; in cec_pin_tx_states()
442 pin->state = CEC_ST_TX_WAIT_FOR_HIGH; in cec_pin_tx_states()
443 pin->work_tx_ts = ts; in cec_pin_tx_states()
444 pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; in cec_pin_tx_states()
445 pin->tx_low_drive_cnt++; in cec_pin_tx_states()
446 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
451 if (tx_last_bit(pin)) { in cec_pin_tx_states()
453 cec_pin_to_idle(pin); in cec_pin_tx_states()
454 pin->tx_msg.len = 0; in cec_pin_tx_states()
455 if (pin->tx_generated_poll) in cec_pin_tx_states()
457 pin->work_tx_ts = ts; in cec_pin_tx_states()
458 pin->work_tx_status = CEC_TX_STATUS_OK; in cec_pin_tx_states()
459 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
462 pin->tx_bit++; in cec_pin_tx_states()
468 if (tx_low_drive(pin)) { in cec_pin_tx_states()
470 cec_pin_low(pin); in cec_pin_tx_states()
471 pin->state = CEC_ST_TX_LOW_DRIVE; in cec_pin_tx_states()
472 pin->tx_msg.len = 0; in cec_pin_tx_states()
473 if (pin->tx_generated_poll) in cec_pin_tx_states()
475 pin->work_tx_ts = ts; in cec_pin_tx_states()
476 pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; in cec_pin_tx_states()
477 pin->tx_low_drive_cnt++; in cec_pin_tx_states()
478 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
481 if (pin->tx_bit / 10 >= pin->tx_msg.len + pin->tx_extra_bytes) { in cec_pin_tx_states()
482 cec_pin_to_idle(pin); in cec_pin_tx_states()
483 pin->tx_msg.len = 0; in cec_pin_tx_states()
484 if (pin->tx_generated_poll) in cec_pin_tx_states()
486 pin->work_tx_ts = ts; in cec_pin_tx_states()
487 pin->work_tx_status = CEC_TX_STATUS_OK; in cec_pin_tx_states()
488 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
492 switch (pin->tx_bit % 10) { in cec_pin_tx_states()
496 * extra bytes, so pin->tx_bit / 10 can become >= 16. in cec_pin_tx_states()
500 unsigned int idx = (pin->tx_bit / 10); in cec_pin_tx_states()
503 if (idx < pin->tx_msg.len) in cec_pin_tx_states()
504 val = pin->tx_msg.msg[idx]; in cec_pin_tx_states()
505 v = val & (1 << (7 - (pin->tx_bit % 10))); in cec_pin_tx_states()
507 pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : in cec_pin_tx_states()
512 unsigned int tot_len = pin->tx_msg.len + in cec_pin_tx_states()
513 pin->tx_extra_bytes; in cec_pin_tx_states()
514 unsigned int tx_byte_idx = pin->tx_bit / 10; in cec_pin_tx_states()
516 v = !pin->tx_post_eom && tx_byte_idx == tot_len - 1; in cec_pin_tx_states()
518 tx_early_eom(pin)) { in cec_pin_tx_states()
521 pin->tx_post_eom = true; in cec_pin_tx_states()
522 } else if (v && tx_no_eom(pin)) { in cec_pin_tx_states()
526 pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : in cec_pin_tx_states()
531 pin->state = CEC_ST_TX_DATA_BIT_1_LOW; in cec_pin_tx_states()
534 if (tx_custom_bit(pin)) in cec_pin_tx_states()
535 pin->state = CEC_ST_TX_DATA_BIT_LOW_CUSTOM; in cec_pin_tx_states()
536 cec_pin_low(pin); in cec_pin_tx_states()
541 v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW; in cec_pin_tx_states()
542 is_ack_bit = pin->tx_bit % 10 == ACK_BIT; in cec_pin_tx_states()
543 if (v && (pin->tx_bit < 4 || is_ack_bit)) { in cec_pin_tx_states()
544 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE; in cec_pin_tx_states()
545 } else if (!is_ack_bit && tx_short_bit(pin)) { in cec_pin_tx_states()
547 pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_SHORT : in cec_pin_tx_states()
549 } else if (!is_ack_bit && tx_long_bit(pin)) { in cec_pin_tx_states()
551 pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_LONG : in cec_pin_tx_states()
554 pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH : in cec_pin_tx_states()
557 cec_pin_high(pin); in cec_pin_tx_states()
561 pin->state = CEC_ST_TX_DATA_BIT_HIGH_CUSTOM; in cec_pin_tx_states()
562 cec_pin_high(pin); in cec_pin_tx_states()
567 v = cec_pin_read(pin); in cec_pin_tx_states()
568 is_ack_bit = pin->tx_bit % 10 == ACK_BIT; in cec_pin_tx_states()
577 if (!v && !is_ack_bit && !pin->tx_generated_poll) { in cec_pin_tx_states()
578 pin->tx_msg.len = 0; in cec_pin_tx_states()
579 pin->work_tx_ts = ts; in cec_pin_tx_states()
580 pin->work_tx_status = CEC_TX_STATUS_ARB_LOST; in cec_pin_tx_states()
581 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_tx_states()
582 pin->rx_bit = pin->tx_bit; in cec_pin_tx_states()
583 pin->tx_bit = 0; in cec_pin_tx_states()
584 memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); in cec_pin_tx_states()
585 pin->rx_msg.msg[0] = pin->tx_msg.msg[0]; in cec_pin_tx_states()
586 pin->rx_msg.msg[0] &= (0xff << (8 - pin->rx_bit)); in cec_pin_tx_states()
587 pin->rx_msg.len = 0; in cec_pin_tx_states()
588 pin->ts = ktime_sub_us(ts, CEC_TIM_DATA_BIT_SAMPLE); in cec_pin_tx_states()
589 pin->state = CEC_ST_RX_DATA_POST_SAMPLE; in cec_pin_tx_states()
590 pin->rx_bit++; in cec_pin_tx_states()
593 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE; in cec_pin_tx_states()
594 if (!is_ack_bit && tx_short_bit(pin)) { in cec_pin_tx_states()
596 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT; in cec_pin_tx_states()
597 } else if (!is_ack_bit && tx_long_bit(pin)) { in cec_pin_tx_states()
599 pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG; in cec_pin_tx_states()
604 ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v; in cec_pin_tx_states()
605 if (!ack && (!pin->tx_ignore_nack_until_eom || in cec_pin_tx_states()
606 pin->tx_bit / 10 == pin->tx_msg.len - 1) && in cec_pin_tx_states()
607 !pin->tx_post_eom) { in cec_pin_tx_states()
620 pin->tx_nacked = true; in cec_pin_tx_states()
625 cec_pin_high(pin); in cec_pin_tx_states()
626 pin->state = CEC_ST_TX_PULSE_HIGH_CUSTOM; in cec_pin_tx_states()
630 cec_pin_to_idle(pin); in cec_pin_tx_states()
653 static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) in cec_pin_rx_states() argument
662 switch (pin->state) { in cec_pin_rx_states()
665 v = cec_pin_read(pin); in cec_pin_rx_states()
668 pin->state = CEC_ST_RX_START_BIT_HIGH; in cec_pin_rx_states()
669 delta = ktime_us_delta(ts, pin->ts); in cec_pin_rx_states()
672 if (!pin->rx_start_bit_low_too_short_cnt++) { in cec_pin_rx_states()
673 pin->rx_start_bit_low_too_short_ts = ktime_to_ns(pin->ts); in cec_pin_rx_states()
674 pin->rx_start_bit_low_too_short_delta = delta; in cec_pin_rx_states()
676 cec_pin_to_idle(pin); in cec_pin_rx_states()
679 if (rx_arb_lost(pin, &poll)) { in cec_pin_rx_states()
680 cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf); in cec_pin_rx_states()
681 pin->tx_generated_poll = true; in cec_pin_rx_states()
682 pin->tx_extra_bytes = 0; in cec_pin_rx_states()
683 pin->state = CEC_ST_TX_START_BIT_HIGH; in cec_pin_rx_states()
684 pin->ts = ts; in cec_pin_rx_states()
689 v = cec_pin_read(pin); in cec_pin_rx_states()
690 delta = ktime_us_delta(ts, pin->ts); in cec_pin_rx_states()
696 pin->rx_start_bit_too_long_cnt++; in cec_pin_rx_states()
697 cec_pin_to_idle(pin); in cec_pin_rx_states()
704 if (!pin->rx_start_bit_too_short_cnt++) { in cec_pin_rx_states()
705 pin->rx_start_bit_too_short_ts = ktime_to_ns(pin->ts); in cec_pin_rx_states()
706 pin->rx_start_bit_too_short_delta = delta; in cec_pin_rx_states()
708 cec_pin_to_idle(pin); in cec_pin_rx_states()
711 if (rx_low_drive(pin)) { in cec_pin_rx_states()
713 cec_pin_low(pin); in cec_pin_rx_states()
714 pin->state = CEC_ST_RX_LOW_DRIVE; in cec_pin_rx_states()
715 pin->rx_low_drive_cnt++; in cec_pin_rx_states()
718 pin->state = CEC_ST_RX_DATA_SAMPLE; in cec_pin_rx_states()
719 pin->ts = ts; in cec_pin_rx_states()
720 pin->rx_eom = false; in cec_pin_rx_states()
724 v = cec_pin_read(pin); in cec_pin_rx_states()
725 pin->state = CEC_ST_RX_DATA_POST_SAMPLE; in cec_pin_rx_states()
726 switch (pin->rx_bit % 10) { in cec_pin_rx_states()
728 if (pin->rx_bit / 10 < CEC_MAX_MSG_SIZE) in cec_pin_rx_states()
729 pin->rx_msg.msg[pin->rx_bit / 10] |= in cec_pin_rx_states()
730 v << (7 - (pin->rx_bit % 10)); in cec_pin_rx_states()
733 pin->rx_eom = v; in cec_pin_rx_states()
734 pin->rx_msg.len = pin->rx_bit / 10 + 1; in cec_pin_rx_states()
739 pin->rx_bit++; in cec_pin_rx_states()
743 pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW; in cec_pin_rx_states()
747 v = cec_pin_read(pin); in cec_pin_rx_states()
748 delta = ktime_us_delta(ts, pin->ts); in cec_pin_rx_states()
754 pin->rx_data_bit_too_long_cnt++; in cec_pin_rx_states()
755 cec_pin_to_idle(pin); in cec_pin_rx_states()
761 if (rx_low_drive(pin)) { in cec_pin_rx_states()
763 cec_pin_low(pin); in cec_pin_rx_states()
764 pin->state = CEC_ST_RX_LOW_DRIVE; in cec_pin_rx_states()
765 pin->rx_low_drive_cnt++; in cec_pin_rx_states()
774 if (!pin->rx_data_bit_too_short_cnt++) { in cec_pin_rx_states()
775 pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts); in cec_pin_rx_states()
776 pin->rx_data_bit_too_short_delta = delta; in cec_pin_rx_states()
778 cec_pin_low(pin); in cec_pin_rx_states()
779 pin->state = CEC_ST_RX_LOW_DRIVE; in cec_pin_rx_states()
780 pin->rx_low_drive_cnt++; in cec_pin_rx_states()
783 pin->ts = ts; in cec_pin_rx_states()
784 if (pin->rx_bit % 10 != 9) { in cec_pin_rx_states()
785 pin->state = CEC_ST_RX_DATA_SAMPLE; in cec_pin_rx_states()
789 dest = cec_msg_destination(&pin->rx_msg); in cec_pin_rx_states()
792 for_us = bcast || (pin->la_mask & (1 << dest)); in cec_pin_rx_states()
796 if (for_us && rx_nack(pin)) { in cec_pin_rx_states()
803 pin->state = CEC_ST_RX_ACK_HIGH_POST; in cec_pin_rx_states()
806 cec_pin_low(pin); in cec_pin_rx_states()
807 pin->state = CEC_ST_RX_ACK_LOW; in cec_pin_rx_states()
811 cec_pin_high(pin); in cec_pin_rx_states()
812 pin->state = CEC_ST_RX_ACK_LOW_POST; in cec_pin_rx_states()
817 v = cec_pin_read(pin); in cec_pin_rx_states()
818 if (v && pin->rx_eom) { in cec_pin_rx_states()
819 pin->work_rx_msg = pin->rx_msg; in cec_pin_rx_states()
820 pin->work_rx_msg.rx_ts = ktime_to_ns(ts); in cec_pin_rx_states()
821 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_rx_states()
822 pin->ts = ts; in cec_pin_rx_states()
823 pin->state = CEC_ST_RX_ACK_FINISH; in cec_pin_rx_states()
826 pin->rx_bit++; in cec_pin_rx_states()
827 pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW; in cec_pin_rx_states()
831 cec_pin_to_idle(pin); in cec_pin_rx_states()
845 struct cec_pin *pin = container_of(timer, struct cec_pin, timer); in cec_pin_timer() local
846 struct cec_adapter *adap = pin->adap; in cec_pin_timer()
852 if (ktime_to_ns(pin->timer_ts)) { in cec_pin_timer()
853 delta = ktime_us_delta(ts, pin->timer_ts); in cec_pin_timer()
854 pin->timer_cnt++; in cec_pin_timer()
855 if (delta > 100 && pin->state != CEC_ST_IDLE) { in cec_pin_timer()
857 pin->timer_sum_overrun += delta; in cec_pin_timer()
858 pin->timer_100us_overruns++; in cec_pin_timer()
860 pin->timer_300us_overruns++; in cec_pin_timer()
861 if (delta > pin->timer_max_overrun) in cec_pin_timer()
862 pin->timer_max_overrun = delta; in cec_pin_timer()
866 cec_pin_read(pin); in cec_pin_timer()
868 if (pin->wait_usecs) { in cec_pin_timer()
870 * If we are monitoring the pin, then we have to in cec_pin_timer()
873 if (pin->wait_usecs > 150) { in cec_pin_timer()
874 pin->wait_usecs -= 100; in cec_pin_timer()
875 pin->timer_ts = ktime_add_us(ts, 100); in cec_pin_timer()
879 if (pin->wait_usecs > 100) { in cec_pin_timer()
880 pin->wait_usecs /= 2; in cec_pin_timer()
881 pin->timer_ts = ktime_add_us(ts, pin->wait_usecs); in cec_pin_timer()
883 ns_to_ktime(pin->wait_usecs * 1000)); in cec_pin_timer()
886 pin->timer_ts = ktime_add_us(ts, pin->wait_usecs); in cec_pin_timer()
888 ns_to_ktime(pin->wait_usecs * 1000)); in cec_pin_timer()
889 pin->wait_usecs = 0; in cec_pin_timer()
893 switch (pin->state) { in cec_pin_timer()
918 cec_pin_tx_states(pin, ts); in cec_pin_timer()
931 cec_pin_rx_states(pin, ts); in cec_pin_timer()
936 if (!cec_pin_high(pin)) { in cec_pin_timer()
938 pin->ts = ts; in cec_pin_timer()
939 pin->state = CEC_ST_RX_START_BIT_LOW; in cec_pin_timer()
947 if (pin->tx_msg.len && pin->tx_signal_free_time > in cec_pin_timer()
949 pin->tx_signal_free_time = in cec_pin_timer()
953 if (ktime_to_ns(pin->ts) == 0) in cec_pin_timer()
954 pin->ts = ts; in cec_pin_timer()
955 if (pin->tx_msg.len) { in cec_pin_timer()
960 delta = ktime_us_delta(ts, pin->ts); in cec_pin_timer()
962 pin->tx_signal_free_time) { in cec_pin_timer()
963 pin->tx_nacked = false; in cec_pin_timer()
964 if (tx_custom_start(pin)) in cec_pin_timer()
965 pin->state = CEC_ST_TX_START_BIT_LOW_CUSTOM; in cec_pin_timer()
967 pin->state = CEC_ST_TX_START_BIT_LOW; in cec_pin_timer()
969 cec_pin_low(pin); in cec_pin_timer()
973 pin->tx_signal_free_time - 1) in cec_pin_timer()
974 pin->state = CEC_ST_TX_WAIT; in cec_pin_timer()
977 if (pin->tx_custom_pulse && pin->state == CEC_ST_IDLE) { in cec_pin_timer()
978 pin->tx_custom_pulse = false; in cec_pin_timer()
980 cec_pin_low(pin); in cec_pin_timer()
981 pin->state = CEC_ST_TX_PULSE_LOW_CUSTOM; in cec_pin_timer()
984 if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL || in cec_pin_timer()
985 pin->enable_irq_failed || adap->is_configuring || in cec_pin_timer()
989 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_ENABLE); in cec_pin_timer()
990 pin->state = CEC_ST_RX_IRQ; in cec_pin_timer()
991 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_timer()
996 cec_pin_high(pin); in cec_pin_timer()
997 cec_pin_to_idle(pin); in cec_pin_timer()
1004 switch (pin->state) { in cec_pin_timer()
1008 usecs = pin->tx_custom_low_usecs; in cec_pin_timer()
1013 usecs = pin->tx_custom_high_usecs; in cec_pin_timer()
1016 usecs = states[pin->state].usecs; in cec_pin_timer()
1021 pin->wait_usecs = 0; in cec_pin_timer()
1022 pin->timer_ts = ktime_add_us(ts, usecs); in cec_pin_timer()
1027 pin->wait_usecs = usecs - 100; in cec_pin_timer()
1028 pin->timer_ts = ktime_add_us(ts, 100); in cec_pin_timer()
1036 struct cec_pin *pin = adap->pin; in cec_pin_thread_func() local
1038 pin->enabled_irq = false; in cec_pin_thread_func()
1039 pin->enable_irq_failed = false; in cec_pin_thread_func()
1041 wait_event_interruptible(pin->kthread_waitq, in cec_pin_thread_func()
1043 pin->work_rx_msg.len || in cec_pin_thread_func()
1044 pin->work_tx_status || in cec_pin_thread_func()
1045 atomic_read(&pin->work_irq_change) || in cec_pin_thread_func()
1046 atomic_read(&pin->work_pin_num_events)); in cec_pin_thread_func()
1051 if (pin->work_rx_msg.len) { in cec_pin_thread_func()
1052 struct cec_msg *msg = &pin->work_rx_msg; in cec_pin_thread_func()
1055 rx_add_byte(pin)) { in cec_pin_thread_func()
1059 if (msg->len > 2 && rx_remove_byte(pin)) { in cec_pin_thread_func()
1066 ns_to_ktime(pin->work_rx_msg.rx_ts)); in cec_pin_thread_func()
1070 if (pin->work_tx_status) { in cec_pin_thread_func()
1071 unsigned int tx_status = pin->work_tx_status; in cec_pin_thread_func()
1073 pin->work_tx_status = 0; in cec_pin_thread_func()
1075 pin->work_tx_ts); in cec_pin_thread_func()
1078 while (atomic_read(&pin->work_pin_num_events)) { in cec_pin_thread_func()
1079 unsigned int idx = pin->work_pin_events_rd; in cec_pin_thread_func()
1080 u8 v = pin->work_pin_events[idx]; in cec_pin_thread_func()
1085 pin->work_pin_ts[idx]); in cec_pin_thread_func()
1086 pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; in cec_pin_thread_func()
1087 atomic_dec(&pin->work_pin_num_events); in cec_pin_thread_func()
1090 switch (atomic_xchg(&pin->work_irq_change, in cec_pin_thread_func()
1093 if (pin->enabled_irq) { in cec_pin_thread_func()
1094 pin->ops->disable_irq(adap); in cec_pin_thread_func()
1095 pin->enabled_irq = false; in cec_pin_thread_func()
1096 pin->enable_irq_failed = false; in cec_pin_thread_func()
1098 cec_pin_high(pin); in cec_pin_thread_func()
1099 if (pin->state == CEC_ST_OFF) in cec_pin_thread_func()
1101 cec_pin_to_idle(pin); in cec_pin_thread_func()
1102 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_thread_func()
1106 if (pin->enabled_irq || !pin->ops->enable_irq || in cec_pin_thread_func()
1107 pin->adap->devnode.unregistered) in cec_pin_thread_func()
1109 pin->enable_irq_failed = !pin->ops->enable_irq(adap); in cec_pin_thread_func()
1110 if (pin->enable_irq_failed) { in cec_pin_thread_func()
1111 cec_pin_to_idle(pin); in cec_pin_thread_func()
1112 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_thread_func()
1115 pin->enabled_irq = true; in cec_pin_thread_func()
1123 if (pin->enabled_irq) { in cec_pin_thread_func()
1124 pin->ops->disable_irq(pin->adap); in cec_pin_thread_func()
1125 pin->enabled_irq = false; in cec_pin_thread_func()
1126 pin->enable_irq_failed = false; in cec_pin_thread_func()
1127 cec_pin_high(pin); in cec_pin_thread_func()
1134 struct cec_pin *pin = adap->pin; in cec_pin_adap_enable() local
1137 cec_pin_read(pin); in cec_pin_adap_enable()
1138 cec_pin_to_idle(pin); in cec_pin_adap_enable()
1139 pin->tx_msg.len = 0; in cec_pin_adap_enable()
1140 pin->timer_ts = ns_to_ktime(0); in cec_pin_adap_enable()
1141 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); in cec_pin_adap_enable()
1142 if (!pin->kthread) { in cec_pin_adap_enable()
1143 pin->kthread = kthread_run(cec_pin_thread_func, adap, in cec_pin_adap_enable()
1144 "cec-pin"); in cec_pin_adap_enable()
1145 if (IS_ERR(pin->kthread)) { in cec_pin_adap_enable()
1146 int err = PTR_ERR(pin->kthread); in cec_pin_adap_enable()
1148 pr_err("cec-pin: kernel_thread() failed\n"); in cec_pin_adap_enable()
1149 pin->kthread = NULL; in cec_pin_adap_enable()
1153 hrtimer_start(&pin->timer, ns_to_ktime(0), in cec_pin_adap_enable()
1155 } else if (pin->kthread) { in cec_pin_adap_enable()
1156 hrtimer_cancel(&pin->timer); in cec_pin_adap_enable()
1157 cec_pin_high(pin); in cec_pin_adap_enable()
1158 cec_pin_to_idle(pin); in cec_pin_adap_enable()
1159 pin->state = CEC_ST_OFF; in cec_pin_adap_enable()
1160 pin->work_tx_status = 0; in cec_pin_adap_enable()
1161 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_adap_enable()
1162 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_adap_enable()
1169 struct cec_pin *pin = adap->pin; in cec_pin_adap_log_addr() local
1172 pin->la_mask = 0; in cec_pin_adap_log_addr()
1174 pin->la_mask |= (1 << log_addr); in cec_pin_adap_log_addr()
1178 void cec_pin_start_timer(struct cec_pin *pin) in cec_pin_start_timer() argument
1180 if (pin->state != CEC_ST_RX_IRQ) in cec_pin_start_timer()
1183 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_start_timer()
1184 wake_up_interruptible(&pin->kthread_waitq); in cec_pin_start_timer()
1190 struct cec_pin *pin = adap->pin; in cec_pin_adap_transmit() local
1197 if (pin->state != CEC_ST_IDLE && in cec_pin_adap_transmit()
1201 pin->tx_signal_free_time = signal_free_time; in cec_pin_adap_transmit()
1202 pin->tx_extra_bytes = 0; in cec_pin_adap_transmit()
1203 pin->tx_msg = *msg; in cec_pin_adap_transmit()
1206 pin->tx_extra_bytes = tx_add_bytes(pin); in cec_pin_adap_transmit()
1208 if (msg->len > 2 && tx_remove_byte(pin)) { in cec_pin_adap_transmit()
1210 pin->tx_msg.len--; in cec_pin_adap_transmit()
1212 pin->work_tx_status = 0; in cec_pin_adap_transmit()
1213 pin->tx_bit = 0; in cec_pin_adap_transmit()
1214 cec_pin_start_timer(pin); in cec_pin_adap_transmit()
1221 struct cec_pin *pin = adap->pin; in cec_pin_adap_status() local
1223 seq_printf(file, "state: %s\n", states[pin->state].name); in cec_pin_adap_status()
1224 seq_printf(file, "tx_bit: %d\n", pin->tx_bit); in cec_pin_adap_status()
1225 seq_printf(file, "rx_bit: %d\n", pin->rx_bit); in cec_pin_adap_status()
1226 seq_printf(file, "cec pin: %d\n", call_pin_op(pin, read)); in cec_pin_adap_status()
1227 seq_printf(file, "cec pin events dropped: %u\n", in cec_pin_adap_status()
1228 pin->work_pin_events_dropped_cnt); in cec_pin_adap_status()
1229 if (pin->ops->enable_irq) in cec_pin_adap_status()
1230 seq_printf(file, "irq %s\n", pin->enabled_irq ? "enabled" : in cec_pin_adap_status()
1231 (pin->enable_irq_failed ? "failed" : "disabled")); in cec_pin_adap_status()
1232 if (pin->timer_100us_overruns) { in cec_pin_adap_status()
1234 pin->timer_100us_overruns, pin->timer_cnt); in cec_pin_adap_status()
1236 pin->timer_300us_overruns, pin->timer_cnt); in cec_pin_adap_status()
1238 pin->timer_max_overrun); in cec_pin_adap_status()
1240 pin->timer_sum_overrun / pin->timer_100us_overruns); in cec_pin_adap_status()
1242 if (pin->rx_start_bit_low_too_short_cnt) in cec_pin_adap_status()
1245 pin->rx_start_bit_low_too_short_cnt, in cec_pin_adap_status()
1246 pin->rx_start_bit_low_too_short_delta, in cec_pin_adap_status()
1247 pin->rx_start_bit_low_too_short_ts); in cec_pin_adap_status()
1248 if (pin->rx_start_bit_too_short_cnt) in cec_pin_adap_status()
1251 pin->rx_start_bit_too_short_cnt, in cec_pin_adap_status()
1252 pin->rx_start_bit_too_short_delta, in cec_pin_adap_status()
1253 pin->rx_start_bit_too_short_ts); in cec_pin_adap_status()
1254 if (pin->rx_start_bit_too_long_cnt) in cec_pin_adap_status()
1256 pin->rx_start_bit_too_long_cnt); in cec_pin_adap_status()
1257 if (pin->rx_data_bit_too_short_cnt) in cec_pin_adap_status()
1260 pin->rx_data_bit_too_short_cnt, in cec_pin_adap_status()
1261 pin->rx_data_bit_too_short_delta, in cec_pin_adap_status()
1262 pin->rx_data_bit_too_short_ts); in cec_pin_adap_status()
1263 if (pin->rx_data_bit_too_long_cnt) in cec_pin_adap_status()
1265 pin->rx_data_bit_too_long_cnt); in cec_pin_adap_status()
1266 seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt); in cec_pin_adap_status()
1267 seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt); in cec_pin_adap_status()
1268 pin->work_pin_events_dropped_cnt = 0; in cec_pin_adap_status()
1269 pin->timer_cnt = 0; in cec_pin_adap_status()
1270 pin->timer_100us_overruns = 0; in cec_pin_adap_status()
1271 pin->timer_300us_overruns = 0; in cec_pin_adap_status()
1272 pin->timer_max_overrun = 0; in cec_pin_adap_status()
1273 pin->timer_sum_overrun = 0; in cec_pin_adap_status()
1274 pin->rx_start_bit_low_too_short_cnt = 0; in cec_pin_adap_status()
1275 pin->rx_start_bit_too_short_cnt = 0; in cec_pin_adap_status()
1276 pin->rx_start_bit_too_long_cnt = 0; in cec_pin_adap_status()
1277 pin->rx_data_bit_too_short_cnt = 0; in cec_pin_adap_status()
1278 pin->rx_data_bit_too_long_cnt = 0; in cec_pin_adap_status()
1279 pin->rx_low_drive_cnt = 0; in cec_pin_adap_status()
1280 pin->tx_low_drive_cnt = 0; in cec_pin_adap_status()
1281 call_void_pin_op(pin, status, file); in cec_pin_adap_status()
1287 struct cec_pin *pin = adap->pin; in cec_pin_adap_monitor_all_enable() local
1289 pin->monitor_all = enable; in cec_pin_adap_monitor_all_enable()
1295 struct cec_pin *pin = adap->pin; in cec_pin_adap_free() local
1297 if (pin->kthread) in cec_pin_adap_free()
1298 kthread_stop(pin->kthread); in cec_pin_adap_free()
1299 pin->kthread = NULL; in cec_pin_adap_free()
1300 if (pin->ops->free) in cec_pin_adap_free()
1301 pin->ops->free(adap); in cec_pin_adap_free()
1302 adap->pin = NULL; in cec_pin_adap_free()
1303 kfree(pin); in cec_pin_adap_free()
1308 struct cec_pin *pin = adap->pin; in cec_pin_received() local
1310 if (pin->ops->received && !adap->devnode.unregistered) in cec_pin_received()
1311 return pin->ops->received(adap, msg); in cec_pin_received()
1317 struct cec_pin *pin = adap->pin; in cec_pin_changed() local
1319 cec_pin_update(pin, value, false); in cec_pin_changed()
1322 atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); in cec_pin_changed()
1344 struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL); in cec_pin_allocate_adapter() local
1346 if (pin == NULL) in cec_pin_allocate_adapter()
1348 pin->ops = pin_ops; in cec_pin_allocate_adapter()
1349 hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in cec_pin_allocate_adapter()
1350 atomic_set(&pin->work_pin_num_events, 0); in cec_pin_allocate_adapter()
1351 pin->timer.function = cec_pin_timer; in cec_pin_allocate_adapter()
1352 init_waitqueue_head(&pin->kthread_waitq); in cec_pin_allocate_adapter()
1353 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; in cec_pin_allocate_adapter()
1354 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT; in cec_pin_allocate_adapter()
1361 kfree(pin); in cec_pin_allocate_adapter()
1365 adap->pin = pin; in cec_pin_allocate_adapter()
1366 pin->adap = adap; in cec_pin_allocate_adapter()
1367 cec_pin_update(pin, cec_pin_high(pin), true); in cec_pin_allocate_adapter()