void tx_irq_handle(void) { unsigned tx_status = aocec_rd_reg(CEC_TX_MSG_STATUS); switch (tx_status) { case TX_DONE: aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; case TX_BUSY: aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; case TX_ERROR: if (cec_msg_dbg_en == 1) hdmi_print(INF, CEC "TX ERROR!!!\n"); if (RX_ERROR == aocec_rd_reg(CEC_RX_MSG_STATUS)) { cec_hw_reset(); } else { aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); } //aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; default: break; } aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 1)); //aml_write_reg32(P_AO_CEC_INTR_MASKN, aml_read_reg32(P_AO_CEC_INTR_MASKN) | (1 << 2)); }
static int ao_cec_ll_rx( unsigned char *msg, unsigned char *len) { unsigned char i; unsigned char data; unsigned char n; unsigned char *msg_start = msg; unsigned int num; int rx_msg_length; int rx_status; rx_status = aocec_rd_reg(CEC_RX_MSG_STATUS); num = aocec_rd_reg(CEC_RX_NUM_MSG); printk("rx irq:rx_status:0x%x:: num :0x%x\n", rx_status, num); //aml_set_reg32_bits(P_AO_CEC_INTR_CLR, 1, 2, 1); if(RX_DONE != rx_status){ printk("rx irq:!!!RX_DONE\n"); aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); return -1; } if(1 != num){ printk("rx irq:!!!num\n"); //aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); //aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); aocec_wr_reg(CEC_RX_CLEAR_BUF, 1); aml_set_reg32_bits(P_AO_CEC_INTR_CLR, 1, 2, 1); return -1; } rx_msg_length = aocec_rd_reg(CEC_RX_MSG_LENGTH) + 1; aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); for (i = 0; i < rx_msg_length && i < MAX_MSG; i++) { data = aocec_rd_reg(CEC_RX_MSG_0_HEADER +i); *msg = data; msg++; } *len = rx_msg_length; rx_status = aocec_rd_reg(CEC_RX_MSG_STATUS); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); //aocec_wr_reg(CEC_RX_CLEAR_BUF, 1); aml_set_reg32_bits(P_AO_CEC_INTR_CLR, 1, 2, 1); cec_hw_reset(); if(cec_msg_dbg_en == 1){ pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: rx msg len: %d dat: ", rx_msg_length); for(n = 0; n < rx_msg_length; n++) { pos += sprintf(msg_log_buf + pos, "%02x ", msg_start[n]); } pos += sprintf(msg_log_buf + pos, "\n"); msg_log_buf[pos] = '\0'; hdmi_print(INF, CEC "%s", msg_log_buf); } return rx_status; }
int cec_rx_buf_check(void) { if (0xf == aocec_rd_reg(CEC_RX_NUM_MSG)) { aocec_wr_reg(CEC_RX_CLEAR_BUF, 0x1); aocec_wr_reg(CEC_RX_CLEAR_BUF, 0x0); hdmi_print(INF, CEC "rx buf clean\n"); return 1; } return 0; }
void cec_hw_reset(void) { //unsigned long data32; // Assert SW reset AO_CEC //data32 = 0; //data32 |= 0 << 1; // [2:1] cntl_clk: 0=Disable clk (Power-off mode); 1=Enable gated clock (Normal mode); 2=Enable free-run clk (Debug mode). //data32 |= 1 << 0; // [0] sw_reset: 1=Reset aml_write_reg32(P_AO_CEC_GEN_CNTL, 0x1); // Enable gated clock (Normal mode). aml_set_reg32_bits(P_AO_CEC_GEN_CNTL, 1, 1, 1); // Release SW reset aml_set_reg32_bits(P_AO_CEC_GEN_CNTL, 0, 0, 1); // Enable all AO_CEC interrupt sources if (!cec_int_disable_flag) aml_set_reg32_bits(P_AO_CEC_INTR_MASKN, 0x6, 0, 3); aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | cec_global_info.my_node_index); //Cec arbitration 3/5/7 bit time set. cec_arbit_bit_time_set(3, 0x118, 0); cec_arbit_bit_time_set(5, 0x000, 0); cec_arbit_bit_time_set(7, 0x2aa, 0); hdmi_print(INF, CEC "hw reset :logical addr:0x%x\n", aocec_rd_reg(CEC_LOGICAL_ADDR0)); }
int cec_ll_rx( unsigned char *msg, unsigned char *len) { int i; int ret = -1; int pos; if ((RX_DONE != aocec_rd_reg(CEC_RX_MSG_STATUS)) || (1 != aocec_rd_reg(CEC_RX_NUM_MSG))) { //cec_rx_buf_check(); aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 2)); aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); return ret; } *len = aocec_rd_reg(CEC_RX_MSG_LENGTH) + 1; for (i = 0; i < (*len) && i < MAX_MSG; i++) { msg[i]= aocec_rd_reg(CEC_RX_MSG_0_HEADER +i); } ret = aocec_rd_reg(CEC_RX_MSG_STATUS); if (cec_msg_dbg_en == 1) { pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: rx msg len: %d dat: ", *len); for (i = 0; i < (*len); i++) { pos += sprintf(msg_log_buf + pos, "%02x ", msg[i]); } pos += sprintf(msg_log_buf + pos, "\n"); msg_log_buf[pos] = '\0'; hdmi_print(INF, CEC "%s", msg_log_buf); } //cec_rx_buf_check(); aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 2)); aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); //aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 2)); return ret; }
static int ao_cec_ll_tx_polling(const unsigned char *msg, unsigned char len) { int i; unsigned int ret = 0xf; unsigned int n; unsigned int j = 30; while( aocec_rd_reg(CEC_TX_MSG_STATUS)){ if(TX_ERROR == aocec_rd_reg(CEC_TX_MSG_STATUS)){ //aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); //cec_hw_reset(); break; } if(!(j--)){ hdmi_print(INF, CEC "tx busy time out.\n"); aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; } msleep(5); } aml_set_reg32_bits(P_AO_CEC_INTR_MASKN, 0x0, 1, 1); for (i = 0; i < len; i++) { aocec_wr_reg(CEC_TX_MSG_0_HEADER + i, msg[i]); } aocec_wr_reg(CEC_TX_MSG_LENGTH, len-1); aocec_wr_reg(CEC_TX_MSG_CMD, RX_ACK_CURRENT); j = 30; while((TX_DONE != aocec_rd_reg(CEC_TX_MSG_STATUS)) && (j--)){ if(TX_ERROR == aocec_rd_reg(CEC_TX_MSG_STATUS)) break; msleep(5); } ret = aocec_rd_reg(CEC_TX_MSG_STATUS); if(ret == TX_DONE) ret = 1; else ret = 0; aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); aml_set_reg32_bits(P_AO_CEC_INTR_MASKN, 1, 1, 1); msleep(100); if(cec_msg_dbg_en == 1) { pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: tx msg len: %d dat: ", len); for(n = 0; n < len; n++) { pos += sprintf(msg_log_buf + pos, "%02x ", msg[n]); } pos += sprintf(msg_log_buf + pos, "\nCEC: tx state: %d\n", ret); msg_log_buf[pos] = '\0'; printk("%s", msg_log_buf); } return ret; }
int cec_ll_tx_polling(const unsigned char *msg, unsigned char len) { int i; unsigned int ret = 0xf; unsigned int n; unsigned int j = 30; int pos; aml_set_reg32_bits(P_AO_CEC_INTR_MASKN, 0x0, 1, 1); for (i = 0; i < len; i++) { aocec_wr_reg(CEC_TX_MSG_0_HEADER + i, msg[i]); } aocec_wr_reg(CEC_TX_MSG_LENGTH, len-1); aocec_wr_reg(CEC_TX_MSG_CMD, RX_ACK_CURRENT); while((TX_DONE != aocec_rd_reg(CEC_TX_MSG_STATUS)) && (j--)){ msleep(5); } ret = aocec_rd_reg(CEC_TX_MSG_STATUS); if(ret == TX_DONE) ret = 1; else ret = 0; aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); aml_set_reg32_bits(P_AO_CEC_INTR_MASKN, 1, 1, 1); if(cec_msg_dbg_en == 1) { pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: tx msg len: %d dat: ", len); for(n = 0; n < len; n++) { pos += sprintf(msg_log_buf + pos, "%02x ", msg[n]); } pos += sprintf(msg_log_buf + pos, "\nCEC: tx state: %d\n", ret); msg_log_buf[pos] = '\0'; printk("%s", msg_log_buf); } return ret; }
void tx_irq_handle(void){ unsigned tx_status = aocec_rd_reg(CEC_TX_MSG_STATUS); switch(tx_status){ case TX_DONE: aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; case TX_BUSY: aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; case TX_ERROR: cec_hw_reset(); //aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; default: break; } aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 1)); //aml_write_reg32(P_AO_CEC_INTR_MASKN, aml_read_reg32(P_AO_CEC_INTR_MASKN) | (1 << 2)); }
static void ao_cec_tx_irq_handle(void) { unsigned tx_status = aocec_rd_reg(CEC_TX_MSG_STATUS); printk("tx_status:0x%x\n", tx_status); switch(tx_status){ case TX_DONE: aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; case TX_BUSY: aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; case TX_ERROR: cec_hw_reset(); //aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); //aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; default: break; } aml_set_reg32_bits(P_AO_CEC_INTR_CLR, 1, 1, 1); }
// return value: 1: successful 0: error static int cec_ll_tx_once(const unsigned char *msg, unsigned char len) { int i; unsigned int ret = 0xf; unsigned int n; unsigned int cnt = 30; int pos; while (aocec_rd_reg(CEC_TX_MSG_STATUS) || aocec_rd_reg(CEC_RX_MSG_STATUS)) { msleep(5); if (TX_ERROR == aocec_rd_reg(CEC_TX_MSG_STATUS)) { if (cec_msg_dbg_en == 1) hdmi_print(INF, CEC "tx once:tx error!\n"); //aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); //cec_hw_reset(); break; } if (!(cnt--)) { if (cec_msg_dbg_en == 1) hdmi_print(INF, CEC "tx busy time out.\n"); aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; } } for (i = 0; i < len; i++) { aocec_wr_reg(CEC_TX_MSG_0_HEADER + i, msg[i]); } aocec_wr_reg(CEC_TX_MSG_LENGTH, len-1); aocec_wr_reg(CEC_TX_MSG_CMD, TX_REQ_CURRENT); if (cec_msg_dbg_en == 1) { pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: tx msg len: %d dat: ", len); for (n = 0; n < len; n++) { pos += sprintf(msg_log_buf + pos, "%02x ", msg[n]); } pos += sprintf(msg_log_buf + pos, "\n"); msg_log_buf[pos] = '\0'; printk("%s", msg_log_buf); } return ret; }
int cec_ll_rx( unsigned char *msg, unsigned char *len) { unsigned char i; unsigned char rx_status; unsigned char data; unsigned char msg_log_buf[128]; int pos; unsigned char n; unsigned char *msg_start = msg; int rx_msg_length; if(RX_DONE != aocec_rd_reg(CEC_RX_MSG_STATUS)){ aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); return -1; } if(1 != aocec_rd_reg(CEC_RX_NUM_MSG)){ aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); return -1; } rx_msg_length = aocec_rd_reg(CEC_RX_MSG_LENGTH) + 1; aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT); for (i = 0; i < rx_msg_length && i < MAX_MSG; i++) { data = aocec_rd_reg(CEC_RX_MSG_0_HEADER +i); *msg = data; msg++; } *len = rx_msg_length; rx_status = aocec_rd_reg(CEC_RX_MSG_STATUS); aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP); aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 2)); if(cec_msg_dbg_en == 1){ pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: rx msg len: %d dat: ", rx_msg_length); for(n = 0; n < rx_msg_length; n++) { pos += sprintf(msg_log_buf + pos, "%02x ", msg_start[n]); } pos += sprintf(msg_log_buf + pos, "\n"); msg_log_buf[pos] = '\0'; hdmi_print(INF, CEC "%s", msg_log_buf); } return rx_status; }
void cec_hw_reset(void) { hd_write_reg(P_AO_CEC_GEN_CNTL, 0x1); /* Enable gated clock (Normal mode). */ hd_set_reg_bits(P_AO_CEC_GEN_CNTL, 1, 1, 1); /* Release SW reset */ hd_set_reg_bits(P_AO_CEC_GEN_CNTL, 0, 0, 1); /* Enable all AO_CEC interrupt sources */ if (!cec_int_disable_flag) hd_set_reg_bits(P_AO_CEC_INTR_MASKN, 0x6, 0, 3); aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | cec_global_info.my_node_index); /* Cec arbitration 3/5/7 bit time set. */ cec_arbit_bit_time_set(3, 0x118, 0); cec_arbit_bit_time_set(5, 0x000, 0); cec_arbit_bit_time_set(7, 0x2aa, 0); hdmi_print(INF, CEC "hw reset :logical addr:0x%x\n", aocec_rd_reg(CEC_LOGICAL_ADDR0)); }
static void ao_cec_logic_addr_set(enum _cec_log_dev_addr_e logic_addr) { //tmp debug:set addr 4 for G9TV CEC. To do. aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0x4); }
static void ao_cec_timing_set(void) { //Cec arbitration 3/5/7 bit time set. //ao_cec_arbit_bit_time_set(3, 0x118, 0); //ao_cec_arbit_bit_time_set(5, 0x000, 0); //ao_cec_arbit_bit_time_set(7, 0x2aa, 0); // Program AO CEC's timing parameters to work with 24MHz cec_clk aocec_wr_reg(CEC_CLOCK_DIV_L, (240-1)&0xff); aocec_wr_reg(CEC_CLOCK_DIV_H, ((240-1)>>8)&0xff); aocec_wr_reg(CEC_QUIESCENT_25MS_BIT7_0, 0xC4); // addr=0x20 aocec_wr_reg(CEC_QUIESCENT_25MS_BIT11_8, 0x09); // addr=0x21 aocec_wr_reg(CEC_STARTBITMINL2H_3MS5_BIT7_0, 0x5E); // addr=0x22 aocec_wr_reg(CEC_STARTBITMINL2H_3MS5_BIT8, 0x01); // addr=0x23 aocec_wr_reg(CEC_STARTBITMAXL2H_3MS9_BIT7_0, 0x86); // addr=0x24 aocec_wr_reg(CEC_STARTBITMAXL2H_3MS9_BIT8, 0x01); // addr=0x25 aocec_wr_reg(CEC_STARTBITMINH_0MS6_BIT7_0, 0x3C); // addr=0x26 aocec_wr_reg(CEC_STARTBITMINH_0MS6_BIT8, 0x00); // addr=0x27 aocec_wr_reg(CEC_STARTBITMAXH_1MS0_BIT7_0, 0x64); // addr=0x28 aocec_wr_reg(CEC_STARTBITMAXH_1MS0_BIT8, 0x00); // addr=0x29 aocec_wr_reg(CEC_STARTBITMINTOTAL_4MS3_BIT7_0, 0xAE); // addr=0x2A aocec_wr_reg(CEC_STARTBITMINTOTAL_4MS3_BIT9_8, 0x01); // addr=0x2B aocec_wr_reg(CEC_STARTBITMAXTOTAL_4MS7_BIT7_0, 0xD6); // addr=0x2C aocec_wr_reg(CEC_STARTBITMAXTOTAL_4MS7_BIT9_8, 0x01); // addr=0x2D aocec_wr_reg(CEC_LOGIC1MINL2H_0MS4_BIT7_0, 0x28); // addr=0x2E aocec_wr_reg(CEC_LOGIC1MINL2H_0MS4_BIT8, 0x00); // addr=0x2F aocec_wr_reg(CEC_LOGIC1MAXL2H_0MS8_BIT7_0, 0x50); // addr=0x30 aocec_wr_reg(CEC_LOGIC1MAXL2H_0MS8_BIT8, 0x00); // addr=0x31 aocec_wr_reg(CEC_LOGIC0MINL2H_1MS3_BIT7_0, 0x82); // addr=0x32 aocec_wr_reg(CEC_LOGIC0MINL2H_1MS3_BIT8, 0x00); // addr=0x33 aocec_wr_reg(CEC_LOGIC0MAXL2H_1MS7_BIT7_0, 0xAA); // addr=0x34 aocec_wr_reg(CEC_LOGIC0MAXL2H_1MS7_BIT8, 0x00); // addr=0x35 aocec_wr_reg(CEC_LOGICMINTOTAL_2MS05_BIT7_0, 0xCD); // addr=0x36 aocec_wr_reg(CEC_LOGICMINTOTAL_2MS05_BIT9_8, 0x00); // addr=0x37 aocec_wr_reg(CEC_LOGICMAXHIGH_2MS8_BIT7_0, 0x18); // addr=0x38 aocec_wr_reg(CEC_LOGICMAXHIGH_2MS8_BIT8, 0x01); // addr=0x39 aocec_wr_reg(CEC_LOGICERRLOW_3MS4_BIT7_0, 0x54); // addr=0x3A aocec_wr_reg(CEC_LOGICERRLOW_3MS4_BIT8, 0x01); // addr=0x3B aocec_wr_reg(CEC_NOMSMPPOINT_1MS05, 0x69); // addr=0x3C aocec_wr_reg(CEC_DELCNTR_LOGICERR, 0x35); // addr=0x3E aocec_wr_reg(CEC_TXTIME_17MS_BIT7_0, 0xA4); // addr=0x40 aocec_wr_reg(CEC_TXTIME_17MS_BIT15_8, 0x06); // addr=0x41 aocec_wr_reg(CEC_TXTIME_2BIT_BIT7_0, 0xF0); // addr=0x42 aocec_wr_reg(CEC_TXTIME_2BIT_BIT15_8, 0x01); // addr=0x43 aocec_wr_reg(CEC_TXTIME_4BIT_BIT7_0, 0xD0); // addr=0x44 aocec_wr_reg(CEC_TXTIME_4BIT_BIT15_8, 0x03); // addr=0x45 aocec_wr_reg(CEC_STARTBITNOML2H_3MS7_BIT7_0, 0x72); // addr=0x46 aocec_wr_reg(CEC_STARTBITNOML2H_3MS7_BIT8, 0x01); // addr=0x47 aocec_wr_reg(CEC_STARTBITNOMH_0MS8_BIT7_0, 0x50); // addr=0x48 aocec_wr_reg(CEC_STARTBITNOMH_0MS8_BIT8, 0x00); // addr=0x49 aocec_wr_reg(CEC_LOGIC1NOML2H_0MS6_BIT7_0, 0x3C); // addr=0x4A aocec_wr_reg(CEC_LOGIC1NOML2H_0MS6_BIT8, 0x00); // addr=0x4B aocec_wr_reg(CEC_LOGIC0NOML2H_1MS5_BIT7_0, 0x96); // addr=0x4C aocec_wr_reg(CEC_LOGIC0NOML2H_1MS5_BIT8, 0x00); // addr=0x4D aocec_wr_reg(CEC_LOGIC1NOMH_1MS8_BIT7_0, 0xB4); // addr=0x4E aocec_wr_reg(CEC_LOGIC1NOMH_1MS8_BIT8, 0x00); // addr=0x4F aocec_wr_reg(CEC_LOGIC0NOMH_0MS9_BIT7_0, 0x5A); // addr=0x50 aocec_wr_reg(CEC_LOGIC0NOMH_0MS9_BIT8, 0x00); // addr=0x51 aocec_wr_reg(CEC_LOGICERRLOW_3MS6_BIT7_0, 0x68); // addr=0x52 aocec_wr_reg(CEC_LOGICERRLOW_3MS6_BIT8, 0x01); // addr=0x53 aocec_wr_reg(CEC_CHKCONTENTION_0MS1, 0x0A); // addr=0x54 aocec_wr_reg(CEC_PREPARENXTBIT_0MS05_BIT7_0, 0x05); // addr=0x56 aocec_wr_reg(CEC_PREPARENXTBIT_0MS05_BIT8, 0x00); // addr=0x57 aocec_wr_reg(CEC_NOMSMPACKPOINT_0MS45, 0x2D); // addr=0x58 aocec_wr_reg(CEC_ACK0NOML2H_1MS5_BIT7_0, 0x96); // addr=0x5A aocec_wr_reg(CEC_ACK0NOML2H_1MS5_BIT8, 0x00); // addr=0x5B }
int cec_ll_tx_polling(const unsigned char *msg, unsigned char len) { int i; unsigned int ret = 0xf; unsigned int n; unsigned int j = 30; int pos; while ((TX_BUSY == aocec_rd_reg(CEC_TX_MSG_STATUS)) || (RX_BUSY == aocec_rd_reg(CEC_RX_MSG_STATUS))) { if (TX_ERROR == aocec_rd_reg(CEC_TX_MSG_STATUS)) { if (cec_msg_dbg_en == 1) hdmi_print(INF, CEC "tx polling:tx error!.\n"); /* aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); */ aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); /* cec_hw_reset(); */ break; } if (!(j--)) { if (cec_msg_dbg_en == 1) hdmi_print(INF, CEC "tx busy time out.\n"); aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT); aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); break; } mdelay(5); } hd_set_reg_bits(P_AO_CEC_INTR_MASKN, 0x0, 1, 1); for (i = 0; i < len; i++) aocec_wr_reg(CEC_TX_MSG_0_HEADER + i, msg[i]); aocec_wr_reg(CEC_TX_MSG_LENGTH, len-1); aocec_wr_reg(CEC_TX_MSG_CMD, RX_ACK_CURRENT); j = 30; while ((TX_DONE != aocec_rd_reg(CEC_TX_MSG_STATUS)) && (j--)) { if (TX_ERROR == aocec_rd_reg(CEC_TX_MSG_STATUS)) break; mdelay(5); } ret = aocec_rd_reg(CEC_TX_MSG_STATUS); if (ret == TX_DONE) ret = 1; else ret = 0; aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP); hd_set_reg_bits(P_AO_CEC_INTR_MASKN, 1, 1, 1); if (cec_msg_dbg_en == 1) { pos = 0; pos += sprintf(msg_log_buf + pos, "CEC: tx msg len: %d dat: ", len); for (n = 0; n < len; n++) pos += sprintf(msg_log_buf + pos, "%02x ", msg[n]); pos += sprintf(msg_log_buf + pos, "\nCEC: tx state: %d\n", ret); msg_log_buf[pos] = '\0'; pr_info("%s", msg_log_buf); } return ret; }