Add support for returning power sources status

This patch contains changes for returning power sources status
to BT HAL and also setting value of SW CTRL for CHE chip.

Change-Id: I8a0349171a5bbd516b098cc5a070804a454c2b7d
Signed-off-by: priyankar <prigup@codeaurora.org>
This commit is contained in:
priyankar 2020-07-29 18:36:10 +05:30
commit e540b89dd6
2 changed files with 185 additions and 90 deletions

View file

@ -32,27 +32,75 @@
#endif
#include <linux/fs.h>
#define PWR_SRC_NOT_AVAILABLE -2
#define DEFAULT_INVALID_VALUE -1
#define PWR_SRC_INIT_STATE_IDX 0
enum power_src_pos {
BT_RESET_GPIO = PWR_SRC_INIT_STATE_IDX,
BT_SW_CTRL_GPIO,
BT_VDD_AON_LDO,
BT_VDD_DIG_LDO,
BT_VDD_RFA1_LDO,
BT_VDD_RFA2_LDO,
BT_VDD_ASD_LDO,
BT_VDD_XTAL_LDO,
BT_VDD_PA_LDO,
BT_VDD_CORE_LDO,
BT_VDD_IO_LDO,
BT_VDD_LDO,
BT_VDD_RFA_0p8,
BT_VDD_RFACMN,
// these indexes GPIOs/regs value are fetched during crash.
BT_RESET_GPIO_CURRENT,
BT_SW_CTRL_GPIO_CURRENT,
BT_VDD_AON_LDO_CURRENT,
BT_VDD_DIG_LDO_CURRENT,
BT_VDD_RFA1_LDO_CURRENT,
BT_VDD_RFA2_LDO_CURRENT,
BT_VDD_ASD_LDO_CURRENT,
BT_VDD_XTAL_LDO_CURRENT,
BT_VDD_PA_LDO_CURRENT,
BT_VDD_CORE_LDO_CURRENT,
BT_VDD_IO_LDO_CURRENT,
BT_VDD_LDO_CURRENT,
BT_VDD_RFA_0p8_CURRENT,
BT_VDD_RFACMN_CURRENT
};
// Regulator structure for QCA6390 and QCA6490 BT SoC series
static struct bt_power_vreg_data bt_vregs_info_qca6x9x[] = {
{NULL, "qcom,bt-vdd-io", 1800000, 1800000, 0, false, true},
{NULL, "qcom,bt-vdd-aon", 950000, 950000, 0, false, true},
{NULL, "qcom,bt-vdd-rfacmn", 950000, 950000, 0, false, true},
{NULL, "qcom,bt-vdd-io", 1800000, 1800000, 0, false, true,
{BT_VDD_IO_LDO, BT_VDD_IO_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-aon", 950000, 950000, 0, false, true,
{BT_VDD_AON_LDO, BT_VDD_AON_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-rfacmn", 950000, 950000, 0, false, true,
{BT_VDD_RFACMN, BT_VDD_RFACMN_CURRENT}},
/* BT_CX_MX */
{NULL, "qcom,bt-vdd-dig", 950000, 952000, 0, false, true},
{NULL, "qcom,bt-vdd-rfa-0p8", 950000, 952000, 0, false, true},
{NULL, "qcom,bt-vdd-rfa1", 1900000, 1900000, 0, false, true},
{NULL, "qcom,bt-vdd-rfa2", 1900000, 1900000, 0, false, true},
{NULL, "qcom,bt-vdd-asd", 2800000, 2800000, 0, false, true},
{NULL, "qcom,bt-vdd-dig", 950000, 952000, 0, false, true,
{BT_VDD_DIG_LDO, BT_VDD_DIG_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-rfa-0p8", 950000, 952000, 0, false, true,
{BT_VDD_RFA_0p8, BT_VDD_RFA_0p8_CURRENT}},
{NULL, "qcom,bt-vdd-rfa1", 1900000, 1900000, 0, false, true,
{BT_VDD_RFA1_LDO, BT_VDD_RFA1_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-rfa2", 1900000, 1900000, 0, false, true,
{BT_VDD_RFA2_LDO, BT_VDD_RFA2_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-asd", 2800000, 2800000, 0, false, true,
{BT_VDD_ASD_LDO, BT_VDD_ASD_LDO_CURRENT}},
};
// Regulator structure for WCN399x BT SoC series
static struct bt_power bt_vreg_info_wcn399x = {
.compatible = "qcom,wcn3990",
.vregs = (struct bt_power_vreg_data []) {
{NULL, "qcom,bt-vdd-io", 1700000, 1900000, 0, false, false},
{NULL, "qcom,bt-vdd-core", 1304000, 1304000, 0, false, false},
{NULL, "qcom,bt-vdd-pa", 3000000, 3312000, 0, false, false},
{NULL, "qcom,bt-vdd-xtal", 1700000, 1900000, 0, false, false},
{NULL, "qcom,bt-vdd-io", 1700000, 1900000, 0, false, false,
{BT_VDD_IO_LDO, BT_VDD_IO_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-core", 1304000, 1304000, 0, false, false,
{BT_VDD_CORE_LDO, BT_VDD_CORE_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-pa", 3000000, 3312000, 0, false, false,
{BT_VDD_PA_LDO, BT_VDD_PA_LDO_CURRENT}},
{NULL, "qcom,bt-vdd-xtal", 1700000, 1900000, 0, false, false,
{BT_VDD_XTAL_LDO, BT_VDD_XTAL_LDO_CURRENT}},
},
.num_vregs = 4,
};
@ -83,6 +131,7 @@ static int btpower_get_tcs_table_info(struct platform_device *plat_dev,
static int btpower_enable_ipa_vreg(struct platform_device *plat_dev,
struct bluetooth_power_platform_data *bt_power_pdata);
static int bt_power_src_status[BT_POWER_SRC_SIZE];
static struct bluetooth_power_platform_data *bt_power_pdata;
static struct platform_device *btpdev;
static bool previous;
@ -265,14 +314,18 @@ static int bt_configure_gpios(int on)
pr_err("%s: Unable to set direction\n", __func__);
return rc;
}
bt_power_src_status[BT_RESET_GPIO] =
gpio_get_value(bt_reset_gpio);
msleep(50);
pr_debug("BTON:Turn Bt Off bt-reset-gpio(%d) value(%d)\n",
pr_info("BTON:Turn Bt Off bt-reset-gpio(%d) value(%d)\n",
bt_reset_gpio, gpio_get_value(bt_reset_gpio));
if (bt_sw_ctrl_gpio >= 0) {
pr_debug("BTON:Turn Bt Off\n");
pr_debug("bt-sw-ctrl-gpio(%d) value(%d)\n",
pr_info("BTON:Turn Bt Off\n");
bt_power_src_status[BT_SW_CTRL_GPIO] =
gpio_get_value(bt_sw_ctrl_gpio);
pr_info("bt-sw-ctrl-gpio(%d) value(%d)\n",
bt_sw_ctrl_gpio,
gpio_get_value(bt_sw_ctrl_gpio));
bt_power_src_status[BT_SW_CTRL_GPIO]);
}
rc = gpio_direction_output(bt_reset_gpio, 1);
@ -280,6 +333,8 @@ static int bt_configure_gpios(int on)
pr_err("%s: Unable to set direction\n", __func__);
return rc;
}
bt_power_src_status[BT_RESET_GPIO] =
gpio_get_value(bt_reset_gpio);
msleep(50);
/* Check if SW_CTRL is asserted */
if (bt_sw_ctrl_gpio >= 0) {
@ -307,24 +362,26 @@ static int bt_configure_gpios(int on)
pr_info("BTON:Turn Bt On bt-reset-gpio(%d) value(%d)\n",
bt_reset_gpio, gpio_get_value(bt_reset_gpio));
if (bt_sw_ctrl_gpio >= 0) {
pr_debug("BTON:Turn Bt On\n");
pr_debug("bt-sw-ctrl-gpio(%d) value(%d)\n",
pr_info("BTON:Turn Bt On\n");
bt_power_src_status[BT_SW_CTRL_GPIO] =
gpio_get_value(bt_sw_ctrl_gpio);
pr_info("bt-sw-ctrl-gpio(%d) value(%d)\n",
bt_sw_ctrl_gpio,
gpio_get_value(bt_sw_ctrl_gpio));
bt_power_src_status[BT_SW_CTRL_GPIO]);
}
} else {
gpio_set_value(bt_reset_gpio, 0);
msleep(100);
pr_debug("BT-OFF:bt-reset-gpio(%d) value(%d)\n",
pr_info("BT-OFF:bt-reset-gpio(%d) value(%d)\n",
bt_reset_gpio, gpio_get_value(bt_reset_gpio));
if (bt_sw_ctrl_gpio >= 0) {
pr_debug("BT-OFF:bt-sw-ctrl-gpio(%d) value(%d)\n",
pr_info("BT-OFF:bt-sw-ctrl-gpio(%d) value(%d)\n",
bt_sw_ctrl_gpio,
gpio_get_value(bt_sw_ctrl_gpio));
}
}
pr_debug("%s: bt_gpio= %d on: %d\n", __func__, bt_reset_gpio, on);
pr_info("%s: bt_gpio= %d on: %d\n", __func__, bt_reset_gpio, on);
return rc;
}
@ -354,6 +411,10 @@ static int bluetooth_power(int on)
}
}
if (bt_power_pdata->bt_gpio_sys_rst > 0) {
bt_power_src_status[BT_RESET_GPIO] =
DEFAULT_INVALID_VALUE;
bt_power_src_status[BT_SW_CTRL_GPIO] =
DEFAULT_INVALID_VALUE;
rc = bt_configure_gpios(on);
if (rc < 0) {
pr_err("%s: bt_power gpio config failed\n",
@ -585,16 +646,25 @@ static int bt_power_vreg_get(struct platform_device *pdev)
static int bt_power_vreg_set(enum bt_power_modes mode)
{
int num_vregs, i = 0, ret = 0;
int log_indx;
struct bt_power_vreg_data *vreg_info = NULL;
num_vregs = bt_power_pdata->num_vregs;
if (mode == BT_POWER_ENABLE) {
for (; i < num_vregs; i++) {
vreg_info = &bt_power_pdata->vreg_info[i];
log_indx = vreg_info->indx.init;
if (vreg_info->reg) {
bt_power_src_status[log_indx] =
DEFAULT_INVALID_VALUE;
ret = bt_vreg_enable(vreg_info);
if (ret < 0)
goto out;
if (vreg_info->is_enabled) {
bt_power_src_status[log_indx] =
regulator_get_voltage(
vreg_info->reg);
}
}
}
} else if (mode == BT_POWER_DISABLE) {
@ -677,9 +747,17 @@ static int bt_power_populate_dt_pinfo(struct platform_device *pdev)
static int bt_power_probe(struct platform_device *pdev)
{
int ret = 0;
int itr;
pr_debug("%s\n", __func__);
/* Fill whole array with -2 i.e NOT_AVAILABLE state by default
* for any GPIO or Reg handle.
*/
for (itr = PWR_SRC_INIT_STATE_IDX;
itr < BT_POWER_SRC_SIZE; ++itr)
bt_power_src_status[itr] = PWR_SRC_NOT_AVAILABLE;
bt_power_pdata = kzalloc(sizeof(*bt_power_pdata), GFP_KERNEL);
if (!bt_power_pdata)
@ -754,46 +832,51 @@ int btpower_get_chipset_version(void)
}
EXPORT_SYMBOL(btpower_get_chipset_version);
static long get_resource_value(char *res_name)
static void set_pwr_srcs_status(struct bt_power_vreg_data *handle)
{
int ret = 0;
int i = 0;
long value = -1;
struct bt_power_vreg_data *vreg;
int num_vregs = bt_power_pdata->num_vregs;
int ldo_index;
for (; i < num_vregs; i++) {
vreg = &bt_power_pdata->vreg_info[i];
if (!vreg->reg)
continue;
else {
if (strnstr(vreg->name, res_name,
strlen(vreg->name)))
break;
}
}
if (i < num_vregs) {
if (regulator_is_enabled(vreg->reg)) {
value = (int)regulator_get_voltage(vreg->reg);
pr_debug("%s:%s value(%d)\n",
__func__, res_name, value);
ret = value;
if (handle) {
ldo_index = handle->indx.crash;
bt_power_src_status[ldo_index] =
DEFAULT_INVALID_VALUE;
if (handle->is_enabled &&
(regulator_is_enabled(handle->reg))) {
bt_power_src_status[ldo_index] =
(int)regulator_get_voltage(handle->reg);
pr_err("%s(%d) value(%d)\n", handle->name,
handle, bt_power_src_status[ldo_index]);
} else {
pr_err("%s:%s not configure/enabled\n",
__func__, res_name);
ret = -EINVAL;
pr_err("%s:%s is_enabled: %d\n",
__func__, handle->name,
handle->is_enabled);
}
}
}
return ret;
static void set_gpios_srcs_status(char *gpio_name,
int gpio_index, int handle)
{
if (handle >= 0) {
bt_power_src_status[gpio_index] =
DEFAULT_INVALID_VALUE;
bt_power_src_status[gpio_index] =
gpio_get_value(handle);
pr_err("%s(%d) value(%d)\n", gpio_name,
handle, bt_power_src_status[gpio_index]);
} else {
pr_err("%s: %s not configured\n",
__func__, gpio_name);
}
}
static long bt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret = 0, pwr_cntrl = 0;
int chipset_version = 0;
long value = -1;
int itr, num_vregs;
struct bt_power_vreg_data *vreg_info = NULL;
switch (cmd) {
case BT_CMD_SLIM_TEST:
#if (defined CONFIG_BT_SLIM_QCA6390 || \
@ -840,43 +923,49 @@ static long bt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = -EFAULT;
}
break;
case BT_CMD_GETVAL_RESET_GPIO:
if (bt_power_pdata->bt_gpio_sys_rst > 0) {
value = (long)gpio_get_value(
bt_power_pdata->bt_gpio_sys_rst);
pr_debug("%s:GET_RESET_GPIO(%d) value(%d)\n",
bt_power_pdata->bt_gpio_sys_rst,
__func__, value);
ret = value;
} else {
pr_err("%s: RESET_GPIO not configured\n", __func__);
ret = -EINVAL;
}
break;
case BT_CMD_GETVAL_SW_CTRL_GPIO:
case BT_CMD_CHECK_SW_CTRL:
/* Check if SW_CTRL is asserted */
pr_info("BT_CMD_CHECK_SW_CTRL\n");
if (bt_power_pdata->bt_gpio_sw_ctrl > 0) {
value = (long)gpio_get_value(
bt_power_src_status[BT_SW_CTRL_GPIO] =
DEFAULT_INVALID_VALUE;
ret = gpio_direction_input(
bt_power_pdata->bt_gpio_sw_ctrl);
pr_debug("%s:GET_SWCTRL_GPIO(%d) value(%d)\n",
bt_power_pdata->bt_gpio_sw_ctrl,
__func__, value);
ret = value;
if (ret) {
pr_err("%s:gpio_direction_input api\n",
__func__);
pr_err("%s:failed for SW_CTRL:%d\n",
__func__, ret);
} else {
bt_power_src_status[BT_SW_CTRL_GPIO] =
gpio_get_value(
bt_power_pdata->bt_gpio_sw_ctrl);
pr_info("bt-sw-ctrl-gpio(%d) value(%d)\n",
bt_power_pdata->bt_gpio_sw_ctrl,
bt_power_src_status[BT_SW_CTRL_GPIO]);
}
} else {
pr_err("%s:SW_CTRL_GPIO not configured\n", __func__);
ret = -EINVAL;
pr_err("bt_gpio_sw_ctrl not configured\n");
return -EINVAL;
}
break;
case BT_CMD_GETVAL_VDD_AON_LDO:
ret = get_resource_value("vdd-aon");
break;
case BT_CMD_GETVAL_VDD_DIG_LDO:
ret = get_resource_value("vdd-dig");
break;
case BT_CMD_GETVAL_VDD_RFA1_LDO:
ret = get_resource_value("vdd-rfa1");
break;
case BT_CMD_GETVAL_VDD_RFA2_LDO:
ret = get_resource_value("vdd-rfa2");
case BT_CMD_GETVAL_POWER_SRCS:
pr_err("BT_CMD_GETVAL_POWER_SRCS\n");
set_gpios_srcs_status("BT_RESET_GPIO", BT_RESET_GPIO_CURRENT,
bt_power_pdata->bt_gpio_sys_rst);
set_gpios_srcs_status("SW_CTRL_GPIO", BT_SW_CTRL_GPIO_CURRENT,
bt_power_pdata->bt_gpio_sw_ctrl);
num_vregs = bt_power_pdata->num_vregs;
for (itr = 0; itr < num_vregs; itr++) {
vreg_info = &bt_power_pdata->vreg_info[itr];
set_pwr_srcs_status(vreg_info);
}
if (copy_to_user((void __user *)arg,
bt_power_src_status, sizeof(bt_power_src_status))) {
pr_err("%s: copy to user failed\n", __func__);
ret = -EFAULT;
}
break;
case BT_CMD_SET_IPA_TCS_INFO:
pr_err("%s: BT_CMD_SET_IPA_TCS_INFO\n", __func__);

View file

@ -18,6 +18,11 @@ enum bt_power_modes {
BT_POWER_RETENTION
};
struct log_index {
int init;
int crash;
};
struct bt_power_vreg_data {
struct regulator *reg; /* voltage regulator handle */
const char *name; /* regulator name */
@ -26,6 +31,7 @@ struct bt_power_vreg_data {
u32 load_curr; /* current */
bool is_enabled; /* is this regulator enabled? */
bool is_retention_supp; /* does this regulator support retention mode */
struct log_index indx; /* Index for reg. w.r.t init & crash */
};
struct bt_power {
@ -66,14 +72,14 @@ int btpower_get_chipset_version(void);
#define BT_CMD_SLIM_TEST 0xbfac
#define BT_CMD_PWR_CTRL 0xbfad
#define BT_CMD_CHIPSET_VERS 0xbfae
#define BT_CMD_GET_CHIPSET_ID 0xbfaf
#define BT_CMD_GETVAL_RESET_GPIO 0xbfb5
#define BT_CMD_GETVAL_SW_CTRL_GPIO 0xbfb0
#define BT_CMD_GETVAL_VDD_AON_LDO 0xbfb1
#define BT_CMD_GETVAL_VDD_DIG_LDO 0xbfb2
#define BT_CMD_GETVAL_VDD_RFA1_LDO 0xbfb3
#define BT_CMD_GETVAL_VDD_RFA2_LDO 0xbfb4
#define BT_CMD_GET_CHIPSET_ID 0xbfaf
#define BT_CMD_CHECK_SW_CTRL 0xbfb0
#define BT_CMD_GETVAL_POWER_SRCS 0xbfb1
#define BT_CMD_SET_IPA_TCS_INFO 0xbfc0
#define TCS_CMD_IO_ADDR_OFFSET 0x4
/* total number of power src */
#define BT_POWER_SRC_SIZE 28
#endif /* __LINUX_BLUETOOTH_POWER_H */