Пример #1
0
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));
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
// 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;
}
Пример #5
0
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;
}
Пример #6
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));

}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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));

}
Пример #11
0
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);
}
Пример #12
0
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));
}
Пример #13
0
    mutex_unlock(&cec_mutex);
    
    return ret;
}

void cec_polling_online_dev(int log_addr, int *bool)
{
    unsigned long r;
    unsigned char msg[1];

    cec_global_info.my_node_index = log_addr;
    msg[0] = (log_addr<<4) | log_addr;

    aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
    hdmi_print(INF, CEC "CEC_LOGICAL_ADDR0:0x%lx\n",aocec_rd_reg(CEC_LOGICAL_ADDR0));
    r = cec_ll_tx_polling(msg, 1);
    cec_hw_reset();

    if (r == 0) {
        *bool = 0;
    }else{
        memset(&(cec_global_info.cec_node_info[log_addr]), 0, sizeof(cec_node_info_t));
        cec_global_info.cec_node_info[log_addr].dev_type = cec_log_addr_to_dev_type(log_addr);
    	  *bool = 1;
    }
    if(*bool == 0) {
        aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | log_addr);
    }
    hdmi_print(INF, CEC "CEC: poll online logic device: 0x%x BOOL: %d\n", log_addr, *bool);
Пример #14
0
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;
}