static void handle_cec_event(struct cros_ec_cec *cros_ec_cec) { struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; uint32_t events = cros_ec->event_data.data.cec_events; if (events & EC_MKBP_CEC_SEND_OK) cec_transmit_attempt_done(cros_ec_cec->adap, CEC_TX_STATUS_OK); /* FW takes care of all retries, tell core to avoid more retries */ if (events & EC_MKBP_CEC_SEND_FAILED) cec_transmit_attempt_done(cros_ec_cec->adap, CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK); }
static void meson_ao_cec_irq_tx(struct meson_ao_cec_device *ao_cec) { unsigned long tx_status = 0; u8 stat; int ret = 0; meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &stat, &ret); if (ret) goto tx_reg_err; switch (stat) { case TX_DONE: tx_status = CEC_TX_STATUS_OK; break; case TX_BUSY: tx_status = CEC_TX_STATUS_ARB_LOST; break; case TX_IDLE: tx_status = CEC_TX_STATUS_LOW_DRIVE; break; case TX_ERROR: default: tx_status = CEC_TX_STATUS_NACK; break; } /* Clear Interruption */ writel_relaxed(CEC_INTR_TX, ao_cec->base + CEC_INTR_CLR_REG); /* Stop TX */ meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret); if (ret) goto tx_reg_err; cec_transmit_attempt_done(ao_cec->adap, tx_status); return; tx_reg_err: cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR); }
static void rain_process_msg(struct rain *rain) { struct cec_msg msg = {}; const char *cmd = rain->cmd + 3; int stat = -1; for (; *cmd; cmd++) { if (!isxdigit(*cmd)) continue; if (isxdigit(cmd[0]) && isxdigit(cmd[1])) { if (msg.len == CEC_MAX_MSG_SIZE) break; if (hex2bin(msg.msg + msg.len, cmd, 1)) continue; msg.len++; cmd++; continue; } if (!cmd[1]) stat = hex_to_bin(cmd[0]); break; } if (rain->cmd[0] == 'R') { if (stat == 1 || stat == 2) cec_received_msg(rain->adap, &msg); return; } switch (stat) { case 1: cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_OK); break; case 2: cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_NACK); break; default: cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE); break; } }
static void drm_dp_cec_handle_irq(struct drm_dp_aux *aux) { struct cec_adapter *adap = aux->cec.adap; u8 flags; if (drm_dp_dpcd_readb(aux, DP_CEC_TUNNELING_IRQ_FLAGS, &flags) < 0) return; if (flags & DP_CEC_RX_MESSAGE_INFO_VALID) drm_dp_cec_received(aux); if (flags & DP_CEC_TX_MESSAGE_SENT) cec_transmit_attempt_done(adap, CEC_TX_STATUS_OK); else if (flags & DP_CEC_TX_LINE_ERROR) cec_transmit_attempt_done(adap, CEC_TX_STATUS_ERROR | CEC_TX_STATUS_MAX_RETRIES); else if (flags & (DP_CEC_TX_ADDRESS_NACK_ERROR | DP_CEC_TX_DATA_NACK_ERROR)) cec_transmit_attempt_done(adap, CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES); drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_IRQ_FLAGS, flags); }
static irqreturn_t tegra_cec_irq_thread_handler(int irq, void *data) { struct device *dev = data; struct tegra_cec *cec = dev_get_drvdata(dev); if (cec->tx_done) { cec_transmit_attempt_done(cec->adap, cec->tx_status); cec->tx_done = false; } if (cec->rx_done) { struct cec_msg msg = {}; msg.len = cec->rx_buf_cnt; memcpy(msg.msg, cec->rx_buf, msg.len); cec_received_msg(cec->adap, &msg); cec->rx_done = false; cec->rx_buf_cnt = 0; } return IRQ_HANDLED; }