mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
Merge "Add support for returning power sources status"
This commit is contained in:
commit
139febc37f
2 changed files with 274 additions and 89 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <linux/btpower.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <soc/qcom/cmd-db.h>
|
||||
|
||||
#if defined CONFIG_BT_SLIM_QCA6390 || \
|
||||
defined CONFIG_BT_SLIM_QCA6490 || \
|
||||
|
|
@ -31,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,
|
||||
};
|
||||
|
|
@ -77,7 +126,12 @@ static const struct of_device_id bt_power_match_table[] = {
|
|||
};
|
||||
|
||||
static int bt_power_vreg_set(enum bt_power_modes mode);
|
||||
static int btpower_get_tcs_table_info(struct platform_device *plat_dev,
|
||||
struct bluetooth_power_platform_data *bt_power_pdata);
|
||||
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;
|
||||
|
|
@ -260,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);
|
||||
|
|
@ -275,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) {
|
||||
|
|
@ -302,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;
|
||||
}
|
||||
|
|
@ -349,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",
|
||||
|
|
@ -580,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) {
|
||||
|
|
@ -672,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)
|
||||
|
|
@ -708,6 +791,8 @@ static int bt_power_probe(struct platform_device *pdev)
|
|||
goto free_pdata;
|
||||
|
||||
btpdev = pdev;
|
||||
if (btpower_get_tcs_table_info(pdev, bt_power_pdata) < 0)
|
||||
pr_err("%s: Failed to get TCS table info\n", __func__);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -747,46 +832,50 @@ 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:
|
||||
|
|
@ -834,43 +923,53 @@ 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");
|
||||
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_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_SET_IPA_TCS_INFO:
|
||||
pr_err("%s: BT_CMD_SET_IPA_TCS_INFO\n", __func__);
|
||||
btpower_enable_ipa_vreg(btpdev, bt_power_pdata);
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
|
|
@ -935,6 +1034,78 @@ driver_err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int btpower_get_tcs_table_info(struct platform_device *dev,
|
||||
struct bluetooth_power_platform_data *bt_power_pdata)
|
||||
{
|
||||
struct platform_device *plat_dev = dev;
|
||||
struct btpower_tcs_table_info *tcs_table_info =
|
||||
&bt_power_pdata->tcs_table_info;
|
||||
struct resource *res;
|
||||
resource_size_t addr_len;
|
||||
void __iomem *tcs_cmd_base_addr;
|
||||
int ret = -1;
|
||||
|
||||
res = platform_get_resource_byname(plat_dev, IORESOURCE_MEM, "tcs_cmd");
|
||||
if (!res) {
|
||||
pr_err("No TCS CMD entry found in DTSI\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
tcs_table_info->tcs_cmd_base_addr = res->start;
|
||||
addr_len = resource_size(res);
|
||||
pr_info("TCS CMD base address is %pa with length %pa\n",
|
||||
&tcs_table_info->tcs_cmd_base_addr, &addr_len);
|
||||
|
||||
tcs_cmd_base_addr = devm_ioremap_resource(&plat_dev->dev, res);
|
||||
if (IS_ERR(tcs_cmd_base_addr)) {
|
||||
ret = PTR_ERR(tcs_cmd_base_addr);
|
||||
pr_err("Failed to map TCS CMD address, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
tcs_table_info->tcs_cmd_base_addr_io = tcs_cmd_base_addr;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btpower_enable_ipa_vreg(struct platform_device *dev,
|
||||
struct bluetooth_power_platform_data *bt_power_pdata)
|
||||
{
|
||||
struct platform_device *plat_dev = dev;
|
||||
struct btpower_tcs_table_info *tcs_table_info =
|
||||
&bt_power_pdata->tcs_table_info;
|
||||
u32 offset, addr_val, data_val;
|
||||
void __iomem *tcs_cmd;
|
||||
int ret = 0;
|
||||
|
||||
if (!tcs_table_info->tcs_cmd_base_addr_io) {
|
||||
pr_err("TCS command not configured\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(plat_dev->dev.of_node,
|
||||
"qcom,tcs_offset_ipa",
|
||||
&offset);
|
||||
if (ret) {
|
||||
pr_err("iPA failed to configure\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tcs_cmd = tcs_table_info->tcs_cmd_base_addr_io + offset;
|
||||
addr_val = readl_relaxed(tcs_cmd);
|
||||
tcs_cmd += TCS_CMD_IO_ADDR_OFFSET;
|
||||
|
||||
writel_relaxed(1, tcs_cmd);
|
||||
|
||||
data_val = readl_relaxed(tcs_cmd);
|
||||
pr_info("Configure S3E TCS Addr : %x with Data: %d\n"
|
||||
, addr_val, data_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit bluetooth_power_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bt_power_driver);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -40,6 +46,10 @@ struct bt_power_clk_data {
|
|||
bool is_enabled; /* is this clock enabled? */
|
||||
};
|
||||
|
||||
struct btpower_tcs_table_info {
|
||||
resource_size_t tcs_cmd_base_addr;
|
||||
void __iomem *tcs_cmd_base_addr_io;
|
||||
};
|
||||
/*
|
||||
* Platform data for the bluetooth power driver.
|
||||
*/
|
||||
|
|
@ -53,6 +63,7 @@ struct bluetooth_power_platform_data {
|
|||
int (*bt_power_setup)(int id); /* Bluetooth power setup function */
|
||||
char compatible[32]; /*Bluetooth SoC name */
|
||||
int num_vregs;
|
||||
struct btpower_tcs_table_info tcs_table_info;
|
||||
};
|
||||
|
||||
int btpower_register_slimdev(struct device *dev);
|
||||
|
|
@ -61,11 +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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue