ASoC: msm: Add I2S support for MDM9x15.
Add changes to enable I2S interface for MDM9x15.
Interface detection between slimbus and I2S is
done at codec init. Driver and functions for that
interface are called during routing. Proper amix
controls for the interface should be used.
Change-Id: I18a8ffab0d2fcdfebf460435eb81e8dacc38e25b
Signed-off-by: Venkat Sudhir <vsudhir@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index 0e18918..3df5000 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -251,6 +251,7 @@
.gpio = 16, /* GSBI5 I2C QUP SCL */
.settings = {
[GPIOMUX_SUSPENDED] = &gsbi5,
+ [GPIOMUX_ACTIVE] = &gsbi5,
},
},
{
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 8328501..0ece37c 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -79,6 +79,10 @@
REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla2x-slim"),
REGULATOR_SUPPLY("VDDD_CDC_D", "tabla-slim"),
REGULATOR_SUPPLY("VDDD_CDC_D", "tabla2x-slim"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "0-000d"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "0-000d"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "tabla top level"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla top level"),
};
VREG_CONSUMERS(S3) = {
REGULATOR_SUPPLY("8018_s3", NULL),
@@ -91,6 +95,14 @@
REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla2x-slim"),
REGULATOR_SUPPLY("VDDIO_CDC", "tabla-slim"),
REGULATOR_SUPPLY("VDDIO_CDC", "tabla2x-slim"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "tabla top level"),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "tabla top level"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla top level"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla top level"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "0-000d"),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "0-000d"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "0-000d"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "0-000d"),
};
VREG_CONSUMERS(S4) = {
REGULATOR_SUPPLY("8018_s4", NULL),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index da9ce67..3b99e6c 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -51,6 +51,7 @@
#include "pm.h"
#include "acpuclock.h"
#include "pm-boot.h"
+#include <mach/gpiomux.h>
#ifdef CONFIG_ION_MSM
#define MSM_ION_AUDIO_SIZE 0xAF000
@@ -295,6 +296,95 @@
#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+/*
+ * MDM9x15 I2S.
+ */
+static struct wcd9xxx_pdata wcd9xxx_i2c_platform_data = {
+ .irq = MSM_GPIO_TO_INT(85),
+ .irq_base = TABLA_INTERRUPT_BASE,
+ .num_irqs = NR_TABLA_IRQS,
+ .reset_gpio = 84,
+ .micbias = {
+ .ldoh_v = TABLA_LDOH_2P85_V,
+ .cfilt1_mv = 1800,
+ .cfilt2_mv = 1800,
+ .cfilt3_mv = 1800,
+ .bias1_cfilt_sel = TABLA_CFILT1_SEL,
+ .bias2_cfilt_sel = TABLA_CFILT2_SEL,
+ .bias3_cfilt_sel = TABLA_CFILT3_SEL,
+ .bias4_cfilt_sel = TABLA_CFILT3_SEL,
+ },
+ .regulator = {
+ {
+ .name = "CDC_VDD_CP",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_RX",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_RX_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_TX",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_TX_CUR_MAX,
+ },
+ {
+ .name = "VDDIO_CDC",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_VDDIO_CDC_CUR_MAX,
+ },
+ {
+ .name = "VDDD_CDC_D",
+ .min_uV = 1225000,
+ .max_uV = 1225000,
+ .optimum_uA = WCD9XXX_VDDD_CDC_D_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_A_1P2V",
+ .min_uV = 1225000,
+ .max_uV = 1225000,
+ .optimum_uA = WCD9XXX_VDDD_CDC_A_CUR_MAX,
+ }
+ },
+};
+
+static struct i2c_board_info wcd9xxx_device_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("tabla top level", TABLA_I2C_SLAVE_ADDR),
+ .platform_data = &wcd9xxx_i2c_platform_data,
+ },
+ {
+ I2C_BOARD_INFO("tabla analog", TABLA_ANALOG_I2C_SLAVE_ADDR),
+ .platform_data = &wcd9xxx_i2c_platform_data,
+ },
+ {
+ I2C_BOARD_INFO("tabla digital1", TABLA_DIGITAL1_I2C_SLAVE_ADDR),
+ .platform_data = &wcd9xxx_i2c_platform_data,
+ },
+ {
+ I2C_BOARD_INFO("tabla digital2", TABLA_DIGITAL2_I2C_SLAVE_ADDR),
+ .platform_data = &wcd9xxx_i2c_platform_data,
+ },
+};
+
+static struct i2c_registry msm9615_i2c_devices[] __initdata = {
+ {
+ I2C_SURF | I2C_FFA | I2C_FLUID,
+ MSM_9615_GSBI5_QUP_I2C_BUS_ID,
+ wcd9xxx_device_info,
+ ARRAY_SIZE(wcd9xxx_device_info),
+ },
+};
+/*
+ * MDM9x15 I2S.
+ */
+
/* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
* 4 micbiases are used to power various analog and digital
* microphones operating at 1800 mV. Technically, all micbiases
@@ -700,6 +790,8 @@
&msm_stub_codec,
&msm_voice,
&msm_voip,
+ &msm_i2s_cpudai0,
+ &msm_i2s_cpudai1,
&msm_pcm_hostless,
&msm_cpudai_afe_01_rx,
&msm_cpudai_afe_01_tx,
@@ -728,8 +820,27 @@
static void __init msm9615_i2c_init(void)
{
+ u8 mach_mask = 0;
+ int i;
+ /* Mask is hardcoded to SURF (CDP).
+ * works on MTP with same configuration.
+ */
+ mach_mask = I2C_SURF;
+ if (machine_is_msm9615_cdp())
+ mach_mask = I2C_SURF;
+ else if (machine_is_msm9615_mtp())
+ mach_mask = I2C_FFA;
+ else
+ pr_err("unmatched machine ID in register_i2c_devices\n");
msm9615_device_qup_i2c_gsbi5.dev.platform_data =
&msm9615_i2c_qup_gsbi5_pdata;
+ for (i = 0; i < ARRAY_SIZE(msm9615_i2c_devices); ++i) {
+ if (msm9615_i2c_devices[i].machs & mach_mask) {
+ i2c_register_board_info(msm9615_i2c_devices[i].bus,
+ msm9615_i2c_devices[i].info,
+ msm9615_i2c_devices[i].len);
+ }
+ }
}
static void __init msm9615_reserve(void)
diff --git a/arch/arm/mach-msm/board-9615.h b/arch/arm/mach-msm/board-9615.h
index 7dd003f..80656b3 100644
--- a/arch/arm/mach-msm/board-9615.h
+++ b/arch/arm/mach-msm/board-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,34 @@
#include <linux/mfd/pm8xxx/pm8018.h>
#include <linux/regulator/gpio-regulator.h>
+/*
+ * MDM9x15 I2S.
+ */
+#ifdef CONFIG_I2C
+#define I2C_SURF 1
+#define I2C_FFA (1 << 1)
+#define I2C_RUMI (1 << 2)
+#define I2C_SIM (1 << 3)
+#define I2C_FLUID (1 << 4)
+#define I2C_LIQUID (1 << 5)
+
+struct i2c_registry {
+ u8 machs;
+ int bus;
+ struct i2c_board_info *info;
+ int len;
+};
+#endif
+/* Tabla slave address for I2C */
+#define TABLA_I2C_SLAVE_ADDR 0x0d
+#define TABLA_ANALOG_I2C_SLAVE_ADDR 0x77
+#define TABLA_DIGITAL1_I2C_SLAVE_ADDR 0x66
+#define TABLA_DIGITAL2_I2C_SLAVE_ADDR 0x55
+#define MSM_9615_GSBI5_QUP_I2C_BUS_ID 0
+/*
+ * MDM9x15 I2S.
+ */
+
/* Macros assume PMIC GPIOs and MPPs start at 1 */
#define PM8018_GPIO_BASE NR_GPIO_IRQS
#define PM8018_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8018_GPIO_BASE)
@@ -36,7 +64,7 @@
#define GPIO_VREG_ID_EXT_2P95V 0
extern struct gpio_regulator_platform_data msm_gpio_regulator_pdata[];
-
+uint32_t msm9615_rpm_get_swfi_latency(void);
int msm9615_init_gpiomux(void);
void msm9615_init_mmc(void);
void mdm9615_allocate_fb_region(void);
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 1fd9b4d..a950e46 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1655,6 +1655,10 @@
"msm-dai-q6.1"),
CLK_LOOKUP("osr_clk", codec_i2s_mic_osr_clk.c,
"msm-dai-q6.1"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.0"),
CLK_LOOKUP("bit_clk", spare_i2s_mic_bit_clk.c,
"msm-dai-q6.5"),
CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index c084d29..8eb1580 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -62,6 +62,9 @@
#define MSM_PMIC1_SSBI_CMD_PHYS 0x00500000
#define MSM_PMIC_SSBI_SIZE SZ_4K
+#define MSM_GPIO_I2C_CLK 16
+#define MSM_GPIO_I2C_SDA 17
+
static struct msm_watchdog_pdata msm_watchdog_pdata = {
.pet_time = 10000,
.bark_time = 11000,
@@ -307,6 +310,19 @@
.end = GSBI5_QUP_IRQ,
.flags = IORESOURCE_IRQ,
},
+ {
+ .name = "i2c_clk",
+ .start = MSM_GPIO_I2C_CLK,
+ .end = MSM_GPIO_I2C_CLK,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "i2c_sda",
+ .start = MSM_GPIO_I2C_SDA,
+ .end = MSM_GPIO_I2C_SDA,
+ .flags = IORESOURCE_IO,
+
+ },
};
struct platform_device msm9615_device_qup_i2c_gsbi5 = {
@@ -472,6 +488,15 @@
.id = -1,
};
+struct platform_device msm_i2s_cpudai0 = {
+ .name = "msm-dai-q6",
+ .id = PRIMARY_I2S_RX,
+};
+
+struct platform_device msm_i2s_cpudai1 = {
+ .name = "msm-dai-q6",
+ .id = PRIMARY_I2S_TX,
+};
struct platform_device msm_voip = {
.name = "msm-voip-dsp",
.id = -1,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 31142c1..8f42ede 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -223,6 +223,8 @@
extern struct platform_device msm_cpudai_incall_music_rx;
extern struct platform_device msm_cpudai_incall_record_rx;
extern struct platform_device msm_cpudai_incall_record_tx;
+extern struct platform_device msm_i2s_cpudai0;
+extern struct platform_device msm_i2s_cpudai1;
extern struct platform_device msm_pil_q6v3;
extern struct platform_device msm_pil_modem;