ASoC: wcd9xxx: Move to a generic framework for codec core driver.
The current core assumes TABLA as the only codec driver registering.
To support single binary for multiple targets its essential that
we remove this restriction and move to a generic framework
to support multiple codec. This can be done by moving all codec
specific code to dedicated codec driver and use core driver to probe
the codec based on slimbus device id and do generic setup for the
codec. This also helps to have same boards with different flavours
of codec variants.
The WCD9XXX family of codecs share the initial codec register
mapping which holds the Slimbus device id to identify the
codec existing on the target.Core driver now registers the
codec device based on this check.
Change-Id: I4c43d5f04c20696f4f5138411460681ec7879d34
Signed-off-by: Asish Bhattacharya <asishb@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 2f94a2e..3848262 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -16,8 +16,8 @@
#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/slimbus/slimbus.h>
-#include <linux/mfd/wcd9310/core.h>
-#include <linux/mfd/wcd9310/pdata.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
#include <linux/mfd/pm8xxx/misc.h>
#include <linux/msm_ssbi.h>
#include <linux/spi/spi.h>
@@ -499,14 +499,14 @@
* does not need to be as high as 2.85V. It is choosen for
* microphone sensitivity purpose.
*/
-static struct tabla_pdata apq8064_tabla_platform_data = {
+static struct wcd9xxx_pdata apq8064_tabla_platform_data = {
.slimbus_slave_device = {
.name = "tabla-slave",
.e_addr = {0, 0, 0x10, 0, 0x17, 2},
},
.irq = MSM_GPIO_TO_INT(42),
.irq_base = TABLA_INTERRUPT_BASE,
- .num_irqs = NR_TABLA_IRQS,
+ .num_irqs = NR_WCD9XXX_IRQS,
.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
.micbias = {
.ldoh_v = TABLA_LDOH_2P85_V,
@@ -517,7 +517,45 @@
.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 slim_device apq8064_slim_tabla = {
@@ -528,14 +566,14 @@
},
};
-static struct tabla_pdata apq8064_tabla20_platform_data = {
+static struct wcd9xxx_pdata apq8064_tabla20_platform_data = {
.slimbus_slave_device = {
.name = "tabla-slave",
.e_addr = {0, 0, 0x60, 0, 0x17, 2},
},
.irq = MSM_GPIO_TO_INT(42),
.irq_base = TABLA_INTERRUPT_BASE,
- .num_irqs = NR_TABLA_IRQS,
+ .num_irqs = NR_WCD9XXX_IRQS,
.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
.micbias = {
.ldoh_v = TABLA_LDOH_2P85_V,
@@ -546,7 +584,45 @@
.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 slim_device apq8064_slim_tabla20 = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index ad71007..32cdd7c 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -70,8 +70,8 @@
#ifdef CONFIG_WCD9310_CODEC
#include <linux/slimbus/slimbus.h>
-#include <linux/mfd/wcd9310/core.h>
-#include <linux/mfd/wcd9310/pdata.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
#endif
#include <linux/ion.h>
@@ -531,14 +531,14 @@
* does not need to be as high as 2.85V. It is choosen for
* microphone sensitivity purpose.
*/
-static struct tabla_pdata tabla_platform_data = {
+static struct wcd9xxx_pdata tabla_platform_data = {
.slimbus_slave_device = {
.name = "tabla-slave",
.e_addr = {0, 0, 0x10, 0, 0x17, 2},
},
.irq = MSM_GPIO_TO_INT(62),
.irq_base = TABLA_INTERRUPT_BASE,
- .num_irqs = NR_TABLA_IRQS,
+ .num_irqs = NR_WCD9XXX_IRQS,
/*TODO: Replace this with right PM8038 gpio */
#ifndef MSM8930_PHASE_2
@@ -564,14 +564,14 @@
},
};
-static struct tabla_pdata tabla20_platform_data = {
+static struct wcd9xxx_pdata tabla20_platform_data = {
.slimbus_slave_device = {
.name = "tabla-slave",
.e_addr = {0, 0, 0x60, 0, 0x17, 2},
},
.irq = MSM_GPIO_TO_INT(62),
.irq_base = TABLA_INTERRUPT_BASE,
- .num_irqs = NR_TABLA_IRQS,
+ .num_irqs = NR_WCD9XXX_IRQS,
/*TODO: Replace this with right PM8038 gpio */
#ifndef MSM8930_PHASE_2
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 2402d43..7fd6820 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -70,9 +70,8 @@
#include <mach/restart.h>
#ifdef CONFIG_WCD9310_CODEC
-#include <linux/slimbus/slimbus.h>
-#include <linux/mfd/wcd9310/core.h>
-#include <linux/mfd/wcd9310/pdata.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
#endif
#include <linux/ion.h>
@@ -664,14 +663,14 @@
* does not need to be as high as 2.85V. It is choosen for
* microphone sensitivity purpose.
*/
-static struct tabla_pdata tabla_platform_data = {
+static struct wcd9xxx_pdata tabla_platform_data = {
.slimbus_slave_device = {
.name = "tabla-slave",
.e_addr = {0, 0, 0x10, 0, 0x17, 2},
},
.irq = MSM_GPIO_TO_INT(62),
.irq_base = TABLA_INTERRUPT_BASE,
- .num_irqs = NR_TABLA_IRQS,
+ .num_irqs = NR_WCD9XXX_IRQS,
.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
.micbias = {
.ldoh_v = TABLA_LDOH_2P85_V,
@@ -682,7 +681,45 @@
.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 slim_device msm_slim_tabla = {
@@ -693,14 +730,14 @@
},
};
-static struct tabla_pdata tabla20_platform_data = {
+static struct wcd9xxx_pdata tabla20_platform_data = {
.slimbus_slave_device = {
.name = "tabla-slave",
.e_addr = {0, 0, 0x60, 0, 0x17, 2},
},
.irq = MSM_GPIO_TO_INT(62),
.irq_base = TABLA_INTERRUPT_BASE,
- .num_irqs = NR_TABLA_IRQS,
+ .num_irqs = NR_WCD9XXX_IRQS,
.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
.micbias = {
.ldoh_v = TABLA_LDOH_2P85_V,
@@ -711,7 +748,45 @@
.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 slim_device msm_slim_tabla20 = {
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 954b673..1ae7454 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -42,10 +42,11 @@
#define NR_GPIO_IRQS 152
#define NR_PM8921_IRQS 256
#define NR_PM8821_IRQS 64
-#define NR_TABLA_IRQS 49
+#define NR_WCD9XXX_IRQS 49
+#define NR_TABLA_IRQS NR_WCD9XXX_IRQS
#define NR_GPIO_EXPANDER_IRQS 8
#define NR_BOARD_IRQS (NR_PM8921_IRQS + NR_PM8821_IRQS + \
- NR_TABLA_IRQS + NR_GPIO_EXPANDER_IRQS)
+ NR_WCD9XXX_IRQS + NR_GPIO_EXPANDER_IRQS)
#define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
#define NR_MSM_GPIOS NR_GPIO_IRQS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c8fcf5f..394236a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,7 +69,7 @@
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
-obj-$(CONFIG_WCD9310_CODEC) += wcd9310-core.o wcd9310-irq.o wcd9310-slimslave.o
+obj-$(CONFIG_WCD9310_CODEC) += wcd9xxx-core.o wcd9xxx-irq.o wcd9xxx-slimslave.o
ifeq ($(CONFIG_SA1100_ASSABET),y)
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
diff --git a/drivers/mfd/wcd9310-core.c b/drivers/mfd/wcd9310-core.c
deleted file mode 100644
index d1d9132..0000000
--- a/drivers/mfd/wcd9310-core.c
+++ /dev/null
@@ -1,1151 +0,0 @@
-/* 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
-#include <linux/mfd/wcd9310/pdata.h>
-#include <linux/mfd/wcd9310/registers.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/debugfs.h>
-#include <linux/regulator/consumer.h>
-#include <linux/i2c.h>
-#include <sound/soc.h>
-
-#define TABLA_SLIM_GLA_MAX_RETRIES 5
-#define TABLA_REGISTER_START_OFFSET 0x800
-#define TABLA_SLIM_RW_MAX_TRIES 3
-
-#define MAX_TABLA_DEVICE 4
-#define TABLA_I2C_MODE 0x03
-
-struct tabla_i2c {
- struct i2c_client *client;
- struct i2c_msg xfer_msg[2];
- struct mutex xfer_lock;
- int mod_id;
-};
-
-struct tabla_i2c tabla_modules[MAX_TABLA_DEVICE];
-static int tabla_intf;
-
-static int tabla_read(struct tabla *tabla, unsigned short reg,
- int bytes, void *dest, bool interface_reg)
-{
- int ret;
- u8 *buf = dest;
-
- if (bytes <= 0) {
- dev_err(tabla->dev, "Invalid byte read length %d\n", bytes);
- return -EINVAL;
- }
-
- ret = tabla->read_dev(tabla, reg, bytes, dest, interface_reg);
- if (ret < 0) {
- dev_err(tabla->dev, "Tabla read failed\n");
- return ret;
- } else
- dev_dbg(tabla->dev, "Read 0x%02x from R%d(0x%x)\n",
- *buf, reg, reg);
-
- return 0;
-}
-int tabla_reg_read(struct tabla *tabla, unsigned short reg)
-{
- u8 val;
- int ret;
-
- mutex_lock(&tabla->io_lock);
- ret = tabla_read(tabla, reg, 1, &val, false);
- mutex_unlock(&tabla->io_lock);
-
- if (ret < 0)
- return ret;
- else
- return val;
-}
-EXPORT_SYMBOL_GPL(tabla_reg_read);
-
-static int tabla_write(struct tabla *tabla, unsigned short reg,
- int bytes, void *src, bool interface_reg)
-{
- u8 *buf = src;
-
- if (bytes <= 0) {
- pr_err("%s: Error, invalid write length\n", __func__);
- return -EINVAL;
- }
-
- dev_dbg(tabla->dev, "Write %02x to R%d(0x%x)\n",
- *buf, reg, reg);
-
- return tabla->write_dev(tabla, reg, bytes, src, interface_reg);
-}
-
-int tabla_reg_write(struct tabla *tabla, unsigned short reg,
- u8 val)
-{
- int ret;
-
- mutex_lock(&tabla->io_lock);
- ret = tabla_write(tabla, reg, 1, &val, false);
- mutex_unlock(&tabla->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tabla_reg_write);
-
-static u8 tabla_pgd_la;
-static u8 tabla_inf_la;
-
-int tabla_get_logical_addresses(u8 *pgd_la, u8 *inf_la)
-{
- *pgd_la = tabla_pgd_la;
- *inf_la = tabla_inf_la;
- return 0;
-
-}
-EXPORT_SYMBOL_GPL(tabla_get_logical_addresses);
-
-int tabla_interface_reg_read(struct tabla *tabla, unsigned short reg)
-{
- u8 val;
- int ret;
-
- mutex_lock(&tabla->io_lock);
- ret = tabla_read(tabla, reg, 1, &val, true);
- mutex_unlock(&tabla->io_lock);
-
- if (ret < 0)
- return ret;
- else
- return val;
-}
-EXPORT_SYMBOL_GPL(tabla_interface_reg_read);
-
-int tabla_interface_reg_write(struct tabla *tabla, unsigned short reg,
- u8 val)
-{
- int ret;
-
- mutex_lock(&tabla->io_lock);
- ret = tabla_write(tabla, reg, 1, &val, true);
- mutex_unlock(&tabla->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tabla_interface_reg_write);
-
-int tabla_bulk_read(struct tabla *tabla, unsigned short reg,
- int count, u8 *buf)
-{
- int ret;
-
- mutex_lock(&tabla->io_lock);
-
- ret = tabla_read(tabla, reg, count, buf, false);
-
- mutex_unlock(&tabla->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tabla_bulk_read);
-
-int tabla_bulk_write(struct tabla *tabla, unsigned short reg,
- int count, u8 *buf)
-{
- int ret;
-
- mutex_lock(&tabla->io_lock);
-
- ret = tabla_write(tabla, reg, count, buf, false);
-
- mutex_unlock(&tabla->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tabla_bulk_write);
-
-static int tabla_slim_read_device(struct tabla *tabla, unsigned short reg,
- int bytes, void *dest, bool interface)
-{
- int ret;
- struct slim_ele_access msg;
- int slim_read_tries = TABLA_SLIM_RW_MAX_TRIES;
- msg.start_offset = TABLA_REGISTER_START_OFFSET + reg;
- msg.num_bytes = bytes;
- msg.comp = NULL;
-
- while (1) {
- mutex_lock(&tabla->xfer_lock);
- ret = slim_request_val_element(interface ?
- tabla->slim_slave : tabla->slim,
- &msg, dest, bytes);
- mutex_unlock(&tabla->xfer_lock);
- if (likely(ret == 0) || (--slim_read_tries == 0))
- break;
- usleep_range(5000, 5000);
- }
-
- if (ret)
- pr_err("%s: Error, Tabla read failed (%d)\n", __func__, ret);
-
- return ret;
-}
-/* Interface specifies whether the write is to the interface or general
- * registers.
- */
-static int tabla_slim_write_device(struct tabla *tabla, unsigned short reg,
- int bytes, void *src, bool interface)
-{
- int ret;
- struct slim_ele_access msg;
- int slim_write_tries = TABLA_SLIM_RW_MAX_TRIES;
- msg.start_offset = TABLA_REGISTER_START_OFFSET + reg;
- msg.num_bytes = bytes;
- msg.comp = NULL;
-
- while (1) {
- mutex_lock(&tabla->xfer_lock);
- ret = slim_change_val_element(interface ?
- tabla->slim_slave : tabla->slim,
- &msg, src, bytes);
- mutex_unlock(&tabla->xfer_lock);
- if (likely(ret == 0) || (--slim_write_tries == 0))
- break;
- usleep_range(5000, 5000);
- }
-
- if (ret)
- pr_err("%s: Error, Tabla write failed (%d)\n", __func__, ret);
-
- return ret;
-}
-
-static struct mfd_cell tabla_devs[] = {
- {
- .name = "tabla_codec",
- },
-};
-
-static struct mfd_cell tabla1x_devs[] = {
- {
- .name = "tabla1x_codec",
- },
-};
-
-static void tabla_bring_up(struct tabla *tabla)
-{
- tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 0x4);
- tabla_reg_write(tabla, TABLA_A_CDC_CTL, 0);
- usleep_range(5000, 5000);
- tabla_reg_write(tabla, TABLA_A_CDC_CTL, 3);
- tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 3);
-}
-
-static void tabla_bring_down(struct tabla *tabla)
-{
- tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 0x7);
- tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 0x6);
- tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 0xe);
- tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 0x8);
-}
-
-static int tabla_reset(struct tabla *tabla)
-{
- int ret;
-
- if (tabla->reset_gpio) {
- ret = gpio_request(tabla->reset_gpio, "CDC_RESET");
- if (ret) {
- pr_err("%s: Failed to request gpio %d\n", __func__,
- tabla->reset_gpio);
- tabla->reset_gpio = 0;
- return ret;
- }
-
- gpio_direction_output(tabla->reset_gpio, 1);
- msleep(20);
- gpio_direction_output(tabla->reset_gpio, 0);
- msleep(20);
- gpio_direction_output(tabla->reset_gpio, 1);
- msleep(20);
- }
- return 0;
-}
-
-static void tabla_free_reset(struct tabla *tabla)
-{
- if (tabla->reset_gpio) {
- gpio_free(tabla->reset_gpio);
- tabla->reset_gpio = 0;
- }
-}
-
-struct tabla_regulator {
- const char *name;
- int min_uV;
- int max_uV;
- int optimum_uA;
- struct regulator *regulator;
-};
-
-
-/*
- * format : TABLA_<POWER_SUPPLY_PIN_NAME>_CUR_MAX
- *
- * <POWER_SUPPLY_PIN_NAME> from Tabla objective spec
-*/
-
-#define TABLA_CDC_VDDA_CP_CUR_MAX 500000
-#define TABLA_CDC_VDDA_RX_CUR_MAX 20000
-#define TABLA_CDC_VDDA_TX_CUR_MAX 20000
-#define TABLA_VDDIO_CDC_CUR_MAX 5000
-
-#define TABLA_VDDD_CDC_D_CUR_MAX 5000
-#define TABLA_VDDD_CDC_A_CUR_MAX 5000
-
-static struct tabla_regulator tabla_regulators[] = {
- {
- .name = "CDC_VDD_CP",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .optimum_uA = TABLA_CDC_VDDA_CP_CUR_MAX,
- },
- {
- .name = "CDC_VDDA_RX",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .optimum_uA = TABLA_CDC_VDDA_RX_CUR_MAX,
- },
- {
- .name = "CDC_VDDA_TX",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .optimum_uA = TABLA_CDC_VDDA_TX_CUR_MAX,
- },
- {
- .name = "VDDIO_CDC",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .optimum_uA = TABLA_VDDIO_CDC_CUR_MAX,
- },
- {
- .name = "VDDD_CDC_D",
- .min_uV = 1225000,
- .max_uV = 1225000,
- .optimum_uA = TABLA_VDDD_CDC_D_CUR_MAX,
- },
- {
- .name = "CDC_VDDA_A_1P2V",
- .min_uV = 1225000,
- .max_uV = 1225000,
- .optimum_uA = TABLA_VDDD_CDC_A_CUR_MAX,
- },
-};
-
-static int tabla_device_init(struct tabla *tabla, int irq)
-{
- int ret;
- struct mfd_cell *tabla_dev;
- int tabla_dev_size;
-
- mutex_init(&tabla->io_lock);
- mutex_init(&tabla->xfer_lock);
-
- mutex_init(&tabla->pm_lock);
- tabla->wlock_holders = 0;
- tabla->pm_state = TABLA_PM_SLEEPABLE;
- init_waitqueue_head(&tabla->pm_wq);
- wake_lock_init(&tabla->wlock, WAKE_LOCK_IDLE, "wcd9310-irq");
-
- dev_set_drvdata(tabla->dev, tabla);
-
- tabla_bring_up(tabla);
-
- ret = tabla_irq_init(tabla);
- if (ret) {
- pr_err("IRQ initialization failed\n");
- goto err;
- }
- tabla->version = tabla_reg_read(tabla, TABLA_A_CHIP_VERSION) & 0x1F;
- pr_info("%s : Tabla version %u initialized\n",
- __func__, tabla->version);
-
- if (TABLA_IS_1_X(tabla->version)) {
- tabla_dev = tabla1x_devs;
- tabla_dev_size = ARRAY_SIZE(tabla1x_devs);
- } else {
- tabla_dev = tabla_devs;
- tabla_dev_size = ARRAY_SIZE(tabla_devs);
- }
- ret = mfd_add_devices(tabla->dev, -1,
- tabla_dev, tabla_dev_size,
- NULL, 0);
- if (ret != 0) {
- dev_err(tabla->dev, "Failed to add children: %d\n", ret);
- goto err_irq;
- }
-
- tabla->version = tabla_reg_read(tabla, TABLA_A_CHIP_VERSION) & 0x1F;
- pr_info("%s : Tabla version %u initialized\n",
- __func__, tabla->version);
-
- return ret;
-err_irq:
- tabla_irq_exit(tabla);
-err:
- tabla_bring_down(tabla);
- wake_lock_destroy(&tabla->wlock);
- mutex_destroy(&tabla->pm_lock);
- mutex_destroy(&tabla->io_lock);
- mutex_destroy(&tabla->xfer_lock);
- return ret;
-}
-
-static void tabla_device_exit(struct tabla *tabla)
-{
- tabla_irq_exit(tabla);
- tabla_bring_down(tabla);
- tabla_free_reset(tabla);
- mutex_destroy(&tabla->pm_lock);
- wake_lock_destroy(&tabla->wlock);
- mutex_destroy(&tabla->io_lock);
- mutex_destroy(&tabla->xfer_lock);
-}
-
-
-#ifdef CONFIG_DEBUG_FS
-struct tabla *debugTabla;
-
-static struct dentry *debugfs_tabla_dent;
-static struct dentry *debugfs_peek;
-static struct dentry *debugfs_poke;
-
-static unsigned char read_data;
-
-static int codec_debug_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static int get_parameters(char *buf, long int *param1, int num_of_par)
-{
- char *token;
- int base, cnt;
-
- token = strsep(&buf, " ");
-
- for (cnt = 0; cnt < num_of_par; cnt++) {
- if (token != NULL) {
- if ((token[1] == 'x') || (token[1] == 'X'))
- base = 16;
- else
- base = 10;
-
- if (strict_strtoul(token, base, ¶m1[cnt]) != 0)
- return -EINVAL;
-
- token = strsep(&buf, " ");
- } else
- return -EINVAL;
- }
- return 0;
-}
-
-static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
- size_t count, loff_t *ppos)
-{
- char lbuf[8];
-
- snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
- return simple_read_from_buffer(ubuf, count, ppos, lbuf,
- strnlen(lbuf, 7));
-}
-
-
-static ssize_t codec_debug_write(struct file *filp,
- const char __user *ubuf, size_t cnt, loff_t *ppos)
-{
- char *access_str = filp->private_data;
- char lbuf[32];
- int rc;
- long int param[5];
-
- if (cnt > sizeof(lbuf) - 1)
- return -EINVAL;
-
- rc = copy_from_user(lbuf, ubuf, cnt);
- if (rc)
- return -EFAULT;
-
- lbuf[cnt] = '\0';
-
- if (!strncmp(access_str, "poke", 6)) {
- /* write */
- rc = get_parameters(lbuf, param, 2);
- if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
- (rc == 0))
- tabla_interface_reg_write(debugTabla, param[0],
- param[1]);
- else
- rc = -EINVAL;
- } else if (!strncmp(access_str, "peek", 6)) {
- /* read */
- rc = get_parameters(lbuf, param, 1);
- if ((param[0] <= 0x3FF) && (rc == 0))
- read_data = tabla_interface_reg_read(debugTabla,
- param[0]);
- else
- rc = -EINVAL;
- }
-
- if (rc == 0)
- rc = cnt;
- else
- pr_err("%s: rc = %d\n", __func__, rc);
-
- return rc;
-}
-
-static const struct file_operations codec_debug_ops = {
- .open = codec_debug_open,
- .write = codec_debug_write,
- .read = codec_debug_read
-};
-#endif
-
-static int tabla_enable_supplies(struct tabla *tabla)
-{
- int ret;
- int i;
-
- tabla->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
- ARRAY_SIZE(tabla_regulators),
- GFP_KERNEL);
- if (!tabla->supplies) {
- ret = -ENOMEM;
- goto err;
- }
-
- for (i = 0; i < ARRAY_SIZE(tabla_regulators); i++)
- tabla->supplies[i].supply = tabla_regulators[i].name;
-
- ret = regulator_bulk_get(tabla->dev, ARRAY_SIZE(tabla_regulators),
- tabla->supplies);
- if (ret != 0) {
- dev_err(tabla->dev, "Failed to get supplies: err = %d\n", ret);
- goto err_supplies;
- }
-
- for (i = 0; i < ARRAY_SIZE(tabla_regulators); i++) {
- ret = regulator_set_voltage(tabla->supplies[i].consumer,
- tabla_regulators[i].min_uV, tabla_regulators[i].max_uV);
- if (ret) {
- pr_err("%s: Setting regulator voltage failed for "
- "regulator %s err = %d\n", __func__,
- tabla->supplies[i].supply, ret);
- goto err_get;
- }
-
- ret = regulator_set_optimum_mode(tabla->supplies[i].consumer,
- tabla_regulators[i].optimum_uA);
- if (ret < 0) {
- pr_err("%s: Setting regulator optimum mode failed for "
- "regulator %s err = %d\n", __func__,
- tabla->supplies[i].supply, ret);
- goto err_get;
- }
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(tabla_regulators),
- tabla->supplies);
- if (ret != 0) {
- dev_err(tabla->dev, "Failed to enable supplies: err = %d\n",
- ret);
- goto err_configure;
- }
- return ret;
-
-err_configure:
- for (i = 0; i < ARRAY_SIZE(tabla_regulators); i++) {
- regulator_set_voltage(tabla->supplies[i].consumer, 0,
- tabla_regulators[i].max_uV);
- regulator_set_optimum_mode(tabla->supplies[i].consumer, 0);
- }
-err_get:
- regulator_bulk_free(ARRAY_SIZE(tabla_regulators), tabla->supplies);
-err_supplies:
- kfree(tabla->supplies);
-err:
- return ret;
-}
-
-static void tabla_disable_supplies(struct tabla *tabla)
-{
- int i;
-
- regulator_bulk_disable(ARRAY_SIZE(tabla_regulators),
- tabla->supplies);
- for (i = 0; i < ARRAY_SIZE(tabla_regulators); i++) {
- regulator_set_voltage(tabla->supplies[i].consumer, 0,
- tabla_regulators[i].max_uV);
- regulator_set_optimum_mode(tabla->supplies[i].consumer, 0);
- }
- regulator_bulk_free(ARRAY_SIZE(tabla_regulators), tabla->supplies);
- kfree(tabla->supplies);
-}
-
-int tabla_get_intf_type(void)
-{
- return tabla_intf;
-}
-EXPORT_SYMBOL_GPL(tabla_get_intf_type);
-
-struct tabla_i2c *get_i2c_tabla_device_info(u16 reg)
-{
- u16 mask = 0x0f00;
- int value = 0;
- struct tabla_i2c *tabla = NULL;
- value = ((reg & mask) >> 8) & 0x000f;
- switch (value) {
- case 0:
- tabla = &tabla_modules[0];
- break;
- case 1:
- tabla = &tabla_modules[1];
- break;
- case 2:
- tabla = &tabla_modules[2];
- break;
- case 3:
- tabla = &tabla_modules[3];
- break;
- default:
- break;
- }
- return tabla;
-}
-
-int tabla_i2c_write_device(u16 reg, u8 *value,
- u32 bytes)
-{
-
- struct i2c_msg *msg;
- int ret = 0;
- u8 reg_addr = 0;
- u8 data[bytes + 1];
- struct tabla_i2c *tabla;
-
- tabla = get_i2c_tabla_device_info(reg);
- if (tabla == NULL || tabla->client == NULL) {
- pr_err("failed to get device info\n");
- return -ENODEV;
- }
- reg_addr = (u8)reg;
- msg = &tabla->xfer_msg[0];
- msg->addr = tabla->client->addr;
- msg->len = bytes + 1;
- msg->flags = 0;
- data[0] = reg;
- data[1] = *value;
- msg->buf = data;
- ret = i2c_transfer(tabla->client->adapter, tabla->xfer_msg, 1);
- /* Try again if the write fails */
- if (ret != 1) {
- ret = i2c_transfer(tabla->client->adapter,
- tabla->xfer_msg, 1);
- if (ret != 1) {
- pr_err("failed to write the device\n");
- return ret;
- }
- }
- pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
- return 0;
-}
-
-
-int tabla_i2c_read_device(unsigned short reg,
- int bytes, unsigned char *dest)
-{
- struct i2c_msg *msg;
- int ret = 0;
- u8 reg_addr = 0;
- struct tabla_i2c *tabla;
- u8 i = 0;
-
- tabla = get_i2c_tabla_device_info(reg);
- if (tabla == NULL || tabla->client == NULL) {
- pr_err("failed to get device info\n");
- return -ENODEV;
- }
- for (i = 0; i < bytes; i++) {
- reg_addr = (u8)reg++;
- msg = &tabla->xfer_msg[0];
- msg->addr = tabla->client->addr;
- msg->len = 1;
- msg->flags = 0;
- msg->buf = ®_addr;
-
- msg = &tabla->xfer_msg[1];
- msg->addr = tabla->client->addr;
- msg->len = 1;
- msg->flags = I2C_M_RD;
- msg->buf = dest++;
- ret = i2c_transfer(tabla->client->adapter, tabla->xfer_msg, 2);
-
- /* Try again if read fails first time */
- if (ret != 2) {
- ret = i2c_transfer(tabla->client->adapter,
- tabla->xfer_msg, 2);
- if (ret != 2) {
- pr_err("failed to read tabla register\n");
- return ret;
- }
- }
- }
- return 0;
-}
-
-int tabla_i2c_read(struct tabla *tabla, unsigned short reg,
- int bytes, void *dest, bool interface_reg)
-{
- return tabla_i2c_read_device(reg, bytes, dest);
-}
-
-int tabla_i2c_write(struct tabla *tabla, unsigned short reg,
- int bytes, void *src, bool interface_reg)
-{
- return tabla_i2c_write_device(reg, src, bytes);
-}
-
-static int __devinit tabla_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct tabla *tabla;
- struct tabla_pdata *pdata = client->dev.platform_data;
- int val = 0;
- int ret = 0;
- static int device_id;
-
- if (device_id > 0) {
- tabla_modules[device_id++].client = client;
- pr_info("probe for other slaves devices of tabla\n");
- return ret;
- }
-
- tabla = kzalloc(sizeof(struct tabla), GFP_KERNEL);
- if (tabla == NULL) {
- pr_err("%s: error, allocation failed\n", __func__);
- ret = -ENOMEM;
- goto fail;
- }
-
- if (!pdata) {
- dev_dbg(&client->dev, "no platform data?\n");
- ret = -EINVAL;
- goto err_tabla;
- }
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
- dev_dbg(&client->dev, "can't talk I2C?\n");
- ret = -EIO;
- goto err_tabla;
- }
- tabla->dev = &client->dev;
- tabla->reset_gpio = pdata->reset_gpio;
-
- ret = tabla_enable_supplies(tabla);
- if (ret) {
- pr_err("%s: Fail to enable Tabla supplies\n", __func__);
- goto err_tabla;
- }
-
- usleep_range(5, 5);
- ret = tabla_reset(tabla);
- if (ret) {
- pr_err("%s: Resetting Tabla failed\n", __func__);
- goto err_supplies;
- }
- tabla_modules[device_id++].client = client;
-
- tabla->read_dev = tabla_i2c_read;
- tabla->write_dev = tabla_i2c_write;
- tabla->irq = pdata->irq;
- tabla->irq_base = pdata->irq_base;
-
- /*read the tabla status before initializing the device type*/
- ret = tabla_read(tabla, TABLA_A_CHIP_STATUS, 1, &val, 0);
- if ((ret < 0) || (val != TABLA_I2C_MODE)) {
- pr_err("failed to read the tabla status\n");
- goto err_device_init;
- }
-
- ret = tabla_device_init(tabla, tabla->irq);
- if (ret) {
- pr_err("%s: error, initializing device failed\n", __func__);
- goto err_device_init;
- }
- tabla_intf = TABLA_INTERFACE_TYPE_I2C;
-
- return ret;
-err_device_init:
- tabla_free_reset(tabla);
-err_supplies:
- tabla_disable_supplies(tabla);
-err_tabla:
- kfree(tabla);
-fail:
- return ret;
-}
-
-static int __devexit tabla_i2c_remove(struct i2c_client *client)
-{
- struct tabla *tabla;
-
- pr_debug("exit\n");
- tabla = dev_get_drvdata(&client->dev);
- tabla_device_exit(tabla);
- tabla_disable_supplies(tabla);
- kfree(tabla);
- return 0;
-}
-
-static int tabla_slim_probe(struct slim_device *slim)
-{
- struct tabla *tabla;
- struct tabla_pdata *pdata;
- int ret = 0;
- int sgla_retry_cnt;
-
- dev_info(&slim->dev, "Initialized slim device %s\n", slim->name);
- pdata = slim->dev.platform_data;
-
- if (!pdata) {
- dev_err(&slim->dev, "Error, no platform data\n");
- ret = -EINVAL;
- goto err;
- }
-
- tabla = kzalloc(sizeof(struct tabla), GFP_KERNEL);
- if (tabla == NULL) {
- pr_err("%s: error, allocation failed\n", __func__);
- ret = -ENOMEM;
- goto err;
- }
- if (!slim->ctrl) {
- pr_err("Error, no SLIMBUS control data\n");
- ret = -EINVAL;
- goto err_tabla;
- }
- tabla->slim = slim;
- slim_set_clientdata(slim, tabla);
- tabla->reset_gpio = pdata->reset_gpio;
- tabla->dev = &slim->dev;
-
- ret = tabla_enable_supplies(tabla);
- if (ret) {
- pr_err("%s: Fail to enable Tabla supplies\n", __func__);
- goto err_tabla;
- }
- usleep_range(5, 5);
-
- ret = tabla_reset(tabla);
- if (ret) {
- pr_err("%s: Resetting Tabla failed\n", __func__);
- goto err_supplies;
- }
-
- ret = slim_get_logical_addr(tabla->slim, tabla->slim->e_addr,
- ARRAY_SIZE(tabla->slim->e_addr), &tabla->slim->laddr);
- if (ret) {
- pr_err("fail to get slimbus logical address %d\n", ret);
- goto err_reset;
- }
- tabla->read_dev = tabla_slim_read_device;
- tabla->write_dev = tabla_slim_write_device;
- tabla->irq = pdata->irq;
- tabla->irq_base = pdata->irq_base;
- tabla_pgd_la = tabla->slim->laddr;
-
- if (pdata->num_irqs < TABLA_NUM_IRQS) {
- pr_err("%s: Error, not enough interrupt lines allocated\n",
- __func__);
- goto err_reset;
- }
-
- tabla->slim_slave = &pdata->slimbus_slave_device;
-
- ret = slim_add_device(slim->ctrl, tabla->slim_slave);
- if (ret) {
- pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
- goto err_reset;
- }
-
- sgla_retry_cnt = 0;
-
- while (1) {
- ret = slim_get_logical_addr(tabla->slim_slave,
- tabla->slim_slave->e_addr,
- ARRAY_SIZE(tabla->slim_slave->e_addr),
- &tabla->slim_slave->laddr);
- if (ret) {
- if (sgla_retry_cnt++ < TABLA_SLIM_GLA_MAX_RETRIES) {
- /* Give SLIMBUS slave time to report present
- and be ready.
- */
- usleep_range(1000, 1000);
- pr_debug("%s: retry slim_get_logical_addr()\n",
- __func__);
- continue;
- }
- pr_err("fail to get slimbus slave logical address"
- " %d\n", ret);
- goto err_slim_add;
- }
- break;
- }
- tabla_inf_la = tabla->slim_slave->laddr;
- tabla_intf = TABLA_INTERFACE_TYPE_SLIMBUS;
-
- ret = tabla_device_init(tabla, tabla->irq);
- if (ret) {
- pr_err("%s: error, initializing device failed\n", __func__);
- goto err_slim_add;
- }
- tabla_init_slimslave(tabla, tabla_pgd_la);
-#ifdef CONFIG_DEBUG_FS
- debugTabla = tabla;
-
- debugfs_tabla_dent = debugfs_create_dir
- ("wcd9310_slimbus_interface_device", 0);
- if (!IS_ERR(debugfs_tabla_dent)) {
- debugfs_peek = debugfs_create_file("peek",
- S_IFREG | S_IRUGO, debugfs_tabla_dent,
- (void *) "peek", &codec_debug_ops);
-
- debugfs_poke = debugfs_create_file("poke",
- S_IFREG | S_IRUGO, debugfs_tabla_dent,
- (void *) "poke", &codec_debug_ops);
- }
-#endif
-
- return ret;
-
-err_slim_add:
- slim_remove_device(tabla->slim_slave);
-err_reset:
- tabla_free_reset(tabla);
-err_supplies:
- tabla_disable_supplies(tabla);
-err_tabla:
- kfree(tabla);
-err:
- return ret;
-}
-
-static int tabla_slim_remove(struct slim_device *pdev)
-{
- struct tabla *tabla;
-
-#ifdef CONFIG_DEBUG_FS
- debugfs_remove(debugfs_peek);
- debugfs_remove(debugfs_poke);
- debugfs_remove(debugfs_tabla_dent);
-#endif
-
- tabla = slim_get_devicedata(pdev);
- tabla_deinit_slimslave(tabla);
- tabla_disable_supplies(tabla);
- slim_remove_device(tabla->slim_slave);
- tabla_device_exit(tabla);
- return 0;
-}
-
-static int tabla_resume(struct tabla *tabla)
-{
- int ret = 0;
-
- pr_debug("%s: enter\n", __func__);
- mutex_lock(&tabla->pm_lock);
- if (tabla->pm_state == TABLA_PM_ASLEEP) {
- pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
- tabla->pm_state, tabla->wlock_holders);
- tabla->pm_state = TABLA_PM_SLEEPABLE;
- } else {
- pr_warn("%s: system is already awake, state %d wlock %d\n",
- __func__, tabla->pm_state, tabla->wlock_holders);
- }
- mutex_unlock(&tabla->pm_lock);
- wake_up_all(&tabla->pm_wq);
-
- return ret;
-}
-
-static int tabla_slim_resume(struct slim_device *sldev)
-{
- struct tabla *tabla = slim_get_devicedata(sldev);
- return tabla_resume(tabla);
-}
-
-static int tabla_i2c_resume(struct i2c_client *i2cdev)
-{
- struct tabla *tabla = dev_get_drvdata(&i2cdev->dev);
- return tabla_resume(tabla);
-}
-
-static int tabla_suspend(struct tabla *tabla, pm_message_t pmesg)
-{
- int ret = 0;
-
- pr_debug("%s: enter\n", __func__);
- /* wake_lock() can be called after this suspend chain call started.
- * thus suspend can be called while wlock is being held */
- mutex_lock(&tabla->pm_lock);
- if (tabla->pm_state == TABLA_PM_SLEEPABLE) {
- pr_debug("%s: suspending system, state %d, wlock %d\n",
- __func__, tabla->pm_state, tabla->wlock_holders);
- tabla->pm_state = TABLA_PM_ASLEEP;
- } else if (tabla->pm_state == TABLA_PM_AWAKE) {
- /* unlock to wait for pm_state == TABLA_PM_SLEEPABLE
- * then set to TABLA_PM_ASLEEP */
- pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
- __func__, tabla->pm_state, tabla->wlock_holders);
- mutex_unlock(&tabla->pm_lock);
- if (!(wait_event_timeout(tabla->pm_wq,
- tabla_pm_cmpxchg(tabla,
- TABLA_PM_SLEEPABLE,
- TABLA_PM_ASLEEP) ==
- TABLA_PM_SLEEPABLE,
- HZ))) {
- pr_debug("%s: suspend failed state %d, wlock %d\n",
- __func__, tabla->pm_state,
- tabla->wlock_holders);
- ret = -EBUSY;
- } else {
- pr_debug("%s: done, state %d, wlock %d\n", __func__,
- tabla->pm_state, tabla->wlock_holders);
- }
- mutex_lock(&tabla->pm_lock);
- } else if (tabla->pm_state == TABLA_PM_ASLEEP) {
- pr_warn("%s: system is already suspended, state %d, wlock %dn",
- __func__, tabla->pm_state, tabla->wlock_holders);
- }
- mutex_unlock(&tabla->pm_lock);
-
- return ret;
-}
-
-static int tabla_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
-{
- struct tabla *tabla = slim_get_devicedata(sldev);
- return tabla_suspend(tabla, pmesg);
-}
-
-static int tabla_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
-{
- struct tabla *tabla = dev_get_drvdata(&i2cdev->dev);
- return tabla_suspend(tabla, pmesg);
-}
-
-static const struct slim_device_id slimtest_id[] = {
- {"tabla-slim", 0},
- {}
-};
-
-static struct slim_driver tabla_slim_driver = {
- .driver = {
- .name = "tabla-slim",
- .owner = THIS_MODULE,
- },
- .probe = tabla_slim_probe,
- .remove = tabla_slim_remove,
- .id_table = slimtest_id,
- .resume = tabla_slim_resume,
- .suspend = tabla_slim_suspend,
-};
-
-static const struct slim_device_id slimtest2x_id[] = {
- {"tabla2x-slim", 0},
- {}
-};
-
-static struct slim_driver tabla2x_slim_driver = {
- .driver = {
- .name = "tabla2x-slim",
- .owner = THIS_MODULE,
- },
- .probe = tabla_slim_probe,
- .remove = tabla_slim_remove,
- .id_table = slimtest2x_id,
- .resume = tabla_slim_resume,
- .suspend = tabla_slim_suspend,
-};
-
-#define TABLA_I2C_TOP_LEVEL 0
-#define TABLA_I2C_ANALOG 1
-#define TABLA_I2C_DIGITAL_1 2
-#define TABLA_I2C_DIGITAL_2 3
-
-static struct i2c_device_id tabla_id_table[] = {
- {"tabla top level", TABLA_I2C_TOP_LEVEL},
- {"tabla analog", TABLA_I2C_TOP_LEVEL},
- {"tabla digital1", TABLA_I2C_TOP_LEVEL},
- {"tabla digital2", TABLA_I2C_TOP_LEVEL},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, tabla_id_table);
-
-static struct i2c_driver tabla_i2c_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tabla-i2c-core",
- },
- .id_table = tabla_id_table,
- .probe = tabla_i2c_probe,
- .remove = __devexit_p(tabla_i2c_remove),
- .resume = tabla_i2c_resume,
- .suspend = tabla_i2c_suspend,
-};
-
-static int __init tabla_init(void)
-{
- int ret1, ret2, ret3;
-
- ret1 = slim_driver_register(&tabla_slim_driver);
- if (ret1 != 0)
- pr_err("Failed to register tabla SB driver: %d\n", ret1);
-
- ret2 = slim_driver_register(&tabla2x_slim_driver);
- if (ret2 != 0)
- pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
-
- ret3 = i2c_add_driver(&tabla_i2c_driver);
- if (ret3 != 0)
- pr_err("failed to add the I2C driver\n");
-
- return (ret1 && ret2 && ret3) ? -1 : 0;
-}
-module_init(tabla_init);
-
-static void __exit tabla_exit(void)
-{
-}
-module_exit(tabla_exit);
-
-MODULE_DESCRIPTION("Tabla core driver");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/wcd9310-irq.c b/drivers/mfd/wcd9310-irq.c
deleted file mode 100644
index c6a9c23..0000000
--- a/drivers/mfd/wcd9310-irq.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <linux/bitops.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/irq.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/wcd9310/core.h>
-#include <linux/mfd/wcd9310/registers.h>
-#include <linux/interrupt.h>
-
-#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE))
-#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
-
-struct tabla_irq {
- bool level;
-};
-
-static struct tabla_irq tabla_irqs[TABLA_NUM_IRQS] = {
- [0] = { .level = 1},
-/* All other tabla interrupts are edge triggered */
-};
-
-static inline int irq_to_tabla_irq(struct tabla *tabla, int irq)
-{
- return irq - tabla->irq_base;
-}
-
-static void tabla_irq_lock(struct irq_data *data)
-{
- struct tabla *tabla = irq_data_get_irq_chip_data(data);
- mutex_lock(&tabla->irq_lock);
-}
-
-static void tabla_irq_sync_unlock(struct irq_data *data)
-{
- struct tabla *tabla = irq_data_get_irq_chip_data(data);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(tabla->irq_masks_cur); i++) {
- /* If there's been a change in the mask write it back
- * to the hardware.
- */
- if (tabla->irq_masks_cur[i] != tabla->irq_masks_cache[i]) {
- tabla->irq_masks_cache[i] = tabla->irq_masks_cur[i];
- tabla_reg_write(tabla, TABLA_A_INTR_MASK0+i,
- tabla->irq_masks_cur[i]);
- }
- }
-
- mutex_unlock(&tabla->irq_lock);
-}
-
-static void tabla_irq_enable(struct irq_data *data)
-{
- struct tabla *tabla = irq_data_get_irq_chip_data(data);
- int tabla_irq = irq_to_tabla_irq(tabla, data->irq);
- tabla->irq_masks_cur[BIT_BYTE(tabla_irq)] &=
- ~(BYTE_BIT_MASK(tabla_irq));
-}
-
-static void tabla_irq_disable(struct irq_data *data)
-{
- struct tabla *tabla = irq_data_get_irq_chip_data(data);
- int tabla_irq = irq_to_tabla_irq(tabla, data->irq);
- tabla->irq_masks_cur[BIT_BYTE(tabla_irq)] |= BYTE_BIT_MASK(tabla_irq);
-}
-
-static struct irq_chip tabla_irq_chip = {
- .name = "tabla",
- .irq_bus_lock = tabla_irq_lock,
- .irq_bus_sync_unlock = tabla_irq_sync_unlock,
- .irq_disable = tabla_irq_disable,
- .irq_enable = tabla_irq_enable,
-};
-
-enum tabla_pm_state tabla_pm_cmpxchg(struct tabla *tabla, enum tabla_pm_state o,
- enum tabla_pm_state n)
-{
- enum tabla_pm_state old;
- mutex_lock(&tabla->pm_lock);
- old = tabla->pm_state;
- if (old == o)
- tabla->pm_state = n;
- mutex_unlock(&tabla->pm_lock);
- return old;
-}
-EXPORT_SYMBOL_GPL(tabla_pm_cmpxchg);
-
-void tabla_lock_sleep(struct tabla *tabla)
-{
- enum tabla_pm_state os;
-
- /* tabla_{lock/unlock}_sleep will be called by tabla_irq_thread
- * and its subroutines only motly.
- * but btn0_lpress_fn is not tabla_irq_thread's subroutine and
- * it can race with tabla_irq_thread.
- * so need to embrace wlock_holders with mutex.
- */
- mutex_lock(&tabla->pm_lock);
- if (tabla->wlock_holders++ == 0)
- wake_lock(&tabla->wlock);
- mutex_unlock(&tabla->pm_lock);
- while (!wait_event_timeout(tabla->pm_wq,
- ((os = tabla_pm_cmpxchg(tabla, TABLA_PM_SLEEPABLE,
- TABLA_PM_AWAKE)) ==
- TABLA_PM_SLEEPABLE ||
- (os == TABLA_PM_AWAKE)),
- 5 * HZ)) {
- pr_err("%s: system didn't resume within 5000ms, state %d, "
- "wlock %d\n", __func__, tabla->pm_state,
- tabla->wlock_holders);
- WARN_ON_ONCE(1);
- }
- wake_up_all(&tabla->pm_wq);
-}
-EXPORT_SYMBOL_GPL(tabla_lock_sleep);
-
-void tabla_unlock_sleep(struct tabla *tabla)
-{
- mutex_lock(&tabla->pm_lock);
- if (--tabla->wlock_holders == 0) {
- tabla->pm_state = TABLA_PM_SLEEPABLE;
- wake_unlock(&tabla->wlock);
- }
- mutex_unlock(&tabla->pm_lock);
- wake_up_all(&tabla->pm_wq);
-}
-EXPORT_SYMBOL_GPL(tabla_unlock_sleep);
-
-static irqreturn_t tabla_irq_thread(int irq, void *data)
-{
- int ret;
- struct tabla *tabla = data;
- u8 status[TABLA_NUM_IRQ_REGS];
- unsigned int i;
-
- tabla_lock_sleep(tabla);
- ret = tabla_bulk_read(tabla, TABLA_A_INTR_STATUS0,
- TABLA_NUM_IRQ_REGS, status);
- if (ret < 0) {
- dev_err(tabla->dev, "Failed to read interrupt status: %d\n",
- ret);
- tabla_unlock_sleep(tabla);
- return IRQ_NONE;
- }
- /* Apply masking */
- for (i = 0; i < TABLA_NUM_IRQ_REGS; i++)
- status[i] &= ~tabla->irq_masks_cur[i];
-
- /* Find out which interrupt was triggered and call that interrupt's
- * handler function
- */
- for (i = 0; i < TABLA_NUM_IRQS; i++) {
- if (status[BIT_BYTE(i)] & BYTE_BIT_MASK(i)) {
- if ((i <= TABLA_IRQ_MBHC_INSERTION) &&
- (i >= TABLA_IRQ_MBHC_REMOVAL)) {
- tabla_reg_write(tabla, TABLA_A_INTR_CLEAR0 +
- BIT_BYTE(i), BYTE_BIT_MASK(i));
- if (tabla_get_intf_type() ==
- TABLA_INTERFACE_TYPE_I2C)
- tabla_reg_write(tabla,
- TABLA_A_INTR_MODE, 0x02);
- handle_nested_irq(tabla->irq_base + i);
- } else {
- handle_nested_irq(tabla->irq_base + i);
- tabla_reg_write(tabla, TABLA_A_INTR_CLEAR0 +
- BIT_BYTE(i), BYTE_BIT_MASK(i));
- if (tabla_get_intf_type() ==
- TABLA_INTERFACE_TYPE_I2C)
- tabla_reg_write(tabla,
- TABLA_A_INTR_MODE, 0x02);
- }
- break;
- }
- }
- tabla_unlock_sleep(tabla);
-
- return IRQ_HANDLED;
-}
-
-int tabla_irq_init(struct tabla *tabla)
-{
- int ret;
- unsigned int i, cur_irq;
-
- mutex_init(&tabla->irq_lock);
-
- if (!tabla->irq) {
- dev_warn(tabla->dev,
- "No interrupt specified, no interrupts\n");
- tabla->irq_base = 0;
- return 0;
- }
-
- if (!tabla->irq_base) {
- dev_err(tabla->dev,
- "No interrupt base specified, no interrupts\n");
- return 0;
- }
- /* Mask the individual interrupt sources */
- for (i = 0, cur_irq = tabla->irq_base; i < TABLA_NUM_IRQS; i++,
- cur_irq++) {
-
- irq_set_chip_data(cur_irq, tabla);
-
- if (tabla_irqs[i].level)
- irq_set_chip_and_handler(cur_irq, &tabla_irq_chip,
- handle_level_irq);
- else
- irq_set_chip_and_handler(cur_irq, &tabla_irq_chip,
- handle_edge_irq);
-
- irq_set_nested_thread(cur_irq, 1);
-
- /* ARM needs us to explicitly flag the IRQ as valid
- * and will set them noprobe when we do so. */
-#ifdef CONFIG_ARM
- set_irq_flags(cur_irq, IRQF_VALID);
-#else
- set_irq_noprobe(cur_irq);
-#endif
-
- tabla->irq_masks_cur[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
- tabla->irq_masks_cache[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
- tabla->irq_level[BIT_BYTE(i)] |= tabla_irqs[i].level <<
- (i % BITS_PER_BYTE);
- }
- for (i = 0; i < TABLA_NUM_IRQ_REGS; i++) {
- /* Initialize interrupt mask and level registers */
- tabla_reg_write(tabla, TABLA_A_INTR_LEVEL0 + i,
- tabla->irq_level[i]);
- tabla_reg_write(tabla, TABLA_A_INTR_MASK0 + i,
- tabla->irq_masks_cur[i]);
- }
-
- ret = request_threaded_irq(tabla->irq, NULL, tabla_irq_thread,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- "tabla", tabla);
- if (ret != 0)
- dev_err(tabla->dev, "Failed to request IRQ %d: %d\n",
- tabla->irq, ret);
- else {
- ret = enable_irq_wake(tabla->irq);
- if (ret == 0) {
- ret = device_init_wakeup(tabla->dev, 1);
- if (ret) {
- dev_err(tabla->dev, "Failed to init device"
- "wakeup : %d\n", ret);
- disable_irq_wake(tabla->irq);
- }
- } else
- dev_err(tabla->dev, "Failed to set wake interrupt on"
- " IRQ %d: %d\n", tabla->irq, ret);
- if (ret)
- free_irq(tabla->irq, tabla);
- }
-
- if (ret)
- mutex_destroy(&tabla->irq_lock);
-
- return ret;
-}
-
-void tabla_irq_exit(struct tabla *tabla)
-{
- if (tabla->irq) {
- disable_irq_wake(tabla->irq);
- free_irq(tabla->irq, tabla);
- device_init_wakeup(tabla->dev, 0);
- }
- mutex_destroy(&tabla->irq_lock);
-}
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
new file mode 100644
index 0000000..21c04135
--- /dev/null
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -0,0 +1,1091 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/debugfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <sound/soc.h>
+
+#define WCD9XXX_SLIM_GLA_MAX_RETRIES 5
+#define WCD9XXX_REGISTER_START_OFFSET 0x800
+#define WCD9XXX_SLIM_RW_MAX_TRIES 3
+
+#define MAX_WCD9XXX_DEVICE 4
+#define WCD9XXX_I2C_MODE 0x03
+
+struct wcd9xxx_i2c {
+ struct i2c_client *client;
+ struct i2c_msg xfer_msg[2];
+ struct mutex xfer_lock;
+ int mod_id;
+};
+
+struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
+static int wcd9xxx_intf;
+
+static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *dest, bool interface_reg)
+{
+ int ret;
+ u8 *buf = dest;
+
+ if (bytes <= 0) {
+ dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
+ return -EINVAL;
+ }
+
+ ret = wcd9xxx->read_dev(wcd9xxx, reg, bytes, dest, interface_reg);
+ if (ret < 0) {
+ dev_err(wcd9xxx->dev, "Codec read failed\n");
+ return ret;
+ } else
+ dev_dbg(wcd9xxx->dev, "Read 0x%02x from R%d(0x%x)\n",
+ *buf, reg, reg);
+
+ return 0;
+}
+int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
+{
+ u8 val;
+ int ret;
+
+ mutex_lock(&wcd9xxx->io_lock);
+ ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false);
+ mutex_unlock(&wcd9xxx->io_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return val;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_reg_read);
+
+static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *src, bool interface_reg)
+{
+ u8 *buf = src;
+
+ if (bytes <= 0) {
+ pr_err("%s: Error, invalid write length\n", __func__);
+ return -EINVAL;
+ }
+
+ dev_dbg(wcd9xxx->dev, "Write %02x to R%d(0x%x)\n",
+ *buf, reg, reg);
+
+ return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
+}
+
+int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ u8 val)
+{
+ int ret;
+
+ mutex_lock(&wcd9xxx->io_lock);
+ ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, false);
+ mutex_unlock(&wcd9xxx->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_reg_write);
+
+static u8 wcd9xxx_pgd_la;
+static u8 wcd9xxx_inf_la;
+
+int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
+{
+ u8 val;
+ int ret;
+
+ mutex_lock(&wcd9xxx->io_lock);
+ ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, true);
+ mutex_unlock(&wcd9xxx->io_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return val;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_read);
+
+int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ u8 val)
+{
+ int ret;
+
+ mutex_lock(&wcd9xxx->io_lock);
+ ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, true);
+ mutex_unlock(&wcd9xxx->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_write);
+
+int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int count, u8 *buf)
+{
+ int ret;
+
+ mutex_lock(&wcd9xxx->io_lock);
+
+ ret = wcd9xxx_read(wcd9xxx, reg, count, buf, false);
+
+ mutex_unlock(&wcd9xxx->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_bulk_read);
+
+int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int count, u8 *buf)
+{
+ int ret;
+
+ mutex_lock(&wcd9xxx->io_lock);
+
+ ret = wcd9xxx_write(wcd9xxx, reg, count, buf, false);
+
+ mutex_unlock(&wcd9xxx->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_bulk_write);
+
+static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *dest, bool interface)
+{
+ int ret;
+ struct slim_ele_access msg;
+ int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
+ msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
+ msg.num_bytes = bytes;
+ msg.comp = NULL;
+
+ while (1) {
+ mutex_lock(&wcd9xxx->xfer_lock);
+ ret = slim_request_val_element(interface ?
+ wcd9xxx->slim_slave : wcd9xxx->slim,
+ &msg, dest, bytes);
+ mutex_unlock(&wcd9xxx->xfer_lock);
+ if (likely(ret == 0) || (--slim_read_tries == 0))
+ break;
+ usleep_range(5000, 5000);
+ }
+
+ if (ret)
+ pr_err("%s: Error, Codec read failed (%d)\n", __func__, ret);
+
+ return ret;
+}
+/* Interface specifies whether the write is to the interface or general
+ * registers.
+ */
+static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
+ unsigned short reg, int bytes, void *src, bool interface)
+{
+ int ret;
+ struct slim_ele_access msg;
+ int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
+ msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
+ msg.num_bytes = bytes;
+ msg.comp = NULL;
+
+ while (1) {
+ mutex_lock(&wcd9xxx->xfer_lock);
+ ret = slim_change_val_element(interface ?
+ wcd9xxx->slim_slave : wcd9xxx->slim,
+ &msg, src, bytes);
+ mutex_unlock(&wcd9xxx->xfer_lock);
+ if (likely(ret == 0) || (--slim_write_tries == 0))
+ break;
+ usleep_range(5000, 5000);
+ }
+
+ if (ret)
+ pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
+
+ return ret;
+}
+
+static struct mfd_cell tabla1x_devs[] = {
+ {
+ .name = "tabla1x_codec",
+ },
+};
+
+static struct mfd_cell tabla_devs[] = {
+ {
+ .name = "tabla_codec",
+ },
+};
+
+static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
+{
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 0);
+ usleep_range(5000, 5000);
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3);
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3);
+}
+
+static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx)
+{
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x7);
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x6);
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0xe);
+ wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x8);
+}
+
+static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
+{
+ int ret;
+
+ if (wcd9xxx->reset_gpio) {
+ ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
+ if (ret) {
+ pr_err("%s: Failed to request gpio %d\n", __func__,
+ wcd9xxx->reset_gpio);
+ wcd9xxx->reset_gpio = 0;
+ return ret;
+ }
+
+ gpio_direction_output(wcd9xxx->reset_gpio, 1);
+ msleep(20);
+ gpio_direction_output(wcd9xxx->reset_gpio, 0);
+ msleep(20);
+ gpio_direction_output(wcd9xxx->reset_gpio, 1);
+ msleep(20);
+ }
+ return 0;
+}
+
+static void wcd9xxx_free_reset(struct wcd9xxx *wcd9xxx)
+{
+ if (wcd9xxx->reset_gpio) {
+ gpio_free(wcd9xxx->reset_gpio);
+ wcd9xxx->reset_gpio = 0;
+ }
+}
+
+static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx, int irq)
+{
+ int ret;
+ u8 idbyte_0, idbyte_1, idbyte_2, idbyte_3;
+ struct mfd_cell *wcd9xxx_dev = NULL;
+ int wcd9xxx_dev_size = 0;
+
+ mutex_init(&wcd9xxx->io_lock);
+ mutex_init(&wcd9xxx->xfer_lock);
+
+ mutex_init(&wcd9xxx->pm_lock);
+ wcd9xxx->wlock_holders = 0;
+ wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
+ init_waitqueue_head(&wcd9xxx->pm_wq);
+ wake_lock_init(&wcd9xxx->wlock, WAKE_LOCK_IDLE, "wcd9310-irq");
+
+ dev_set_drvdata(wcd9xxx->dev, wcd9xxx);
+
+ wcd9xxx_bring_up(wcd9xxx);
+
+ ret = wcd9xxx_irq_init(wcd9xxx);
+ if (ret) {
+ pr_err("IRQ initialization failed\n");
+ goto err;
+ }
+
+ idbyte_0 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_0);
+ idbyte_1 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_1);
+ idbyte_2 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_2);
+ idbyte_3 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_3);
+
+ wcd9xxx->version = wcd9xxx_reg_read(wcd9xxx,
+ WCD9XXX_A_CHIP_VERSION) & 0x1F;
+ pr_info("%s : Codec version %u initialized\n",
+ __func__, wcd9xxx->version);
+
+ if (TABLA_IS_1_X(wcd9xxx->version)) {
+ wcd9xxx_dev = tabla1x_devs;
+ wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
+ } else {
+ wcd9xxx_dev = tabla_devs;
+ wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
+ }
+ ret = mfd_add_devices(wcd9xxx->dev, -1,
+ wcd9xxx_dev, wcd9xxx_dev_size,
+ NULL, 0);
+ if (ret != 0) {
+ dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
+ goto err_irq;
+ }
+ return ret;
+err_irq:
+ wcd9xxx_irq_exit(wcd9xxx);
+err:
+ wcd9xxx_bring_down(wcd9xxx);
+ wake_lock_destroy(&wcd9xxx->wlock);
+ mutex_destroy(&wcd9xxx->pm_lock);
+ mutex_destroy(&wcd9xxx->io_lock);
+ mutex_destroy(&wcd9xxx->xfer_lock);
+ return ret;
+}
+
+static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
+{
+ wcd9xxx_irq_exit(wcd9xxx);
+ wcd9xxx_bring_down(wcd9xxx);
+ wcd9xxx_free_reset(wcd9xxx);
+ mutex_destroy(&wcd9xxx->pm_lock);
+ wake_lock_destroy(&wcd9xxx->wlock);
+ mutex_destroy(&wcd9xxx->io_lock);
+ mutex_destroy(&wcd9xxx->xfer_lock);
+ slim_remove_device(wcd9xxx->slim_slave);
+ kfree(wcd9xxx);
+}
+
+
+#ifdef CONFIG_DEBUG_FS
+struct wcd9xxx *debugCodec;
+
+static struct dentry *debugfs_wcd9xxx_dent;
+static struct dentry *debugfs_peek;
+static struct dentry *debugfs_poke;
+
+static unsigned char read_data;
+
+static int codec_debug_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static int get_parameters(char *buf, long int *param1, int num_of_par)
+{
+ char *token;
+ int base, cnt;
+
+ token = strsep(&buf, " ");
+
+ for (cnt = 0; cnt < num_of_par; cnt++) {
+ if (token != NULL) {
+ if ((token[1] == 'x') || (token[1] == 'X'))
+ base = 16;
+ else
+ base = 10;
+
+ if (strict_strtoul(token, base, ¶m1[cnt]) != 0)
+ return -EINVAL;
+
+ token = strsep(&buf, " ");
+ } else
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ char lbuf[8];
+
+ snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
+ return simple_read_from_buffer(ubuf, count, ppos, lbuf,
+ strnlen(lbuf, 7));
+}
+
+
+static ssize_t codec_debug_write(struct file *filp,
+ const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char *access_str = filp->private_data;
+ char lbuf[32];
+ int rc;
+ long int param[5];
+
+ if (cnt > sizeof(lbuf) - 1)
+ return -EINVAL;
+
+ rc = copy_from_user(lbuf, ubuf, cnt);
+ if (rc)
+ return -EFAULT;
+
+ lbuf[cnt] = '\0';
+
+ if (!strncmp(access_str, "poke", 6)) {
+ /* write */
+ rc = get_parameters(lbuf, param, 2);
+ if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
+ (rc == 0))
+ wcd9xxx_interface_reg_write(debugCodec, param[0],
+ param[1]);
+ else
+ rc = -EINVAL;
+ } else if (!strncmp(access_str, "peek", 6)) {
+ /* read */
+ rc = get_parameters(lbuf, param, 1);
+ if ((param[0] <= 0x3FF) && (rc == 0))
+ read_data = wcd9xxx_interface_reg_read(debugCodec,
+ param[0]);
+ else
+ rc = -EINVAL;
+ }
+
+ if (rc == 0)
+ rc = cnt;
+ else
+ pr_err("%s: rc = %d\n", __func__, rc);
+
+ return rc;
+}
+
+static const struct file_operations codec_debug_ops = {
+ .open = codec_debug_open,
+ .write = codec_debug_write,
+ .read = codec_debug_read
+};
+#endif
+
+static int wcd9xxx_enable_supplies(struct wcd9xxx *wcd9xxx)
+{
+ int ret;
+ int i;
+ struct wcd9xxx_pdata *pdata = wcd9xxx->slim->dev.platform_data;
+
+ wcd9xxx->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
+ ARRAY_SIZE(pdata->regulator),
+ GFP_KERNEL);
+ if (!wcd9xxx->supplies) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++)
+ wcd9xxx->supplies[i].supply = pdata->regulator[i].name;
+
+ ret = regulator_bulk_get(wcd9xxx->dev, ARRAY_SIZE(pdata->regulator),
+ wcd9xxx->supplies);
+ if (ret != 0) {
+ dev_err(wcd9xxx->dev, "Failed to get supplies: err = %d\n",
+ ret);
+ goto err_supplies;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
+ ret = regulator_set_voltage(wcd9xxx->supplies[i].consumer,
+ pdata->regulator[i].min_uV, pdata->regulator[i].max_uV);
+ if (ret) {
+ pr_err("%s: Setting regulator voltage failed for "
+ "regulator %s err = %d\n", __func__,
+ wcd9xxx->supplies[i].supply, ret);
+ goto err_get;
+ }
+
+ ret = regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer,
+ pdata->regulator[i].optimum_uA);
+ if (ret < 0) {
+ pr_err("%s: Setting regulator optimum mode failed for "
+ "regulator %s err = %d\n", __func__,
+ wcd9xxx->supplies[i].supply, ret);
+ goto err_get;
+ }
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(pdata->regulator),
+ wcd9xxx->supplies);
+ if (ret != 0) {
+ dev_err(wcd9xxx->dev, "Failed to enable supplies: err = %d\n",
+ ret);
+ goto err_configure;
+ }
+ return ret;
+
+err_configure:
+ for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
+ regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
+ pdata->regulator[i].max_uV);
+ regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
+ }
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(pdata->regulator), wcd9xxx->supplies);
+err_supplies:
+ kfree(wcd9xxx->supplies);
+err:
+ return ret;
+}
+
+static void wcd9xxx_disable_supplies(struct wcd9xxx *wcd9xxx)
+{
+ int i;
+ struct wcd9xxx_pdata *pdata = wcd9xxx->slim->dev.platform_data;
+
+ regulator_bulk_disable(ARRAY_SIZE(pdata->regulator),
+ wcd9xxx->supplies);
+ for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
+ regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
+ pdata->regulator[i].max_uV);
+ regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
+ }
+ regulator_bulk_free(ARRAY_SIZE(pdata->regulator), wcd9xxx->supplies);
+ kfree(wcd9xxx->supplies);
+}
+
+int wcd9xxx_get_intf_type(void)
+{
+ return wcd9xxx_intf;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
+
+struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
+{
+ u16 mask = 0x0f00;
+ int value = 0;
+ struct wcd9xxx_i2c *wcd9xxx = NULL;
+ value = ((reg & mask) >> 8) & 0x000f;
+ switch (value) {
+ case 0:
+ wcd9xxx = &wcd9xxx_modules[0];
+ break;
+ case 1:
+ wcd9xxx = &wcd9xxx_modules[1];
+ break;
+ case 2:
+ wcd9xxx = &wcd9xxx_modules[2];
+ break;
+ case 3:
+ wcd9xxx = &wcd9xxx_modules[3];
+ break;
+ default:
+ break;
+ }
+ return wcd9xxx;
+}
+
+int wcd9xxx_i2c_write_device(u16 reg, u8 *value,
+ u32 bytes)
+{
+
+ struct i2c_msg *msg;
+ int ret = 0;
+ u8 reg_addr = 0;
+ u8 data[bytes + 1];
+ struct wcd9xxx_i2c *wcd9xxx;
+
+ wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
+ if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
+ pr_err("failed to get device info\n");
+ return -ENODEV;
+ }
+ reg_addr = (u8)reg;
+ msg = &wcd9xxx->xfer_msg[0];
+ msg->addr = wcd9xxx->client->addr;
+ msg->len = bytes + 1;
+ msg->flags = 0;
+ data[0] = reg;
+ data[1] = *value;
+ msg->buf = data;
+ ret = i2c_transfer(wcd9xxx->client->adapter, wcd9xxx->xfer_msg, 1);
+ /* Try again if the write fails */
+ if (ret != 1) {
+ ret = i2c_transfer(wcd9xxx->client->adapter,
+ wcd9xxx->xfer_msg, 1);
+ if (ret != 1) {
+ pr_err("failed to write the device\n");
+ return ret;
+ }
+ }
+ pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
+ return 0;
+}
+
+
+int wcd9xxx_i2c_read_device(unsigned short reg,
+ int bytes, unsigned char *dest)
+{
+ struct i2c_msg *msg;
+ int ret = 0;
+ u8 reg_addr = 0;
+ struct wcd9xxx_i2c *wcd9xxx;
+ u8 i = 0;
+
+ wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
+ if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
+ pr_err("failed to get device info\n");
+ return -ENODEV;
+ }
+ for (i = 0; i < bytes; i++) {
+ reg_addr = (u8)reg++;
+ msg = &wcd9xxx->xfer_msg[0];
+ msg->addr = wcd9xxx->client->addr;
+ msg->len = 1;
+ msg->flags = 0;
+ msg->buf = ®_addr;
+
+ msg = &wcd9xxx->xfer_msg[1];
+ msg->addr = wcd9xxx->client->addr;
+ msg->len = 1;
+ msg->flags = I2C_M_RD;
+ msg->buf = dest++;
+ ret = i2c_transfer(wcd9xxx->client->adapter,
+ wcd9xxx->xfer_msg, 2);
+
+ /* Try again if read fails first time */
+ if (ret != 2) {
+ ret = i2c_transfer(wcd9xxx->client->adapter,
+ wcd9xxx->xfer_msg, 2);
+ if (ret != 2) {
+ pr_err("failed to read wcd9xxx register\n");
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *dest, bool interface_reg)
+{
+ return wcd9xxx_i2c_read_device(reg, bytes, dest);
+}
+
+int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *src, bool interface_reg)
+{
+ return wcd9xxx_i2c_write_device(reg, src, bytes);
+}
+
+static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct wcd9xxx *wcd9xxx;
+ struct wcd9xxx_pdata *pdata = client->dev.platform_data;
+ int val = 0;
+ int ret = 0;
+ static int device_id;
+
+ if (device_id > 0) {
+ wcd9xxx_modules[device_id++].client = client;
+ pr_info("probe for other slaves devices of tabla\n");
+ return ret;
+ }
+
+ wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
+ if (wcd9xxx == NULL) {
+ pr_err("%s: error, allocation failed\n", __func__);
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ if (!pdata) {
+ dev_dbg(&client->dev, "no platform data?\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
+ dev_dbg(&client->dev, "can't talk I2C?\n");
+ ret = -EIO;
+ goto fail;
+ }
+ wcd9xxx->dev = &client->dev;
+ wcd9xxx->reset_gpio = pdata->reset_gpio;
+
+ ret = wcd9xxx_enable_supplies(wcd9xxx);
+ if (ret) {
+ pr_err("%s: Fail to enable Codec supplies\n", __func__);
+ goto err_codec;
+ }
+
+ usleep_range(5, 5);
+ ret = wcd9xxx_reset(wcd9xxx);
+ if (ret) {
+ pr_err("%s: Resetting Codec failed\n", __func__);
+ goto err_supplies;
+ }
+ wcd9xxx_modules[device_id++].client = client;
+
+ wcd9xxx->read_dev = wcd9xxx_i2c_read;
+ wcd9xxx->write_dev = wcd9xxx_i2c_write;
+ wcd9xxx->irq = pdata->irq;
+ wcd9xxx->irq_base = pdata->irq_base;
+
+ /*read the tabla status before initializing the device type*/
+ ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
+ if ((ret < 0) || (val != WCD9XXX_I2C_MODE)) {
+ pr_err("failed to read the wcd9xxx status\n");
+ goto err_device_init;
+ }
+
+ ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
+ if (ret) {
+ pr_err("%s: error, initializing device failed\n", __func__);
+ goto err_device_init;
+ }
+ wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
+
+ return ret;
+err_device_init:
+ wcd9xxx_free_reset(wcd9xxx);
+err_supplies:
+ wcd9xxx_disable_supplies(wcd9xxx);
+err_codec:
+ kfree(wcd9xxx);
+fail:
+ return ret;
+}
+
+static int __devexit wcd9xxx_i2c_remove(struct i2c_client *client)
+{
+ struct wcd9xxx *wcd9xxx;
+
+ pr_debug("exit\n");
+ wcd9xxx = dev_get_drvdata(&client->dev);
+ wcd9xxx_disable_supplies(wcd9xxx);
+ wcd9xxx_device_exit(wcd9xxx);
+ return 0;
+}
+
+static int wcd9xxx_slim_probe(struct slim_device *slim)
+{
+ struct wcd9xxx *wcd9xxx;
+ struct wcd9xxx_pdata *pdata;
+ int ret = 0;
+ int sgla_retry_cnt;
+
+ dev_info(&slim->dev, "Initialized slim device %s\n", slim->name);
+ pdata = slim->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&slim->dev, "Error, no platform data\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
+ if (wcd9xxx == NULL) {
+ pr_err("%s: error, allocation failed\n", __func__);
+ ret = -ENOMEM;
+ goto err;
+ }
+ if (!slim->ctrl) {
+ pr_err("Error, no SLIMBUS control data\n");
+ ret = -EINVAL;
+ goto err_codec;
+ }
+ wcd9xxx->slim = slim;
+ slim_set_clientdata(slim, wcd9xxx);
+ wcd9xxx->reset_gpio = pdata->reset_gpio;
+ wcd9xxx->dev = &slim->dev;
+
+ ret = wcd9xxx_enable_supplies(wcd9xxx);
+ if (ret)
+ goto err_codec;
+ usleep_range(5, 5);
+
+ ret = wcd9xxx_reset(wcd9xxx);
+ if (ret) {
+ pr_err("%s: Resetting Codec failed\n", __func__);
+ goto err_supplies;
+ }
+
+ ret = slim_get_logical_addr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
+ ARRAY_SIZE(wcd9xxx->slim->e_addr), &wcd9xxx->slim->laddr);
+ if (ret) {
+ pr_err("fail to get slimbus logical address %d\n", ret);
+ goto err_reset;
+ }
+ wcd9xxx->read_dev = wcd9xxx_slim_read_device;
+ wcd9xxx->write_dev = wcd9xxx_slim_write_device;
+ wcd9xxx->irq = pdata->irq;
+ wcd9xxx->irq_base = pdata->irq_base;
+ wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
+
+ if (pdata->num_irqs < TABLA_NUM_IRQS) {
+ pr_err("%s: Error, not enough interrupt lines allocated\n",
+ __func__);
+ goto err_reset;
+ }
+
+ wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
+
+ ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
+ if (ret) {
+ pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
+ goto err_reset;
+ }
+
+ sgla_retry_cnt = 0;
+
+ while (1) {
+ ret = slim_get_logical_addr(wcd9xxx->slim_slave,
+ wcd9xxx->slim_slave->e_addr,
+ ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
+ &wcd9xxx->slim_slave->laddr);
+ if (ret) {
+ if (sgla_retry_cnt++ < WCD9XXX_SLIM_GLA_MAX_RETRIES) {
+ /* Give SLIMBUS slave time to report present
+ and be ready.
+ */
+ usleep_range(1000, 1000);
+ pr_debug("%s: retry slim_get_logical_addr()\n",
+ __func__);
+ continue;
+ }
+ pr_err("fail to get slimbus slave logical address"
+ " %d\n", ret);
+ goto err_slim_add;
+ }
+ break;
+ }
+ wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
+ wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_SLIMBUS;
+
+ ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
+ if (ret) {
+ pr_err("%s: error, initializing device failed\n", __func__);
+ goto err_slim_add;
+ }
+/*
+ if (!strncmp(wcd9xxx->slim->name, "tabla", 5)) {
+ wcd9xxx->num_rx_port = 7;
+ wcd9xxx->num_tx_port = 10;
+ }
+*/
+ wcd9xxx_init_slimslave(wcd9xxx, wcd9xxx_pgd_la);
+#ifdef CONFIG_DEBUG_FS
+ debugCodec = wcd9xxx;
+
+ debugfs_wcd9xxx_dent = debugfs_create_dir
+ ("wcd9310_slimbus_interface_device", 0);
+ if (!IS_ERR(debugfs_wcd9xxx_dent)) {
+ debugfs_peek = debugfs_create_file("peek",
+ S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
+ (void *) "peek", &codec_debug_ops);
+
+ debugfs_poke = debugfs_create_file("poke",
+ S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
+ (void *) "poke", &codec_debug_ops);
+ }
+#endif
+
+ return ret;
+
+err_slim_add:
+ slim_remove_device(wcd9xxx->slim_slave);
+err_reset:
+ wcd9xxx_free_reset(wcd9xxx);
+err_supplies:
+ wcd9xxx_disable_supplies(wcd9xxx);
+err_codec:
+ kfree(wcd9xxx);
+err:
+ return ret;
+}
+static int wcd9xxx_slim_remove(struct slim_device *pdev)
+{
+ struct wcd9xxx *wcd9xxx;
+
+#ifdef CONFIG_DEBUG_FS
+ debugfs_remove(debugfs_peek);
+ debugfs_remove(debugfs_poke);
+ debugfs_remove(debugfs_wcd9xxx_dent);
+#endif
+ wcd9xxx = slim_get_devicedata(pdev);
+ wcd9xxx_deinit_slimslave(wcd9xxx);
+ slim_remove_device(wcd9xxx->slim_slave);
+ wcd9xxx_disable_supplies(wcd9xxx);
+ wcd9xxx_device_exit(wcd9xxx);
+ return 0;
+}
+
+static int wcd9xxx_resume(struct wcd9xxx *wcd9xxx)
+{
+ int ret = 0;
+
+ pr_debug("%s: enter\n", __func__);
+ mutex_lock(&wcd9xxx->pm_lock);
+ if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
+ pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
+ wcd9xxx->pm_state, wcd9xxx->wlock_holders);
+ wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
+ } else {
+ pr_warn("%s: system is already awake, state %d wlock %d\n",
+ __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
+ }
+ mutex_unlock(&wcd9xxx->pm_lock);
+ wake_up_all(&wcd9xxx->pm_wq);
+
+ return ret;
+}
+
+static int wcd9xxx_slim_resume(struct slim_device *sldev)
+{
+ struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
+ return wcd9xxx_resume(wcd9xxx);
+}
+
+static int wcd9xxx_i2c_resume(struct i2c_client *i2cdev)
+{
+ struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
+ return wcd9xxx_resume(wcd9xxx);
+}
+
+static int wcd9xxx_suspend(struct wcd9xxx *wcd9xxx, pm_message_t pmesg)
+{
+ int ret = 0;
+
+ pr_debug("%s: enter\n", __func__);
+ /* wake_lock() can be called after this suspend chain call started.
+ * thus suspend can be called while wlock is being held */
+ mutex_lock(&wcd9xxx->pm_lock);
+ if (wcd9xxx->pm_state == WCD9XXX_PM_SLEEPABLE) {
+ pr_debug("%s: suspending system, state %d, wlock %d\n",
+ __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
+ wcd9xxx->pm_state = WCD9XXX_PM_ASLEEP;
+ } else if (wcd9xxx->pm_state == WCD9XXX_PM_AWAKE) {
+ /* unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
+ * then set to WCD9XXX_PM_ASLEEP */
+ pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
+ __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
+ mutex_unlock(&wcd9xxx->pm_lock);
+ if (!(wait_event_timeout(wcd9xxx->pm_wq,
+ wcd9xxx_pm_cmpxchg(wcd9xxx,
+ WCD9XXX_PM_SLEEPABLE,
+ WCD9XXX_PM_ASLEEP) ==
+ WCD9XXX_PM_SLEEPABLE,
+ HZ))) {
+ pr_debug("%s: suspend failed state %d, wlock %d\n",
+ __func__, wcd9xxx->pm_state,
+ wcd9xxx->wlock_holders);
+ ret = -EBUSY;
+ } else {
+ pr_debug("%s: done, state %d, wlock %d\n", __func__,
+ wcd9xxx->pm_state, wcd9xxx->wlock_holders);
+ }
+ mutex_lock(&wcd9xxx->pm_lock);
+ } else if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
+ pr_warn("%s: system is already suspended, state %d, wlock %dn",
+ __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
+ }
+ mutex_unlock(&wcd9xxx->pm_lock);
+
+ return ret;
+}
+
+static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
+{
+ struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
+ return wcd9xxx_suspend(wcd9xxx, pmesg);
+}
+
+static int wcd9xxx_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
+{
+ struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
+ return wcd9xxx_suspend(wcd9xxx, pmesg);
+}
+
+static const struct slim_device_id slimtest_id[] = {
+ {"tabla-slim", 0},
+ {}
+};
+
+static struct slim_driver tabla_slim_driver = {
+ .driver = {
+ .name = "tabla-slim",
+ .owner = THIS_MODULE,
+ },
+ .probe = wcd9xxx_slim_probe,
+ .remove = wcd9xxx_slim_remove,
+ .id_table = slimtest_id,
+ .resume = wcd9xxx_slim_resume,
+ .suspend = wcd9xxx_slim_suspend,
+};
+
+static const struct slim_device_id slimtest2x_id[] = {
+ {"tabla2x-slim", 0},
+ {}
+};
+
+static struct slim_driver tabla2x_slim_driver = {
+ .driver = {
+ .name = "tabla2x-slim",
+ .owner = THIS_MODULE,
+ },
+ .probe = wcd9xxx_slim_probe,
+ .remove = wcd9xxx_slim_remove,
+ .id_table = slimtest2x_id,
+ .resume = wcd9xxx_slim_resume,
+ .suspend = wcd9xxx_slim_suspend,
+};
+
+#define TABLA_I2C_TOP_LEVEL 0
+#define TABLA_I2C_ANALOG 1
+#define TABLA_I2C_DIGITAL_1 2
+#define TABLA_I2C_DIGITAL_2 3
+
+static struct i2c_device_id tabla_id_table[] = {
+ {"tabla top level", TABLA_I2C_TOP_LEVEL},
+ {"tabla analog", TABLA_I2C_TOP_LEVEL},
+ {"tabla digital1", TABLA_I2C_TOP_LEVEL},
+ {"tabla digital2", TABLA_I2C_TOP_LEVEL},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, tabla_id_table);
+
+static struct i2c_driver tabla_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "tabla-i2c-core",
+ },
+ .id_table = tabla_id_table,
+ .probe = wcd9xxx_i2c_probe,
+ .remove = __devexit_p(wcd9xxx_i2c_remove),
+ .resume = wcd9xxx_i2c_resume,
+ .suspend = wcd9xxx_i2c_suspend,
+};
+
+static int __init wcd9xxx_init(void)
+{
+ int ret1, ret2, ret3;
+
+ ret1 = slim_driver_register(&tabla_slim_driver);
+ if (ret1 != 0)
+ pr_err("Failed to register tabla SB driver: %d\n", ret1);
+
+ ret2 = slim_driver_register(&tabla2x_slim_driver);
+ if (ret2 != 0)
+ pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
+
+ ret3 = i2c_add_driver(&tabla_i2c_driver);
+ if (ret3 != 0)
+ pr_err("failed to add the I2C driver\n");
+
+ return (ret1 && ret2 && ret3) ? -1 : 0;
+}
+module_init(wcd9xxx_init);
+
+static void __exit wcd9xxx_exit(void)
+{
+}
+module_exit(wcd9xxx_exit);
+
+MODULE_DESCRIPTION("Codec core driver");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
new file mode 100644
index 0000000..86c01ee
--- /dev/null
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -0,0 +1,286 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+#include <linux/mfd/wcd9xxx/wcd9310_registers.h>
+#include <linux/interrupt.h>
+
+#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE))
+#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
+
+struct wcd9xxx_irq {
+ bool level;
+};
+
+static struct wcd9xxx_irq wcd9xxx_irqs[TABLA_NUM_IRQS] = {
+ [0] = { .level = 1},
+/* All other wcd9xxx interrupts are edge triggered */
+};
+
+static inline int irq_to_wcd9xxx_irq(struct wcd9xxx *wcd9xxx, int irq)
+{
+ return irq - wcd9xxx->irq_base;
+}
+
+static void wcd9xxx_irq_lock(struct irq_data *data)
+{
+ struct wcd9xxx *wcd9xxx = irq_data_get_irq_chip_data(data);
+ mutex_lock(&wcd9xxx->irq_lock);
+}
+
+static void wcd9xxx_irq_sync_unlock(struct irq_data *data)
+{
+ struct wcd9xxx *wcd9xxx = irq_data_get_irq_chip_data(data);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(wcd9xxx->irq_masks_cur); i++) {
+ /* If there's been a change in the mask write it back
+ * to the hardware.
+ */
+ if (wcd9xxx->irq_masks_cur[i] != wcd9xxx->irq_masks_cache[i]) {
+ wcd9xxx->irq_masks_cache[i] = wcd9xxx->irq_masks_cur[i];
+ wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_MASK0+i,
+ wcd9xxx->irq_masks_cur[i]);
+ }
+ }
+
+ mutex_unlock(&wcd9xxx->irq_lock);
+}
+
+static void wcd9xxx_irq_enable(struct irq_data *data)
+{
+ struct wcd9xxx *wcd9xxx = irq_data_get_irq_chip_data(data);
+ int wcd9xxx_irq = irq_to_wcd9xxx_irq(wcd9xxx, data->irq);
+ wcd9xxx->irq_masks_cur[BIT_BYTE(wcd9xxx_irq)] &=
+ ~(BYTE_BIT_MASK(wcd9xxx_irq));
+}
+
+static void wcd9xxx_irq_disable(struct irq_data *data)
+{
+ struct wcd9xxx *wcd9xxx = irq_data_get_irq_chip_data(data);
+ int wcd9xxx_irq = irq_to_wcd9xxx_irq(wcd9xxx, data->irq);
+ wcd9xxx->irq_masks_cur[BIT_BYTE(wcd9xxx_irq)]
+ |= BYTE_BIT_MASK(wcd9xxx_irq);
+}
+
+static struct irq_chip wcd9xxx_irq_chip = {
+ .name = "wcd9xxx",
+ .irq_bus_lock = wcd9xxx_irq_lock,
+ .irq_bus_sync_unlock = wcd9xxx_irq_sync_unlock,
+ .irq_disable = wcd9xxx_irq_disable,
+ .irq_enable = wcd9xxx_irq_enable,
+};
+
+enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
+ enum wcd9xxx_pm_state o,
+ enum wcd9xxx_pm_state n)
+{
+ enum wcd9xxx_pm_state old;
+ mutex_lock(&wcd9xxx->pm_lock);
+ old = wcd9xxx->pm_state;
+ if (old == o)
+ wcd9xxx->pm_state = n;
+ mutex_unlock(&wcd9xxx->pm_lock);
+ return old;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_pm_cmpxchg);
+
+void wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx)
+{
+ enum wcd9xxx_pm_state os;
+
+ /* wcd9xxx_{lock/unlock}_sleep will be called by wcd9xxx_irq_thread
+ * and its subroutines only motly.
+ * but btn0_lpress_fn is not wcd9xxx_irq_thread's subroutine and
+ * it can race with wcd9xxx_irq_thread.
+ * so need to embrace wlock_holders with mutex.
+ */
+ mutex_lock(&wcd9xxx->pm_lock);
+ if (wcd9xxx->wlock_holders++ == 0)
+ wake_lock(&wcd9xxx->wlock);
+ mutex_unlock(&wcd9xxx->pm_lock);
+ while (!wait_event_timeout(wcd9xxx->pm_wq,
+ ((os = wcd9xxx_pm_cmpxchg(wcd9xxx, WCD9XXX_PM_SLEEPABLE,
+ WCD9XXX_PM_AWAKE)) ==
+ WCD9XXX_PM_SLEEPABLE ||
+ (os == WCD9XXX_PM_AWAKE)),
+ 5 * HZ)) {
+ pr_err("%s: system didn't resume within 5000ms, state %d, "
+ "wlock %d\n", __func__, wcd9xxx->pm_state,
+ wcd9xxx->wlock_holders);
+ WARN_ON_ONCE(1);
+ }
+ wake_up_all(&wcd9xxx->pm_wq);
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_lock_sleep);
+
+void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx)
+{
+ mutex_lock(&wcd9xxx->pm_lock);
+ if (--wcd9xxx->wlock_holders == 0) {
+ wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
+ wake_unlock(&wcd9xxx->wlock);
+ }
+ mutex_unlock(&wcd9xxx->pm_lock);
+ wake_up_all(&wcd9xxx->pm_wq);
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_unlock_sleep);
+
+static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
+{
+ int ret;
+ struct wcd9xxx *wcd9xxx = data;
+ u8 status[WCD9XXX_NUM_IRQ_REGS];
+ unsigned int i;
+
+ wcd9xxx_lock_sleep(wcd9xxx);
+ ret = wcd9xxx_bulk_read(wcd9xxx, TABLA_A_INTR_STATUS0,
+ WCD9XXX_NUM_IRQ_REGS, status);
+ if (ret < 0) {
+ dev_err(wcd9xxx->dev, "Failed to read interrupt status: %d\n",
+ ret);
+ wcd9xxx_unlock_sleep(wcd9xxx);
+ return IRQ_NONE;
+ }
+ /* Apply masking */
+ for (i = 0; i < WCD9XXX_NUM_IRQ_REGS; i++)
+ status[i] &= ~wcd9xxx->irq_masks_cur[i];
+
+ /* Find out which interrupt was triggered and call that interrupt's
+ * handler function
+ */
+ for (i = 0; i < TABLA_NUM_IRQS; i++) {
+ if (status[BIT_BYTE(i)] & BYTE_BIT_MASK(i)) {
+ if ((i <= TABLA_IRQ_MBHC_INSERTION) &&
+ (i >= TABLA_IRQ_MBHC_REMOVAL)) {
+ wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_CLEAR0 +
+ BIT_BYTE(i), BYTE_BIT_MASK(i));
+ if (wcd9xxx_get_intf_type() ==
+ WCD9XXX_INTERFACE_TYPE_I2C)
+ wcd9xxx_reg_write(wcd9xxx,
+ TABLA_A_INTR_MODE, 0x02);
+ handle_nested_irq(wcd9xxx->irq_base + i);
+ } else {
+ handle_nested_irq(wcd9xxx->irq_base + i);
+ wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_CLEAR0 +
+ BIT_BYTE(i), BYTE_BIT_MASK(i));
+ if (wcd9xxx_get_intf_type() ==
+ WCD9XXX_INTERFACE_TYPE_I2C)
+ wcd9xxx_reg_write(wcd9xxx,
+ TABLA_A_INTR_MODE, 0x02);
+ }
+ break;
+ }
+ }
+ wcd9xxx_unlock_sleep(wcd9xxx);
+
+ return IRQ_HANDLED;
+}
+
+int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx)
+{
+ int ret;
+ unsigned int i, cur_irq;
+
+ mutex_init(&wcd9xxx->irq_lock);
+
+ if (!wcd9xxx->irq) {
+ dev_warn(wcd9xxx->dev,
+ "No interrupt specified, no interrupts\n");
+ wcd9xxx->irq_base = 0;
+ return 0;
+ }
+
+ if (!wcd9xxx->irq_base) {
+ dev_err(wcd9xxx->dev,
+ "No interrupt base specified, no interrupts\n");
+ return 0;
+ }
+ /* Mask the individual interrupt sources */
+ for (i = 0, cur_irq = wcd9xxx->irq_base; i < TABLA_NUM_IRQS; i++,
+ cur_irq++) {
+
+ irq_set_chip_data(cur_irq, wcd9xxx);
+
+ if (wcd9xxx_irqs[i].level)
+ irq_set_chip_and_handler(cur_irq, &wcd9xxx_irq_chip,
+ handle_level_irq);
+ else
+ irq_set_chip_and_handler(cur_irq, &wcd9xxx_irq_chip,
+ handle_edge_irq);
+
+ irq_set_nested_thread(cur_irq, 1);
+
+ /* ARM needs us to explicitly flag the IRQ as valid
+ * and will set them noprobe when we do so. */
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ set_irq_noprobe(cur_irq);
+#endif
+
+ wcd9xxx->irq_masks_cur[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
+ wcd9xxx->irq_masks_cache[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
+ wcd9xxx->irq_level[BIT_BYTE(i)] |= wcd9xxx_irqs[i].level <<
+ (i % BITS_PER_BYTE);
+ }
+ for (i = 0; i < WCD9XXX_NUM_IRQ_REGS; i++) {
+ /* Initialize interrupt mask and level registers */
+ wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_LEVEL0 + i,
+ wcd9xxx->irq_level[i]);
+ wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_MASK0 + i,
+ wcd9xxx->irq_masks_cur[i]);
+ }
+
+ ret = request_threaded_irq(wcd9xxx->irq, NULL, wcd9xxx_irq_thread,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ "wcd9xxx", wcd9xxx);
+ if (ret != 0)
+ dev_err(wcd9xxx->dev, "Failed to request IRQ %d: %d\n",
+ wcd9xxx->irq, ret);
+ else {
+ ret = enable_irq_wake(wcd9xxx->irq);
+ if (ret == 0) {
+ ret = device_init_wakeup(wcd9xxx->dev, 1);
+ if (ret) {
+ dev_err(wcd9xxx->dev, "Failed to init device"
+ "wakeup : %d\n", ret);
+ disable_irq_wake(wcd9xxx->irq);
+ }
+ } else
+ dev_err(wcd9xxx->dev, "Failed to set wake interrupt on"
+ " IRQ %d: %d\n", wcd9xxx->irq, ret);
+ if (ret)
+ free_irq(wcd9xxx->irq, wcd9xxx);
+ }
+
+ if (ret)
+ mutex_destroy(&wcd9xxx->irq_lock);
+
+ return ret;
+}
+
+void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx)
+{
+ if (wcd9xxx->irq) {
+ disable_irq_wake(wcd9xxx->irq);
+ free_irq(wcd9xxx->irq, wcd9xxx);
+ device_init_wakeup(wcd9xxx->dev, 0);
+ }
+ mutex_destroy(&wcd9xxx->irq_lock);
+}
diff --git a/drivers/mfd/wcd9310-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
similarity index 72%
rename from drivers/mfd/wcd9310-slimslave.c
rename to drivers/mfd/wcd9xxx-slimslave.c
index 12ac27f..acef55e 100644
--- a/drivers/mfd/wcd9310-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -11,45 +11,47 @@
*/
#include <linux/slab.h>
#include <linux/mutex.h>
-#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
-struct tabla_slim_sch_rx {
+struct wcd9xxx_slim_sch_rx {
u32 sph;
u32 ch_num;
u16 ch_h;
u16 grph;
};
-struct tabla_slim_sch_tx {
+struct wcd9xxx_slim_sch_tx {
u32 sph;
u32 ch_num;
u16 ch_h;
u16 grph;
};
-struct tabla_slim_sch {
- struct tabla_slim_sch_rx rx[SLIM_MAX_RX_PORTS];
- struct tabla_slim_sch_tx tx[SLIM_MAX_TX_PORTS];
+struct wcd9xxx_slim_sch {
+ struct wcd9xxx_slim_sch_rx rx[SLIM_MAX_RX_PORTS];
+ struct wcd9xxx_slim_sch_tx tx[SLIM_MAX_TX_PORTS];
};
-static struct tabla_slim_sch sh_ch;
+static struct wcd9xxx_slim_sch sh_ch;
-static int tabla_alloc_slim_sh_ch_rx(struct tabla *tabla, u8 tabla_pgd_la);
-static int tabla_alloc_slim_sh_ch_tx(struct tabla *tabla, u8 tabla_pgd_la);
-static int tabla_dealloc_slim_sh_ch_rx(struct tabla *tab);
-static int tabla_dealloc_slim_sh_ch_tx(struct tabla *tab);
+static int wcd9xxx_alloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx,
+ u8 wcd9xxx_pgd_la);
+static int wcd9xxx_alloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx,
+ u8 wcd9xxx_pgd_la);
+static int wcd9xxx_dealloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx);
+static int wcd9xxx_dealloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx);
-int tabla_init_slimslave(struct tabla *tabla, u8 tabla_pgd_la)
+int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la)
{
int ret = 0;
- ret = tabla_alloc_slim_sh_ch_rx(tabla, tabla_pgd_la);
+ ret = wcd9xxx_alloc_slim_sh_ch_rx(wcd9xxx, wcd9xxx_pgd_la);
if (ret) {
pr_err("%s: Failed to alloc rx slimbus shared channels\n",
__func__);
goto rx_err;
}
- ret = tabla_alloc_slim_sh_ch_tx(tabla, tabla_pgd_la);
+ ret = wcd9xxx_alloc_slim_sh_ch_tx(wcd9xxx, wcd9xxx_pgd_la);
if (ret) {
pr_err("%s: Failed to alloc tx slimbus shared channels\n",
__func__);
@@ -57,21 +59,21 @@
}
return 0;
tx_err:
- tabla_dealloc_slim_sh_ch_rx(tabla);
+ wcd9xxx_dealloc_slim_sh_ch_rx(wcd9xxx);
rx_err:
return ret;
}
-int tabla_deinit_slimslave(struct tabla *tabla)
+int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx)
{
int ret = 0;
- ret = tabla_dealloc_slim_sh_ch_rx(tabla);
+ ret = wcd9xxx_dealloc_slim_sh_ch_rx(wcd9xxx);
if (ret < 0) {
pr_err("%s: fail to dealloc rx slim ports\n", __func__);
goto err;
}
- ret = tabla_dealloc_slim_sh_ch_tx(tabla);
+ ret = wcd9xxx_dealloc_slim_sh_ch_tx(wcd9xxx);
if (ret < 0) {
pr_err("%s: fail to dealloc tx slim ports\n", __func__);
goto err;
@@ -80,13 +82,13 @@
return ret;
}
-int tabla_get_channel(struct tabla *tabla,
+int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx,
unsigned int *rx_ch,
unsigned int *tx_ch)
{
int ch_idx = 0;
- struct tabla_slim_sch_rx *rx = sh_ch.rx;
- struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
+ struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++)
rx_ch[ch_idx] = rx[ch_idx].ch_num;
@@ -95,23 +97,23 @@
return 0;
}
-static int tabla_alloc_slim_sh_ch_rx(struct tabla *tabla, u8 tabla_pgd_la)
+static int wcd9xxx_alloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx,
+ u8 wcd9xxx_pgd_la)
{
int ret = 0;
u8 ch_idx ;
u16 slave_port_id = 0;
- struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
- /* DSP requires channel number to be between 128 and 255. For RX port
- * use channel numbers from 138 to 144, for TX port
- * use channel numbers from 128 to 137
+ /*
+ * DSP requires channel number to be between 128 and 255.
*/
- pr_debug("%s: pgd_la[%d]\n", __func__, tabla_pgd_la);
+ pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++) {
slave_port_id = (ch_idx + 1 +
SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS);
rx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
- ret = slim_get_slaveport(tabla_pgd_la, slave_port_id,
+ ret = slim_get_slaveport(wcd9xxx_pgd_la, slave_port_id,
&rx[ch_idx].sph, SLIM_SINK);
if (ret < 0) {
pr_err("%s: slave port failure id[%d] ret[%d]\n",
@@ -119,7 +121,7 @@
goto err;
}
- ret = slim_query_ch(tabla->slim, rx[ch_idx].ch_num,
+ ret = slim_query_ch(wcd9xxx->slim, rx[ch_idx].ch_num,
&rx[ch_idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
@@ -131,14 +133,15 @@
return ret;
}
-static int tabla_alloc_slim_sh_ch_tx(struct tabla *tabla, u8 tabla_pgd_la)
+static int wcd9xxx_alloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx,
+ u8 wcd9xxx_pgd_la)
{
int ret = 0;
u8 ch_idx ;
- struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
u16 slave_port_id = 0;
- pr_debug("%s: pgd_la[%d]\n", __func__, tabla_pgd_la);
+ pr_err("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
/* DSP requires channel number to be between 128 and 255. For RX port
* use channel numbers from 138 to 144, for TX port
* use channel numbers from 128 to 137
@@ -146,14 +149,14 @@
for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++) {
slave_port_id = ch_idx;
tx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
- ret = slim_get_slaveport(tabla_pgd_la, slave_port_id,
+ ret = slim_get_slaveport(wcd9xxx_pgd_la, slave_port_id,
&tx[ch_idx].sph, SLIM_SRC);
if (ret < 0) {
pr_err("%s: slave port failure id[%d] ret[%d]\n",
__func__, slave_port_id, ret);
goto err;
}
- ret = slim_query_ch(tabla->slim, tx[ch_idx].ch_num,
+ ret = slim_query_ch(wcd9xxx->slim, tx[ch_idx].ch_num,
&tx[ch_idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
@@ -165,14 +168,14 @@
return ret;
}
-static int tabla_dealloc_slim_sh_ch_rx(struct tabla *tab)
+static int wcd9xxx_dealloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx)
{
int idx = 0;
int ret = 0;
- struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
/* slim_dealloc_ch */
for (idx = 0; idx < SLIM_MAX_RX_PORTS; idx++) {
- ret = slim_dealloc_ch(tab->slim, rx[idx].ch_h);
+ ret = slim_dealloc_ch(wcd9xxx->slim, rx[idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
__func__, ret, rx[idx].ch_h);
@@ -182,14 +185,14 @@
return ret;
}
-static int tabla_dealloc_slim_sh_ch_tx(struct tabla *tab)
+static int wcd9xxx_dealloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx)
{
int idx = 0;
int ret = 0;
- struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
/* slim_dealloc_ch */
for (idx = 0; idx < SLIM_MAX_TX_PORTS; idx++) {
- ret = slim_dealloc_ch(tab->slim, tx[idx].ch_h);
+ ret = slim_dealloc_ch(wcd9xxx->slim, tx[idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
__func__, ret, tx[idx].ch_h);
@@ -200,7 +203,7 @@
}
/* Enable slimbus slave device for RX path */
-int tabla_cfg_slim_sch_rx(struct tabla *tab, unsigned int *ch_num,
+int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int ch_cnt, unsigned int rate)
{
u8 i = 0;
@@ -211,15 +214,15 @@
u8 payload_rx = 0, wm_payload = 0;
int ret, idx = 0;
unsigned short multi_chan_cfg_reg_addr;
- struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
struct slim_ch prop;
/* Configure slave interface device */
- pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
+ pr_err("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
for (i = 0; i < ch_cnt; i++) {
idx = (ch_num[i] - BASE_CH_NUM -
- SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
ch_h[i] = rx[idx].ch_h;
sph[i] = rx[idx].sph;
slave_port_id = idx + 1;
@@ -249,7 +252,8 @@
multi_chan_cfg_reg_addr =
SB_PGD_RX_PORT_MULTI_CHANNEL_0(slave_port_id);
/* write to interface device */
- ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+ ret = wcd9xxx_interface_reg_write(wcd9xxx,
+ multi_chan_cfg_reg_addr,
payload_rx);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
@@ -262,7 +266,7 @@
wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
SLAVE_PORT_WATER_MARK_SHIFT) +
SLAVE_PORT_ENABLE;
- ret = tabla_interface_reg_write(tab,
+ ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
wm_payload);
if (ret < 0) {
@@ -279,7 +283,7 @@
prop.ratem = (rate/4000);
prop.sampleszbits = 16;
- ret = slim_define_ch(tab->slim, &prop, ch_h, ch_cnt,
+ ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
true, &grph);
if (ret < 0) {
pr_err("%s: slim_define_ch failed ret[%d]\n",
@@ -287,7 +291,7 @@
goto err;
}
for (i = 0; i < ch_cnt; i++) {
- ret = slim_connect_sink(tab->slim, &sph[i],
+ ret = slim_connect_sink(wcd9xxx->slim, &sph[i],
1, ch_h[i]);
if (ret < 0) {
pr_err("%s: slim_connect_sink failed ret[%d]\n",
@@ -296,7 +300,7 @@
}
}
/* slim_control_ch */
- ret = slim_control_ch(tab->slim, grph, SLIM_CH_ACTIVATE,
+ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE,
true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
@@ -312,14 +316,14 @@
err_close_slim_sch:
/* release all acquired handles */
- tabla_close_slim_sch_rx(tab, ch_num, ch_cnt);
+ wcd9xxx_close_slim_sch_rx(wcd9xxx, ch_num, ch_cnt);
err:
return ret;
}
-EXPORT_SYMBOL_GPL(tabla_cfg_slim_sch_rx);
+EXPORT_SYMBOL_GPL(wcd9xxx_cfg_slim_sch_rx);
/* Enable slimbus slave device for RX path */
-int tabla_cfg_slim_sch_tx(struct tabla *tab, unsigned int *ch_num,
+int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int ch_cnt, unsigned int rate)
{
u8 i = 0;
@@ -331,7 +335,7 @@
int ret = 0;
unsigned short multi_chan_cfg_reg_addr;
- struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
struct slim_ch prop;
pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate);
@@ -366,7 +370,8 @@
multi_chan_cfg_reg_addr =
SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id);
/* write to interface device */
- ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+ ret = wcd9xxx_interface_reg_write(wcd9xxx,
+ multi_chan_cfg_reg_addr,
payload_tx_0);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
@@ -378,7 +383,8 @@
multi_chan_cfg_reg_addr =
SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id);
/* ports 8,9 */
- ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+ ret = wcd9xxx_interface_reg_write(wcd9xxx,
+ multi_chan_cfg_reg_addr,
payload_tx_1);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
@@ -391,7 +397,7 @@
wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
SLAVE_PORT_WATER_MARK_SHIFT) +
SLAVE_PORT_ENABLE;
- ret = tabla_interface_reg_write(tab,
+ ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
wm_payload);
if (ret < 0) {
@@ -408,7 +414,7 @@
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
prop.ratem = (rate/4000);
prop.sampleszbits = 16;
- ret = slim_define_ch(tab->slim, &prop, ch_h, ch_cnt,
+ ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
true, &grph);
if (ret < 0) {
pr_err("%s: slim_define_ch failed ret[%d]\n",
@@ -416,7 +422,7 @@
goto err;
}
for (i = 0; i < ch_cnt; i++) {
- ret = slim_connect_src(tab->slim, sph[i],
+ ret = slim_connect_src(wcd9xxx->slim, sph[i],
ch_h[i]);
if (ret < 0) {
pr_err("%s: slim_connect_src failed ret[%d]\n",
@@ -425,7 +431,7 @@
}
}
/* slim_control_ch */
- ret = slim_control_ch(tab->slim, grph, SLIM_CH_ACTIVATE,
+ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE,
true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
@@ -439,21 +445,21 @@
return 0;
err:
/* release all acquired handles */
- tabla_close_slim_sch_tx(tab, ch_num, ch_cnt);
+ wcd9xxx_close_slim_sch_tx(wcd9xxx, ch_num, ch_cnt);
return ret;
}
-EXPORT_SYMBOL_GPL(tabla_cfg_slim_sch_tx);
+EXPORT_SYMBOL_GPL(wcd9xxx_cfg_slim_sch_tx);
-int tabla_close_slim_sch_rx(struct tabla *tab, unsigned int *ch_num,
+int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int ch_cnt)
{
u16 grph = 0;
u32 sph[SLIM_MAX_RX_PORTS] = {0};
int i = 0 , idx = 0;
int ret = 0;
- struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
- pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+ pr_err("%s: ch_cnt[%d]\n", __func__, ch_cnt);
for (i = 0; i < ch_cnt; i++) {
idx = (ch_num[i] - BASE_CH_NUM -
SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
@@ -462,13 +468,13 @@
}
/* slim_disconnect_port */
- ret = slim_disconnect_ports(tab->slim, sph, ch_cnt);
+ ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
if (ret < 0) {
pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
__func__, ret);
}
/* slim_control_ch (REMOVE) */
- ret = slim_control_ch(tab->slim, grph, SLIM_CH_REMOVE, true);
+ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
@@ -482,31 +488,31 @@
err:
return ret;
}
-EXPORT_SYMBOL_GPL(tabla_close_slim_sch_rx);
+EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_rx);
-int tabla_close_slim_sch_tx(struct tabla *tab, unsigned int *ch_num,
+int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int ch_cnt)
{
u16 grph = 0;
u32 sph[SLIM_MAX_TX_PORTS] = {0};
int ret = 0;
int i = 0 , idx = 0;
- struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
- pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+ pr_err("%s: ch_cnt[%d]\n", __func__, ch_cnt);
for (i = 0; i < ch_cnt; i++) {
idx = (ch_num[i] - BASE_CH_NUM);
sph[i] = tx[idx].sph;
grph = tx[idx].grph;
}
/* slim_disconnect_port */
- ret = slim_disconnect_ports(tab->slim, sph, ch_cnt);
+ ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
if (ret < 0) {
pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
__func__, ret);
}
/* slim_control_ch (REMOVE) */
- ret = slim_control_ch(tab->slim, grph, SLIM_CH_REMOVE, true);
+ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
@@ -519,4 +525,4 @@
err:
return ret;
}
-EXPORT_SYMBOL_GPL(tabla_close_slim_sch_tx);
+EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_tx);
diff --git a/include/linux/mfd/Kbuild b/include/linux/mfd/Kbuild
index 1acc78f..bba647c 100644
--- a/include/linux/mfd/Kbuild
+++ b/include/linux/mfd/Kbuild
@@ -1,3 +1,3 @@
header-y += timpani-audio.h
header-y += msm-adie-codec.h
-header-y += wcd9310/
+header-y += wcd9xxx/
diff --git a/include/linux/mfd/wcd9310/Kbuild b/include/linux/mfd/wcd9310/Kbuild
deleted file mode 100644
index 2702ec6..0000000
--- a/include/linux/mfd/wcd9310/Kbuild
+++ /dev/null
@@ -1 +0,0 @@
-header-y += registers.h
diff --git a/include/linux/mfd/wcd9310/core.h b/include/linux/mfd/wcd9310/core.h
deleted file mode 100644
index 8605ac6..0000000
--- a/include/linux/mfd/wcd9310/core.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __MFD_TABLA_CORE_H__
-#define __MFD_TABLA_CORE_H__
-
-#include <linux/interrupt.h>
-#include <linux/wakelock.h>
-
-#define TABLA_NUM_IRQ_REGS 3
-
-#define TABLA_SLIM_NUM_PORT_REG 3
-
-#define TABLA_INTERFACE_TYPE_SLIMBUS 0x00
-#define TABLA_INTERFACE_TYPE_I2C 0x01
-
-#define TABLA_VERSION_1_0 0
-#define TABLA_VERSION_1_1 1
-#define TABLA_VERSION_2_0 2
-#define TABLA_IS_1_X(ver) \
- (((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0)
-#define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0)
-
-enum {
- TABLA_IRQ_SLIMBUS = 0,
- TABLA_IRQ_MBHC_REMOVAL,
- TABLA_IRQ_MBHC_SHORT_TERM,
- TABLA_IRQ_MBHC_PRESS,
- TABLA_IRQ_MBHC_RELEASE,
- TABLA_IRQ_MBHC_POTENTIAL,
- TABLA_IRQ_MBHC_INSERTION,
- TABLA_IRQ_BG_PRECHARGE,
- TABLA_IRQ_PA1_STARTUP,
- TABLA_IRQ_PA2_STARTUP,
- TABLA_IRQ_PA3_STARTUP,
- TABLA_IRQ_PA4_STARTUP,
- TABLA_IRQ_PA5_STARTUP,
- TABLA_IRQ_MICBIAS1_PRECHARGE,
- TABLA_IRQ_MICBIAS2_PRECHARGE,
- TABLA_IRQ_MICBIAS3_PRECHARGE,
- TABLA_IRQ_HPH_PA_OCPL_FAULT,
- TABLA_IRQ_HPH_PA_OCPR_FAULT,
- TABLA_IRQ_EAR_PA_OCPL_FAULT,
- TABLA_IRQ_HPH_L_PA_STARTUP,
- TABLA_IRQ_HPH_R_PA_STARTUP,
- TABLA_IRQ_EAR_PA_STARTUP,
- TABLA_NUM_IRQS,
-};
-
-enum tabla_pm_state {
- TABLA_PM_SLEEPABLE,
- TABLA_PM_AWAKE,
- TABLA_PM_ASLEEP,
-};
-
-struct tabla {
- struct device *dev;
- struct slim_device *slim;
- struct slim_device *slim_slave;
- struct mutex io_lock;
- struct mutex xfer_lock;
- struct mutex irq_lock;
- u8 version;
-
- unsigned int irq_base;
- unsigned int irq;
- u8 irq_masks_cur[TABLA_NUM_IRQ_REGS];
- u8 irq_masks_cache[TABLA_NUM_IRQ_REGS];
- u8 irq_level[TABLA_NUM_IRQ_REGS];
-
- int reset_gpio;
-
- int (*read_dev)(struct tabla *tabla, unsigned short reg,
- int bytes, void *dest, bool interface_reg);
- int (*write_dev)(struct tabla *tabla, unsigned short reg,
- int bytes, void *src, bool interface_reg);
-
- struct regulator_bulk_data *supplies;
-
- enum tabla_pm_state pm_state;
- struct mutex pm_lock;
- /* pm_wq notifies change of pm_state */
- wait_queue_head_t pm_wq;
- struct wake_lock wlock;
- int wlock_holders;
-};
-
-int tabla_reg_read(struct tabla *tabla, unsigned short reg);
-int tabla_reg_write(struct tabla *tabla, unsigned short reg, u8 val);
-int tabla_interface_reg_read(struct tabla *tabla, unsigned short reg);
-int tabla_interface_reg_write(struct tabla *tabla, unsigned short reg, u8 val);
-int tabla_bulk_read(struct tabla *tabla, unsigned short reg, int count,
- u8 *buf);
-int tabla_bulk_write(struct tabla *tabla, unsigned short reg, int count,
- u8 *buf);
-int tabla_irq_init(struct tabla *tabla);
-void tabla_irq_exit(struct tabla *tabla);
-int tabla_get_logical_addresses(u8 *pgd_la, u8 *inf_la);
-int tabla_get_intf_type(void);
-
-void tabla_lock_sleep(struct tabla *tabla);
-void tabla_unlock_sleep(struct tabla *tabla);
-enum tabla_pm_state tabla_pm_cmpxchg(struct tabla *tabla, enum tabla_pm_state o,
- enum tabla_pm_state n);
-
-static inline int tabla_request_irq(struct tabla *tabla, int irq,
- irq_handler_t handler, const char *name,
- void *data)
-{
- if (!tabla->irq_base)
- return -EINVAL;
- return request_threaded_irq(tabla->irq_base + irq, NULL, handler,
- IRQF_TRIGGER_RISING, name,
- data);
-}
-static inline void tabla_free_irq(struct tabla *tabla, int irq, void *data)
-{
- if (!tabla->irq_base)
- return;
- free_irq(tabla->irq_base + irq, data);
-}
-static inline void tabla_enable_irq(struct tabla *tabla, int irq)
-{
- if (!tabla->irq_base)
- return;
- enable_irq(tabla->irq_base + irq);
-}
-static inline void tabla_disable_irq(struct tabla *tabla, int irq)
-{
- if (!tabla->irq_base)
- return;
- disable_irq_nosync(tabla->irq_base + irq);
-}
-
-#endif
diff --git a/include/linux/mfd/wcd9xxx/Kbuild b/include/linux/mfd/wcd9xxx/Kbuild
new file mode 100644
index 0000000..acfab6e
--- /dev/null
+++ b/include/linux/mfd/wcd9xxx/Kbuild
@@ -0,0 +1,2 @@
+header-y += wcd9xxx_registers.h
+header-y += wcd9310_registers.h
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
new file mode 100644
index 0000000..0d99e37
--- /dev/null
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -0,0 +1,177 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MFD_TABLA_CORE_H__
+#define __MFD_TABLA_CORE_H__
+
+#include <linux/interrupt.h>
+#include <linux/wakelock.h>
+
+#define WCD9XXX_NUM_IRQ_REGS 3
+
+#define WCD9XXX_SLIM_NUM_PORT_REG 3
+
+#define WCD9XXX_INTERFACE_TYPE_SLIMBUS 0x00
+#define WCD9XXX_INTERFACE_TYPE_I2C 0x01
+
+#define TABLA_VERSION_1_0 0
+#define TABLA_VERSION_1_1 1
+#define TABLA_VERSION_2_0 2
+#define TABLA_IS_1_X(ver) \
+ (((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0)
+#define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0)
+
+enum {
+ TABLA_IRQ_SLIMBUS = 0,
+ TABLA_IRQ_MBHC_REMOVAL,
+ TABLA_IRQ_MBHC_SHORT_TERM,
+ TABLA_IRQ_MBHC_PRESS,
+ TABLA_IRQ_MBHC_RELEASE,
+ TABLA_IRQ_MBHC_POTENTIAL,
+ TABLA_IRQ_MBHC_INSERTION,
+ TABLA_IRQ_BG_PRECHARGE,
+ TABLA_IRQ_PA1_STARTUP,
+ TABLA_IRQ_PA2_STARTUP,
+ TABLA_IRQ_PA3_STARTUP,
+ TABLA_IRQ_PA4_STARTUP,
+ TABLA_IRQ_PA5_STARTUP,
+ TABLA_IRQ_MICBIAS1_PRECHARGE,
+ TABLA_IRQ_MICBIAS2_PRECHARGE,
+ TABLA_IRQ_MICBIAS3_PRECHARGE,
+ TABLA_IRQ_HPH_PA_OCPL_FAULT,
+ TABLA_IRQ_HPH_PA_OCPR_FAULT,
+ TABLA_IRQ_EAR_PA_OCPL_FAULT,
+ TABLA_IRQ_HPH_L_PA_STARTUP,
+ TABLA_IRQ_HPH_R_PA_STARTUP,
+ TABLA_IRQ_EAR_PA_STARTUP,
+ TABLA_NUM_IRQS,
+};
+
+enum {
+ SITAR_IRQ_SLIMBUS = 0,
+ SITAR_IRQ_MBHC_REMOVAL,
+ SITAR_IRQ_MBHC_SHORT_TERM,
+ SITAR_IRQ_MBHC_PRESS,
+ SITAR_IRQ_MBHC_RELEASE,
+ SITAR_IRQ_MBHC_POTENTIAL,
+ SITAR_IRQ_MBHC_INSERTION,
+ SITAR_IRQ_BG_PRECHARGE,
+ SITAR_IRQ_PA1_STARTUP,
+ SITAR_IRQ_PA2_STARTUP,
+ SITAR_IRQ_PA3_STARTUP,
+ SITAR_IRQ_PA4_STARTUP,
+ SITAR_IRQ_PA5_STARTUP,
+ SITAR_IRQ_MICBIAS1_PRECHARGE,
+ SITAR_IRQ_MICBIAS2_PRECHARGE,
+ SITAR_IRQ_MICBIAS3_PRECHARGE,
+ SITAR_IRQ_HPH_PA_OCPL_FAULT,
+ SITAR_IRQ_HPH_PA_OCPR_FAULT,
+ SITAR_IRQ_EAR_PA_OCPL_FAULT,
+ SITAR_IRQ_HPH_L_PA_STARTUP,
+ SITAR_IRQ_HPH_R_PA_STARTUP,
+ SITAR_IRQ_EAR_PA_STARTUP,
+ SITAR_NUM_IRQS,
+};
+
+
+enum wcd9xxx_pm_state {
+ WCD9XXX_PM_SLEEPABLE,
+ WCD9XXX_PM_AWAKE,
+ WCD9XXX_PM_ASLEEP,
+};
+
+struct wcd9xxx {
+ struct device *dev;
+ struct slim_device *slim;
+ struct slim_device *slim_slave;
+ struct mutex io_lock;
+ struct mutex xfer_lock;
+ struct mutex irq_lock;
+ u8 version;
+
+ unsigned int irq_base;
+ unsigned int irq;
+ u8 irq_masks_cur[WCD9XXX_NUM_IRQ_REGS];
+ u8 irq_masks_cache[WCD9XXX_NUM_IRQ_REGS];
+ u8 irq_level[WCD9XXX_NUM_IRQ_REGS];
+
+ int reset_gpio;
+
+ int (*read_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *dest, bool interface_reg);
+ int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int bytes, void *src, bool interface_reg);
+
+ struct regulator_bulk_data *supplies;
+
+ enum wcd9xxx_pm_state pm_state;
+ struct mutex pm_lock;
+ /* pm_wq notifies change of pm_state */
+ wait_queue_head_t pm_wq;
+ struct wake_lock wlock;
+ int wlock_holders;
+ int num_rx_port;
+ int num_tx_port;
+};
+
+int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
+int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ u8 val);
+int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
+int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ u8 val);
+int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int count, u8 *buf);
+int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
+ int count, u8 *buf);
+int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx);
+void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx);
+int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la);
+int wcd9xxx_get_intf_type(void);
+
+void wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
+void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
+enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
+ enum wcd9xxx_pm_state o,
+ enum wcd9xxx_pm_state n);
+
+static inline int wcd9xxx_request_irq(struct wcd9xxx *wcd9xxx, int irq,
+ irq_handler_t handler, const char *name,
+ void *data)
+{
+ if (!wcd9xxx->irq_base)
+ return -EINVAL;
+ return request_threaded_irq(wcd9xxx->irq_base + irq, NULL, handler,
+ IRQF_TRIGGER_RISING, name,
+ data);
+}
+static inline void wcd9xxx_free_irq(struct wcd9xxx *wcd9xxx,
+ int irq, void *data)
+{
+ if (!wcd9xxx->irq_base)
+ return;
+ free_irq(wcd9xxx->irq_base + irq, data);
+}
+static inline void wcd9xxx_enable_irq(struct wcd9xxx *wcd9xxx, int irq)
+{
+ if (!wcd9xxx->irq_base)
+ return;
+ enable_irq(wcd9xxx->irq_base + irq);
+}
+static inline void wcd9xxx_disable_irq(struct wcd9xxx *wcd9xxx, int irq)
+{
+ if (!wcd9xxx->irq_base)
+ return;
+ disable_irq_nosync(wcd9xxx->irq_base + irq);
+}
+
+#endif
diff --git a/include/linux/mfd/wcd9310/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
similarity index 71%
rename from include/linux/mfd/wcd9310/pdata.h
rename to include/linux/mfd/wcd9xxx/pdata.h
index af801f0..db76294 100644
--- a/include/linux/mfd/wcd9310/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.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
@@ -16,6 +16,15 @@
#include <linux/slimbus/slimbus.h>
+#define SITAR_LDOH_1P95_V 0x0
+#define SITAR_LDOH_2P35_V 0x1
+#define SITAR_LDOH_2P75_V 0x2
+#define SITAR_LDOH_2P85_V 0x3
+
+#define SITAR_CFILT1_SEL 0x0
+#define SITAR_CFILT2_SEL 0x1
+#define SITAR_CFILT3_SEL 0x2
+
#define TABLA_LDOH_1P95_V 0x0
#define TABLA_LDOH_2P35_V 0x1
#define TABLA_LDOH_2P75_V 0x2
@@ -51,7 +60,7 @@
#define TABLA_DCYCLE_3839 0xE
#define TABLA_DCYCLE_4095 0xF
-struct tabla_amic {
+struct wcd9xxx_amic {
/*legacy mode, txfe_enable and txfe_buff take 7 input
* each bit represent the channel / TXFE number
* and numbered as below
@@ -75,7 +84,7 @@
* If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv
*/
-struct tabla_micbias_setting {
+struct wcd9xxx_micbias_setting {
u8 ldoh_v;
u32 cfilt1_mv; /* in mv */
u32 cfilt2_mv; /* in mv */
@@ -86,7 +95,7 @@
u8 bias4_cfilt_sel;
};
-struct tabla_ocp_setting {
+struct wcd9xxx_ocp_setting {
unsigned int use_pdata:1; /* 0 - use sys default as recommended */
unsigned int num_attempts:4; /* up to 15 attempts */
unsigned int run_time:4; /* in duty cycle */
@@ -94,15 +103,39 @@
unsigned int hph_ocp_limit:3; /* Headphone OCP current limit */
};
-struct tabla_pdata {
+#define MAX_REGULATOR 6
+/*
+ * format : TABLA_<POWER_SUPPLY_PIN_NAME>_CUR_MAX
+ *
+ * <POWER_SUPPLY_PIN_NAME> from Tabla objective spec
+*/
+
+#define WCD9XXX_CDC_VDDA_CP_CUR_MAX 500000
+#define WCD9XXX_CDC_VDDA_RX_CUR_MAX 20000
+#define WCD9XXX_CDC_VDDA_TX_CUR_MAX 20000
+#define WCD9XXX_VDDIO_CDC_CUR_MAX 5000
+
+#define WCD9XXX_VDDD_CDC_D_CUR_MAX 5000
+#define WCD9XXX_VDDD_CDC_A_CUR_MAX 5000
+
+struct wcd9xxx_regulator {
+ const char *name;
+ int min_uV;
+ int max_uV;
+ int optimum_uA;
+ struct regulator *regulator;
+};
+
+struct wcd9xxx_pdata {
int irq;
int irq_base;
int num_irqs;
int reset_gpio;
- struct tabla_amic amic_settings;
+ struct wcd9xxx_amic amic_settings;
struct slim_device slimbus_slave_device;
- struct tabla_micbias_setting micbias;
- struct tabla_ocp_setting ocp;
+ struct wcd9xxx_micbias_setting micbias;
+ struct wcd9xxx_ocp_setting ocp;
+ struct wcd9xxx_regulator regulator[MAX_REGULATOR];
};
#endif
diff --git a/include/linux/mfd/wcd9310/registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
similarity index 95%
rename from include/linux/mfd/wcd9310/registers.h
rename to include/linux/mfd/wcd9xxx/wcd9310_registers.h
index ef27c08..d2736ea 100644
--- a/include/linux/mfd/wcd9310/registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
@@ -1,29 +1,41 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
#ifndef TABLA_CODEC_DIGITAL_H
#define TABLA_CODEC_DIGITAL_H
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
-#define TABLA_A_CHIP_CTL (0x00)
-#define TABLA_A_CHIP_CTL__POR (0x00000000)
-#define TABLA_A_CHIP_STATUS (0x01)
-#define TABLA_A_CHIP_STATUS__POR (0x00000000)
-#define TABLA_A_CHIP_ID_BYTE_0 (0x04)
-#define TABLA_A_CHIP_ID_BYTE_0__POR (0x00000000)
-#define TABLA_A_CHIP_ID_BYTE_1 (0x05)
-#define TABLA_A_CHIP_ID_BYTE_1__POR (0x00000000)
-#define TABLA_A_CHIP_ID_BYTE_2 (0x06)
-#define TABLA_A_CHIP_ID_BYTE_2__POR (0x00000000)
-#define TABLA_A_CHIP_ID_BYTE_3 (0x07)
-#define TABLA_A_CHIP_ID_BYTE_3__POR (0x00000001)
-#define TABLA_A_CHIP_VERSION (0x08)
-#define TABLA_A_CHIP_VERSION__POR (0x00000020)
-#define TABLA_A_SB_VERSION (0x09)
-#define TABLA_A_SB_VERSION__POR (0x00000010)
-#define TABLA_A_SLAVE_ID_1 (0x0C)
-#define TABLA_A_SLAVE_ID_1__POR (0x00000077)
-#define TABLA_A_SLAVE_ID_2 (0x0D)
-#define TABLA_A_SLAVE_ID_2__POR (0x00000066)
-#define TABLA_A_SLAVE_ID_3 (0x0E)
-#define TABLA_A_SLAVE_ID_3__POR (0x00000055)
+#define TABLA_A_CHIP_CTL WCD9XXX_A_CHIP_CTL
+#define TABLA_A_CHIP_CTL__POR WCD9XXX_A_CHIP_CTL__POR
+#define TABLA_A_CHIP_STATUS WCD9XXX_A_CHIP_STATUS
+#define TABLA_A_CHIP_STATUS__POR WCD9XXX_A_CHIP_STATUS__POR
+#define TABLA_A_CHIP_ID_BYTE_0 WCD9XXX_A_CHIP_ID_BYTE_0
+#define TABLA_A_CHIP_ID_BYTE_0__POR WCD9XXX_A_CHIP_ID_BYTE_0__POR
+#define TABLA_A_CHIP_ID_BYTE_1 WCD9XXX_A_CHIP_ID_BYTE_1
+#define TABLA_A_CHIP_ID_BYTE_1__POR WCD9XXX_A_CHIP_ID_BYTE_1__POR
+#define TABLA_A_CHIP_ID_BYTE_2 WCD9XXX_A_CHIP_ID_BYTE_2
+#define TABLA_A_CHIP_ID_BYTE_2__POR WCD9XXX_A_CHIP_ID_BYTE_2__POR
+#define TABLA_A_CHIP_ID_BYTE_3 WCD9XXX_A_CHIP_ID_BYTE_3
+#define TABLA_A_CHIP_ID_BYTE_3__POR WCD9XXX_A_CHIP_ID_BYTE_3__POR
+#define TABLA_A_CHIP_VERSION WCD9XXX_A_CHIP_VERSION
+#define TABLA_A_CHIP_VERSION__POR WCD9XXX_A_CHIP_VERSION__POR
+#define TABLA_A_SB_VERSION WCD9XXX_A_SB_VERSION
+#define TABLA_A_SB_VERSION__POR WCD9XXX_A_SB_VERSION__POR
+#define TABLA_A_SLAVE_ID_1 WCD9XXX_A_SLAVE_ID_1
+#define TABLA_A_SLAVE_ID_1__POR WCD9XXX_A_SLAVE_ID_1__POR
+#define TABLA_A_SLAVE_ID_2 WCD9XXX_A_SLAVE_ID_2
+#define TABLA_A_SLAVE_ID_2__POR WCD9XXX_A_SLAVE_ID_2__POR
+#define TABLA_A_SLAVE_ID_3 WCD9XXX_A_SLAVE_ID_3
+#define TABLA_A_SLAVE_ID_3__POR WCD9XXX_A_SLAVE_ID_3__POR
#define TABLA_A_PIN_CTL_OE0 (0x10)
#define TABLA_A_PIN_CTL_OE0__POR (0x00000000)
#define TABLA_A_PIN_CTL_OE1 (0x11)
@@ -58,10 +70,10 @@
#define TABLA_A_QFUSE_DATA_OUT2__POR (0x00000000)
#define TABLA_A_QFUSE_DATA_OUT3 (0x4D)
#define TABLA_A_QFUSE_DATA_OUT3__POR (0x00000000)
-#define TABLA_A_CDC_CTL (0x80)
-#define TABLA_A_CDC_CTL__POR (0x00000000)
-#define TABLA_A_LEAKAGE_CTL (0x88)
-#define TABLA_A_LEAKAGE_CTL__POR (0x00000004)
+#define TABLA_A_CDC_CTL WCD9XXX_A_CDC_CTL
+#define TABLA_A_CDC_CTL__POR WCD9XXX_A_CDC_CTL__POR
+#define TABLA_A_LEAKAGE_CTL WCD9XXX_A_LEAKAGE_CTL
+#define TABLA_A_LEAKAGE_CTL__POR WCD9XXX_A_LEAKAGE_CTL__POR
#define TABLA_A_INTR_MODE (0x90)
#define TABLA_A_INTR_MODE__POR (0x00000000)
#define TABLA_A_INTR_MASK0 (0x94)
diff --git a/include/linux/mfd/wcd9310/wcd9310-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
similarity index 84%
rename from include/linux/mfd/wcd9310/wcd9310-slimslave.h
rename to include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
index 0bbf96f..fcd3bd3 100644
--- a/include/linux/mfd/wcd9310/wcd9310-slimslave.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
@@ -14,7 +14,7 @@
#define __WCD9310_SLIMSLAVE_H_
#include <linux/slimbus/slimbus.h>
-#include <linux/mfd/wcd9310/core.h>
+#include <linux/mfd/wcd9xxx/core.h>
/* Local to the core only */
#define SLIM_MAX_RX_PORTS 7
@@ -84,19 +84,19 @@
#define BASE_CH_NUM 128
-int tabla_init_slimslave(struct tabla *tabla, u8 tabla_pgd_la);
+int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la);
-int tabla_deinit_slimslave(struct tabla *tabla);
+int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx);
-int tabla_cfg_slim_sch_rx(struct tabla *tabla, unsigned int *ch_num,
+int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int tot_ch, unsigned int rate);
-int tabla_cfg_slim_sch_tx(struct tabla *tabla, unsigned int *ch_num,
+int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int tot_ch, unsigned int rate);
-int tabla_close_slim_sch_rx(struct tabla *tabla, unsigned int *ch_num,
+int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int tot_ch);
-int tabla_close_slim_sch_tx(struct tabla *tabla, unsigned int *ch_num,
+int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
unsigned int tot_ch);
-int tabla_get_channel(struct tabla *tabla,
+int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx,
unsigned int *rx_ch,
unsigned int *tx_ch);
#endif /* __WCD9310_SLIMSLAVE_H_ */
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
new file mode 100644
index 0000000..c66e953
--- /dev/null
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef WCD9XXX_CODEC_DIGITAL_H
+
+#define WCD9XXX_CODEC_DIGITAL_H
+
+#define WCD9XXX_A_CHIP_CTL (0x00)
+#define WCD9XXX_A_CHIP_CTL__POR (0x00000000)
+#define WCD9XXX_A_CHIP_STATUS (0x01)
+#define WCD9XXX_A_CHIP_STATUS__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_0 (0x04)
+#define WCD9XXX_A_CHIP_ID_BYTE_0__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_1 (0x05)
+#define WCD9XXX_A_CHIP_ID_BYTE_1__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_2 (0x06)
+#define WCD9XXX_A_CHIP_ID_BYTE_2__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_3 (0x07)
+#define WCD9XXX_A_CHIP_ID_BYTE_3__POR (0x00000001)
+#define WCD9XXX_A_CHIP_VERSION (0x08)
+#define WCD9XXX_A_CHIP_VERSION__POR (0x00000020)
+#define WCD9XXX_A_SB_VERSION (0x09)
+#define WCD9XXX_A_SB_VERSION__POR (0x00000010)
+#define WCD9XXX_A_SLAVE_ID_1 (0x0C)
+#define WCD9XXX_A_SLAVE_ID_1__POR (0x00000077)
+#define WCD9XXX_A_SLAVE_ID_2 (0x0D)
+#define WCD9XXX_A_SLAVE_ID_2__POR (0x00000066)
+#define WCD9XXX_A_SLAVE_ID_3 (0x0E)
+#define WCD9XXX_A_SLAVE_ID_3__POR (0x00000055)
+#define WCD9XXX_A_CDC_CTL (0x80)
+#define WCD9XXX_A_CDC_CTL__POR (0x00000000)
+#define WCD9XXX_A_LEAKAGE_CTL (0x88)
+#define WCD9XXX_A_LEAKAGE_CTL__POR (0x00000004)
+#endif
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index c681771..e0ad541 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -10,7 +10,7 @@
* GNU General Public License for more details.
*/
-#include <linux/mfd/wcd9310/registers.h>
+#include <linux/mfd/wcd9xxx/wcd9310_registers.h>
#include "wcd9310.h"
const u8 tabla_reg_readable[TABLA_CACHE_SIZE] = {
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 46f6461..a5427ed 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -18,9 +18,10 @@
#include <linux/printk.h>
#include <linux/ratelimit.h>
#include <linux/debugfs.h>
-#include <linux/mfd/wcd9310/core.h>
-#include <linux/mfd/wcd9310/registers.h>
-#include <linux/mfd/wcd9310/pdata.h>
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+#include <linux/mfd/wcd9xxx/wcd9310_registers.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -171,7 +172,7 @@
struct snd_soc_jack *headset_jack;
struct snd_soc_jack *button_jack;
- struct tabla_pdata *pdata;
+ struct wcd9xxx_pdata *pdata;
u32 anc_slot;
bool no_mic_headset_override;
@@ -1319,10 +1320,12 @@
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
snd_soc_write(codec, TABLA_A_MBHC_SCALING_MUX_1, 0x84);
- tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
+ wcd9xxx_enable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
if (!tabla->no_mic_headset_override) {
- tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
- tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
+ wcd9xxx_enable_irq(codec->control_data,
+ TABLA_IRQ_MBHC_POTENTIAL);
+ wcd9xxx_enable_irq(codec->control_data,
+ TABLA_IRQ_MBHC_RELEASE);
} else {
tabla_codec_disable_button_presses(codec);
}
@@ -1336,11 +1339,12 @@
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
if (!tabla->no_mic_headset_override) {
- tabla_disable_irq(codec->control_data,
+ wcd9xxx_disable_irq(codec->control_data,
TABLA_IRQ_MBHC_POTENTIAL);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
+ wcd9xxx_disable_irq(codec->control_data,
+ TABLA_IRQ_MBHC_RELEASE);
}
}
@@ -1767,7 +1771,7 @@
tabla->hphlocp_cnt = 0;
else
tabla->hphrocp_cnt = 0;
- tabla_enable_irq(codec->control_data, irq);
+ wcd9xxx_enable_irq(codec->control_data, irq);
} else {
pr_err("%s: Bad tabla private data\n", __func__);
}
@@ -1925,16 +1929,16 @@
static const struct snd_soc_dapm_widget tabla_1_x_dapm_widgets[] = {
SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_1_A_MICB_4_CTL, 7,
- 0, tabla_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
+ 0, tabla_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_widget tabla_2_higher_dapm_widgets[] = {
SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_2_A_MICB_4_CTL, 7,
- 0, tabla_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
+ 0, tabla_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route audio_i2s_map[] = {
@@ -2284,7 +2288,7 @@
static int tabla_readable(struct snd_soc_codec *ssc, unsigned int reg)
{
int i;
- struct tabla *tabla_core = dev_get_drvdata(ssc->dev->parent);
+ struct wcd9xxx *tabla_core = dev_get_drvdata(ssc->dev->parent);
if (TABLA_IS_1_X(tabla_core->version)) {
for (i = 0; i < ARRAY_SIZE(tabla_1_reg_readable); i++) {
@@ -2333,7 +2337,7 @@
reg, ret);
}
- return tabla_reg_write(codec->control_data, reg, value);
+ return wcd9xxx_reg_write(codec->control_data, reg, value);
}
static unsigned int tabla_read(struct snd_soc_codec *codec,
unsigned int reg)
@@ -2353,7 +2357,7 @@
reg, ret);
}
- val = tabla_reg_read(codec->control_data, reg);
+ val = wcd9xxx_reg_read(codec->control_data, reg);
return val;
}
@@ -2622,7 +2626,7 @@
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
/* CPU is master */
- if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
+ if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
if (dai->id == AIF1_CAP)
snd_soc_update_bits(dai->codec,
TABLA_A_CDC_CLK_TX_I2S_CTL,
@@ -2635,7 +2639,7 @@
break;
case SND_SOC_DAIFMT_CBM_CFM:
/* CPU is slave */
- if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
+ if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
val = TABLA_I2S_MASTER_MODE_MASK;
if (dai->id == AIF1_CAP)
snd_soc_update_bits(dai->codec,
@@ -2685,7 +2689,7 @@
unsigned int *rx_num, unsigned int *rx_slot)
{
- struct tabla *tabla = dev_get_drvdata(dai->codec->control_data);
+ struct wcd9xxx *tabla = dev_get_drvdata(dai->codec->control_data);
u32 cnt = 0;
u32 tx_ch[SLIM_MAX_TX_PORTS];
@@ -2699,7 +2703,7 @@
/* for virtual port, codec driver needs to do
* housekeeping, for now should be ok
*/
- tabla_get_channel(tabla, rx_ch, tx_ch);
+ wcd9xxx_get_channel(tabla, rx_ch, tx_ch);
if (dai->id == AIF1_PB) {
*rx_num = tabla_dai[dai->id - 1].playback.channels_max;
while (cnt < *rx_num) {
@@ -2784,7 +2788,7 @@
0x03, tx_fs_rate);
}
}
- if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
+ if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
snd_soc_update_bits(codec,
@@ -2830,7 +2834,7 @@
0xE0, rx_fs_rate);
}
}
- if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
+ if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
snd_soc_update_bits(codec,
@@ -2945,7 +2949,7 @@
static int tabla_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- struct tabla *tabla;
+ struct wcd9xxx *tabla;
struct snd_soc_codec *codec = w->codec;
struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
u32 j = 0;
@@ -2953,7 +2957,7 @@
codec->control_data = dev_get_drvdata(codec->dev->parent);
tabla = codec->control_data;
/* Execute the callback only if interface type is slimbus */
- if (tabla_p->intf_type != TABLA_INTERFACE_TYPE_SLIMBUS)
+ if (tabla_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
return 0;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@@ -2967,10 +2971,10 @@
}
}
if (tabla_p->dai[j].ch_act == tabla_p->dai[j].ch_tot)
- ret = tabla_cfg_slim_sch_rx(tabla,
- tabla_p->dai[j].ch_num,
- tabla_p->dai[j].ch_tot,
- tabla_p->dai[j].rate);
+ ret = wcd9xxx_cfg_slim_sch_rx(tabla,
+ tabla_p->dai[j].ch_num,
+ tabla_p->dai[j].ch_tot,
+ tabla_p->dai[j].rate);
break;
case SND_SOC_DAPM_POST_PMD:
for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
@@ -2983,12 +2987,12 @@
}
}
if (!tabla_p->dai[j].ch_act) {
- ret = tabla_close_slim_sch_rx(tabla,
+ ret = wcd9xxx_close_slim_sch_rx(tabla,
tabla_p->dai[j].ch_num,
tabla_p->dai[j].ch_tot);
tabla_p->dai[j].rate = 0;
memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
- tabla_p->dai[j].ch_tot));
+ tabla_p->dai[j].ch_tot));
tabla_p->dai[j].ch_tot = 0;
}
}
@@ -2998,7 +3002,7 @@
static int tabla_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- struct tabla *tabla;
+ struct wcd9xxx *tabla;
struct snd_soc_codec *codec = w->codec;
struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
/* index to the DAI ID, for now hardcoding */
@@ -3009,7 +3013,7 @@
tabla = codec->control_data;
/* Execute the callback only if interface type is slimbus */
- if (tabla_p->intf_type != TABLA_INTERFACE_TYPE_SLIMBUS)
+ if (tabla_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
return 0;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@@ -3024,7 +3028,7 @@
}
}
if (tabla_p->dai[j].ch_act == tabla_p->dai[j].ch_tot)
- ret = tabla_cfg_slim_sch_tx(tabla,
+ ret = wcd9xxx_cfg_slim_sch_tx(tabla,
tabla_p->dai[j].ch_num,
tabla_p->dai[j].ch_tot,
tabla_p->dai[j].rate);
@@ -3041,12 +3045,12 @@
}
}
if (!tabla_p->dai[j].ch_act) {
- ret = tabla_close_slim_sch_tx(tabla,
+ ret = wcd9xxx_close_slim_sch_tx(tabla,
tabla_p->dai[j].ch_num,
tabla_p->dai[j].ch_tot);
tabla_p->dai[j].rate = 0;
memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
- tabla_p->dai[j].ch_tot));
+ tabla_p->dai[j].ch_tot));
tabla_p->dai[j].ch_tot = 0;
}
}
@@ -3584,7 +3588,7 @@
snd_soc_update_bits(codec, tabla->reg_addr.micb_4_mbhc, 0x3,
tabla->micbias);
- tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
+ wcd9xxx_enable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x1, 0x1);
return 0;
}
@@ -3655,10 +3659,10 @@
if (tabla->button_jack) {
bias_value = tabla_codec_read_sta_result(tabla->codec);
sta_mv = tabla_codec_sta_dce_v(tabla->codec, 0,
- bias_value);
+ bias_value);
bias_value = tabla_codec_read_dce_result(tabla->codec);
dce_mv = tabla_codec_sta_dce_v(tabla->codec, 1,
- bias_value);
+ bias_value);
pr_debug("%s: Reporting long button press event"
" STA: %d, DCE: %d\n", __func__,
sta_mv, dce_mv);
@@ -3670,7 +3674,6 @@
pr_err("%s: Bad tabla private data\n", __func__);
}
- tabla_unlock_sleep(core);
}
void tabla_mbhc_cal(struct snd_soc_codec *codec)
@@ -3850,7 +3853,7 @@
struct tabla_mbhc_btn_detect_cfg *btn_det;
int n;
u8 *n_cic, *gain;
- struct tabla *tabla_core = dev_get_drvdata(codec->dev->parent);
+ struct wcd9xxx *tabla_core = dev_get_drvdata(codec->dev->parent);
tabla = snd_soc_codec_get_drvdata(codec);
generic = TABLA_MBHC_CAL_GENERAL_PTR(tabla->calibration);
@@ -3998,7 +4001,7 @@
if (mclk_rate != TABLA_MCLK_RATE_12288KHZ) {
if (mclk_rate == TABLA_MCLK_RATE_9600KHZ)
pr_err("Error: clock rate %dHz is not yet supported\n",
- mclk_rate);
+ mclk_rate);
else
pr_err("Error: unsupported clock rate %d\n", mclk_rate);
return -EINVAL;
@@ -4037,9 +4040,9 @@
if (!IS_ERR_VALUE(rc)) {
snd_soc_update_bits(codec, TABLA_A_RX_HPH_OCP_CTL, 0x10,
0x10);
- tabla_enable_irq(codec->control_data,
+ wcd9xxx_enable_irq(codec->control_data,
TABLA_IRQ_HPH_PA_OCPL_FAULT);
- tabla_enable_irq(codec->control_data,
+ wcd9xxx_enable_irq(codec->control_data,
TABLA_IRQ_HPH_PA_OCPR_FAULT);
}
@@ -4057,7 +4060,7 @@
btn_det = TABLA_MBHC_CAL_BTN_DET_PTR(priv->calibration);
v_btn_low = tabla_mbhc_cal_btn_det_mp(btn_det, TABLA_BTN_DET_V_BTN_LOW);
v_btn_high = tabla_mbhc_cal_btn_det_mp(btn_det,
- TABLA_BTN_DET_V_BTN_HIGH);
+ TABLA_BTN_DET_V_BTN_HIGH);
for (i = 0; i < btn_det->num_btn; i++) {
if ((v_btn_low[i] <= bias_mv) && (v_btn_high[i] >= bias_mv)) {
btn = i;
@@ -4115,10 +4118,10 @@
TABLA_MBHC_CAL_BTN_DET_PTR(priv->calibration);
short btnmeas[d->n_btn_meas + 1];
struct snd_soc_codec *codec = priv->codec;
- struct tabla *core = dev_get_drvdata(priv->codec->dev->parent);
+ struct wcd9xxx *core = dev_get_drvdata(priv->codec->dev->parent);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
bias_value_dce = tabla_codec_read_dce_result(codec);
bias_mv_dce = tabla_codec_sta_dce_v(codec, 1, bias_value_dce);
@@ -4164,12 +4167,12 @@
/* XXX: assuming button 0 has the lowest micbias voltage */
if (btn == 0) {
- tabla_lock_sleep(core);
+ wcd9xxx_lock_sleep(core);
if (schedule_delayed_work(&priv->btn0_dwork,
msecs_to_jiffies(400)) == 0) {
WARN(1, "Button pressed twice without release"
"event\n");
- tabla_unlock_sleep(core);
+ wcd9xxx_unlock_sleep(core);
}
} else {
pr_debug("%s: Reporting short button %d(0x%x) press\n",
@@ -4191,10 +4194,10 @@
short mb_v;
struct tabla_priv *priv = data;
struct snd_soc_codec *codec = priv->codec;
- struct tabla *core = dev_get_drvdata(priv->codec->dev->parent);
+ struct wcd9xxx *core = dev_get_drvdata(priv->codec->dev->parent);
pr_debug("%s: enter\n", __func__);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
if (priv->buttons_pressed & SND_JACK_BTN_0) {
ret = cancel_delayed_work(&priv->btn0_dwork);
@@ -4208,7 +4211,7 @@
} else {
/* if scheduled btn0_dwork is canceled from here,
* we have to unlock from here instead btn0_work */
- tabla_unlock_sleep(core);
+ wcd9xxx_unlock_sleep(core);
mb_v = tabla_codec_sta_dce(codec, 0);
pr_debug("%s: Mic Voltage on release STA: %d,%d\n",
__func__, mb_v,
@@ -4304,7 +4307,7 @@
snd_soc_update_bits(codec, TABLA_A_RX_HPH_OCP_CTL, 0x10,
0x10);
} else {
- tabla_disable_irq(codec->control_data,
+ wcd9xxx_disable_irq(codec->control_data,
TABLA_IRQ_HPH_PA_OCPL_FAULT);
tabla->hphlocp_cnt = 0;
tabla->hph_status |= SND_JACK_OC_HPHL;
@@ -4337,7 +4340,7 @@
snd_soc_update_bits(codec, TABLA_A_RX_HPH_OCP_CTL, 0x10,
0x10);
} else {
- tabla_disable_irq(codec->control_data,
+ wcd9xxx_disable_irq(codec->control_data,
TABLA_IRQ_HPH_PA_OCPR_FAULT);
tabla->hphrocp_cnt = 0;
tabla->hph_status |= SND_JACK_OC_HPHR;
@@ -4357,26 +4360,26 @@
static void tabla_sync_hph_state(struct tabla_priv *tabla)
{
if (test_and_clear_bit(TABLA_HPHR_PA_OFF_ACK,
- &tabla->hph_pa_dac_state)) {
+ &tabla->hph_pa_dac_state)) {
pr_debug("%s: HPHR clear flag and enable PA\n", __func__);
snd_soc_update_bits(tabla->codec, TABLA_A_RX_HPH_CNP_EN, 0x10,
1 << 4);
}
if (test_and_clear_bit(TABLA_HPHL_PA_OFF_ACK,
- &tabla->hph_pa_dac_state)) {
+ &tabla->hph_pa_dac_state)) {
pr_debug("%s: HPHL clear flag and enable PA\n", __func__);
snd_soc_update_bits(tabla->codec, TABLA_A_RX_HPH_CNP_EN, 0x20,
1 << 5);
}
if (test_and_clear_bit(TABLA_HPHR_DAC_OFF_ACK,
- &tabla->hph_pa_dac_state)) {
+ &tabla->hph_pa_dac_state)) {
pr_debug("%s: HPHR clear flag and enable DAC\n", __func__);
snd_soc_update_bits(tabla->codec, TABLA_A_RX_HPH_R_DAC_CTL,
0xC0, 0xC0);
}
if (test_and_clear_bit(TABLA_HPHL_DAC_OFF_ACK,
- &tabla->hph_pa_dac_state)) {
+ &tabla->hph_pa_dac_state)) {
pr_debug("%s: HPHL clear flag and enable DAC\n", __func__);
snd_soc_update_bits(tabla->codec, TABLA_A_RX_HPH_L_DAC_CTL,
0xC0, 0xC0);
@@ -4395,7 +4398,7 @@
int mic_mv;
pr_debug("%s: enter\n", __func__);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
is_removal = snd_soc_read(codec, TABLA_A_CDC_MBHC_INT_CTL) & 0x02;
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x03, 0x00);
@@ -4406,7 +4409,7 @@
if (priv->mbhc_fake_ins_start &&
time_after(jiffies, priv->mbhc_fake_ins_start +
- msecs_to_jiffies(TABLA_FAKE_INS_THRESHOLD_MS))) {
+ msecs_to_jiffies(TABLA_FAKE_INS_THRESHOLD_MS))) {
pr_debug("%s: fake context interrupt, reset insertion\n",
__func__);
priv->mbhc_fake_ins_start = 0;
@@ -4482,8 +4485,8 @@
0),
mb_v, mic_mv);
if (time_after(jiffies,
- priv->mbhc_fake_ins_start +
- msecs_to_jiffies(TABLA_FAKE_INS_THRESHOLD_MS))) {
+ priv->mbhc_fake_ins_start +
+ msecs_to_jiffies(TABLA_FAKE_INS_THRESHOLD_MS))) {
/* Disable HPH trigger and enable MIC line trigger */
snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x12,
0x00);
@@ -4509,7 +4512,8 @@
}
/* Setup for insertion detection */
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x2, 0);
- tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
+ wcd9xxx_enable_irq(codec->control_data,
+ TABLA_IRQ_MBHC_INSERTION);
snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x1, 0x1);
} else if (mb_v < (short) priv->mbhc_data.v_no_mic) {
@@ -4559,9 +4563,9 @@
int min_us = TABLA_FAKE_REMOVAL_MIN_PERIOD_MS * 1000;
pr_debug("%s: enter, removal interrupt\n", __func__);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
usleep_range(generic->t_shutdown_plug_rem,
generic->t_shutdown_plug_rem);
@@ -4611,11 +4615,11 @@
int i, j;
u8 val;
- for (i = 0; i < TABLA_SLIM_NUM_PORT_REG; i++) {
- slimbus_value = tabla_interface_reg_read(codec->control_data,
+ for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) {
+ slimbus_value = wcd9xxx_interface_reg_read(codec->control_data,
TABLA_SLIM_PGD_PORT_INT_STATUS0 + i);
for_each_set_bit(j, &slimbus_value, BITS_PER_BYTE) {
- val = tabla_interface_reg_read(codec->control_data,
+ val = wcd9xxx_interface_reg_read(codec->control_data,
TABLA_SLIM_PGD_PORT_INT_SOURCE0 + i*8 + j);
if (val & 0x1)
pr_err_ratelimited("overflow error on port %x,"
@@ -4624,7 +4628,7 @@
pr_err_ratelimited("underflow error on port %x,"
" value %x\n", i*8 + j, val);
}
- tabla_interface_reg_write(codec->control_data,
+ wcd9xxx_interface_reg_write(codec->control_data,
TABLA_SLIM_PGD_PORT_INT_CLR0 + i, 0xFF);
}
@@ -4635,7 +4639,7 @@
static int tabla_handle_pdata(struct tabla_priv *tabla)
{
struct snd_soc_codec *codec = tabla->codec;
- struct tabla_pdata *pdata = tabla->pdata;
+ struct wcd9xxx_pdata *pdata = tabla->pdata;
int k1, k2, k3, rc = 0;
u8 leg_mode = pdata->amic_settings.legacy_mode;
u8 txfe_bypass = pdata->amic_settings.txfe_enable;
@@ -4802,7 +4806,7 @@
static void tabla_update_reg_defaults(struct snd_soc_codec *codec)
{
u32 i;
- struct tabla *tabla_core = dev_get_drvdata(codec->dev->parent);
+ struct wcd9xxx *tabla_core = dev_get_drvdata(codec->dev->parent);
for (i = 0; i < ARRAY_SIZE(tabla_1_1_reg_defaults); i++)
snd_soc_write(codec, tabla_1_1_reg_defaults[i].reg,
@@ -4894,7 +4898,7 @@
static void tabla_codec_init_reg(struct snd_soc_codec *codec)
{
u32 i;
- struct tabla *tabla_core = dev_get_drvdata(codec->dev->parent);
+ struct wcd9xxx *tabla_core = dev_get_drvdata(codec->dev->parent);
for (i = 0; i < ARRAY_SIZE(tabla_codec_reg_init_val); i++)
snd_soc_update_bits(codec, tabla_codec_reg_init_val[i].reg,
@@ -4918,7 +4922,7 @@
static void tabla_update_reg_address(struct tabla_priv *priv)
{
- struct tabla *tabla_core = dev_get_drvdata(priv->codec->dev->parent);
+ struct wcd9xxx *tabla_core = dev_get_drvdata(priv->codec->dev->parent);
struct tabla_reg_address *reg_addr = &priv->reg_addr;
if (TABLA_IS_1_X(tabla_core->version)) {
@@ -4934,7 +4938,7 @@
static int tabla_codec_probe(struct snd_soc_codec *codec)
{
- struct tabla *control;
+ struct wcd9xxx *control;
struct tabla_priv *tabla;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
@@ -4973,7 +4977,7 @@
tabla->no_mic_headset_override = false;
tabla->codec = codec;
tabla->pdata = dev_get_platdata(codec->dev->parent);
- tabla->intf_type = tabla_get_intf_type();
+ tabla->intf_type = wcd9xxx_get_intf_type();
tabla_update_reg_address(tabla);
tabla_update_reg_defaults(codec);
@@ -5002,7 +5006,7 @@
snd_soc_dapm_new_controls(dapm, tabla_2_higher_dapm_widgets,
ARRAY_SIZE(tabla_2_higher_dapm_widgets));
- if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
+ if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
snd_soc_dapm_new_controls(dapm, tabla_dapm_i2s_widgets,
ARRAY_SIZE(tabla_dapm_i2s_widgets));
snd_soc_dapm_add_routes(dapm, audio_i2s_map,
@@ -5018,49 +5022,49 @@
ARRAY_SIZE(tabla_2_x_lineout_2_to_4_map));
} else {
pr_err("%s : ERROR. Unsupported Tabla version 0x%2x\n",
- __func__, control->version);
+ __func__, control->version);
goto err_pdata;
}
snd_soc_dapm_sync(dapm);
- ret = tabla_request_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION,
+ ret = wcd9xxx_request_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION,
tabla_hs_insert_irq, "Headset insert detect", tabla);
if (ret) {
pr_err("%s: Failed to request irq %d\n", __func__,
TABLA_IRQ_MBHC_INSERTION);
goto err_insert_irq;
}
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
- ret = tabla_request_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL,
+ ret = wcd9xxx_request_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL,
tabla_hs_remove_irq, "Headset remove detect", tabla);
if (ret) {
pr_err("%s: Failed to request irq %d\n", __func__,
TABLA_IRQ_MBHC_REMOVAL);
goto err_remove_irq;
}
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL);
- ret = tabla_request_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL,
+ ret = wcd9xxx_request_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL,
tabla_dce_handler, "DC Estimation detect", tabla);
if (ret) {
pr_err("%s: Failed to request irq %d\n", __func__,
TABLA_IRQ_MBHC_POTENTIAL);
goto err_potential_irq;
}
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL);
- ret = tabla_request_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE,
+ ret = wcd9xxx_request_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE,
tabla_release_handler, "Button Release detect", tabla);
if (ret) {
pr_err("%s: Failed to request irq %d\n", __func__,
TABLA_IRQ_MBHC_RELEASE);
goto err_release_irq;
}
- tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE);
- ret = tabla_request_irq(codec->control_data, TABLA_IRQ_SLIMBUS,
+ ret = wcd9xxx_request_irq(codec->control_data, TABLA_IRQ_SLIMBUS,
tabla_slimbus_irq, "SLIMBUS Slave", tabla);
if (ret) {
pr_err("%s: Failed to request irq %d\n", __func__,
@@ -5068,11 +5072,11 @@
goto err_slimbus_irq;
}
- for (i = 0; i < TABLA_SLIM_NUM_PORT_REG; i++)
- tabla_interface_reg_write(codec->control_data,
+ for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
+ wcd9xxx_interface_reg_write(codec->control_data,
TABLA_SLIM_PGD_PORT_INT_EN0 + i, 0xFF);
- ret = tabla_request_irq(codec->control_data,
+ ret = wcd9xxx_request_irq(codec->control_data,
TABLA_IRQ_HPH_PA_OCPL_FAULT, tabla_hphl_ocp_irq,
"HPH_L OCP detect", tabla);
if (ret) {
@@ -5080,9 +5084,9 @@
TABLA_IRQ_HPH_PA_OCPL_FAULT);
goto err_hphl_ocp_irq;
}
- tabla_disable_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPL_FAULT);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPL_FAULT);
- ret = tabla_request_irq(codec->control_data,
+ ret = wcd9xxx_request_irq(codec->control_data,
TABLA_IRQ_HPH_PA_OCPR_FAULT, tabla_hphr_ocp_irq,
"HPH_R OCP detect", tabla);
if (ret) {
@@ -5090,7 +5094,7 @@
TABLA_IRQ_HPH_PA_OCPR_FAULT);
goto err_hphr_ocp_irq;
}
- tabla_disable_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPR_FAULT);
+ wcd9xxx_disable_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPR_FAULT);
for (i = 0; i < ARRAY_SIZE(tabla_dai); i++) {
switch (tabla_dai[i].id) {
case AIF1_PB:
@@ -5116,17 +5120,18 @@
return ret;
err_hphr_ocp_irq:
- tabla_free_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPL_FAULT, tabla);
+ wcd9xxx_free_irq(codec->control_data,
+ TABLA_IRQ_HPH_PA_OCPL_FAULT, tabla);
err_hphl_ocp_irq:
- tabla_free_irq(codec->control_data, TABLA_IRQ_SLIMBUS, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_SLIMBUS, tabla);
err_slimbus_irq:
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE, tabla);
err_release_irq:
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL, tabla);
err_potential_irq:
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL, tabla);
err_remove_irq:
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
err_insert_irq:
err_pdata:
kfree(tabla);
@@ -5136,11 +5141,11 @@
{
int i;
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
- tabla_free_irq(codec->control_data, TABLA_IRQ_SLIMBUS, tabla);
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE, tabla);
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL, tabla);
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL, tabla);
- tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_SLIMBUS, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_POTENTIAL, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_REMOVAL, tabla);
+ wcd9xxx_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
tabla_codec_disable_clock_block(codec);
tabla_codec_enable_bandgap(codec, TABLA_BANDGAP_OFF);
if (tabla->mbhc_fw)
@@ -5227,10 +5232,10 @@
S_IFREG | S_IRUGO, NULL, (void *) "TRRS", &codec_debug_ops);
#endif
- if (tabla_get_intf_type() == TABLA_INTERFACE_TYPE_SLIMBUS)
+ if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tabla,
tabla_dai, ARRAY_SIZE(tabla_dai));
- else if (tabla_get_intf_type() == TABLA_INTERFACE_TYPE_I2C)
+ else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tabla,
tabla_i2s_dai, ARRAY_SIZE(tabla_i2s_dai));
return ret;
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 9c430b9..d1d0c17 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -11,7 +11,7 @@
*/
#include <sound/soc.h>
#include <sound/jack.h>
-#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
#define TABLA_NUM_REGISTERS 0x400
#define TABLA_MAX_REGISTER (TABLA_NUM_REGISTERS-1)
diff --git a/sound/soc/msm/msm-dai-q6-hdmi.c b/sound/soc/msm/msm-dai-q6-hdmi.c
index 6907ded..3333344 100644
--- a/sound/soc/msm/msm-dai-q6-hdmi.c
+++ b/sound/soc/msm/msm-dai-q6-hdmi.c
@@ -14,10 +14,8 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <linux/mfd/wcd9310/core.h>
#include <linux/bitops.h>
#include <linux/slab.h>
-#include <linux/clk.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
@@ -25,7 +23,6 @@
#include <sound/q6afe.h>
#include <sound/q6adm.h>
#include <sound/msm-dai-q6.h>
-#include <mach/clk.h>
#include <mach/msm_hdmi_audio.h>
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 070dc7b..0430f7b 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -14,7 +14,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <linux/mfd/wcd9310/core.h>
+#include <linux/mfd/wcd9xxx/core.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/clk.h>