|
|
/*
|
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2017-2021. All rights reserved.
|
|
|
* Description: A8300 LNB driver
|
|
|
* Author: Hisilicon
|
|
|
* Create: 2017/10/23
|
|
|
*/
|
|
|
#include "drv_lnbctrl.h"
|
|
|
|
|
|
#include "drv_i2c_ext.h"
|
|
|
|
|
|
#define A8300_ADDR 0x10
|
|
|
#define A8300_CTRL_REG0_ADDR 0
|
|
|
#define A8300_CTRL_REG1_ADDR 1
|
|
|
|
|
|
#define A8300_STATUS_REG0_ADDR 0
|
|
|
|
|
|
#define A8300_I2C_WRITE_TIMES 1
|
|
|
|
|
|
|
|
|
static td_bool g_a8300_inited = TD_FALSE;
|
|
|
static td_u8 g_reg1_data = 0;
|
|
|
static td_u8 g_reg2_data = 0;
|
|
|
static td_u32 g_a8300_port = 0;
|
|
|
|
|
|
static td_s32 a8300_read_byte(lnbctrl_dev_param* param, td_u8 reg_addr, td_u8 *reg_val)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
|
|
|
if (reg_val == TD_NULL) {
|
|
|
soc_log_err("pointer is null\n");
|
|
|
return SOC_ERR_FRONTEND_INVALID_POINT;
|
|
|
}
|
|
|
|
|
|
ret = ext_drv_i2c_read_2stop(param->i2c_num, param->dev_addr, reg_addr, 1, reg_val, 1);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("A8300 read i2c 0x%02x failed.\n", *reg_val);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 a8300_write_byte(lnbctrl_dev_param* param, td_u8 reg_addr, td_u8 reg_val)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
|
|
|
ret = ext_drv_i2c_write(param->i2c_num, param->dev_addr, reg_addr, 1, ®_val, 1);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("A8300 write i2c failed, %x\n", ret);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
soc_log_info("A8300 write i2c 0x%02x ok.\n", reg_val);
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 a8300_init(td_u32 port, td_u8 i2c_channel, td_u8 dev_addr)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
td_u8 reg_val = 0x80;
|
|
|
lnbctrl_dev_param* param = TD_NULL;
|
|
|
|
|
|
if (g_a8300_inited) {
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
g_reg1_data = 0;
|
|
|
g_reg2_data = 0;
|
|
|
|
|
|
/* 添加一个node,所有port共用一个 pstParam */
|
|
|
g_a8300_port = port;
|
|
|
param = lnbctrl_queue_get(g_a8300_port);
|
|
|
if (param == TD_NULL) {
|
|
|
param = lnbctrl_queue_insert(g_a8300_port, i2c_channel, dev_addr);
|
|
|
if (param == TD_NULL) {
|
|
|
soc_log_err("lnbctrl_queue_insert failed.\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!param->inited) {
|
|
|
/* 初始化,寄存器写0。如果不先读一下寄存器的话,首次写入会失效,原因待查。 */
|
|
|
ret = a8300_read_byte(param, A8300_STATUS_REG0_ADDR, ®_val);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("a8300_read_byte 0x%x failed.\n", reg_val);
|
|
|
return ret;
|
|
|
}
|
|
|
ret = a8300_write_byte(param, A8300_STATUS_REG0_ADDR, 0);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("a8300_write_byte failed.\n");
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
reg_val = g_reg1_data;
|
|
|
reg_val |= 0x20; /* 22k波形由外部产生 */
|
|
|
ret = a8300_write_byte(param, A8300_CTRL_REG0_ADDR, reg_val);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("a8300_write_byte 0x%x failed.\n", reg_val);
|
|
|
return ret;
|
|
|
}
|
|
|
g_reg1_data = reg_val;
|
|
|
|
|
|
param->inited = TD_TRUE;
|
|
|
}
|
|
|
|
|
|
g_a8300_inited = TD_TRUE;
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 a8300_standby(td_u32 tuner_port, td_u32 standby)
|
|
|
{
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 a8300_lnbctrl_power(td_u32 tuner_port, td_u8 power)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
td_u8 reg_val;
|
|
|
lnbctrl_dev_param* param;
|
|
|
|
|
|
/* Find node */
|
|
|
param = lnbctrl_queue_get(g_a8300_port);
|
|
|
if (param == TD_NULL) {
|
|
|
soc_log_err("lnbctrl_queue_get failed.\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
reg_val = g_reg1_data;
|
|
|
if (power == 0) {
|
|
|
reg_val &= 0xe0;
|
|
|
} else {
|
|
|
reg_val |= 0x10;
|
|
|
}
|
|
|
|
|
|
ret = a8300_write_byte(param, A8300_CTRL_REG0_ADDR, reg_val);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("a8300_write_byte failed.\n");
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
g_reg1_data = reg_val;
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 a8300_set_lnb_out(td_u32 tuner_port, frontend_lnb_out_level out)
|
|
|
{
|
|
|
td_s32 ret;
|
|
|
lnbctrl_dev_param* param;
|
|
|
td_u8 reg;
|
|
|
|
|
|
param = lnbctrl_queue_get(g_a8300_port);
|
|
|
if (param == TD_NULL) {
|
|
|
soc_log_err("lnbctrl_queue_get failed.\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (!param->inited) {
|
|
|
soc_log_err("pstParam uninited.\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
reg = g_reg1_data;
|
|
|
switch (out) {
|
|
|
case FRONTEND_LNB_OUT_0V:
|
|
|
case FRONTEND_LNB_OUT_BUTT:
|
|
|
reg &= 0xe0;
|
|
|
break;
|
|
|
case FRONTEND_LNB_OUT_13V:
|
|
|
reg &= 0xe0;
|
|
|
reg |= 0x12;
|
|
|
break;
|
|
|
case FRONTEND_LNB_OUT_14V:
|
|
|
reg &= 0xe0;
|
|
|
reg |= 0x13;
|
|
|
break;
|
|
|
case FRONTEND_LNB_OUT_18V:
|
|
|
reg &= 0xe0;
|
|
|
reg |= 0x1b;
|
|
|
break;
|
|
|
case FRONTEND_LNB_OUT_19V:
|
|
|
reg &= 0xe0;
|
|
|
reg |= 0x1c;
|
|
|
break;
|
|
|
default:
|
|
|
soc_log_err("Unkown enout: %d.\n", out);
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
ret = a8300_write_byte(param, A8300_CTRL_REG0_ADDR, reg);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("a8300_write_byte 0x%x failed.\n", reg);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
g_reg1_data = reg;
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 a8300_deinit(td_u32 tuner_port)
|
|
|
{
|
|
|
lnbctrl_dev_param* param;
|
|
|
td_s32 ret;
|
|
|
|
|
|
/* Find node */
|
|
|
param = lnbctrl_queue_get(g_a8300_port);
|
|
|
if (param == TD_NULL) {
|
|
|
soc_log_info("lnbctrl_queue_get failed.\n");
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* A8300 power off */
|
|
|
ret = a8300_lnbctrl_power(g_a8300_port, 0);
|
|
|
if (ret != TD_SUCCESS) {
|
|
|
soc_log_err("a8300_lnbctrl_power0 failed.\n");
|
|
|
return TD_FAILURE;
|
|
|
}
|
|
|
|
|
|
lnbctrl_queue_remove(g_a8300_port);
|
|
|
g_a8300_inited = TD_FALSE;
|
|
|
g_reg1_data = 0;
|
|
|
g_reg2_data = 0;
|
|
|
g_a8300_port = 0;
|
|
|
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|
|
|
td_s32 drv_fe_adp_a8300_regist_func(drv_fe_lnb_ops *lnb_ops)
|
|
|
{
|
|
|
drv_fe_check_pointer(lnb_ops);
|
|
|
|
|
|
lnb_ops->init = a8300_init;
|
|
|
lnb_ops->deinit = a8300_deinit;
|
|
|
lnb_ops->standby = a8300_standby;
|
|
|
lnb_ops->set_lnb_out = a8300_set_lnb_out;
|
|
|
return TD_SUCCESS;
|
|
|
}
|
|
|
|