Revert "[ARM] tegra: stingray: cpcap-audio: integrate Motorola's driver"
authorRebecca Schultz Zavin <rebecca@android.com>
Fri, 3 Sep 2010 08:27:24 +0000 (01:27 -0700)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:50:51 +0000 (16:50 -0700)
This reverts commit f01ee18d3d1f7e03216b652a04ba82161fd069aa.

arch/arm/mach-tegra/board-stingray.c
arch/arm/mach-tegra/include/mach/cpcap_audio.h
drivers/mfd/Makefile
drivers/mfd/cpcap-audio-core.c [deleted file]
drivers/mfd/cpcap-audio.c [new file with mode: 0644]
drivers/mfd/tegra-cpcap-audio.c [deleted file]
include/linux/cpcap_audio.h

index e3df31d80653daaba02acdbfbab711e6849a2484..8c501fef27733f491aeaf30398587a7f76faaf17 100644 (file)
@@ -229,38 +229,88 @@ static struct platform_device cpcap_otg = {
        .num_resources = ARRAY_SIZE(cpcap_otg_resources),
 };
 
-static struct cpcap_audio_state stingray_cpcap_audio_state = {
-       NULL,
-       CPCAP_AUDIO_MODE_NORMAL,
-       CPCAP_AUDIO_CODEC_OFF,
-       CPCAP_AUDIO_CODEC_RATE_8000_HZ,
-       CPCAP_AUDIO_CODEC_MUTE,
-       CPCAP_AUDIO_STDAC_OFF,
-       CPCAP_AUDIO_STDAC_RATE_44100_HZ,
-       CPCAP_AUDIO_STDAC_MUTE,
-       CPCAP_AUDIO_ANALOG_SOURCE_OFF,
-       CPCAP_AUDIO_OUT_NONE,
-       CPCAP_AUDIO_OUT_NONE,
-       CPCAP_AUDIO_OUT_LINEOUT,
-       CPCAP_AUDIO_OUT_LINEOUT,
-       CPCAP_AUDIO_OUT_NONE,
-       CPCAP_AUDIO_OUT_NONE,
-       CPCAP_AUDIO_BALANCE_NEUTRAL,
-       CPCAP_AUDIO_BALANCE_NEUTRAL,
-       CPCAP_AUDIO_BALANCE_NEUTRAL,
-       7,                      /*default output gain */
-       CPCAP_AUDIO_IN_NONE,
-       31,                     /*default input_gain */
-       CPCAP_AUDIO_RAT_NONE
+#define CPCAP_REG(r, v, m) { .reg = (r), .val = (v), .mask = (m) }
+#define CPCAP_REG_SLAVE(r, v, m, s) { .reg = (r), .val = (v), \
+                                       .mask = (m), .slave_or = (s) }
+
+static const struct cpcap_audio_config_table speaker_config_table[] = {
+       CPCAP_REG(CPCAP_REG_VAUDIOC, 0x0007, 0x77),             /* 512 */
+       CPCAP_REG(CPCAP_REG_CC, 0x8E93, 0xFEDF),                /* 513 */
+       CPCAP_REG(CPCAP_REG_CDI, 0x1E42, 0xBFFF),               /* 514 */
+       CPCAP_REG(CPCAP_REG_SDAC, 0x0079, 0xFFF),               /* 515 */
+       CPCAP_REG_SLAVE(CPCAP_REG_SDACDI, 0x003E, 0x3FFF, 1),   /* 516 */
+       CPCAP_REG(CPCAP_REG_RXOA, 0x0218, 0x07FF),              /* 519 */
+       CPCAP_REG(CPCAP_REG_RXVC, 0x0028, 0x003C),              /* 520 */
+       CPCAP_REG(CPCAP_REG_RXCOA, 0x0618, 0x07FF),             /* 521 */
+       CPCAP_REG(CPCAP_REG_RXSDOA, 0x1818, 0x1FFF),            /* 522 */
+};
+
+static const struct cpcap_audio_config_table headset_config_table[] = {
+       CPCAP_REG(CPCAP_REG_VAUDIOC, 0x0007, 0x0077),           /* 512 */
+       CPCAP_REG(CPCAP_REG_CC, 0x8000, 0xFEDF),                /* 513 */
+       CPCAP_REG(CPCAP_REG_CDI, 0x8607, 0xBFFF),               /* 514 */
+       CPCAP_REG(CPCAP_REG_SDAC, 0x0079, 0xFFF),               /* 515 */
+       CPCAP_REG_SLAVE(CPCAP_REG_SDACDI, 0x003E, 0x3FFF, 1),   /* 516 */
+       CPCAP_REG(CPCAP_REG_RXOA, 0x0262, 0x07FF),              /* 519 */
+       CPCAP_REG(CPCAP_REG_RXVC, 0x0030, 0x003C),              /* 520 */
+       CPCAP_REG(CPCAP_REG_RXCOA, 0x0000, 0x07FF),             /* 521 */
+       CPCAP_REG(CPCAP_REG_RXSDOA, 0x1862, 0x1FFF),            /* 522 */
+};
+
+static const struct cpcap_audio_config_table mic1_config_table[] = {
+       CPCAP_REG(CPCAP_REG_VAUDIOC, 0x0035, 0x77),             /* 512 */
+       CPCAP_REG(CPCAP_REG_CC, 0x8F11, 0xFE11),                /* 513 */
+       CPCAP_REG(CPCAP_REG_CDI, 0x9E42, 0xBFFF),               /* 514 */
+       CPCAP_REG_SLAVE(CPCAP_REG_SDACDI, 0x003E, 0x3FFF, 1),   /* 516 */
+       CPCAP_REG(CPCAP_REG_TXI, 0x1CC6, 0xFFFF),               /* 517 */
+};
+
+static const struct cpcap_audio_config_table mic2_config_table[] = {
+       CPCAP_REG(CPCAP_REG_VAUDIOC, 0x0007, 0x77),
+       CPCAP_REG(CPCAP_REG_CC, 0x8FB3, 0xFEDF),
+       CPCAP_REG(CPCAP_REG_CDI, 0x1E40, 0xBFFF),
+       CPCAP_REG_SLAVE(CPCAP_REG_SDACDI, 0x007E, 0x3FFF, 1),
+       CPCAP_REG(CPCAP_REG_TXI, 0x0CC6, 0xFFFF),
+};
+
+#undef CPCAP_REG
+#undef CPCAP_REG_SLAVE
+
+static struct cpcap_audio_path speaker = {
+       .name = "speaker",
+       .gpio = TEGRA_GPIO_PR3,
+       .table = speaker_config_table,
+       .table_len = ARRAY_SIZE(speaker_config_table)
+};
+
+static const struct cpcap_audio_path headset = {
+       .name = "headset",
+       .gpio = TEGRA_GPIO_PS7,
+       .table = headset_config_table,
+       .table_len = ARRAY_SIZE(headset_config_table)
+};
+
+static const struct cpcap_audio_path mic1 = {
+       .name = "mic1",
+       .gpio = -1,
+       .table = mic1_config_table,
+       .table_len = ARRAY_SIZE(mic1_config_table),
+};
+
+static const struct cpcap_audio_path mic2 = {
+       .name = "mic2",
+       .gpio = -1,
+       .table = mic2_config_table,
+       .table_len = ARRAY_SIZE(mic2_config_table),
 };
 
 /* CPCAP is i2s master; tegra_audio_pdata.master == false */
 static struct cpcap_audio_platform_data cpcap_audio_pdata = {
        .master = true,
-       .regulator = "vaudio",
-       .state = &stingray_cpcap_audio_state,
-       .speaker_gpio = TEGRA_GPIO_PR3,
-       .headset_gpio = TEGRA_GPIO_PS7,
+       .speaker = &speaker,
+       .headset = &headset,
+       .mic1 = &mic1,
+       .mic2 = &mic2,
 };
 
 static struct platform_device cpcap_audio_device = {
index 85f740be57b7a29bc0ff3485586040a1bbaab2a6..1f6804dbaba7eb880a887db3de69f1d4facf7326 100644 (file)
@@ -2,7 +2,6 @@
  * arch/arm/mach-tegra/include/mach/cpcap_audio.h
  *
  * Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2007 - 2010 Motorola, Inc.
  *
  * Author:
  *     Iliyan Malchev <malchev@google.com>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
-#include <linux/spi/cpcap-regbits.h>
-#include <linux/spi/cpcap.h>
 
-enum {
-       CPCAP_AUDIO_MODE_NORMAL, /* mode of normal audio operation */
-       CPCAP_AUDIO_MODE_DAI, /* CPCAP_AUDIO is configured for DAI testing */
-       CPCAP_AUDIO_MODE_DAI_DOWNLINK = CPCAP_AUDIO_MODE_DAI,
-       CPCAP_AUDIO_MODE_DAI_UPLINK,
-       CPCAP_AUDIO_MODE_TTY /* CPCAP_AUDIO is configured for TTY */
+struct cpcap_audio_config_table {
+       int reg;
+       int val;
+       int mask;
+       int slave_or;
 };
 
-enum {
-       CPCAP_AUDIO_CODEC_OFF, /* codec is powered down */
-       CPCAP_AUDIO_CODEC_CLOCK_ONLY, /* codec powered down, clocks running */
-       CPCAP_AUDIO_CODEC_ON, /* codec is completely operational */
-       CPCAP_AUDIO_CODEC_LOOPBACK /* xcap in (analog->digital->analog) mode */
-};
-
-enum {
-       CPCAP_AUDIO_CODEC_RATE_8000_HZ,
-               /* codec is running at 8Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_11025_HZ,
-               /* codec is running at 11.025Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_12000_HZ,
-               /* codec is running at 12Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_16000_HZ,
-               /* codec is running at 16Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_22050_HZ,
-               /* codec is running at 22.05Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_24000_HZ,
-               /* codec is running at 24Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_32000_HZ,
-               /* codec is running at 32Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_44100_HZ,
-               /* codec is running at 44.1Khz sample rate */
-       CPCAP_AUDIO_CODEC_RATE_48000_HZ,
-               /* codec is running at 48Khz sample rate */
-};
-
-enum {
-       CPCAP_AUDIO_CODEC_UNMUTE, /* codec is unmuted */
-       CPCAP_AUDIO_CODEC_MUTE, /* codec is muted */
-       CPCAP_AUDIO_CODEC_BYPASS_LOOP
-                               /* codec is bypassed
-                                * (analog-only loopback mode) */
-};
-
-enum {
-       CPCAP_AUDIO_STDAC_OFF,
-               /* stereo dac is powered down */
-       CPCAP_AUDIO_STDAC_CLOCK_ONLY,
-               /* stereo dac is powered down, but clocks are activated */
-       CPCAP_AUDIO_STDAC_ON
-               /* stereo dac is completely operational */
-};
-
-enum {
-               /* THESE MUST CORRESPOND TO XCPCAP_AUDIO SETTINGS */
-       CPCAP_AUDIO_STDAC_RATE_8000_HZ,
-               /* stereo dac set for 8Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_11025_HZ,
-               /* stereo dac set for 11.025Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_12000_HZ,
-               /* stereo dac set for 12Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_16000_HZ,
-               /* stereo dac set for 16Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_22050_HZ,
-               /* stereo dac set for 22.05Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_24000_HZ,
-               /* stereo dac set for 24Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_32000_HZ,
-               /* stereo dac set for 32Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_44100_HZ,
-               /* stereo dac set for 44.1Khz sample rate */
-       CPCAP_AUDIO_STDAC_RATE_48000_HZ
-               /* stereo dac set for 48Khz sample rate */
-};
-
-enum {
-       CPCAP_AUDIO_STDAC_UNMUTE, /* stereo dac is unmuted */
-       CPCAP_AUDIO_STDAC_MUTE /* stereo dac is muted */
-};
-
-enum {
-       CPCAP_AUDIO_ANALOG_SOURCE_OFF,
-               /* Analog PGA input is disabled */
-       CPCAP_AUDIO_ANALOG_SOURCE_R,
-               /* Right analog PGA input is enabled */
-       CPCAP_AUDIO_ANALOG_SOURCE_L,
-               /* Left analog PGA input is enabled */
-       CPCAP_AUDIO_ANALOG_SOURCE_STEREO
-               /* Both analog PGA inputs are enabled */
-};
-
-enum {
-       CPCAP_AUDIO_OUT_NONE,
-               /* No audio output selected */
-       CPCAP_AUDIO_OUT_HANDSET,
-               /* handset (earpiece) speaker */
-       CPCAP_AUDIO_OUT_LOUDSPEAKER,
-               /* loudspeaker (speakerphone) */
-       CPCAP_AUDIO_OUT_LINEAR_VIBRATOR,
-               /* linear vibrator, if equipped */
-       CPCAP_AUDIO_OUT_MONO_HEADSET,
-               /* mono (R channel) x.5mm headset */
-       CPCAP_AUDIO_OUT_STEREO_HEADSET,
-               /* stereo x.5mm headset */
-       CPCAP_AUDIO_OUT_EXT_BUS_MONO,
-               /* accessory bus mono output(EMU) */
-       CPCAP_AUDIO_OUT_EMU_MONO,
-       CPCAP_AUDIO_OUT_EXT_BUS_STEREO,
-               /* accessory bus stereo output (EMU only) */
-       CPCAP_AUDIO_OUT_EMU_STEREO,
-       CPCAP_AUDIO_OUT_LINEOUT,
-       CPCAP_AUDIO_OUT_BT_MONO,
-       CPCAP_AUDIO_OUT_NUM_OF_PATHS
-               /* Max number of audio output paths */
-};
-
-enum {
-       CPCAP_AUDIO_IN_NONE,
-               /* No audio input selected */
-       CPCAP_AUDIO_IN_HANDSET,
-               /* handset (internal) microphone */
-       CPCAP_AUDIO_IN_AUX_INTERNAL,
-               /* Auxiliary (second) internal mic */
-       CPCAP_AUDIO_IN_DUAL_INTERNAL,
-               /* both internal microphones are connected */
-       CPCAP_AUDIO_IN_HEADSET,
-               /* Audio <- x.5mm headset microphone */
-       CPCAP_AUDIO_IN_EXT_BUS,
-               /* Audio <- accessory bus analog input (EMU) */
-       CPCAP_AUDIO_IN_EMU = CPCAP_AUDIO_IN_EXT_BUS,
-       CPCAP_AUDIO_IN_HEADSET_BIAS_ONLY,
-               /* 3.5mm headset control when no mic is selected */
-       CPCAP_AUDIO_IN_DUAL_EXTERNAL,
-               /* Recording from external source */
-       CPCAP_AUDIO_IN_BT_MONO,
-       CPCAP_AUDIO_IN_NUM_OF_PATHS
-               /* Max number of audio input paths */
-};
-
-enum {
-               /* Defines the audio path type */
-       CPCAP_AUDIO_AUDIO_IN_PATH,
-               /* Audio input path refers to CPCAP_AUDIO_MIC_TYPE */
-       CPCAP_AUDIO_AUDIO_OUT_PATH
-               /* Audio output path refers to CPCAP_AUDIO_SPEAKER_TYPE */
-};
-
-enum {
-       CPCAP_AUDIO_BALANCE_NEUTRAL,/* audio routed normally */
-       CPCAP_AUDIO_BALANCE_R_ONLY, /* audio routed to left channel only */
-       CPCAP_AUDIO_BALANCE_L_ONLY /* audio routed to right channel only */
-};
-
-enum {
-       CPCAP_AUDIO_RAT_NONE, /* Not in a call mode */
-       CPCAP_AUDIO_RAT_2G,   /* In 2G call mode */
-       CPCAP_AUDIO_RAT_3G,   /* In 3G call mode */
-       CPCAP_AUDIO_RAT_CDMA  /* In CDMA call mode */
-};
-
-/* Clock multipliers for A2LA register */
-enum {
-       CPCAP_AUDIO_A2_CLOCK_MASK  = CPCAP_BIT_A2_CLK2 | CPCAP_BIT_A2_CLK1 |
-                                                        CPCAP_BIT_A2_CLK0,
-       CPCAP_AUDIO_A2_CLOCK_15_36 = CPCAP_BIT_A2_CLK0,
-       CPCAP_AUDIO_A2_CLOCK_16_80 = CPCAP_BIT_A2_CLK1,
-       CPCAP_AUDIO_A2_CLOCK_19_20 = CPCAP_BIT_A2_CLK1 | CPCAP_BIT_A2_CLK0,
-       CPCAP_AUDIO_A2_CLOCK_26_00 = CPCAP_BIT_A2_CLK2,
-       CPCAP_AUDIO_A2_CLOCK_33_60 = CPCAP_BIT_A2_CLK2 | CPCAP_BIT_A2_CLK0,
-       CPCAP_AUDIO_A2_CLOCK_38_40 = CPCAP_BIT_A2_CLK2 | CPCAP_BIT_A2_CLK1
-};
-
-struct cpcap_audio_state {
-       struct cpcap_device *cpcap;
-       int mode;
-       int codec_mode;
-       int codec_rate;
-       int codec_mute;
-       int stdac_mode;
-       int stdac_rate;
-       int stdac_mute;
-       int analog_source;
-       int codec_primary_speaker;
-       int codec_secondary_speaker;
-       int stdac_primary_speaker;
-       int stdac_secondary_speaker;
-       int ext_primary_speaker;
-       int ext_secondary_speaker;
-       int codec_primary_balance;
-       int stdac_primary_balance;
-       int ext_primary_balance;
-       unsigned int output_gain;
-       int microphone;
-       unsigned int input_gain;
-       int rat_type;
+struct cpcap_audio_path {
+       const char *name;
+       int gpio;
+       const struct cpcap_audio_config_table *table;
+       int table_len;
 };
 
 struct cpcap_audio_platform_data {
        bool master;
-       const char *regulator;
-       struct cpcap_audio_state *state;
-       int speaker_gpio;
-       int headset_gpio;
+       const struct cpcap_audio_path *speaker;
+       const struct cpcap_audio_path *headset;
+       const struct cpcap_audio_path *mic1;
+       const struct cpcap_audio_path *mic2;
 };
 
-int cpcap_audio_init(struct cpcap_audio_state *state, const char *regulator);
-void cpcap_audio_register_dump(struct cpcap_audio_state *state);
-void cpcap_audio_set_audio_state(struct cpcap_audio_state *state);
-
 #endif/*__ARCH_ARM_MACH_TEGRA_CPCAP_AUDIO_H_*/
index a28fc814aea6832796205ba52147e3a602eee29e..ece21b1a98a2b4dfbc7e90971be81434600f85e3 100644 (file)
@@ -85,7 +85,6 @@ cpcap-objs                    := cpcap-core.o \
                                   cpcap-adc.o \
                                   cpcap-uc.o \
                                   cpcap-3mm5.o \
-                                  tegra-cpcap-audio.o \
-                                  cpcap-audio-core.o
+                                  cpcap-audio.o
 
 obj-$(CONFIG_MFD_CPCAP)                += cpcap.o
diff --git a/drivers/mfd/cpcap-audio-core.c b/drivers/mfd/cpcap-audio-core.c
deleted file mode 100644 (file)
index 8c725a0..0000000
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * Copyright (C) 2007 - 2009 Motorola, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/poll.h>
-#include <linux/spi/cpcap.h>
-#include <linux/regulator/consumer.h>
-
-#include <mach/cpcap_audio.h>
-
-#define SLEEP_ACTIVATE_POWER_DELAY_MS  2
-#define CLOCK_TREE_RESET_DELAY_MS      1
-
-#define CPCAP_AUDIO_SPI_READBACK       1
-
-#define E(args...)  pr_err("cpcap-audio: " args)
-
-static struct cpcap_audio_state current_state = {
-       .cpcap                          = NULL,
-       .mode                           = CPCAP_AUDIO_MODE_NORMAL,
-
-       .codec_mode                     = CPCAP_AUDIO_CODEC_OFF,
-       .codec_rate                     = CPCAP_AUDIO_CODEC_RATE_8000_HZ,
-       .codec_mute                     = CPCAP_AUDIO_CODEC_MUTE,
-
-       .stdac_mode                     = CPCAP_AUDIO_STDAC_OFF,
-       .stdac_rate                     = CPCAP_AUDIO_STDAC_RATE_8000_HZ,
-       .stdac_mute                     = CPCAP_AUDIO_STDAC_MUTE,
-
-       .analog_source                  = CPCAP_AUDIO_ANALOG_SOURCE_OFF,
-
-       .codec_primary_speaker          = CPCAP_AUDIO_OUT_NONE,
-       .codec_secondary_speaker        = CPCAP_AUDIO_OUT_NONE,
-
-       .stdac_primary_speaker          = CPCAP_AUDIO_OUT_NONE,
-       .stdac_secondary_speaker        = CPCAP_AUDIO_OUT_NONE,
-
-       .ext_primary_speaker            = CPCAP_AUDIO_OUT_NONE,
-       .ext_secondary_speaker          = CPCAP_AUDIO_OUT_NONE,
-
-       .codec_primary_balance          = CPCAP_AUDIO_BALANCE_NEUTRAL,
-       .stdac_primary_balance          = CPCAP_AUDIO_BALANCE_NEUTRAL,
-       .ext_primary_balance            = CPCAP_AUDIO_BALANCE_NEUTRAL,
-
-       .output_gain                    = 0,
-       .microphone                     = CPCAP_AUDIO_IN_NONE,
-       .input_gain                     = 0,
-       .rat_type                       = CPCAP_AUDIO_RAT_NONE
-};
-
-/* Define regulator to turn on the audio portion of cpcap */
-struct regulator *audio_reg;
-
-static inline bool is_mic_stereo(int microphone)
-{
-       return microphone == CPCAP_AUDIO_IN_DUAL_INTERNAL ||
-               microphone == CPCAP_AUDIO_IN_DUAL_EXTERNAL;
-}
-
-static inline bool is_codec_changed(struct cpcap_audio_state *state,
-                                       struct cpcap_audio_state *prev)
-{
-       return state->codec_mode != prev->codec_mode ||
-               state->codec_rate != prev->codec_rate ||
-               state->rat_type != prev->rat_type ||
-               state->microphone != prev->microphone;
-}
-
-static inline bool is_stdac_changed(struct cpcap_audio_state *state,
-                                       struct cpcap_audio_state *prev)
-{
-       return state->stdac_mode != prev->stdac_mode ||
-               state->rat_type != prev->rat_type ||
-               state->stdac_rate != prev->stdac_rate;
-}
-
-static inline bool is_output_bt_only(struct cpcap_audio_state *state)
-{
-       if (state->codec_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO &&
-                       state->codec_secondary_speaker == CPCAP_AUDIO_OUT_NONE)
-               return true;
-
-       if (state->stdac_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO &&
-                       state->stdac_secondary_speaker == CPCAP_AUDIO_OUT_NONE)
-               return true;
-
-       if (state->ext_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO &&
-                       state->ext_secondary_speaker == CPCAP_AUDIO_OUT_NONE)
-               return true;
-
-       return false;
-}
-
-static inline bool is_output_headset(struct cpcap_audio_state *state)
-{
-       if (state->codec_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET ||
-                       state->codec_primary_speaker ==
-                               CPCAP_AUDIO_OUT_MONO_HEADSET ||
-                       state->codec_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_STEREO_HEADSET ||
-                       state->codec_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_MONO_HEADSET)
-               return true;
-
-       if (state->stdac_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET ||
-                       state->stdac_primary_speaker ==
-                               CPCAP_AUDIO_OUT_MONO_HEADSET ||
-                       state->stdac_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_STEREO_HEADSET ||
-                       state->stdac_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_MONO_HEADSET)
-               return true;
-
-       if (state->ext_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET ||
-                       state->ext_primary_speaker ==
-                               CPCAP_AUDIO_OUT_MONO_HEADSET ||
-                       state->ext_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_STEREO_HEADSET ||
-                       state->ext_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_MONO_HEADSET)
-               return true;
-
-       return false;
-}
-
-static inline bool is_speaker_turning_off(struct cpcap_audio_state *state,
-                                       struct cpcap_audio_state *prev)
-{
-       return (prev->codec_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->codec_primary_speaker ==
-                               CPCAP_AUDIO_OUT_NONE) ||
-               (prev->codec_secondary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->codec_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_NONE) ||
-               (prev->stdac_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->stdac_primary_speaker ==
-                               CPCAP_AUDIO_OUT_NONE) ||
-               (prev->stdac_secondary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->stdac_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_NONE) ||
-               (prev->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->ext_primary_speaker ==
-                               CPCAP_AUDIO_OUT_NONE) ||
-               (prev->ext_secondary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->ext_secondary_speaker ==
-                               CPCAP_AUDIO_OUT_NONE);
-}
-
-static inline bool is_output_changed(struct cpcap_audio_state *state,
-                       struct cpcap_audio_state *prev)
-{
-       if (state->codec_primary_speaker != prev->codec_primary_speaker ||
-                       state->codec_primary_balance !=
-                               prev->codec_primary_balance ||
-                       state->codec_secondary_speaker !=
-                               prev->codec_secondary_speaker)
-               return true;
-
-       if (state->stdac_primary_speaker != prev->stdac_primary_speaker ||
-                       state->stdac_primary_balance !=
-                               prev->stdac_primary_balance ||
-                       state->stdac_secondary_speaker !=
-                               prev->stdac_secondary_speaker)
-               return true;
-
-       if (state->ext_primary_speaker != prev->ext_primary_speaker ||
-                       state->ext_primary_balance !=
-                               prev->ext_primary_balance ||
-                       state->ext_secondary_speaker !=
-                               prev->ext_secondary_speaker)
-               return true;
-
-       return false;
-}
-
-/* this is only true for audio registers, but those are the only ones we use */
-#define CPCAP_REG_FOR_POWERIC_REG(a) ((a) + (0x200 - CPCAP_REG_VAUDIOC))
-
-static void logged_cpcap_write(struct cpcap_device *cpcap, unsigned int reg,
-                       unsigned short int value, unsigned short int mask)
-{
-       if (mask != 0) {
-               int ret_val = 0;
-               pr_debug("%s: audio: reg %u, value 0x%x,mask 0x%x\n", __func__,
-                       CPCAP_REG_FOR_POWERIC_REG(reg), value, mask);
-               ret_val = cpcap_regacc_write(cpcap, reg, value, mask);
-               if (ret_val != 0)
-                       E("%s: w %04x m %04x -> r %u failed: %d\n", __func__,
-                               value, mask, reg, ret_val);
-#if CPCAP_AUDIO_SPI_READBACK
-               ret_val = cpcap_regacc_read(cpcap, reg, &value);
-               if (ret_val == 0)
-                       pr_debug("%s: audio verify: reg %u: value 0x%x\n",
-                               __func__,
-                               CPCAP_REG_FOR_POWERIC_REG(reg), value);
-               else
-                       E("%s: audio verify: reg %u FAILED\n", __func__,
-                               CPCAP_REG_FOR_POWERIC_REG(reg));
-#endif
-       }
-}
-
-static unsigned short int cpcap_audio_get_codec_output_amp_switches(
-                                               int speaker, int balance)
-{
-       unsigned short int value = CPCAP_BIT_PGA_CDC_EN;
-
-       pr_debug("%s() called with speaker = %d\n", __func__,
-                         speaker);
-
-       switch (speaker) {
-       case CPCAP_AUDIO_OUT_HANDSET:
-               value |= CPCAP_BIT_A1_EAR_CDC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_LOUDSPEAKER:
-               value |= CPCAP_BIT_A2_LDSP_L_CDC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_MONO_HEADSET:
-       case CPCAP_AUDIO_OUT_STEREO_HEADSET:
-               if (balance != CPCAP_AUDIO_BALANCE_L_ONLY)
-                       value |= CPCAP_BIT_ARIGHT_HS_CDC_SW;
-               if (balance != CPCAP_AUDIO_BALANCE_R_ONLY)
-                       value |= CPCAP_BIT_ALEFT_HS_CDC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_LINEOUT:
-               value |= CPCAP_BIT_A4_LINEOUT_R_CDC_SW |
-                       CPCAP_BIT_A4_LINEOUT_L_CDC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_BT_MONO:
-       default:
-               value = 0;
-               break;
-       }
-
-       pr_debug("Exiting %s() with return value = %d\n", __func__,
-                         value);
-       return value;
-}
-
-static unsigned short int cpcap_audio_get_stdac_output_amp_switches(
-                                               int speaker, int balance)
-{
-       unsigned short int value = CPCAP_BIT_PGA_DAC_EN;
-
-       pr_debug("%s() called with speaker = %d\n", __func__,
-                         speaker);
-
-       switch (speaker) {
-       case CPCAP_AUDIO_OUT_HANDSET:
-               value |= CPCAP_BIT_A1_EAR_DAC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_MONO_HEADSET:
-       case CPCAP_AUDIO_OUT_STEREO_HEADSET:
-               if (balance != CPCAP_AUDIO_BALANCE_R_ONLY)
-                       value |= CPCAP_BIT_ALEFT_HS_DAC_SW;
-               if (balance != CPCAP_AUDIO_BALANCE_L_ONLY)
-                       value |= CPCAP_BIT_ARIGHT_HS_DAC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_LOUDSPEAKER:
-               value |= CPCAP_BIT_A2_LDSP_L_DAC_SW | CPCAP_BIT_MONO_DAC0 |
-                       CPCAP_BIT_MONO_DAC1;
-               break;
-
-       case CPCAP_AUDIO_OUT_LINEOUT:
-               value |= CPCAP_BIT_A4_LINEOUT_R_DAC_SW |
-                       CPCAP_BIT_A4_LINEOUT_L_DAC_SW;
-               break;
-
-       case CPCAP_AUDIO_OUT_BT_MONO:
-       default:
-               value = 0;
-               break;
-       }
-
-       pr_debug("Exiting %s() with return value = %d\n", __func__,
-                         value);
-       return value;
-}
-
-static unsigned short int cpcap_audio_get_ext_output_amp_switches(
-                                               int speaker, int balance)
-{
-       unsigned short int value = 0;
-       pr_debug("%s() called with speaker %d\n", __func__,
-                                                               speaker);
-       switch (speaker) {
-       case CPCAP_AUDIO_OUT_HANDSET:
-               value = CPCAP_BIT_A1_EAR_EXT_SW | CPCAP_BIT_PGA_EXT_R_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_MONO_HEADSET:
-       case CPCAP_AUDIO_OUT_STEREO_HEADSET:
-               if (balance != CPCAP_AUDIO_BALANCE_L_ONLY)
-                       value = CPCAP_BIT_ARIGHT_HS_EXT_SW |
-                               CPCAP_BIT_PGA_EXT_R_EN;
-               if (balance != CPCAP_AUDIO_BALANCE_R_ONLY)
-                       value |= CPCAP_BIT_ALEFT_HS_EXT_SW |
-                               CPCAP_BIT_PGA_EXT_L_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_LOUDSPEAKER:
-               value = CPCAP_BIT_A2_LDSP_L_EXT_SW | CPCAP_BIT_PGA_EXT_L_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_LINEOUT:
-               value = CPCAP_BIT_A4_LINEOUT_R_EXT_SW |
-                       CPCAP_BIT_A4_LINEOUT_L_EXT_SW |
-                       CPCAP_BIT_PGA_EXT_L_EN | CPCAP_BIT_PGA_EXT_R_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_BT_MONO:
-       default:
-               value = 0;
-               break;
-       }
-
-       pr_debug("Exiting %s() with return value = %d\n", __func__,
-                         value);
-       return value;
-}
-
-static void cpcap_audio_set_output_amp_switches(struct cpcap_audio_state *state)
-{
-       static unsigned int codec_prev_settings;
-       static unsigned int stdac_prev_settings;
-       static unsigned int ext_prev_settings;
-
-       struct cpcap_regacc reg_changes;
-       unsigned short int value1 = 0, value2 = 0;
-
-       /* First set codec output amp switches */
-       value1 = cpcap_audio_get_codec_output_amp_switches(state->
-                       codec_primary_speaker, state->codec_primary_balance);
-       value2 = cpcap_audio_get_codec_output_amp_switches(state->
-                       codec_secondary_speaker, state->codec_primary_balance);
-
-       reg_changes.mask = value1 | value2 | codec_prev_settings;
-       reg_changes.value = value1 | value2;
-       codec_prev_settings = reg_changes.value;
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXCOA, reg_changes.value,
-                                                       reg_changes.mask);
-
-       /* Second Stdac switches */
-       value1 = cpcap_audio_get_stdac_output_amp_switches(state->
-                       stdac_primary_speaker, state->stdac_primary_balance);
-       value2 = cpcap_audio_get_stdac_output_amp_switches(state->
-                       stdac_secondary_speaker, state->stdac_primary_balance);
-
-       reg_changes.mask = value1 | value2 | stdac_prev_settings;
-       reg_changes.value = value1 | value2;
-
-       if ((state->stdac_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET &&
-               state->stdac_secondary_speaker == CPCAP_AUDIO_OUT_LOUDSPEAKER)
-               || (state->stdac_primary_speaker == CPCAP_AUDIO_OUT_LOUDSPEAKER
-               && state->stdac_secondary_speaker ==
-                                               CPCAP_AUDIO_OUT_STEREO_HEADSET))
-               reg_changes.value &= ~(CPCAP_BIT_MONO_DAC0 |
-                                       CPCAP_BIT_MONO_DAC1);
-
-       stdac_prev_settings = reg_changes.value;
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXSDOA, reg_changes.value,
-                                                       reg_changes.mask);
-
-       /* Last External source switches */
-       value1 =
-           cpcap_audio_get_ext_output_amp_switches(state->
-                               ext_primary_speaker,
-                               state->ext_primary_balance);
-       value2 =
-           cpcap_audio_get_ext_output_amp_switches(state->
-                               ext_secondary_speaker,
-                               state->ext_primary_balance);
-
-       reg_changes.mask = value1 | value2 | ext_prev_settings;
-       reg_changes.value = value1 | value2;
-       ext_prev_settings = reg_changes.value;
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXEPOA,
-                       reg_changes.value, reg_changes.mask);
-}
-
-static bool cpcap_audio_set_bits_for_speaker(int speaker, int balance,
-                                               unsigned short int *message)
-{
-       pr_debug("%s() called with speaker = %d\n", __func__,
-                         speaker);
-
-       /* Get the data required to enable each possible path */
-       switch (speaker) {
-       case CPCAP_AUDIO_OUT_HANDSET:
-               (*message) |= CPCAP_BIT_A1_EAR_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_MONO_HEADSET:
-       case CPCAP_AUDIO_OUT_STEREO_HEADSET:
-               if (balance != CPCAP_AUDIO_BALANCE_R_ONLY)
-                       (*message) |= CPCAP_BIT_HS_L_EN;
-               if (balance != CPCAP_AUDIO_BALANCE_L_ONLY)
-                       (*message) |= CPCAP_BIT_HS_R_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_LOUDSPEAKER:
-               (*message) |= CPCAP_BIT_A2_LDSP_L_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_LINEOUT:
-               (*message) |= CPCAP_BIT_A4_LINEOUT_R_EN |
-                               CPCAP_BIT_A4_LINEOUT_L_EN;
-               break;
-
-       case CPCAP_AUDIO_OUT_BT_MONO:
-       default:
-               (*message) |= 0;
-               break;
-       }
-
-       return false; /* There is no external loudspeaker on this product */
-}
-
-static void cpcap_audio_configure_aud_mute(struct cpcap_audio_state *state,
-                               struct cpcap_audio_state *prev)
-{
-       struct cpcap_regacc reg_changes = { 0 };
-       unsigned short int value1 = 0, value2 = 0;
-
-       if (state->codec_mute != prev->codec_mute) {
-               value1 = cpcap_audio_get_codec_output_amp_switches(
-                               prev->codec_primary_speaker,
-                               prev->codec_primary_balance);
-
-               value2 = cpcap_audio_get_codec_output_amp_switches(
-                               prev->codec_secondary_speaker,
-                               prev->codec_primary_balance);
-
-               reg_changes.mask = value1 | value2 | CPCAP_BIT_CDC_SW;
-
-               if (state->codec_mute == CPCAP_AUDIO_CODEC_UNMUTE)
-                       reg_changes.value = reg_changes.mask;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_RXCOA,
-                                       reg_changes.value, reg_changes.mask);
-       }
-
-       if (state->stdac_mute != prev->stdac_mute) {
-               value1 = cpcap_audio_get_stdac_output_amp_switches(
-                               prev->stdac_primary_speaker,
-                               prev->stdac_primary_balance);
-
-               value2 = cpcap_audio_get_stdac_output_amp_switches(
-                               prev->stdac_secondary_speaker,
-                               prev->stdac_primary_balance);
-
-               reg_changes.mask = value1 | value2 | CPCAP_BIT_ST_DAC_SW;
-
-               if (state->stdac_mute == CPCAP_AUDIO_STDAC_UNMUTE)
-                       reg_changes.value = reg_changes.mask;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_RXSDOA,
-                                       reg_changes.value, reg_changes.mask);
-       }
-}
-
-static void cpcap_audio_configure_codec(struct cpcap_audio_state *state,
-                               struct cpcap_audio_state *prev)
-{
-       unsigned int temp_codec_rate = state->codec_rate;
-       struct cpcap_regacc cdai_changes = { 0 };
-       struct cpcap_regacc codec_changes = { 0 };
-       int codec_freq_config = 0;
-
-       const unsigned int CODEC_FREQ_MASK = CPCAP_BIT_CDC_CLK0
-               | CPCAP_BIT_CDC_CLK1 | CPCAP_BIT_CDC_CLK2;
-       const unsigned int CODEC_RESET_FREQ_MASK = CODEC_FREQ_MASK
-               | CPCAP_BIT_CDC_CLOCK_TREE_RESET;
-
-       static unsigned int prev_codec_data = 0x0, prev_cdai_data = 0x0;
-
-       if (!is_codec_changed(state, prev))
-               return;
-
-       if (state->rat_type == CPCAP_AUDIO_RAT_CDMA)
-               codec_freq_config = (CPCAP_BIT_CDC_CLK0
-                               | CPCAP_BIT_CDC_CLK1) ; /* 19.2Mhz */
-       else
-               codec_freq_config = CPCAP_BIT_CDC_CLK2 ; /* 26Mhz */
-
-       /* If a codec is already in use, reset codec to initial state */
-       if (prev->codec_mode != CPCAP_AUDIO_CODEC_OFF) {
-               codec_changes.mask = prev_codec_data
-                       | CPCAP_BIT_DF_RESET
-                       | CPCAP_BIT_CDC_CLOCK_TREE_RESET;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_CC,
-                       codec_changes.value, codec_changes.mask);
-
-               prev_codec_data = 0;
-               prev->codec_mode = CPCAP_AUDIO_CODEC_OFF;
-       }
-
-       temp_codec_rate &= 0x0000000F;
-       temp_codec_rate = temp_codec_rate << 9;
-
-       switch (state->codec_mode) {
-       case CPCAP_AUDIO_CODEC_LOOPBACK:
-       case CPCAP_AUDIO_CODEC_ON:
-               if (state->codec_primary_speaker !=
-                       CPCAP_AUDIO_OUT_NONE) {
-                       codec_changes.value |= CPCAP_BIT_CDC_EN_RX;
-               }
-
-               /* Turning on the input HPF */
-               if (state->microphone != CPCAP_AUDIO_IN_NONE)
-                       codec_changes.value |= CPCAP_BIT_AUDIHPF_0 |
-                                               CPCAP_BIT_AUDIHPF_1;
-
-#if 1
-               if (state->microphone != CPCAP_AUDIO_IN_NONE) {
-                       codec_changes.value |= CPCAP_BIT_MIC1_CDC_EN;
-                       codec_changes.value |= CPCAP_BIT_MIC2_CDC_EN;
-               }
-#else
-               if (state->microphone != CPCAP_AUDIO_IN_AUX_INTERNAL &&
-                       state->microphone != CPCAP_AUDIO_IN_NONE)
-                       codec_changes.value |= CPCAP_BIT_MIC1_CDC_EN |
-                                               CPCAP_BIT_MIC2_CDC_EN;
-
-               if (state->microphone == CPCAP_AUDIO_IN_AUX_INTERNAL ||
-                       is_mic_stereo(state->microphone))
-                       codec_changes.value |= CPCAP_BIT_MIC2_CDC_EN;
-#endif
-
-       /* falling through intentionally */
-       case CPCAP_AUDIO_CODEC_CLOCK_ONLY:
-               codec_changes.value |=
-                       (codec_freq_config | temp_codec_rate |
-                       CPCAP_BIT_DF_RESET);
-               cdai_changes.value |= CPCAP_BIT_CDC_CLK_EN;
-               break;
-
-       case CPCAP_AUDIO_CODEC_OFF:
-               cdai_changes.value |= CPCAP_BIT_SMB_CDC;
-               break;
-
-       default:
-               break;
-       }
-
-       /* Multimedia uses CLK_IN0, incall uses CLK_IN1 */
-       if (state->rat_type != CPCAP_AUDIO_RAT_NONE)
-               cdai_changes.value |= CPCAP_BIT_CLK_IN_SEL;
-
-       cdai_changes.value |= CPCAP_BIT_CDC_PLL_SEL | CPCAP_BIT_CLK_INV;
-       cdai_changes.value |= CPCAP_BIT_DIG_AUD_IN;
-
-       /* Setting I2S mode */
-       cdai_changes.value |= CPCAP_BIT_CDC_DIG_AUD_FS0 |
-                       CPCAP_BIT_CDC_DIG_AUD_FS1 |
-                       CPCAP_BIT_MIC2_TIMESLOT0;
-
-       /* OK, now start paranoid codec sequence */
-       /* FIRST, make sure the frequency config is right... */
-       logged_cpcap_write(state->cpcap, CPCAP_REG_CC,
-                               codec_freq_config, CODEC_FREQ_MASK);
-
-       /* Next, write the CDAI if it's changed */
-       if (prev_cdai_data != cdai_changes.value) {
-               cdai_changes.mask = cdai_changes.value
-                       | prev_cdai_data;
-               prev_cdai_data = cdai_changes.value;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_CDI,
-                               cdai_changes.value, cdai_changes.mask);
-
-               /* Clock tree change -- reset and wait */
-               codec_freq_config |= CPCAP_BIT_CDC_CLOCK_TREE_RESET;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_CC,
-                       codec_freq_config, CODEC_RESET_FREQ_MASK);
-
-               /* Wait for clock tree reset to complete */
-               mdelay(CLOCK_TREE_RESET_DELAY_MS);
-       }
-
-       /* Clear old settings */
-       codec_changes.mask = codec_changes.value | prev_codec_data;
-       prev_codec_data    = codec_changes.value;
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_CC,
-                       codec_changes.value, codec_changes.mask);
-}
-
-static void cpcap_audio_configure_stdac(struct cpcap_audio_state *state,
-                               struct cpcap_audio_state *prev)
-{
-       const unsigned int SDAC_FREQ_MASK = CPCAP_BIT_ST_DAC_CLK0
-                       | CPCAP_BIT_ST_DAC_CLK1 | CPCAP_BIT_ST_DAC_CLK2;
-       const unsigned int SDAC_RESET_FREQ_MASK = SDAC_FREQ_MASK
-                                       | CPCAP_BIT_ST_CLOCK_TREE_RESET;
-       static unsigned int prev_stdac_data, prev_sdai_data;
-
-       if (is_stdac_changed(state, prev)) {
-               unsigned int temp_stdac_rate = state->stdac_rate;
-               struct cpcap_regacc sdai_changes = { 0 };
-               struct cpcap_regacc stdac_changes = { 0 };
-
-               int stdac_freq_config = 0;
-               if (state->rat_type == CPCAP_AUDIO_RAT_CDMA)
-                       stdac_freq_config = (CPCAP_BIT_ST_DAC_CLK0
-                                       | CPCAP_BIT_ST_DAC_CLK1) ; /*19.2Mhz*/
-               else
-                       stdac_freq_config = CPCAP_BIT_ST_DAC_CLK2 ; /* 26Mhz */
-
-               /* We need to turn off stdac before changing its settings */
-               if (prev->stdac_mode != CPCAP_AUDIO_STDAC_OFF) {
-                       stdac_changes.mask = prev_stdac_data |
-                                       CPCAP_BIT_DF_RESET_ST_DAC |
-                                       CPCAP_BIT_ST_CLOCK_TREE_RESET;
-
-                       logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
-                               stdac_changes.value, stdac_changes.mask);
-
-                       prev_stdac_data = 0;
-                       prev->stdac_mode = CPCAP_AUDIO_STDAC_OFF;
-               }
-
-               temp_stdac_rate &= 0x0000000F;
-               temp_stdac_rate = temp_stdac_rate << 4;
-
-               switch (state->stdac_mode) {
-               case CPCAP_AUDIO_STDAC_ON:
-                       stdac_changes.value |= CPCAP_BIT_ST_DAC_EN;
-               /* falling through intentionally */
-               case CPCAP_AUDIO_STDAC_CLOCK_ONLY:
-                       stdac_changes.value |= temp_stdac_rate |
-                               CPCAP_BIT_DF_RESET_ST_DAC | stdac_freq_config;
-                       sdai_changes.value |= CPCAP_BIT_ST_CLK_EN;
-                       break;
-
-               case CPCAP_AUDIO_STDAC_OFF:
-               default:
-                       break;
-               }
-
-               if (state->rat_type != CPCAP_AUDIO_RAT_NONE)
-                       sdai_changes.value |= CPCAP_BIT_ST_DAC_CLK_IN_SEL;
-               /* begin everest change */
-               /*
-               sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 |
-                       CPCAP_BIT_DIG_AUD_IN_ST_DAC | CPCAP_BIT_ST_L_TIMESLOT0;
-               */
-               /* I2S Mode, ignore timeslots, invert bit clock */
-               sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 |
-                       CPCAP_BIT_DIG_AUD_IN_ST_DAC |
-                       CPCAP_BIT_ST_DIG_AUD_FS1 | CPCAP_BIT_ST_CLK_INV;
-               /* end everest change */
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
-                               stdac_freq_config, SDAC_FREQ_MASK);
-
-               /* Next, write the SDACDI if it's changed */
-               if (prev_sdai_data != sdai_changes.value) {
-                       sdai_changes.mask = sdai_changes.value
-                                               | prev_sdai_data;
-                       prev_sdai_data = sdai_changes.value;
-
-                       logged_cpcap_write(state->cpcap, CPCAP_REG_SDACDI,
-                                       sdai_changes.value, sdai_changes.mask);
-
-                       /* Clock tree change -- reset and wait */
-                       stdac_freq_config |= CPCAP_BIT_ST_CLOCK_TREE_RESET;
-
-                       logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
-                               stdac_freq_config, SDAC_RESET_FREQ_MASK);
-
-                       /* Wait for clock tree reset to complete */
-                       mdelay(CLOCK_TREE_RESET_DELAY_MS);
-               }
-
-               /* Clear old settings */
-               stdac_changes.mask = stdac_changes.value | prev_stdac_data;
-               prev_stdac_data = stdac_changes.value;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
-                       stdac_changes.value, stdac_changes.mask);
-       }
-}
-
-static void cpcap_audio_configure_analog_source(
-       struct cpcap_audio_state *state,
-       struct cpcap_audio_state *prev)
-{
-       if (state->analog_source != prev->analog_source) {
-               struct cpcap_regacc ext_changes = { 0 };
-               static unsigned int prev_ext_data;
-               switch (state->analog_source) {
-               case CPCAP_AUDIO_ANALOG_SOURCE_STEREO:
-                       ext_changes.value |= CPCAP_BIT_MONO_EXT0 |
-                               CPCAP_BIT_PGA_IN_R_SW | CPCAP_BIT_PGA_IN_L_SW;
-                       break;
-               case CPCAP_AUDIO_ANALOG_SOURCE_L:
-                       ext_changes.value |= CPCAP_BIT_MONO_EXT1 |
-                                               CPCAP_BIT_PGA_IN_L_SW;
-                       break;
-               case CPCAP_AUDIO_ANALOG_SOURCE_R:
-                       ext_changes.value |= CPCAP_BIT_MONO_EXT1 |
-                                               CPCAP_BIT_PGA_IN_R_SW;
-                       break;
-               default:
-                       break;
-               }
-
-               ext_changes.mask = ext_changes.value | prev_ext_data;
-
-               prev_ext_data = ext_changes.value;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_RXEPOA,
-                               ext_changes.value, ext_changes.mask);
-       }
-}
-
-static void cpcap_audio_configure_input_gains(
-       struct cpcap_audio_state *state,
-       struct cpcap_audio_state *prev)
-{
-       if (state->input_gain != prev->input_gain) {
-               struct cpcap_regacc reg_changes = { 0 };
-               unsigned int temp_input_gain = state->input_gain & 0x0000001F;
-
-               reg_changes.value |= ((temp_input_gain << 5) | temp_input_gain);
-
-               reg_changes.mask = 0x3FF;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_TXMP,
-                               reg_changes.value, reg_changes.mask);
-       }
-}
-
-static void cpcap_audio_configure_output_gains(
-       struct cpcap_audio_state *state,
-       struct cpcap_audio_state *prev)
-{
-       if (state->output_gain != prev->output_gain) {
-               struct cpcap_regacc reg_changes = { 0 };
-               unsigned int temp_output_gain = state->output_gain & 0x0000000F;
-
-               reg_changes.value |=
-                   ((temp_output_gain << 2) | (temp_output_gain << 8) |
-                    (temp_output_gain << 12));
-
-               reg_changes.mask = 0xFF3C;
-
-               logged_cpcap_write(state->cpcap, CPCAP_REG_RXVC,
-                               reg_changes.value, reg_changes.mask);
-       }
-}
-
-static void cpcap_audio_configure_output(
-       struct cpcap_audio_state *state,
-       struct cpcap_audio_state *prev)
-{
-       static unsigned int prev_aud_out_data;
-
-       bool activate_ext_loudspeaker = false;
-       struct cpcap_regacc reg_changes = { 0 };
-
-       if (!is_output_changed(prev, state) &&
-                       !is_codec_changed(prev, state) &&
-                       !is_stdac_changed(prev, state))
-               return;
-
-       cpcap_audio_set_output_amp_switches(state);
-
-       activate_ext_loudspeaker = cpcap_audio_set_bits_for_speaker(
-                                       state->codec_primary_speaker,
-                                        state->codec_primary_balance,
-                                        &(reg_changes.value));
-
-       activate_ext_loudspeaker = activate_ext_loudspeaker ||
-                               cpcap_audio_set_bits_for_speaker(
-                                       state->codec_secondary_speaker,
-                                        CPCAP_AUDIO_BALANCE_NEUTRAL,
-                                        &(reg_changes.value));
-
-       activate_ext_loudspeaker = activate_ext_loudspeaker ||
-                               cpcap_audio_set_bits_for_speaker(
-                                       state->stdac_primary_speaker,
-                                        state->stdac_primary_balance,
-                                        &(reg_changes.value));
-
-       activate_ext_loudspeaker = activate_ext_loudspeaker ||
-                               cpcap_audio_set_bits_for_speaker(
-                                       state->stdac_secondary_speaker,
-                                        CPCAP_AUDIO_BALANCE_NEUTRAL,
-                                        &(reg_changes.value));
-
-       activate_ext_loudspeaker = activate_ext_loudspeaker ||
-                               cpcap_audio_set_bits_for_speaker(
-                                       state->ext_primary_speaker,
-                                        state->ext_primary_balance,
-                                        &(reg_changes.value));
-
-       activate_ext_loudspeaker = activate_ext_loudspeaker ||
-                               cpcap_audio_set_bits_for_speaker(
-                                       state->ext_secondary_speaker,
-                                        CPCAP_AUDIO_BALANCE_NEUTRAL,
-                                        &(reg_changes.value));
-
-       reg_changes.mask = reg_changes.value | prev_aud_out_data;
-
-       prev_aud_out_data = reg_changes.value;
-
-       /* Sleep for 300ms if we are getting into a call to allow the switch to
-        * settle.  If we don't do this, it causes a loud pop at the beginning
-        * of the call.
-        */
-       if (state->rat_type == CPCAP_AUDIO_RAT_CDMA &&
-                       state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       prev->ext_primary_speaker == CPCAP_AUDIO_OUT_NONE)
-               msleep(300);
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA,
-                               reg_changes.value, reg_changes.mask);
-}
-
-static inline bool codec_loopback_changed(struct cpcap_audio_state *new,
-                       struct cpcap_audio_state *old)
-{
-       return (new->codec_mode != old->codec_mode) &&
-               (new->codec_mode == CPCAP_AUDIO_CODEC_LOOPBACK ||
-                old->codec_mode == CPCAP_AUDIO_CODEC_LOOPBACK);
-}
-
-static void cpcap_audio_configure_input(struct cpcap_audio_state *state,
-                       struct cpcap_audio_state *prev)
-{
-       static unsigned int prev_input_data = 0x0;
-       struct cpcap_regacc reg_changes = { 0 };
-
-       if (state->microphone == prev->microphone &&
-                       !codec_loopback_changed(state, prev))
-               return;
-
-       if (state->codec_mode == CPCAP_AUDIO_CODEC_LOOPBACK)
-               reg_changes.value |= CPCAP_BIT_DLM;
-
-       if (prev->microphone == CPCAP_AUDIO_IN_HEADSET)
-               logged_cpcap_write(state->cpcap, CPCAP_REG_GPIO4,
-                                               0, CPCAP_BIT_GPIO4DRV);
-
-       switch (state->microphone) {
-       case CPCAP_AUDIO_IN_HANDSET:
-               pr_debug("%s: handset\n", __func__);
-               reg_changes.value |= CPCAP_BIT_MB_ON1R
-                       | CPCAP_BIT_MIC1_MUX | CPCAP_BIT_MIC1_PGA_EN;
-               break;
-
-       case CPCAP_AUDIO_IN_HEADSET:
-               pr_debug("%s: headset\n", __func__);
-               reg_changes.value |= CPCAP_BIT_HS_MIC_MUX
-                       | CPCAP_BIT_MIC1_PGA_EN;
-               if (state->rat_type == CPCAP_AUDIO_RAT_CDMA)
-                       logged_cpcap_write(state->cpcap, CPCAP_REG_GPIO4,
-                               CPCAP_BIT_GPIO4DRV, CPCAP_BIT_GPIO4DRV);
-               break;
-
-       case CPCAP_AUDIO_IN_EXT_BUS:
-               reg_changes.value |=  CPCAP_BIT_EMU_MIC_MUX
-                       | CPCAP_BIT_MIC1_PGA_EN;
-               break;
-
-       case CPCAP_AUDIO_IN_AUX_INTERNAL:
-               reg_changes.value |= CPCAP_BIT_MB_ON1L
-                       | CPCAP_BIT_MIC2_MUX | CPCAP_BIT_MIC2_PGA_EN;
-               break;
-
-       case CPCAP_AUDIO_IN_DUAL_INTERNAL:
-               reg_changes.value |= CPCAP_BIT_MB_ON1R
-                       | CPCAP_BIT_MIC1_MUX | CPCAP_BIT_MIC1_PGA_EN
-                       | CPCAP_BIT_MB_ON1L | CPCAP_BIT_MIC2_MUX
-                       | CPCAP_BIT_MIC2_PGA_EN;
-               break;
-
-       case CPCAP_AUDIO_IN_DUAL_EXTERNAL:
-               reg_changes.value |= CPCAP_BIT_RX_R_ENCODE
-                       | CPCAP_BIT_RX_L_ENCODE;
-               break;
-
-       case CPCAP_AUDIO_IN_BT_MONO:
-       default:
-               reg_changes.value = 0;
-               break;
-       }
-
-       reg_changes.mask = reg_changes.value | prev_input_data;
-       prev_input_data = reg_changes.value;
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_TXI,
-                               reg_changes.value, reg_changes.mask);
-}
-
-static void cpcap_audio_configure_power(int power)
-{
-       static int previous_power = -1;
-
-       pr_debug("%s() called with power= %d\n", __func__, power);
-
-       if (power == previous_power)
-               return;
-
-       if (IS_ERR_OR_NULL(audio_reg)) {
-               E("audio_reg not valid for regulator setup\n");
-               return;
-       }
-
-       if (power) {
-               pr_info("%s: regulator -> enable\n", __func__);
-               regulator_enable(audio_reg);
-               regulator_set_mode(audio_reg, REGULATOR_MODE_NORMAL);
-               mdelay(SLEEP_ACTIVATE_POWER_DELAY_MS);
-       } else {
-               pr_info("%s: regulator -> standby\n", __func__);
-               regulator_set_mode(audio_reg, REGULATOR_MODE_STANDBY);
-               regulator_disable(audio_reg);
-       }
-
-       previous_power = power;
-}
-
-void cpcap_audio_register_dump(struct cpcap_audio_state *state)
-{
-       unsigned short reg_val = 0;
-
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_VAUDIOC, &reg_val);
-       printk(KERN_INFO "0x200[512] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_CC, &reg_val);
-       printk(KERN_INFO "0x201[513] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_CDI, &reg_val);
-       printk(KERN_INFO "0x202[514] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_SDAC, &reg_val);
-       printk(KERN_INFO "0x203[515] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_SDACDI, &reg_val);
-       printk(KERN_INFO "0x204[516] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_TXI, &reg_val);
-       printk(KERN_INFO "0x205[517] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_TXMP, &reg_val);
-       printk(KERN_INFO "0x206[518] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_RXOA, &reg_val);
-       printk(KERN_INFO "0x207[519] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_RXVC, &reg_val);
-       printk(KERN_INFO "0x208[520] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_RXCOA, &reg_val);
-       printk(KERN_INFO "0x209[521] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_RXSDOA, &reg_val);
-       printk(KERN_INFO "0x20A[522] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_RXEPOA, &reg_val);
-       printk(KERN_INFO "0x20B[523] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_RXLL, &reg_val);
-       printk(KERN_INFO "0x20C[524] = %x\n", reg_val);
-       cpcap_regacc_read(state->cpcap, CPCAP_REG_A2LA, &reg_val);
-       printk(KERN_INFO "0x20D[525] = %x\n", reg_val);
-}
-
-static inline bool should_power_on(struct cpcap_audio_state *state)
-{
-       if (state->codec_mode != CPCAP_AUDIO_CODEC_OFF &&
-                       state->codec_mode != CPCAP_AUDIO_CODEC_CLOCK_ONLY)
-               return true;
-
-       if (state->stdac_mode != CPCAP_AUDIO_STDAC_OFF)
-               return true;
-
-       if (state->codec_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
-                       state->codec_primary_speaker !=
-                               CPCAP_AUDIO_OUT_BT_MONO)
-               return true;
-
-       if (state->stdac_primary_speaker != CPCAP_AUDIO_OUT_NONE)
-               return true;
-
-       if (state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE)
-               return true;
-
-       if (state->microphone != CPCAP_AUDIO_IN_NONE &&
-                       state->microphone != CPCAP_AUDIO_IN_BT_MONO)
-               return true;
-
-       return false;
-}
-
-void cpcap_audio_set_audio_state(struct cpcap_audio_state *state)
-{
-       bool power_on;
-       struct cpcap_audio_state *prev = &current_state;
-
-       if (state->codec_mute == CPCAP_AUDIO_CODEC_BYPASS_LOOP)
-               state->codec_mode = CPCAP_AUDIO_CODEC_ON;
-
-       if (state->codec_mode == CPCAP_AUDIO_CODEC_OFF ||
-                       state->codec_mode == CPCAP_AUDIO_CODEC_CLOCK_ONLY ||
-                       state->rat_type == CPCAP_AUDIO_RAT_CDMA)
-               state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;
-       else
-               state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE;
-
-       if (state->stdac_mode != CPCAP_AUDIO_STDAC_ON)
-               state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;
-       else
-               state->stdac_mute = CPCAP_AUDIO_STDAC_UNMUTE;
-
-       if (state->stdac_mode == CPCAP_AUDIO_STDAC_CLOCK_ONLY)
-               state->stdac_mode = CPCAP_AUDIO_STDAC_ON;
-
-       power_on = should_power_on(state);
-
-       if (power_on)
-               cpcap_audio_configure_power(1);
-
-       if (is_speaker_turning_off(state, prev))
-               cpcap_audio_configure_output(state, prev);
-
-       if (is_codec_changed(state, prev) || is_stdac_changed(state, prev)) {
-               int codec_mute = state->codec_mute;
-               int stdac_mute = state->stdac_mute;
-
-               state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;
-               state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;
-
-               cpcap_audio_configure_aud_mute(state, prev);
-
-               prev->codec_mute = state->codec_mute;
-               prev->stdac_mute = state->stdac_mute;
-
-               state->codec_mute = codec_mute;
-               state->stdac_mute = stdac_mute;
-
-               cpcap_audio_configure_codec(state, prev);
-               cpcap_audio_configure_stdac(state, prev);
-       }
-
-       cpcap_audio_configure_analog_source(state, prev);
-
-       cpcap_audio_configure_input(state, prev);
-
-       cpcap_audio_configure_input_gains(state, prev);
-
-       cpcap_audio_configure_output(state, prev);
-
-       cpcap_audio_configure_output_gains(state, prev);
-
-       cpcap_audio_configure_aud_mute(state, prev);
-
-       if (!power_on)
-               cpcap_audio_configure_power(0);
-
-       current_state = *state;
-}
-
-int cpcap_audio_init(struct cpcap_audio_state *state, const char *regulator)
-{
-       logged_cpcap_write(state->cpcap, CPCAP_REG_CC, 0, 0xFFFF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_CDI, 0, 0xBFFF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC, 0, 0xFFF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_SDACDI, 0, 0x3FFF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_TXI, 0, 0xFDF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_TXMP, 0, 0xFFF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA, 0, 0x1FF);
-       /* logged_cpcap_write(state->cpcap, CPCAP_REG_RXVC, 0, 0xFFF); */
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXCOA, 0, 0x7FF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXSDOA, 0, 0x1FFF);
-       logged_cpcap_write(state->cpcap, CPCAP_REG_RXEPOA, 0, 0x7FFF);
-
-       /* Use free running clock for amplifiers */
-       logged_cpcap_write(state->cpcap, CPCAP_REG_A2LA,
-               CPCAP_BIT_A2_FREE_RUN,
-               CPCAP_BIT_A2_FREE_RUN);
-
-       logged_cpcap_write(state->cpcap, CPCAP_REG_GPIO4,
-                          CPCAP_BIT_GPIO4DIR, CPCAP_BIT_GPIO4DIR);
-
-       audio_reg = regulator_get(NULL, regulator);
-
-       if (IS_ERR(audio_reg)) {
-               E("could not get regulator for audio\n");
-               return PTR_ERR(audio_reg);
-       }
-
-       return 0;
-}
-
-int cpcap_set_volume(struct cpcap_device *cpcap, unsigned volume)
-{
-       volume &= 0xF;
-       volume = volume << 12 | volume << 8;
-       return cpcap_regacc_write(cpcap, CPCAP_REG_RXVC, volume, 0xFF00);
-}
diff --git a/drivers/mfd/cpcap-audio.c b/drivers/mfd/cpcap-audio.c
new file mode 100644 (file)
index 0000000..d335083
--- /dev/null
@@ -0,0 +1,351 @@
+/* drivers/mfd/cpcap-audio.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ *      Iliyan Malchev <malchev@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/cpcap-regbits.h>
+#include <linux/spi/cpcap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/cpcap_audio.h>
+#include <linux/spi/cpcap.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/cpcap_audio.h>
+#include <linux/uaccess.h>
+
+#include <mach/cpcap_audio.h>
+
+static struct cpcap_device *cpcap;
+static struct cpcap_audio_platform_data *pdata;
+static unsigned current_output = CPCAP_AUDIO_OUT_SPEAKER;
+static unsigned current_input  = -1U; /* none */
+static unsigned current_volume = CPCAP_AUDIO_OUT_VOL_MAX;
+static unsigned current_in_volume = CPCAP_AUDIO_IN_VOL_MAX;
+
+static int cpcap_audio_set(const struct cpcap_audio_path *path, bool on)
+{
+       int len, rc;
+       const struct cpcap_audio_config_table *entry;
+
+       pr_info("%s: %s %s\n", __func__, path->name, on ? "on" : "off");
+
+       if (!path) {
+               pr_info("%s: no path\n", __func__);
+               return -ENOSYS;
+       }
+
+       if (path->gpio >= 0) {
+               pr_info("%s: %s: enable gpio %d\n", __func__,
+                       path->name, path->gpio);
+               rc = gpio_direction_output(path->gpio, on);
+               if (rc)
+                       pr_err("%s: could not set gpio %d to %d\n", __func__,
+                               path->gpio, on);
+       }
+
+       if (!on)
+               return 0;
+       if (!path->table) {
+               pr_info("%s: no config table for path %s\n", __func__,
+                               path->name);
+               return -ENOSYS;
+       }
+
+       entry = path->table;
+       len = path->table_len;
+       while (len--) {
+               u16 val = entry->val | (pdata->master ? 0 : entry->slave_or);
+               int rc = cpcap_regacc_write(cpcap,
+                               entry->reg,
+                               val,
+                               entry->mask);
+               if (rc) {
+                       pr_err("%s: cpcap_regacc_write %d %x/%x %x failed: %d\n",
+                               __func__,
+                               entry->reg,
+                               entry->val,
+                               entry->slave_or,
+                               entry->mask, rc);
+                       rc = -EIO;
+               }
+               entry++;
+       }
+
+       return 0;
+}
+
+static int cpcap_set_volume(struct cpcap_device *cpcap, unsigned volume)
+{
+       pr_info("%s\n", __func__);
+       volume &= 0xF;
+       volume = volume << 12 | volume << 8;
+       return cpcap_regacc_write(cpcap, CPCAP_REG_RXVC, volume, 0xFF00);
+}
+
+
+static int cpcap_set_mic_volume(struct cpcap_device *cpcap, unsigned volume)
+{
+       pr_info("%s\n", __func__);
+       volume &= 0x1F;
+       /* set the same volume for mic1 and mic2 */
+       volume = volume << 5 | volume;
+       return cpcap_regacc_write(cpcap, CPCAP_REG_TXMP, volume, 0x3FF);
+}
+
+static int cpcap_audio_ctl_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int cpcap_audio_ctl_release(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static DEFINE_MUTEX(cpcap_lock);
+
+static long cpcap_audio_ctl_ioctl(struct file *file, unsigned int cmd,
+                       unsigned long arg)
+{
+       int rc = 0;
+       struct cpcap_audio_output out;
+
+       mutex_lock(&cpcap_lock);
+
+       switch (cmd) {
+       case CPCAP_AUDIO_OUT_SET_OUTPUT:
+               if (copy_from_user(&out, (const void __user *)arg,
+                               sizeof(out))) {
+                       rc = -EFAULT;
+                       goto done;
+               }
+               if (out.id > CPCAP_AUDIO_OUT_MAX) {
+                       pr_err("%s: invalid audio-output selector %d\n",
+                               __func__, out.id);
+                       rc = -EINVAL;
+                       goto done;
+               }
+               switch (out.id) {
+               case CPCAP_AUDIO_OUT_SPEAKER:
+                       pr_info("%s: setting output path to %s\n", __func__,
+                                       pdata->speaker->name);
+                       cpcap_audio_set(pdata->headset, 0);
+                       cpcap_audio_set(pdata->speaker, out.on);
+                       break;
+               case CPCAP_AUDIO_OUT_HEADSET:
+                       pr_info("%s: setting output path to %s\n", __func__,
+                                       pdata->headset->name);
+                       cpcap_audio_set(pdata->speaker, 0);
+                       cpcap_audio_set(pdata->headset, out.on);
+                       break;
+               }
+               current_output = out.id;
+               break;
+       case CPCAP_AUDIO_OUT_GET_OUTPUT:
+               if (copy_to_user((void __user *)arg, &current_output,
+                                       sizeof(unsigned int)))
+                       rc = -EFAULT;
+               break;
+       case CPCAP_AUDIO_IN_SET_INPUT:
+               if (arg > CPCAP_AUDIO_IN_MAX && arg != -1UL) {
+                       pr_err("%s: invalid audio input selector %ld\n",
+                               __func__, arg);
+                       rc = -EINVAL;
+                       goto done;
+               }
+               switch (arg) {
+               case -1UL:
+                       pr_info("%s: turning off input path\n", __func__);
+                       cpcap_audio_set(pdata->mic1, 0);
+                       cpcap_audio_set(pdata->mic2, 0);
+                       break;
+               case CPCAP_AUDIO_IN_MIC1:
+                       pr_info("%s: setting input path to %s\n", __func__,
+                                       pdata->mic1->name);
+                       cpcap_audio_set(pdata->mic2, 0);
+                       cpcap_audio_set(pdata->mic1, 1);
+                       break;
+               case CPCAP_AUDIO_IN_MIC2:
+                       pr_info("%s: setting input path to %s\n", __func__,
+                                       pdata->mic2->name);
+                       cpcap_audio_set(pdata->mic1, 0);
+                       cpcap_audio_set(pdata->mic2, 1);
+                       break;
+               }
+               current_input = arg;
+               break;
+       case CPCAP_AUDIO_IN_GET_INPUT:
+               if (copy_to_user((void __user *)arg, &current_input,
+                                       sizeof(unsigned int)))
+                       rc = -EFAULT;
+               break;
+       case CPCAP_AUDIO_OUT_SET_VOLUME:
+               if (arg > CPCAP_AUDIO_OUT_VOL_MAX) {
+                       pr_err("%s: invalid audio volume %ld\n",
+                               __func__, arg);
+                       rc = -EINVAL;
+                       goto done;
+               }
+               rc = cpcap_set_volume(cpcap, (unsigned)arg);
+               if (rc < 0) {
+                       pr_err("%s: could not set audio volume to %ld: %d\n",
+                               __func__, arg, rc);
+                       goto done;
+               }
+               current_volume = arg;
+               break;
+       case CPCAP_AUDIO_IN_SET_VOLUME:
+               if (arg > CPCAP_AUDIO_IN_VOL_MAX) {
+                       pr_err("%s: invalid audio-input volume %ld\n",
+                               __func__, arg);
+                       rc = -EINVAL;
+                       goto done;
+               }
+               rc = cpcap_set_mic_volume(cpcap, (unsigned)arg);
+               if (rc < 0) {
+                       pr_err("%s: could not set audio-input"\
+                               " volume to %ld: %d\n", __func__, arg, rc);
+                       goto done;
+               }
+               current_in_volume = arg;
+               break;
+       case CPCAP_AUDIO_OUT_GET_VOLUME:
+               if (copy_to_user((void __user *)arg, &current_volume,
+                                       sizeof(unsigned int))) {
+                       rc = -EFAULT;
+                       goto done;
+               }
+               break;
+       case CPCAP_AUDIO_IN_GET_VOLUME:
+               if (copy_to_user((void __user *)arg, &current_in_volume,
+                                       sizeof(unsigned int))) {
+                       rc = -EFAULT;
+                       goto done;
+               }
+               break;
+       }
+
+done:
+       mutex_unlock(&cpcap_lock);
+       return rc;
+}
+
+static const struct file_operations cpcap_audio_ctl_fops = {
+       .open = cpcap_audio_ctl_open,
+       .release = cpcap_audio_ctl_release,
+       .unlocked_ioctl = cpcap_audio_ctl_ioctl,
+};
+
+static struct miscdevice cpcap_audio_ctl = {
+       .name = "audio_ctl",
+       .minor = MISC_DYNAMIC_MINOR,
+       .fops = &cpcap_audio_ctl_fops,
+};
+
+static int cpcap_audio_probe(struct platform_device *pdev)
+{
+       int rc;
+       struct regulator *audio_reg;
+
+       pr_info("%s\n", __func__);
+
+       cpcap = platform_get_drvdata(pdev);
+       BUG_ON(!cpcap);
+
+       pdata = pdev->dev.platform_data;
+       BUG_ON(!pdata);
+
+       audio_reg = regulator_get(NULL, "vaudio");
+       if (IS_ERR(audio_reg)) {
+               rc = PTR_ERR(audio_reg);
+               pr_err("%s: could not get vaudio regulator: %d\n", __func__,
+                       rc);
+               return rc;
+       }
+
+       rc = regulator_enable(audio_reg);
+       if (rc) {
+               pr_err("%s: failed to enable vaudio regulator: %d\n", __func__,
+                       rc);
+               goto fail;
+       }
+
+       if (pdata->speaker->gpio >= 0) {
+               tegra_gpio_enable(pdata->speaker->gpio);
+               rc = gpio_request(pdata->speaker->gpio, pdata->speaker->name);
+               if (rc) {
+                       pr_err("%s: could not get speaker GPIO %d: %d\n",
+                               __func__, pdata->speaker->gpio, rc);
+                       goto fail1;
+               }
+       }
+
+       if (pdata->headset->gpio >= 0) {
+               tegra_gpio_enable(pdata->headset->gpio);
+               rc = gpio_request(pdata->headset->gpio, pdata->headset->name);
+               if (rc) {
+                       pr_err("%s: could not get headset GPIO %d: %d\n",
+                               __func__, pdata->headset->gpio, rc);
+                       goto fail2;
+               }
+       }
+
+       cpcap_audio_set(pdata->speaker, 1);
+       cpcap_set_volume(cpcap, current_volume);
+       cpcap_set_mic_volume(cpcap, current_in_volume);
+
+       rc = misc_register(&cpcap_audio_ctl);
+       if (rc < 0) {
+               pr_err("%s: failed to register misc device: %d\n", __func__,
+                               rc);
+               goto fail3;
+       }
+
+       return rc;
+
+fail3:
+       if (pdata->headset->gpio >= 0)
+               gpio_free(pdata->headset->gpio);
+fail2:
+       if (pdata->speaker->gpio >= 0)
+               gpio_free(pdata->speaker->gpio);
+fail1:
+       regulator_disable(audio_reg);
+fail:
+       regulator_put(audio_reg);
+       return rc;
+}
+
+static struct platform_driver cpcap_audio_driver = {
+       .probe = cpcap_audio_probe,
+       .driver = {
+               .name = "cpcap_audio",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init cpcap_audio_init(void)
+{
+       return cpcap_driver_register(&cpcap_audio_driver);
+}
+
+module_init(cpcap_audio_init);
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tegra-cpcap-audio.c b/drivers/mfd/tegra-cpcap-audio.c
deleted file mode 100644 (file)
index 5a78d14..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/* drivers/mfd/cpcap-audio.c
- *
- * Copyright (C) 2010 Google, Inc.
- *
- * Author:
- *      Iliyan Malchev <malchev@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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/module.h>
-#include <linux/kernel.h>
-#include <linux/spi/cpcap-regbits.h>
-#include <linux/spi/cpcap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/cpcap_audio.h>
-#include <linux/spi/cpcap.h>
-#include <linux/mutex.h>
-#include <linux/fs.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/miscdevice.h>
-#include <linux/cpcap_audio.h>
-#include <linux/uaccess.h>
-
-#include <mach/cpcap_audio.h>
-
-static struct cpcap_device *cpcap;
-static struct cpcap_audio_platform_data *pdata;
-static unsigned current_output = CPCAP_AUDIO_OUT_SPEAKER;
-static unsigned current_input  = -1U; /* none */
-static unsigned current_volume = CPCAP_AUDIO_OUT_VOL_MAX;
-static unsigned current_in_volume = CPCAP_AUDIO_IN_VOL_MAX;
-
-static int cpcap_set_volume(struct cpcap_device *cpcap, unsigned volume)
-{
-       pr_info("%s\n", __func__);
-       volume &= 0xF;
-       volume = volume << 12 | volume << 8;
-       return cpcap_regacc_write(cpcap, CPCAP_REG_RXVC, volume, 0xFF00);
-}
-
-
-static int cpcap_set_mic_volume(struct cpcap_device *cpcap, unsigned volume)
-{
-       pr_info("%s\n", __func__);
-       volume &= 0x1F;
-       /* set the same volume for mic1 and mic2 */
-       volume = volume << 5 | volume;
-       return cpcap_regacc_write(cpcap, CPCAP_REG_TXMP, volume, 0x3FF);
-}
-
-static int cpcap_audio_ctl_open(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static int cpcap_audio_ctl_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static DEFINE_MUTEX(cpcap_lock);
-
-static long cpcap_audio_ctl_ioctl(struct file *file, unsigned int cmd,
-                       unsigned long arg)
-{
-       int rc = 0;
-       struct cpcap_audio_stream in, out;
-
-       mutex_lock(&cpcap_lock);
-
-       switch (cmd) {
-       case CPCAP_AUDIO_OUT_SET_OUTPUT:
-               if (copy_from_user(&out, (const void __user *)arg,
-                               sizeof(out))) {
-                       rc = -EFAULT;
-                       goto done;
-               }
-               if (out.id > CPCAP_AUDIO_OUT_MAX) {
-                       pr_err("%s: invalid audio-output selector %d\n",
-                               __func__, out.id);
-                       rc = -EINVAL;
-                       goto done;
-               }
-               switch (out.id) {
-               case CPCAP_AUDIO_OUT_SPEAKER:
-                       pr_info("%s: setting output path to speaker\n",
-                                       __func__);
-                       pdata->state->stdac_primary_speaker =
-                                       CPCAP_AUDIO_OUT_NONE;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       if (!out.on) {
-                               if (pdata->speaker_gpio >= 0)
-                                       gpio_direction_output(
-                                               pdata->speaker_gpio, 0);
-                               break;
-                       }
-
-                       pr_info("%s: enable speaker\n", __func__);
-
-                       pdata->state->stdac_primary_speaker =
-                                       CPCAP_AUDIO_OUT_LOUDSPEAKER;
-                       gpio_direction_output(pdata->headset_gpio, 0);
-                       gpio_direction_output(pdata->speaker_gpio, 1);
-                       break;
-               case CPCAP_AUDIO_OUT_HEADSET:
-                       pr_info("%s: setting output path to headset\n",
-                                       __func__);
-                       pdata->state->stdac_primary_speaker =
-                                       CPCAP_AUDIO_OUT_NONE;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       if (!out.on) {
-                               if (pdata->headset_gpio >= 0)
-                                       gpio_direction_output(
-                                               pdata->headset_gpio, 0);
-                               break;
-                       }
-                       pdata->state->stdac_primary_speaker =
-                                       CPCAP_AUDIO_OUT_STEREO_HEADSET;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       gpio_direction_output(pdata->speaker_gpio, 0);
-                       gpio_direction_output(pdata->headset_gpio, 1);
-                       break;
-               case CPCAP_AUDIO_OUT_HEADSET_AND_SPEAKER:
-                       pr_info("%s: setting output path to "
-                                       "headset + speaker\n", __func__);
-                       pdata->state->stdac_primary_speaker =
-                                       CPCAP_AUDIO_OUT_NONE;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       if (!out.on) {
-                               if (pdata->headset_gpio >= 0)
-                                       gpio_direction_output(
-                                               pdata->headset_gpio, 0);
-                                       gpio_direction_output(
-                                               pdata->speaker_gpio, 0);
-                               break;
-                       }
-                       pdata->state->stdac_primary_speaker =
-                                       CPCAP_AUDIO_OUT_STEREO_HEADSET;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       gpio_direction_output(pdata->speaker_gpio, 1);
-                       gpio_direction_output(pdata->headset_gpio, 1);
-                       break;
-               }
-               current_output = out.id;
-               break;
-       case CPCAP_AUDIO_OUT_GET_OUTPUT:
-               if (copy_to_user((void __user *)arg, &current_output,
-                                       sizeof(unsigned int)))
-                       rc = -EFAULT;
-               break;
-       case CPCAP_AUDIO_IN_SET_INPUT:
-               if (copy_from_user(&in, (const void __user *)arg,
-                               sizeof(in))) {
-                       rc = -EFAULT;
-                       goto done;
-               }
-
-               if (in.id > CPCAP_AUDIO_IN_MAX) {
-                       pr_err("%s: invalid audio input selector %d\n",
-                               __func__, in.id);
-                       rc = -EINVAL;
-                       goto done;
-               }
-
-               pr_info("%s: muting current input before switch\n", __func__);
-
-               pdata->state->microphone = CPCAP_AUDIO_IN_NONE;
-               pdata->state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;
-               pdata->state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;
-               pdata->state->codec_mode = CPCAP_AUDIO_CODEC_OFF;
-               pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_OFF;
-               cpcap_audio_set_audio_state(pdata->state);
-
-               if (!in.on)
-                       break;
-
-               pdata->state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE;
-               pdata->state->stdac_mute = CPCAP_AUDIO_STDAC_UNMUTE;
-               pdata->state->codec_mode = CPCAP_AUDIO_CODEC_ON;
-               pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_ON;
-
-               switch (in.id) {
-               case CPCAP_AUDIO_IN_MIC1:
-                       pr_info("%s: setting input path to on-board mic\n",
-                                       __func__);
-                       pdata->state->microphone = CPCAP_AUDIO_IN_HANDSET;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       cpcap_audio_register_dump(pdata->state);
-                       break;
-               case CPCAP_AUDIO_IN_MIC2:
-                       pr_info("%s: setting input path to headset mic\n",
-                                       __func__);
-                       pdata->state->microphone = CPCAP_AUDIO_IN_HEADSET;
-                       cpcap_audio_set_audio_state(pdata->state);
-                       cpcap_audio_register_dump(pdata->state);
-                       break;
-               }
-               current_input = arg;
-               break;
-       case CPCAP_AUDIO_IN_GET_INPUT:
-               if (copy_to_user((void __user *)arg, &current_input,
-                                       sizeof(unsigned int)))
-                       rc = -EFAULT;
-               break;
-       case CPCAP_AUDIO_OUT_SET_VOLUME:
-               if (arg > CPCAP_AUDIO_OUT_VOL_MAX) {
-                       pr_err("%s: invalid audio volume %ld\n",
-                               __func__, arg);
-                       rc = -EINVAL;
-                       goto done;
-               }
-               rc = cpcap_set_volume(cpcap, (unsigned)arg);
-               if (rc < 0) {
-                       pr_err("%s: could not set audio volume to %ld: %d\n",
-                               __func__, arg, rc);
-                       goto done;
-               }
-               current_volume = arg;
-               break;
-       case CPCAP_AUDIO_IN_SET_VOLUME:
-               if (arg > CPCAP_AUDIO_IN_VOL_MAX) {
-                       pr_err("%s: invalid audio-input volume %ld\n",
-                               __func__, arg);
-                       rc = -EINVAL;
-                       goto done;
-               }
-               rc = cpcap_set_mic_volume(cpcap, (unsigned)arg);
-               if (rc < 0) {
-                       pr_err("%s: could not set audio-input"\
-                               " volume to %ld: %d\n", __func__, arg, rc);
-                       goto done;
-               }
-               current_in_volume = arg;
-               break;
-       case CPCAP_AUDIO_OUT_GET_VOLUME:
-               if (copy_to_user((void __user *)arg, &current_volume,
-                                       sizeof(unsigned int))) {
-                       rc = -EFAULT;
-                       goto done;
-               }
-               break;
-       case CPCAP_AUDIO_IN_GET_VOLUME:
-               if (copy_to_user((void __user *)arg, &current_in_volume,
-                                       sizeof(unsigned int))) {
-                       rc = -EFAULT;
-                       goto done;
-               }
-               break;
-       }
-
-done:
-       mutex_unlock(&cpcap_lock);
-       return rc;
-}
-
-static const struct file_operations cpcap_audio_ctl_fops = {
-       .open = cpcap_audio_ctl_open,
-       .release = cpcap_audio_ctl_release,
-       .unlocked_ioctl = cpcap_audio_ctl_ioctl,
-};
-
-static struct miscdevice cpcap_audio_ctl = {
-       .name = "audio_ctl",
-       .minor = MISC_DYNAMIC_MINOR,
-       .fops = &cpcap_audio_ctl_fops,
-};
-
-static int cpcap_audio_probe(struct platform_device *pdev)
-{
-       int rc;
-
-       pr_info("%s\n", __func__);
-
-       cpcap = platform_get_drvdata(pdev);
-       BUG_ON(!cpcap);
-
-       pdata = pdev->dev.platform_data;
-       BUG_ON(!pdata);
-
-       if (pdata->speaker_gpio >= 0) {
-               tegra_gpio_enable(pdata->speaker_gpio);
-               rc = gpio_request(pdata->speaker_gpio, "speaker");
-               if (rc) {
-                       pr_err("%s: could not get speaker GPIO %d: %d\n",
-                               __func__, pdata->speaker_gpio, rc);
-                       goto fail1;
-               }
-       }
-
-       if (pdata->headset_gpio >= 0) {
-               tegra_gpio_enable(pdata->headset_gpio);
-               rc = gpio_request(pdata->headset_gpio, "headset");
-               if (rc) {
-                       pr_err("%s: could not get headset GPIO %d: %d\n",
-                               __func__, pdata->headset_gpio, rc);
-                       goto fail2;
-               }
-       }
-
-       pdata->state->cpcap = cpcap;
-       if (cpcap_audio_init(pdata->state, pdata->regulator))
-               goto fail3;
-       cpcap_audio_register_dump(pdata->state);
-
-       pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_ON;
-       cpcap_audio_set_audio_state(pdata->state);
-       cpcap_audio_register_dump(pdata->state);
-
-       rc = misc_register(&cpcap_audio_ctl);
-       if (rc < 0) {
-               pr_err("%s: failed to register misc device: %d\n", __func__,
-                               rc);
-               goto fail3;
-       }
-
-       return rc;
-
-fail3:
-       if (pdata->headset_gpio >= 0)
-               gpio_free(pdata->headset_gpio);
-fail2:
-       if (pdata->headset_gpio >= 0)
-               tegra_gpio_disable(pdata->headset_gpio);
-       if (pdata->speaker_gpio >= 0)
-               gpio_free(pdata->speaker_gpio);
-fail1:
-       if (pdata->speaker_gpio >= 0)
-               tegra_gpio_disable(pdata->speaker_gpio);
-       return rc;
-}
-
-static struct platform_driver cpcap_audio_driver = {
-       .probe = cpcap_audio_probe,
-       .driver = {
-               .name = "cpcap_audio",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init tegra_cpcap_audio_init(void)
-{
-       return cpcap_driver_register(&cpcap_audio_driver);
-}
-
-module_init(tegra_cpcap_audio_init);
-MODULE_LICENSE("GPL");
index 3d3766e03858e2bd466ccb4a16d20eb0246ebd2a..50097231b276df7df35dea857d8ce21b4689322e 100644 (file)
 
 #define CPCAP_AUDIO_MAGIC 'c'
 
-#define CPCAP_AUDIO_OUT_SPEAKER                        0
-#define CPCAP_AUDIO_OUT_HEADSET                        1
-#define CPCAP_AUDIO_OUT_HEADSET_AND_SPEAKER    2
-#define CPCAP_AUDIO_OUT_MAX                    2
-
-struct cpcap_audio_stream {
-       unsigned id; /* e.g., CPCAP_AUDIO_OUT_SPEAKER or CPCAP_AUDIO_IN_MIC1 */
-       int on; /* enable/disable for output, unmute/mute for input */
+#define CPCAP_AUDIO_OUT_SPEAKER                0
+#define CPCAP_AUDIO_OUT_HEADSET                1
+#define CPCAP_AUDIO_OUT_MAX            1
+
+struct cpcap_audio_output {
+       int id; /* e.g., CPCAP_AUDIO_OUT_SPEAKER */
+       int on;
 };
 
 #define CPCAP_AUDIO_OUT_SET_OUTPUT _IOW(CPCAP_AUDIO_MAGIC, 0, \
-                       const struct cpcap_audio_stream *)
+                       struct cpcap_audio_output *)
 
 #define CPCAP_AUDIO_OUT_VOL_MIN 0
 #define CPCAP_AUDIO_OUT_VOL_MAX 15
@@ -50,11 +49,9 @@ struct cpcap_audio_stream {
 #define CPCAP_AUDIO_IN_MIC2            1
 #define CPCAP_AUDIO_IN_MAX             1
 
-#define CPCAP_AUDIO_IN_SET_INPUT   _IOW(CPCAP_AUDIO_MAGIC, 4, \
-                       const struct cpcap_audio_stream *)
+#define CPCAP_AUDIO_IN_SET_INPUT   _IOW(CPCAP_AUDIO_MAGIC, 4, unsigned int)
 
-#define CPCAP_AUDIO_IN_GET_INPUT   _IOR(CPCAP_AUDIO_MAGIC, 5, \
-                       struct cpcap_audio_stream *)
+#define CPCAP_AUDIO_IN_GET_INPUT   _IOR(CPCAP_AUDIO_MAGIC, 5, unsigned int *)
 
 #define CPCAP_AUDIO_IN_VOL_MIN 0
 #define CPCAP_AUDIO_IN_VOL_MAX 31