You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

341 lines
7.9 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved.
* Description: LNBH25 driver
* Author: Hisilicon
* Created: 2019-10-11
*/
#include "lnbh26.h"
#include "drv_lnbctrl.h"
#include "drv_fe_time.h"
static td_s32 lnbh26_a_write(td_u32 port, td_u8 reg_addr, td_u8 val)
{
td_s32 ret;
td_u8 temp = 0;
ret = lnb_read_byte(port, reg_addr, &temp);
if (ret != TD_SUCCESS) {
return ret;
}
temp &= 0xf0;
temp |= val;
return lnb_write_byte(port, reg_addr, temp);
}
static td_s32 lnbh26_b_write(td_u32 port, td_u8 reg_addr, td_u8 val)
{
td_s32 ret;
td_u8 temp = 0;
ret = lnb_read_byte(port, reg_addr, &temp);
if (ret != TD_SUCCESS) {
return ret;
}
temp &= 0x0f;
temp |= val << BIT_OFFSET_4;
return lnb_write_byte(port, reg_addr, temp);
}
td_s32 lnbh26_a_init(td_u32 port, td_u8 i2c_channel, td_u8 dev_addr)
{
lnbctrl_dev_param* param = NULL;
td_s32 ret;
soc_log_dbg("port %d, I2C %d, addr 0x%x.\n", port, i2c_channel, dev_addr);
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
param = lnbctrl_queue_insert(port, i2c_channel, dev_addr);
if (param == TD_NULL) {
return TD_FAILURE;
}
}
if (!param->inited) {
/* Ext 22K */
ret = lnbh26_a_write(port, 0x3, 0x5);
if (ret != TD_SUCCESS) {
soc_log_err("Port:%u, call lnbh26_a_write Failed, Error Code: [0x%08X]\n", port, ret);
return ret;
}
/* 13V */
ret = lnbh26_a_write(port, 0x2, 0x1);
if (ret != TD_SUCCESS) {
soc_log_err("Port:%u, call lnbh26_a_write Failed, Error Code: [0x%08X]\n", port, ret);
return ret;
}
tuner_mdelay(10); /* 10:delay */
param->lnb_out = FRONTEND_LNB_OUT_13V;
param->inited = TD_TRUE;
}
return TD_SUCCESS;
}
td_s32 lnbh26_b_init(td_u32 port, td_u8 i2c_channel, td_u8 dev_addr)
{
lnbctrl_dev_param* param = NULL;
td_s32 ret;
soc_log_dbg("port %d, I2C %d, addr 0x%x.\n", port, i2c_channel, dev_addr);
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
param = lnbctrl_queue_insert(port, i2c_channel, dev_addr);
if (param == TD_NULL) {
return TD_FAILURE;
}
}
if (!param->inited) {
/* Ext 22K */
ret = lnbh26_b_write(port, 0x3, 0x5);
if (ret != TD_SUCCESS) {
soc_log_err("Port:%u, call lnbh26_b_write Failed, Error Code: [0x%08X]\n", port, ret);
return ret;
}
/* 13V */
ret = lnbh26_b_write(port, 0x2, 0x1);
if (ret != TD_SUCCESS) {
soc_log_err("Port:%u, call lnbh26_b_write Failed, Error Code: [0x%08X]\n", port, ret);
return ret;
}
tuner_mdelay(10); /* 10:delay */
param->lnb_out = FRONTEND_LNB_OUT_13V;
param->inited = TD_TRUE;
}
return TD_SUCCESS;
}
td_s32 lnbh26_a_deinit(td_u32 port)
{
lnbctrl_dev_param* param = NULL;
td_u8 reg_addr;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_SUCCESS;
}
for (reg_addr = 0x2; reg_addr <= 0x5; reg_addr++) {
lnbh26_a_write(port, reg_addr, 0);
}
if (param->inited) {
param->inited = TD_FALSE;
}
lnbctrl_queue_remove(port);
return TD_SUCCESS;
}
td_s32 lnbh26_b_deinit(td_u32 port)
{
lnbctrl_dev_param* param = NULL;
td_u8 reg_addr;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_SUCCESS;
}
for (reg_addr = 0x2; reg_addr <= 0x5; reg_addr++) {
lnbh26_b_write(port, reg_addr, 0);
}
if (param->inited) {
param->inited = TD_FALSE;
}
lnbctrl_queue_remove(port);
return TD_SUCCESS;
}
static td_u8 lnbh26_get_vsel(frontend_lnb_out_level out)
{
td_u8 vsel = 0;
switch (out) {
/* 13.00V: b 0001 */
case FRONTEND_LNB_OUT_13V:
vsel = 0x1;
break;
/* 14.00V: b 0100 */
case FRONTEND_LNB_OUT_14V:
vsel = 0x4;
break;
/* 18.15V: b 1000 */
case FRONTEND_LNB_OUT_18V:
vsel = 0x8;
break;
/* 19.15V: b 1011 */
case FRONTEND_LNB_OUT_19V:
vsel = 0xb;
break;
/* 0V: b 00000 */
case FRONTEND_LNB_OUT_0V:
default:
vsel = 0x0;
break;
}
return vsel;
}
td_s32 lnbh26_a_set_lnb_out(td_u32 port, frontend_lnb_out_level out)
{
td_s32 ret;
lnbctrl_dev_param* param = NULL;
td_u8 vsel;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_FAILURE;
}
if (!param->inited) {
soc_log_err("lnbh26 %d not init.\n", port);
return TD_FAILURE;
}
vsel = lnbh26_get_vsel(out);
ret = lnbh26_a_write(port, 0x02, vsel);
if (ret != TD_SUCCESS) {
soc_log_err("Port:%u, call lnbh26_a_write Failed, Error Code: [0x%08X]\n", port, ret);
return ret;
}
param->lnb_out = out;
return TD_SUCCESS;
}
td_s32 lnbh26_b_set_lnb_out(td_u32 port, frontend_lnb_out_level out)
{
td_s32 ret;
lnbctrl_dev_param* param = NULL;
td_u8 vsel;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_FAILURE;
}
if (!param->inited) {
soc_log_err("lnbh26 %d not init.\n", port);
return TD_FAILURE;
}
vsel = lnbh26_get_vsel(out);
ret = lnbh26_b_write(port, 0x02, vsel);
if (ret != TD_SUCCESS) {
soc_log_err("Port:%u, call lnbh26_a_write Failed, Error Code: [0x%08X]\n", port, ret);
return ret;
}
param->lnb_out = out;
return TD_SUCCESS;
}
td_s32 lnbh26_a_standby(td_u32 port, td_u32 standby)
{
lnbctrl_dev_param* param = NULL;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_FAILURE;
}
/* If standby, power off */
if (standby == 1) {
return lnbh26_a_set_lnb_out(port, FRONTEND_LNB_OUT_0V);
}
return TD_SUCCESS;
}
td_s32 lnbh26_b_standby(td_u32 port, td_u32 standby)
{
lnbctrl_dev_param* param;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_FAILURE;
}
/* If standby, power off */
if (standby == 1) {
return lnbh26_b_set_lnb_out(port, FRONTEND_LNB_OUT_0V);
}
return TD_SUCCESS;
}
td_s32 lnbh26_a_set_ten(td_u32 port, td_bool enable)
{
lnbctrl_dev_param* param = NULL;
td_u8 reg_value = 0;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_FAILURE;
}
lnb_read_byte(port, 0x3, &reg_value);
if (enable) {
reg_value |= 0x1 << 0;
} else {
reg_value &= ~(0x1 << 0);
}
lnb_write_byte(port, 0x3, reg_value);
return TD_SUCCESS;
}
td_s32 lnbh26_b_set_ten(td_u32 port, td_bool enable)
{
lnbctrl_dev_param* param = NULL;
td_u8 reg_value = 0;
param = lnbctrl_queue_get(port);
if (param == TD_NULL) {
return TD_FAILURE;
}
lnb_read_byte(port, 0x3, &reg_value);
if (enable) {
reg_value |= 0x1 << BIT_OFFSET_4;
} else {
reg_value &= ~(0x1 << BIT_OFFSET_4);
}
lnb_write_byte(port, 0x3, reg_value);
return TD_SUCCESS;
}
td_s32 drv_fe_adp_lnbh26_a_regist_func(drv_fe_lnb_ops *lnb_ops)
{
drv_fe_check_pointer(lnb_ops);
lnb_ops->init = lnbh26_a_init;
lnb_ops->deinit = lnbh26_a_deinit;
lnb_ops->standby = lnbh26_a_standby;
lnb_ops->set_lnb_out = lnbh26_a_set_lnb_out;
lnb_ops->i2c_read_byte = lnb_read_byte;
lnb_ops->i2c_write_byte = lnb_write_byte;
return TD_SUCCESS;
}
td_s32 drv_fe_adp_lnbh26_b_regist_func(drv_fe_lnb_ops *lnb_ops)
{
drv_fe_check_pointer(lnb_ops);
lnb_ops->init = lnbh26_b_init;
lnb_ops->deinit = lnbh26_b_deinit;
lnb_ops->standby = lnbh26_b_standby;
lnb_ops->set_lnb_out = lnbh26_b_set_lnb_out;
lnb_ops->i2c_read_byte = lnb_read_byte;
lnb_ops->i2c_write_byte = lnb_write_byte;
return TD_SUCCESS;
}