board: msm7x27a: Put BT GPIO in LPM when not in use.
Bahama's SYS RESET GPIO from the i/o expander is put in low
power mode when not in use, for power optimization.
CRs-Fixed: 294153
CRs-Fixed: 295572
Signed-off-by: Rahul Kashyap <rkashyap@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 6f2249b..b727475 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -56,6 +56,7 @@
#define MSM_PMEM_AUDIO_SIZE 0x5B000
#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
+#define BAHAMA_SLAVE_ID_FM_REG 0x02
#define FM_GPIO 83
enum {
@@ -299,12 +300,35 @@
return rc;
}
+static int bt_set_gpio(int on)
+{
+ int rc = 0;
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+
+ if (on) {
+ rc = gpio_direction_output(GPIO_BT_SYS_REST_EN, 1);
+ msleep(100);
+ } else {
+ if (!marimba_get_fm_status(&config) &&
+ !marimba_get_bt_status(&config)) {
+ gpio_set_value_cansleep(GPIO_BT_SYS_REST_EN, 0);
+ rc = gpio_direction_input(GPIO_BT_SYS_REST_EN);
+ msleep(100);
+ }
+ }
+ if (rc)
+ pr_err("%s: BT sys_reset_en GPIO : Error", __func__);
+
+ return rc;
+}
static struct vreg *fm_regulator;
static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
{
int rc = 0;
const char *id = "FMPW";
uint32_t irqcfg;
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
+ u8 value;
/* Voting for 1.8V Regulator */
fm_regulator = vreg_get(NULL , "msme1");
@@ -339,6 +363,19 @@
goto fm_clock_vote_fail;
}
+ rc = bt_set_gpio(1);
+ if (rc) {
+ pr_err("%s: bt_set_gpio = %d", __func__, rc);
+ goto fm_gpio_config_fail;
+ }
+ /*re-write FM Slave Id, after reset*/
+ value = BAHAMA_SLAVE_ID_FM_ADDR;
+ rc = marimba_write_bit_mask(&config,
+ BAHAMA_SLAVE_ID_FM_REG, &value, 1, 0xFF);
+ if (rc < 0) {
+ pr_err("%s: FM Slave ID rewrite Failed = %d", __func__, rc);
+ goto fm_gpio_config_fail;
+ }
/* Configuring the FM GPIO */
irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA);
@@ -355,6 +392,7 @@
fm_gpio_config_fail:
pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
PMAPP_CLOCK_VOTE_OFF);
+ bt_set_gpio(0);
fm_clock_vote_fail:
vreg_disable(fm_regulator);
@@ -391,10 +429,12 @@
/* Voting off the clock */
rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
PMAPP_CLOCK_VOTE_OFF);
-
if (rc < 0)
pr_err("%s: voting off failed with :(%d)\n",
__func__, rc);
+ rc = bt_set_gpio(0);
+ if (rc)
+ pr_err("%s: bt_set_gpio = %d", __func__, rc);
}
static struct marimba_fm_platform_data marimba_fm_pdata = {
@@ -645,9 +685,9 @@
GPIO_BT_SYS_REST_EN, rc);
goto vreg_fail;
}
- rc = gpio_direction_output(GPIO_BT_SYS_REST_EN, 1);
+ rc = bt_set_gpio(1);
if (rc < 0) {
- pr_err("%s: gpio_direction_output %d = %d\n", __func__,
+ pr_err("%s: bt_set_gpio %d = %d\n", __func__,
GPIO_BT_SYS_REST_EN, rc);
goto gpio_fail;
}
@@ -678,18 +718,21 @@
vreg_put(vreg_s3);
return rc;
}
-
+ rc = bt_set_gpio(0);
+ if (rc) {
+ pr_err("%s: bt_set_gpio = %d\n",
+ __func__, rc);
+ }
return rc;
}
-
static unsigned int msm_bahama_core_config(int type)
{
int rc = 0;
if (type == BAHAMA_ID) {
int i;
- struct marimba config = { .mod_id = SLAVE_ID_BAHAMA };
+ struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
const struct bahama_config_register v20_init[] = {
/* reg, value, mask */
{ 0xF4, 0x84, 0xFF }, /* AREG */
@@ -715,6 +758,11 @@
}
}
}
+ rc = bt_set_gpio(0);
+ if (rc) {
+ pr_err("%s: bt_set_gpio = %d\n",
+ __func__, rc);
+ }
pr_debug("core type: %d\n", type);
return rc;
}
@@ -733,6 +781,12 @@
}
if (on) {
/*setup power for BT SOC*/
+ rc = bt_set_gpio(on);
+ if (rc) {
+ pr_err("%s: bt_set_gpio = %d\n",
+ __func__, rc);
+ goto exit;
+ }
rc = bluetooth_switch_regulators(on);
if (rc < 0) {
pr_err("%s: bluetooth_switch_regulators rc = %d",
@@ -786,6 +840,12 @@
rc = bahama_bt(0);
if (rc < 0)
pr_err("%s: bahama_bt rc = %d", __func__, rc);
+
+ rc = bt_set_gpio(on);
+ if (rc) {
+ pr_err("%s: bt_set_gpio = %d\n",
+ __func__, rc);
+ }
fail_i2c:
rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
PMAPP_CLOCK_VOTE_OFF);