/* * 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, ®_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, ®_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; }