mpq8064: Add support for GSBI6 UARTDM for Bluetooth feature
On MPQ8064 Hybrid and DTV variant with ASIC 1.0/1.1, Bluetooth is
connected to MSM externally through GSBI6 UARTDM interface. Hence
add GSBI6 UART device and required resources (its GPIOs, ADM
(Channel/CRCI), clocks ) and its configuration.
CRs-Fixed: 386832
Change-Id: Ib1ba5efe04ed10067ac0e3f7326f4820ef800645
Signed-off-by: Saket Saurabh <ssaurabh@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index b70da23..41eee63 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1395,6 +1395,18 @@
.pull = GPIOMUX_PULL_DOWN,
};
+static struct gpiomux_setting gsbi6_uartdm_active = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi6_uartdm_suspended = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
static struct msm_gpiomux_config apq8064_uartdm_gsbi4_configs[] __initdata = {
{
.gpio = 11, /* GSBI4 UARTDM RX */
@@ -1426,6 +1438,37 @@
},
};
+static struct msm_gpiomux_config mpq8064_uartdm_configs[] __initdata = {
+ { /* UARTDM_TX */
+ .gpio = 14,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &gsbi6_uartdm_active,
+ [GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+ },
+ },
+ { /* UARTDM_RX */
+ .gpio = 15,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &gsbi6_uartdm_active,
+ [GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+ },
+ },
+ { /* UARTDM_CTS */
+ .gpio = 16,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &gsbi6_uartdm_active,
+ [GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+ },
+ },
+ { /* UARTDM_RFR */
+ .gpio = 17,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &gsbi6_uartdm_active,
+ [GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+ },
+ },
+};
+
void __init apq8064_init_gpiomux(void)
{
int rc;
@@ -1548,4 +1591,7 @@
msm_gpiomux_install(apq8064_sdc3_configs,
ARRAY_SIZE(apq8064_sdc3_configs));
+ if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv())
+ msm_gpiomux_install(mpq8064_uartdm_configs,
+ ARRAY_SIZE(mpq8064_uartdm_configs));
}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 1221df3..81f989d 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -69,6 +69,7 @@
#include <linux/msm_tsens.h>
#include <mach/msm_xo.h>
#include <mach/msm_rtb.h>
+#include <mach/msm_serial_hs.h>
#include <sound/cs8427.h>
#include <media/gpio-ir-recv.h>
#include <linux/fmem.h>
@@ -2603,6 +2604,40 @@
}
late_initcall(rf4ce_gpio_init);
+#ifdef CONFIG_SERIAL_MSM_HS
+static int configure_uart_gpios(int on)
+{
+ int ret = 0, i;
+ int uart_gpios[] = {14, 15, 16, 17};
+
+ for (i = 0; i < ARRAY_SIZE(uart_gpios); i++) {
+ if (on) {
+ ret = gpio_request(uart_gpios[i], NULL);
+ if (ret) {
+ pr_err("%s:unable to request uart gpio[%d]\n",
+ __func__, uart_gpios[i]);
+ break;
+ }
+ } else {
+ gpio_free(uart_gpios[i]);
+ }
+ }
+
+ if (ret && on && i)
+ for (; i >= 0; i--)
+ gpio_free(uart_gpios[i]);
+ return ret;
+}
+
+static struct msm_serial_hs_platform_data mpq8064_gsbi6_uartdm_pdata = {
+ .inject_rx_on_wakeup = 1,
+ .rx_to_inject = 0xFD,
+ .gpio_config = configure_uart_gpios,
+};
+#else
+static struct msm_serial_hs_platform_data msm_uart_dm9_pdata;
+#endif
+
static struct platform_device *mpq_devices[] __initdata = {
&msm_device_sps_apq8064,
&mpq8064_device_qup_i2c_gsbi5,
@@ -3375,6 +3410,16 @@
apq8064_init_cam();
#endif
+ if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv()) {
+#ifdef CONFIG_SERIAL_MSM_HS
+ /* GSBI6(2) - UARTDM_RX */
+ mpq8064_gsbi6_uartdm_pdata.wakeup_irq = gpio_to_irq(15);
+ mpq8064_device_uartdm_gsbi6.dev.platform_data =
+ &mpq8064_gsbi6_uartdm_pdata;
+#endif
+ platform_device_register(&mpq8064_device_uartdm_gsbi6);
+ }
+
if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
platform_device_register(&cdp_kp_pdev);
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 0b4e5d9..e891e4e 100755
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5311,7 +5311,7 @@
CLK_LOOKUP("core_clk", gsbi4_uart_clk.c, "msm_serial_hs.1"),
#endif
CLK_LOOKUP("core_clk", gsbi5_uart_clk.c, ""),
- CLK_LOOKUP("core_clk", gsbi6_uart_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi6_uart_clk.c, "msm_serial_hs.0"),
#ifdef CONFIG_MACH_LGE
CLK_LOOKUP("core_clk", gsbi7_uart_clk.c, ""),
#else
@@ -5373,7 +5373,7 @@
CLK_LOOKUP("iface_clk", gsbi4_p_clk.c, "msm_serial_hs.1"),
CLK_LOOKUP("iface_clk", gsbi5_p_clk.c, "spi_qsd.0"),
CLK_LOOKUP("iface_clk", gsbi5_p_clk.c, "qup_i2c.5"),
- CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, "msm_serial_hs.0"),
#ifdef CONFIG_MACH_LGE
CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, ""),
#else
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 936040c..677ad82 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -488,6 +488,50 @@
.resource = resources_qup_i2c_gsbi5,
};
+/* GSBI 6 used into UARTDM Mode */
+static struct resource msm_uart_dm6_resources[] = {
+ {
+ .start = MSM_UART6DM_PHYS,
+ .end = MSM_UART6DM_PHYS + PAGE_SIZE - 1,
+ .name = "uartdm_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = GSBI6_UARTDM_IRQ,
+ .end = GSBI6_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_GSBI6_PHYS,
+ .end = MSM_GSBI6_PHYS + 4 - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN,
+ .end = DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN,
+ .name = "uartdm_channels",
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI,
+ .end = DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI,
+ .name = "uartdm_crci",
+ .flags = IORESOURCE_DMA,
+ },
+};
+static u64 msm_uart_dm6_dma_mask = DMA_BIT_MASK(32);
+struct platform_device mpq8064_device_uartdm_gsbi6 = {
+ .name = "msm_serial_hs",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msm_uart_dm6_resources),
+ .resource = msm_uart_dm6_resources,
+ .dev = {
+ .dma_mask = &msm_uart_dm6_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
static struct resource resources_uart_gsbi7[] = {
{
.start = GSBI7_UARTDM_IRQ,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 54f1300..141a864 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -55,6 +55,7 @@
extern struct platform_device msm_device_uart_dm6;
extern struct platform_device msm_device_uart_dm8;
extern struct platform_device msm_device_uart_dm9;
+extern struct platform_device mpq8064_device_uartdm_gsbi6;
extern struct platform_device msm8960_device_uart_gsbi2;
extern struct platform_device msm8960_device_uart_gsbi5;
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 05a13ba..361dce2 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -279,6 +279,12 @@
#define DMOV_APQ8064_HSUART_GSBI4_RX_CHAN 10
#define DMOV_APQ8064_HSUART_GSBI4_RX_CRCI 7
+/* channels for MPQ8064 */
+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN 7
+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI 6
+
+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN 6
+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI 11
/* no client rate control ifc (eg, ram) */
#define DMOV_NONE_CRCI 0