summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig60
-rw-r--r--sound/Makefile7
-rw-r--r--sound/ab8500_codec.c6697
-rw-r--r--sound/ab8500_codec_v1_0.c6405
-rw-r--r--sound/arm/Kconfig12
-rw-r--r--sound/arm/Makefile4
-rw-r--r--sound/arm/u8500_alsa_ab8500.c2691
-rw-r--r--sound/arm/u8500_alsa_ab8500.h165
-rw-r--r--sound/arm/u8500_alsa_hdmi.c936
-rw-r--r--sound/pci/hda/patch_realtek.c4
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/codecs/Kconfig22
-rw-r--r--sound/soc/codecs/Makefile17
-rw-r--r--sound/soc/codecs/ab3550.c1429
-rw-r--r--sound/soc/codecs/ab3550.h333
-rw-r--r--sound/soc/codecs/ab5500.c1691
-rw-r--r--sound/soc/codecs/ab5500.h408
-rw-r--r--sound/soc/codecs/ab8500_audio.c2476
-rw-r--r--sound/soc/codecs/ab8500_audio.h569
-rw-r--r--sound/soc/codecs/av8100_audio.c453
-rw-r--r--sound/soc/codecs/av8100_audio.h162
-rw-r--r--sound/soc/codecs/cg29xx.c773
-rw-r--r--sound/soc/codecs/cg29xx.h41
-rw-r--r--sound/soc/ux500/Kconfig57
-rw-r--r--sound/soc/ux500/Makefile47
-rw-r--r--sound/soc/ux500/u5500.c108
-rw-r--r--sound/soc/ux500/u8500.c244
-rw-r--r--sound/soc/ux500/ux500_ab3550.c76
-rw-r--r--sound/soc/ux500/ux500_ab3550.h19
-rw-r--r--sound/soc/ux500/ux500_ab5500.c57
-rw-r--r--sound/soc/ux500/ux500_ab5500.h24
-rw-r--r--sound/soc/ux500/ux500_ab8500.c561
-rw-r--r--sound/soc/ux500/ux500_av8100.c168
-rw-r--r--sound/soc/ux500/ux500_av8100.h19
-rw-r--r--sound/soc/ux500/ux500_cg29xx.c110
-rw-r--r--sound/soc/ux500/ux500_cg29xx.h19
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c1006
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h79
-rw-r--r--sound/soc/ux500/ux500_pcm.c429
-rw-r--r--sound/soc/ux500/ux500_pcm.h44
-rw-r--r--sound/u8500_acodec_ab8500.c2523
42 files changed, 30946 insertions, 3 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index 1fef141ef8e..35bb190ed54 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -23,6 +23,66 @@ menuconfig SOUND
and read <file:Documentation/sound/oss/README.modules>; the module
will be called soundcore.
+# added for U8500 audio codec device
+config U8500_ACODEC
+ tristate "U8500 audio codec generic module (used both by SAA and ALSA)"
+ depends on STM_MSP_I2S
+ default Y
+ help
+ Say Y here if you have a U8500 based device
+ and want to use its audio codec chip.
+
+ To compile this driver as a module, choose M here: the module
+ will be called u8500mod_acodec.
+
+choice
+ prompt "Audio codec type"
+ depends on U8500_ACODEC
+ default U8500_AB8500_ED
+
+ config U8500_AB8500_ED
+ bool "U8500 ab8500 v0 audio codec"
+
+ config U8500_AB8500_CUT10
+ bool "U8500 ab8500 v1.x audio codec"
+
+endchoice
+
+menu "Debug level for ux500 audio drivers"
+config STM_ACODEC_DEBUG
+ int "STM ACODEC Debug Level"
+ depends on U8500_ACODEC
+ default 0
+ help
+ Sets the ACODEC debug ON/OFF for U8500 SoC
+ * 0 OFF
+ * 1 ON
+
+config STM_ALSA_DEBUG
+ int "STM ALSA Debug Level"
+ depends on SND_U8500_ALSA || SND_U8500_ALSA_AB8500
+ default 0
+ help
+ Sets the ALSA debug ON/OFF for U8500 SoC
+ * 0 OFF
+ * 1 ON
+endmenu
+
+choice
+ prompt "Driver mode"
+ depends on U8500_ACODEC
+ default U8500_ACODEC_DMA
+
+ config U8500_ACODEC_DMA
+ bool "DMA mode"
+
+ config U8500_ACODEC_POLL
+ bool "Polling mode"
+
+ config U8500_ACODEC_INTR
+ bool "Interrupt mode"
+endchoice
+
if SOUND
config SOUND_OSS_CORE
diff --git a/sound/Makefile b/sound/Makefile
index ce9132b1c39..b5963c8b70d 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -16,4 +16,11 @@ ifeq ($(CONFIG_SND),y)
obj-y += last.o
endif
+obj-$(CONFIG_U8500_ACODEC) += u8500mod_acodec.o
+ifeq ($(CONFIG_U8500_AB8500_CUT10),y)
+ u8500mod_acodec-objs := u8500_acodec_ab8500.o ab8500_codec_v1_0.o
+else
+ u8500mod_acodec-objs := u8500_acodec_ab8500.o ab8500_codec.o
+endif
+
soundcore-objs := sound_core.o
diff --git a/sound/ab8500_codec.c b/sound/ab8500_codec.c
new file mode 100644
index 00000000000..fd4975bbdce
--- /dev/null
+++ b/sound/ab8500_codec.c
@@ -0,0 +1,6697 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: ST-Ericsson
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+ /*----------------------------------------------------------------------------
+ * Includes
+ *---------------------------------------------------------------------------*/
+#include <mach/ab8500_codec.h>
+#include <mach/ab8500_codec_p.h>
+
+/*--------------------------------------------------------------------------*
+ * debug stuff *
+ *--------------------------------------------------------------------------*/
+#ifdef __DEBUG
+#define MY_DEBUG_LEVEL_VAR_NAME myDebugLevel_AB8500_CODEC
+#define MY_DEBUG_ID myDebugID_AB8500_CODEC
+PRIVATE t_dbg_level MY_DEBUG_LEVEL_VAR_NAME = DEBUG_LEVEL0;
+PRIVATE t_dbg_id MY_DEBUG_ID = AB8500_CODEC_HCL_DBG_ID;
+#endif
+
+/*--------------------------------------------------------------------------*
+ * Global data for interrupt mode management *
+ *--------------------------------------------------------------------------*/
+PRIVATE t_ab8500_codec_system_context g_ab8500_codec_system_context;
+
+/*--------------------------------------------------------------------------*
+ * Default Values *
+ *--------------------------------------------------------------------------*/
+#define AB8500_CODEC_DEFAULT_SLAVE_ADDRESS_OF_CODEC 0xD
+#define AB8500_CODEC_DEFAULT_DIRECTION AB8500_CODEC_DIRECTION_OUT
+
+#define AB8500_CODEC_DEFAULT_MODE_IN AB8500_CODEC_MODE_VOICE
+#define AB8500_CODEC_DEFAULT_MODE_OUT AB8500_CODEC_MODE_VOICE
+
+#define AB8500_CODEC_DEFAULT_INPUT_SRC AB8500_CODEC_SRC_MICROPHONE_1A
+#define AB8500_CODEC_DEFAULT_OUTPUT_DEST AB8500_CODEC_DEST_HEADSET
+
+#define AB8500_CODEC_DEFAULT_VOLUME_LEFT_IN 75
+#define AB8500_CODEC_DEFAULT_VOLUME_RIGHT_IN 75
+#define AB8500_CODEC_DEFAULT_VOLUME_LEFT_OUT 75
+#define AB8500_CODEC_DEFAULT_VOLUME_RIGHT_OUT 75
+
+/*---------------------------------------------------------------------
+ * PRIVATE APIs
+ *--------------------------------------------------------------------*/
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch1(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch2(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch3(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch4(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch1(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state);
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch2(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state);
+PRIVATE t_ab8500_codec_error ab8500_codec_SetModeAndDirectionUpdateCR(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_SetSrcVolumeUpdateCR(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_SetDestVolumeUpdateCR(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionIN(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionOUT(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_DestPowerControlUpdateCR(void);
+
+/********************************************************************************************/
+/* Name: ab8500_codec_SingleWrite */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_SingleWrite(t_uint8 register_offset,
+ t_uint8 data)
+{
+ return (t_ab8500_codec_error) (AB8500_CODEC_Write
+ (register_offset, 0x01, &data));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_SingleRead */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_SingleRead(t_uint8 register_offset,
+ t_uint8 data)
+{
+ t_uint8 dummy_data = 0xAA;
+
+ return (t_ab8500_codec_error) (AB8500_CODEC_Read
+ (register_offset, 0x01, &dummy_data,
+ &data));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR0 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR0(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr0_powerup,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR0_POWERUP);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr0_enaana,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR0_ENAANA);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR0, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR1 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR1(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr1_swreset,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR1_SWRESET);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR1, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR2 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR2(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr2_enad1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR2_ENAD1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr2_enad2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR2_ENAD2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr2_enad3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR2_ENAD3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr2_enad4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR2_ENAD4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr2_enad5,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR2_ENAD5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr2_enad6,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR2_ENAD6);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR2, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR3 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR3(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr3_enda1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR3_ENDA1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr3_enda2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR3_ENDA2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr3_enda3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR3_ENDA3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr3_enda4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR3_ENDA4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr3_enda5,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR3_ENDA5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr3_enda6,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR3_ENDA6);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR3, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR4 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR4(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr4_lowpowhs,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR4_LOWPOWHS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr4_lowpowdachs,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR4_LOWPOWDACHS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr4_lowpowear,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR4_LOWPOWEAR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr4_ear_sel_cm,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR4_EAR_SEL_CM);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr4_hs_hp_dis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR4_HS_HP_DIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr4_ear_hp_dis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR4_EAR_HP_DIS);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR4, value));
+}
+#endif
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR5 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR5(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_enmic1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_ENMIC1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_enmic2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_ENMIC2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_enlinl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_ENLINL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_enlinr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_ENLINR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_mutmic1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_MUTMIC1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_mutmic2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_MUTMIC2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_mutlinl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_MUTELINL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr5_mutlinr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR5_MUTELINR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR5, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR6 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR6(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr6_endmic1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR6_ENDMIC1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr6_endmic2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR6_ENDMIC2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr6_endmic3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR6_ENDMIC3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr6_endmic4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR6_ENDMIC4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr6_endmic5,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR6_ENDMIC5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr6_endmic6,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR6_ENDMIC6);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR6, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR7 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR7(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_mic1sel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_MIC1SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_linrsel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_LINRSEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_endrvhsl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_ENDRVHSL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_endrvhsr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_ENDRVHSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_enadcmic,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_ENADCMIC);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_enadclinl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_ENADCLINL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr7_enadclinr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR7_ENADCLINR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR7, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR8 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR8(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_cp_dis_pldwn,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_CP_DIS_PLDWN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_enear,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENEAR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_enhsl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENHSL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_enhsr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENHSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_enhfl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENHFL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_enhfr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENHFR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_envibl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENVIBL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr8_envibr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR8_ENVIBR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR8, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR9 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR9(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endacear,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACEAR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endachsl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACHSL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endachsr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACHSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endachfl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACHFL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endachfr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACHFR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endacvibl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACVIBL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr9_endacvibr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR9_ENADACVIBR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR9, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR10 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR10(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_muteear,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEEAR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_mutehsl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEHSL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_mutehsr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEHSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_mutehfl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEHFL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_mutehfr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEHFR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_mutevibl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEVIBL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr10_mutevibr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR10_MUTEVIBR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR10, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR11 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR11(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_earshortpwd,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_ENSHORTPWD);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_earshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_EARSHORTDIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_hslshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_HSLSHORTDIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_hsrshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_HSRSHORTDIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_hflshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_HFLSHORTDIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_hfrshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_HFRSHORTDIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_viblshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_VIBLSHORTDIS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr11_vibrshortdis,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR11_VIBRSHORTDIS);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR11, value));
+}
+
+#endif
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR12 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR12(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr12_encphs,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR12_ENCPHS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr12_hsautotime,
+ AB8500_CODEC_MASK_THREE_BITS, AB8500_CODEC_CR12_HSAUTOTIME);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr12_hsautoensel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR12_HSAUTOENSEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr12_hsautoen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR12_HSAUTOEN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR12, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR13 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR13(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr13_envdet_hthresh,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR13_ENVDET_HTHRESH);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr13_envdet_lthresh,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR13_ENVDET_LTHRESH);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR13, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR14 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR14(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr14_smpslven,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR14_SMPSLVEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr14_envdetsmpsen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR14_ENVDETSMPSEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr14_cplven,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR14_CPLVEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr14_envdetcpen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR14_ENVDETCPEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr14_envet_time,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR14_ENVDET_TIME);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR14, value));
+}
+#endif
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR15 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR15(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmtovibl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMTOVIBL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmtovibr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMTOVIBR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmlctrl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMLCTRL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmrctrl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMRCTRL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmnlctrl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMNLCTRL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmplctrl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMPLCTRL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmnrctrl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMNRCTRL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr15_pwmprctrl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR15_PWMPRCTRL);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR15, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR16 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR16(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr16_pwmnlpol,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR16_PWMNLPOL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr16_pwmnldutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS, AB8500_CODEC_CR16_PWMNLDUTYCYCLE);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR16, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR17 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR17(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr17_pwmplpol,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR17_PWMPLPOL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr17_pwmpldutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS, AB8500_CODEC_CR17_PWMLPDUTYCYCLE);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR17, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR18 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR18(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr18_pwmnrpol,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR18_PWMNRPOL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr18_pwmnrdutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS, AB8500_CODEC_CR18_PWMNRDUTYCYCLE);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR18, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR19 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR19(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr19_pwmprpol,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR19_PWMPRPOL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr19_pwmprdutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS, AB8500_CODEC_CR19_PWMRPDUTYCYCLE);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR19, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR20 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR20(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr20_en_se_mic1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR20_EN_SE_MIC1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr20_mic1_gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR20_MIC1_GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR20, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR21 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR21(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr21_en_se_mic2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR21_EN_SE_MIC2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr21_mic2_gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR21_MIC2_GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR21, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR22 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR22(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr22_hsl_gain,
+ AB8500_CODEC_MASK_THREE_BITS, AB8500_CODEC_CR22_HSL_GAIN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr22_linl_gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR22_LINL_GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR22, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR23 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR23(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr23_hsr_gain,
+ AB8500_CODEC_MASK_THREE_BITS, AB8500_CODEC_CR23_HSR_GAIN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr23_linr_gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR23_LINR_GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR23, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR24 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR24(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr24_lintohsl_gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR24_LINTOHSL_GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR24, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR25 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR25(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr25_lintohsr_gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR25_LINTOHSR_GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR25, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR26 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR26(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad1nh,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD1NH);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad2nh,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD2NH);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad3nh,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD3NH);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad4nh,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD4NH);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad1_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD1_VOICE);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad2_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD2_VOICE);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad3_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD3_VOICE);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr26_ad4_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR26_AD4_VOICE);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR26, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR27 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR27(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr27_en_mastgen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR27_EN_MASTGEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr27_if1_bitclk_osr,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR27_IF1_BITCLK_OSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr27_enfs_bitclk1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR27_ENFS_BITCLK1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr27_if0_bitclk_osr,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR27_IF0_BITCLK_OSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr27_enfs_bitclk0,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR27_ENFS_BITCLK0);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR27, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR28 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR28(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr28_fsync0p,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR28_FSYNC0P);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr28_bitclk0p,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR28_BITCLK0P);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr28_if0del,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR28_IF0DEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr28_if0format,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR28_IF0FORMAT);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr28_if0wl,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR28_IF0WL);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR28, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR29 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR29(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if0datoif1ad,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF0DATOIF1AD);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if0cktoif1ck,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF0CKTOIF1CK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if1master,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF1MASTER);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if1datoif0ad,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF1DATOIF0AD);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if1cktoif0ck,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF1CKTOIF0CK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if0master,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF0MASTER);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr29_if0bfifoen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR29_IF0BFIFOEN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR29, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR30 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR30(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr30_fsync1p,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR30_FSYNC1P);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr30_bitclk1p,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR30_BITCLK1P);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr30_if1del,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR30_IF1DEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr30_if1format,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR30_IF1FORMAT);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr30_if1wl,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR30_IF1WL);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR30, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR31 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR31(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr31_adotoslot1,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR31_ADOTOSLOT1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr31_adotoslot0,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR31_ADOTOSLOT0);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR31, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR32 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR32(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr32_adotoslot3,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR32_ADOTOSLOT3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr32_adotoslot2,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR32_ADOTOSLOT2);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR32, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR33 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR33(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr33_adotoslot5,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR33_ADOTOSLOT5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr33_adotoslot4,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR33_ADOTOSLOT4);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR33, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR34 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR34(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr34_adotoslot7,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR34_ADOTOSLOT7);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr34_adotoslot6,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR34_ADOTOSLOT6);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR34, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR35 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR35(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr35_adotoslot9,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR35_ADOTOSLOT9);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr35_adotoslot8,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR35_ADOTOSLOT8);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR35, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR36 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR36(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr36_adotoslot11,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR36_ADOTOSLOT11);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr36_adotoslot10,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR36_ADOTOSLOT10);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR36, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR37 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR37(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr37_adotoslot13,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR37_ADOTOSLOT13);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr37_adotoslot12,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR37_ADOTOSLOT12);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR37, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR38 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR38(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr38_adotoslot15,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR38_ADOTOSLOT15);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr38_adotoslot14,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR38_ADOTOSLOT14);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR38, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR39 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR39(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr39_adotoslot17,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR39_ADOTOSLOT17);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr39_adotoslot16,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR39_ADOTOSLOT16);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR39, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR40 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR40(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr40_adotoslot19,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR40_ADOTOSLOT19);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr40_adotoslot18,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR40_ADOTOSLOT18);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR40, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR41 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR41(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr41_adotoslot21,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR41_ADOTOSLOT21);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr41_adotoslot20,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR41_ADOTOSLOT20);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR41, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR42 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR42(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr42_adotoslot23,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR42_ADOTOSLOT23);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr42_adotoslot22,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR42_ADOTOSLOT22);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR42, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR43 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR43(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr43_adotoslot25,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR43_ADOTOSLOT25);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr43_adotoslot24,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR43_ADOTOSLOT24);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR43, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR44 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR44(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr44_adotoslot27,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR44_ADOTOSLOT27);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr44_adotoslot26,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR44_ADOTOSLOT26);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR44, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR45 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR45(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr45_adotoslot29,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR45_ADOTOSLOT29);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr45_adotoslot28,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR45_ADOTOSLOT28);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR45, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR46 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR46(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr46_adotoslot31,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR46_ADOTOSLOT31);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr46_adotoslot30,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR46_ADOTOSLOT30);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR46, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR47 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR47(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl7,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL7);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl6,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL6);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl5,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr47_hiz_sl0,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR47_HIZ_SL0);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR47, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR48 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR48(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl15,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL15);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl14,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL14);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl13,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL13);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl12,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL12);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl11,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL11);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl10,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL10);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl9,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL9);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr48_hiz_sl8,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR48_HIZ_SL8);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR48, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR49 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR49(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl23,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL23);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl22,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL22);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl21,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL21);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl20,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL20);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl19,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL19);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl18,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL18);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl17,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL17);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr49_hiz_sl16,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR49_HIZ_SL16);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR49, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR50 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR50(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl31,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL31);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl30,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL30);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl29,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL29);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl28,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL28);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl27,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL27);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl26,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL26);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl25,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL25);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr50_hiz_sl24,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR50_HIZ_SL24);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR50, value));
+}
+
+#endif
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR51 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR51(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr51_da12_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR51_DA12_VOICE);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr51_sldai1toslado1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR51_SLDAI1TOSLADO1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr51_sltoda1,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR51_SLTODA1);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR51, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR52 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR52(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr52_sldai2toslado2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR52_SLDAI1TOSLADO2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr52_sltoda2,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR52_SLTODA2);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR52, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR53 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR53(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr53_da34_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR53_DA34_VOICE);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr53_sldai3toslado3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR53_SLDAI1TOSLADO3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr53_sltoda3,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR53_SLTODA3);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR53, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR54 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR54(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr54_sldai4toslado4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR54_SLDAI1TOSLADO4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr54_sltoda4,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR54_SLTODA4);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR54, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR55 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR55(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr55_da56_voice,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR55_DA56_VOICE);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr55_sldai5toslado5,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR55_SLDAI1TOSLADO5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr55_sltoda5,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR55_SLTODA5);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR55, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR56 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR56(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr56_sldai6toslado7,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR56_SLDAI1TOSLADO6);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr56_sltoda6,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR56_SLTODA6);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR56, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR57 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR57(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_bfifull_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_BFIFULL_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_bfiempt_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_BFIEMPT_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_dachan_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_DACHAN_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_gain_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_GAIN_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_dspad_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_DSPAD_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_dspda_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_DSPDA_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr57_stfir_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR57_STFIR_MSK);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR57, value));
+}
+
+/* CR58 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR59 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR59(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_vssready_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_VSSREADY_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrtvibl_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTVIBL_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrtvibr_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTVIBR_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrthfl_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTHFL_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrthfr_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTHFR_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrthsl_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTHSL_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrthsr_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTHSR_MSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr59_shrtear_msk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR59_SHRTEAR_MSK);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR59, value));
+}
+
+/* CR60 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR61 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR61(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ /* 5 bits are Read Only */
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr61_fade_speed,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR61_FADE_SPEED);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR61, value));
+}
+#endif
+/* CR62 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR63 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR63(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_datohslen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_DATOHSLEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_datohsren,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_DATOHSREN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_ad1sel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_AD1SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_ad2sel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_AD2SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_ad3sel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_AD3SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_ad5sel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_AD5SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_ad6sel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_AD6SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr63_ancsel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR63_ANCSEL);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR63, value));
+}
+
+#if 0
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR64 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR64(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr64_datohfren,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR64_DATOHFREN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr64_datohflen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR64_DATOHFLEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr64_hfrsel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR64_HFRSEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr64_hflsel,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR64_HFLSEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr64_stfir1sel,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR64_STFIR1SEL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr64_stfir2sel,
+ AB8500_CODEC_MASK_TWO_BITS, AB8500_CODEC_CR64_STFIR2SEL);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR64, value));
+}
+
+#endif
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR65 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR65(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr65_fadedis_ad1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR65_FADEDIS_AD1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr65_ad1gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR65_AD1GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR65, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR66 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR66(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr66_fadedis_ad2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR66_FADEDIS_AD2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr66_ad2gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR66_AD2GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR66, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR67 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR67(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr67_fadedis_ad3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR67_FADEDIS_AD3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr67_ad3gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR67_AD3GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR67, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR68 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR68(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr68_fadedis_ad4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR68_FADEDIS_AD4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr68_ad4gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR68_AD4GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR68, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR69 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR69(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr69_fadedis_ad5,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR69_FADEDIS_AD5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr69_ad5gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR69_AD5GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR69, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR70 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR70(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr70_fadedis_ad6,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR70_FADEDIS_AD6);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr70_ad6gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR70_AD6GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR70, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR71 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR71(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr71_fadedis_da1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR71_FADEDIS_DA1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr71_da1gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR71_DA1GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR71, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR72 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR72(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr72_fadedis_da2,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR72_FADEDIS_DA2);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr72_da2gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR72_DA2GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR72, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR73 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR73(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr73_fadedis_da3,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR73_FADEDIS_DA3);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr73_da3gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR73_DA3GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR73, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR74 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR74(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr74_fadedis_da4,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR74_FADEDIS_DA4);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr74_da4gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR74_DA4GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR74, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR75 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR75(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr75_fadedis_da5,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR75_FADEDIS_DA5);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr75_da5gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR75_DA5GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR75, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR76 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR76(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr76_fadedis_da6,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR76_FADEDIS_DA6);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr76_da6gain,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR76_DA6GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR76, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR77 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR77(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr77_fadedis_ad1l,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR77_FADEDIS_AD1L);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr77_ad1lbgain_to_hfl,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR77_AD1LBGAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR77, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR78 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR78(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr78_fadedis_ad2l,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR78_FADEDIS_AD2L);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr78_ad2lbgain_to_hfr,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR78_AD2LBGAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR78, value));
+}
+#endif
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR79 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR79(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr79_hssinc1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR79_HSSINC1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr79_fadedis_hsl,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR79_FADEDIS_HSL);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr79_hsldgain,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR79_HSLDGAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR79, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR80 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR80(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr80_fadedis_hsr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR80_FADEDIS_HSR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr80_hsrdgain,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR80_HSRDGAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR80, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR81 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR81(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr81_stfir1gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR81_STFIR1GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR81, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR82 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR82(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr82_stfir2gain,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR82_STFIR2GAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR82, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR83 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR83(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr83_enanc,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR83_ENANC);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr83_anciirinit,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR83_ANCIIRINIT);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr83_ancfirupdate,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR83_ANCFIRUPDATE);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR83, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR84 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR84(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr84_ancinshift,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR84_ANCINSHIFT);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR84, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR85 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR85(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr85_ancfiroutshift,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR85_ANCFIROUTSHIFT);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR85, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR86 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR86(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr86_ancshiftout,
+ AB8500_CODEC_MASK_FIVE_BITS, AB8500_CODEC_CR86_ANCSHIFTOUT);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR86, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR87 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR87(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr87_ancfircoeff_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR87_ANCFIRCOEFF_MSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR87, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR88 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR88(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr88_ancfircoeff_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR88_ANCFIRCOEFF_LSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR88, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR89 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR89(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr89_anciircoeff_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR89_ANCIIRCOEFF_MSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR89, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR90 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR90(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr90_anciircoeff_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR90_ANCIIRCOEFF_LSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR90, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR91 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR91(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr91_ancwarpdel_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR91_ANCWARPDEL_MSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR91, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR92 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR92(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr92_ancwarpdel_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR92_ANCWARPDEL_LSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR92, value));
+}
+
+/* CR93 is Read Only */
+/* CR94 is Read Only */
+/* CR95 is Read Only */
+/* CR96 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR97 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR97(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr97_stfir_set,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR97_STFIR_SET);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr97_stfir_addr,
+ AB8500_CODEC_MASK_SEVEN_BITS, AB8500_CODEC_CR97_STFIR_ADDR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR97, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR98 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR98(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr98_stfir_coeff_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR98_STFIR_COEFF_MSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR98, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR99 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR99(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr99_stfir_coeff_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR99_STFIR_COEFF_LSB);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR99, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR100 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR100(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr100_enstfirs,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR100_ENSTFIRS);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr100_stfirstoif1,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR100_STFIRSTOIF1);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr100_stfir_busy,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR100_STFIR_BUSY);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR100, value));
+}
+
+#endif
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR101 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR101(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr101_parlhf,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR101_PARLHF);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr101_parlvib,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR101_PARLVIB);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr101_classd_viblswapen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR101_CLASSDVIBLSWAPEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr101_classd_vibrswapen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR101_CLASSDVIBRSWAPEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr101_classd_hflswapen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR101_CLASSDHFLSWAPEN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr101_classd_hfrswapen,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR101_CLASSDHFRSWAPEN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR101, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR102 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR102(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr102_classd_firbyp,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR102_CLASSD_FIRBYP);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr102_classd_highvolen,
+ AB8500_CODEC_MASK_FOUR_BITS, AB8500_CODEC_CR102_CLASSD_HIGHVOLEN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR102, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR103 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR103(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr103_classd_ditherhpgain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR103_CLASSD_DITHERHPGAIN);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr103_classd_ditherwgain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR103_CLASSD_DITHERWGAIN);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR103, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR104 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR104(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr104_bfifoint,
+ AB8500_CODEC_MASK_SIX_BITS, AB8500_CODEC_CR104_BFIFOINT);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR104, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR105 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR105(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr105_bfifotx,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR105_BFIFOTX);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR105, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR106 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR106(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr106_bfifofsext,
+ AB8500_CODEC_MASK_THREE_BITS, AB8500_CODEC_CR106_BFIFOFSEXT);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr106_bfifomsk,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR106_BFIFOMSK);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr106_bfifomstr,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR106_BFIFOMSTR);
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr106_bfifostrt,
+ AB8500_CODEC_MASK_ONE_BIT, AB8500_CODEC_CR106_BFIFOSTRT);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR106, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR107 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR107(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr107_bfifosampnr,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR107_BFIFOSAMPNR);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR107, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR108 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR108(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr108_bfifowakeup,
+ AB8500_CODEC_MASK_EIGHT_BITS, AB8500_CODEC_CR108_BFIFOWAKEUP);
+
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR108, value));
+}
+
+/* CR109 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_Reset() */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_Reset(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ p_ab8500_codec_configuration->cr1_swreset =
+ AB8500_CODEC_CR1_SWRESET_ENABLED;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR1();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirection(IN
+ t_ab8500_codec_direction
+ ab8500_codec_direction)
+{ /*only IN or OUT must be passed (not INOUT) */
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ if (AB8500_CODEC_DIRECTION_IN == ab8500_codec_direction) {
+ ab8500_codec_error = ab8500_codec_ProgramDirectionIN();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ if (AB8500_CODEC_DIRECTION_OUT == ab8500_codec_direction) {
+ ab8500_codec_error = ab8500_codec_ProgramDirectionOUT();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetDirection(IN
+ t_ab8500_codec_direction
+ ab8500_codec_direction)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ switch (ab8500_codec_direction) {
+ case AB8500_CODEC_DIRECTION_IN:
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection(AB8500_CODEC_DIRECTION_IN);
+ break;
+
+ case AB8500_CODEC_DIRECTION_OUT:
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection(AB8500_CODEC_DIRECTION_OUT);
+ break;
+
+ case AB8500_CODEC_DIRECTION_INOUT:
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection(AB8500_CODEC_DIRECTION_IN);
+ if (AB8500_CODEC_OK == ab8500_codec_error) {
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection
+ (AB8500_CODEC_DIRECTION_OUT);
+ }
+ break;
+ }
+
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR5();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR6();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR7();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR8();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR9();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR10();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR12();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR15();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR63();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_Init */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Initialize the global variables & stores the slave address of codec. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* slave_address_of_ab8500_codec: Audio codec slave address */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* Returns AB8500_CODEC_OK */
+/* COMMENTS: */
+/* 1) Saves the supplied slave_address_of_codec in global variable */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_Init(IN t_uint8
+ slave_address_of_ab8500_codec)
+{
+ DBGENTER1(" (%lx)", slave_address_of_ab8500_codec);
+
+ g_ab8500_codec_system_context.slave_address_of_ab8500_codec =
+ slave_address_of_ab8500_codec;
+
+ DBGEXIT(AB8500_CODEC_OK);
+ return (AB8500_CODEC_OK);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_Reset */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Reset the global variables and clear audiocodec settings to default. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_Reset(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ DBGENTER();
+
+ g_ab8500_codec_system_context.ab8500_codec_direction =
+ AB8500_CODEC_DEFAULT_DIRECTION;
+ g_ab8500_codec_system_context.ab8500_codec_mode_in =
+ AB8500_CODEC_DEFAULT_MODE_IN;
+ g_ab8500_codec_system_context.ab8500_codec_mode_out =
+ AB8500_CODEC_DEFAULT_MODE_OUT;
+
+ g_ab8500_codec_system_context.ab8500_codec_src =
+ AB8500_CODEC_DEFAULT_INPUT_SRC;
+ g_ab8500_codec_system_context.ab8500_codec_dest =
+ AB8500_CODEC_DEFAULT_OUTPUT_DEST;
+
+ g_ab8500_codec_system_context.in_left_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_LEFT_IN;
+ g_ab8500_codec_system_context.in_right_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_RIGHT_IN;
+ g_ab8500_codec_system_context.out_left_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_LEFT_OUT;
+ g_ab8500_codec_system_context.out_right_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_RIGHT_OUT;
+
+ ab8500_codec_error = ab8500_codec_Reset();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetModeAndDirection */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Configures the whole audio codec to work in audio mode */
+/* (using I2S protocol). */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* direction: select the direction (IN, OUT or INOUT) */
+/* in_mode: codec mode for recording. If direction is OUT only, */
+/* this parameter is ignored. */
+/* out_mode: codec mode for playing. If direction is IN only, */
+/* this parameter is ignored. */
+/* p_tdm_config: TDM configuration required to be configured by user */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: The API may not allow setting */
+/* 2 different modes, in which case it should return this value. */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetModeAndDirection
+ (IN t_ab8500_codec_direction ab8500_codec_direction,
+ IN t_ab8500_codec_mode ab8500_codec_mode_in,
+ IN t_ab8500_codec_mode ab8500_codec_mode_out,
+ IN t_ab8500_codec_tdm_config const *const p_tdm_config) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ DBGENTER3(" (%lx %lx %lx)", ab8500_codec_direction,
+ ab8500_codec_mode_in, ab8500_codec_mode_out);
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface) {
+ if (AB8500_CODEC_DIRECTION_OUT == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT == ab8500_codec_direction) {
+ p_ab8500_codec_configuration->cr3_enda1 =
+ AB8500_CODEC_CR3_ENDA1_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda2 =
+ AB8500_CODEC_CR3_ENDA2_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda3 =
+ AB8500_CODEC_CR3_ENDA3_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda4 =
+ AB8500_CODEC_CR3_ENDA4_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda5 =
+ AB8500_CODEC_CR3_ENDA5_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda6 =
+ AB8500_CODEC_CR3_ENDA6_ENABLED;
+
+ p_ab8500_codec_configuration->cr27_if1_bitclk_osr =
+ p_tdm_config->cr27_if1_bitclk_osr;
+
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_out) {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ } else {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_TDM;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ }
+ }
+
+ if (AB8500_CODEC_DIRECTION_IN == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT == ab8500_codec_direction) {
+ p_ab8500_codec_configuration->cr2_enad1 =
+ AB8500_CODEC_CR2_ENAD1_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad2 =
+ AB8500_CODEC_CR2_ENAD2_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad3 =
+ AB8500_CODEC_CR2_ENAD3_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad4 =
+ AB8500_CODEC_CR2_ENAD4_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad5 =
+ AB8500_CODEC_CR2_ENAD5_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad6 =
+ AB8500_CODEC_CR2_ENAD6_ENABLED;
+
+ p_ab8500_codec_configuration->cr27_if1_bitclk_osr =
+ p_tdm_config->cr27_if1_bitclk_osr;
+
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_in) {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ } else {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_RISING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_NOT_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_TDM;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ }
+ }
+ } else {
+ if (AB8500_CODEC_DIRECTION_OUT == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT == ab8500_codec_direction) {
+ p_ab8500_codec_configuration->cr3_enda1 =
+ AB8500_CODEC_CR3_ENDA1_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda2 =
+ AB8500_CODEC_CR3_ENDA2_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda3 =
+ AB8500_CODEC_CR3_ENDA3_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda4 =
+ AB8500_CODEC_CR3_ENDA4_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda5 =
+ AB8500_CODEC_CR3_ENDA5_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda6 =
+ AB8500_CODEC_CR3_ENDA6_ENABLED;
+
+ p_ab8500_codec_configuration->cr27_if0_bitclk_osr =
+ p_tdm_config->cr27_if0_bitclk_osr;
+
+ p_ab8500_codec_configuration->cr63_datohslen =
+ AB8500_CODEC_CR63_DATOHSLEN_ENABLED;
+ p_ab8500_codec_configuration->cr63_datohsren =
+ AB8500_CODEC_CR63_DATOHSREN_ENABLED;
+
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_out) {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ } else {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_TDM;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ }
+ }
+
+ if (AB8500_CODEC_DIRECTION_IN == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT == ab8500_codec_direction) {
+ p_ab8500_codec_configuration->cr2_enad1 =
+ AB8500_CODEC_CR2_ENAD1_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad2 =
+ AB8500_CODEC_CR2_ENAD2_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad3 =
+ AB8500_CODEC_CR2_ENAD3_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad4 =
+ AB8500_CODEC_CR2_ENAD4_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad5 =
+ AB8500_CODEC_CR2_ENAD5_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad6 =
+ AB8500_CODEC_CR2_ENAD6_ENABLED;
+
+ p_ab8500_codec_configuration->cr26_ad1_voice =
+ AB8500_CODEC_CR26_AD1_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr26_ad2_voice =
+ AB8500_CODEC_CR26_AD2_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr26_ad3_voice =
+ AB8500_CODEC_CR26_AD3_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr26_ad4_voice =
+ AB8500_CODEC_CR26_AD4_VOICE_LOWLATENCYFILTER;
+
+ p_ab8500_codec_configuration->cr27_if0_bitclk_osr =
+ p_tdm_config->cr27_if0_bitclk_osr;
+
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_in) {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_RISING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_RISING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_NOT_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ } else {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_RISING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_NOT_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_TDM;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ }
+ }
+ }
+
+ ab8500_codec_error = ab8500_codec_SetModeAndDirectionUpdateCR();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ g_ab8500_codec_system_context.ab8500_codec_direction =
+ ab8500_codec_direction;
+ g_ab8500_codec_system_context.ab8500_codec_mode_in =
+ ab8500_codec_mode_in;
+ g_ab8500_codec_system_context.ab8500_codec_mode_out =
+ ab8500_codec_mode_out;
+
+ ab8500_codec_error = ab8500_codec_SetDirection(ab8500_codec_direction);
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetSrcVolume */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Sets the record volumes. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* t_ab8500_codec_src: select source device for recording. */
+/* in_left_volume: record volume for left channel. */
+/* in_right_volume: record volume for right channel. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetSrcVolume
+ (IN t_ab8500_codec_src src_device,
+ IN t_uint8 in_left_volume, IN t_uint8 in_right_volume) {
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER3(" (%lx %lx %lx)", src_device, in_left_volume,
+ in_right_volume);
+
+ if (in_left_volume > AB8500_CODEC_MAX_VOLUME) {
+ in_left_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+
+ if (in_right_volume > AB8500_CODEC_MAX_VOLUME) {
+ in_right_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+
+ g_ab8500_codec_system_context.in_left_volume = in_left_volume;
+ g_ab8500_codec_system_context.in_right_volume = in_right_volume;
+
+ p_ab8500_codec_configuration->cr65_ad1gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr66_ad2gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr67_ad3gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr68_ad4gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr69_ad5gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr70_ad6gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+
+ /* Set mininimum volume if volume is zero */
+ switch (src_device) {
+ case AB8500_CODEC_SRC_LINEIN:
+ p_ab8500_codec_configuration->cr22_linl_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr23_linr_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_right_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ p_ab8500_codec_configuration->cr20_mic1_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ p_ab8500_codec_configuration->cr21_mic2_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ break;
+
+ case AB8500_CODEC_SRC_ALL:
+ p_ab8500_codec_configuration->cr22_linl_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr23_linr_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_right_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+
+ p_ab8500_codec_configuration->cr20_mic1_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+
+ p_ab8500_codec_configuration->cr21_mic2_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_SetSrcVolumeUpdateCR();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetDestVolume */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Sets the play volumes. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* out_left_volume: play volume for left channel. */
+/* out_right_volume: play volume for right channel. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetDestVolume
+ (IN t_ab8500_codec_dest dest_device,
+ IN t_uint8 out_left_volume, IN t_uint8 out_right_volume) {
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER3(" (%lx %lx %lx)", dest_device, out_left_volume,
+ out_right_volume);
+
+ if (out_left_volume > AB8500_CODEC_MAX_VOLUME) {
+ out_left_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+
+ if (out_right_volume > AB8500_CODEC_MAX_VOLUME) {
+ out_right_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+
+ g_ab8500_codec_system_context.out_left_volume = out_left_volume;
+ g_ab8500_codec_system_context.out_right_volume = out_right_volume;
+
+ p_ab8500_codec_configuration->cr71_da1gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr72_da2gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr73_da3gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr74_da4gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr75_da5gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr76_da6gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+
+ /* Set mininimum volume if volume is zero */
+ switch (dest_device) {
+ case AB8500_CODEC_DEST_HEADSET:
+ p_ab8500_codec_configuration->cr22_hsl_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr23_hsr_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+
+ p_ab8500_codec_configuration->cr79_hsldgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ p_ab8500_codec_configuration->cr80_hsrdgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ break;
+
+ case AB8500_CODEC_DEST_EARPIECE:
+ p_ab8500_codec_configuration->cr79_hsldgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ break;
+
+ case AB8500_CODEC_DEST_HANDSFREE:
+
+ p_ab8500_codec_configuration->cr101_parlhf =
+ AB8500_CODEC_CR101_PARLHF_INDEPENDENT;
+ p_ab8500_codec_configuration->cr101_parlvib =
+ AB8500_CODEC_CR101_PARLVIB_INDEPENDENT;
+ p_ab8500_codec_configuration->cr101_classd_viblswapen =
+ AB8500_CODEC_CR101_CLASSD_VIBLSWAPEN_DISABLED;
+ p_ab8500_codec_configuration->cr101_classd_vibrswapen =
+ AB8500_CODEC_CR101_CLASSD_VIBRSWAPEN_DISABLED;
+ p_ab8500_codec_configuration->cr101_classd_hflswapen =
+ AB8500_CODEC_CR101_CLASSD_HFLSWAPEN_DISABLED;
+ p_ab8500_codec_configuration->cr101_classd_hfrswapen =
+ AB8500_CODEC_CR101_CLASSD_HFRSWAPEN_DISABLED;
+
+ p_ab8500_codec_configuration->cr102_classd_firbyp =
+ AB8500_CODEC_CR102_CLASSD_FIRBYP_ALL_ENABLED;
+ p_ab8500_codec_configuration->cr102_classd_highvolen =
+ AB8500_CODEC_CR102_CLASSD_HIGHVOLEN_DISABLED;
+
+ p_ab8500_codec_configuration->cr103_classd_ditherhpgain = 0x8;
+ p_ab8500_codec_configuration->cr103_classd_ditherwgain = 0x4;
+
+ break;
+
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ p_ab8500_codec_configuration->cr16_pwmnldutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN;
+ p_ab8500_codec_configuration->cr17_pwmpldutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_VIBRATOR_VOLUME_MAX -
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN)) / 100;
+ break;
+
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ p_ab8500_codec_configuration->cr18_pwmnrdutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN;
+ p_ab8500_codec_configuration->cr19_pwmprdutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_VIBRATOR_VOLUME_MAX -
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN)) / 100;
+ break;
+
+ case AB8500_CODEC_DEST_ALL:
+ p_ab8500_codec_configuration->cr22_hsl_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr23_hsr_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+
+ p_ab8500_codec_configuration->cr79_hsldgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_SetDestVolumeUpdateCR();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetMasterMode */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Set the Audio Codec in Master mode. */
+/* */
+/* ARGUMENTS */
+/* IN: t_codec_master_mode: Enable/disable master mode */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: Call this API after calling AB8500_CODEC_SetModeAndDirection() API*/
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetMasterMode(IN
+ t_ab8500_codec_master_mode
+ mode)
+{
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface) {
+
+ p_ab8500_codec_configuration->cr27_en_mastgen =
+ AB8500_CODEC_CR27_EN_MASTGEN_ENABLED;
+ p_ab8500_codec_configuration->cr27_enfs_bitclk1 =
+ AB8500_CODEC_CR27_ENFS_BITCLK1_ENABLED;
+
+ if (AB8500_CODEC_MASTER_MODE_ENABLE == mode) {
+ p_ab8500_codec_configuration->cr29_if1master =
+ AB8500_CODEC_CR29_IF1MASTER_FS1CK1_OUTPUT;
+ } else {
+ p_ab8500_codec_configuration->cr29_if1master =
+ AB8500_CODEC_CR29_IF1MASTER_FS1CK1_INPUT;
+ }
+
+ } else {
+
+ p_ab8500_codec_configuration->cr27_en_mastgen =
+ AB8500_CODEC_CR27_EN_MASTGEN_ENABLED;
+ p_ab8500_codec_configuration->cr27_enfs_bitclk0 =
+ AB8500_CODEC_CR27_ENFS_BITCLK0_ENABLED;
+
+ if (AB8500_CODEC_MASTER_MODE_ENABLE == mode) {
+ p_ab8500_codec_configuration->cr29_if0master =
+ AB8500_CODEC_CR29_IF0MASTER_FS0CK0_OUTPUT;
+ } else {
+ p_ab8500_codec_configuration->cr29_if0master =
+ AB8500_CODEC_CR29_IF0MASTER_FS0CK0_INPUT;
+ }
+
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR27();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SelectInput */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Select input source for recording. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* input_src: select input source for recording when several sources */
+/* are supported in codec. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If input_src provided is invalid */
+/* by the codec hardware in use. */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SelectInput(IN t_ab8500_codec_src
+ ab8500_codec_src)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER1(" (%lx)", ab8500_codec_src);
+
+ g_ab8500_codec_system_context.ab8500_codec_src = ab8500_codec_src;
+
+ ab8500_codec_error =
+ ab8500_codec_SetDirection(AB8500_CODEC_DIRECTION_IN);
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SelectOutput */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Select output desination for playing. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* output_dest: select output destination for playing when several are */
+/* supported by codec hardware. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If output_src provided is invalid */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SelectOutput(IN t_ab8500_codec_dest
+ ab8500_codec_dest)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ g_ab8500_codec_system_context.ab8500_codec_dest = ab8500_codec_dest;
+ DBGENTER1(" (%lx)", ab8500_codec_dest);
+
+ ab8500_codec_error =
+ ab8500_codec_SetDirection(AB8500_CODEC_DIRECTION_OUT);
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_PowerDown */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Shuts the audio codec down completely. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* OUT: */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_PowerDown(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ g_ab8500_codec_system_context.ab8500_codec_configuration.cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_OFF;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_PowerUp */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Switch on the audio codec. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_PowerUp(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ DBGENTER();
+
+ /*g_ab8500_codec_system_context.ab8500_codec_configuration.cr1_swreset = AB8500_CODEC_CR1_SWRESET_ENABLED; Removed by kardad
+ ab8500_codec_error = ab8500_codec_UpdateCR1();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return(ab8500_codec_error);
+ } */
+
+ g_ab8500_codec_system_context.ab8500_codec_configuration.cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_ON;
+ g_ab8500_codec_system_context.ab8500_codec_configuration.cr0_enaana =
+ AB8500_CODEC_CR0_ENAANA_ON;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SelectInterface */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Select the Audio Interface 0 or 1. */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_audio_interface: The selected interface */
+/* */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_OK: Always. */
+/* REMARK: Call this API before using a function of the low level drivers */
+/* to select the interface that you want to configure */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SelectInterface(IN
+ t_ab8500_codec_audio_interface
+ audio_interface)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+
+ g_ab8500_codec_system_context.audio_interface = audio_interface;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_GetInterface */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Get the Audio Interface 0 or 1. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: p_audio_interface: Store the selected interface */
+/* RETURN: */
+/* AB8500_CODEC_OK: Always */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_GetInterface(OUT
+ t_ab8500_codec_audio_interface
+ * p_audio_interface)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+
+ *p_audio_interface = g_ab8500_codec_system_context.audio_interface;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetAnalogLoopback */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Sets Line-In to HeadSet loopback with the required gain. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* out_left_volume: play volume for left channel. */
+/* out_right_volume: play volume for right channel. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetAnalogLoopback(IN t_uint8
+ out_left_volume,
+ IN t_uint8
+ out_right_volume)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER2(" (%lx %lx)", out_left_volume, out_right_volume);
+
+ if (out_left_volume > AB8500_CODEC_MAX_VOLUME) {
+ out_left_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+
+ if (out_right_volume > AB8500_CODEC_MAX_VOLUME) {
+ out_right_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+
+ g_ab8500_codec_system_context.out_left_volume = out_left_volume;
+ g_ab8500_codec_system_context.out_right_volume = out_right_volume;
+
+ p_ab8500_codec_configuration->cr24_lintohsl_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr25_lintohsr_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN)) / 100;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR24();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR25();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_RemoveAnalogLoopback */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Remove Line-In to HeadSet loopback. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_RemoveAnalogLoopback(void)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER0();
+
+ p_ab8500_codec_configuration->cr24_lintohsl_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_LOOP_OPEN;
+ p_ab8500_codec_configuration->cr25_lintohsr_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_LOOP_OPEN;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR24();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR25();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_EnableBypassMode */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enables IF0 to IF1 path or vice versa */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_EnableBypassMode(void)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER0();
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface) {
+ p_ab8500_codec_configuration->cr29_if1datoif0ad =
+ AB8500_CODEC_CR29_IF1DATOIF0AD_SENT;
+ p_ab8500_codec_configuration->cr29_if1cktoif0ck =
+ AB8500_CODEC_CR29_IF1CKTOIF0CK_SENT;
+ } else {
+ p_ab8500_codec_configuration->cr29_if0datoif1ad =
+ AB8500_CODEC_CR29_IF0DATOIF1AD_SENT;
+ p_ab8500_codec_configuration->cr29_if0cktoif1ck =
+ AB8500_CODEC_CR29_IF0CKTOIF1CK_SENT;
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DisableBypassMode */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Disables IF0 to IF1 path or vice versa */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DisableBypassMode(void)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER0();
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface) {
+ p_ab8500_codec_configuration->cr29_if1datoif0ad =
+ AB8500_CODEC_CR29_IF1DATOIF0AD_NOTSENT;
+ p_ab8500_codec_configuration->cr29_if1cktoif0ck =
+ AB8500_CODEC_CR29_IF1CKTOIF0CK_NOTSENT;
+ } else {
+ p_ab8500_codec_configuration->cr29_if0datoif1ad =
+ AB8500_CODEC_CR29_IF0DATOIF1AD_NOTSENT;
+ p_ab8500_codec_configuration->cr29_if0cktoif1ck =
+ AB8500_CODEC_CR29_IF0CKTOIF1CK_NOTSENT;
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SrcPowerControl */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enables/Disables & UnMute/Mute the desired source */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* t_ab8500_codec_src: select source device for enabling/disabling. */
+/* t_ab8500_codec_src_state: Enable/Disable */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SrcPowerControl(IN t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+
+ DBGENTER2(" (%lx %lx)", src_device, state);
+
+ if (src_device <= AB8500_CODEC_SRC_D_MICROPHONE_2) {
+ ab8500_codec_error =
+ ab8500_codec_SrcPowerControlSwitch1(src_device, state);
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else if (src_device <= AB8500_CODEC_SRC_ALL) {
+ ab8500_codec_error =
+ ab8500_codec_SrcPowerControlSwitch2(src_device, state);
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else {
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR5();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR6();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR7();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR63();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DestPowerControl */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enables/Disables & UnMute/Mute the desired destination */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* t_ab8500_codec_dest: select destination device for enabling/disabling. */
+/* t_ab8500_codec_dest_state: Enable/Disable */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DestPowerControl(IN t_ab8500_codec_dest
+ dest_device,
+ t_ab8500_codec_dest_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER2(" (%lx %lx)", dest_device, state);
+
+ switch (dest_device) {
+ case AB8500_CODEC_DEST_HEADSET:
+
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ } else {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_EARPIECE:
+
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ } else {
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_DISABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_HANDSFREE:
+
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_DISABLED;
+ } else {
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_ENABLED;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ } else {
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLGPOL;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+ } else {
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRGPOL;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_ALL:
+
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+ } else {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRGPOL;
+
+ }
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_DestPowerControlUpdateCR();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_GetVersion */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* This routine populates the pVersion structure with */
+/* the current version of HCL. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* p_version: this parameter is used to return current HCL version. */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_ERROR: if p_version is NULL. */
+/* AB8500_CODEC_OK: if successful */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_GetVersion(OUT t_version * p_version)
+{
+ DBGENTER1(" (%lx)", p_version);
+ if (p_version != NULL) {
+ p_version->minor = AB8500_CODEC_HCL_MINOR_ID;
+ p_version->major = AB8500_CODEC_HCL_MAJOR_ID;
+ p_version->version = AB8500_CODEC_HCL_VERSION_ID;
+ DBGEXIT0(AB8500_CODEC_OK);
+ return (AB8500_CODEC_OK);
+ } else {
+ DBGEXIT0(AB8500_CODEC_INVALID_PARAMETER);
+ return (AB8500_CODEC_INVALID_PARAMETER);
+ }
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetDbgLevel */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Set the debug level used by the debug module (mask-like value). */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* debug_level: debug level to be set */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_OK: always */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+/*
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetDbgLevel(IN t_dbg_level dbg_level)
+{
+ DBGENTER1(" (%d)", dbg_level);
+ dbg_level = dbg_level;
+#ifdef __DEBUG
+ MY_DEBUG_LEVEL_VAR_NAME = dbg_level;
+#endif
+ DBGEXIT(AB8500_CODEC_OK);
+ return(AB8500_CODEC_OK);
+}*/
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_GetDbgLevel */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Set the debug level used by the debug module (mask-like value). */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* p_dbg_level: this parameter is used to return debug level. */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_ERROR: if p_version is NULL. */
+/* AB8500_CODEC_OK: if successful */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+/*
+PUBLIC t_ab8500_codec_error AB8500_CODEC_GetDbgLevel(OUT t_dbg_level *p_dbg_level)
+{
+ if (NULL == p_dbg_level)
+ {
+ DBGEXIT(AB8500_CODEC_INVALID_PARAMETER);
+ return(AB8500_CODEC_INVALID_PARAMETER);
+ }
+
+#ifdef __DEBUG
+ * p_dbg_level = MY_DEBUG_LEVEL_VAR_NAME;
+#endif
+ DBGEXIT(AB8500_CODEC_OK);
+ return(AB8500_CODEC_OK);
+}
+*/
+/****************************************************************************/
+/* NAME: AB8500_CODEC_ADSlotAllocation */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* AD Data Allocation in slots. */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_slot: The slot to be allocated. */
+/* IN: t_ab8500_codec_cr31_to_cr46_ad_data_allocation: The value */
+/* to be allocated. */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If invalid slot number */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_ADSlotAllocation
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ DBGENTER2(" (%lx %lx)", ad_slot, value);
+
+ if (ad_slot <= AB8500_CODEC_SLOT7) {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch1(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else if (ad_slot <= AB8500_CODEC_SLOT15) {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch2(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else if (ad_slot <= AB8500_CODEC_SLOT23) {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch3(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else if (ad_slot <= AB8500_CODEC_SLOT31) {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch4(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else {
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DASlotAllocation */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Allocate the Audio Interface slot for DA paths. */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_da_channel_number: Channel number 1/2/3/4/5/6 */
+/* IN: t_ab8500_codec_cr51_to_cr56_sltoda: Slot number */
+/* */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If invalid channel number */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DASlotAllocation
+ (IN t_ab8500_codec_da_channel_number channel_number,
+ IN t_ab8500_codec_cr51_to_cr56_sltoda slot) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ t_ab8500_codec_cr0_powerup ab8500_codec_cr0_powerup;
+
+ DBGENTER2(" (%lx %lx)", channel_number, slot);
+
+ p_ab8500_codec_configuration->cr51_da12_voice =
+ AB8500_CODEC_CR51_DA12_VOICE_LOWLATENCYFILTER;
+
+ switch (channel_number) {
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_1:
+ p_ab8500_codec_configuration->cr51_sltoda1 = slot;
+ break;
+
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_2:
+ p_ab8500_codec_configuration->cr52_sltoda2 = slot;
+ break;
+
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_3:
+ p_ab8500_codec_configuration->cr53_sltoda3 = slot;
+ break;
+
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_4:
+ p_ab8500_codec_configuration->cr54_sltoda4 = slot;
+ break;
+
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_5:
+ p_ab8500_codec_configuration->cr55_sltoda5 = slot;
+ break;
+
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_6:
+ p_ab8500_codec_configuration->cr56_sltoda6 = slot;
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_cr0_powerup = p_ab8500_codec_configuration->cr0_powerup;
+
+ p_ab8500_codec_configuration->cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_OFF;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR51();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR52();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR53();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR54();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR55();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR56();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ p_ab8500_codec_configuration->cr0_powerup = ab8500_codec_cr0_powerup;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_ConfigureBurstFifo */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Configuration for Burst FIFO control */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_burst_fifo_config: structure for configuration of */
+/* burst FIFO */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If invalid parameter */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: If interface 1 selected */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+t_ab8500_codec_error AB8500_CODEC_ConfigureBurstFifo(IN
+ t_ab8500_codec_burst_fifo_config
+ const *const
+ p_burst_fifo_config)
+{
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER1(" (%lx)", p_burst_fifo_config);
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_0 ==
+ g_ab8500_codec_system_context.audio_interface) {
+ if (AB8500_CODEC_CR27_EN_MASTGEN_ENABLED ==
+ p_ab8500_codec_configuration->cr27_en_mastgen) {
+ p_ab8500_codec_configuration->cr104_bfifoint =
+ p_burst_fifo_config->cr104_bfifoint;
+
+ p_ab8500_codec_configuration->cr105_bfifotx =
+ p_burst_fifo_config->cr105_bfifotx;
+
+ p_ab8500_codec_configuration->cr106_bfifofsext =
+ p_burst_fifo_config->cr106_bfifofsext;
+ p_ab8500_codec_configuration->cr106_bfifomsk =
+ p_burst_fifo_config->cr106_bfifomsk;
+ p_ab8500_codec_configuration->cr106_bfifomstr =
+ p_burst_fifo_config->cr106_bfifomstr;
+ p_ab8500_codec_configuration->cr106_bfifostrt =
+ p_burst_fifo_config->cr106_bfifostrt;
+
+ p_ab8500_codec_configuration->cr107_bfifosampnr =
+ p_burst_fifo_config->cr107_bfifosampnr;
+
+ p_ab8500_codec_configuration->cr108_bfifowakeup =
+ p_burst_fifo_config->cr108_bfifowakeup;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR104();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR105();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR106();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR107();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR108();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else {
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else {
+ ab8500_codec_error = AB8500_CODEC_UNSUPPORTED_FEATURE;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_EnableBurstFifo */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enable the Burst FIFO for Interface 0 */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: If Interface 1 is selected */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_EnableBurstFifo(void)
+{
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_0 ==
+ g_ab8500_codec_system_context.audio_interface) {
+ p_ab8500_codec_configuration->cr29_if0bfifoen =
+ AB8500_CODEC_CR29_IF0BFIFOEN_BURST_MODE;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else {
+ ab8500_codec_error = AB8500_CODEC_UNSUPPORTED_FEATURE;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DisableBurstFifo */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Disable the Burst FIFO for Interface 0 */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: If Interface 1 is selected */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DisableBurstFifo(void)
+{
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+
+ if (AB8500_CODEC_AUDIO_INTERFACE_0 ==
+ g_ab8500_codec_system_context.audio_interface) {
+ p_ab8500_codec_configuration->cr29_if0bfifoen =
+ AB8500_CODEC_CR29_IF0BFIFOEN_NORMAL_MODE;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ } else {
+ ab8500_codec_error = AB8500_CODEC_UNSUPPORTED_FEATURE;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch1
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (ad_slot) {
+ case AB8500_CODEC_SLOT0:
+ p_ab8500_codec_configuration->cr31_adotoslot0 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR31();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT1:
+ p_ab8500_codec_configuration->cr31_adotoslot1 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR31();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT2:
+ p_ab8500_codec_configuration->cr32_adotoslot2 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR32();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT3:
+ p_ab8500_codec_configuration->cr32_adotoslot3 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR32();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT4:
+ p_ab8500_codec_configuration->cr33_adotoslot4 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR33();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT5:
+ p_ab8500_codec_configuration->cr33_adotoslot5 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR33();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT6:
+ p_ab8500_codec_configuration->cr34_adotoslot6 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR34();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT7:
+ p_ab8500_codec_configuration->cr34_adotoslot7 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR34();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch2
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (ad_slot) {
+ case AB8500_CODEC_SLOT8:
+ p_ab8500_codec_configuration->cr35_adotoslot8 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR35();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT9:
+ p_ab8500_codec_configuration->cr35_adotoslot9 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR35();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT10:
+ p_ab8500_codec_configuration->cr36_adotoslot10 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR36();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT11:
+ p_ab8500_codec_configuration->cr36_adotoslot11 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR36();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT12:
+ p_ab8500_codec_configuration->cr37_adotoslot12 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR37();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT13:
+ p_ab8500_codec_configuration->cr37_adotoslot13 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR37();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT14:
+ p_ab8500_codec_configuration->cr38_adotoslot14 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR38();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT15:
+ p_ab8500_codec_configuration->cr38_adotoslot15 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR38();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch3
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (ad_slot) {
+ case AB8500_CODEC_SLOT16:
+ p_ab8500_codec_configuration->cr39_adotoslot16 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR39();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT17:
+ p_ab8500_codec_configuration->cr39_adotoslot17 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR39();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT18:
+ p_ab8500_codec_configuration->cr40_adotoslot18 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR40();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT19:
+ p_ab8500_codec_configuration->cr40_adotoslot19 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR40();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT20:
+ p_ab8500_codec_configuration->cr41_adotoslot20 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR41();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT21:
+ p_ab8500_codec_configuration->cr41_adotoslot21 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR41();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT22:
+ p_ab8500_codec_configuration->cr42_adotoslot22 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR42();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT23:
+ p_ab8500_codec_configuration->cr42_adotoslot23 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR42();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch4
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (ad_slot) {
+ case AB8500_CODEC_SLOT24:
+ p_ab8500_codec_configuration->cr43_adotoslot24 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR43();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT25:
+ p_ab8500_codec_configuration->cr43_adotoslot25 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR43();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT26:
+ p_ab8500_codec_configuration->cr44_adotoslot26 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR44();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT27:
+ p_ab8500_codec_configuration->cr44_adotoslot27 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR44();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT28:
+ p_ab8500_codec_configuration->cr45_adotoslot28 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR45();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT29:
+ p_ab8500_codec_configuration->cr45_adotoslot29 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR45();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT30:
+ p_ab8500_codec_configuration->cr46_adotoslot30 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR46();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ case AB8500_CODEC_SLOT31:
+ p_ab8500_codec_configuration->cr46_adotoslot31 = value;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR46();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch1(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (src_device) {
+ case AB8500_CODEC_SRC_LINEIN:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_LINR;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+ } else {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_MIC2;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1A;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ } else {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_DISABLED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1B;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ } else {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_DISABLED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_MIC2;
+ } else {
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_LINR;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+
+ p_ab8500_codec_configuration->cr63_ad1sel =
+ AB8500_CODEC_CR63_AD1SEL_DMIC1_SELECTED;
+ } else {
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad1sel =
+ AB8500_CODEC_CR63_AD1SEL_LINLADL_SELECTED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+
+ p_ab8500_codec_configuration->cr63_ad2sel =
+ AB8500_CODEC_CR63_AD2SEL_DMIC2_SELECTED;
+ } else {
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad2sel =
+ AB8500_CODEC_CR63_AD2SEL_LINRADR_SELECTED;
+ }
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch2(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (src_device) {
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+
+ p_ab8500_codec_configuration->cr63_ad3sel =
+ AB8500_CODEC_CR63_AD3SEL_DMIC3_SELECTED;
+ } else {
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad3sel =
+ AB8500_CODEC_CR63_AD3SEL_ADMO_SELECTED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ } else {
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+
+ p_ab8500_codec_configuration->cr63_ad5sel =
+ AB8500_CODEC_CR63_AD5SEL_DMIC5_SELECTED;
+ } else {
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad5sel =
+ AB8500_CODEC_CR63_AD5SEL_AMADR_SELECTED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+
+ p_ab8500_codec_configuration->cr63_ad6sel =
+ AB8500_CODEC_CR63_AD6SEL_DMIC6_SELECTED;
+ } else {
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad6sel =
+ AB8500_CODEC_CR63_AD6SEL_ADMO_SELECTED;
+ }
+ break;
+
+ case AB8500_CODEC_SRC_ALL:
+
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state) {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+ } else {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_FM_RX:
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetModeAndDirectionUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ t_ab8500_codec_cr0_powerup ab8500_codec_cr0_powerup;
+
+ ab8500_codec_cr0_powerup = p_ab8500_codec_configuration->cr0_powerup;
+
+ p_ab8500_codec_configuration->cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_OFF;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR2();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR3();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR26();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR28();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR30();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR63();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ p_ab8500_codec_configuration->cr0_powerup = ab8500_codec_cr0_powerup;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetSrcVolumeUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR20();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR21();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR22();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR23();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR65();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR66();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR67();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR68();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR69();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR70();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetDestVolumeUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR16();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR17();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR18();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR19();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR22();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR23();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR71();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR72();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR73();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR74();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR75();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR76();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR79();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR80();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR101();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR102();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR103();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionIN(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (g_ab8500_codec_system_context.ab8500_codec_src) {
+ case AB8500_CODEC_SRC_LINEIN:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_LINR;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1A;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1B;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_MIC2;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad1sel =
+ AB8500_CODEC_CR63_AD1SEL_DMIC1_SELECTED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad2sel =
+ AB8500_CODEC_CR63_AD2SEL_DMIC2_SELECTED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad3sel =
+ AB8500_CODEC_CR63_AD3SEL_DMIC3_SELECTED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad5sel =
+ AB8500_CODEC_CR63_AD5SEL_DMIC5_SELECTED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+
+ p_ab8500_codec_configuration->cr63_ad6sel =
+ AB8500_CODEC_CR63_AD6SEL_DMIC6_SELECTED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_SRC_ALL:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionOUT(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration *p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+
+ switch (g_ab8500_codec_system_context.ab8500_codec_dest) {
+ case AB8500_CODEC_DEST_HEADSET:
+ p_ab8500_codec_configuration->cr7_endrvhsl =
+ AB8500_CODEC_CR7_ENDRVHSL_ENABLED;
+ p_ab8500_codec_configuration->cr7_endrvhsr =
+ AB8500_CODEC_CR7_ENDRVHSR_ENABLED;
+
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr9_endachsl =
+ AB8500_CODEC_CR9_ENDACHSL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachsr =
+ AB8500_CODEC_CR9_ENDACHSR_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr12_encphs =
+ AB8500_CODEC_CR12_ENCPHS_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_DEST_EARPIECE:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_DEST_HANDSFREE:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_ENABLED;
+
+ break;
+
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+
+ break;
+
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+
+ break;
+
+ case AB8500_CODEC_DEST_ALL:
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfl =
+ AB8500_CODEC_CR10_MUTEHFL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehfr =
+ AB8500_CODEC_CR10_MUTEHFR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibl =
+ AB8500_CODEC_CR10_MUTEVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutevibr =
+ AB8500_CODEC_CR10_MUTEVIBR_DISABLED;
+
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+
+ break;
+
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_DestPowerControlUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+
+ ab8500_codec_error = ab8500_codec_UpdateCR8();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR9();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR10();
+ if (ab8500_codec_error != AB8500_CODEC_OK) {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+
+ ab8500_codec_error = ab8500_codec_UpdateCR15();
+
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
diff --git a/sound/ab8500_codec_v1_0.c b/sound/ab8500_codec_v1_0.c
new file mode 100644
index 00000000000..5df1ca3eae4
--- /dev/null
+++ b/sound/ab8500_codec_v1_0.c
@@ -0,0 +1,6405 @@
+/*****************************************************************************/
+
+/**
+* © ST-Ericsson, 2009 - All rights reserved
+* Reproduction and Communication of this document is strictly prohibited
+* unless specifically authorized in writing by ST-Ericsson
+*
+* \brief This module provides some support routines for the AB8500 CODEC
+* \author ST-Ericsson
+*/
+/*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * Includes
+ *---------------------------------------------------------------------------*/
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+#include <mach/ab8500_codec_v1_0.h>
+#include <mach/ab8500_codec_p_v1_0.h>
+#else /* */
+#include <mach/ab8500_codec.h>
+#include <mach/ab8500_codec_p.h>
+#endif /* */
+
+/*--------------------------------------------------------------------------*
+ * debug stuff *
+ *--------------------------------------------------------------------------*/
+#ifdef __DEBUG
+#define MY_DEBUG_LEVEL_VAR_NAME myDebugLevel_AB8500_CODEC
+#define MY_DEBUG_ID myDebugID_AB8500_CODEC
+PRIVATE t_dbg_level MY_DEBUG_LEVEL_VAR_NAME = DEBUG_LEVEL0;
+PRIVATE t_dbg_id MY_DEBUG_ID = AB8500_CODEC_HCL_DBG_ID;
+
+#endif /* */
+
+/*--------------------------------------------------------------------------*
+ * Global data for interrupt mode management *
+ *--------------------------------------------------------------------------*/
+PRIVATE t_ab8500_codec_system_context g_ab8500_codec_system_context;
+
+/*--------------------------------------------------------------------------*
+ * Default Values *
+ *--------------------------------------------------------------------------*/
+#define AB8500_CODEC_DEFAULT_SLAVE_ADDRESS_OF_CODEC 0xD
+#define AB8500_CODEC_DEFAULT_DIRECTION AB8500_CODEC_DIRECTION_OUT
+
+#define AB8500_CODEC_DEFAULT_MODE_IN AB8500_CODEC_MODE_VOICE
+#define AB8500_CODEC_DEFAULT_MODE_OUT AB8500_CODEC_MODE_VOICE
+
+#define AB8500_CODEC_DEFAULT_INPUT_SRC AB8500_CODEC_SRC_MICROPHONE_1A
+#define AB8500_CODEC_DEFAULT_OUTPUT_DEST AB8500_CODEC_DEST_HEADSET
+
+#define AB8500_CODEC_DEFAULT_VOLUME_LEFT_IN 75
+#define AB8500_CODEC_DEFAULT_VOLUME_RIGHT_IN 75
+#define AB8500_CODEC_DEFAULT_VOLUME_LEFT_OUT 75
+#define AB8500_CODEC_DEFAULT_VOLUME_RIGHT_OUT 75
+
+/*---------------------------------------------------------------------
+ * PRIVATE APIs
+ *--------------------------------------------------------------------*/
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch1(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch2(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch3(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch4(IN
+ t_ab8500_codec_slot
+ ad_slot,
+ IN
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation
+ value);
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch1(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state);
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch2(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state);
+PRIVATE t_ab8500_codec_error ab8500_codec_SetModeAndDirectionUpdateCR(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_SetSrcVolumeUpdateCR(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_SetDestVolumeUpdateCR(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionIN(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionOUT(void);
+PRIVATE t_ab8500_codec_error ab8500_codec_DestPowerControlUpdateCR(void);
+
+/********************************************************************************************/
+/* Name: ab8500_codec_SingleWrite */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_SingleWrite(t_uint8
+ register_offset,
+ t_uint8 data)
+{
+ return (t_ab8500_codec_error) (AB8500_CODEC_Write
+ (register_offset, 0x01, &data));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_SingleRead */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_SingleRead(t_uint8
+ register_offset,
+ t_uint8 data)
+{
+ t_uint8 dummy_data = 0xAA;
+ return (t_ab8500_codec_error) (AB8500_CODEC_Read
+ (register_offset, 0x01, &dummy_data,
+ &data));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR0 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR0(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr0_powerup, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR0_POWERUP );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr0_enaana, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR0_ENAANA );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR0, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR1 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR1(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr1_swreset, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR1_SWRESET );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR1, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR2 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR2(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr2_enad1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR2_ENAD1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr2_enad2, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR2_ENAD2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr2_enad3, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR2_ENAD3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr2_enad4, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR2_ENAD4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr2_enad5, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR2_ENAD5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr2_enad6, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR2_ENAD6 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR2, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR3 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR3(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr3_enda1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR3_ENDA1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr3_enda2, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR3_ENDA2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr3_enda3, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR3_ENDA3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr3_enda4, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR3_ENDA4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr3_enda5, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR3_ENDA5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr3_enda6, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR3_ENDA6 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR3, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR4 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR4(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr4_lowpowhs, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR4_LOWPOWHS );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr4_lowpowdachs,
+ AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR4_LOWPOWDACHS );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr4_lowpowear, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR4_LOWPOWEAR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr4_ear_sel_cm, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR4_EAR_SEL_CM );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr4_hs_hp_en, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR4_HS_HP_EN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR4, value));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR5 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR5(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_enmic1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_ENMIC1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_enmic2, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_ENMIC2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_enlinl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_ENLINL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_enlinr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_ENLINR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_mutmic1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_MUTMIC1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_mutmic2, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_MUTMIC2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_mutlinl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_MUTELINL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr5_mutlinr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR5_MUTELINR );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR5, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR6 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR6(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr6_endmic1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR6_ENDMIC1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr6_endmic2, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR6_ENDMIC2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr6_endmic3, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR6_ENDMIC3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr6_endmic4, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR6_ENDMIC4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr6_endmic5, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR6_ENDMIC5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr6_endmic6, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR6_ENDMIC6 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR6, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR7 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR7(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_mic1sel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_MIC1SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_linrsel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_LINRSEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_endrvhsl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_ENDRVHSL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_endrvhsr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_ENDRVHSR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_enadcmic, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_ENADCMIC );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_enadclinl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_ENADCLINL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr7_enadclinr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR7_ENADCLINR );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR7, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR8 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR8(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_cp_dis_pldwn,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_CP_DIS_PLDWN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_enear, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENEAR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_enhsl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENHSL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_enhsr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENHSR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_enhfl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENHFL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_enhfr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENHFR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_envibl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENVIBL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr8_envibr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR8_ENVIBR );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR8, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR9 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR9(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endacear, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACEAR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endachsl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACHSL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endachsr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACHSR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endachfl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACHFL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endachfr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACHFR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endacvibl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACVIBL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr9_endacvibr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR9_ENADACVIBR );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR9, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR10 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR10(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr10_muteear, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR10_MUTEEAR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr10_mutehsl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR10_MUTEHSL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr10_mutehsr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR10_MUTEHSR );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR10, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR11 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR11(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_earshortpwd,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_ENSHORTPWD );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_earshortdis,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_EARSHORTDIS );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_hsshortdis, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_HSSHORTDIS );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_hspullden, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_HSPULLDEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_hsoscen, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_HSOSCEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_hsfaden, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_HSFADEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr11_hszcddis, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR11_HSZCDDIS );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR11, value));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR12 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR12(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr12_encphs, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR12_ENCPHS );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr12_hsautoen, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR12_HSAUTOEN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR12, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR13 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR13(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr13_envdet_hthresh,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR13_ENVDET_HTHRESH );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr13_envdet_lthresh,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR13_ENVDET_LTHRESH );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR13, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR14 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR14(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr14_smpslven, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR14_SMPSLVEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr14_envdetsmpsen,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR14_ENVDETSMPSEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr14_cplven, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR14_CPLVEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr14_envdetcpen, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR14_ENVDETCPEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr14_envet_time,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR14_ENVDET_TIME );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR14, value));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR15 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR15(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmtovibl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMTOVIBL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmtovibr, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMTOVIBR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmlctrl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMLCTRL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmrctrl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMRCTRL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmnlctrl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMNLCTRL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmplctrl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMPLCTRL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmnrctrl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMNRCTRL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr15_pwmprctrl, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR15_PWMPRCTRL );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR15, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR16 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR16(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr16_pwmnlpol, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR16_PWMNLPOL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr16_pwmnldutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS,
+ AB8500_CODEC_CR16_PWMNLDUTYCYCLE );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR16, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR17 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR17(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr17_pwmplpol, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR17_PWMPLPOL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr17_pwmpldutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS,
+ AB8500_CODEC_CR17_PWMLPDUTYCYCLE );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR17, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR18 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR18(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr18_pwmnrpol, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR18_PWMNRPOL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr18_pwmnrdutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS,
+ AB8500_CODEC_CR18_PWMNRDUTYCYCLE );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR18, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR19 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR19(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr19_pwmprpol, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR19_PWMPRPOL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr19_pwmprdutycycle,
+ AB8500_CODEC_MASK_SEVEN_BITS,
+ AB8500_CODEC_CR19_PWMRPDUTYCYCLE );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR19, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR20 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR20(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr20_en_se_mic1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR20_EN_SE_MIC1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr20_low_pow_mic1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR20_LOW_POW_MIC1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr20_mic1_gain,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR20_MIC1_GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR20, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR21 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR21(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr21_en_se_mic2,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR21_EN_SE_MIC2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr21_low_pow_mic2,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR21_LOW_POW_MIC2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr21_mic2_gain,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR21_MIC2_GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR21, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR22 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR22(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr22_hsl_gain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR22_HSL_GAIN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr22_hsr_gain, AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR22_HSR_GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR22, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR23 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR23(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr23_linl_gain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR23_LINL_GAIN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr23_linr_gain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR23_LINR_GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR23, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR24 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR24(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr24_lintohsl_gain,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR24_LINTOHSL_GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR24, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR25 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR25(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr25_lintohsr_gain,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR25_LINTOHSR_GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR25, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR26 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR26(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad1nh, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD1NH );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad2nh, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD2NH );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad3nh, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD3NH );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad4nh, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD4NH );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad1_voice, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD1_VOICE );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad2_voice, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD2_VOICE );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad3_voice, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD3_VOICE );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr26_ad4_voice, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR26_AD4_VOICE );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR26, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR27 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR27(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr27_en_mastgen,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR27_EN_MASTGEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr27_if1_bitclk_osr,
+ AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR27_IF1_BITCLK_OSR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr27_enfs_bitclk1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR27_ENFS_BITCLK1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr27_if0_bitclk_osr,
+ AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR27_IF0_BITCLK_OSR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr27_enfs_bitclk0,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR27_ENFS_BITCLK0 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR27, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR28 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR28(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr28_fsync0p, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR28_FSYNC0P );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr28_bitclk0p, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR28_BITCLK0P );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr28_if0del, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR28_IF0DEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr28_if0format, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR28_IF0FORMAT );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr28_if0wl, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR28_IF0WL );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR28, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR29 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR29(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if0datoif1ad,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF0DATOIF1AD );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if0cktoif1ck,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF0CKTOIF1CK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if1master, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF1MASTER );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if1datoif0ad,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF1DATOIF0AD );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if1cktoif0ck,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF1CKTOIF0CK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if0master, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF0MASTER );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr29_if0bfifoen, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR29_IF0BFIFOEN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR29, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR30 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR30(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr30_fsync1p, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR30_FSYNC1P );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr30_bitclk1p, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR30_BITCLK1P );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr30_if1del, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR30_IF1DEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr30_if1format, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR30_IF1FORMAT );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr30_if1wl, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR30_IF1WL );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR30, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR31 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR31(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr31_adotoslot1,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR31_ADOTOSLOT1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr31_adotoslot0,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR31_ADOTOSLOT0 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR31, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR32 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR32(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr32_adotoslot3,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR32_ADOTOSLOT3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr32_adotoslot2,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR32_ADOTOSLOT2 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR32, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR33 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR33(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr33_adotoslot5,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR33_ADOTOSLOT5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr33_adotoslot4,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR33_ADOTOSLOT4 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR33, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR34 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR34(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr34_adotoslot7,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR34_ADOTOSLOT7 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr34_adotoslot6,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR34_ADOTOSLOT6 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR34, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR35 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR35(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr35_adotoslot9,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR35_ADOTOSLOT9 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr35_adotoslot8,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR35_ADOTOSLOT8 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR35, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR36 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR36(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr36_adotoslot11,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR36_ADOTOSLOT11 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr36_adotoslot10,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR36_ADOTOSLOT10 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR36, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR37 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR37(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr37_adotoslot13,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR37_ADOTOSLOT13 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr37_adotoslot12,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR37_ADOTOSLOT12 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR37, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR38 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR38(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr38_adotoslot15,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR38_ADOTOSLOT15 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr38_adotoslot14,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR38_ADOTOSLOT14 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR38, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR39 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR39(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr39_adotoslot17,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR39_ADOTOSLOT17 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr39_adotoslot16,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR39_ADOTOSLOT16 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR39, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR40 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR40(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr40_adotoslot19,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR40_ADOTOSLOT19 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr40_adotoslot18,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR40_ADOTOSLOT18 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR40, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR41 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR41(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr41_adotoslot21,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR41_ADOTOSLOT21 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr41_adotoslot20,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR41_ADOTOSLOT20 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR41, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR42 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR42(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr42_adotoslot23,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR42_ADOTOSLOT23 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr42_adotoslot22,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR42_ADOTOSLOT22 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR42, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR43 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR43(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr43_adotoslot25,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR43_ADOTOSLOT25 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr43_adotoslot24,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR43_ADOTOSLOT24 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR43, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR44 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR44(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr44_adotoslot27,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR44_ADOTOSLOT27 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr44_adotoslot26,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR44_ADOTOSLOT26 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR44, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR45 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR45(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr45_adotoslot29,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR45_ADOTOSLOT29 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr45_adotoslot28,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR45_ADOTOSLOT28 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR45, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR46 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR46(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr46_adotoslot31,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR46_ADOTOSLOT31 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr46_adotoslot30,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR46_ADOTOSLOT30 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR46, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR47 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR47(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl7, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL7 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl6, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL6 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl5, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl4, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl3, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl2, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr47_hiz_sl0, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR47_HIZ_SL0 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR47, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR48 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR48(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl15, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL15 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl14, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL14 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl13, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL13 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl12, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL12 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl11, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL11 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl10, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL10 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl9, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL9 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr48_hiz_sl8, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR48_HIZ_SL8 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR48, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR49 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR49(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl23, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL23 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl22, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL22 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl21, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL21 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl20, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL20 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl19, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL19 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl18, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL18 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl17, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL17 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr49_hiz_sl16, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR49_HIZ_SL16 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR49, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR50 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR50(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl31, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL31 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl30, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL30 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl29, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL29 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl28, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL28 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl27, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL27 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl26, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL26 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl25, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL25 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr50_hiz_sl24, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR50_HIZ_SL24 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR50, value));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR51 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR51(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr51_da12_voice,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR51_DA12_VOICE );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr51_swapda12_34,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR51_SWAP_DA12_34 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr51_sldai7toslado1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR51_SLDAI7TOSLADO1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr51_sltoda1, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR51_SLTODA1 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR51, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR52 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR52(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr52_sldai8toslado2,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR52_SLDAI8TOSLADO2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr52_sltoda2, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR52_SLTODA2 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR52, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR53 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR53(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr53_da34_voice,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR53_DA34_VOICE );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr53_sldai7toslado3,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR53_SLDAI7TOSLADO3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr53_sltoda3, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR53_SLTODA3 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR53, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR54 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR54(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr54_sldai8toslado4,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR54_SLDAI8TOSLADO4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr54_sltoda4, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR54_SLTODA4 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR54, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR55 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR55(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr55_da56_voice,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR55_DA56_VOICE );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr55_sldai7toslado5,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR55_SLDAI7TOSLADO5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr55_sltoda5, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR55_SLTODA5 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR55, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR56 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR56(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr56_sldai8toslado6,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR56_SLDAI8TOSLADO6 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr56_sltoda6, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR56_SLTODA6 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR56, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR57 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR57(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr57_sldai8toslado7,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR57_SLDAI8TOSLADO7 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr57_sltoda7, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR57_SLTODA7 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR57, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR58 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR58(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr58_sldai7toslado8,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR58_SLDAI7TOSLADO8 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr58_sltoda8, AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR58_SLTODA8 );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR58, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR59 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR59(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr59_parlhf, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR59_PARLHF );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr59_parlvib, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR59_PARLVIB );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr59_classdvib1_swapen,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR59_CLASSDVIB1SWAPEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr59_classdvib2_swapen,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR59_CLASSDVIB2SWAPEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr59_classdhfl_swapen,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR59_CLASSDHFLSWAPEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr59_classdhfr_swapen,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR59_CLASSDHFRSWAPEN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR59, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR60 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR60(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr60_classd_firbyp,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR60_CLASSD_FIR_BYP );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr60_classd_highvolen,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR60_CLASSD_HIGHVOL_EN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR60, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR61 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR61(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+
+ /* 5 bits are Read Only */
+ AB8500_CODEC_WRITE_BITS
+ (value,
+ (t_uint8) p_ab8500_codec_configuration->cr61_classddith_hpgain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR61_CLASSD_DITH_HPGAIN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr61_classddith_wgain,
+ AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR61_CLASSD_DITH_WGAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR61, value));
+}
+
+#endif /* */
+
+/* CR62 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR63 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR63(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_datohslen, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_DATOHSLEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_datohsren, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_DATOHSREN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_ad1sel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_AD1SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_ad2sel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_AD2SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_ad3sel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_AD3SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_ad5sel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_AD5SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_ad6sel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_AD6SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr63_ancsel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR63_ANCSEL );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR63, value));
+}
+
+#if 0
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR64 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR64(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr64_datohfren, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR64_DATOHFREN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr64_datohflen, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR64_DATOHFLEN );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr64_hfrsel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR64_HFRSEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr64_hflsel, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR64_HFLSEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr64_stfir1sel, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR64_STFIR1SEL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr64_stfir2sel, AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR64_STFIR2SEL );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR64, value));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR65 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR65(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr65_fadedis_ad1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR65_FADEDIS_AD1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr65_ad1gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR65_AD1GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR65, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR66 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR66(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr66_fadedis_ad2,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR66_FADEDIS_AD2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr66_ad2gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR66_AD2GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR66, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR67 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR67(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr67_fadedis_ad3,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR67_FADEDIS_AD3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr67_ad3gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR67_AD3GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR67, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR68 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR68(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr68_fadedis_ad4,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR68_FADEDIS_AD4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr68_ad4gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR68_AD4GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR68, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR69 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR69(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr69_fadedis_ad5,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR69_FADEDIS_AD5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr69_ad5gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR69_AD5GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR69, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR70 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR70(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr70_fadedis_ad6,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR70_FADEDIS_AD6 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr70_ad6gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR70_AD6GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR70, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR71 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR71(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr71_fadedis_da1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR71_FADEDIS_DA1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr71_da1gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR71_DA1GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR71, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR72 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR72(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr72_fadedis_da2,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR72_FADEDIS_DA2 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr72_da2gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR72_DA2GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR72, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR73 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR73(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr73_fadedis_da3,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR73_FADEDIS_DA3 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr73_da3gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR73_DA3GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR73, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR74 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR74(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr74_fadedis_da4,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR74_FADEDIS_DA4 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr74_da4gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR74_DA4GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR74, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR75 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR75(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr75_fadedis_da5,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR75_FADEDIS_DA5 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr75_da5gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR75_DA5GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR75, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR76 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR76(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr76_fadedis_da6,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR76_FADEDIS_DA6 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr76_da6gain, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR76_DA6GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR76, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR77 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR77(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr77_fadedis_ad1l,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR77_FADEDIS_AD1L );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr77_ad1lbgain_to_hfl,
+ AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR77_AD1LBGAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR77, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR78 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR78(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr78_fadedis_ad2l,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR78_FADEDIS_AD2L );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr78_ad2lbgain_to_hfr,
+ AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR78_AD2LBGAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR78, value));
+}
+
+#endif /* */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR79 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR79(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr79_hssinc1, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR79_HSSINC1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr79_fadedis_hsl,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR79_FADEDIS_HSL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr79_hsldgain, AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR79_HSLDGAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR79, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR80 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR80(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr80_fade_speed,
+ AB8500_CODEC_MASK_TWO_BITS,
+ AB8500_CODEC_CR80_FADE_SPEED );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr80_fadedis_hsr,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR80_FADEDIS_HSR );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr80_hsrdgain, AB8500_CODEC_MASK_FOUR_BITS,
+ AB8500_CODEC_CR80_HSRDGAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR80, value));
+}
+
+#if 0
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR81 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR81(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr81_stfir1gain,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR81_STFIR1GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR81, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR82 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR82(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr82_stfir2gain,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR82_STFIR2GAIN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR82, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR83 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR83(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr83_enanc, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR83_ENANC );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr83_anciirinit, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR83_ANCIIRINIT );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr83_ancfirupdate,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR83_ANCFIRUPDATE );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR83, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR84 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR84(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr84_ancinshift,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR84_ANCINSHIFT );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR84, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR85 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR85(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr85_ancfiroutshift,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR85_ANCFIROUTSHIFT );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR85, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR86 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR86(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr86_ancshiftout,
+ AB8500_CODEC_MASK_FIVE_BITS,
+ AB8500_CODEC_CR86_ANCSHIFTOUT );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR86, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR87 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR87(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr87_ancfircoeff_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR87_ANCFIRCOEFF_MSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR87, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR88 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR88(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr88_ancfircoeff_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR88_ANCFIRCOEFF_LSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR88, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR89 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR89(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr89_anciircoeff_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR89_ANCIIRCOEFF_MSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR89, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR90 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR90(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr90_anciircoeff_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR90_ANCIIRCOEFF_LSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR90, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR91 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR91(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr91_ancwarpdel_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR91_ANCWARPDEL_MSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR91, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR92 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR92(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr92_ancwarpdel_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR92_ANCWARPDEL_LSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR92, value));
+}
+
+/* CR93 is Read Only */
+/* CR94 is Read Only */
+/* CR95 is Read Only */
+/* CR96 is Read Only */
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR97 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR97(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr97_stfir_set, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR97_STFIR_SET );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr97_stfir_addr,
+ AB8500_CODEC_MASK_SEVEN_BITS,
+ AB8500_CODEC_CR97_STFIR_ADDR );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR97, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR98 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR98(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr98_stfir_coeff_msb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR98_STFIR_COEFF_MSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR98, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR99 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR99(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr99_stfir_coeff_lsb,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR99_STFIR_COEFF_LSB );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR99, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR100 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR100(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr100_enstfirs, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR100_ENSTFIRS );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr100_stfirstoif1,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR100_STFIRSTOIF1 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr100_stfir_busy,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR100_STFIR_BUSY );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR100, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR101 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR101(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_hsoffst_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_HSOFFSTMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_fifofull_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_FIFOFULLMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_fifoempty_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_FIFOEMPTYMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_dasat_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_DASATMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_adsat_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_ADSATMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_addsp_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_ADDSPMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_dadsp_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_DADSPMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr101_firsid_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR101_FIRSIDMASK );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR101, value));
+}
+
+/* CR102 is Read Only */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR103 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR103(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr103_vssready_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR103_VSSREADYMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr103_shorthsl_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR103_SHORTHSLMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr103_shorthsr_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR103_SHORTHSRMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr103_shortear_mask,
+ AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR103_SHORTEARMASK );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR103, value));
+}
+
+#endif /* */
+
+/* CR104 is Read Only */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR105 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR105(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr105_bfifomsk, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR105_BFIFOMASK );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr105_bfifoint, AB8500_CODEC_MASK_SIX_BITS,
+ AB8500_CODEC_CR105_BFIFOINT );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR105, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR106 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR106(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr106_bfifotx,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR106_BFIFOTX );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR106, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR107 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR107(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr107_bfifoexsl,
+ AB8500_CODEC_MASK_THREE_BITS,
+ AB8500_CODEC_CR107_BFIFOEXSL );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr107_prebitclk0,
+ AB8500_CODEC_MASK_THREE_BITS,
+ AB8500_CODEC_CR107_PREBITCLK0 );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr107_bfifomast, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR107_BFIFOMAST );
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr107_bfiforun, AB8500_CODEC_MASK_ONE_BIT,
+ AB8500_CODEC_CR107_BFIFORUN );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR107, value));
+}
+
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR108 */
+/********************************************************************************************/
+ PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR108(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr108_bfifoframsw,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR108_BFIFOFRAMESW );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR108, value));
+}
+
+/********************************************************************************************/
+/* Name: ab8500_codec_UpdateCR109 */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_UpdateCR109(void)
+{
+ t_uint8 value = 0x00;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ AB8500_CODEC_WRITE_BITS (value,
+ (t_uint8) p_ab8500_codec_configuration->
+ cr109_bfifowakeup,
+ AB8500_CODEC_MASK_EIGHT_BITS,
+ AB8500_CODEC_CR109_BFIFOWAKEUP );
+ return (ab8500_codec_SingleWrite(AB8500_CODEC_CR109, value));
+}
+
+/* CR110 is Read Only */
+
+/* CR111 is Read Only */
+
+/********************************************************************************************/
+/* Name: ab8500_codec_Reset() */
+
+/********************************************************************************************/
+PRIVATE t_ab8500_codec_error ab8500_codec_Reset(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ p_ab8500_codec_configuration->cr1_swreset =
+ AB8500_CODEC_CR1_SWRESET_ENABLED;
+ ab8500_codec_error = ab8500_codec_UpdateCR1();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirection(IN
+ t_ab8500_codec_direction
+ ab8500_codec_direction)
+ /*only IN or OUT must be passed (not INOUT) */
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ if (AB8500_CODEC_DIRECTION_IN == ab8500_codec_direction)
+ {
+ ab8500_codec_error = ab8500_codec_ProgramDirectionIN();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+ if (AB8500_CODEC_DIRECTION_OUT == ab8500_codec_direction)
+ {
+ ab8500_codec_error = ab8500_codec_ProgramDirectionOUT();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetDirection(IN
+ t_ab8500_codec_direction
+ ab8500_codec_direction)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ switch (ab8500_codec_direction)
+ {
+ case AB8500_CODEC_DIRECTION_IN:
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection(AB8500_CODEC_DIRECTION_IN);
+ break;
+ case AB8500_CODEC_DIRECTION_OUT:
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection(AB8500_CODEC_DIRECTION_OUT);
+ break;
+ case AB8500_CODEC_DIRECTION_INOUT:
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection(AB8500_CODEC_DIRECTION_IN);
+ if (AB8500_CODEC_OK == ab8500_codec_error)
+ {
+ ab8500_codec_error =
+ ab8500_codec_ProgramDirection
+ (AB8500_CODEC_DIRECTION_OUT);
+ }
+ break;
+ }
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR5();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR6();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR7();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR8();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR9();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR10();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR12();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR15();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR63();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_Init */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Initialize the global variables & stores the slave address of codec. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* slave_address_of_ab8500_codec: Audio codec slave address */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* Returns AB8500_CODEC_OK */
+/* COMMENTS: */
+/* 1) Saves the supplied slave_address_of_codec in global variable */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_Init(IN t_uint8
+ slave_address_of_ab8500_codec)
+{
+ DBGENTER1(" (%lx)", slave_address_of_ab8500_codec);
+ g_ab8500_codec_system_context.slave_address_of_ab8500_codec =
+ slave_address_of_ab8500_codec;
+ DBGEXIT(AB8500_CODEC_OK);
+ return (AB8500_CODEC_OK);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_Reset */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Reset the global variables and clear audiocodec settings to default. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_Reset(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER();
+ g_ab8500_codec_system_context.ab8500_codec_direction =
+ AB8500_CODEC_DEFAULT_DIRECTION;
+ g_ab8500_codec_system_context.ab8500_codec_mode_in =
+ AB8500_CODEC_DEFAULT_MODE_IN;
+ g_ab8500_codec_system_context.ab8500_codec_mode_out =
+ AB8500_CODEC_DEFAULT_MODE_OUT;
+ g_ab8500_codec_system_context.ab8500_codec_src =
+ AB8500_CODEC_DEFAULT_INPUT_SRC;
+ g_ab8500_codec_system_context.ab8500_codec_dest =
+ AB8500_CODEC_DEFAULT_OUTPUT_DEST;
+ g_ab8500_codec_system_context.in_left_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_LEFT_IN;
+ g_ab8500_codec_system_context.in_right_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_RIGHT_IN;
+ g_ab8500_codec_system_context.out_left_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_LEFT_OUT;
+ g_ab8500_codec_system_context.out_right_volume =
+ AB8500_CODEC_DEFAULT_VOLUME_RIGHT_OUT;
+ ab8500_codec_error = ab8500_codec_Reset();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetModeAndDirection */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Configures the whole audio codec to work in audio mode */
+/* (using I2S protocol). */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* direction: select the direction (IN, OUT or INOUT) */
+/* in_mode: codec mode for recording. If direction is OUT only, */
+/* this parameter is ignored. */
+/* out_mode: codec mode for playing. If direction is IN only, */
+/* this parameter is ignored. */
+/* p_tdm_config: TDM configuration required to be configured by user */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: The API may not allow setting */
+/* 2 different modes, in which case it should return this value. */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetModeAndDirection
+ (IN t_ab8500_codec_direction ab8500_codec_direction,
+ IN t_ab8500_codec_mode ab8500_codec_mode_in,
+ IN t_ab8500_codec_mode ab8500_codec_mode_out,
+ IN t_ab8500_codec_tdm_config const *const p_tdm_config ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ DBGENTER3(" (%lx %lx %lx)", ab8500_codec_direction,
+ ab8500_codec_mode_in, ab8500_codec_mode_out);
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ if (AB8500_CODEC_DIRECTION_OUT == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT ==
+ ab8500_codec_direction )
+ {
+ p_ab8500_codec_configuration->cr3_enda1 =
+ AB8500_CODEC_CR3_ENDA1_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda2 =
+ AB8500_CODEC_CR3_ENDA2_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda3 =
+ AB8500_CODEC_CR3_ENDA3_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda4 =
+ AB8500_CODEC_CR3_ENDA4_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda5 =
+ AB8500_CODEC_CR3_ENDA5_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda6 =
+ AB8500_CODEC_CR3_ENDA6_ENABLED;
+ p_ab8500_codec_configuration->cr27_if1_bitclk_osr =
+ p_tdm_config->cr27_if1_bitclk_osr;
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_out)
+ {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_TDM;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ }
+ }
+ if (AB8500_CODEC_DIRECTION_IN == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT ==
+ ab8500_codec_direction )
+ {
+ p_ab8500_codec_configuration->cr2_enad1 =
+ AB8500_CODEC_CR2_ENAD1_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad2 =
+ AB8500_CODEC_CR2_ENAD2_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad3 =
+ AB8500_CODEC_CR2_ENAD3_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad4 =
+ AB8500_CODEC_CR2_ENAD4_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad5 =
+ AB8500_CODEC_CR2_ENAD5_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad6 =
+ AB8500_CODEC_CR2_ENAD6_ENABLED;
+ p_ab8500_codec_configuration->cr27_if1_bitclk_osr =
+ p_tdm_config->cr27_if1_bitclk_osr;
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_in)
+ {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr30_fsync1p =
+ AB8500_CODEC_CR30_FSYNC1P_RISING_EDGE;
+ p_ab8500_codec_configuration->cr30_bitclk1p =
+ AB8500_CODEC_CR30_BITCLK1P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr30_if1del =
+ AB8500_CODEC_CR30_IF1DEL_NOT_DELAYED;
+ p_ab8500_codec_configuration->cr30_if1format =
+ AB8500_CODEC_CR30_IF1FORMAT_TDM;
+ p_ab8500_codec_configuration->cr30_if1wl =
+ p_tdm_config->cr30_if1wl;
+ }
+ }
+ }
+
+ else
+ {
+ if (AB8500_CODEC_DIRECTION_OUT == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT ==
+ ab8500_codec_direction )
+ {
+ p_ab8500_codec_configuration->cr3_enda1 =
+ AB8500_CODEC_CR3_ENDA1_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda2 =
+ AB8500_CODEC_CR3_ENDA2_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda3 =
+ AB8500_CODEC_CR3_ENDA3_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda4 =
+ AB8500_CODEC_CR3_ENDA4_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda5 =
+ AB8500_CODEC_CR3_ENDA5_ENABLED;
+ p_ab8500_codec_configuration->cr3_enda6 =
+ AB8500_CODEC_CR3_ENDA6_ENABLED;
+ p_ab8500_codec_configuration->cr27_if0_bitclk_osr =
+ p_tdm_config->cr27_if0_bitclk_osr;
+ p_ab8500_codec_configuration->cr63_datohslen =
+ AB8500_CODEC_CR63_DATOHSLEN_ENABLED;
+ p_ab8500_codec_configuration->cr63_datohsren =
+ AB8500_CODEC_CR63_DATOHSREN_ENABLED;
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_out)
+ {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_FALLING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_TDM;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ }
+ }
+ if (AB8500_CODEC_DIRECTION_IN == ab8500_codec_direction
+ || AB8500_CODEC_DIRECTION_INOUT ==
+ ab8500_codec_direction )
+ {
+ p_ab8500_codec_configuration->cr2_enad1 =
+ AB8500_CODEC_CR2_ENAD1_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad2 =
+ AB8500_CODEC_CR2_ENAD2_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad3 =
+ AB8500_CODEC_CR2_ENAD3_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad4 =
+ AB8500_CODEC_CR2_ENAD4_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad5 =
+ AB8500_CODEC_CR2_ENAD5_ENABLED;
+ p_ab8500_codec_configuration->cr2_enad6 =
+ AB8500_CODEC_CR2_ENAD6_ENABLED;
+ p_ab8500_codec_configuration->cr26_ad1_voice =
+ AB8500_CODEC_CR26_AD1_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr26_ad2_voice =
+ AB8500_CODEC_CR26_AD2_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr26_ad3_voice =
+ AB8500_CODEC_CR26_AD3_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr26_ad4_voice =
+ AB8500_CODEC_CR26_AD4_VOICE_LOWLATENCYFILTER;
+ p_ab8500_codec_configuration->cr27_if0_bitclk_osr =
+ p_tdm_config->cr27_if0_bitclk_osr;
+ if (AB8500_CODEC_MODE_HIFI == ab8500_codec_mode_in)
+ {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_RISING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_RISING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_NOT_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_I2S_LEFTALIGNED;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr28_fsync0p =
+ AB8500_CODEC_CR28_FSYNC0P_RISING_EDGE;
+ p_ab8500_codec_configuration->cr28_bitclk0p = p_tdm_config->cr28_bitclk0p; /*AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE; */
+ p_ab8500_codec_configuration->cr28_if0del = p_tdm_config->cr28_if0del; /*AB8500_CODEC_CR28_IF0DEL_NOT_DELAYED; */
+ p_ab8500_codec_configuration->cr28_if0format =
+ AB8500_CODEC_CR28_IF0FORMAT_TDM;
+ p_ab8500_codec_configuration->cr28_if0wl =
+ p_tdm_config->cr28_if0wl;
+ }
+ }
+ }
+ ab8500_codec_error = ab8500_codec_SetModeAndDirectionUpdateCR();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ g_ab8500_codec_system_context.ab8500_codec_direction =
+ ab8500_codec_direction;
+ g_ab8500_codec_system_context.ab8500_codec_mode_in =
+ ab8500_codec_mode_in;
+ g_ab8500_codec_system_context.ab8500_codec_mode_out =
+ ab8500_codec_mode_out;
+ ab8500_codec_error =
+ ab8500_codec_SetDirection(ab8500_codec_direction);
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetSrcVolume */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Sets the record volumes. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* t_ab8500_codec_src: select source device for recording. */
+/* in_left_volume: record volume for left channel. */
+/* in_right_volume: record volume for right channel. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetSrcVolume
+ (IN t_ab8500_codec_src src_device, IN t_uint8 in_left_volume,
+ IN t_uint8 in_right_volume ) {
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ DBGENTER3(" (%lx %lx %lx)", src_device, in_left_volume,
+ in_right_volume);
+ if (in_left_volume > AB8500_CODEC_MAX_VOLUME)
+ {
+ in_left_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+ if (in_right_volume > AB8500_CODEC_MAX_VOLUME)
+ {
+ in_right_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+ g_ab8500_codec_system_context.in_left_volume = in_left_volume;
+ g_ab8500_codec_system_context.in_right_volume = in_right_volume;
+ p_ab8500_codec_configuration->cr65_ad1gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr66_ad2gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr67_ad3gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr68_ad4gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr69_ad5gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr70_ad6gain =
+ AB8500_CODEC_AD_D_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_AD_D_VOLUME_MAX -
+ AB8500_CODEC_AD_D_VOLUME_MIN)) / 100;
+
+ /* Set mininimum volume if volume is zero */
+ switch (src_device)
+ {
+ case AB8500_CODEC_SRC_LINEIN:
+ p_ab8500_codec_configuration->cr23_linl_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr23_linr_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_right_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ p_ab8500_codec_configuration->cr20_mic1_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ p_ab8500_codec_configuration->cr21_mic2_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ break;
+ case AB8500_CODEC_SRC_ALL:
+ p_ab8500_codec_configuration->cr23_linl_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr23_linr_gain =
+ AB8500_CODEC_LINEIN_VOLUME_MIN +
+ (in_right_volume *
+ (AB8500_CODEC_LINEIN_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr20_mic1_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr21_mic2_gain =
+ AB8500_CODEC_MIC_VOLUME_MIN +
+ (in_left_volume *
+ (AB8500_CODEC_MIC_VOLUME_MAX -
+ AB8500_CODEC_MIC_VOLUME_MIN)) / 100;
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_SetSrcVolumeUpdateCR();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetDestVolume */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Sets the play volumes. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* out_left_volume: play volume for left channel. */
+/* out_right_volume: play volume for right channel. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetDestVolume
+ (IN t_ab8500_codec_dest dest_device, IN t_uint8 out_left_volume,
+ IN t_uint8 out_right_volume ) {
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ DBGENTER3(" (%lx %lx %lx)", dest_device, out_left_volume,
+ out_right_volume);
+ if (out_left_volume > AB8500_CODEC_MAX_VOLUME)
+ {
+ out_left_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+ if (out_right_volume > AB8500_CODEC_MAX_VOLUME)
+ {
+ out_right_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+ g_ab8500_codec_system_context.out_left_volume = out_left_volume;
+ g_ab8500_codec_system_context.out_right_volume = out_right_volume;
+ p_ab8500_codec_configuration->cr71_da1gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr72_da2gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr73_da3gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr74_da4gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr75_da5gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr76_da6gain =
+ AB8500_CODEC_DA_D_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_DA_D_VOLUME_MAX -
+ AB8500_CODEC_DA_D_VOLUME_MIN)) / 100;
+
+ /* Set mininimum volume if volume is zero */
+ switch (dest_device)
+ {
+ case AB8500_CODEC_DEST_HEADSET:
+ p_ab8500_codec_configuration->cr22_hsl_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr22_hsr_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr79_hsldgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ p_ab8500_codec_configuration->cr80_hsrdgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ break;
+ case AB8500_CODEC_DEST_EARPIECE:
+ p_ab8500_codec_configuration->cr79_hsldgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ break;
+ case AB8500_CODEC_DEST_HANDSFREE:
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ p_ab8500_codec_configuration->cr16_pwmnldutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN;
+ p_ab8500_codec_configuration->cr17_pwmpldutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_VIBRATOR_VOLUME_MAX -
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN)) / 100;
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ p_ab8500_codec_configuration->cr18_pwmnrdutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN;
+ p_ab8500_codec_configuration->cr19_pwmprdutycycle =
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_VIBRATOR_VOLUME_MAX -
+ AB8500_CODEC_VIBRATOR_VOLUME_MIN)) / 100;
+ break;
+ case AB8500_CODEC_DEST_ALL:
+ p_ab8500_codec_configuration->cr22_hsl_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr22_hsr_gain =
+ AB8500_CODEC_HEADSET_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_HEADSET_VOLUME_MAX -
+ AB8500_CODEC_HEADSET_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr79_hsldgain =
+ AB8500_CODEC_HEADSET_D_VOLUME_0DB;
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_SetDestVolumeUpdateCR();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetMasterMode */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Set the Audio Codec in Master mode. */
+/* */
+/* ARGUMENTS */
+/* IN: t_codec_master_mode: Enable/disable master mode */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: Call this API after calling AB8500_CODEC_SetModeAndDirection() API*/
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetMasterMode(IN
+ t_ab8500_codec_master_mode
+ mode)
+{
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ p_ab8500_codec_configuration->cr27_en_mastgen =
+ AB8500_CODEC_CR27_EN_MASTGEN_ENABLED;
+ p_ab8500_codec_configuration->cr27_enfs_bitclk1 =
+ AB8500_CODEC_CR27_ENFS_BITCLK1_ENABLED;
+ if (AB8500_CODEC_MASTER_MODE_ENABLE == mode)
+ {
+ p_ab8500_codec_configuration->cr29_if1master =
+ AB8500_CODEC_CR29_IF1MASTER_FS1CK1_OUTPUT;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr29_if1master =
+ AB8500_CODEC_CR29_IF1MASTER_FS1CK1_INPUT;
+ }
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr27_en_mastgen =
+ AB8500_CODEC_CR27_EN_MASTGEN_ENABLED;
+ p_ab8500_codec_configuration->cr27_enfs_bitclk0 =
+ AB8500_CODEC_CR27_ENFS_BITCLK0_ENABLED;
+ if (AB8500_CODEC_MASTER_MODE_ENABLE == mode)
+ {
+ p_ab8500_codec_configuration->cr29_if0master =
+ AB8500_CODEC_CR29_IF0MASTER_FS0CK0_OUTPUT;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr29_if0master =
+ AB8500_CODEC_CR29_IF0MASTER_FS0CK0_INPUT;
+ }
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR27();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SelectInput */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Select input source for recording. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* input_src: select input source for recording when several sources */
+/* are supported in codec. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If input_src provided is invalid */
+/* by the codec hardware in use. */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SelectInput(IN t_ab8500_codec_src
+ ab8500_codec_src)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER1(" (%lx)", ab8500_codec_src);
+ g_ab8500_codec_system_context.ab8500_codec_src = ab8500_codec_src;
+ ab8500_codec_error =
+ ab8500_codec_SetDirection(AB8500_CODEC_DIRECTION_IN);
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SelectOutput */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Select output desination for playing. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* output_dest: select output destination for playing when several are */
+/* supported by codec hardware. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If output_src provided is invalid */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SelectOutput(IN t_ab8500_codec_dest
+ ab8500_codec_dest)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ g_ab8500_codec_system_context.ab8500_codec_dest = ab8500_codec_dest;
+ DBGENTER1(" (%lx)", ab8500_codec_dest);
+ ab8500_codec_error =
+ ab8500_codec_SetDirection(AB8500_CODEC_DIRECTION_OUT);
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_PowerDown */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Shuts the audio codec down completely. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* OUT: */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_PowerDown(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ g_ab8500_codec_system_context.ab8500_codec_configuration.cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_OFF;
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_PowerUp */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Switch on the audio codec. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_PowerUp(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER();
+ g_ab8500_codec_system_context.ab8500_codec_configuration.cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_ON;
+ g_ab8500_codec_system_context.ab8500_codec_configuration.cr0_enaana =
+ AB8500_CODEC_CR0_ENAANA_ON;
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SelectInterface */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Select the Audio Interface 0 or 1. */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_audio_interface: The selected interface */
+/* */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_OK: Always. */
+/* REMARK: Call this API before using a function of the low level drivers */
+/* to select the interface that you want to configure */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SelectInterface(IN
+ t_ab8500_codec_audio_interface
+ audio_interface)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+ g_ab8500_codec_system_context.audio_interface = audio_interface;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_GetInterface */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Get the Audio Interface 0 or 1. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: p_audio_interface: Store the selected interface */
+/* RETURN: */
+/* AB8500_CODEC_OK: Always */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_GetInterface(OUT
+ t_ab8500_codec_audio_interface
+ * p_audio_interface)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+ *p_audio_interface = g_ab8500_codec_system_context.audio_interface;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetAnalogLoopback */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Sets Line-In to HeadSet loopback with the required gain. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* out_left_volume: play volume for left channel. */
+/* out_right_volume: play volume for right channel. */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetAnalogLoopback(IN t_uint8
+ out_left_volume,
+ IN t_uint8
+ out_right_volume)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER2(" (%lx %lx)", out_left_volume, out_right_volume);
+ if (out_left_volume > AB8500_CODEC_MAX_VOLUME)
+ {
+ out_left_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+ if (out_right_volume > AB8500_CODEC_MAX_VOLUME)
+ {
+ out_right_volume = AB8500_CODEC_MAX_VOLUME;
+ }
+ g_ab8500_codec_system_context.out_left_volume = out_left_volume;
+ g_ab8500_codec_system_context.out_right_volume = out_right_volume;
+ p_ab8500_codec_configuration->cr24_lintohsl_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN +
+ (out_left_volume *
+ (AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN)) / 100;
+ p_ab8500_codec_configuration->cr25_lintohsr_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN +
+ (out_right_volume *
+ (AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MAX -
+ AB8500_CODEC_LINEIN_TO_HS_L_R_VOLUME_MIN)) / 100;
+ ab8500_codec_error = ab8500_codec_UpdateCR24();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR25();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_RemoveAnalogLoopback */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Remove Line-In to HeadSet loopback. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_RemoveAnalogLoopback(void)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER0();
+ p_ab8500_codec_configuration->cr24_lintohsl_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_LOOP_OPEN;
+ p_ab8500_codec_configuration->cr25_lintohsr_gain =
+ AB8500_CODEC_LINEIN_TO_HS_L_R_LOOP_OPEN;
+ ab8500_codec_error = ab8500_codec_UpdateCR24();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR25();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_EnableBypassMode */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enables IF0 to IF1 path or vice versa */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_EnableBypassMode(void)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER0();
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ p_ab8500_codec_configuration->cr29_if1datoif0ad =
+ AB8500_CODEC_CR29_IF1DATOIF0AD_SENT;
+ p_ab8500_codec_configuration->cr29_if1cktoif0ck =
+ AB8500_CODEC_CR29_IF1CKTOIF0CK_SENT;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr29_if0datoif1ad =
+ AB8500_CODEC_CR29_IF0DATOIF1AD_SENT;
+ p_ab8500_codec_configuration->cr29_if0cktoif1ck =
+ AB8500_CODEC_CR29_IF0CKTOIF1CK_SENT;
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DisableBypassMode */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Disables IF0 to IF1 path or vice versa */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DisableBypassMode(void)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER0();
+ if (AB8500_CODEC_AUDIO_INTERFACE_1 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ p_ab8500_codec_configuration->cr29_if1datoif0ad =
+ AB8500_CODEC_CR29_IF1DATOIF0AD_NOTSENT;
+ p_ab8500_codec_configuration->cr29_if1cktoif0ck =
+ AB8500_CODEC_CR29_IF1CKTOIF0CK_NOTSENT;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr29_if0datoif1ad =
+ AB8500_CODEC_CR29_IF0DATOIF1AD_NOTSENT;
+ p_ab8500_codec_configuration->cr29_if0cktoif1ck =
+ AB8500_CODEC_CR29_IF0CKTOIF1CK_NOTSENT;
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SrcPowerControl */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enables/Disables & UnMute/Mute the desired source */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* t_ab8500_codec_src: select source device for enabling/disabling. */
+/* t_ab8500_codec_src_state: Enable/Disable */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SrcPowerControl(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ DBGENTER2(" (%lx %lx)", src_device, state);
+ if (src_device <= AB8500_CODEC_SRC_D_MICROPHONE_2)
+ {
+ ab8500_codec_error =
+ ab8500_codec_SrcPowerControlSwitch1(src_device, state);
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else if (src_device <= AB8500_CODEC_SRC_ALL)
+ {
+ ab8500_codec_error =
+ ab8500_codec_SrcPowerControlSwitch2(src_device, state);
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else
+ {
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR5();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR6();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR7();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR63();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DestPowerControl */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enables/Disables & UnMute/Mute the desired destination */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* t_ab8500_codec_dest: select destination device for enabling/disabling. */
+/* t_ab8500_codec_dest_state: Enable/Disable */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_TRANSACTION_FAILED: If transaction fails. */
+/* AB8500_CODEC_OK: if successful. */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DestPowerControl(IN
+ t_ab8500_codec_dest
+ dest_device,
+ t_ab8500_codec_dest_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context.ab8500_codec_configuration;
+ DBGENTER2(" (%lx %lx)", dest_device, state);
+ switch (dest_device)
+ {
+ case AB8500_CODEC_DEST_HEADSET:
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachsl =
+ AB8500_CODEC_CR9_ENDACHSL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachsr =
+ AB8500_CODEC_CR9_ENDACHSR_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachsl =
+ AB8500_CODEC_CR9_ENDACHSL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachsr =
+ AB8500_CODEC_CR9_ENDACHSR_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_DEST_EARPIECE:
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_DISABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ }
+ break;
+ case AB8500_CODEC_DEST_HANDSFREE:
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLGPOL;
+ }
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRGPOL;
+ }
+ break;
+ case AB8500_CODEC_DEST_ALL:
+ if (AB8500_CODEC_DEST_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLGPOL;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_DA_PATH;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRGPOL;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRGPOL;
+ }
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_DestPowerControlUpdateCR();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_GetVersion */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* This routine populates the pVersion structure with */
+/* the current version of HCL. */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* p_version: this parameter is used to return current HCL version. */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_ERROR: if p_version is NULL. */
+/* AB8500_CODEC_OK: if successful */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_GetVersion(OUT t_version * p_version)
+{
+ DBGENTER1(" (%lx)", p_version);
+ if (p_version != NULL)
+ {
+ p_version->minor = AB8500_CODEC_HCL_MINOR_ID;
+ p_version->major = AB8500_CODEC_HCL_MAJOR_ID;
+ p_version->version = AB8500_CODEC_HCL_VERSION_ID;
+ DBGEXIT0(AB8500_CODEC_OK);
+ return (AB8500_CODEC_OK);
+ }
+
+ else
+ {
+ DBGEXIT0(AB8500_CODEC_INVALID_PARAMETER);
+ return (AB8500_CODEC_INVALID_PARAMETER);
+ }
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_SetDbgLevel */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Set the debug level used by the debug module (mask-like value). */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* debug_level: debug level to be set */
+/* OUT: */
+/* None */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_OK: always */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+/*
+PUBLIC t_ab8500_codec_error AB8500_CODEC_SetDbgLevel(IN t_dbg_level dbg_level)
+{
+ DBGENTER1(" (%d)", dbg_level);
+ dbg_level = dbg_level;
+#ifdef __DEBUG
+ MY_DEBUG_LEVEL_VAR_NAME = dbg_level;
+#endif
+ DBGEXIT(AB8500_CODEC_OK);
+ return(AB8500_CODEC_OK);
+}
+ */
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_GetDbgLevel */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Set the debug level used by the debug module (mask-like value). */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* p_dbg_level: this parameter is used to return debug level. */
+/* */
+/* RETURN: */
+/* AB8500_CODEC_ERROR: if p_version is NULL. */
+/* AB8500_CODEC_OK: if successful */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Re-Entrant */
+/* REENTRANCY ISSUES: No Issues */
+
+/****************************************************************************/
+/*
+PUBLIC t_ab8500_codec_error AB8500_CODEC_GetDbgLevel(OUT t_dbg_level *p_dbg_level)
+{
+ if (NULL == p_dbg_level)
+ {
+ DBGEXIT(AB8500_CODEC_INVALID_PARAMETER);
+ return(AB8500_CODEC_INVALID_PARAMETER);
+ }
+
+#ifdef __DEBUG
+ * p_dbg_level = MY_DEBUG_LEVEL_VAR_NAME;
+#endif
+ DBGEXIT(AB8500_CODEC_OK);
+ return(AB8500_CODEC_OK);
+}
+*/
+/****************************************************************************/
+/* NAME: AB8500_CODEC_ADSlotAllocation */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* AD Data Allocation in slots. */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_slot: The slot to be allocated. */
+/* IN: t_ab8500_codec_cr31_to_cr46_ad_data_allocation: The value */
+/* to be allocated. */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If invalid slot number */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_ADSlotAllocation
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER2(" (%lx %lx)", ad_slot, value);
+ if (ad_slot <= AB8500_CODEC_SLOT7)
+ {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch1(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else if (ad_slot <= AB8500_CODEC_SLOT15)
+ {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch2(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else if (ad_slot <= AB8500_CODEC_SLOT23)
+ {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch3(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else if (ad_slot <= AB8500_CODEC_SLOT31)
+ {
+ ab8500_codec_error =
+ ab8500_codec_ADSlotAllocationSwitch4(ad_slot, value);
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else
+ {
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DASlotAllocation */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Allocate the Audio Interface slot for DA paths. */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_da_channel_number: Channel number 1/2/3/4/5/6 */
+/* IN: t_ab8500_codec_cr51_to_cr56_sltoda: Slot number */
+/* */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If invalid channel number */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DASlotAllocation
+ (IN t_ab8500_codec_da_channel_number channel_number,
+ IN t_ab8500_codec_cr51_to_cr58_sltoda slot ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ t_ab8500_codec_cr0_powerup ab8500_codec_cr0_powerup;
+ DBGENTER2(" (%lx %lx)", channel_number, slot);
+ p_ab8500_codec_configuration->cr51_da12_voice =
+ AB8500_CODEC_CR51_DA12_VOICE_LOWLATENCYFILTER;
+ switch (channel_number)
+ {
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_1:
+ p_ab8500_codec_configuration->cr51_sltoda1 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_2:
+ p_ab8500_codec_configuration->cr52_sltoda2 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_3:
+ p_ab8500_codec_configuration->cr53_sltoda3 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_4:
+ p_ab8500_codec_configuration->cr54_sltoda4 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_5:
+ p_ab8500_codec_configuration->cr55_sltoda5 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_6:
+ p_ab8500_codec_configuration->cr56_sltoda6 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_7:
+ p_ab8500_codec_configuration->cr57_sltoda7 = slot;
+ break;
+ case AB8500_CODEC_DA_CHANNEL_NUMBER_8:
+ p_ab8500_codec_configuration->cr58_sltoda8 = slot;
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_cr0_powerup = p_ab8500_codec_configuration->cr0_powerup;
+ p_ab8500_codec_configuration->cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_OFF;
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR51();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR52();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR53();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR54();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR55();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR56();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR57();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR58();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ p_ab8500_codec_configuration->cr0_powerup = ab8500_codec_cr0_powerup;
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_ConfigureBurstFifo */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Configuration for Burst FIFO control */
+/* */
+/* ARGUMENTS */
+/* IN: t_ab8500_codec_burst_fifo_config: structure for configuration of */
+/* burst FIFO */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_INVALID_PARAMETER: If invalid parameter */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: If interface 1 selected */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+t_ab8500_codec_error AB8500_CODEC_ConfigureBurstFifo(IN
+ t_ab8500_codec_burst_fifo_config
+ const *const
+ p_burst_fifo_config)
+{
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER1(" (%lx)", p_burst_fifo_config);
+ if (AB8500_CODEC_AUDIO_INTERFACE_0 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ if (AB8500_CODEC_CR27_EN_MASTGEN_ENABLED ==
+ p_ab8500_codec_configuration->cr27_en_mastgen)
+ {
+ p_ab8500_codec_configuration->cr105_bfifomsk =
+ p_burst_fifo_config->cr105_bfifomsk;
+ p_ab8500_codec_configuration->cr105_bfifoint =
+ p_burst_fifo_config->cr105_bfifoint;
+ p_ab8500_codec_configuration->cr106_bfifotx =
+ p_burst_fifo_config->cr106_bfifotx;
+ p_ab8500_codec_configuration->cr107_bfifoexsl =
+ p_burst_fifo_config->cr107_bfifoexsl;
+ p_ab8500_codec_configuration->cr107_bfifomast =
+ p_burst_fifo_config->cr107_bfifomast;
+ p_ab8500_codec_configuration->cr107_bfiforun =
+ p_burst_fifo_config->cr107_bfiforun;
+ p_ab8500_codec_configuration->cr108_bfifoframsw =
+ p_burst_fifo_config->cr108_bfifoframsw;
+ p_ab8500_codec_configuration->cr109_bfifowakeup =
+ p_burst_fifo_config->cr109_bfifowakeup;
+ ab8500_codec_error = ab8500_codec_UpdateCR105();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR106();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR107();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR108();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR109();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else
+ {
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else
+ {
+ ab8500_codec_error = AB8500_CODEC_UNSUPPORTED_FEATURE;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_EnableBurstFifo */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Enable the Burst FIFO for Interface 0 */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: If Interface 1 is selected */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_EnableBurstFifo(void)
+{
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+ if (AB8500_CODEC_AUDIO_INTERFACE_0 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ p_ab8500_codec_configuration->cr29_if0bfifoen =
+ AB8500_CODEC_CR29_IF0BFIFOEN_BURST_MODE;
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else
+ {
+ ab8500_codec_error = AB8500_CODEC_UNSUPPORTED_FEATURE;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+/****************************************************************************/
+/* NAME: AB8500_CODEC_DisableBurstFifo */
+/*--------------------------------------------------------------------------*/
+/* DESCRIPTION: */
+/* Disable the Burst FIFO for Interface 0 */
+/* */
+/* ARGUMENTS */
+/* IN: */
+/* None */
+/* OUT: */
+/* None */
+/* RETURN: */
+/* AB8500_CODEC_UNSUPPORTED_FEATURE: If Interface 1 is selected */
+/* AB8500_CODEC_OK: if successful. */
+/* REMARK: */
+/*--------------------------------------------------------------------------*/
+/* REENTRANCY: Non Re-Entrant */
+
+/****************************************************************************/
+PUBLIC t_ab8500_codec_error AB8500_CODEC_DisableBurstFifo(void)
+{
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ DBGENTER0();
+ if (AB8500_CODEC_AUDIO_INTERFACE_0 ==
+ g_ab8500_codec_system_context.audio_interface)
+ {
+ p_ab8500_codec_configuration->cr29_if0bfifoen =
+ AB8500_CODEC_CR29_IF0BFIFOEN_NORMAL_MODE;
+ ab8500_codec_error = ab8500_codec_UpdateCR29();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ }
+
+ else
+ {
+ ab8500_codec_error = AB8500_CODEC_UNSUPPORTED_FEATURE;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch1
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (ad_slot)
+ {
+ case AB8500_CODEC_SLOT0:
+ p_ab8500_codec_configuration->cr31_adotoslot0 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR31();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT1:
+ p_ab8500_codec_configuration->cr31_adotoslot1 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR31();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT2:
+ p_ab8500_codec_configuration->cr32_adotoslot2 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR32();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT3:
+ p_ab8500_codec_configuration->cr32_adotoslot3 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR32();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT4:
+ p_ab8500_codec_configuration->cr33_adotoslot4 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR33();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT5:
+ p_ab8500_codec_configuration->cr33_adotoslot5 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR33();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT6:
+ p_ab8500_codec_configuration->cr34_adotoslot6 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR34();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT7:
+ p_ab8500_codec_configuration->cr34_adotoslot7 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR34();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch2
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (ad_slot)
+ {
+ case AB8500_CODEC_SLOT8:
+ p_ab8500_codec_configuration->cr35_adotoslot8 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR35();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT9:
+ p_ab8500_codec_configuration->cr35_adotoslot9 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR35();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT10:
+ p_ab8500_codec_configuration->cr36_adotoslot10 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR36();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT11:
+ p_ab8500_codec_configuration->cr36_adotoslot11 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR36();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT12:
+ p_ab8500_codec_configuration->cr37_adotoslot12 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR37();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT13:
+ p_ab8500_codec_configuration->cr37_adotoslot13 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR37();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT14:
+ p_ab8500_codec_configuration->cr38_adotoslot14 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR38();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT15:
+ p_ab8500_codec_configuration->cr38_adotoslot15 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR38();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch3
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (ad_slot)
+ {
+ case AB8500_CODEC_SLOT16:
+ p_ab8500_codec_configuration->cr39_adotoslot16 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR39();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT17:
+ p_ab8500_codec_configuration->cr39_adotoslot17 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR39();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT18:
+ p_ab8500_codec_configuration->cr40_adotoslot18 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR40();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT19:
+ p_ab8500_codec_configuration->cr40_adotoslot19 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR40();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT20:
+ p_ab8500_codec_configuration->cr41_adotoslot20 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR41();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT21:
+ p_ab8500_codec_configuration->cr41_adotoslot21 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR41();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT22:
+ p_ab8500_codec_configuration->cr42_adotoslot22 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR42();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT23:
+ p_ab8500_codec_configuration->cr42_adotoslot23 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR42();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ADSlotAllocationSwitch4
+ (IN t_ab8500_codec_slot ad_slot,
+ IN t_ab8500_codec_cr31_to_cr46_ad_data_allocation value ) {
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (ad_slot)
+ {
+ case AB8500_CODEC_SLOT24:
+ p_ab8500_codec_configuration->cr43_adotoslot24 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR43();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT25:
+ p_ab8500_codec_configuration->cr43_adotoslot25 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR43();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT26:
+ p_ab8500_codec_configuration->cr44_adotoslot26 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR44();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT27:
+ p_ab8500_codec_configuration->cr44_adotoslot27 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR44();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT28:
+ p_ab8500_codec_configuration->cr45_adotoslot28 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR45();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT29:
+ p_ab8500_codec_configuration->cr45_adotoslot29 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR45();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT30:
+ p_ab8500_codec_configuration->cr46_adotoslot30 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR46();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ case AB8500_CODEC_SLOT31:
+ p_ab8500_codec_configuration->cr46_adotoslot31 = value;
+ ab8500_codec_error = ab8500_codec_UpdateCR46();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch1(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (src_device)
+ {
+ case AB8500_CODEC_SRC_LINEIN:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_LINR;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_MIC2;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1A;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1B;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_MIC2;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_LINR;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr63_ad1sel =
+ AB8500_CODEC_CR63_AD1SEL_DMIC1_SELECTED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad1sel =
+ AB8500_CODEC_CR63_AD1SEL_LINLADL_SELECTED;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr63_ad2sel =
+ AB8500_CODEC_CR63_AD2SEL_DMIC2_SELECTED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad2sel =
+ AB8500_CODEC_CR63_AD2SEL_LINRADR_SELECTED;
+ }
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SrcPowerControlSwitch2(IN
+ t_ab8500_codec_src
+ src_device,
+ t_ab8500_codec_src_state
+ state)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (src_device)
+ {
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr63_ad3sel =
+ AB8500_CODEC_CR63_AD3SEL_DMIC3_SELECTED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad3sel =
+ AB8500_CODEC_CR63_AD3SEL_ADMO_SELECTED;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr63_ad5sel =
+ AB8500_CODEC_CR63_AD5SEL_DMIC5_SELECTED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad5sel =
+ AB8500_CODEC_CR63_AD5SEL_AMADR_SELECTED;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr63_ad6sel =
+ AB8500_CODEC_CR63_AD6SEL_DMIC6_SELECTED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad6sel =
+ AB8500_CODEC_CR63_AD6SEL_ADMO_SELECTED;
+ }
+ break;
+ case AB8500_CODEC_SRC_ALL:
+ if (AB8500_CODEC_SRC_STATE_ENABLE == state)
+ {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+ }
+
+ else
+ {
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ }
+ break;
+ case AB8500_CODEC_SRC_FM_RX:
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetModeAndDirectionUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ t_ab8500_codec_cr0_powerup ab8500_codec_cr0_powerup;
+ ab8500_codec_cr0_powerup = p_ab8500_codec_configuration->cr0_powerup;
+ p_ab8500_codec_configuration->cr0_powerup =
+ AB8500_CODEC_CR0_POWERUP_OFF;
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ if (AB8500_CODEC_OK != ab8500_codec_error)
+ {
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR2();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR3();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR26();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR27();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR28();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR30();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR63();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ p_ab8500_codec_configuration->cr0_powerup = ab8500_codec_cr0_powerup;
+ ab8500_codec_error = ab8500_codec_UpdateCR0();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetSrcVolumeUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ ab8500_codec_error = ab8500_codec_UpdateCR20();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR21();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR23();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR65();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR66();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR67();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR68();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR69();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR70();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_SetDestVolumeUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ ab8500_codec_error = ab8500_codec_UpdateCR16();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR17();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR18();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR19();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR22();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR71();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR72();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR73();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR74();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR75();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR76();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR79();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR80();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionIN(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (g_ab8500_codec_system_context.ab8500_codec_src)
+ {
+ case AB8500_CODEC_SRC_LINEIN:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_LINR;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1A;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_mic1sel =
+ AB8500_CODEC_CR7_MIC1SEL_MIC1B;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_linrsel =
+ AB8500_CODEC_CR7_LINRSEL_MIC2;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad1sel =
+ AB8500_CODEC_CR63_AD1SEL_DMIC1_SELECTED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad2sel =
+ AB8500_CODEC_CR63_AD2SEL_DMIC2_SELECTED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad3sel =
+ AB8500_CODEC_CR63_AD3SEL_DMIC3_SELECTED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad5sel =
+ AB8500_CODEC_CR63_AD5SEL_DMIC5_SELECTED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_DISABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_DISABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_DISABLED;
+ p_ab8500_codec_configuration->cr63_ad6sel =
+ AB8500_CODEC_CR63_AD6SEL_DMIC6_SELECTED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_ENABLED;
+ break;
+ case AB8500_CODEC_SRC_ALL:
+ p_ab8500_codec_configuration->cr5_enlinl =
+ AB8500_CODEC_CR5_ENLINL_ENABLED;
+ p_ab8500_codec_configuration->cr5_enlinr =
+ AB8500_CODEC_CR5_ENLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic1 =
+ AB8500_CODEC_CR5_ENMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr5_enmic2 =
+ AB8500_CODEC_CR5_ENMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic1 =
+ AB8500_CODEC_CR6_ENDMIC1_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic2 =
+ AB8500_CODEC_CR6_ENDMIC2_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic3 =
+ AB8500_CODEC_CR6_ENDMIC3_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic4 =
+ AB8500_CODEC_CR6_ENDMIC4_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic5 =
+ AB8500_CODEC_CR6_ENDMIC5_ENABLED;
+ p_ab8500_codec_configuration->cr6_endmic6 =
+ AB8500_CODEC_CR6_ENDMIC6_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadcmic =
+ AB8500_CODEC_CR7_ENADCMIC_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinl =
+ AB8500_CODEC_CR7_ENADCLINL_ENABLED;
+ p_ab8500_codec_configuration->cr7_enadclinr =
+ AB8500_CODEC_CR7_ENADCLINR_ENABLED;
+ p_ab8500_codec_configuration->cr5_mutlinl =
+ AB8500_CODEC_CR5_MUTLINL_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutlinr =
+ AB8500_CODEC_CR5_MUTLINR_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic1 =
+ AB8500_CODEC_CR5_MUTMIC1_DISABLED;
+ p_ab8500_codec_configuration->cr5_mutmic2 =
+ AB8500_CODEC_CR5_MUTMIC2_DISABLED;
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_12:
+ case AB8500_CODEC_SRC_D_MICROPHONE_34:
+ case AB8500_CODEC_SRC_D_MICROPHONE_56:
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_ProgramDirectionOUT(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ t_ab8500_codec_configuration * p_ab8500_codec_configuration =
+ &g_ab8500_codec_system_context. ab8500_codec_configuration;
+ switch (g_ab8500_codec_system_context.ab8500_codec_dest)
+ {
+ case AB8500_CODEC_DEST_HEADSET:
+ p_ab8500_codec_configuration->cr7_endrvhsl =
+ AB8500_CODEC_CR7_ENDRVHSL_ENABLED;
+ p_ab8500_codec_configuration->cr7_endrvhsr =
+ AB8500_CODEC_CR7_ENDRVHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachsl =
+ AB8500_CODEC_CR9_ENDACHSL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachsr =
+ AB8500_CODEC_CR9_ENDACHSR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr12_encphs =
+ AB8500_CODEC_CR12_ENCPHS_ENABLED;
+ break;
+ case AB8500_CODEC_DEST_EARPIECE:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ break;
+ case AB8500_CODEC_DEST_HANDSFREE:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_DISABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_DISABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_DISABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_ENABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+ break;
+ case AB8500_CODEC_DEST_ALL:
+ p_ab8500_codec_configuration->cr8_enhsl =
+ AB8500_CODEC_CR8_ENHSL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhsr =
+ AB8500_CODEC_CR8_ENHSR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enear =
+ AB8500_CODEC_CR8_ENEAR_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfl =
+ AB8500_CODEC_CR8_ENHFL_ENABLED;
+ p_ab8500_codec_configuration->cr8_enhfr =
+ AB8500_CODEC_CR8_ENHFR_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibl =
+ AB8500_CODEC_CR8_ENVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr8_envibr =
+ AB8500_CODEC_CR8_ENVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacear =
+ AB8500_CODEC_CR9_ENDACEAR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfl =
+ AB8500_CODEC_CR9_ENDACHFL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endachfr =
+ AB8500_CODEC_CR9_ENDACHFR_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibl =
+ AB8500_CODEC_CR9_ENDACVIBL_ENABLED;
+ p_ab8500_codec_configuration->cr9_endacvibr =
+ AB8500_CODEC_CR9_ENDACVIBR_ENABLED;
+ p_ab8500_codec_configuration->cr10_mutehsl =
+ AB8500_CODEC_CR10_MUTEHSL_DISABLED;
+ p_ab8500_codec_configuration->cr10_mutehsr =
+ AB8500_CODEC_CR10_MUTEHSR_DISABLED;
+ p_ab8500_codec_configuration->cr10_muteear =
+ AB8500_CODEC_CR10_MUTEEAR_DISABLED;
+ p_ab8500_codec_configuration->cr15_pwmtovibl =
+ AB8500_CODEC_CR15_PWMTOVIBL_PWM;
+ p_ab8500_codec_configuration->cr15_pwmlctrl =
+ AB8500_CODEC_CR15_PWMLCTRL_PWMNPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnlctrl =
+ AB8500_CODEC_CR15_PWMNLCTRL_PWMNLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmplctrl =
+ AB8500_CODEC_CR15_PWMPLCTRL_PWMPLDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmtovibr =
+ AB8500_CODEC_CR15_PWMTOVIBR_PWM;
+ p_ab8500_codec_configuration->cr15_pwmrctrl =
+ AB8500_CODEC_CR15_PWMRCTRL_PWMNPRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmnrctrl =
+ AB8500_CODEC_CR15_PWMNRCTRL_PWMNRDUTYCYCLE;
+ p_ab8500_codec_configuration->cr15_pwmprctrl =
+ AB8500_CODEC_CR15_PWMPRCTRL_PWMPRDUTYCYCLE;
+ break;
+ default:
+ ab8500_codec_error = AB8500_CODEC_INVALID_PARAMETER;
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
+
+PRIVATE t_ab8500_codec_error ab8500_codec_DestPowerControlUpdateCR(void)
+{
+ t_ab8500_codec_error ab8500_codec_error = AB8500_CODEC_OK;
+ ab8500_codec_error = ab8500_codec_UpdateCR8();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR9();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR10();
+ if (ab8500_codec_error != AB8500_CODEC_OK)
+ {
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+ }
+ ab8500_codec_error = ab8500_codec_UpdateCR15();
+ DBGEXIT(ab8500_codec_error);
+ return (ab8500_codec_error);
+}
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 885683a3b0b..86cd48bfd8d 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -39,5 +39,17 @@ config SND_PXA2XX_AC97
Say Y or M if you want to support any AC97 codec attached to
the PXA2xx AC97 interface.
+config SND_U8500_ALSA_AB8500
+ tristate "U8500 alsa support for AB8500"
+ depends on SND && STE_DMA40 && U8500_ACODEC && (U8500_AB8500_ED || U8500_AB8500_CUT10)
+ default y
+ select SND_PCM
+ help
+ Say Y here if you have a u8500 based device
+ and want to use alsa for pcm playback and capture.
+
+ To compile this driver as a module, choose M here: the module
+ will be called u8500mod_alsa.
+
endif # SND_ARM
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
index 8c0c851d464..e41f1f4db14 100644
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -14,3 +14,7 @@ snd-pxa2xx-lib-$(CONFIG_SND_PXA2XX_LIB_AC97) += pxa2xx-ac97-lib.o
obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o
snd-pxa2xx-ac97-objs := pxa2xx-ac97.o
+obj-$(CONFIG_SND_U8500_ALSA_AB8500) += u8500mod_alsa.o
+ifneq ($(CONFIG_SND_U8500_ALSA_AB8500),n)
+u8500mod_alsa-objs := u8500_alsa_ab8500.o u8500_alsa_hdmi.o
+endif
diff --git a/sound/arm/u8500_alsa_ab8500.c b/sound/arm/u8500_alsa_ab8500.c
new file mode 100644
index 00000000000..39752388ab1
--- /dev/null
+++ b/sound/arm/u8500_alsa_ab8500.c
@@ -0,0 +1,2691 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Deepak Karda
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2.1 as published
+ * by the Free Software Foundation.
+ */
+
+/* This include must be defined at this point */
+//#include <sound/driver.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <mach/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* alsa system */
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include "u8500_alsa_ab8500.h"
+#include <mach/msp.h>
+#include <mach/debug.h>
+
+#define ALSA_NAME "DRIVER ALSA"
+
+#define DRIVER_DEBUG CONFIG_STM_ALSA_DEBUG /* enables/disables debug msgs */
+#define DRIVER_DEBUG_PFX ALSA_NAME /* msg header represents this module */
+#define DRIVER_DBG KERN_ERR /* message level */
+
+static struct platform_device *device;
+static int active_user = 0;
+
+/*
+** Externel references
+*/
+#if DRIVER_DEBUG > 0
+t_ab8500_codec_error dump_acodec_registers(void);
+t_ab8500_codec_error dump_msp_registers(void);
+#endif
+
+extern int u8500_acodec_rates[MAX_NO_OF_RATES];
+extern char *lpbk_state_in_texts[NUMBER_LOOPBACK_STATE];
+extern char *switch_state_in_texts[NUMBER_SWITCH_STATE];
+extern char *power_state_in_texts[NUMBER_POWER_STATE];
+extern char *tdm_mode_state_in_texts[NUMBER_TDM_MODE_STATE];
+extern char *direct_rendering_state_in_texts[NUMBER_DIRECT_RENDERING_STATE];
+extern char *pcm_rendering_state_in_texts[NUMBER_PCM_RENDERING_STATE];
+extern char *codec_dest_texts[NUMBER_OUTPUT_DEVICE];
+extern char *codec_in_texts[NUMBER_INPUT_DEVICE];
+extern struct driver_debug_st DBG_ST;
+extern int second_config;
+extern int u8500_register_alsa_hdmi_controls(struct snd_card *card,
+ u8500_acodec_chip_t * u8500_chip);
+extern int snd_card_u8500_alsa_hdmi_new(u8500_acodec_chip_t * chip, int device);
+/*
+** Declaration for local functions
+*/
+static int u8500_analog_lpbk_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_analog_lpbk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_analog_lpbk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_digital_lpbk_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_digital_lpbk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_digital_lpbk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_playback_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_playback_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_playback_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_capture_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_capture_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_capture_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_playback_sink_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_playback_sink_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_playback_sink_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_capture_src_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_capture_src_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_capture_src_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_playback_switch_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_playback_switch_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_playback_switch_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_capture_switch_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_capture_switch_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_capture_switch_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_playback_power_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_playback_power_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_playback_power_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_capture_power_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_capture_power_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_capture_power_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_tdm_mode_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_tdm_mode_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_tdm_mode_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+static int u8500_direct_rendering_mode_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
+ *uinfo);
+static int u8500_direct_rendering_mode_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
+ *uinfo);
+static int u8500_direct_rendering_mode_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
+ *uinfo);
+static int u8500_register_alsa_controls(struct snd_card *card,
+ u8500_acodec_chip_t * u8500_chip);
+
+static int u8500_pcm_rendering_mode_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_pcm_rendering_mode_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_pcm_rendering_mode_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+#if 0 /* DUMP REGISTER CONTROL */
+static int u8500_dump_register_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_dump_register_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_dump_register_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+#endif /* DUMP REGISTER CONTROL */
+
+static int configure_rate(struct snd_pcm_substream *,
+ t_u8500_acodec_config_need acodec_config_need);
+static void dma_eot_handler(void *data);
+/**
+* configure_rate
+* @substream - pointer to the playback/capture substream structure
+*
+* This functions configures audio codec in to stream frequency frequency
+*/
+
+static int configure_rate(struct snd_pcm_substream *substream,
+ t_u8500_acodec_config_need acodec_config_need)
+{
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ t_codec_sample_frequency sampling_frequency = 0;
+ t_ab8500_codec_direction direction = 0;
+ struct acodec_configuration acodec_config;
+ int stream_id = substream->pstr->stream;
+
+ FUNC_ENTER();
+ switch (chip->freq) {
+ case 48000:
+ sampling_frequency = CODEC_SAMPLING_FREQ_48KHZ;
+ break;
+ default:
+ printk("not supported frequnecy \n");
+ stm_error("not supported frequnecy \n");
+ return -EINVAL;
+ }
+
+ switch (stream_id) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ direction = AB8500_CODEC_DIRECTION_OUT;
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ direction = AB8500_CODEC_DIRECTION_IN;
+ break;
+ default:
+ stm_error(": wrong pcm stream\n");
+ return -EINVAL;
+ }
+
+ stm_dbg(DBG_ST.alsa, "enabling audiocodec audio mode\n");
+ acodec_config.direction = direction;
+ acodec_config.input_frequency = T_CODEC_SAMPLING_FREQ_48KHZ;
+ acodec_config.output_frequency = T_CODEC_SAMPLING_FREQ_48KHZ;
+ acodec_config.mspClockSel = CODEC_MSP_APB_CLOCK;
+ acodec_config.mspInClockFreq = CODEC_MSP_INPUT_FREQ_48MHZ;
+ acodec_config.channels = chip->channels;
+ acodec_config.user = 2;
+ acodec_config.acodec_config_need = acodec_config_need;
+ acodec_config.handler = dma_eot_handler;
+ acodec_config.tx_callback_data =
+ &chip->stream[ALSA_PCM_DEV][SNDRV_PCM_STREAM_PLAYBACK];
+ acodec_config.rx_callback_data =
+ &chip->stream[ALSA_PCM_DEV][SNDRV_PCM_STREAM_CAPTURE];
+ acodec_config.direct_rendering_mode = chip->direct_rendering_mode;
+ acodec_config.tdm8_ch_mode = chip->tdm8_ch_mode;
+ acodec_config.digital_loopback = DISABLE;
+ u8500_acodec_enable_audio_mode(&acodec_config);
+ FUNC_EXIT();
+
+ return 0;
+}
+
+/*
+****************************************************************************************
+* playback vol control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_playback_vol_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 0,
+ .name = "PCM Playback Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_playback_vol_info,
+ .get = u8500_playback_vol_get,
+ .put = u8500_playback_vol_put
+};
+
+/**
+* u8500_playback_vol_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback volume info into user structure.
+*/
+
+static int u8500_playback_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 100;
+ uinfo->value.integer.step = 10;
+ return 0;
+}
+
+/**
+* u8500_playback_vol_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills the current volume setting to user structure.
+*/
+
+static int u8500_playback_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+
+ int *p_left_volume = NULL;
+ int *p_right_volume = NULL;
+
+ p_left_volume = (int *)&uinfo->value.integer.value[0];
+ p_right_volume = (int *)&uinfo->value.integer.value[1];
+
+ u8500_acodec_get_output_volume(chip->output_device, p_left_volume,
+ p_right_volume, USER_ALSA);
+ return 0;
+}
+
+/**
+* u8500_playback_vol_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure.
+*
+* This functions sets the playback audio codec volume .
+*/
+
+static int u8500_playback_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0, error = 0;
+
+ if (chip->output_lvolume != uinfo->value.integer.value[0]
+ || chip->output_rvolume != uinfo->value.integer.value[1]) {
+ chip->output_lvolume = uinfo->value.integer.value[0];
+ chip->output_rvolume = uinfo->value.integer.value[1];
+
+ if (chip->output_lvolume > 100)
+ chip->output_lvolume = 100;
+ else if (chip->output_lvolume < 0)
+ chip->output_lvolume = 0;
+
+ if (chip->output_rvolume > 100)
+ chip->output_rvolume = 100;
+ else if (chip->output_rvolume < 0)
+ chip->output_rvolume = 0;
+
+ error =
+ u8500_acodec_set_output_volume(chip->output_device,
+ chip->output_lvolume,
+ chip->output_rvolume,
+ USER_ALSA);
+
+ if (error) {
+ stm_error
+ (" : set volume for speaker/headphone failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+
+ return changed;
+}
+
+/*
+****************************************************************************************
+* capture vol control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_capture_vol_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 1,
+ .name = "PCM Capture Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_capture_vol_info,
+ .get = u8500_capture_vol_get,
+ .put = u8500_capture_vol_put
+};
+
+/**
+* u8500_capture_vol_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills capture volume info into user structure.
+*/
+static int u8500_capture_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 100;
+ uinfo->value.integer.step = 10;
+ return 0;
+}
+
+/**
+* u8500_capture_vol_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current capture volume setting to user structure.
+*/
+
+static int u8500_capture_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+
+ int *p_left_volume = NULL;
+ int *p_right_volume = NULL;
+
+ p_left_volume = (int *)&uinfo->value.integer.value[0];
+ p_right_volume = (int *)&uinfo->value.integer.value[1];
+
+ u8500_acodec_get_input_volume(chip->input_device, p_left_volume,
+ p_right_volume, USER_ALSA);
+ return 0;
+}
+
+/**
+* u8500_capture_vol_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure.
+*
+* This functions sets the capture audio codec volume with values provided.
+*/
+
+static int u8500_capture_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0, error = 0;
+
+ if (chip->input_lvolume != uinfo->value.integer.value[0]
+ || chip->input_rvolume != uinfo->value.integer.value[1]) {
+ chip->input_lvolume = uinfo->value.integer.value[0];
+ chip->input_rvolume = uinfo->value.integer.value[1];
+
+ if (chip->input_lvolume > 100)
+ chip->input_lvolume = 100;
+ else if (chip->input_lvolume < 0)
+ chip->input_lvolume = 0;
+
+ if (chip->input_rvolume > 100)
+ chip->input_rvolume = 100;
+ else if (chip->input_rvolume < 0)
+ chip->input_rvolume = 0;
+
+ error = u8500_acodec_set_input_volume(chip->input_device,
+ chip->input_rvolume,
+ chip->input_lvolume,
+ USER_ALSA);
+ if (error) {
+ stm_error(" : set input volume failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+
+ return changed;
+}
+
+/*
+****************************************************************************************
+* playback sink control *
+****************************************************************************************
+*/
+
+static struct snd_kcontrol_new u8500_playback_sink_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 0,
+ .name = "PCM Playback Sink",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xffff,
+ .info = u8500_playback_sink_info,
+ .get = u8500_playback_sink_get,
+ .put = u8500_playback_sink_put
+};
+
+/**
+* u8500_playback_sink_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_playback_sink_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_OUTPUT_DEVICE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_OUTPUT_DEVICE)
+ uinfo->value.enumerated.item = NUMBER_OUTPUT_DEVICE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ codec_dest_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_playback_sink_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_playback_sink_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->output_device;
+ return 0;
+}
+
+/**
+* u8500_playback_sink_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_playback_sink_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0, error;
+
+ if (chip->output_device != uinfo->value.enumerated.item[0]) {
+ chip->output_device = uinfo->value.enumerated.item[0];
+ error =
+ u8500_acodec_select_output(chip->output_device,
+ USER_ALSA, chip->tdm8_ch_mode);
+ if (error) {
+ stm_error(" : select output failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* capture src control *
+****************************************************************************************
+*/
+
+static struct snd_kcontrol_new u8500_capture_src_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 1,
+ .name = "PCM Capture Source",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xffff,
+ .info = u8500_capture_src_ctrl_info,
+ .get = u8500_capture_src_ctrl_get,
+ .put = u8500_capture_src_ctrl_put
+};
+
+/**
+* u8500_capture_src_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills capture device info into user structure.
+*/
+static int u8500_capture_src_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_INPUT_DEVICE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_INPUT_DEVICE)
+ uinfo->value.enumerated.item = NUMBER_INPUT_DEVICE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ codec_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_capture_src_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current capture device selected.
+*/
+static int u8500_capture_src_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->input_device;
+ return 0;
+}
+
+/**
+* u8500_capture_src_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure,
+*
+* This functions sets the capture device.
+*/
+static int u8500_capture_src_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0, error;
+
+ if (chip->input_device != uinfo->value.enumerated.item[0]) {
+ chip->input_device = uinfo->value.enumerated.item[0];
+ error =
+ u8500_acodec_select_input(chip->input_device, USER_ALSA,
+ chip->tdm8_ch_mode);
+ if (error) {
+ stm_error(" : select input failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+***************************************************************************************
+* analog lpbk control *
+***************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_analog_lpbk_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .name = "Analog Loopback",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_analog_lpbk_info,
+ .get = u8500_analog_lpbk_get,
+ .put = u8500_analog_lpbk_put
+};
+
+/**
+* u8500_analog_lpbk_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_analog_lpbk_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_LOOPBACK_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_LOOPBACK_STATE)
+ uinfo->value.enumerated.item = NUMBER_LOOPBACK_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ lpbk_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_analog_lpbk_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_analog_lpbk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->analog_lpbk;
+ return 0;
+}
+
+/**
+* u8500_analog_lpbk_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_analog_lpbk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ if (chip->analog_lpbk != uinfo->value.enumerated.item[0]) {
+ chip->analog_lpbk = uinfo->value.enumerated.item[0];
+
+ error =
+ u8500_acodec_toggle_analog_lpbk(chip->analog_lpbk,
+ USER_ALSA);
+
+ if (AB8500_CODEC_OK != error) {
+ stm_error
+ (" : select u8500_acodec_set_analog_lpbk_state failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* digital lpbk control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_digital_lpbk_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .name = "Digital Loopback",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_digital_lpbk_info,
+ .get = u8500_digital_lpbk_get,
+ .put = u8500_digital_lpbk_put
+};
+
+/**
+* u8500_digital_lpbk_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_digital_lpbk_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_LOOPBACK_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_LOOPBACK_STATE)
+ uinfo->value.enumerated.item = NUMBER_LOOPBACK_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ lpbk_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_digital_lpbk_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_digital_lpbk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->digital_lpbk;
+ return 0;
+}
+
+/**
+* u8500_analog_lpbk_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_digital_lpbk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ if (chip->digital_lpbk != uinfo->value.enumerated.item[0]) {
+ chip->digital_lpbk = uinfo->value.enumerated.item[0];
+
+ error = u8500_acodec_toggle_digital_lpbk(chip->digital_lpbk,
+ chip->output_device,
+ chip->input_device,
+ USER_ALSA,
+ chip->tdm8_ch_mode);
+
+ /*if((error = u8500_acodec_set_output_volume(chip->output_device,50,50,USER_ALSA)))
+ {
+ stm_error(" : set output volume failed\n");
+ return error;
+ }
+
+ if ((error = u8500_acodec_set_input_volume(chip->input_device,50,50,USER_ALSA)))
+ {
+ stm_error(" : set input volume failed\n");
+ return error;
+ } */
+
+ if (AB8500_CODEC_OK != error) {
+ stm_error
+ (" : select u8500_acodec_set_digital_lpbk_state failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* playback switch control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_playback_switch_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 0,
+ .name = "PCM Playback Mute",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_playback_switch_ctrl_info,
+ .get = u8500_playback_switch_ctrl_get,
+ .put = u8500_playback_switch_ctrl_put
+};
+
+/**
+* u8500_playback_switch_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_playback_switch_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_SWITCH_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_SWITCH_STATE)
+ uinfo->value.enumerated.item = NUMBER_SWITCH_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ switch_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_playback_switch_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_playback_switch_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->playback_switch;
+ return 0;
+}
+
+/**
+* u8500_playback_switch_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_playback_switch_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ if (chip->playback_switch != uinfo->value.enumerated.item[0]) {
+ chip->playback_switch = uinfo->value.enumerated.item[0];
+
+ error =
+ u8500_acodec_toggle_playback_mute_control(chip->
+ output_device,
+ chip->
+ playback_switch,
+ USER_ALSA);
+
+ if (AB8500_CODEC_OK != error) {
+ stm_error
+ (" : select u8500_playback_switch_ctrl_put failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* Capture switch control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_capture_switch_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 1,
+ .name = "PCM Capture Mute",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_capture_switch_ctrl_info,
+ .get = u8500_capture_switch_ctrl_get,
+ .put = u8500_capture_switch_ctrl_put
+};
+
+/**
+* u8500_capture_switch_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_capture_switch_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_SWITCH_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_SWITCH_STATE)
+ uinfo->value.enumerated.item = NUMBER_SWITCH_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ switch_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_capture_switch_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_capture_switch_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->capture_switch;
+ return 0;
+}
+
+/**
+* u8500_capture_switch_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_capture_switch_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ if (chip->capture_switch != uinfo->value.enumerated.item[0]) {
+ chip->capture_switch = uinfo->value.enumerated.item[0];
+
+ error =
+ u8500_acodec_toggle_capture_mute_control(chip->input_device,
+ chip->
+ capture_switch,
+ USER_ALSA);
+
+ if (AB8500_CODEC_OK != error) {
+ stm_error
+ (" : select u8500_capture_switch_ctrl_put failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* playback power control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_playback_power_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 0,
+ .name = "PCM Playback Power",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_playback_power_ctrl_info,
+ .get = u8500_playback_power_ctrl_get,
+ .put = u8500_playback_power_ctrl_put
+};
+
+/**
+* u8500_playback_power_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_playback_power_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_POWER_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_POWER_STATE)
+ uinfo->value.enumerated.item = NUMBER_POWER_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ power_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_playback_power_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_playback_power_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] =
+ u8500_acodec_get_dest_power_state(chip->output_device);
+ return 0;
+}
+
+/**
+* u8500_playback_power_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_playback_power_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+ t_u8500_bool_state power_state;
+
+ power_state = u8500_acodec_get_dest_power_state(chip->output_device);
+
+ if (power_state != uinfo->value.enumerated.item[0]) {
+ power_state = uinfo->value.enumerated.item[0];
+
+ error =
+ u8500_acodec_set_dest_power_cntrl(chip->output_device,
+ power_state);
+
+ if (AB8500_CODEC_OK != error) {
+ stm_error
+ (" : select u8500_acodec_set_dest_power_cntrl failed\n");
+ return changed;
+ }
+
+ /* configure the volume settings for the acodec */
+ if ((error =
+ u8500_acodec_set_output_volume(chip->output_device,
+ chip->output_lvolume,
+ chip->output_rvolume,
+ USER_ALSA))) {
+ stm_error(" : set output volume failed\n");
+ return error;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* capture power control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_capture_power_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 0,
+ .name = "PCM Capture Power",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_capture_power_ctrl_info,
+ .get = u8500_capture_power_ctrl_get,
+ .put = u8500_capture_power_ctrl_put
+};
+
+/**
+* u8500_capture_power_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_capture_power_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_POWER_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_POWER_STATE)
+ uinfo->value.enumerated.item = NUMBER_POWER_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ power_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_capture_power_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_capture_power_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] =
+ u8500_acodec_get_src_power_state(chip->input_device);
+ return 0;
+}
+
+/**
+* u8500_capture_power_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_capture_power_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+ t_u8500_bool_state power_state;
+
+ power_state = u8500_acodec_get_src_power_state(chip->input_device);
+
+ if (power_state != uinfo->value.enumerated.item[0]) {
+ power_state = uinfo->value.enumerated.item[0];
+
+ error =
+ u8500_acodec_set_src_power_cntrl(chip->input_device,
+ power_state);
+
+ if (AB8500_CODEC_OK != error) {
+ stm_error
+ (" : select u8500_acodec_set_src_power_cntrl failed\n");
+ return changed;
+ }
+ changed = 1;
+ }
+ return changed;
+}
+
+/*
+****************************************************************************************
+* TDM 8 channel mode control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_tdm_mode_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .subdevice = 0,
+ .name = "TDM 8 Channel Mode",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_tdm_mode_ctrl_info,
+ .get = u8500_tdm_mode_ctrl_get,
+ .put = u8500_tdm_mode_ctrl_put
+};
+
+/**
+* u8500_tdm_mode_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_tdm_mode_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_TDM_MODE_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_TDM_MODE_STATE)
+ uinfo->value.enumerated.item = NUMBER_TDM_MODE_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ tdm_mode_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_tdm_mode_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_tdm_mode_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->tdm8_ch_mode;
+ return 0;
+}
+
+/**
+* u8500_tdm_mode_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_tdm_mode_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ chip->tdm8_ch_mode = uinfo->value.enumerated.item[0];
+
+ if (ENABLE == chip->tdm8_ch_mode)
+ printk("\n TDM 8 channel mode enabled\n");
+ else
+ printk("\n TDM 8 channel mode disabled\n");
+
+ changed = 1;
+
+ return changed;
+}
+
+/*
+****************************************************************************************
+* Direct Rendering Mode control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_direct_rendering_mode_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .name = "Direct Rendering Mode",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_direct_rendering_mode_ctrl_info,
+ .get = u8500_direct_rendering_mode_ctrl_get,
+ .put = u8500_direct_rendering_mode_ctrl_put
+};
+
+/**
+* u8500_direct_rendering_mode_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_direct_rendering_mode_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
+ *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_DIRECT_RENDERING_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_DIRECT_RENDERING_STATE)
+ uinfo->value.enumerated.item =
+ NUMBER_DIRECT_RENDERING_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ direct_rendering_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_direct_rendering_mode_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_direct_rendering_mode_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
+ *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->direct_rendering_mode;
+ return 0;
+}
+
+/**
+* u8500_direct_rendering_mode_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_direct_rendering_mode_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
+ *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ chip->direct_rendering_mode = uinfo->value.enumerated.item[0];
+ changed = 1;
+
+ return changed;
+}
+
+/*
+****************************************************************************************
+* PCM Rendering Mode control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_pcm_rendering_mode_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .name = "PCM Rendering Mode",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_pcm_rendering_mode_ctrl_info,
+ .get = u8500_pcm_rendering_mode_ctrl_get,
+ .put = u8500_pcm_rendering_mode_ctrl_put
+};
+
+/**
+* u8500_pcm_rendering_mode_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_pcm_rendering_mode_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_PCM_RENDERING_STATE;
+ uinfo->count = 3;
+ if (uinfo->value.enumerated.item >= NUMBER_PCM_RENDERING_STATE)
+ uinfo->value.enumerated.item = NUMBER_PCM_RENDERING_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ pcm_rendering_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_pcm_rendering_mode_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_pcm_rendering_mode_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->burst_fifo_mode;
+ uinfo->value.enumerated.item[1] = chip->fm_playback_mode;
+ uinfo->value.enumerated.item[2] = chip->fm_tx_mode;
+ return 0;
+}
+
+/**
+* u8500_pcm_rendering_mode_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_pcm_rendering_mode_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ if (RENDERING_PENDING == uinfo->value.enumerated.item[0]) {
+ return changed;
+ }
+ if (chip->burst_fifo_mode != uinfo->value.enumerated.item[0]) {
+ chip->burst_fifo_mode = uinfo->value.enumerated.item[0];
+ u8500_acodec_set_burst_mode_fifo(chip->burst_fifo_mode);
+ }
+
+ chip->fm_playback_mode = uinfo->value.enumerated.item[1];
+ chip->fm_tx_mode = uinfo->value.enumerated.item[2];
+
+ changed = 1;
+
+ return changed;
+}
+
+#if 0 /* DUMP REGISTER CONTROL */
+/*
+****************************************************************************************
+* dump registers control *
+****************************************************************************************
+*/
+
+struct snd_kcontrol_new u8500_dump_register_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 0,
+ .name = "",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_dump_register_ctrl_info,
+ .get = u8500_dump_register_ctrl_get,
+ .put = u8500_dump_register_ctrl_put
+};
+
+/**
+* u8500_dump_register_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_dump_register_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_PCM_RENDERING_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_PCM_RENDERING_STATE)
+ uinfo->value.enumerated.item = NUMBER_PCM_RENDERING_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ pcm_rendering_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_dump_register_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_dump_register_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = chip->burst_fifo_mode;
+ uinfo->value.enumerated.item[1] = chip->fm_playback_mode;
+ uinfo->value.enumerated.item[2] = chip->fm_tx_mode;
+ return 0;
+}
+
+/**
+* u8500_dump_register_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_dump_register_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+
+ if (RENDERING_PENDING == uinfo->value.enumerated.item[0]) {
+ return changed;
+ }
+ if (chip->burst_fifo_mode != uinfo->value.enumerated.item[0]) {
+ chip->burst_fifo_mode = uinfo->value.enumerated.item[0];
+ //u8500_acodec_set_burst_mode_fifo(chip->burst_fifo_mode);
+ }
+
+ chip->fm_playback_mode = uinfo->value.enumerated.item[1];
+ chip->fm_tx_mode = uinfo->value.enumerated.item[2];
+
+ changed = 1;
+
+ return changed;
+}
+
+#endif /* DUMP REGISTER CONTROL */
+
+/* Hardware description , this structure (struct snd_pcm_hardware )
+ * contains the definitions of the fundamental hardware configuration.
+ * This configuration will be applied on the runtime structure
+ */
+static struct snd_pcm_hardware snd_u8500_playback_hw = {
+ .info =
+ (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE),
+ .formats =
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |
+ SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_U24_BE |
+ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE |
+ SNDRV_PCM_FMTBIT_S32_BE | SNDRV_PCM_FMTBIT_U32_BE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = MIN_RATE_PLAYBACK,
+ .rate_max = MAX_RATE_PLAYBACK,
+ .channels_min = 1,
+ .channels_max = 8,
+ .buffer_bytes_max = NMDK_BUFFER_SIZE,
+ .period_bytes_min = 128,
+ .period_bytes_max = PAGE_SIZE,
+ .periods_min = NMDK_BUFFER_SIZE / PAGE_SIZE,
+ .periods_max = NMDK_BUFFER_SIZE / 128
+};
+
+static struct snd_pcm_hardware snd_u8500_capture_hw = {
+ .info =
+ (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE),
+ .formats =
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |
+ SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_U24_BE |
+ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE |
+ SNDRV_PCM_FMTBIT_S32_BE | SNDRV_PCM_FMTBIT_U32_BE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = MIN_RATE_CAPTURE,
+ .rate_max = MAX_RATE_CAPTURE,
+ .channels_min = 1,
+ .channels_max = 8,
+ .buffer_bytes_max = NMDK_BUFFER_SIZE,
+ .period_bytes_min = 128,
+ .period_bytes_max = PAGE_SIZE,
+ .periods_min = NMDK_BUFFER_SIZE / PAGE_SIZE,
+ .periods_max = NMDK_BUFFER_SIZE / 128
+};
+
+static struct snd_pcm_hw_constraint_list constraints_rate = {
+ .count = sizeof(u8500_acodec_rates) / sizeof(u8500_acodec_rates[0]),
+ .list = u8500_acodec_rates,
+ .mask = 0,
+};
+
+/**
+ * snd_u8500_alsa_pcm_close
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This routine is used by alsa framework to close a pcm stream .
+ * Here a dma pipe is disabled and freed.
+ */
+static int snd_u8500_alsa_pcm_close(struct snd_pcm_substream *substream)
+{
+ int stream_id, error = 0;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ stream_id = substream->pstr->stream;
+ ptr_audio_stream = &chip->stream[ALSA_PCM_DEV][stream_id];
+
+ if (ENABLE == chip->direct_rendering_mode) {
+ ptr_audio_stream->substream = NULL;
+ return 0;
+ } else {
+ stm_close_alsa(chip, ALSA_PCM_DEV, stream_id);
+
+ /* reset the different variables to default */
+
+ ptr_audio_stream->active = 0;
+ ptr_audio_stream->period = 0;
+ ptr_audio_stream->periods = 0;
+ ptr_audio_stream->old_offset = 0;
+ ptr_audio_stream->substream = NULL;
+ if (!(--active_user)) {
+ /* Disable the MSP1 */
+ error = u8500_acodec_unsetuser(USER_ALSA);
+ u8500_acodec_close(I2S_CLIENT_MSP1, ACODEC_DISABLE_ALL);
+ } else {
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+ u8500_acodec_close(I2S_CLIENT_MSP1,
+ ACODEC_DISABLE_TRANSMIT);
+ else if (stream_id == SNDRV_PCM_STREAM_CAPTURE)
+ u8500_acodec_close(I2S_CLIENT_MSP1,
+ ACODEC_DISABLE_RECEIVE);
+ }
+
+ stm_hw_free(substream);
+
+ return error;
+ }
+}
+
+void my_write(u32 address, u8 data)
+{
+ ab8500_write(AB8500_AUDIO, address, data);
+}
+
+void dsp_configure_audio_codec(void)
+{
+ //4500 config for both record DMIC1&2 and playback HS stereo
+ //data width is 16 bits
+
+ my_write(0x200, 0x02); // Start-up audio unreset
+ my_write(0x20B, 0x10); // Start-up audio clk audio enable
+ my_write(0x383, 0x06); // Start-up audio Vaudio supply
+
+ my_write(0xD00, 0x88); // General power up=0x88
+ my_write(0xD01, 0x00); // Software Reset=0x0
+ my_write(0xD02, 0xC0); // Digital AD Channels Enable=0xC0
+ my_write(0xD03, 0xC0); // Digital DA Channels Enable=0xC0
+ my_write(0xD04, 0x00); // Low Power and Conf=0x0
+ my_write(0xD05, 0x0F); // Line in Conf=0xF
+ my_write(0xD06, 0xC0); // Analog Inputs Enable=0xC0
+ my_write(0xD07, 0x30); // ADC Enable=0x30
+ my_write(0xD08, 0x30); // Analog Output Enable=0x30
+ my_write(0xD09, 0x30); // Digital Output Enable=0x30
+ my_write(0xD0A, 0x4F); // Mute Enable=0x4F
+ my_write(0xD0B, 0x7F); // Short Circuit Disable=0x7F
+ my_write(0xD0C, 0x80); // Power-up for Headset=0x80
+ my_write(0xD0D, 0x00); // Envelope Threshold=0x0
+ my_write(0xD0E, 0x00); // Envelope Decay Time=0x0
+ my_write(0xD0F, 0xF0); // Class-D Configuration=0xF0
+ my_write(0xD10, 0x32); // PWM VIBNL Configuration=0x32
+ my_write(0xD11, 0x32); // PWM VIBPL Configuration=0x32
+ my_write(0xD12, 0x32); // PWM VIBNR Configuration=0x32
+ my_write(0xD13, 0x32); // PWM VIBPR Configuration=0x32
+ my_write(0xD14, 0x00); // Microphone 1 Gain=0x0
+ my_write(0xD15, 0x00); // Microphone 2 Gain=0x0
+ my_write(0xD16, 0x00); // Left line-in and HS Analog Gain=0x0
+ my_write(0xD17, 0x00); // Right line-in and HS Analog Gain=0x0
+ my_write(0xD18, 0x1F); // Line-in to HSL Gain=0x1F
+ my_write(0xD19, 0x1F); // Line-in to HSR Gain=0x1F
+ my_write(0xD1A, 0xF0); // AD Channel Filters Configuration=0xF0
+ my_write(0xD1B, 0x85); // TDM Configuration 1=0x85
+ my_write(0xD1C, 0x94); // TDM Configuration 2=0x94
+ my_write(0xD1D, 0x02); // TDM loopback control=0x2
+ my_write(0xD1E, 0x00); // TDM format=0x0
+ my_write(0xD1F, 0x10); // AD Data allocation in Slot 0 to 1=0x10
+ my_write(0xD20, 0xCC); // AD Data allocation in Slot 2 to 3=0xCC
+ my_write(0xD21, 0xCC); // AD Data allocation in Slots 4 to 5=0xCC
+ my_write(0xD22, 0xCC); // AD Data allocation in Slots 6 to 7=0xCC
+ my_write(0xD23, 0xCC); // AD Data allocation in Slots 8 to 9=0xCC
+ my_write(0xD24, 0xCC); // AD Data allocation in Slots 10 to 11=0xCC
+ my_write(0xD25, 0xCC); // AD Data allocation in Slots 12 to 13=0xCC
+ my_write(0xD26, 0xCC); // AD Data allocation in Slots 14 to 15=0xCC
+ my_write(0xD27, 0xCC); // AD Data allocation in Slots 16 to 17=0xCC
+ my_write(0xD28, 0xCC); // AD Data allocation in Slots 18 to 19=0xCC
+ my_write(0xD29, 0xCC); // AD Data allocation in Slots 20 to 21=0xCC
+ my_write(0xD2A, 0xCC); // AD Data allocation in Slots 22 to 23=0xCC
+ my_write(0xD2B, 0xCC); // AD Data allocation in Slots 24 to 25=0xCC
+ my_write(0xD2C, 0xCC); // AD Data allocation in Slots 26 to 27=0xCC
+ my_write(0xD2D, 0xCC); // AD Data allocation in Slots 28 to 29=0xCC
+ my_write(0xD2E, 0xCC); // AD Data allocation in Slots 30 to 31=0xCC
+ my_write(0xD2F, 0x00); // AD slot 0/7 tristate=0x0
+ my_write(0xD30, 0x00); // AD slot 8/15 tristate=0x0
+ my_write(0xD31, 0x00); // AD slot 16/23 tristate=0x0
+ my_write(0xD32, 0x00); // AD slot 24/31 tristate=0x0
+ my_write(0xD33, 0x08); // Slots selection for DA path 1=0x8
+ my_write(0xD34, 0x09); // Slots selection for DA path 2=0x9
+ my_write(0xD35, 0x00); // Slots selection for DA path 3=0x0
+ my_write(0xD36, 0x00); // Slots selection for DA path 4=0x0
+ my_write(0xD37, 0x00); // Slots selection for DA path 5=0x0
+ my_write(0xD38, 0x00); // Slots selection for DA path 6=0x0
+ my_write(0xD39, 0x00); // IRQ mask lsb=0x0
+ my_write(0xD3A, 0x00); // IRQ status lsb=0x0
+ my_write(0xD3B, 0x00); // IRQ mask msb=0x0
+ my_write(0xD3C, 0x00); // IRQ status msb=0x0
+ my_write(0xD3D, 0x00); // Fade speed=0x0
+ my_write(0xD3E, 0x00); // DMIC decimator filter=0x0
+ my_write(0xD3F, 0xF0); // muxing lsb=0xF0
+ my_write(0xD40, 0x00); // muxing msb=0x0
+ my_write(0xD41, 0x1F); // AD1 Digital Gain=0x1F
+ my_write(0xD42, 0x1F); // AD2 Digital Gain=0x1F
+ my_write(0xD43, 0x1F); // AD3 Digital Gain=0x1F
+ my_write(0xD44, 0x1F); // AD4 Digital Gain=0x1F
+ my_write(0xD45, 0x1F); // AD5 Digital Gain=0x1F
+ my_write(0xD46, 0x1F); // AD6 Digital Gain=0x1F
+ my_write(0xD47, 0x00); // DA1 digital Gain=0x00
+ my_write(0xD48, 0x00); // DA2 digital Gain=0x00
+ my_write(0xD49, 0x3F); // DA3 digital Gain=0x3F
+ my_write(0xD4A, 0x3F); // DA4 digital Gain=0x3F
+ my_write(0xD4B, 0x3F); // DA5 digital Gain=0x3F
+ my_write(0xD4C, 0x3F); // DA6 digital Gain=0x3F
+ my_write(0xD4D, 0x3F); // AD1 loopback to HFL digital gain=0x3F
+ my_write(0xD4E, 0x3F); // AD2 loopback to HFR digital gain=0x3F
+ my_write(0xD4F, 0x08); // HSL and EAR digital gain=0x8
+ my_write(0xD50, 0x08); // HSR digital gain=0x8
+ my_write(0xD51, 0x1F); // Side tone FIR1 gain=0x1F
+ my_write(0xD52, 0x1F); // Side tone FIR2 gain=0x1F
+ my_write(0xD53, 0x00); // ANC filter control=0x0
+ my_write(0xD54, 0x00); // ANC Warped Delay Line Shift=0x0
+ my_write(0xD55, 0x00); // ANC FIR output Shift=0x0
+ my_write(0xD56, 0x00); // ANC IIR output Shift=0x0
+ my_write(0xD57, 0x00); // ANC FIR coefficients msb=0x0
+ my_write(0xD58, 0x00); // ANC FIR coefficients lsb=0x0
+ my_write(0xD59, 0x00); // ANC IIR coefficients msb=0x0
+ my_write(0xD5A, 0x00); // ANC IIR coefficients lsb=0x0
+ my_write(0xD5B, 0x00); // ANC Warp delay msb=0x0
+ my_write(0xD5C, 0x00); // ANC Warp delay lsb=0x0
+ my_write(0xD5D, 0x00); // ANC FIR peak register MSB=0x0
+ my_write(0xD5E, 0x00); // ANC FIR peak register LSB=0x0
+ my_write(0xD5F, 0x00); // ANC IIR peak register. MSB part=0x0
+ my_write(0xD60, 0x00); // ANC IIR peak register. LSB part=0x0
+ my_write(0xD61, 0x00); // Side tone FIR address=0x0
+ my_write(0xD62, 0x00); // Side tone FIR coefficient MSB=0x0
+ my_write(0xD63, 0x00); // Side tone FIR coefficient LSB=0x0
+ my_write(0xD64, 0x00); // Filters control=0x0
+ my_write(0xD65, 0x00); // Class D EMI Control=0x0
+ my_write(0xD66, 0x00); // Class D control path=0x0
+ my_write(0xD67, 0x00); // Class D control gain=0x0
+ my_write(0xD68, 0x00); // Burst FIFO int control=0x0
+ my_write(0xD69, 0x00); // Burst FIFO length=0x0
+ my_write(0xD6A, 0x00); // Burst FIFO control=0x0
+ my_write(0xD6B, 0x00); // Burst FIFO switch frame=0x0
+ my_write(0xD6C, 0x00); // Burst FIFO wake up delay=0x0
+ my_write(0xD6D, 0x00); // Burst FIFO samples number=0x0
+ my_write(0xD70, 0x00); // CR112=0x0
+ my_write(0xD71, 0x04); // CR113=0x4
+ my_write(0xD72, 0x00); // CR114=0x0
+ my_write(0xD73, 0x00); // CR115=0x0
+ my_write(0xD74, 0x00); // CR116=0x0
+ my_write(0xD75, 0x00); // CR117=0x0
+ my_write(0xD76, 0x00); // CR118=0x0
+ my_write(0xD77, 0x00); // CR119=0x0
+ my_write(0xD78, 0x00); // CR120=0x0
+ my_write(0xD79, 0x00); // CR121=0x0
+ my_write(0xD7A, 0x00); // CR122=0x0
+ my_write(0xD7B, 0x00); // CR123=0x0
+}
+
+static int configure_direct_rendering(struct snd_pcm_substream *substream)
+{
+ int error = 0, stream_id;
+ int status = 0;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ stream_id = substream->pstr->stream;
+
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
+ runtime->hw = snd_u8500_playback_hw;
+ } else {
+ runtime->hw = snd_u8500_capture_hw;
+ }
+
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x04))); //MSP_GCR
+
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x08))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x0C))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x10))); //MSP
+
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x30))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x34))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x38))); //MSP
+
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x40))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x44))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x48))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x4C))); //MSP
+
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x60))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x64))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x68))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x6C))); //MSP
+
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x18))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x20))); //MSP
+ writel(0x0, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x2C))); //MSP
+
+ dsp_configure_audio_codec();
+
+#if DRIVER_DEBUG > 0
+ {
+ dump_msp_registers();
+ dump_acodec_registers();
+ }
+#endif
+
+ ptr_audio_stream = &chip->stream[ALSA_PCM_DEV][stream_id];
+
+ ptr_audio_stream->substream = substream;
+
+ FUNC_EXIT();
+ return 0;
+}
+
+/**
+ * snd_u8500_alsa_pcm_open
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This routine is used by alsa framework to open a pcm stream .
+ * Here a dma pipe is requested and device is configured(default).
+ */
+static int snd_u8500_alsa_pcm_open(struct snd_pcm_substream *substream)
+{
+ int error = 0, stream_id, status = 0;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ FUNC_ENTER();
+
+ if (ENABLE == chip->direct_rendering_mode) {
+ configure_direct_rendering(substream);
+ return 0;
+ } else {
+ stream_id = substream->pstr->stream;
+ status = u8500_acodec_open(I2S_CLIENT_MSP1, stream_id);
+
+ if (status) {
+ printk("failed in getting open\n");
+ return -1;
+ }
+
+ if (!active_user)
+ error = u8500_acodec_setuser(USER_ALSA);
+ if (error)
+ return error;
+ else
+ active_user++;
+
+ error =
+ snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rate);
+ if (error < 0) {
+ stm_error
+ (": error initializing hw sample rate constraint\n");
+ return error;
+ }
+
+ /* configure the default sampling rate for the acodec */
+ second_config = 0;
+
+ if ((error = configure_rate(substream, ACODEC_CONFIG_REQUIRED)))
+ return error;
+
+ /* Set the hardware configuration */
+ stream_id = substream->pstr->stream;
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
+ runtime->hw = snd_u8500_playback_hw;
+ /* configure the output sink for the acodec */
+ if ((error =
+ u8500_acodec_select_output(chip->output_device,
+ USER_ALSA,
+ chip->tdm8_ch_mode))) {
+ stm_error(" : select output failed\n");
+ return error;
+ }
+
+ /* configure the volume settings for the acodec */
+ if ((error =
+ u8500_acodec_set_output_volume(chip->output_device,
+ chip->
+ output_lvolume,
+ chip->
+ output_rvolume,
+ USER_ALSA))) {
+ stm_error(" : set output volume failed\n");
+ return error;
+ }
+ } else {
+ runtime->hw = snd_u8500_capture_hw;
+ /* configure the input source for the acodec */
+ if ((error =
+ u8500_acodec_select_input(chip->input_device,
+ USER_ALSA,
+ chip->tdm8_ch_mode))) {
+ stm_error(" : select input failed\n");
+ return error;
+ }
+ /*u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_1,ENABLE);
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_2,ENABLE);
+
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_1,
+ chip->input_lvolume,
+ chip->input_rvolume,
+ USER_ALSA);
+
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_2,
+ chip->input_lvolume,
+ chip->input_rvolume,
+ USER_ALSA);
+ */
+
+ if ((error =
+ u8500_acodec_set_input_volume(chip->input_device,
+ chip->input_lvolume,
+ chip->input_rvolume,
+ USER_ALSA))) {
+ stm_error(" : set input volume failed\n");
+ return error;
+ }
+ }
+
+ u8500_acodec_set_burst_mode_fifo(chip->burst_fifo_mode);
+
+#if DRIVER_DEBUG > 0
+ {
+ dump_msp_registers();
+ dump_acodec_registers();
+ }
+#endif
+
+ ptr_audio_stream = &chip->stream[ALSA_PCM_DEV][stream_id];
+
+ ptr_audio_stream->substream = substream;
+
+ if (DISABLE == chip->direct_rendering_mode) {
+ stm_config_hw(chip, substream, ALSA_PCM_DEV, stream_id);
+ }
+ sema_init(&(ptr_audio_stream->alsa_sem), 1);
+ init_completion(&(ptr_audio_stream->alsa_com));
+ ptr_audio_stream->state = ALSA_STATE_UNPAUSE;
+
+ FUNC_EXIT();
+ return 0;
+ }
+}
+
+/**
+ * snd_u8500_alsa_pcm_hw_params
+ * @substream - pointer to the playback/capture substream structure
+ * @hw_params - specifies the hw parameters like format/no of channels etc
+ *
+ * This routine is used by alsa framework to allocate a dma buffer
+ * used to transfer the data from user space to kernel space
+ *
+ */
+static int snd_u8500_alsa_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+}
+
+/**
+ * snd_u8500_alsa_pcm_hw_free
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This routine is used by alsa framework to deallocate a dma buffer
+ * allocated berfore by snd_u8500_alsa_pcm_hw_params
+ */
+static int snd_u8500_alsa_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ stm_hw_free(substream);
+ return 0;
+}
+
+/**
+ * snd_u8500_alsa_pcm_prepare
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This callback is called whene the pcm is "prepared" Here is possible
+ * to set the format type ,sample rate ,etc.The callback is called as
+ * well everytime a recovery after an underrun happens.
+ */
+
+static int snd_u8500_alsa_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int error, stream_id;
+
+ FUNC_ENTER();
+
+ if (chip->freq != runtime->rate || chip->channels != runtime->channels) {
+ stm_dbg(DBG_ST.alsa, " freq not same, %d %d\n", chip->freq,
+ runtime->rate);
+ stm_dbg(DBG_ST.alsa, " channels not same, %d %d\n",
+ chip->channels, runtime->channels);
+ if (chip->channels != runtime->channels) {
+ chip->channels = runtime->channels;
+ if ((error =
+ stm_config_hw(chip, substream, ALSA_PCM_DEV,
+ -1))) {
+ stm_dbg(DBG_ST.alsa,
+ "In func %s, stm_config_hw fails",
+ __FUNCTION__);
+ return error;
+ }
+ }
+ chip->freq = runtime->rate;
+ second_config = 1;
+ stream_id = substream->pstr->stream;
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+ u8500_acodec_close(I2S_CLIENT_MSP1,
+ ACODEC_DISABLE_TRANSMIT);
+ else if (stream_id == SNDRV_PCM_STREAM_CAPTURE)
+ u8500_acodec_close(I2S_CLIENT_MSP1,
+ ACODEC_DISABLE_RECEIVE);
+
+ error = u8500_acodec_open(I2S_CLIENT_MSP1, stream_id);
+ if (error) {
+ printk("failed in getting open\n");
+ return -1;
+ }
+ if ((error =
+ configure_rate(substream, ACODEC_CONFIG_NOT_REQUIRED))) {
+ stm_dbg(DBG_ST.alsa, "In func %s, configure_rate fails",
+ __FUNCTION__);
+ return error;
+ }
+ }
+
+ FUNC_EXIT();
+ return 0;
+}
+
+/**
+ * snd_u8500_alsa_pcm_trigger
+ * @substream - pointer to the playback/capture substream structure
+ * @cmd - specifies the command : start/stop/pause/resume
+ *
+ * This callback is called whene the pcm is started ,stopped or paused
+ * The action is specified in the second argument, SND_PCM_TRIGGER_XXX in
+ * <sound/pcm.h>.
+ * This callback is atomic and the interrupts are disabled , so you can't
+ * call other functions that need interrupts without possible risks
+ */
+static int snd_u8500_alsa_pcm_trigger(struct snd_pcm_substream *substream,
+ int cmd)
+{
+ int stream_id = substream->pstr->stream;
+ audio_stream_t *stream = NULL;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ int error = 0;
+
+ FUNC_ENTER();
+
+ stream = &chip->stream[ALSA_PCM_DEV][stream_id];
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ /* Start the pcm engine */
+ stm_dbg(DBG_ST.alsa, " TRIGGER START\n");
+ if (stream->active == 0) {
+ stream->active = 1;
+ stm_trigger_alsa(stream);
+ break;
+ }
+ stm_error(": H/w is busy\n");
+ return -EINVAL;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ stm_dbg(DBG_ST.alsa, " SNDRV_PCM_TRIGGER_PAUSE_PUSH\n");
+ if (stream->active == 1) {
+ stm_pause_alsa(stream);
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ stm_dbg(DBG_ST.alsa, " SNDRV_PCM_TRIGGER_PAUSE_RELEASE\n");
+ if (stream->active == 1)
+ stm_unpause_alsa(stream);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ /* Stop the pcm engine */
+ stm_dbg(DBG_ST.alsa, " TRIGGER STOP\n");
+ if (stream->active == 1)
+ stm_stop_alsa(stream);
+ break;
+ default:
+ stm_error(": invalid command in pcm trigger\n");
+ return -EINVAL;
+ }
+
+ FUNC_EXIT();
+ return error;
+}
+
+/**
+ * snd_u8500_alsa_pcm_pointer
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This callback is called whene the pcm middle layer inquires the current
+ * hardware position on the buffer .The position is returned in frames
+ * ranged from 0 to buffer_size -1
+ */
+static snd_pcm_uframes_t snd_u8500_alsa_pcm_pointer(struct snd_pcm_substream
+ *substream)
+{
+ unsigned int offset;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ audio_stream_t *stream =
+ &chip->stream[ALSA_PCM_DEV][substream->pstr->stream];
+ struct snd_pcm_runtime *runtime = stream->substream->runtime;
+
+ offset = bytes_to_frames(runtime, stream->old_offset);
+ if (offset < 0 || stream->old_offset < 0)
+ stm_dbg(DBG_ST.alsa, " Offset=%i %i\n", offset,
+ stream->old_offset);
+
+ return offset;
+}
+
+static struct snd_pcm_ops snd_u8500_alsa_playback_ops = {
+ .open = snd_u8500_alsa_pcm_open,
+ .close = snd_u8500_alsa_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_u8500_alsa_pcm_hw_params,
+ .hw_free = snd_u8500_alsa_pcm_hw_free,
+ .prepare = snd_u8500_alsa_pcm_prepare,
+ .trigger = snd_u8500_alsa_pcm_trigger,
+ .pointer = snd_u8500_alsa_pcm_pointer,
+};
+
+static struct snd_pcm_ops snd_u8500_alsa_capture_ops = {
+ .open = snd_u8500_alsa_pcm_open,
+ .close = snd_u8500_alsa_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_u8500_alsa_pcm_hw_params,
+ .hw_free = snd_u8500_alsa_pcm_hw_free,
+ .prepare = snd_u8500_alsa_pcm_prepare,
+ .trigger = snd_u8500_alsa_pcm_trigger,
+ .pointer = snd_u8500_alsa_pcm_pointer,
+};
+
+#ifdef CONFIG_U8500_ACODEC_POLL
+
+/**
+* u8500_alsa_pio_start
+* @stream - pointer to the playback/capture audio_stream_t structure
+*
+* This function sends/receive one chunck of stream data to/from MSP
+*/
+static void u8500_alsa_pio_start(audio_stream_t * stream)
+{
+ unsigned int offset, dma_size, stream_id;
+ int ret_val;
+ struct snd_pcm_substream *substream = stream->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ stream_id = substream->pstr->stream;
+
+ FUNC_ENTER();
+ dma_size = frames_to_bytes(runtime, runtime->period_size);
+ offset = dma_size * stream->period;
+ stream->old_offset = offset;
+
+ stm_dbg(DBG_ST.alsa, " Transfer started\n");
+ stm_dbg(DBG_ST.alsa, " address = %x size=%d\n",
+ (runtime->dma_addr + offset), dma_size);
+
+ /* Send our stuff */
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_send_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_send_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+ else
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_receive_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_receive_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+
+ stream->period++;
+ stream->period %= runtime->periods;
+ stream->periods++;
+
+ FUNC_EXIT();
+
+}
+
+/**
+* acodec_feeding_thread
+* @data - void pointer to the playback/capture audio_stream_t structure
+*
+* This thread sends/receive data to MSP while stream is active
+*/
+static int acodec_feeding_thread(void *data)
+{
+ audio_stream_t *stream = (audio_stream_t *) data;
+
+ FUNC_ENTER();
+ daemonize("acodec_feeding_thread");
+ allow_signal(SIGKILL);
+ down(&stream->alsa_sem);
+
+ while ((!signal_pending(current)) && (stream->active)) {
+ if (stream->state == ALSA_STATE_PAUSE)
+ wait_for_completion(&(stream->alsa_com));
+
+ u8500_alsa_pio_start(stream);
+ if (stream->substream)
+ snd_pcm_period_elapsed(stream->substream);
+ }
+
+ up(&stream->alsa_sem);
+
+ FUNC_EXIT();
+ return 0;
+}
+
+/**
+* acodec_feeding_thread
+* @stream - pointer to the playback/capture audio_stream_t structure
+*
+* This function creates a kernel thread .
+*/
+
+int spawn_acodec_feeding_thread(audio_stream_t * stream)
+{
+ pid_t pid;
+
+ FUNC_ENTER();
+
+ pid =
+ kernel_thread(acodec_feeding_thread, stream,
+ CLONE_FS | CLONE_SIGHAND);
+
+ FUNC_EXIT();
+ return 0;
+}
+#endif
+
+/**
+ * dma_eot_handler
+ * @data - pointer to structure set in the dma callback handler
+ *
+ * This is the PCM tasklet handler linked to a pipe, its role is to tell
+ * the PCM middler layer whene the buffer position goes across the prescribed
+ * period size.To inform of this the snd_pcm_period_elapsed is called.
+ *
+ * this callback will be called in case of DMA_EVENT_TC only
+ */
+static void dma_eot_handler(void *data)
+{
+ audio_stream_t *stream = data;
+
+ /* snd_pcm_period_elapsed() is _not_ to be protected
+ */
+ stm_dbg(DBG_ST.alsa,
+ "One transfer complete.. going to start the next one\n");
+
+ if (stream->substream)
+ snd_pcm_period_elapsed(stream->substream);
+ if (stream->state == ALSA_STATE_PAUSE)
+ return;
+ if (stream->active == 1) {
+ u8500_alsa_dma_start(stream);
+ }
+}
+
+/**
+ * u8500_alsa_dma_start - used to transmit or recive a dma chunk
+ * @stream - specifies the playback/record stream structure
+ */
+void u8500_alsa_dma_start(audio_stream_t * stream)
+{
+ unsigned int offset, dma_size, stream_id;
+
+ struct snd_pcm_substream *substream = stream->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ u8500_acodec_chip_t *u8500_chip = NULL;
+ stream_id = substream->pstr->stream;
+ u8500_chip = snd_pcm_substream_chip(substream);
+
+ dma_size = frames_to_bytes(runtime, runtime->period_size);
+ offset = dma_size * stream->period;
+ stream->old_offset = offset;
+
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_send_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_send_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+ else
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_receive_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_receive_data(I2S_CLIENT_MSP1,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+
+ stm_dbg(DBG_ST.alsa, " DMA Transfer started\n");
+ stm_dbg(DBG_ST.alsa, " address = %x size=%d\n",
+ (runtime->dma_addr + offset), dma_size);
+
+ stream->period++;
+ stream->period %= runtime->periods;
+ stream->periods++;
+}
+
+/**
+* u8500_audio_init
+* @chip - pointer to u8500_acodec_chip_t structure.
+*
+* This function intialises the u8500 chip structure with default values
+*/
+static void u8500_audio_init(u8500_acodec_chip_t * chip)
+{
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ ptr_audio_stream =
+ &chip->stream[ALSA_PCM_DEV][SNDRV_PCM_STREAM_PLAYBACK];
+ /* Setup DMA stuff */
+ strlcpy(ptr_audio_stream->id, "u8500 playback",
+ sizeof(ptr_audio_stream->id));
+ ptr_audio_stream->stream_id = SNDRV_PCM_STREAM_PLAYBACK;
+
+ /* default initialization for playback */
+ ptr_audio_stream->active = 0;
+ ptr_audio_stream->period = 0;
+ ptr_audio_stream->periods = 0;
+ ptr_audio_stream->old_offset = 0;
+
+ ptr_audio_stream =
+ &chip->stream[ALSA_PCM_DEV][SNDRV_PCM_STREAM_CAPTURE];
+ strlcpy(ptr_audio_stream->id, "u8500 capture",
+ sizeof(ptr_audio_stream->id));
+ ptr_audio_stream->stream_id = SNDRV_PCM_STREAM_CAPTURE;
+
+ /* default initialization for capture */
+ ptr_audio_stream->active = 0;
+ ptr_audio_stream->period = 0;
+ ptr_audio_stream->periods = 0;
+ ptr_audio_stream->old_offset = 0;
+
+ chip->freq = DEFAULT_SAMPLE_RATE;
+ chip->channels = 1;
+ chip->input_lvolume = DEFAULT_GAIN;
+ chip->input_rvolume = DEFAULT_GAIN;
+ chip->output_lvolume = DEFAULT_VOLUME;
+ chip->output_rvolume = DEFAULT_VOLUME;
+ chip->output_device = DEFAULT_OUTPUT_DEVICE;
+ chip->input_device = DEFAULT_INPUT_DEVICE;
+ chip->analog_lpbk = DEFAULT_LOOPBACK_STATE;
+ chip->digital_lpbk = DEFAULT_LOOPBACK_STATE;
+ chip->playback_switch = DEFAULT_SWITCH_STATE;
+ chip->capture_switch = DEFAULT_SWITCH_STATE;
+ chip->tdm8_ch_mode = DEFAULT_TDM8_CH_MODE_STATE;
+ chip->direct_rendering_mode = DEFAULT_DIRECT_RENDERING_STATE;
+ chip->burst_fifo_mode = DEFAULT_BURST_FIFO_STATE;
+ chip->fm_playback_mode = DEFAULT_FM_PLAYBACK_STATE;
+ chip->fm_tx_mode = DEFAULT_FM_TX_STATE;
+
+ //HDMI Default params set
+ chip->hdmi_params.sampling_freq = 48000;
+ chip->hdmi_params.channel_count = 2;
+}
+
+/**
+ * snd_card_u8500_alsa_pcm_new - constructor for a new pcm cmponent
+ * @chip - pointer to chip specific data
+ * @device - specifies the card number
+ */
+static int snd_card_u8500_alsa_pcm_new(u8500_acodec_chip_t * chip, int device)
+{
+ struct snd_pcm *pcm;
+ int err;
+
+ if ((err = snd_pcm_new(chip->card, "u8500", device, 1, 1, &pcm)) < 0) {
+ stm_error(": error in snd_pcm_new\n");
+ return err;
+ }
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_u8500_alsa_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_u8500_alsa_capture_ops);
+
+ pcm->private_data = chip;
+ pcm->info_flags = 0;
+ chip->pcm = pcm;
+ strcpy(pcm->name, "u8500_alsa");
+
+ u8500_audio_init(pcm->private_data);
+ return 0;
+}
+
+static int u8500_register_alsa_controls(struct snd_card *card,
+ u8500_acodec_chip_t * u8500_chip)
+{
+ int error;
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_playback_vol_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_playback_vol_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_capture_vol_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_capture_vol_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_playback_sink_ctrl,
+ u8500_chip))) < 0) {
+ stm_error(": error initializing playback ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_capture_src_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_playback_sink_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_analog_lpbk_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_analog_lpbk_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_digital_lpbk_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_digital_lpbk_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_playback_switch_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_playback_switch_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_capture_switch_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_capture_switch_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_playback_power_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_playback_power_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_capture_power_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_capture_power_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_tdm_mode_ctrl, u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_tdm_mode_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_direct_rendering_mode_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_direct_rendering_mode_ctrl interface \n\n");
+ return (-1);
+ }
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_pcm_rendering_mode_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_pcm_rendering_mode_ctrl interface \n\n");
+ return (-1);
+ }
+
+ return 0;
+}
+
+static int __init u8500_alsa_probe(struct platform_device *devptr)
+{
+ //static int card_count=0;
+ int error;
+ struct snd_card *card, *hdmi_card;
+ u8500_acodec_chip_t *u8500_chip;
+
+ /*Set currently active users to 0 */
+ active_user = 0;
+
+ error = snd_card_create(0, NULL, THIS_MODULE, sizeof(u8500_acodec_chip_t), &card);
+ if (error < 0) {
+ stm_error(": error in snd_card_create\n");
+ return error;
+ }
+
+ u8500_chip = (u8500_acodec_chip_t *) card->private_data;
+ u8500_chip->card = card;
+
+ if ((error = snd_card_u8500_alsa_pcm_new(u8500_chip, 0)) < 0) {
+ stm_error(": pcm interface can't be initialized\n\n");
+ goto nodev;
+ }
+
+ if ((error = snd_card_u8500_alsa_hdmi_new(u8500_chip, 1)) < 0) {
+ stm_error(": alsa HDMI interface can't be initialized\n\n");
+ goto nodev;
+ }
+
+ if (u8500_register_alsa_controls(card, u8500_chip) < 0) {
+ goto nodev;
+ }
+
+ if (u8500_register_alsa_hdmi_controls(card, u8500_chip) < 0) {
+ goto nodev;
+ }
+#if 0
+ ///////////////////////////////$ H D M I $//////////////////////////////////////
+
+ if (card_count == 1) {
+ hdmi_card =
+ snd_card_new(1, NULL, THIS_MODULE,
+ sizeof(u8500_acodec_chip_t));
+ if (hdmi_card == NULL) {
+ stm_error(": error in hdmi - snd_card_new\n");
+ return -ENOMEM;
+ }
+
+ u8500_chip = (u8500_acodec_chip_t *) hdmi_card->private_data;
+ u8500_chip->card = hdmi_card;
+
+ if ((error = snd_card_u8500_alsa_hdmi_new(u8500_chip, 0)) < 0) {
+ stm_error
+ (": alsa HDMI interface can't be initialized\n\n");
+ goto nodev;
+ }
+
+ if (u8500_register_alsa_hdmi_controls(card, u8500_chip) < 0) {
+ goto nodev;
+ }
+ }
+#endif ////////////////////////////////////////////////////////
+
+ /*char driver[16]; driver name
+ char shortname[32]; short name of this soundcard
+ char longname[80]; name of this soundcard
+ char mixername[80]; mixer name
+ char components[80]; card components delimited withspace */
+
+ strcpy(card->driver, "u8500 alsa");
+ strcpy(card->shortname, "u8500 alsa pcm hdmi driver");
+ strcpy(card->longname, "u8500 alsa pcm hdmi driver");
+
+ snd_card_set_dev(card, &devptr->dev);
+
+ if ((error = snd_card_register(card)) == 0) {
+ stm_info("u8500 audio <hdmi> support running..\n");
+ platform_set_drvdata(devptr, card);
+ return 0;
+ }
+
+ nodev:
+ snd_card_free(card);
+ return error;
+}
+
+static int __devexit u8500_alsa_remove(struct platform_device *devptr)
+{
+ snd_card_free(platform_get_drvdata(devptr));
+ platform_set_drvdata(devptr, NULL);
+ stm_info("u8500 audio support stopped\n");
+
+ /*Set currently active users to 0 */
+ active_user = 0;
+
+ return 0;
+}
+
+static struct platform_driver u8500_alsa_driver = {
+ .probe = u8500_alsa_probe,
+ .remove = __devexit_p(u8500_alsa_remove),
+ .driver = {
+ .name = U8500_ALSA_DRIVER,
+ },
+};
+
+/**
+* u8500_alsa_init - Entry function of AB8500 alsa driver
+*
+* This function registers u8500 alsa driver with linux framework
+*/
+static int __init u8500_alsa_init(void)
+{
+ int err;
+
+ if ((err = platform_driver_register(&u8500_alsa_driver)) < 0)
+ return err;
+ device =
+ platform_device_register_simple(U8500_ALSA_DRIVER, -1, NULL, 0);
+ if (IS_ERR(device)) {
+ platform_driver_unregister(&u8500_alsa_driver);
+ return PTR_ERR(device);
+ }
+ //DBG_ST.acodec = 1;
+ //DBG_ST.alsa = 1;
+
+ return 0;
+}
+
+static void __exit u8500_alsa_exit(void)
+{
+ platform_device_unregister(device);
+ platform_driver_unregister(&u8500_alsa_driver);
+}
+
+module_init(u8500_alsa_init);
+module_exit(u8500_alsa_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AB8500 ALSA driver");
diff --git a/sound/arm/u8500_alsa_ab8500.h b/sound/arm/u8500_alsa_ab8500.h
new file mode 100644
index 00000000000..dda802c2156
--- /dev/null
+++ b/sound/arm/u8500_alsa_ab8500.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Deepak Karda
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef _U8500_ALSA_H_
+#define _U8500_ALSA_H_
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+#include <mach/ab8500_codec_v1_0.h>
+//#include <mach/ab8500_codec_p_v1_0.h>
+#else
+//#include <mach/ab8500_codec_p.h>
+#include <mach/ab8500_codec.h>
+#endif
+#include <mach/u8500_acodec_ab8500.h>
+
+#define DEFAULT_SAMPLE_RATE 48000
+#define NMDK_BUFFER_SIZE (64*1024)
+#define U8500_ALSA_DRIVER "u8500_alsa"
+
+#define MAX_NUMBER_OF_DEVICES 3 /* ALSA_PCM, ALSA_BT, ALSA_HDMI */
+#define MAX_NUMBER_OF_STREAMS 2 /* PLAYBACK, CAPTURE */
+
+#define ALSA_PCM_DEV 0
+#define ALSA_BT_DEV 2
+#define ALSA_HDMI_DEV 1
+
+/* Debugging stuff */
+#ifndef CONFIG_DEBUG_USER
+#define DEBUG_LEVEL 0
+#else
+#define DEBUG_LEVEL 10
+#endif
+
+#if DEBUG_LEVEL > 0
+static int u8500_acodec_debug = DEBUG_LEVEL;
+#define DEBUG(n, args...) do { if (u8500_acodec_debug>(n)) printk(args); } while (0)
+#else
+#define DEBUG(n, args...) do { } while (0)
+#endif
+enum alsa_state {
+ ALSA_STATE_PAUSE,
+ ALSA_STATE_UNPAUSE
+};
+
+/* audio stream definition */
+typedef struct audio_stream_s {
+ char id[64]; /* module identifier string */
+ int stream_id; /* stream identifier */
+ int status;
+ int active; /* we are using this stream for transfer now */
+ int period; /* current transfer period */
+ int periods; /* current count of periods registerd in the DMA engine */
+ enum alsa_state state;
+ unsigned int old_offset;
+ struct snd_pcm_substream *substream;
+ unsigned int exchId;
+ snd_pcm_uframes_t played_frame;
+ struct semaphore alsa_sem;
+ struct completion alsa_com;
+
+} audio_stream_t;
+
+typedef struct hdmi_params_s {
+ int sampling_freq;
+ int channel_count;
+} hdmi_params_t;
+
+/* chip structure definition */
+typedef struct u8500_acodec_s {
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ struct snd_pcm *pcm_hdmi;
+ struct snd_pcm *pcm_bt;
+ unsigned int freq;
+ unsigned int channels;
+ unsigned int input_lvolume;
+ unsigned int input_rvolume;
+ unsigned int output_lvolume;
+ unsigned int output_rvolume;
+ t_ab8500_codec_src input_device;
+ t_ab8500_codec_dest output_device;
+ t_u8500_bool_state analog_lpbk;
+ t_u8500_bool_state digital_lpbk;
+ t_u8500_bool_state playback_switch;
+ t_u8500_bool_state capture_switch;
+ t_u8500_bool_state tdm8_ch_mode;
+ t_u8500_bool_state direct_rendering_mode;
+ t_u8500_pmc_rendering_state burst_fifo_mode;
+ t_u8500_pmc_rendering_state fm_playback_mode;
+ t_u8500_pmc_rendering_state fm_tx_mode;
+ audio_stream_t stream[MAX_NUMBER_OF_DEVICES][MAX_NUMBER_OF_STREAMS];
+ hdmi_params_t hdmi_params;
+} u8500_acodec_chip_t;
+
+void u8500_alsa_dma_start(audio_stream_t * stream);
+
+#if (defined(CONFIG_U8500_ACODEC_DMA) || defined(CONFIG_U8500_ACODEC_INTR))
+
+#define stm_trigger_alsa(x) u8500_alsa_dma_start(x)
+static void inline stm_pause_alsa(audio_stream_t * stream)
+{
+ if (stream->state == ALSA_STATE_UNPAUSE) {
+ stream->state = ALSA_STATE_PAUSE;
+ }
+
+}
+static void inline stm_unpause_alsa(audio_stream_t * stream)
+{
+ if (stream->state == ALSA_STATE_PAUSE) {
+ stream->state = ALSA_STATE_UNPAUSE;
+ stm_trigger_alsa(stream);
+ }
+}
+static void inline stm_stop_alsa(audio_stream_t * stream)
+{
+ stream->active = 0;
+ stream->period = 0;
+
+}
+static void inline stm_hw_free(struct snd_pcm_substream *substream)
+{
+ snd_pcm_lib_free_pages(substream);
+}
+
+#define stm_close_alsa(x, y,z)
+#define stm_config_hw(w,x, y, z) 0
+
+#else ////// CONFIG_U8500_ACODEC_POLL ////////////
+
+int spawn_acodec_feeding_thread(audio_stream_t * stream);
+//static int configure_dmadev_acodec(struct snd_pcm_substream *substream);
+
+#define stm_trigger_alsa(x) spawn_acodec_feeding_thread(x)
+#define stm_close_alsa(x, y,z)
+#define stm_config_hw(w,x, y, z) 0
+#define stm_hw_free(x)
+static void inline stm_pause_alsa(audio_stream_t * stream)
+{
+ stream->state = ALSA_STATE_PAUSE;
+}
+static void inline stm_unpause_alsa(audio_stream_t * stream)
+{
+ stream->state = ALSA_STATE_UNPAUSE;
+ complete(&stream->alsa_com);
+}
+static void inline stm_stop_alsa(audio_stream_t * stream)
+{
+ stream->active = 0;
+ stream->period = 0;
+ if (stream->state == ALSA_STATE_PAUSE)
+ complete(&stream->alsa_com);
+}
+
+#endif
+#endif /*END OF HEADER FILE */
diff --git a/sound/arm/u8500_alsa_hdmi.c b/sound/arm/u8500_alsa_hdmi.c
new file mode 100644
index 00000000000..dcbc3583ba7
--- /dev/null
+++ b/sound/arm/u8500_alsa_hdmi.c
@@ -0,0 +1,936 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL),
+ * version 2.
+ */
+
+/* This include must be defined at this point */
+//#include <sound/driver.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <mach/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* alsa system */
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include "u8500_alsa_ab8500.h"
+#include <mach/msp.h>
+#include <mach/debug.h>
+
+#define ALSA_NAME "DRIVER ALSA HDMI"
+
+/* enables/disables debug msgs */
+#define DRIVER_DEBUG CONFIG_STM_ALSA_DEBUG
+/* msg header represents this module */
+#define DRIVER_DEBUG_PFX ALSA_NAME
+/* message level */
+#define DRIVER_DBG KERN_ERR
+#define ELEMENT_SIZE 0
+
+extern char *power_state_in_texts[NUMBER_POWER_STATE];
+
+static int u8500_hdmi_power_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int u8500_hdmi_power_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+static int u8500_hdmi_power_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo);
+
+void dump_msp2_registers();
+
+#ifdef CONFIG_U8500_ACODEC_DMA
+
+static void u8500_alsa_hdmi_dma_start(audio_stream_t * stream);
+#define stm_trigger_hdmi(x) u8500_alsa_hdmi_dma_start(x)
+static void inline stm_pause_hdmi(audio_stream_t * stream)
+{
+ if (stream->state == ALSA_STATE_UNPAUSE) {
+ stream->state = ALSA_STATE_PAUSE;
+ }
+}
+static void inline stm_unpause_hdmi(audio_stream_t * stream)
+{
+ if (stream->state == ALSA_STATE_PAUSE) {
+ stream->state = ALSA_STATE_UNPAUSE;
+ stm_trigger_hdmi(stream);
+ }
+}
+static void inline stm_stop_hdmi(audio_stream_t * stream)
+{
+ stream->active = 0;
+ stream->period = 0;
+}
+#else /* Polling */
+
+static int spawn_hdmi_feeding_thread(audio_stream_t * stream);
+static int hdmi_feeding_thread(void *data);
+static void u8500_hdmi_pio_start(audio_stream_t * stream);
+
+#define stm_trigger_hdmi(x) spawn_hdmi_feeding_thread(x);
+
+static void inline stm_pause_hdmi(audio_stream_t * stream)
+{
+ stream->state = ALSA_STATE_PAUSE;
+}
+static void inline stm_unpause_hdmi(audio_stream_t * stream)
+{
+ stream->state = ALSA_STATE_UNPAUSE;
+ complete(&stream->alsa_com);
+}
+static void inline stm_stop_hdmi(audio_stream_t * stream)
+{
+ stream->active = 0;
+ stream->period = 0;
+ if (stream->state == ALSA_STATE_PAUSE)
+ complete(&stream->alsa_com);
+}
+
+#endif
+
+extern struct driver_debug_st DBG_ST;
+extern struct i2sdrv_data *i2sdrv[MAX_I2S_CLIENTS];
+
+static void u8500_audio_hdmi_init(u8500_acodec_chip_t * chip);
+int u8500_register_alsa_hdmi_controls(struct snd_card *card,
+ u8500_acodec_chip_t * u8500_chip);
+static int snd_u8500_alsa_hdmi_open(struct snd_pcm_substream *substream);
+static int snd_u8500_alsa_hdmi_close(struct snd_pcm_substream *substream);
+static int snd_u8500_alsa_hdmi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params);
+static int snd_u8500_alsa_hdmi_hw_free(struct snd_pcm_substream *substream);
+static int snd_u8500_alsa_hdmi_prepare(struct snd_pcm_substream *substream);
+static int snd_u8500_alsa_hdmi_trigger(struct snd_pcm_substream *substream,
+ int cmd);
+static snd_pcm_uframes_t snd_u8500_alsa_hdmi_pointer(struct snd_pcm_substream
+ *substream);
+static int configure_hdmi_rate(struct snd_pcm_substream *);
+static int configure_msp_hdmi(int sampling_freq, int channel_count);
+
+int u8500_hdmi_rates[] = { 32000, 44100, 48000, 64000, 88200,
+ 96000, 128000, 176100, 192000
+};
+
+typedef enum {
+ HDMI_SAMPLING_FREQ_32KHZ = 32,
+ HDMI_SAMPLING_FREQ_44_1KHZ = 44,
+ HDMI_SAMPLING_FREQ_48KHZ = 48,
+ HDMI_SAMPLING_FREQ_64KHZ = 64,
+ HDMI_SAMPLING_FREQ_88_2KHZ = 88,
+ HDMI_SAMPLING_FREQ_96KHZ = 96,
+ HDMI_SAMPLING_FREQ_128KHZ = 128,
+ HDMI_SAMPLING_FREQ_176_1KHZ = 176,
+ HDMI_SAMPLING_FREQ_192KHZ = 192
+} t_hdmi_sample_freq;
+
+static struct snd_pcm_ops snd_u8500_alsa_hdmi_playback_ops = {
+ .open = snd_u8500_alsa_hdmi_open,
+ .close = snd_u8500_alsa_hdmi_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_u8500_alsa_hdmi_hw_params,
+ .hw_free = snd_u8500_alsa_hdmi_hw_free,
+ .prepare = snd_u8500_alsa_hdmi_prepare,
+ .trigger = snd_u8500_alsa_hdmi_trigger,
+ .pointer = snd_u8500_alsa_hdmi_pointer,
+};
+
+static struct snd_pcm_ops snd_u8500_alsa_hdmi_capture_ops = {
+ .open = snd_u8500_alsa_hdmi_open,
+ .close = snd_u8500_alsa_hdmi_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_u8500_alsa_hdmi_hw_params,
+ .hw_free = snd_u8500_alsa_hdmi_hw_free,
+ .prepare = snd_u8500_alsa_hdmi_prepare,
+ .trigger = snd_u8500_alsa_hdmi_trigger,
+ .pointer = snd_u8500_alsa_hdmi_pointer,
+};
+
+/* Hardware description , this structure (struct snd_pcm_hardware )
+ * contains the definitions of the fundamental hardware configuration.
+ * This configuration will be applied on the runtime structure
+ */
+static struct snd_pcm_hardware snd_u8500_hdmi_playback_hw = {
+ .info =
+ (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE),
+ .formats =
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = MIN_RATE_PLAYBACK,
+ .rate_max = MAX_RATE_PLAYBACK,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = NMDK_BUFFER_SIZE,
+ .period_bytes_min = 128,
+ .period_bytes_max = PAGE_SIZE,
+ .periods_min = NMDK_BUFFER_SIZE / PAGE_SIZE,
+ .periods_max = NMDK_BUFFER_SIZE / 128
+};
+
+static struct snd_pcm_hardware snd_u8500_hdmi_capture_hw = {
+ .info =
+ (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE),
+ .formats =
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = MIN_RATE_CAPTURE,
+ .rate_max = MAX_RATE_CAPTURE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = NMDK_BUFFER_SIZE,
+ .period_bytes_min = 128,
+ .period_bytes_max = PAGE_SIZE,
+ .periods_min = NMDK_BUFFER_SIZE / PAGE_SIZE,
+ .periods_max = NMDK_BUFFER_SIZE / 128
+};
+
+static struct snd_pcm_hw_constraint_list constraints_hdmi_rate = {
+ .count = sizeof(u8500_hdmi_rates) / sizeof(u8500_hdmi_rates[0]),
+ .list = u8500_hdmi_rates,
+ .mask = 0,
+};
+
+/**
+ * snd_card_u8500_alsa_hdmi_new - constructor for a new pcm cmponent
+ * @chip - pointer to chip specific data
+ * @device - specifies the card number
+ */
+int snd_card_u8500_alsa_hdmi_new(u8500_acodec_chip_t * chip, int device)
+{
+ struct snd_pcm *pcm;
+ int err;
+
+ if ((err =
+ snd_pcm_new(chip->card, "u8500_hdmi", device, 1, 1, &pcm)) < 0) {
+ stm_error(" : error in snd_pcm_new\n");
+ return err;
+ }
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_u8500_alsa_hdmi_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_u8500_alsa_hdmi_capture_ops);
+
+ pcm->private_data = chip;
+ pcm->info_flags = 0;
+ chip->pcm_hdmi = pcm;
+ strcpy(pcm->name, "u8500_alsa_hdmi");
+
+ u8500_audio_hdmi_init(pcm->private_data);
+ return 0;
+}
+
+/**
+* u8500_audio_hdmi_init
+* @chip - pointer to u8500_acodec_chip_t structure.
+*
+* This function intialises the u8500 chip structure with default values
+*/
+static void u8500_audio_hdmi_init(u8500_acodec_chip_t * chip)
+{
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ ptr_audio_stream =
+ &chip->stream[ALSA_HDMI_DEV][SNDRV_PCM_STREAM_PLAYBACK];
+ /* Setup DMA stuff */
+
+ strlcpy(ptr_audio_stream->id, "u8500 hdmi playback",
+ sizeof(ptr_audio_stream->id));
+
+ ptr_audio_stream->stream_id = SNDRV_PCM_STREAM_PLAYBACK;
+
+ /* default initialization for playback */
+ ptr_audio_stream->active = 0;
+ ptr_audio_stream->period = 0;
+ ptr_audio_stream->periods = 0;
+ ptr_audio_stream->old_offset = 0;
+
+ ptr_audio_stream =
+ &chip->stream[ALSA_HDMI_DEV][SNDRV_PCM_STREAM_CAPTURE];
+
+ strlcpy(ptr_audio_stream->id, "u8500 hdmi capture",
+ sizeof(ptr_audio_stream->id));
+
+ ptr_audio_stream->stream_id = SNDRV_PCM_STREAM_CAPTURE;
+
+ /* default initialization for capture */
+ ptr_audio_stream->active = 0;
+ ptr_audio_stream->period = 0;
+ ptr_audio_stream->periods = 0;
+ ptr_audio_stream->old_offset = 0;
+
+}
+
+/**
+ * snd_u8500_alsa_hdmi_open
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This routine is used by alsa framework to open a pcm stream .
+ * Here a dma pipe is requested and device is configured(default).
+ */
+static int snd_u8500_alsa_hdmi_open(struct snd_pcm_substream *substream)
+{
+ int error = 0, stream_id, status = 0;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ stream_id = substream->pstr->stream;
+ error = u8500_acodec_setuser(USER_ALSA);
+ status = u8500_acodec_open(I2S_CLIENT_MSP2, stream_id);
+ if (status) {
+ printk("failed in getting open\n");
+ return (-1);
+ }
+
+ error = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_hdmi_rate);
+ if (error < 0) {
+ stm_error
+ (": error initializing hdmi hw sample rate constraint\n");
+ return error;
+ }
+
+ if ((error = configure_hdmi_rate(substream)))
+ return error;
+
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
+ runtime->hw = snd_u8500_hdmi_playback_hw;
+ } else {
+ runtime->hw = snd_u8500_hdmi_capture_hw;
+ }
+
+ ptr_audio_stream = &chip->stream[ALSA_HDMI_DEV][stream_id];
+
+ ptr_audio_stream->substream = substream;
+
+ stm_config_hw(chip, substream, ALSA_HDMI_DEV, stream_id);
+ sema_init(&(ptr_audio_stream->alsa_sem), 1);
+ init_completion(&(ptr_audio_stream->alsa_com));
+
+ ptr_audio_stream->state = ALSA_STATE_UNPAUSE;
+ return 0;
+}
+
+/**
+ * snd_u8500_alsa_hdmi_close
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This routine is used by alsa framework to close a pcm stream .
+ * Here a dma pipe is disabled and freed.
+ */
+
+static int snd_u8500_alsa_hdmi_close(struct snd_pcm_substream *substream)
+{
+ int stream_id, error = 0;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ audio_stream_t *ptr_audio_stream = NULL;
+
+ stream_id = substream->pstr->stream;
+ ptr_audio_stream = &chip->stream[ALSA_HDMI_DEV][stream_id];
+
+ stm_close_alsa(chip, ALSA_HDMI_DEV, stream_id);
+
+ /* reset the different variables to default */
+
+ ptr_audio_stream->active = 0;
+ ptr_audio_stream->period = 0;
+ ptr_audio_stream->periods = 0;
+ ptr_audio_stream->old_offset = 0;
+ ptr_audio_stream->substream = NULL;
+
+ /* Disable the MSP2 */
+ error = u8500_acodec_unsetuser(USER_ALSA);
+ u8500_acodec_close(I2S_CLIENT_MSP2, ACODEC_DISABLE_ALL);
+
+ return error;
+
+}
+
+/**
+ * snd_u8500_alsa_hdmi_hw_params
+ * @substream - pointer to the playback/capture substream structure
+ * @hw_params - specifies the hw parameters like format/no of channels etc
+ *
+ * This routine is used by alsa framework to allocate a dma buffer
+ * used to transfer the data from user space to kernel space
+ *
+ */
+static int snd_u8500_alsa_hdmi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+}
+
+/**
+ * snd_u8500_alsa_hdmi_hw_free
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This routine is used by alsa framework to deallocate a dma buffer
+ * allocated berfore by snd_u8500_alsa_pcm_hw_params
+ */
+static int snd_u8500_alsa_hdmi_hw_free(struct snd_pcm_substream *substream)
+{
+ stm_hw_free(substream);
+ return 0;
+}
+
+/**
+ * snd_u8500_alsa_hdmi_pointer
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This callback is called whene the pcm middle layer inquires the current
+ * hardware position on the buffer .The position is returned in frames
+ * ranged from 0 to buffer_size -1
+ */
+static snd_pcm_uframes_t snd_u8500_alsa_hdmi_pointer(struct snd_pcm_substream
+ *substream)
+{
+ unsigned int offset;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ audio_stream_t *stream =
+ &chip->stream[ALSA_HDMI_DEV][substream->pstr->stream];
+ struct snd_pcm_runtime *runtime = stream->substream->runtime;
+
+ offset = bytes_to_frames(runtime, stream->old_offset);
+ if (offset < 0 || stream->old_offset < 0)
+ stm_dbg(DBG_ST.alsa, " Offset=%i %i\n", offset,
+ stream->old_offset);
+
+ return offset;
+}
+
+/**
+ * snd_u8500_alsa_hdmi_prepare
+ * @substream - pointer to the playback/capture substream structure
+ *
+ * This callback is called whene the pcm is "prepared" Here is possible
+ * to set the format type ,sample rate ,etc.The callback is called as
+ * well everytime a recovery after an underrun happens.
+ */
+
+static int snd_u8500_alsa_hdmi_prepare(struct snd_pcm_substream *substream)
+{
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int error;
+
+ if (chip->hdmi_params.sampling_freq != runtime->rate
+ || chip->hdmi_params.channel_count != runtime->channels) {
+ stm_dbg(DBG_ST.alsa, " freq not same, %d %d\n",
+ chip->hdmi_params.sampling_freq, runtime->rate);
+ stm_dbg(DBG_ST.alsa, " channels not same, %d %d\n",
+ chip->hdmi_params.channel_count, runtime->channels);
+ if (chip->hdmi_params.channel_count != runtime->channels) {
+ chip->hdmi_params.channel_count = runtime->channels;
+ if ((error =
+ stm_config_hw(chip, substream, ALSA_HDMI_DEV,
+ -1))) {
+ stm_dbg(DBG_ST.alsa,
+ "In func %s, stm_config_hw fails",
+ __FUNCTION__);
+ return error;
+ }
+ }
+ chip->hdmi_params.sampling_freq = runtime->rate;
+ if ((error = configure_hdmi_rate(substream))) {
+ stm_dbg(DBG_ST.alsa, "In func %s, configure_rate fails",
+ __FUNCTION__);
+ return error;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * snd_u8500_alsa_hdmi_trigger
+ * @substream - pointer to the playback/capture substream structure
+ * @cmd - specifies the command : start/stop/pause/resume
+ *
+ * This callback is called whene the pcm is started ,stopped or paused
+ * The action is specified in the second argument, SND_PCM_TRIGGER_XXX in
+ * <sound/pcm.h>.
+ * This callback is atomic and the interrupts are disabled , so you can't
+ * call other functions that need interrupts without possible risks
+ */
+static int snd_u8500_alsa_hdmi_trigger(struct snd_pcm_substream *substream,
+ int cmd)
+{
+ int stream_id = substream->pstr->stream;
+ audio_stream_t *stream = NULL;
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+ int error = 0;
+
+ stream = &chip->stream[ALSA_HDMI_DEV][stream_id];
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ /* Start the pcm engine */
+ stm_dbg(DBG_ST.alsa, " TRIGGER START\n");
+ if (stream->active == 0) {
+ stream->active = 1;
+ stm_trigger_hdmi(stream);
+ break;
+ }
+ stm_error(": H/w is busy\n");
+ return -EINVAL;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ stm_dbg(DBG_ST.alsa, " SNDRV_PCM_TRIGGER_PAUSE_PUSH\n");
+ if (stream->active == 1) {
+ stm_pause_hdmi(stream);
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ stm_dbg(DBG_ST.alsa, " SNDRV_PCM_TRIGGER_PAUSE_RELEASE\n");
+ if (stream->active == 1)
+ stm_unpause_hdmi(stream);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ /* Stop the pcm engine */
+ stm_dbg(DBG_ST.alsa, " TRIGGER STOP\n");
+ if (stream->active == 1)
+ stm_stop_hdmi(stream);
+ break;
+ default:
+ stm_error(": invalid command in pcm trigger\n");
+ return -EINVAL;
+ }
+
+ return error;
+
+}
+
+struct snd_kcontrol_new u8500_hdmi_power_ctrl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .device = 1,
+ .subdevice = 0,
+ .name = "HDMI Power",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = 0xfff,
+ .info = u8500_hdmi_power_ctrl_info,
+ .get = u8500_hdmi_power_ctrl_get,
+ .put = u8500_hdmi_power_ctrl_put
+};
+
+/**
+* u8500_hdmi_power_ctrl_info
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions fills playback device info into user structure.
+*/
+static int u8500_hdmi_power_ctrl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->value.enumerated.items = NUMBER_POWER_STATE;
+ uinfo->count = 1;
+ if (uinfo->value.enumerated.item >= NUMBER_POWER_STATE)
+ uinfo->value.enumerated.item = NUMBER_POWER_STATE - 1;
+ strcpy(uinfo->value.enumerated.name,
+ power_state_in_texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+/**
+* u8500_hdmi_power_ctrl_get
+* @kcontrol - pointer to the snd_kcontrol structure
+* @uinfo - pointer to the snd_ctl_elem_info structure, this is filled by the function
+*
+* This functions returns the current playback device selected.
+*/
+static int u8500_hdmi_power_ctrl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ uinfo->value.enumerated.item[0] = 0;
+ return 0;
+}
+
+/**
+* u8500_hdmi_power_ctrl_put
+* @kcontrol - pointer to the snd_kcontrol structure
+* @ .
+*
+* This functions sets the playback device.
+*/
+static int u8500_hdmi_power_ctrl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uinfo)
+{
+ u8500_acodec_chip_t *chip =
+ (u8500_acodec_chip_t *) snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+ t_ab8500_codec_error error;
+ t_u8500_bool_state power_state;
+
+ power_state = uinfo->value.enumerated.item[0];
+
+ changed = 1;
+
+ return changed;
+}
+
+int u8500_register_alsa_hdmi_controls(struct snd_card *card,
+ u8500_acodec_chip_t * u8500_chip)
+{
+ int error;
+
+ if ((error =
+ snd_ctl_add(card,
+ snd_ctl_new1(&u8500_hdmi_power_ctrl,
+ u8500_chip))) < 0) {
+ stm_error
+ (": error initializing u8500_hdmi_power_ctrl interface \n\n");
+ return (-1);
+ }
+
+ return 0;
+}
+
+/**
+* configure_hdmi_rate
+* @substream - pointer to the playback/capture substream structure
+*
+* This functions configures audio codec in to stream frequency frequency
+*/
+static int configure_hdmi_rate(struct snd_pcm_substream *substream)
+{
+ t_hdmi_sample_freq hdmi_sampling_freq;
+
+ u8500_acodec_chip_t *chip = snd_pcm_substream_chip(substream);
+
+ switch (chip->hdmi_params.sampling_freq) {
+ case 32000:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_32KHZ;
+ break;
+ case 44100:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_44_1KHZ;
+ break;
+ case 48000:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_48KHZ;
+ break;
+ case 64000:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_64KHZ;
+ break;
+ case 88200:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_88_2KHZ;
+ break;
+ case 96000:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_96KHZ;
+ break;
+ case 128000:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_128KHZ;
+ break;
+ case 176100:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_176_1KHZ;
+ break;
+ case 192000:
+ hdmi_sampling_freq = HDMI_SAMPLING_FREQ_192KHZ;
+ default:
+ stm_error("not supported frequnecy\n");
+ return -EINVAL;
+ }
+
+ configure_msp_hdmi(hdmi_sampling_freq, chip->hdmi_params.channel_count);
+
+ return 0;
+
+}
+
+static int configure_msp_hdmi(int sampling_freq, int channel_count)
+{
+ struct i2s_device *i2s_dev = i2sdrv[I2S_CLIENT_MSP2]->i2s;
+ struct msp_config msp_config;
+ t_ab8500_codec_error error_status = AB8500_CODEC_OK;
+
+ memset(&msp_config, 0, sizeof(msp_config));
+
+
+ if (i2sdrv[I2S_CLIENT_MSP2]->flag) {
+ stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
+ return -1;
+ }
+
+ /* MSP configuration */
+
+ msp_config.tx_clock_sel = 0;
+ msp_config.rx_clock_sel = 0;
+
+ msp_config.tx_frame_sync_sel = 0;
+ msp_config.rx_frame_sync_sel = 0;
+
+ msp_config.input_clock_freq = MSP_INPUT_FREQ_48MHZ;
+ msp_config.srg_clock_sel = 0;
+
+ msp_config.rx_frame_sync_pol = RX_FIFO_SYNC_HI;
+ msp_config.tx_frame_sync_pol = TX_FIFO_SYNC_HI;
+
+ msp_config.rx_fifo_config = 0;
+ msp_config.tx_fifo_config = TX_FIFO_ENABLE;
+
+ msp_config.spi_clk_mode = SPI_CLK_MODE_NORMAL;
+ msp_config.spi_burst_mode = 0;
+ msp_config.tx_data_enable = 0;
+ msp_config.loopback_enable = 0;
+ msp_config.default_protocol_desc = 1;
+ msp_config.direction = MSP_TRANSMIT_MODE;
+ msp_config.protocol = MSP_I2S_PROTOCOL;
+ msp_config.frame_size = ELEMENT_SIZE;
+ msp_config.frame_freq = sampling_freq;
+ msp_config.def_elem_len = 0;
+ /* enable msp for both tr and rx mode with dma data transfer.
+ THIS IS NOW DONE SEPARATELY from SAA. */
+ msp_config.data_size = MSP_DATA_SIZE_16BIT;
+
+#ifdef CONFIG_U8500_ACODEC_DMA
+ msp_config.work_mode = MSP_DMA_MODE;
+#elif defined(CONFIG_U8500_ACODEC_POLL)
+ msp_config.work_mode = MSP_POLLING_MODE;
+#else
+ msp_config.work_mode = MSP_INTERRUPT_MODE;
+#endif
+ msp_config.default_protocol_desc = 0;
+
+ msp_config.protocol_desc.rx_phase_mode = MSP_DUAL_PHASE;
+ msp_config.protocol_desc.tx_phase_mode = MSP_DUAL_PHASE;
+ msp_config.protocol_desc.rx_phase2_start_mode =
+ MSP_PHASE2_START_MODE_FRAME_SYNC;
+ msp_config.protocol_desc.tx_phase2_start_mode =
+ MSP_PHASE2_START_MODE_FRAME_SYNC;
+ msp_config.protocol_desc.rx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+ msp_config.protocol_desc.tx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+ msp_config.protocol_desc.rx_frame_length_1 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.rx_frame_length_2 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.tx_frame_length_1 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.tx_frame_length_2 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.rx_element_length_1 = MSP_ELEM_LENGTH_16;
+ msp_config.protocol_desc.rx_element_length_2 = MSP_ELEM_LENGTH_16;
+ msp_config.protocol_desc.tx_element_length_1 = MSP_ELEM_LENGTH_16;
+ msp_config.protocol_desc.tx_element_length_2 = MSP_ELEM_LENGTH_16;
+ msp_config.protocol_desc.rx_data_delay = MSP_DELAY_1;
+ msp_config.protocol_desc.tx_data_delay = MSP_DELAY_1;
+ msp_config.protocol_desc.rx_clock_pol = MSP_RISING_EDGE;
+ msp_config.protocol_desc.tx_clock_pol = 0;
+ msp_config.protocol_desc.rx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH;
+ msp_config.protocol_desc.tx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH;
+ msp_config.protocol_desc.rx_half_word_swap = MSP_HWS_NO_SWAP;
+ msp_config.protocol_desc.tx_half_word_swap = MSP_HWS_NO_SWAP;
+ msp_config.protocol_desc.compression_mode = MSP_COMPRESS_MODE_LINEAR;
+ msp_config.protocol_desc.expansion_mode = MSP_EXPAND_MODE_LINEAR;
+ msp_config.protocol_desc.spi_clk_mode = MSP_SPI_CLOCK_MODE_NON_SPI;
+ msp_config.protocol_desc.spi_burst_mode = MSP_SPI_BURST_MODE_DISABLE;
+ msp_config.protocol_desc.frame_period = 63;
+ msp_config.protocol_desc.frame_width = 31;
+ msp_config.protocol_desc.total_clocks_for_one_frame = 64;
+ msp_config.multichannel_configured = 0;
+ msp_config.multichannel_config.tx_multichannel_enable = 0;
+ /* Channel 1 and channel 3 */
+ msp_config.multichannel_config.tx_channel_0_enable = 0x0000005;
+ msp_config.multichannel_config.tx_channel_1_enable = 0x0000000;
+ msp_config.multichannel_config.tx_channel_2_enable = 0x0000000;
+ msp_config.multichannel_config.tx_channel_3_enable = 0x0000000;
+ error_status = i2s_setup(i2s_dev->controller, &msp_config);
+
+#ifdef CONFIG_DEBUG
+ {
+ dump_msp2_registers();
+ }
+#endif
+
+ if (error_status < 0) {
+ printk("error in msp enable, error_status is %d\n",
+ error_status);
+ return error_status;
+ }
+
+ return 0;
+
+}
+
+#ifdef CONFIG_U8500_ACODEC_DMA
+/**
+ * u8500_alsa_hdmi_dma_start - used to transmit or recive a dma chunk
+ * @stream - specifies the playback/record stream structure
+ */
+static void u8500_alsa_hdmi_dma_start(audio_stream_t * stream)
+{
+ unsigned int offset, dma_size, stream_id;
+
+ struct snd_pcm_substream *substream = stream->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ stream_id = substream->pstr->stream;
+
+ dma_size = frames_to_bytes(runtime, runtime->period_size);
+ offset = dma_size * stream->period;
+ stream->old_offset = offset;
+
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_send_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_send_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+ else
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_receive_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_receive_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+
+ stm_dbg(DBG_ST.alsa, " DMA Transfer started\n");
+ stm_dbg(DBG_ST.alsa, " address = %x size=%d\n",
+ (runtime->dma_addr + offset), dma_size);
+
+ stream->period++;
+ stream->period %= runtime->periods;
+ stream->periods++;
+
+
+}
+
+#else
+
+/**
+* acodec_feeding_thread
+* @stream - pointer to the playback/capture audio_stream_t structure
+*
+* This function creates a kernel thread .
+*/
+
+static int spawn_hdmi_feeding_thread(audio_stream_t * stream)
+{
+ pid_t pid;
+
+ pid =
+ kernel_thread(hdmi_feeding_thread, stream,
+ CLONE_FS | CLONE_SIGHAND);
+
+ return 0;
+}
+
+/**
+* hdmi_feeding_thread
+* @data - void pointer to the playback/capture audio_stream_t structure
+*
+* This thread sends/receive data to MSP while stream is active
+*/
+static int hdmi_feeding_thread(void *data)
+{
+ audio_stream_t *stream = (audio_stream_t *) data;
+
+ daemonize("hdmi_feeding_thread");
+ allow_signal(SIGKILL);
+ down(&stream->alsa_sem);
+
+ while ((!signal_pending(current)) && (stream->active)) {
+ if (stream->state == ALSA_STATE_PAUSE)
+ wait_for_completion(&(stream->alsa_com));
+
+ u8500_hdmi_pio_start(stream);
+ if (stream->substream)
+ snd_pcm_period_elapsed(stream->substream);
+ }
+
+ up(&stream->alsa_sem);
+
+ return 0;
+}
+
+/**
+* u8500_hdmi_pio_start
+* @stream - pointer to the playback/capture audio_stream_t structure
+*
+* This function sends/receive one chunck of stream data to/from MSP
+*/
+static void u8500_hdmi_pio_start(audio_stream_t * stream)
+{
+ unsigned int offset, dma_size, stream_id;
+ struct snd_pcm_substream *substream = stream->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ stream_id = substream->pstr->stream;
+
+ dma_size = frames_to_bytes(runtime, runtime->period_size);
+ offset = dma_size * stream->period;
+ stream->old_offset = offset;
+
+ stm_dbg(DBG_ST.alsa, " Transfer started\n");
+ stm_dbg(DBG_ST.alsa, " address = %x size=%d\n",
+ (runtime->dma_addr + offset), dma_size);
+
+ /* Send our stuff */
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_send_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_send_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+ else
+#ifdef CONFIG_U8500_ACODEC_DMA
+ u8500_acodec_receive_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_addr + offset),
+ dma_size, 1);
+#else
+ u8500_acodec_receive_data(I2S_CLIENT_MSP2,
+ (void *)(runtime->dma_area + offset),
+ dma_size, 0);
+#endif
+
+ stream->period++;
+ stream->period %= runtime->periods;
+ stream->periods++;
+}
+#endif
+
+void dump_msp2_registers()
+{
+ int i;
+
+ stm_dbg(DBG_ST.acodec, "\nMSP_2 base add = 0x%x\n",
+ (unsigned int)U8500_MSP2_BASE);
+
+ for (i = 0; i < 0x40; i += 4)
+ stm_dbg(DBG_ST.acodec, "msp[0x%x]=0x%x\n", i,
+ readl((char *)(IO_ADDRESS(U8500_MSP2_BASE) + i)));
+
+ return 0;
+}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b48fb43b544..d2c82caa6cc 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -19491,6 +19491,10 @@ static const struct alc_fixup alc662_fixups[] = {
.type = ALC_FIXUP_SKU,
.v.sku = ALC_FIXUP_SKU_IGNORE,
},
+ [ALC662_FIXUP_SKU_IGNORE] = {
+ .type = ALC_FIXUP_SKU,
+ .v.sku = ALC_FIXUP_SKU_IGNORE,
+ },
};
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 8224db5f043..adcbc43276d 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -11,7 +11,7 @@ menuconfig SND_SOC
If you want ASoC support, you should say Y here and also to the
specific driver for your SoC platform below.
-
+
ASoC provides power efficient ALSA support for embedded battery powered
SoC based systems like PDA's, Phones and Personal Media Players.
@@ -57,6 +57,7 @@ source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
source "sound/soc/tegra/Kconfig"
source "sound/soc/txx9/Kconfig"
+source "sound/soc/ux500/Kconfig"
# Supported codecs
source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 1ed61c5df2c..79a9e203e94 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += tegra/
obj-$(CONFIG_SND_SOC) += txx9/
+obj-$(CONFIG_SND_SOC) += ux500/
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 98175a096df..4ac475d51bd 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -96,7 +96,12 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
select SND_SOC_WM9713 if SND_SOC_AC97_BUS
- help
+ select SND_SOC_AB3550
+ select SND_SOC_AB5500
+ select SND_SOC_AB8500
+ select SND_SOC_CG29XX
+ select SND_SOC_AV8100
+ help
Normally ASoC codec drivers are only built if a machine driver which
uses them is also built since they are only usable with a machine
driver. Selecting this option will allow these drivers to be built
@@ -371,6 +376,21 @@ config SND_SOC_WM9712
config SND_SOC_WM9713
tristate
+config SND_SOC_AB3550
+ tristate
+
+config SND_SOC_AB5500
+ tristate
+
+config SND_SOC_AB8500
+ tristate
+
+config SND_SOC_CG29XX
+ tristate
+
+config SND_SOC_AV8100
+ tristate
+
# Amp
config SND_SOC_LM4857
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fd8558406ef..a8e4d5c6cde 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,4 +1,7 @@
snd-soc-88pm860x-objs := 88pm860x-codec.o
+snd-soc-ab3550-objs := ab3550.o
+snd-soc-ab5500-objs := ab5500.o
+snd-soc-ab8500_audio-objs := ab8500_audio.o
snd-soc-ac97-objs := ac97.o
snd-soc-ad1836-objs := ad1836.o
snd-soc-ad193x-objs := ad193x.o
@@ -10,6 +13,8 @@ snd-soc-ak4535-objs := ak4535.o
snd-soc-ak4641-objs := ak4641.o
snd-soc-ak4642-objs := ak4642.o
snd-soc-ak4671-objs := ak4671.o
+snd-soc-av8100_audio-objs := av8100_audio.o
+snd-soc-cg29xx-objs := cg29xx.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs42l51-objs := cs42l51.o
snd-soc-cs4270-objs := cs4270.o
@@ -89,6 +94,9 @@ snd-soc-tpa6130a2-objs := tpa6130a2.o
snd-soc-wm2000-objs := wm2000.o
snd-soc-wm9090-objs := wm9090.o
+obj-$(CONFIG_SND_SOC_AB3550) += snd-soc-ab3550.o
+obj-$(CONFIG_SND_SOC_AB5500) += snd-soc-ab5500.o
+obj-$(CONFIG_SND_SOC_AB8500) += snd-soc-ab8500_audio.o
obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
@@ -102,6 +110,8 @@ obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
+obj-$(CONFIG_SND_SOC_AV8100) += snd-soc-av8100_audio.o
+obj-$(CONFIG_SND_SOC_CG29XX) += snd-soc-cg29xx.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
@@ -178,4 +188,9 @@ obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
-obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
+ifdef CONFIG_SND_SOC_UX500_DEBUG
+CFLAGS_av8100_audio.o := -DDEBUG
+CFLAGS_ab3550.o := -DDEBUG
+CFLAGS_cg29xx.o := -DDEBUG
+CFLAGS_ab8500_audio.o := -DDEBUG
+endif
diff --git a/sound/soc/codecs/ab3550.c b/sound/soc/codecs/ab3550.c
new file mode 100644
index 00000000000..4a15ab64d32
--- /dev/null
+++ b/sound/soc/codecs/ab3550.c
@@ -0,0 +1,1429 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Xie Xiaolei <xie.xiaolei@etericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
+ * Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/mfd/abx500.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <asm/atomic.h>
+#include <linux/rwsem.h>
+#include <linux/mutex.h>
+#include <stdarg.h>
+#include "ab3550.h"
+
+
+#define I2C_BANK 0
+
+/* codec private data */
+struct ab3550_codec_dai_data {
+};
+
+static struct device *ab3550_dev;
+
+static u8 virtual_regs[] = {
+ 0, 0
+};
+
+static void set_reg(u8 reg, u8 val)
+{
+ if (!ab3550_dev) {
+ pr_err("%s: The AB3550 codec driver not initialized.\n",
+ __func__);
+ return;
+ }
+ if (reg < AB3550_FIRST_REG)
+ return;
+ else if (reg <= AB3550_LAST_REG) {
+ abx500_set_register_interruptible(
+ ab3550_dev, I2C_BANK, reg, val);
+ } else if (reg - AB3550_LAST_REG - 1 < ARRAY_SIZE(virtual_regs)) {
+ virtual_regs[reg - AB3550_LAST_REG - 1] = val;
+ }
+}
+
+static void mask_set_reg(u8 reg, u8 mask, u8 val)
+{
+ if (!ab3550_dev) {
+ pr_err("%s: The AB3550 codec driver not initialized.\n",
+ __func__);
+ return;
+ }
+ if (reg < AB3550_FIRST_REG)
+ return;
+ else if (reg <= AB3550_LAST_REG) {
+ abx500_mask_and_set_register_interruptible(
+ ab3550_dev, I2C_BANK, reg, mask, val);
+ } else if (reg - AB3550_LAST_REG - 1 < ARRAY_SIZE(virtual_regs)) {
+ virtual_regs[reg - AB3550_LAST_REG - 1] &= ~mask;
+ virtual_regs[reg - AB3550_LAST_REG - 1] |= val & mask;
+ }
+}
+
+static u8 read_reg(u8 reg)
+{
+ if (!ab3550_dev) {
+ pr_err("%s: The AB3550 codec driver not initialized.\n",
+ __func__);
+ return 0;
+ }
+ if (reg < AB3550_FIRST_REG)
+ return 0;
+ else if (reg <= AB3550_LAST_REG) {
+ u8 val;
+ abx500_get_register_interruptible(
+ ab3550_dev, I2C_BANK, reg, &val);
+ return val;
+ } else if (reg - AB3550_LAST_REG - 1 < ARRAY_SIZE(virtual_regs))
+ return virtual_regs[reg - AB3550_LAST_REG - 1];
+ dev_warn(ab3550_dev, "%s: out-of-scope reigster %u.\n",
+ __func__, reg);
+ return 0;
+}
+
+/* Components that can be powered up/down */
+enum enum_widget {
+ widget_ear = 0,
+ widget_auxo1,
+ widget_auxo2,
+
+ widget_spkr,
+ widget_line1,
+ widget_line2,
+
+ widget_dac1,
+ widget_dac2,
+ widget_dac3,
+
+ widget_rx1,
+ widget_rx2,
+ widget_rx3,
+
+ widget_mic1,
+ widget_mic2,
+
+ widget_micbias1,
+ widget_micbias2,
+
+ widget_apga1,
+ widget_apga2,
+
+ widget_tx1,
+ widget_tx2,
+
+ widget_adc1,
+ widget_adc2,
+
+ widget_if0_dld_l,
+ widget_if0_dld_r,
+ widget_if0_uld_l,
+ widget_if0_uld_r,
+ widget_if1_dld_l,
+ widget_if1_dld_r,
+ widget_if1_uld_l,
+ widget_if1_uld_r,
+
+ widget_mic1p1,
+ widget_mic1n1,
+ widget_mic1p2,
+ widget_mic1n2,
+
+ widget_mic2p1,
+ widget_mic2n1,
+ widget_mic2p2,
+ widget_mic2n2,
+
+ widget_clock,
+
+ number_of_widgets
+};
+
+/* This is only meant for debugging */
+static const char *widget_names[] = {
+ "EAR", "AUXO1", "AUXO2", "SPKR", "LINE1", "LINE2",
+ "DAC1", "DAC2", "DAC3",
+ "RX1", "RX2", "RX3",
+ "MIC1", "MIC2",
+ "MIC-BIAS1", "MIC-BIAS2",
+ "APGA1", "APGA2",
+ "TX1", "TX2",
+ "ADC1", "ADC2",
+ "IF0-DLD-L", "IF0-DLD-R", "IF0-ULD-L", "IF0-ULD-R",
+ "IF1-DLD-L", "IF1-DLD-R", "IF1-ULD-L", "IF1-ULD-R",
+ "MIC1P1", "MIC1N1", "MIC1P2", "MIC1N2",
+ "MIC2P1", "MIC2N1", "MIC2P2", "MIC2N2",
+ "CLOCK"
+};
+
+struct widget_pm {
+ enum enum_widget widget;
+ u8 reg;
+ u8 shift;
+
+ unsigned long source_list[BIT_WORD(number_of_widgets) + 1];
+ unsigned long sink_list[BIT_WORD(number_of_widgets) + 1];
+};
+
+static struct widget_pm widget_pm_array[] = {
+ {.widget = widget_ear, .reg = EAR, .shift = EAR_PWR_SHIFT},
+ {.widget = widget_auxo1, .reg = AUXO1, .shift = AUXOx_PWR_SHIFT},
+ {.widget = widget_auxo2, .reg = AUXO2, .shift = AUXOx_PWR_SHIFT},
+ {.widget = widget_spkr, .reg = SPKR, .shift = SPKR_PWR_SHIFT},
+ {.widget = widget_line1, .reg = LINE1, .shift = LINEx_PWR_SHIFT},
+ {.widget = widget_line2, .reg = LINE2, .shift = LINEx_PWR_SHIFT},
+
+ {.widget = widget_dac1, .reg = RX1, .shift = DACx_PWR_SHIFT},
+ {.widget = widget_dac2, .reg = RX2, .shift = DACx_PWR_SHIFT},
+ {.widget = widget_dac3, .reg = RX3, .shift = DACx_PWR_SHIFT},
+
+ {.widget = widget_rx1, .reg = RX1, .shift = RXx_PWR_SHIFT},
+ {.widget = widget_rx2, .reg = RX2, .shift = RXx_PWR_SHIFT},
+ {.widget = widget_rx3, .reg = RX3, .shift = RXx_PWR_SHIFT},
+
+ {.widget = widget_mic1, .reg = MIC1_GAIN, .shift = MICx_PWR_SHIFT},
+ {.widget = widget_mic2, .reg = MIC2_GAIN, .shift = MICx_PWR_SHIFT},
+
+ {.widget = widget_micbias1, .reg = MIC_BIAS1,
+ .shift = MBIAS_PWR_SHIFT},
+ {.widget = widget_micbias2, .reg = MIC_BIAS2,
+ .shift = MBIAS_PWR_SHIFT},
+
+ {.widget = widget_apga1, .reg = ANALOG_LOOP_PGA1,
+ .shift = APGAx_PWR_SHIFT},
+ {.widget = widget_apga2, .reg = ANALOG_LOOP_PGA2,
+ .shift = APGAx_PWR_SHIFT},
+
+ {.widget = widget_tx1, .reg = TX1, .shift = TXx_PWR_SHIFT},
+ {.widget = widget_tx2, .reg = TX2, .shift = TXx_PWR_SHIFT},
+
+ {.widget = widget_adc1, .reg = TX1, .shift = ADCx_PWR_SHIFT},
+ {.widget = widget_adc2, .reg = TX2, .shift = ADCx_PWR_SHIFT},
+
+ {.widget = widget_if0_dld_l, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF0_DLD_L_PW_SHIFT},
+ {.widget = widget_if0_dld_r, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF0_DLD_R_PW_SHIFT},
+ {.widget = widget_if0_uld_l, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF0_ULD_L_PW_SHIFT},
+ {.widget = widget_if0_uld_r, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF0_ULD_R_PW_SHIFT},
+
+ {.widget = widget_if1_dld_l, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF1_DLD_L_PW_SHIFT},
+ {.widget = widget_if1_dld_r, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF1_DLD_R_PW_SHIFT},
+ {.widget = widget_if1_uld_l, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF1_ULD_L_PW_SHIFT},
+ {.widget = widget_if1_uld_r, .reg = AB3550_VIRTUAL_REG1,
+ .shift = IF1_ULD_R_PW_SHIFT},
+
+ {.widget = widget_mic1p1, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC1P1_PW_SHIFT},
+ {.widget = widget_mic1n1, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC1N1_PW_SHIFT},
+ {.widget = widget_mic1p2, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC1P2_PW_SHIFT},
+ {.widget = widget_mic1n2, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC1N2_PW_SHIFT},
+
+ {.widget = widget_mic2p1, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC2P1_PW_SHIFT},
+ {.widget = widget_mic2n1, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC2N1_PW_SHIFT},
+ {.widget = widget_mic2p2, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC2P2_PW_SHIFT},
+ {.widget = widget_mic2n2, .reg = AB3550_VIRTUAL_REG2,
+ .shift = MIC2N2_PW_SHIFT},
+
+ {.widget = widget_clock, .reg = CLOCK, .shift = CLOCK_ENABLE_SHIFT},
+};
+
+DEFINE_MUTEX(ab3550_pm_mutex);
+
+static struct {
+ enum enum_widget stack[number_of_widgets];
+ int p;
+} pm_stack;
+
+struct ab3550_dai_private {
+ unsigned int fmt;
+};
+
+#define pm_stack_as_bitmap ({ \
+ unsigned long bitmap[BIT_WORD(number_of_widgets) + 1]; \
+ int i; \
+ memset(bitmap, 0, sizeof(bitmap)); \
+ for (i = 0; i < pm_stack.p; i++) { \
+ set_bit(pm_stack.stack[i], bitmap); \
+ } \
+ bitmap; \
+ })
+
+/* These are only meant to meet the obligations of DAPM */
+static const struct snd_soc_dapm_widget ab3550_dapm_widgets[] = {
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+};
+
+
+static const char *enum_rx2_select[] = {"I2S0", "I2S1"};
+static const char *enum_i2s_input_select[] = {
+ "tri-state", "MIC1", "MIC2", "mute"
+};
+static const char *enum_apga1_source[] = {"LINEIN1", "MIC1", "MIC2"};
+static const char *enum_apga2_source[] = {"LINEIN2", "MIC1", "MIC2"};
+static const char *enum_dac_side_tone[] = {"TX1", "TX2"};
+static const char *enum_dac_power_mode[] = {"100%", "75%", "55%"};
+static const char *enum_ear_power_mode[] = {"100%", "70%"};
+static const char *enum_auxo_power_mode[] = {
+ "100%", "67%", "50%", "25%", "auto"
+};
+static const char *enum_onoff[] = {"Off", "On"};
+static const char *enum_mbias_hiz_option[] = {"GND", "HiZ"};
+static const char *enum_mbias2_output_voltage[] = {"2.0v", "2.2v"};
+static const char *enum_mic_input_impedance[] = {
+ "12.5 kohm", "25 kohm", "50 kohm"
+};
+static const char *enum_hp_filter[] = {"HP3", "HP1", "bypass"};
+static const char *enum_i2s_word_length[] = {"16 bits", "24 bits"};
+static const char *enum_i2s_mode[] = {"Master Mode", "Slave Mode"};
+static const char *enum_i2s_tristate[] = {"Normal", "Tri-state"};
+static const char *enum_optional_resistor[] = {"disconnected", "connected"};
+static const char *enum_i2s_sample_rate[] = {
+ "8 kHz", "16 kHz", "44.1 kHz", "48 kHz"
+};
+static const char *enum_signal_inversion[] = {"normal", "inverted"};
+
+/* RX2 Select */
+static struct soc_enum soc_enum_rx2_select =
+ SOC_ENUM_SINGLE(RX2, 4, ARRAY_SIZE(enum_rx2_select), enum_rx2_select);
+
+/* I2S0 Input Select */
+static struct soc_enum soc_enum_i2s0_input_select =
+ SOC_ENUM_DOUBLE(INTERFACE0_DATA, 0, 2,
+ ARRAY_SIZE(enum_i2s_input_select),
+ enum_i2s_input_select);
+/* I2S1 Input Select */
+static struct soc_enum soc_enum_i2s1_input_select =
+ SOC_ENUM_DOUBLE(INTERFACE1_DATA, 0, 2,
+ ARRAY_SIZE(enum_i2s_input_select),
+ enum_i2s_input_select);
+
+/* APGA1 Source */
+static struct soc_enum soc_enum_apga1_source =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA1, APGAx_MUX_SHIFT,
+ ARRAY_SIZE(enum_apga1_source), enum_apga1_source);
+
+/* APGA2 Source */
+static struct soc_enum soc_enum_apga2_source =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA2, APGAx_MUX_SHIFT,
+ ARRAY_SIZE(enum_apga2_source), enum_apga2_source);
+
+static struct soc_enum soc_enum_apga1_enable =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA1, APGAx_PWR_SHIFT,
+ ARRAY_SIZE(enum_onoff), enum_onoff);
+
+static struct soc_enum soc_enum_apga2_enable =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA2, APGAx_PWR_SHIFT,
+ ARRAY_SIZE(enum_onoff), enum_onoff);
+
+/* DAC1 Side Tone */
+static struct soc_enum soc_enum_dac1_side_tone =
+ SOC_ENUM_SINGLE(SIDETONE1_PGA, STx_MUX_SHIFT,
+ ARRAY_SIZE(enum_dac_side_tone), enum_dac_side_tone);
+
+/* DAC2 Side Tone */
+static struct soc_enum soc_enum_dac2_side_tone =
+ SOC_ENUM_SINGLE(SIDETONE2_PGA, STx_MUX_SHIFT,
+ ARRAY_SIZE(enum_dac_side_tone), enum_dac_side_tone);
+
+/* DAC1 Power Mode */
+static struct soc_enum soc_enum_dac1_power_mode =
+ SOC_ENUM_SINGLE(RX1, DACx_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_dac_power_mode), enum_dac_power_mode);
+
+/* DAC2 Power Mode */
+static struct soc_enum soc_enum_dac2_power_mode =
+ SOC_ENUM_SINGLE(RX2, DACx_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_dac_power_mode), enum_dac_power_mode);
+
+/* DAC3 Power Mode */
+static struct soc_enum soc_enum_dac3_power_mode =
+ SOC_ENUM_SINGLE(RX3, DACx_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_dac_power_mode), enum_dac_power_mode);
+
+/* EAR Power Mode */
+static struct soc_enum soc_enum_ear_power_mode =
+ SOC_ENUM_SINGLE(EAR, EAR_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_ear_power_mode), enum_ear_power_mode);
+
+/* AUXO Power Mode */
+static struct soc_enum soc_enum_auxo_power_mode =
+ SOC_ENUM_SINGLE(AUXO_PWR_MODE, AUXO_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_auxo_power_mode),
+ enum_auxo_power_mode);
+
+/* MBIAS1 HiZ Option */
+static struct soc_enum soc_enum_mbias1_hiz_option =
+ SOC_ENUM_SINGLE(MIC_BIAS1, MBIAS_PDN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mbias_hiz_option),
+ enum_mbias_hiz_option);
+
+/* MBIAS1 HiZ Option */
+static struct soc_enum soc_enum_mbias2_hiz_option =
+ SOC_ENUM_SINGLE(MIC_BIAS2, MBIAS_PDN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mbias_hiz_option),
+ enum_mbias_hiz_option);
+
+/* MBIAS2 Output voltage */
+static struct soc_enum soc_enum_mbias2_output_voltage =
+ SOC_ENUM_SINGLE(MIC_BIAS2, MBIAS2_OUT_V_SHIFT,
+ ARRAY_SIZE(enum_mbias2_output_voltage),
+ enum_mbias2_output_voltage);
+
+static struct soc_enum soc_enum_mbias2_internal_resistor =
+ SOC_ENUM_SINGLE(MIC_BIAS2_VAD, MBIAS2_R_INT_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_mic1_input_impedance =
+ SOC_ENUM_SINGLE(MIC1_GAIN, MICx_IN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mic_input_impedance),
+ enum_mic_input_impedance);
+
+static struct soc_enum soc_enum_mic2_input_impedance =
+ SOC_ENUM_SINGLE(MIC2_GAIN, MICx_IN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mic_input_impedance),
+ enum_mic_input_impedance);
+
+static struct soc_enum soc_enum_tx1_hp_filter =
+ SOC_ENUM_SINGLE(TX1, TXx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_tx2_hp_filter =
+ SOC_ENUM_SINGLE(TX2, TXx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_st1_hp_filter =
+ SOC_ENUM_SINGLE(SIDETONE1_PGA, STx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_st2_hp_filter =
+ SOC_ENUM_SINGLE(SIDETONE2_PGA, STx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_i2s0_word_length =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_WORDLENGTH_SHIFT,
+ ARRAY_SIZE(enum_i2s_word_length),
+ enum_i2s_word_length);
+
+static struct soc_enum soc_enum_i2s1_word_length =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_WORDLENGTH_SHIFT,
+ ARRAY_SIZE(enum_i2s_word_length),
+ enum_i2s_word_length);
+
+static struct soc_enum soc_enum_i2s0_mode =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_MODE_SHIFT,
+ ARRAY_SIZE(enum_i2s_mode),
+ enum_i2s_mode);
+
+static struct soc_enum soc_enum_i2s1_mode =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_MODE_SHIFT,
+ ARRAY_SIZE(enum_i2s_mode),
+ enum_i2s_mode);
+
+static struct soc_enum soc_enum_i2s0_tristate =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_TRISTATE_SHIFT,
+ ARRAY_SIZE(enum_i2s_tristate),
+ enum_i2s_tristate);
+
+static struct soc_enum soc_enum_i2s1_tristate =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_TRISTATE_SHIFT,
+ ARRAY_SIZE(enum_i2s_tristate),
+ enum_i2s_tristate);
+
+static struct soc_enum soc_enum_i2s0_pulldown_resistor =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_i2s1_pulldown_resistor =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_i2s0_sample_rate =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_SR_SHIFT,
+ ARRAY_SIZE(enum_i2s_sample_rate),
+ enum_i2s_sample_rate);
+
+static struct soc_enum soc_enum_i2s1_sample_rate =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_SR_SHIFT,
+ ARRAY_SIZE(enum_i2s_sample_rate),
+ enum_i2s_sample_rate);
+
+static struct soc_enum soc_enum_line1_inversion =
+ SOC_ENUM_SINGLE(LINE1, LINEx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_line2_inversion =
+ SOC_ENUM_SINGLE(LINE2, LINEx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo1_inversion =
+ SOC_ENUM_SINGLE(AUXO1, AUXOx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo2_inversion =
+ SOC_ENUM_SINGLE(AUXO1, AUXOx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo1_pulldown_resistor =
+ SOC_ENUM_SINGLE(AUXO1, AUXOx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_auxo2_pulldown_resistor =
+ SOC_ENUM_SINGLE(AUXO1, AUXOx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct snd_kcontrol_new ab3550_snd_controls[] = {
+ /* RX Routing */
+ SOC_ENUM("RX2 Select", soc_enum_rx2_select),
+ SOC_SINGLE("LINE1 Adder", LINE1_ADDER, 0, 0x07, 0),
+ SOC_SINGLE("LINE2 Adder", LINE2_ADDER, 0, 0x07, 0),
+ SOC_SINGLE("EAR Adder", EAR_ADDER, 0, 0x07, 0),
+ SOC_SINGLE("SPKR Adder", SPKR_ADDER, 0, 0x07, 0),
+ SOC_SINGLE("AUXO1 Adder", AUXO1_ADDER, 0, 0x07, 0),
+ SOC_SINGLE("AUXO2 Adder", AUXO2_ADDER, 0, 0x07, 0),
+ /* TX Routing */
+ SOC_SINGLE("MIC1 Input Select", MIC1_INPUT_SELECT, 0, 0xff, 0),
+ SOC_SINGLE("MIC2 Input Select", MIC1_INPUT_SELECT, 0, 0xff, 0),
+ SOC_SINGLE("MIC2 to MIC1", MIC2_TO_MIC1, 0, 0x03, 0),
+ SOC_ENUM("I2S0 Input Select", soc_enum_i2s0_input_select),
+ SOC_ENUM("I2S1 Input Select", soc_enum_i2s1_input_select),
+ /* Routing of Side Tone and Analop Loop */
+ SOC_ENUM("APGA1 Source", soc_enum_apga1_source),
+ SOC_ENUM("APGA2 Source", soc_enum_apga2_source),
+ SOC_ENUM("APGA1 Enable", soc_enum_apga1_enable),
+ SOC_ENUM("APGA2 Enable", soc_enum_apga2_enable),
+ SOC_SINGLE("APGA1 Destination", APGA1_ADDER, 0, 0x3f, 0),
+ SOC_SINGLE("APGA2 Destination", APGA2_ADDER, 0, 0x3f, 0),
+ SOC_ENUM("DAC1 Side Tone", soc_enum_dac1_side_tone),
+ SOC_ENUM("DAC2 Side Tone", soc_enum_dac2_side_tone),
+ /* RX Volume Control */
+ SOC_SINGLE("RX-DPGA1 Gain", RX1_DIGITAL_PGA, 0, 0x43, 0),
+ SOC_SINGLE("RX-DPGA2 Gain", RX1_DIGITAL_PGA, 0, 0x43, 0),
+ SOC_SINGLE("RX-DPGA3 Gain", RX3_DIGITAL_PGA, 0, 0x43, 0),
+ SOC_SINGLE("LINE1 Gain", LINE1, LINEx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("LINE2 Gain", LINE2, LINEx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("SPKR Gain", SPKR, SPKR_GAIN_SHIFT, 0x16, 0),
+ SOC_SINGLE("EAR Gain", EAR, EAR_GAIN_SHIFT, 0x0e, 0),
+ SOC_SINGLE("AUXO1 Gain", AUXO1, AUXOx_GAIN_SHIFT, 0x0c, 0),
+ SOC_SINGLE("AUXO2 Gain", AUXO2, AUXOx_GAIN_SHIFT, 0x0c, 0),
+ /* TX Volume Control */
+ SOC_SINGLE("MIC1 Gain", MIC1_GAIN, MICx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("MIC2 Gain", MIC2_GAIN, MICx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("TX-DPGA1 Gain", TX_DIGITAL_PGA1, TXDPGAx_SHIFT, 0x0f, 0),
+ SOC_SINGLE("TX-DPGA2 Gain", TX_DIGITAL_PGA2, TXDPGAx_SHIFT, 0x0f, 0),
+ /* Volume Control of Side Tone and Analog Loop */
+ SOC_SINGLE("ST-PGA1 Gain", SIDETONE1_PGA, STx_PGA_SHIFT, 0x0a, 0),
+ SOC_SINGLE("ST-PGA2 Gain", SIDETONE2_PGA, STx_PGA_SHIFT, 0x0a, 0),
+ SOC_SINGLE("APGA1 Gain", ANALOG_LOOP_PGA1, APGAx_GAIN_SHIFT, 0x1d, 0),
+ SOC_SINGLE("APGA2 Gain", ANALOG_LOOP_PGA2, APGAx_GAIN_SHIFT, 0x1d, 0),
+ /* RX Properties */
+ SOC_ENUM("DAC1 Power Mode", soc_enum_dac1_power_mode),
+ SOC_ENUM("DAC2 Power Mode", soc_enum_dac2_power_mode),
+ SOC_ENUM("DAC3 Power Mode", soc_enum_dac3_power_mode),
+ SOC_ENUM("EAR Power Mode", soc_enum_ear_power_mode),
+ SOC_ENUM("AUXO Power Mode", soc_enum_auxo_power_mode),
+ SOC_ENUM("LINE1 Inversion", soc_enum_line1_inversion),
+ SOC_ENUM("LINE2 Inversion", soc_enum_line2_inversion),
+ SOC_ENUM("AUXO1 Inversion", soc_enum_auxo1_inversion),
+ SOC_ENUM("AUXO2 Inversion", soc_enum_auxo2_inversion),
+ SOC_ENUM("AUXO1 Pulldown Resistor", soc_enum_auxo1_pulldown_resistor),
+ SOC_ENUM("AUXO2 Pulldown Resistor", soc_enum_auxo2_pulldown_resistor),
+ /* TX Properties */
+ SOC_SINGLE("MIC1 VMID", MIC1_VMID_SELECT, 0, 0xff, 0),
+ SOC_SINGLE("MIC2 VMID", MIC2_VMID_SELECT, 0, 0xff, 0),
+ SOC_ENUM("MBIAS1 HiZ Option", soc_enum_mbias1_hiz_option),
+ SOC_ENUM("MBIAS2 HiZ Option", soc_enum_mbias2_hiz_option),
+ SOC_ENUM("MBIAS2 Output Voltage", soc_enum_mbias2_output_voltage),
+ SOC_ENUM("MBIAS2 Internal Resistor", soc_enum_mbias2_internal_resistor),
+ SOC_ENUM("MIC1 Input Impedance", soc_enum_mic1_input_impedance),
+ SOC_ENUM("MIC2 Input Impedance", soc_enum_mic2_input_impedance),
+ SOC_ENUM("TX1 HP Filter", soc_enum_tx1_hp_filter),
+ SOC_ENUM("TX2 HP Filter", soc_enum_tx2_hp_filter),
+ /* Side Tone and Analog Loop Properties */
+ SOC_ENUM("ST1 HP Filter", soc_enum_st1_hp_filter),
+ SOC_ENUM("ST2 HP Filter", soc_enum_st2_hp_filter),
+ /* I2S Interface Properties */
+ SOC_ENUM("I2S0 Word Length", soc_enum_i2s0_word_length),
+ SOC_ENUM("I2S1 Word Length", soc_enum_i2s1_word_length),
+ SOC_ENUM("I2S0 Mode", soc_enum_i2s0_mode),
+ SOC_ENUM("I2S1 Mode", soc_enum_i2s1_mode),
+ SOC_ENUM("I2S0 tri-state", soc_enum_i2s0_tristate),
+ SOC_ENUM("I2S1 tri-state", soc_enum_i2s1_tristate),
+ SOC_ENUM("I2S0 Pulldown Resistor", soc_enum_i2s0_pulldown_resistor),
+ SOC_ENUM("I2S1 Pulldown Resistor", soc_enum_i2s1_pulldown_resistor),
+ SOC_ENUM("I2S0 Sample Rate", soc_enum_i2s0_sample_rate),
+ SOC_ENUM("I2S1 Sample Rate", soc_enum_i2s1_sample_rate),
+ SOC_SINGLE("Interface Loop", INTERFACE_LOOP, 0, 0x0f, 0),
+ SOC_SINGLE("Interface Swap", INTERFACE_SWAP, 0, 0x1f, 0),
+ /* Miscellaneous */
+ SOC_SINGLE("Negative Charge Pump", NEGATIVE_CHARGE_PUMP, 0, 0x03, 0)
+};
+
+/* count the number of 1 */
+#define count_ones(x) ({ \
+ int num; \
+ for (num = 0; x; (x) &= (x) - 1, num++) \
+ ; \
+ num; \
+ })
+
+enum enum_power {
+ POWER_OFF = 0,
+ POWER_ON = 1
+};
+
+enum enum_link {
+ UNLINK = 0,
+ LINK = 1
+};
+
+static enum enum_power get_widget_power_status(enum enum_widget widget)
+{
+ u8 val;
+
+ if (widget >= number_of_widgets)
+ return POWER_OFF;
+ val = read_reg(widget_pm_array[widget].reg);
+ if (val & (1 << widget_pm_array[widget].shift))
+ return POWER_ON;
+ else
+ return POWER_OFF;
+}
+
+static int count_powered_neighbors(const unsigned long *neighbors)
+{
+ unsigned long i;
+ int n = 0;
+ for_each_set_bit(i, neighbors, number_of_widgets) {
+ if (get_widget_power_status(i) == POWER_ON)
+ n++;
+ }
+ return n;
+}
+
+static int has_powered_neighbors(const unsigned long *neighbors)
+{
+ unsigned int i;
+ for_each_set_bit(i, neighbors, number_of_widgets) {
+ if (get_widget_power_status(i) == POWER_ON)
+ return 1;
+ }
+ return 0;
+}
+
+
+static int has_stacked_neighbors(const unsigned long *neighbors)
+{
+ unsigned long *stack_map = pm_stack_as_bitmap;
+ return bitmap_intersects(stack_map, neighbors, number_of_widgets);
+}
+
+static void power_widget_unlocked(enum enum_power onoff,
+ enum enum_widget widget)
+{
+ enum enum_widget w;
+ int done;
+
+ if (widget >= number_of_widgets)
+ return;
+ if (get_widget_power_status(widget) == onoff)
+ return;
+
+ for (w = widget, done = 0; !done;) {
+ unsigned long i;
+ unsigned long *srcs = widget_pm_array[w].source_list;
+ unsigned long *sinks = widget_pm_array[w].sink_list;
+ dev_dbg(ab3550_dev, "%s: processing widget %s.\n",
+ __func__, widget_names[w]);
+
+ if (onoff == POWER_ON &&
+ !bitmap_empty(srcs, number_of_widgets) &&
+ !has_powered_neighbors(srcs)) {
+ pm_stack.stack[pm_stack.p++] = w;
+ for_each_set_bit(i, srcs, number_of_widgets) {
+ pm_stack.stack[pm_stack.p++] = i;
+ }
+ w = pm_stack.stack[--pm_stack.p];
+ continue;
+ } else if (onoff == POWER_OFF &&
+ has_powered_neighbors(sinks)) {
+ int n = 0;
+ pm_stack.stack[pm_stack.p++] = w;
+ for_each_set_bit(i, sinks, number_of_widgets) {
+ if (count_powered_neighbors(
+ widget_pm_array[i].source_list)
+ == 1 &&
+ get_widget_power_status(i) == POWER_ON) {
+ pm_stack.stack[pm_stack.p++] = i;
+ n++;
+ }
+ }
+ if (n) {
+ w = pm_stack.stack[--pm_stack.p];
+ continue;
+ } else
+ --pm_stack.p;
+ }
+ mask_set_reg(widget_pm_array[w].reg,
+ 1 << widget_pm_array[w].shift,
+ onoff == POWER_ON ? 0xff : 0);
+ dev_dbg(ab3550_dev, "%s: widget %s powered %s.\n",
+ __func__, widget_names[w],
+ onoff == POWER_ON ? "on" : "off");
+
+ if (onoff == POWER_ON &&
+ !bitmap_empty(sinks, number_of_widgets) &&
+ !has_powered_neighbors(sinks) &&
+ !has_stacked_neighbors(sinks)) {
+ for_each_set_bit(i, sinks, number_of_widgets) {
+ pm_stack.stack[pm_stack.p++] = i;
+ }
+ w = pm_stack.stack[--pm_stack.p];
+ continue;
+ } else if (onoff == POWER_OFF) {
+ for_each_set_bit(i, srcs, number_of_widgets) {
+ if (!has_powered_neighbors(
+ widget_pm_array[i].sink_list)
+ && get_widget_power_status(i) == POWER_ON
+ && !test_bit(i, pm_stack_as_bitmap)) {
+ pm_stack.stack[pm_stack.p++] = i;
+ }
+ }
+ }
+ if (pm_stack.p > 0)
+ w = pm_stack.stack[--pm_stack.p];
+ else
+ done = 1;
+ }
+}
+
+static void power_widget_locked(enum enum_power onoff,
+ enum enum_widget widget)
+{
+ if (mutex_lock_interruptible(&ab3550_pm_mutex)) {
+ dev_warn(ab3550_dev,
+ "%s: Signal received while waiting on the PM mutex.\n",
+ __func__);
+ return;
+ }
+ power_widget_unlocked(onoff, widget);
+ mutex_unlock(&ab3550_pm_mutex);
+}
+
+static void dump_registers(const char *where, ...)
+{
+ va_list ap;
+ va_start(ap, where);
+ do {
+ short reg = va_arg(ap, int);
+ if (reg < 0)
+ break;
+ dev_dbg(ab3550_dev, "%s from %s> 0x%02X : 0x%02X.\n",
+ __func__, where, reg, read_reg(reg));
+ } while (1);
+ va_end(ap);
+}
+
+/**
+ * update the link between two widgets.
+ * @op: 1 - connect; 0 - disconnect
+ * @src: source of the connection
+ * @sink: sink of the connection
+ */
+static int update_widgets_link(enum enum_link op, enum enum_widget src,
+ enum enum_widget sink,
+ u8 reg, u8 mask, u8 newval)
+{
+ int ret = 0;
+
+ if (mutex_lock_interruptible(&ab3550_pm_mutex)) {
+ dev_warn(ab3550_dev, "%s: A signal is received while waiting on"
+ " the PM mutex.\n", __func__);
+ return -EINTR;
+ }
+
+ switch (op << 2 | test_bit(sink, widget_pm_array[src].sink_list) << 1 |
+ test_bit(src, widget_pm_array[sink].source_list)) {
+ case 3: /* UNLINK, sink in sink_list, src in source_list */
+ case 4: /* LINK, sink not in sink_list, src not in source_list */
+ break;
+ default:
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (((int)op) << 2 | get_widget_power_status(src) << 1 |
+ get_widget_power_status(sink)) {
+ case 3: /* op = 0, src on, sink on */
+ if (count_powered_neighbors(widget_pm_array[sink].source_list)
+ == 1)
+ power_widget_unlocked(POWER_OFF, sink);
+ mask_set_reg(reg, mask, newval);
+ break;
+ case 6: /* op = 1, src on, sink off */
+ mask_set_reg(reg, mask, newval);
+ power_widget_unlocked(POWER_ON, sink);
+ break;
+ default:
+ /* op = 0, src off, sink off */
+ /* op = 0, src off, sink on */
+ /* op = 0, src on, sink off */
+ /* op = 1, src off, sink off */
+ /* op = 1, src off, sink on */
+ /* op = 1, src on, sink on */
+ mask_set_reg(reg, mask, newval);
+ }
+ change_bit(sink, widget_pm_array[src].sink_list);
+ change_bit(src, widget_pm_array[sink].source_list);
+end:
+ mutex_unlock(&ab3550_pm_mutex);
+ return ret;
+};
+
+static enum enum_widget apga_source_translate(u8 reg_value)
+{
+ switch (reg_value) {
+ case 1:
+ return widget_mic1;
+ case 2:
+ return widget_mic2;
+ default:
+ return number_of_widgets;
+ }
+}
+
+static enum enum_widget adder_sink_translate(u8 reg)
+{
+ switch (reg) {
+ case EAR_ADDER:
+ return widget_ear;
+ case AUXO1_ADDER:
+ return widget_auxo1;
+ case AUXO2_ADDER:
+ return widget_auxo2;
+ case SPKR_ADDER:
+ return widget_spkr;
+ case LINE1_ADDER:
+ return widget_line1;
+ case LINE2_ADDER:
+ return widget_line2;
+ case APGA1_ADDER:
+ return widget_apga1;
+ case APGA2_ADDER:
+ return widget_apga2;
+ default:
+ return number_of_widgets;
+ }
+}
+
+static int ab3550_add_widgets(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_new_controls(&codec->dapm, ab3550_dapm_widgets,
+ ARRAY_SIZE(ab3550_dapm_widgets));
+
+ snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon));
+
+ snd_soc_dapm_new_widgets(&codec->dapm);
+ return 0;
+}
+
+static void power_for_playback(enum enum_power onoff, int ifsel)
+{
+ dev_dbg(ab3550_dev, "%s: interface %d power %s.\n", __func__,
+ ifsel, onoff == POWER_ON ? "on" : "off");
+
+ if (mutex_lock_interruptible(&ab3550_pm_mutex)) {
+ dev_warn(ab3550_dev,
+ "%s: Signal received while waiting on the PM mutex.\n",
+ __func__);
+ return;
+ }
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_dld_l : widget_if1_dld_l);
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_dld_r : widget_if1_dld_r);
+ mutex_unlock(&ab3550_pm_mutex);
+}
+
+static void power_for_capture(enum enum_power onoff, int ifsel)
+{
+ dev_dbg(ab3550_dev, "%s: interface %d power %s", __func__,
+ ifsel, onoff == POWER_ON ? "on" : "off");
+ if (mutex_lock_interruptible(&ab3550_pm_mutex)) {
+ dev_warn(ab3550_dev,
+ "%s: Signal received while waiting on the PM mutex.\n",
+ __func__);
+ return;
+ }
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_uld_l : widget_if1_uld_l);
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_uld_r : widget_if1_uld_r);
+ mutex_unlock(&ab3550_pm_mutex);
+}
+
+static int ab3550_add_controls(struct snd_soc_codec *codec)
+{
+ int err = 0, i, n = ARRAY_SIZE(ab3550_snd_controls);
+
+ pr_debug("%s: %s called.\n", __FILE__, __func__);
+ for (i = 0; i < n; i++) {
+ err = snd_ctl_add(codec->card->snd_card, snd_ctl_new1(
+ &ab3550_snd_controls[i], codec));
+ if (err < 0) {
+ pr_err("%s failed to add control No.%d of %d.\n",
+ __func__, i, n);
+ return err;
+ }
+ }
+ return err;
+}
+
+static int ab3550_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params,
+ struct snd_soc_dai *dai)
+{
+ u8 val;
+ u8 reg = dai->id == 0 ? INTERFACE0 : INTERFACE1;
+
+ if (!ab3550_dev) {
+ pr_err("%s: The AB3550 codec driver not initialized.\n",
+ __func__);
+ return -EAGAIN;
+ }
+ dev_info(ab3550_dev, "%s called.\n", __func__);
+ switch (params_rate(hw_params)) {
+ case 8000:
+ val = I2Sx_SR_8000Hz;
+ break;
+ case 16000:
+ val = I2Sx_SR_16000Hz;
+ break;
+ case 44100:
+ val = I2Sx_SR_44100Hz;
+ break;
+ case 48000:
+ val = I2Sx_SR_48000Hz;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ !dai->capture_active : !dai->playback_active) {
+
+ mask_set_reg(reg, I2Sx_SR_MASK, val << I2Sx_SR_SHIFT);
+ if ((read_reg(reg) & I2Sx_MODE_MASK) == 0) {
+ mask_set_reg(reg, MASTER_GENx_PWR_MASK,
+ 1 << MASTER_GENx_PWR_SHIFT);
+ }
+ }
+ return 0;
+}
+
+static int ab3550_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ dai->playback_active : dai->capture_active) {
+
+ dev_err(ab3550_dev, "%s: A %s stream is already active.\n",
+ __func__,
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ "PLAYBACK" : "CAPTURE");
+ return -EBUSY;
+ }
+ return 0;
+}
+static int ab3550_pcm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ dev_info(ab3550_dev, "%s called.\n", __func__);
+
+ /* Configure registers for either playback or capture */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ power_for_playback(POWER_ON, dai->id);
+ dump_registers(__func__,
+ dai->id == 0 ? INTERFACE0 : INTERFACE1,
+ RX1, RX2, SPKR, EAR, -1);
+ } else {
+ power_for_capture(POWER_ON, dai->id);
+ dump_registers(__func__, MIC_BIAS1, MIC_BIAS2, MIC1_GAIN, TX1,
+ dai->id == 0 ? INTERFACE0 : INTERFACE1, -1);
+ }
+ return 0;
+}
+
+static void ab3550_pcm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ u8 iface = dai->id == 0 ? INTERFACE0 : INTERFACE1;
+ dev_info(ab3550_dev, "%s called.\n", __func__);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ power_for_playback(POWER_OFF, dai->id);
+ else
+ power_for_capture(POWER_OFF, dai->id);
+ if (!dai->playback_active && !dai->capture_active &&
+ (read_reg(iface) & I2Sx_MODE_MASK) == 0)
+ mask_set_reg(iface, MASTER_GENx_PWR_MASK, 0);
+}
+
+static int ab3550_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ return 0;
+}
+
+static int ab3550_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ u8 iface = (codec_dai->id == 0) ? INTERFACE0 : INTERFACE1;
+ u8 val = 0;
+ dev_info(ab3550_dev, "%s called.\n", __func__);
+
+ switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
+ SND_SOC_DAIFMT_MASTER_MASK)) {
+
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
+ val |= 1 << I2Sx_MODE_SHIFT;
+ break;
+
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
+ break;
+
+ default:
+ dev_warn(ab3550_dev, "AB3550_dai: unsupported DAI format "
+ "0x%x\n", fmt);
+ return -EINVAL;
+ }
+ if (codec_dai->playback_active && codec_dai->capture_active) {
+ if ((read_reg(iface) & I2Sx_MODE_MASK) == val)
+ return 0;
+ else {
+ dev_err(ab3550_dev,
+ "%s: DAI format set differently "
+ "by an existing stream.\n", __func__);
+ return -EINVAL;
+ }
+ }
+ mask_set_reg(iface, I2Sx_MODE_MASK, val);
+ return 0;
+}
+
+struct snd_soc_dai_driver ab3550_dai_drv[] = {
+ {
+ .name = "ab3550-codec-dai.0",
+ .id = 0,
+ .playback = {
+ .stream_name = "AB3550.0 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB3550_SUPPORTED_RATE,
+ .formats = AB3550_SUPPORTED_FMT,
+ },
+ .capture = {
+ .stream_name = "AB3550.0 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB3550_SUPPORTED_RATE,
+ .formats = AB3550_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .startup = ab3550_pcm_startup,
+ .prepare = ab3550_pcm_prepare,
+ .hw_params = ab3550_pcm_hw_params,
+ .shutdown = ab3550_pcm_shutdown,
+ .set_sysclk = ab3550_set_dai_sysclk,
+ .set_fmt = ab3550_set_dai_fmt,
+ }
+ },
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "ab3550-codec-dai.1",
+ .id = 1,
+ .playback = {
+ .stream_name = "AB3550.1 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB3550_SUPPORTED_RATE,
+ .formats = AB3550_SUPPORTED_FMT,
+ },
+ .capture = {
+ .stream_name = "AB3550.0 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB3550_SUPPORTED_RATE,
+ .formats = AB3550_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .startup = ab3550_pcm_startup,
+ .prepare = ab3550_pcm_prepare,
+ .hw_params = ab3550_pcm_hw_params,
+ .shutdown = ab3550_pcm_shutdown,
+ .set_sysclk = ab3550_set_dai_sysclk,
+ .set_fmt = ab3550_set_dai_fmt,
+ }
+ },
+ .symmetric_rates = 1,
+ }
+};
+EXPORT_SYMBOL_GPL(ab3550_dai_drv);
+
+static int ab3550_codec_probe(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ pr_info("%s: Enter.\n", __func__);
+
+ /* Add controls */
+ if (ab3550_add_controls(codec) < 0)
+ return ret;
+
+ /* Add widgets */
+ ab3550_add_widgets(codec);
+
+ return 0;
+}
+
+static int ab3550_codec_remove(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_free(&codec->dapm);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ab3550_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ mask_set_reg(CLOCK, CLOCK_ENABLE_MASK, 0);
+
+ return 0;
+}
+
+static int ab3550_codec_resume(struct snd_soc_codec *codec)
+{
+ mask_set_reg(CLOCK, CLOCK_ENABLE_MASK, 0xff);
+
+ return 0;
+}
+#else
+#define ab3550_codec_resume NULL
+#define ab3550_codec_suspend NULL
+#endif
+
+/*
+ * This function is only called by the SOC framework to
+ * set registers associated to the mixer controls.
+ */
+static int ab3550_codec_write_reg(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ if (reg < MIC_BIAS1 || reg > INTERFACE_SWAP)
+ return -EINVAL;
+ switch (reg) {
+ u8 diff, oldval;
+ case ANALOG_LOOP_PGA1:
+ case ANALOG_LOOP_PGA2: {
+ enum enum_widget apga = reg == ANALOG_LOOP_PGA1 ?
+ widget_apga1 : widget_apga2;
+
+ oldval = read_reg(reg);
+ diff = value ^ oldval;
+
+ /* The APGA is to be turned on/off.
+ * The power bit and the other bits in the
+ * same register won't be changed at the same time
+ * since they belong to different controls.
+ */
+ if (diff & (1 << APGAx_PWR_SHIFT)) {
+ power_widget_locked(value >> APGAx_PWR_SHIFT & 1,
+ apga);
+ } else if (diff & APGAx_MUX_MASK) {
+ enum enum_widget old_source =
+ apga_source_translate(oldval);
+ enum enum_widget new_source =
+ apga_source_translate(value);
+ update_widgets_link(UNLINK, old_source, apga,
+ reg, APGAx_MUX_MASK, 0);
+ update_widgets_link(LINK, new_source, apga,
+ reg, APGAx_MUX_MASK, value);
+ } else {
+ set_reg(reg, value);
+ }
+ break;
+ }
+
+ case APGA1_ADDER:
+ case APGA2_ADDER: {
+ int i;
+ enum enum_widget apga;
+ enum enum_widget apga_dst[] = {
+ widget_auxo2, widget_auxo1, widget_ear, widget_spkr,
+ widget_line2, widget_line1
+ };
+
+ apga = adder_sink_translate(reg);
+ oldval = read_reg(reg);
+ diff = value ^ oldval;
+ for (i = 0; diff; i++) {
+ if (!(diff & 1 << i))
+ continue;
+ diff ^= 1 << i;
+ update_widgets_link(value >> i & 1, apga, apga_dst[i],
+ reg, 1 << i, value);
+ }
+ break;
+ }
+
+ case EAR_ADDER:
+ case AUXO1_ADDER:
+ case AUXO2_ADDER:
+ case SPKR_ADDER:
+ case LINE1_ADDER:
+ case LINE2_ADDER: {
+ int i;
+ enum enum_widget widgets[] = {
+ widget_dac1, widget_dac2, widget_dac3,
+ };
+ oldval = read_reg(reg);
+ diff = value ^ oldval;
+ for (i = 0; diff; i++) {
+ if (!(diff & 1 << i))
+ continue;
+ diff ^= 1 << i;
+ update_widgets_link(value >> i & 1, widgets[i],
+ adder_sink_translate(reg),
+ reg, 1 << i, value);
+ }
+ break;
+ }
+
+ default:
+ set_reg(reg, value);
+ }
+ return 0;
+}
+
+static unsigned int ab3550_codec_read_reg(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return read_reg(reg);
+}
+
+static struct snd_soc_codec_driver ab3550_codec_drv = {
+ .probe = ab3550_codec_probe,
+ .remove = ab3550_codec_remove,
+ .suspend = ab3550_codec_suspend,
+ .resume = ab3550_codec_resume,
+ .read = ab3550_codec_read_reg,
+ .write = ab3550_codec_write_reg,
+};
+EXPORT_SYMBOL_GPL(ab3550_codec_drv);
+
+static inline void init_playback_route(void)
+{
+ update_widgets_link(LINK, widget_if0_dld_l, widget_rx1, 0, 0, 0);
+ update_widgets_link(LINK, widget_rx1, widget_dac1, 0, 0, 0);
+ update_widgets_link(LINK, widget_dac1, widget_spkr,
+ SPKR_ADDER, DAC1_TO_ADDER_MASK, 0xff);
+
+ update_widgets_link(LINK, widget_if0_dld_r, widget_rx2,
+ RX2, RX2_IF_SELECT_MASK, 0);
+ update_widgets_link(LINK, widget_rx2, widget_dac2, 0, 0, 0);
+ update_widgets_link(LINK, widget_dac2, widget_ear,
+ EAR_ADDER, DAC2_TO_ADDER_MASK, 0xff);
+}
+
+static inline void init_capture_route(void)
+{
+ update_widgets_link(LINK, widget_micbias2, widget_mic1p1,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_micbias2, widget_mic1n1,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_mic1p1, widget_mic1,
+ MIC1_INPUT_SELECT, MICxP1_SEL_MASK, 0xff);
+ update_widgets_link(LINK, widget_mic1n1, widget_mic1,
+ MIC1_INPUT_SELECT, MICxN1_SEL_MASK, 0xff);
+ update_widgets_link(LINK, widget_mic1, widget_adc1,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_adc1, widget_tx1,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_tx1, widget_if0_uld_l,
+ INTERFACE0_DATA, I2Sx_L_DATA_MASK,
+ I2Sx_L_DATA_TX1_MASK);
+ update_widgets_link(LINK, widget_tx1, widget_if0_uld_r,
+ INTERFACE0_DATA, I2Sx_R_DATA_MASK,
+ I2Sx_R_DATA_TX1_MASK);
+}
+
+static inline void init_playback_gain(void)
+{
+ mask_set_reg(RX1_DIGITAL_PGA, RXx_PGA_GAIN_MASK,
+ 0x40 << RXx_PGA_GAIN_SHIFT);
+ mask_set_reg(RX2_DIGITAL_PGA, RXx_PGA_GAIN_MASK,
+ 0x40 << RXx_PGA_GAIN_SHIFT);
+ mask_set_reg(EAR, EAR_GAIN_MASK, 0x06 << EAR_GAIN_SHIFT);
+ mask_set_reg(SPKR, SPKR_GAIN_MASK, 0x6 << SPKR_GAIN_SHIFT);
+}
+
+static inline void init_capture_gain(void)
+{
+ mask_set_reg(MIC1_GAIN, MICx_GAIN_MASK, 0x06 << MICx_GAIN_SHIFT);
+ mask_set_reg(TX_DIGITAL_PGA1, TXDPGAx_MASK, 0x0f << TXDPGAx_SHIFT);
+}
+
+static __devinit int ab3550_codec_drv_probe(struct platform_device *pdev)
+{
+ struct ab3550_codec_dai_data *codec_drvdata;
+ int ret = 0;
+ u8 reg;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ pr_info("%s: Init codec private data.\n", __func__);
+ codec_drvdata = kzalloc(sizeof(struct ab3550_codec_dai_data), GFP_KERNEL);
+ if (codec_drvdata == NULL)
+ return -ENOMEM;
+
+ /* TODO: Add private data to codec_drvdata */
+
+ platform_set_drvdata(pdev, codec_drvdata);
+
+ pr_info("%s: Register codec.\n", __func__);
+ ret = snd_soc_register_codec(&pdev->dev, &ab3550_codec_drv, &ab3550_dai_drv[0], 2);
+ if (ret < 0) {
+ pr_debug("%s: Error: Failed to register codec (ret = %d).\n",
+ __func__,
+ ret);
+ snd_soc_unregister_codec(&pdev->dev);
+ kfree(platform_get_drvdata(pdev));
+ return ret;
+ }
+
+ ab3550_dev = &pdev->dev;
+ /* Initialize the codec registers */
+ for (reg = AB3550_FIRST_REG; reg <= AB3550_LAST_REG; reg++)
+ set_reg(reg, 0);
+
+ mask_set_reg(CLOCK, CLOCK_REF_SELECT_MASK | CLOCK_ENABLE_MASK,
+ 1 << CLOCK_REF_SELECT_SHIFT | 1 << CLOCK_ENABLE_SHIFT);
+ init_playback_route();
+ init_playback_gain();
+ init_capture_route();
+ init_capture_gain();
+ memset(&pm_stack, 0, sizeof(pm_stack));
+
+ return 0;
+}
+
+static int __devexit ab3550_codec_drv_remove(struct platform_device *pdev)
+{
+ mask_set_reg(CLOCK, CLOCK_ENABLE_MASK, 0);
+
+ ab3550_dev = NULL;
+
+ snd_soc_unregister_codec(&pdev->dev);
+ kfree(platform_get_drvdata(pdev));
+
+ return 0;
+}
+
+static int ab3550_codec_drv_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+static int ab3550_codec_drv_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver ab3550_codec_platform_drv = {
+ .driver = {
+ .name = "ab3550-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab3550_codec_drv_probe,
+ .remove = __devexit_p(ab3550_codec_drv_remove),
+ .suspend = ab3550_codec_drv_suspend,
+ .resume = ab3550_codec_drv_resume,
+};
+
+
+static int __devinit ab3550_codec_platform_drv_init(void)
+{
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ ab3550_dev = NULL;
+
+ ret = platform_driver_register(&ab3550_codec_platform_drv);
+ if (ret != 0)
+ pr_err("Failed to register AB3550 platform driver (%d)!\n", ret);
+
+ return ret;
+}
+
+static void __exit ab3550_codec_platform_drv_exit(void)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ platform_driver_unregister(&ab3550_codec_platform_drv);
+}
+
+
+module_init(ab3550_codec_platform_drv_init);
+module_exit(ab3550_codec_platform_drv_exit);
+
+MODULE_DESCRIPTION("AB3550 Codec driver");
+MODULE_AUTHOR("Xie Xiaolei <xie.xiaolei@stericsson.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ab3550.h b/sound/soc/codecs/ab3550.h
new file mode 100644
index 00000000000..fe9c77b1a62
--- /dev/null
+++ b/sound/soc/codecs/ab3550.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Xie Xiaolei <xie.xiaolei@etericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#ifndef AB3550_CODEC_REGISTERS_H
+#define AB3550_CODEC_REGISTERS_H
+
+#define AB3550_SUPPORTED_RATE (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
+ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+
+#define AB3550_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+/* MIC BIAS */
+
+#define MIC_BIAS1 0X31
+#define MIC_BIAS2 0X32
+#define MBIAS2_OUT_V_MASK 0x04
+#define MBIAS2_OUT_V_SHIFT 2
+#define MBIAS_PWR_MASK 0x02
+#define MBIAS_PWR_SHIFT 1
+#define MBIAS_PDN_IMP_MASK 0x01
+#define MBIAS_PDN_IMP_SHIFT 0
+
+#define MIC_BIAS2_VAD 0x33
+#define MBIAS2_R_INT_MASK 0x01
+#define MBIAS2_R_INT_SHIFT 0
+
+/* MIC */
+#define MIC1_GAIN 0x34
+#define MIC2_GAIN 0x35
+#define MICx_GAIN_MASK 0xF0
+#define MICx_GAIN_SHIFT 4
+#define MICx_IN_IMP_MASK 0x0C
+#define MICx_IN_IMP_SHIFT 2
+#define MICx_PWR_MASK 0x01
+#define MICx_PWR_SHIFT 0
+
+#define MIC1_INPUT_SELECT 0x36
+#define MIC2_INPUT_SELECT 0x37
+#define MICxP1_SEL_MASK 0x80
+#define MICxP1_SEL_SHIFT 7
+#define MICxN1_SEL_MASK 0x40
+#define MICxN1_SEL_SHIFT 6
+#define MICxP2_SEL_MASK 0x20
+#define MICxP2_SEL_SHIFT 5
+#define MICxN2_SEL_MASK 0x10
+#define MICxN2_SEL_SHIFT 4
+#define LINEIN_SEL_MASK 0x03
+#define LINEIN_SEL_SHIFT 0
+
+#define MIC1_VMID_SELECT 0x38
+#define MIC2_VMID_SELECT 0x39
+#define VMIDx_ENABLE_MASK 0xC0
+#define VMIDx_ENABLE_SHIFT 6
+#define VMIDx_LINEIN1_N_MASK 0x20
+#define VMIDx_LINEIN1_N_SHIFT 5
+#define VMIDx_LINEIN2_N_MASK 0x10
+#define VMIDx_LINEIN2_N_SHIFT 4
+#define VMIDx_MICxP1_MASK 0x08
+#define VMIDx_MICxP1_SHIFT 3
+#define VMIDx_MICxP2_MASK 0x04
+#define VMIDx_MICxP2_SHIFT 2
+#define VMIDx_MICxN1_MASK 0x02
+#define VMIDx_MICxN1_SHIFT 1
+#define VMIDx_MICxN2_MASK 0x01
+#define VMIDx_MICxN2_SHIFT 0
+
+#define MIC2_TO_MIC1 0x3A
+#define MIC2_TO_MIC1_MASK 0x03
+#define MIC2_TO_MIC1_SHIFT 0
+
+/* Analog Loop */
+#define ANALOG_LOOP_PGA1 0x3B
+#define ANALOG_LOOP_PGA2 0x3C
+#define APGAx_GAIN_MASK 0xF8
+#define APGAx_GAIN_SHIFT 3
+#define APGAx_PWR_MASK 0x04
+#define APGAx_PWR_SHIFT 2
+#define APGAx_MUX_MASK 0x03
+#define APGAx_MUX_SHIFT 0
+#define APGAx_MUX_MIC1_MASK 0x01
+#define APGAx_MUX_MIC1_SHIFT 0
+#define APGAx_MUX_MIC2_MASK 0x02
+#define APGAx_MUX_MIC2_SHIFT 1
+
+
+#define APGA_VMID_SELECT 0x3D
+#define VMID_APGA1_ENABLE_MASK 0xC0
+#define VMID_APGA1_ENABLE_SHIFT 6
+#define VMID_APGA1_LINEIN1_MASK 0x20
+#define VMID_APGA1_LINEIN1_SHIFT 5
+#define VMID_APGA2_ENABLE_MASK 0x0C
+#define VMID_APGA2_ENABLE_SHIFT 2
+#define VMID_APGA2_LINEIN2_MASK 0x02
+#define VMID_APGA2_LINEIN2_SHIFT 1
+
+/* Output Amplifiers */
+#define EAR 0x3E
+#define EAR_PWR_MODE_MASK 0x20
+#define EAR_PWR_MODE_SHIFT 5
+#define EAR_PWR_MASK 0x10
+#define EAR_PWR_SHIFT 4
+#define EAR_GAIN_MASK 0x0F
+#define EAR_GAIN_SHIFT 0
+
+#define AUXO1 0x3F
+#define AUXO2 0x40
+#define AUXOx_PWR_MASK 0x80
+#define AUXOx_PWR_SHIFT 7
+#define AUXOx_INV_MASK 0x40
+#define AUXOx_INV_SHIFT 6
+#define AUXOx_PULLDOWN_MASK 0x20
+#define AUXOx_PULLDOWN_SHIFT 5
+#define AUXOx_GAIN_MASK 0x0F
+#define AUXOx_GAIN_SHIFT 0
+
+#define AUXO_PWR_MODE 0x41
+#define AUT_PWR_MODE_MASK 0x04
+#define AUT_PWR_MODE_SHIFT 2
+#define AUXO_PWR_MODE_MASK 0x03
+#define AUXO_PWR_MODE_SHIFT 0
+
+#define OFFSET_CANCEL 0x42
+#define SPKR_OFF_CANC_MASK 0x04
+#define SPKR_OFF_CANC_SHIFT 2
+#define AUXO_OFF_CANC_MASK 0x02
+#define AUXO_OFF_CANC_SHIFT 1
+#define OFFSET_CLOCK_MASK 0x01
+#define OFFSET_CLOCK_SHIFT 0
+
+#define SPKR 0x43
+#define OVR_CURR_PROT_MASK 0x80
+#define OVR_CURR_PROT_SHIFT 7
+#define SPKR_PWR_MASK 0x40
+#define SPKR_PWR_SHIFT 6
+#define SPKR_GAIN_MASK 0x1F
+#define SPKR_GAIN_SHIFT 0
+
+#define LINE1 0x44
+#define LINE2 0x45
+#define LINEx_PWR_MASK 0x80
+#define LINEx_PWR_SHIFT 7
+#define LINEx_INV_MASK 0x40
+#define LINEx_INV_SHIFT 6
+#define VMID_BUFFx_MASK 0x10
+#define VMID_BUFFx_SHIFT 4
+#define LINEx_GAIN_MASK 0x0F
+#define LINEx_GAIN_SHIFT 0
+
+/* Analog loop Routing */
+
+#define APGA1_ADDER 0x46
+#define APGA2_ADDER 0x47
+#define APGAx_TO_LINE1_MASK 0x20
+#define APGAx_TO_LINE1_SHIFT 0x5F
+#define APGAx_TO_LINE2_MASK 0x10
+#define APGAx_TO_LINE2_SHIFT 4
+#define APGAx_TO_SPKR_MASK 0x08
+#define APGAx_TO_SPKR_SHIFT 3
+#define APGAx_TO_EAR_MASK 0x04
+#define APGAx_TO_EAR_SHIFT 2
+#define APGAx_TO_AUXO1_MASK 0x02
+#define APGAx_TO_AUXO1_SHIFT 1
+#define APGAx_TO_AUXO2_MASK 0x01
+#define APGAx_TO_AUXO2_SHIFT 0
+#define APGAx_ADDER_VALID_BITS_MASK 0x3F
+
+/* Output Amplifiers Routing */
+
+#define EAR_ADDER 0x48
+#define AUXO1_ADDER 0x49
+#define AUXO2_ADDER 0x4A
+#define SPKR_ADDER 0x4B
+#define LINE1_ADDER 0x4C
+#define LINE2_ADDER 0x4D
+#define DAC3_TO_ADDER_MASK 0x04
+#define DAC3_TO_ADDER_SHIFT 2
+#define DAC2_TO_ADDER_MASK 0x02
+#define DAC2_TO_ADDER_SHIFT 1
+#define DAC1_TO_ADDER_MASK 0x01
+#define DAC1_TO_ADDER_SHIFT 0
+
+#define EAR_TO_MIC2 0x4E
+#define EAR_TO_MIC2_MASK 0x01
+#define EAR_TO_MIC2_SHIFT 0
+
+#define SPKR_TO_MIC2 0x4F
+#define SPKR_TO_MIC2_MASK 0x01
+#define SPKR_TO_MIC2_SHIFT 0
+
+#define NEGATIVE_CHARGE_PUMP 0x50
+#define NCP_MODE_MASK 0x02
+#define NCP_MODE_SHIFT 1
+#define NCP_PWR_MASK 0x01
+#define NCP_PWR_SHIFT 0
+
+#define TX1 0x51
+#define TX2 0x52
+#define TXx_HP_FILTER_MASK 0x0C
+#define TXx_HP_FILTER_SHIFT 2
+#define TXx_PWR_MASK 0x02
+#define TXx_PWR_SHIFT 1
+#define ADCx_PWR_MASK 0x01
+#define ADCx_PWR_SHIFT 0
+
+#define RX1 0x53
+#define RX2 0x54
+#define RX2_IF_SELECT_MASK 0x10
+#define RX2_IF_SELECT_SHIFT 4
+#define RX3 0x55
+#define RXx_PWR_MASK 0x08
+#define RXx_PWR_SHIFT 3
+#define DACx_PWR_MASK 0x04
+#define DACx_PWR_SHIFT 2
+#define DACx_PWR_MODE_MASK 0x03
+#define DACx_PWR_MODE_SHIFT 0
+
+#define TX_DIGITAL_PGA1 0X56
+#define TX_DIGITAL_PGA2 0X57
+#define TXDPGAx_MASK 0x0F
+#define TXDPGAx_SHIFT 0
+
+#define RX1_DIGITAL_PGA 0x58
+#define RX2_DIGITAL_PGA 0x59
+#define RX3_DIGITAL_PGA 0x5A
+#define RXx_PGA_GAIN_MASK 0x7F
+#define RXx_PGA_GAIN_SHIFT 0
+
+#define SIDETONE1_PGA 0x5B
+#define SIDETONE2_PGA 0x5C
+#define STx_HP_FILTER_MASK 0x60
+#define STx_HP_FILTER_SHIFT 5
+#define STx_MUX_MASK 0x10
+#define STx_MUX_SHIFT 4
+#define STx_PGA_MASK 0x0F
+#define STx_PGA_SHIFT 0
+
+/* clock */
+
+#define CLOCK 0x5D
+#define CLOCK_REF_SELECT_MASK 0x02
+#define CLOCK_REF_SELECT_SHIFT 1
+#define CLOCK_ENABLE_MASK 0x01
+#define CLOCK_ENABLE_SHIFT 0
+
+/* Interface */
+
+#define INTERFACE0 0x5E
+#define INTERFACE1 0x60
+#define I2Sx_WORDLENGTH_MASK 0x40
+#define I2Sx_WORDLENGTH_SHIFT 6
+#define MASTER_GENx_PWR_MASK 0x20
+#define MASTER_GENx_PWR_SHIFT 5
+#define I2Sx_MODE_MASK 0x10
+#define I2Sx_MODE_SHIFT 4
+#define I2Sx_TRISTATE_MASK 0x08
+#define I2Sx_TRISTATE_SHIFT 3
+#define I2Sx_PULLDOWN_MASK 0x04
+#define I2Sx_PULLDOWN_SHIFT 2
+#define I2Sx_SR_MASK 0x03
+#define I2Sx_SR_SHIFT 0
+#define I2Sx_SR_8000Hz 0
+#define I2Sx_SR_16000Hz 1
+#define I2Sx_SR_44100Hz 2
+#define I2Sx_SR_48000Hz 3
+
+#define INTERFACE0_DATA 0x5F
+#define INTERFACE1_DATA 0x61
+#define I2Sx_L_DATA_MASK 0x0C
+#define I2Sx_L_DATA_TX1_MASK 0x04
+#define I2Sx_L_DATA_TX2_MASK 0x08
+#define I2Sx_L_DATA_SHIFT 2
+#define I2Sx_R_DATA_MASK 0x03
+#define I2Sx_R_DATA_TX1_MASK 0x01
+#define I2Sx_R_DATA_TX2_MASK 0x02
+#define I2Sx_R_DATA_SHIFT 0
+
+#define INTERFACE_LOOP 0x62
+#define I2S0_INT_LOOP_MASK 0x08
+#define I2S0_INT_LOOP_SHIFT 3
+#define I2S0_EXT_LOOP_MASK 0x04
+#define I2S0_EXT_LOOP_SHIFT 2
+#define I2S1_INT_LOOP_MASK 0x02
+#define I2S1_INT_LOOP_SHIFT 1
+#define I2S1_EXT_LOOP_MASK 0x01
+#define I2S1_EXT_LOOP_SHIFT 0
+
+#define INTERFACE_SWAP 0x63
+#define RX_SWAP0_MASK 0x10
+#define RX_SWAP0_SHIFT 4
+#define RX_SWAP1_MASK 0x08
+#define RX_SWAP1_SHIFT 3
+#define IF_SWAP_MASK 0x04
+#define IF_SWAP_SHIFT 2
+#define IO_SWAP0_MASK 0x02
+#define IO_SWAP0_SHIFT 1
+#define IO_SWAP1_MASK 0x01
+#define IO_SWAP1_SHIFT 0
+
+#define AB3550_FIRST_REG MIC_BIAS1
+#define AB3550_LAST_REG INTERFACE_SWAP
+
+#define AB3550_VIRTUAL_REG1 (AB3550_LAST_REG + 1)
+#define IF0_DLD_L_PW_SHIFT 0
+#define IF0_DLD_R_PW_SHIFT 1
+#define IF0_ULD_L_PW_SHIFT 2
+#define IF0_ULD_R_PW_SHIFT 3
+#define IF1_DLD_L_PW_SHIFT 4
+#define IF1_DLD_R_PW_SHIFT 5
+#define IF1_ULD_L_PW_SHIFT 6
+#define IF1_ULD_R_PW_SHIFT 7
+
+#define AB3550_VIRTUAL_REG2 (AB3550_LAST_REG + 2)
+#define MIC1P1_PW_SHIFT 0
+#define MIC1N1_PW_SHIFT 1
+#define MIC1P2_PW_SHIFT 2
+#define MIC1N2_PW_SHIFT 3
+#define MIC2P1_PW_SHIFT 4
+#define MIC2N1_PW_SHIFT 5
+#define MIC2P2_PW_SHIFT 6
+#define MIC2N2_PW_SHIFT 7
+
+
+#endif
diff --git a/sound/soc/codecs/ab5500.c b/sound/soc/codecs/ab5500.c
new file mode 100644
index 00000000000..1875db4fc77
--- /dev/null
+++ b/sound/soc/codecs/ab5500.c
@@ -0,0 +1,1691 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Xie Xiaolei <xie.xiaolei@etericsson.com>,
+ * Ola Lilja <ola.o.lilja@stericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/mfd/abx500.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <asm/atomic.h>
+#include <linux/rwsem.h>
+#include <linux/mutex.h>
+#include <stdarg.h>
+#include "ab5500.h"
+
+/* No of digital interface on the Codec */
+#define NO_CODEC_DAI_IF 2
+
+/* codec private data */
+struct ab5500_codec_dai_data {
+ bool playback_active;
+ bool capture_active;
+
+};
+
+static struct device *ab5500_dev;
+
+static u8 virtual_regs[] = {
+ 0, 0, 0, 0, 0
+};
+
+#define set_reg(reg, val) mask_set_reg((reg), 0xff, (val))
+
+static void mask_set_reg(u8 reg, u8 mask, u8 val)
+{
+ u8 newval = mask & val;
+ u8 oldval, diff;
+
+ if (!ab5500_dev) {
+ pr_err("%s: The AB5500 codec driver not initialized.\n",
+ __func__);
+ return;
+ }
+ /* Check if the reg value falls within the
+ * range of AB5500 real registers. If
+ * so, set the mask */
+ if (reg < AB5500_FIRST_REG)
+ return;
+ if (reg <= AB5500_LAST_REG) {
+ abx500_mask_and_set_register_interruptible(
+ ab5500_dev, AB5500_BANK_AUDIO_HEADSETUSB,
+ reg, mask, val);
+ return;
+ }
+ if (reg - AB5500_LAST_REG - 1 >= ARRAY_SIZE(virtual_regs))
+ return;
+
+ /* treatment of virtual registers follows */
+ /*Compute the difference between the new value and the old value.
+ *1.If there is no difference, do nothing.
+ *2.If the difference is in the PWR_SHIFT,
+ *set the PWR masks appropriately.
+ */
+ oldval = virtual_regs[reg - AB5500_LAST_REG - 1];
+ diff = (val ^ oldval) & mask;
+ if (!diff)
+ return;
+
+ switch (reg) {
+ case AB5500_VIRTUAL_REG3:
+ if ((diff & (1 << SPKR1_PWR_SHIFT))) {
+ if ((val & (1 << SPKR1_PWR_SHIFT)) == 0) {
+ /*
+ * If the new value has PWR_SHIFT
+ * disabled, set the
+ * PWR_MASK to 0
+ */
+ mask_set_reg(SPKR1, SPKRx_PWR_MASK, 0);
+ }
+ else {
+ /* Else, set the PWR_MASK values based on the old value. */
+ switch (oldval & SPKR1_MODE_MASK) {
+ case 0:
+ mask_set_reg(SPKR1, SPKRx_PWR_MASK,
+ SPKRx_PWR_VBR_VALUE);
+ break;
+ case 1:
+ mask_set_reg(SPKR1, SPKRx_PWR_MASK,
+ SPKRx_PWR_CLS_D_VALUE);
+ break;
+ case 2:
+ mask_set_reg(SPKR1, SPKRx_PWR_MASK,
+ SPKRx_PWR_CLS_AB_VALUE);
+ break;
+ }
+ }
+ }
+ if ((diff & (1 << SPKR2_PWR_SHIFT))) {
+ if ((val & (1 << SPKR2_PWR_SHIFT)) == 0) {
+ /*
+ * If the new value has PWR_SHIFT
+ * disabled, set the
+ * PWR_MASK to 0
+ */
+ mask_set_reg(SPKR2, SPKRx_PWR_MASK, 0);
+ }
+ else {
+ /* Else, set the PWR_MASK values based on the old value. */
+ switch (oldval & SPKR2_MODE_MASK) {
+ case 0:
+ mask_set_reg(SPKR2, SPKRx_PWR_MASK,
+ SPKRx_PWR_VBR_VALUE);
+ break;
+ case 1:
+ mask_set_reg(SPKR2, SPKRx_PWR_MASK,
+ SPKRx_PWR_CLS_D_VALUE);
+ break;
+ }
+ }
+ }
+
+ break;
+ case AB5500_VIRTUAL_REG4:
+ ;
+ /* configure PWMCTRL_SPKR1, PWMCTRL_SPKR2, etc. */
+ }
+ virtual_regs[reg - AB5500_LAST_REG - 1] &= ~mask;
+ virtual_regs[reg - AB5500_LAST_REG - 1] |= newval;
+}
+
+static u8 read_reg(u8 reg)
+{
+ if (!ab5500_dev) {
+ pr_err("%s: The AB5500 codec driver not initialized.\n",
+ __func__);
+ return 0;
+ }
+ /* Check if the reg value falls within the range of AB5500 real
+ * registers.If so, set the mask */
+ if (reg < AB5500_FIRST_REG)
+ return 0;
+ else if (reg <= AB5500_LAST_REG) {
+ u8 val;
+ abx500_get_register_interruptible(
+ ab5500_dev, AB5500_BANK_AUDIO_HEADSETUSB, reg, &val);
+ return val;
+ } else if (reg - AB5500_LAST_REG - 1 < ARRAY_SIZE(virtual_regs))
+ return virtual_regs[reg - AB5500_LAST_REG - 1];
+ dev_warn(ab5500_dev, "%s: out-of-scope reigster %u.\n",
+ __func__, reg);
+ return 0;
+}
+
+/* Components that can be powered up/down */
+enum enum_widget {
+ widget_ear = 0,
+ widget_auxo1,
+ widget_auxo2,
+ widget_auxo3,
+ widget_auxo4,
+ widget_spkr1,
+ widget_spkr2,
+ widget_spkr1_adder,
+ widget_spkr2_adder,
+ widget_pwm_spkr1,
+ widget_pwm_spkr2,
+ widget_pwm_spkr1n,
+ widget_pwm_spkr1p,
+ widget_pwm_spkr2n,
+ widget_pwm_spkr2p,
+ widget_line1,
+ widget_line2,
+ widget_dac1,
+ widget_dac2,
+ widget_dac3,
+ widget_rx1,
+ widget_rx2,
+ widget_rx3,
+ widget_mic1,
+ widget_mic2,
+ widget_micbias1,
+ widget_micbias2,
+ widget_apga1,
+ widget_apga2,
+ widget_tx1,
+ widget_tx2,
+ widget_adc1,
+ widget_adc2,
+ widget_if0_dld_l,
+ widget_if0_dld_r,
+ widget_if0_uld_l,
+ widget_if0_uld_r,
+ widget_if1_dld_l,
+ widget_if1_dld_r,
+ widget_if1_uld_l,
+ widget_if1_uld_r,
+ widget_mic1p1,
+ widget_mic1n1,
+ widget_mic1p2,
+ widget_mic1n2,
+ widget_mic2p1,
+ widget_mic2n1,
+ widget_mic2p2,
+ widget_mic2n2,
+ widget_clock,
+ number_of_widgets
+};
+
+/* This is only meant for debugging */
+static const char *widget_names[] = {
+ "EAR", "AUXO1", "AUXO2", "AUXO3", "AUXO4",
+ "SPKR1", "SPKR2", "SPKR1_ADDER", "SPKR2_ADDER",
+ "PWM_SPKR1", "PWM_SPKR2",
+ "PWM_SPKR1N", "PWM_SPKR1P",
+ "PWM_SPKR2N", "PWM_SPKR2P",
+ "LINE1", "LINE2",
+ "DAC1", "DAC2", "DAC3",
+ "RX1", "RX2", "RX3",
+ "MIC1", "MIC2",
+ "MIC-BIAS1", "MIC-BIAS2",
+ "APGA1", "APGA2",
+ "TX1", "TX2",
+ "ADC1", "ADC2",
+ "IF0-DLD-L", "IF0-DLD-R", "IF0-ULD-L", "IF0-ULD-R",
+ "IF1-DLD-L", "IF1-DLD-R", "IF1-ULD-L", "IF1-ULD-R",
+ "MIC1P1", "MIC1N1", "MIC1P2", "MIC1N2",
+ "MIC2P1", "MIC2N1", "MIC2P2", "MIC2N2",
+ "CLOCK"
+};
+
+struct widget_pm {
+ enum enum_widget widget;
+ u8 reg;
+ u8 shift;
+
+ unsigned long source_list[BIT_WORD(number_of_widgets) + 1];
+ unsigned long sink_list[BIT_WORD(number_of_widgets) + 1];
+};
+
+static struct widget_pm widget_pm_array[] = {
+ {.widget = widget_ear, .reg = EAR_PWR, .shift = EAR_PWR_SHIFT},
+
+ {.widget = widget_auxo1, .reg = AUXO1, .shift = AUXOx_PWR_SHIFT},
+ {.widget = widget_auxo2, .reg = AUXO2, .shift = AUXOx_PWR_SHIFT},
+ {.widget = widget_auxo3, .reg = AUXO3, .shift = AUXOx_PWR_SHIFT},
+ {.widget = widget_auxo4, .reg = AUXO4, .shift = AUXOx_PWR_SHIFT},
+
+ {.widget = widget_spkr1, .reg = AB5500_VIRTUAL_REG3,
+ .shift = SPKR1_PWR_SHIFT},
+ {.widget = widget_spkr2, .reg = AB5500_VIRTUAL_REG3,
+ .shift = SPKR2_PWR_SHIFT},
+
+ {.widget = widget_spkr1_adder, .reg = AB5500_VIRTUAL_REG3,
+ .shift = SPKR1_ADDER_PWR_SHIFT},
+ {.widget = widget_spkr2_adder, .reg = AB5500_VIRTUAL_REG3,
+ .shift = SPKR2_ADDER_PWR_SHIFT},
+
+ {.widget = widget_pwm_spkr1, .reg = AB5500_VIRTUAL_REG4,
+ .shift = PWM_SPKR1_PWR_SHIFT},
+ {.widget = widget_pwm_spkr2, .reg = AB5500_VIRTUAL_REG4,
+ .shift = PWM_SPKR2_PWR_SHIFT},
+
+ {.widget = widget_pwm_spkr1n, .reg = AB5500_VIRTUAL_REG4,
+ .shift = PWM_SPKR1N_PWR_SHIFT},
+ {.widget = widget_pwm_spkr1p, .reg = AB5500_VIRTUAL_REG4,
+ .shift = PWM_SPKR1P_PWR_SHIFT},
+
+ {.widget = widget_pwm_spkr2n, .reg = AB5500_VIRTUAL_REG4,
+ .shift = PWM_SPKR2N_PWR_SHIFT},
+ {.widget = widget_pwm_spkr2p, .reg = AB5500_VIRTUAL_REG4,
+ .shift = PWM_SPKR2P_PWR_SHIFT},
+
+
+ {.widget = widget_line1, .reg = LINE1, .shift = LINEx_PWR_SHIFT},
+ {.widget = widget_line2, .reg = LINE2, .shift = LINEx_PWR_SHIFT},
+
+ {.widget = widget_dac1, .reg = RX1, .shift = DACx_PWR_SHIFT},
+ {.widget = widget_dac2, .reg = RX2, .shift = DACx_PWR_SHIFT},
+ {.widget = widget_dac3, .reg = RX3, .shift = DACx_PWR_SHIFT},
+
+ {.widget = widget_rx1, .reg = RX1, .shift = RXx_PWR_SHIFT},
+ {.widget = widget_rx2, .reg = RX2, .shift = RXx_PWR_SHIFT},
+ {.widget = widget_rx3, .reg = RX3, .shift = RXx_PWR_SHIFT},
+
+ {.widget = widget_mic1, .reg = MIC1_GAIN, .shift = MICx_PWR_SHIFT},
+ {.widget = widget_mic2, .reg = MIC2_GAIN, .shift = MICx_PWR_SHIFT},
+
+ {.widget = widget_micbias1, .reg = MIC_BIAS1,
+ .shift = MBIASx_PWR_SHIFT},
+ {.widget = widget_micbias2, .reg = MIC_BIAS2,
+ .shift = MBIASx_PWR_SHIFT},
+
+ {.widget = widget_apga1, .reg = ANALOG_LOOP_PGA1,
+ .shift = APGAx_PWR_SHIFT},
+ {.widget = widget_apga2, .reg = ANALOG_LOOP_PGA2,
+ .shift = APGAx_PWR_SHIFT},
+
+ {.widget = widget_tx1, .reg = TX1, .shift = TXx_PWR_SHIFT},
+ {.widget = widget_tx2, .reg = TX2, .shift = TXx_PWR_SHIFT},
+
+ {.widget = widget_adc1, .reg = TX1, .shift = ADCx_PWR_SHIFT},
+ {.widget = widget_adc2, .reg = TX2, .shift = ADCx_PWR_SHIFT},
+
+ {.widget = widget_if0_dld_l, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF0_DLD_L_PW_SHIFT},
+ {.widget = widget_if0_dld_r, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF0_DLD_R_PW_SHIFT},
+ {.widget = widget_if0_uld_l, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF0_ULD_L_PW_SHIFT},
+ {.widget = widget_if0_uld_r, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF0_ULD_R_PW_SHIFT},
+
+ {.widget = widget_if1_dld_l, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF1_DLD_L_PW_SHIFT},
+ {.widget = widget_if1_dld_r, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF1_DLD_R_PW_SHIFT},
+ {.widget = widget_if1_uld_l, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF1_ULD_L_PW_SHIFT},
+ {.widget = widget_if1_uld_r, .reg = AB5500_VIRTUAL_REG1,
+ .shift = IF1_ULD_R_PW_SHIFT},
+
+ {.widget = widget_mic1p1, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC1P1_PW_SHIFT},
+ {.widget = widget_mic1n1, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC1N1_PW_SHIFT},
+ {.widget = widget_mic1p2, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC1P2_PW_SHIFT},
+ {.widget = widget_mic1n2, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC1N2_PW_SHIFT},
+
+ {.widget = widget_mic2p1, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC2P1_PW_SHIFT},
+ {.widget = widget_mic2n1, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC2N1_PW_SHIFT},
+ {.widget = widget_mic2p2, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC2P2_PW_SHIFT},
+ {.widget = widget_mic2n2, .reg = AB5500_VIRTUAL_REG2,
+ .shift = MIC2N2_PW_SHIFT},
+
+ {.widget = widget_clock, .reg = CLOCK, .shift = CLOCK_ENABLE_SHIFT},
+};
+
+DEFINE_MUTEX(ab5500_pm_mutex);
+
+static struct {
+ enum enum_widget stack[number_of_widgets];
+ int p;
+} pm_stack;
+
+#define pm_stack_as_bitmap ({ \
+ unsigned long bitmap[BIT_WORD(number_of_widgets) + 1]; \
+ int i; \
+ memset(bitmap, 0, sizeof(bitmap)); \
+ for (i = 0; i < pm_stack.p; i++) { \
+ set_bit(pm_stack.stack[i], bitmap); \
+ } \
+ bitmap; \
+ })
+
+/* These are only meant to meet the obligations of DAPM */
+static const struct snd_soc_dapm_widget ab5500_dapm_widgets[] = {
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+};
+
+
+struct ab5500_codec_dai_data ab5500_codec_privates[NO_CODEC_DAI_IF] = {
+ {
+ .playback_active = false,
+ .capture_active = false,
+ },
+ {
+ .playback_active = false,
+ .capture_active = false,
+ }
+};
+
+static const char *enum_rx_input_select[] = {
+ "Mute", "TX1", "TX2", "I2S0_DLD_L",
+ "I2S0_DLD_R", "I2S1_DLD_L", "I2S1_DLD_R"
+};
+
+static const char *enum_i2s_uld_select[] = {
+ "Mute", "TX1", "TX2", "I2S0_DLD_L",
+ "I2S0_DLD_R", "I2S1_DLD_L", "I2S1_DLD_R", "tri-state"
+};
+static const char *enum_apga1_source[] = {"LINEIN1", "MIC1", "MIC2", "None"};
+static const char *enum_apga2_source[] = {"LINEIN2", "MIC1", "MIC2", "None"};
+static const char *enum_rx_side_tone[] = {"TX1", "TX2"};
+static const char *enum_dac_power_mode[] = {"100%", "75%", "55%"};
+static const char *enum_ear_power_mode[] = {"100%", "70%", "50%"};
+static const char *enum_auxo_power_mode[] = {
+ "100%", "67%", "50%", "25%", "auto"
+};
+static const char *enum_onoff[] = {"Off", "On"};
+static const char *enum_mbias_pdn_imp[] = {"GND", "HiZ"};
+static const char *enum_mbias2_out_v[] = {"2.0v", "2.2v"};
+static const char *enum_mic_in_imp[] = {
+ "12.5 kohm", "25 kohm", "50 kohm"
+};
+static const char *enum_hp_filter[] = {"HP3", "HP1", "bypass"};
+static const char *enum_i2s_word_length[] = {"16 bits", "24 bits"};
+static const char *enum_i2s_mode[] = {"Master Mode", "Slave Mode"};
+static const char *enum_i2s_tristate[] = {"Normal", "Tri-state"};
+static const char *enum_optional_resistor[] = {"disconnected", "connected"};
+static const char *enum_i2s_sample_rate[] = {
+ "8 kHz", "16 kHz", "44.1 kHz", "48 kHz"
+};
+static const char *enum_tx1_input_select[] = {
+ "ADC1", "DIGMIC1", "DIGMIC2"
+};
+static const char *enum_tx2_input_select[] = {
+ "ADC2", "DIGMIC1", "DIGMIC2"
+};
+static const char *enum_signal_inversion[] = {"normal", "inverted"};
+static const char *enum_spkr1_mode[] = {
+ "Vibra PWM", "class D amplifier", "class AB amplifier"
+};
+static const char *enum_spkr2_mode[] = {
+ "Vibra PWM", "class D amplifier",
+};
+static const char *enum_pwm_pol[] = {
+ "GND", "VDD"
+};
+/* RX1 Input Select */
+static struct soc_enum soc_enum_rx1_in_sel =
+ SOC_ENUM_SINGLE(RX1, RXx_DATA_SHIFT,
+ ARRAY_SIZE(enum_rx_input_select),
+ enum_rx_input_select);
+
+/* RX2 Input Select */
+static struct soc_enum soc_enum_rx2_in_sel =
+ SOC_ENUM_SINGLE(RX2, RXx_DATA_SHIFT,
+ ARRAY_SIZE(enum_rx_input_select),
+ enum_rx_input_select);
+/* RX3 Input Select */
+static struct soc_enum soc_enum_rx3_in_sel =
+ SOC_ENUM_SINGLE(RX3, RXx_DATA_SHIFT,
+ ARRAY_SIZE(enum_rx_input_select),
+ enum_rx_input_select);
+/* TX1 Input Select */
+static struct soc_enum soc_enum_tx1_in_sel =
+ SOC_ENUM_SINGLE(TX1, TXx_MUX_SHIFT,
+ ARRAY_SIZE(enum_tx1_input_select),
+ enum_tx1_input_select);
+/* TX2 Input Select */
+static struct soc_enum soc_enum_tx2_in_sel =
+ SOC_ENUM_SINGLE(TX2, TXx_MUX_SHIFT,
+ ARRAY_SIZE(enum_tx2_input_select),
+ enum_tx2_input_select);
+
+/* I2S0 ULD Select */
+static struct soc_enum soc_enum_i2s0_input_select =
+ SOC_ENUM_DOUBLE(INTERFACE0_ULD, 0, 4,
+ ARRAY_SIZE(enum_i2s_uld_select),
+ enum_i2s_uld_select);
+/* I2S1 ULD Select */
+static struct soc_enum soc_enum_i2s1_input_select =
+ SOC_ENUM_DOUBLE(INTERFACE1_ULD, 0, 4,
+ ARRAY_SIZE(enum_i2s_uld_select),
+ enum_i2s_uld_select);
+
+/* APGA1 Source */
+static struct soc_enum soc_enum_apga1_source =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA1, APGAx_MUX_SHIFT,
+ ARRAY_SIZE(enum_apga1_source),
+ enum_apga1_source);
+
+/* APGA2 Source */
+static struct soc_enum soc_enum_apga2_source =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA2, APGAx_MUX_SHIFT,
+ ARRAY_SIZE(enum_apga2_source),
+ enum_apga2_source);
+
+static struct soc_enum soc_enum_apga1_enable =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA1, APGAx_PWR_SHIFT,
+ ARRAY_SIZE(enum_onoff), enum_onoff);
+
+static struct soc_enum soc_enum_apga2_enable =
+ SOC_ENUM_SINGLE(ANALOG_LOOP_PGA2, APGAx_PWR_SHIFT,
+ ARRAY_SIZE(enum_onoff), enum_onoff);
+
+/* RX1 Side Tone */
+static struct soc_enum soc_enum_dac1_side_tone =
+ SOC_ENUM_SINGLE(ST1_PGA, STx_MUX_SHIFT,
+ ARRAY_SIZE(enum_rx_side_tone),
+ enum_rx_side_tone);
+
+/* RX2 Side Tone */
+static struct soc_enum soc_enum_dac2_side_tone =
+ SOC_ENUM_SINGLE(ST2_PGA, STx_MUX_SHIFT,
+ ARRAY_SIZE(enum_rx_side_tone),
+ enum_rx_side_tone);
+
+/* DAC1 Power Mode */
+static struct soc_enum soc_enum_dac1_power_mode =
+ SOC_ENUM_SINGLE(RX1, DACx_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_dac_power_mode),
+ enum_dac_power_mode);
+
+/* DAC2 Power Mode */
+static struct soc_enum soc_enum_dac2_power_mode =
+ SOC_ENUM_SINGLE(RX2, DACx_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_dac_power_mode),
+ enum_dac_power_mode);
+
+/* DAC3 Power Mode */
+static struct soc_enum soc_enum_dac3_power_mode =
+ SOC_ENUM_SINGLE(RX3, DACx_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_dac_power_mode),
+ enum_dac_power_mode);
+
+/* EAR Power Mode */
+static struct soc_enum soc_enum_ear_power_mode =
+ SOC_ENUM_SINGLE(EAR_PWR, EAR_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_ear_power_mode),
+ enum_ear_power_mode);
+
+/* AUXO12 Power Mode */
+static struct soc_enum soc_enum_auxo12_power_mode =
+ SOC_ENUM_SINGLE(AUXO12_PWR_MODE, AUXOxy_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_auxo_power_mode),
+ enum_auxo_power_mode);
+
+/* AUXO34 Power Mode */
+static struct soc_enum soc_enum_auxo34_power_mode =
+ SOC_ENUM_SINGLE(AUXO34_PWR_MODE, AUXOxy_PWR_MODE_SHIFT,
+ ARRAY_SIZE(enum_auxo_power_mode),
+ enum_auxo_power_mode);
+
+/* MBIAS1 PDN Impedance */
+static struct soc_enum soc_enum_mbias1_pdn_imp =
+ SOC_ENUM_SINGLE(MIC_BIAS1, MBIASx_PDN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mbias_pdn_imp),
+ enum_mbias_pdn_imp);
+
+/* MBIAS2 PDN Impedance */
+static struct soc_enum soc_enum_mbias2_pdn_imp =
+ SOC_ENUM_SINGLE(MIC_BIAS2, MBIASx_PDN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mbias_pdn_imp),
+ enum_mbias_pdn_imp);
+
+/* MBIAS2 Output voltage */
+static struct soc_enum soc_enum_mbias2_out_v =
+ SOC_ENUM_SINGLE(MIC_BIAS2, MBIAS2_OUT_V_SHIFT,
+ ARRAY_SIZE(enum_mbias2_out_v),
+ enum_mbias2_out_v);
+
+static struct soc_enum soc_enum_mbias2_int_r =
+ SOC_ENUM_SINGLE(MIC_BIAS2_VAD, MBIAS2_R_INT_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_mic1_in_imp =
+ SOC_ENUM_SINGLE(MIC1_GAIN, MICx_IN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mic_in_imp),
+ enum_mic_in_imp);
+
+static struct soc_enum soc_enum_mic2_in_imp =
+ SOC_ENUM_SINGLE(MIC2_GAIN, MICx_IN_IMP_SHIFT,
+ ARRAY_SIZE(enum_mic_in_imp),
+ enum_mic_in_imp);
+
+static struct soc_enum soc_enum_tx1_hp_filter =
+ SOC_ENUM_SINGLE(TX1, TXx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_tx2_hp_filter =
+ SOC_ENUM_SINGLE(TX2, TXx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_st1_hp_filter =
+ SOC_ENUM_SINGLE(ST1_PGA, STx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_st2_hp_filter =
+ SOC_ENUM_SINGLE(ST2_PGA, STx_HP_FILTER_SHIFT,
+ ARRAY_SIZE(enum_hp_filter),
+ enum_hp_filter);
+
+static struct soc_enum soc_enum_i2s0_word_length =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_WORDLENGTH_SHIFT,
+ ARRAY_SIZE(enum_i2s_word_length),
+ enum_i2s_word_length);
+
+static struct soc_enum soc_enum_i2s1_word_length =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_WORDLENGTH_SHIFT,
+ ARRAY_SIZE(enum_i2s_word_length),
+ enum_i2s_word_length);
+
+static struct soc_enum soc_enum_i2s0_mode =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_MODE_SHIFT,
+ ARRAY_SIZE(enum_i2s_mode),
+ enum_i2s_mode);
+
+static struct soc_enum soc_enum_i2s1_mode =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_MODE_SHIFT,
+ ARRAY_SIZE(enum_i2s_mode),
+ enum_i2s_mode);
+
+static struct soc_enum soc_enum_i2s0_tristate =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_TRISTATE_SHIFT,
+ ARRAY_SIZE(enum_i2s_tristate),
+ enum_i2s_tristate);
+
+static struct soc_enum soc_enum_i2s1_tristate =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_TRISTATE_SHIFT,
+ ARRAY_SIZE(enum_i2s_tristate),
+ enum_i2s_tristate);
+
+static struct soc_enum soc_enum_i2s0_pulldown_resistor =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_i2s1_pulldown_resistor =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_i2s0_sample_rate =
+ SOC_ENUM_SINGLE(INTERFACE0, I2Sx_SR_SHIFT,
+ ARRAY_SIZE(enum_i2s_sample_rate),
+ enum_i2s_sample_rate);
+
+static struct soc_enum soc_enum_i2s1_sample_rate =
+ SOC_ENUM_SINGLE(INTERFACE1, I2Sx_SR_SHIFT,
+ ARRAY_SIZE(enum_i2s_sample_rate),
+ enum_i2s_sample_rate);
+
+static struct soc_enum soc_enum_line1_inversion =
+ SOC_ENUM_SINGLE(LINE1, LINEx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_line2_inversion =
+ SOC_ENUM_SINGLE(LINE2, LINEx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo1_inversion =
+ SOC_ENUM_SINGLE(AUXO1, AUXOx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo2_inversion =
+ SOC_ENUM_SINGLE(AUXO2, AUXOx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo3_inversion =
+ SOC_ENUM_SINGLE(AUXO3, AUXOx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo4_inversion =
+ SOC_ENUM_SINGLE(AUXO4, AUXOx_INV_SHIFT,
+ ARRAY_SIZE(enum_signal_inversion),
+ enum_signal_inversion);
+
+static struct soc_enum soc_enum_auxo1_pulldown_resistor =
+ SOC_ENUM_SINGLE(AUXO1, AUXOx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_auxo2_pulldown_resistor =
+ SOC_ENUM_SINGLE(AUXO2, AUXOx_PULLDOWN_SHIFT,
+ ARRAY_SIZE(enum_optional_resistor),
+ enum_optional_resistor);
+
+static struct soc_enum soc_enum_spkr1_mode =
+ SOC_ENUM_SINGLE(AB5500_VIRTUAL_REG3, SPKR1_MODE_SHIFT,
+ ARRAY_SIZE(enum_spkr1_mode),
+ enum_spkr1_mode);
+
+static struct soc_enum soc_enum_spkr2_mode =
+ SOC_ENUM_SINGLE(AB5500_VIRTUAL_REG3, SPKR2_MODE_SHIFT,
+ ARRAY_SIZE(enum_spkr2_mode),
+ enum_spkr2_mode);
+
+static struct soc_enum soc_enum_pwm_spkr1n_pol =
+ SOC_ENUM_SINGLE(PWMCTRL_SPKR1, PWMCTRL_SPKRx_N1_POL_SHIFT,
+ ARRAY_SIZE(enum_pwm_pol), enum_pwm_pol);
+
+static struct soc_enum soc_enum_pwm_spkr1p_pol =
+ SOC_ENUM_SINGLE(PWMCTRL_SPKR1, PWMCTRL_SPKRx_P1_POL_SHIFT,
+ ARRAY_SIZE(enum_pwm_pol), enum_pwm_pol);
+
+static struct soc_enum soc_enum_pwm_spkr2n_pol =
+ SOC_ENUM_SINGLE(PWMCTRL_SPKR2, PWMCTRL_SPKRx_N1_POL_SHIFT,
+ ARRAY_SIZE(enum_pwm_pol), enum_pwm_pol);
+
+static struct soc_enum soc_enum_pwm_spkr2p_pol =
+ SOC_ENUM_SINGLE(PWMCTRL_SPKR2, PWMCTRL_SPKRx_P1_POL_SHIFT,
+ ARRAY_SIZE(enum_pwm_pol), enum_pwm_pol);
+
+static struct snd_kcontrol_new ab5500_snd_controls[] = {
+ /* RX Routing */
+ SOC_ENUM("RX1 Input Select", soc_enum_rx1_in_sel),
+ SOC_ENUM("RX2 Input Select", soc_enum_rx2_in_sel),
+ SOC_ENUM("RX3 Input Select", soc_enum_rx3_in_sel),
+ SOC_SINGLE("LINE1 Adder", LINE1_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("LINE2 Adder", LINE2_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("EAR Adder", EAR_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("SPKR1 Adder", SPKR1_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("SPKR2 Adder", SPKR2_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("AUXO1 Adder", AUXO1_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("AUXO2 Adder", AUXO2_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("AUXO3 Adder", AUXO3_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("AUXO4 Adder", AUXO4_ADDER, 0, 0x1F, 0),
+ SOC_SINGLE("SPKR1 PWM Select", AB5500_VIRTUAL_REG5, 0, 0x03, 0),
+ SOC_SINGLE("SPKR2 PWM Select", AB5500_VIRTUAL_REG5, 2, 0x0C, 0),
+ /* TX Routing */
+ SOC_ENUM("TX1 Input Select", soc_enum_tx1_in_sel),
+ SOC_ENUM("TX2 Input Select", soc_enum_tx2_in_sel),
+ SOC_SINGLE("MIC1 Input Select", MIC1_INPUT_SELECT, 0, 0xff, 0),
+ SOC_SINGLE("MIC2 Input Select", MIC2_INPUT_SELECT, 0, 0xff, 0),
+ SOC_SINGLE("MIC2 to MIC1", MIC2_TO_MIC1, 0, 0x03, 0),
+ SOC_ENUM("I2S0 Input Select", soc_enum_i2s0_input_select),
+ SOC_ENUM("I2S1 Input Select", soc_enum_i2s1_input_select),
+ /* Routing of Side Tone and Analop Loop */
+ SOC_ENUM("APGA1 Source", soc_enum_apga1_source),
+ SOC_ENUM("APGA2 Source", soc_enum_apga2_source),
+ SOC_ENUM("APGA1 Enable", soc_enum_apga1_enable),
+ SOC_ENUM("APGA2 Enable", soc_enum_apga2_enable),
+ SOC_ENUM("DAC1 Side Tone", soc_enum_dac1_side_tone),
+ SOC_ENUM("DAC2 Side Tone", soc_enum_dac2_side_tone),
+ /* RX Volume Control */
+ SOC_SINGLE("RX-DPGA1 Gain", RX1_DPGA, 0, 0x43, 0),
+ SOC_SINGLE("RX-DPGA2 Gain", RX1_DPGA, 0, 0x43, 0),
+ SOC_SINGLE("RX-DPGA3 Gain", RX3_DPGA, 0, 0x43, 0),
+ SOC_SINGLE("LINE1 Gain", LINE1, LINEx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("LINE2 Gain", LINE2, LINEx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("SPKR1 Gain", SPKR1, SPKRx_GAIN_SHIFT, 0x16, 0),
+ SOC_SINGLE("SPKR2 Gain", SPKR2, SPKRx_GAIN_SHIFT, 0x16, 0),
+ SOC_SINGLE("EAR Gain", EAR_GAIN, EAR_GAIN_SHIFT, 0x12, 0),
+ SOC_SINGLE("AUXO1 Gain", AUXO1, AUXOx_GAIN_SHIFT, 0x0c, 0),
+ SOC_SINGLE("AUXO2 Gain", AUXO2, AUXOx_GAIN_SHIFT, 0x0c, 0),
+ SOC_SINGLE("AUXO3 Gain", AUXO3, AUXOx_GAIN_SHIFT, 0x0c, 0),
+ SOC_SINGLE("AUXO4 Gain", AUXO4, AUXOx_GAIN_SHIFT, 0x0c, 0),
+ /* TX Volume Control */
+ SOC_SINGLE("MIC1 Gain", MIC1_GAIN, MICx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("MIC2 Gain", MIC2_GAIN, MICx_GAIN_SHIFT, 0x0a, 0),
+ SOC_SINGLE("TX-DPGA1 Gain", TX_DPGA1, TX_DPGAx_SHIFT, 0x0f, 0),
+ SOC_SINGLE("TX-DPGA2 Gain", TX_DPGA2, TX_DPGAx_SHIFT, 0x0f, 0),
+ /* Volume Control of Side Tone and Analog Loop */
+ SOC_SINGLE("ST-PGA1 Gain", ST1_PGA, STx_PGA_SHIFT, 0x0a, 0),
+ SOC_SINGLE("ST-PGA2 Gain", ST2_PGA, STx_PGA_SHIFT, 0x0a, 0),
+ SOC_SINGLE("APGA1 Gain", ANALOG_LOOP_PGA1, APGAx_GAIN_SHIFT, 0x1d, 0),
+ SOC_SINGLE("APGA2 Gain", ANALOG_LOOP_PGA2, APGAx_GAIN_SHIFT, 0x1d, 0),
+ /* RX Properties */
+ SOC_ENUM("DAC1 Power Mode", soc_enum_dac1_power_mode),
+ SOC_ENUM("DAC2 Power Mode", soc_enum_dac2_power_mode),
+ SOC_ENUM("DAC3 Power Mode", soc_enum_dac3_power_mode),
+ SOC_ENUM("EAR Power Mode", soc_enum_ear_power_mode),
+ SOC_ENUM("AUXO12 Power Mode", soc_enum_auxo12_power_mode),
+ SOC_ENUM("AUXO34 Power Mode", soc_enum_auxo34_power_mode),
+ SOC_ENUM("LINE1 Inversion", soc_enum_line1_inversion),
+ SOC_ENUM("LINE2 Inversion", soc_enum_line2_inversion),
+ SOC_ENUM("AUXO1 Inversion", soc_enum_auxo1_inversion),
+ SOC_ENUM("AUXO2 Inversion", soc_enum_auxo2_inversion),
+ SOC_ENUM("AUXO3 Inversion", soc_enum_auxo3_inversion),
+ SOC_ENUM("AUXO4 Inversion", soc_enum_auxo4_inversion),
+ SOC_ENUM("AUXO1 Pulldown Resistor", soc_enum_auxo1_pulldown_resistor),
+ SOC_ENUM("AUXO2 Pulldown Resistor", soc_enum_auxo2_pulldown_resistor),
+ SOC_ENUM("SPKR1 Mode", soc_enum_spkr1_mode),
+ SOC_ENUM("SPKR2 Mode", soc_enum_spkr2_mode),
+ SOC_ENUM("PWM SPKR1N POL", soc_enum_pwm_spkr1n_pol),
+ SOC_ENUM("PWM SPKR1P POL", soc_enum_pwm_spkr1p_pol),
+ SOC_ENUM("PWM SPKR2N POL", soc_enum_pwm_spkr2n_pol),
+ SOC_ENUM("PWM SPKR2P POL", soc_enum_pwm_spkr2p_pol),
+ /* TX Properties */
+ SOC_SINGLE("MIC1 VMID", MIC1_VMID_SELECT, 0, 0x3f, 0),
+ SOC_SINGLE("MIC2 VMID", MIC2_VMID_SELECT, 0, 0x3f, 0),
+ SOC_ENUM("MBIAS1 PDN Impedance", soc_enum_mbias1_pdn_imp),
+ SOC_ENUM("MBIAS2 PDN Impedance", soc_enum_mbias2_pdn_imp),
+ SOC_ENUM("MBIAS2 Output Voltage", soc_enum_mbias2_out_v),
+ SOC_ENUM("MBIAS2 Internal Resistor", soc_enum_mbias2_int_r),
+ SOC_ENUM("MIC1 Input Impedance", soc_enum_mic1_in_imp),
+ SOC_ENUM("MIC2 Input Impedance", soc_enum_mic2_in_imp),
+ SOC_ENUM("TX1 HP Filter", soc_enum_tx1_hp_filter),
+ SOC_ENUM("TX2 HP Filter", soc_enum_tx2_hp_filter),
+ /* Side Tone and Analog Loop Properties */
+ SOC_ENUM("ST1 HP Filter", soc_enum_st1_hp_filter),
+ SOC_ENUM("ST2 HP Filter", soc_enum_st2_hp_filter),
+ /* I2S Interface Properties */
+ SOC_ENUM("I2S0 Word Length", soc_enum_i2s0_word_length),
+ SOC_ENUM("I2S1 Word Length", soc_enum_i2s1_word_length),
+ SOC_ENUM("I2S0 Mode", soc_enum_i2s0_mode),
+ SOC_ENUM("I2S1 Mode", soc_enum_i2s1_mode),
+ SOC_ENUM("I2S0 tri-state", soc_enum_i2s0_tristate),
+ SOC_ENUM("I2S1 tri-state", soc_enum_i2s1_tristate),
+ SOC_ENUM("I2S0 Pulldown Resistor", soc_enum_i2s0_pulldown_resistor),
+ SOC_ENUM("I2S1 Pulldown Resistor", soc_enum_i2s1_pulldown_resistor),
+ SOC_ENUM("I2S0 Sample Rate", soc_enum_i2s0_sample_rate),
+ SOC_ENUM("I2S1 Sample Rate", soc_enum_i2s1_sample_rate),
+ SOC_SINGLE("Interface Swap", INTERFACE_SWAP, 0, 0x03, 0),
+ /* Miscellaneous */
+ SOC_SINGLE("Negative Charge Pump", NEG_CHARGE_PUMP, 0, 0x03, 0)
+};
+
+/* count the number of 1 */
+#define count_ones(x) ({ \
+ int num; \
+ typeof(x) y = x; \
+ for (num = 0; y; y &= y - 1, num++) \
+ ; \
+ num; \
+ })
+
+enum enum_power {
+ POWER_OFF = 0,
+ POWER_ON = 1
+};
+
+enum enum_link {
+ UNLINK = 0,
+ LINK = 1
+};
+
+static enum enum_power get_widget_power_status(enum enum_widget widget)
+{
+ u8 val;
+
+ if (widget >= number_of_widgets)
+ return POWER_OFF;
+ val = read_reg(widget_pm_array[widget].reg);
+ if (val & (1 << widget_pm_array[widget].shift))
+ return POWER_ON;
+ else
+ return POWER_OFF;
+}
+
+static int count_powered_neighbors(const unsigned long *neighbors)
+{
+ unsigned long i;
+ int n = 0;
+ for_each_set_bit(i, neighbors, number_of_widgets) {
+ if (get_widget_power_status(i) == POWER_ON)
+ n++;
+ }
+ return n;
+}
+
+static int has_powered_neighbors(const unsigned long *neighbors)
+{
+ unsigned int i;
+ for_each_set_bit(i, neighbors, number_of_widgets) {
+ if (get_widget_power_status(i) == POWER_ON)
+ return 1;
+ }
+ return 0;
+}
+
+
+static int has_stacked_neighbors(const unsigned long *neighbors)
+{
+ unsigned long *stack_map = pm_stack_as_bitmap;
+ return bitmap_intersects(stack_map, neighbors, number_of_widgets);
+}
+
+static void power_widget_unlocked(enum enum_power onoff, enum enum_widget widget)
+{
+ enum enum_widget w;
+ int done;
+
+ if (widget >= number_of_widgets)
+ return;
+ if (get_widget_power_status(widget) == onoff)
+ return;
+
+ for (w = widget, done = 0; !done;) {
+ unsigned long i;
+ unsigned long *srcs = widget_pm_array[w].source_list;
+ unsigned long *sinks = widget_pm_array[w].sink_list;
+ dev_dbg(ab5500_dev, "%s: processing widget %s.\n",
+ __func__, widget_names[w]);
+
+ if (onoff == POWER_ON &&
+ !bitmap_empty(srcs, number_of_widgets) &&
+ !has_powered_neighbors(srcs)) {
+ pm_stack.stack[pm_stack.p++] = w;
+ for_each_set_bit(i, srcs, number_of_widgets) {
+ pm_stack.stack[pm_stack.p++] = i;
+ }
+ w = pm_stack.stack[--pm_stack.p];
+ continue;
+ } else if (onoff == POWER_OFF &&
+ has_powered_neighbors(sinks)) {
+ int n = 0;
+ pm_stack.stack[pm_stack.p++] = w;
+ for_each_set_bit(i, sinks, number_of_widgets) {
+ if (count_powered_neighbors(
+ widget_pm_array[i].source_list)
+ == 1 &&
+ get_widget_power_status(i) == POWER_ON) {
+ pm_stack.stack[pm_stack.p++] = i;
+ n++;
+ }
+ }
+ if (n) {
+ w = pm_stack.stack[--pm_stack.p];
+ continue;
+ } else
+ --pm_stack.p;
+ }
+ mask_set_reg(widget_pm_array[w].reg,
+ 1 << widget_pm_array[w].shift,
+ onoff == POWER_ON ? 0xff : 0);
+ dev_dbg(ab5500_dev, "%s: widget %s powered %s.\n",
+ __func__, widget_names[w],
+ onoff == POWER_ON ? "on" : "off");
+ if (onoff == POWER_ON &&
+ !bitmap_empty(sinks, number_of_widgets) &&
+ !has_powered_neighbors(sinks) &&
+ !has_stacked_neighbors(sinks)) {
+ for_each_set_bit(i, sinks, number_of_widgets) {
+ pm_stack.stack[pm_stack.p++] = i;
+ }
+ w = pm_stack.stack[--pm_stack.p];
+ continue;
+ } else if (onoff == POWER_OFF) {
+ for_each_set_bit(i, srcs, number_of_widgets) {
+ if (!has_powered_neighbors(
+ widget_pm_array[i].sink_list)
+ && get_widget_power_status(i) == POWER_ON
+ && !test_bit(i, pm_stack_as_bitmap)) {
+ pm_stack.stack[pm_stack.p++] = i;
+ }
+ }
+ }
+ if (pm_stack.p > 0)
+ w = pm_stack.stack[--pm_stack.p];
+ else
+ done = 1;
+ }
+}
+
+static void power_widget_locked(enum enum_power onoff,
+ enum enum_widget widget)
+{
+ if (mutex_lock_interruptible(&ab5500_pm_mutex)) {
+ dev_warn(ab5500_dev,
+ "%s: Signal received while waiting on the PM mutex.\n",
+ __func__);
+ return;
+ }
+ power_widget_unlocked(onoff, widget);
+ mutex_unlock(&ab5500_pm_mutex);
+}
+
+
+static void dump_registers(const char *where, ...)
+{
+ va_list ap;
+ va_start(ap, where);
+ do {
+ short reg = va_arg(ap, int);
+ if (reg < 0)
+ break;
+ dev_dbg(ab5500_dev, "%s from %s> 0x%02X : 0x%02X.\n",
+ __func__, where, reg, read_reg(reg));
+ } while (1);
+ va_end(ap);
+}
+
+/**
+ * update the link two widgets.
+ * @op: 1 - connect; 0 - disconnect
+ * @src: source of the connection
+ * @sink: sink of the connection
+ */
+static int update_widgets_link(enum enum_link op, enum enum_widget src,
+ enum enum_widget sink,
+ u8 reg, u8 mask, u8 newval)
+{
+ int ret = 0;
+
+ if (mutex_lock_interruptible(&ab5500_pm_mutex)) {
+ dev_warn(ab5500_dev, "%s: A signal is received while waiting on"
+ " the PM mutex.\n", __func__);
+ return -EINTR;
+ }
+
+ switch (op << 2 | test_bit(sink, widget_pm_array[src].sink_list) << 1 |
+ test_bit(src, widget_pm_array[sink].source_list)) {
+ case 3: /* UNLINK, sink in sink_list, src in source_list */
+ case 4: /* LINK, sink not in sink_list, src not in source_list */
+ break;
+ default:
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (((int)op) << 2 | get_widget_power_status(src) << 1 |
+ get_widget_power_status(sink)) {
+ case 3: /* op = 0, src on, sink on */
+ if (count_powered_neighbors(widget_pm_array[sink].source_list)
+ == 1)
+ power_widget_unlocked(POWER_OFF, sink);
+ mask_set_reg(reg, mask, newval);
+ break;
+ case 6: /* op = 1, src on, sink off */
+ mask_set_reg(reg, mask, newval);
+ power_widget_unlocked(POWER_ON, sink);
+ break;
+ default:
+ /* op = 0, src off, sink off */
+ /* op = 0, src off, sink on */
+ /* op = 0, src on, sink off */
+ /* op = 1, src off, sink off */
+ /* op = 1, src off, sink on */
+ /* op = 1, src on, sink on */
+ mask_set_reg(reg, mask, newval);
+ }
+ change_bit(sink, widget_pm_array[src].sink_list);
+ change_bit(src, widget_pm_array[sink].source_list);
+end:
+ mutex_unlock(&ab5500_pm_mutex);
+ return ret;
+};
+
+static enum enum_widget apga_source_translate(u8 reg_value)
+{
+ switch (reg_value) {
+ case 1:
+ return widget_mic1;
+ case 2:
+ return widget_mic2;
+ default:
+ return number_of_widgets;
+ }
+}
+
+static enum enum_widget adder_sink_translate(u8 reg)
+{
+ switch (reg) {
+ case EAR_ADDER:
+ return widget_ear;
+ case AUXO1_ADDER:
+ return widget_auxo1;
+ case AUXO2_ADDER:
+ return widget_auxo2;
+ case AUXO3_ADDER:
+ return widget_auxo3;
+ case AUXO4_ADDER:
+ return widget_auxo4;
+ case SPKR1_ADDER:
+ return widget_spkr1;
+ case SPKR2_ADDER:
+ return widget_spkr2;
+ case LINE1_ADDER:
+ return widget_line1;
+ case LINE2_ADDER:
+ return widget_line2;
+ default:
+ return number_of_widgets;
+ }
+}
+
+static int ab5500_add_widgets(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_new_controls(&codec->dapm, ab5500_dapm_widgets,
+ ARRAY_SIZE(ab5500_dapm_widgets));
+
+ snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon));
+
+ snd_soc_dapm_new_widgets(&codec->dapm);
+ return 0;
+}
+
+static void power_for_playback(enum enum_power onoff, int ifsel)
+{
+ dev_dbg(ab5500_dev, "%s: interface %d power %s.\n", __func__,
+ ifsel, onoff == POWER_ON ? "on" : "off");
+ if (mutex_lock_interruptible(&ab5500_pm_mutex)) {
+ dev_warn(ab5500_dev,
+ "%s: Signal received while waiting on the PM mutex.\n",
+ __func__);
+ return;
+ }
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_dld_l : widget_if1_dld_l);
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_dld_r : widget_if1_dld_r);
+ mutex_unlock(&ab5500_pm_mutex);
+}
+
+static void power_for_capture(enum enum_power onoff, int ifsel)
+{
+ dev_info(ab5500_dev, "%s: interface %d power %s", __func__,
+ ifsel, onoff == POWER_ON ? "on" : "off");
+ if (mutex_lock_interruptible(&ab5500_pm_mutex)) {
+ dev_warn(ab5500_dev,
+ "%s: Signal received while waiting on the PM mutex.\n",
+ __func__);
+ return;
+ }
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_uld_l : widget_if1_uld_l);
+ power_widget_unlocked(onoff, ifsel == 0 ?
+ widget_if0_uld_r : widget_if1_uld_r);
+ mutex_unlock(&ab5500_pm_mutex);
+}
+
+static int ab5500_add_controls(struct snd_soc_codec *codec)
+{
+ int err = 0, i, n = ARRAY_SIZE(ab5500_snd_controls);
+
+ pr_info("%s: %s called.\n", __FILE__, __func__);
+ for (i = 0; i < n; i++) {
+ err = snd_ctl_add(codec->card->snd_card, snd_ctl_new1(
+ &ab5500_snd_controls[i], codec));
+ if (err < 0) {
+ pr_err("%s failed to add control No.%d of %d.\n",
+ __func__, i, n);
+ return err;
+ }
+ }
+ return err;
+}
+
+static int ab5500_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ dai->playback_active : dai->capture_active) {
+ dev_err(dai->dev, "A %s stream is already active.\n",
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ "playback" : "capture");
+ return -EBUSY;
+ }
+ return 0;
+}
+
+static int ab5500_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params,
+ struct snd_soc_dai *dai)
+{
+ u8 val;
+ u8 reg = dai->id == 0 ? INTERFACE0 : INTERFACE1;
+
+ if (!ab5500_dev) {
+ pr_err("%s: The AB5500 codec driver not initialized.\n",
+ __func__);
+ return -EAGAIN;
+ }
+ dev_info(ab5500_dev, "%s called.\n", __func__);
+ switch (params_rate(hw_params)) {
+ case 8000:
+ val = I2Sx_SR_8000Hz;
+ break;
+ case 16000:
+ val = I2Sx_SR_16000Hz;
+ break;
+ case 44100:
+ val = I2Sx_SR_44100Hz;
+ break;
+ case 48000:
+ val = I2Sx_SR_48000Hz;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ !dai->capture_active : !dai->playback_active) {
+
+ mask_set_reg(reg, I2Sx_SR_MASK, val << I2Sx_SR_SHIFT);
+ if ((read_reg(reg) & I2Sx_MODE_MASK) == 0) {
+ mask_set_reg(reg, MASTER_GENx_PWR_MASK,
+ 1 << MASTER_GENx_PWR_SHIFT);
+ }
+ }
+ return 0;
+}
+
+static int ab5500_pcm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ dev_dbg(ab5500_dev, "%s called.\n", __func__);
+ /* Configure registers for either playback or capture */
+ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
+ !(ab5500_codec_privates[dai->id].playback_active == true)) {
+ power_for_playback(POWER_ON, dai->id);
+ ab5500_codec_privates[dai->id].playback_active = true;
+ } else if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) &&
+ !(ab5500_codec_privates[dai->id].capture_active == true)) {
+ power_for_capture(POWER_ON, dai->id);
+ ab5500_codec_privates[dai->id].capture_active = true;
+ }
+ dump_registers(__func__, RX1, AUXO1_ADDER, RX2,
+ AUXO2_ADDER, RX1_DPGA, RX2_DPGA, AUXO1, AUXO2, -1);
+ return 0;
+}
+
+static void ab5500_pcm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ u8 iface = dai->id == 0 ? INTERFACE0 : INTERFACE1;
+ dev_info(ab5500_dev, "%s called.\n", __func__);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ power_for_playback(POWER_OFF, dai->id);
+ ab5500_codec_privates[dai->id].playback_active = false;
+ } else {
+ power_for_capture(POWER_OFF, dai->id);
+ ab5500_codec_privates[dai->id].capture_active = false;
+
+ }
+ if (!dai->playback_active && !dai->capture_active &&
+ (read_reg(iface) & I2Sx_MODE_MASK) == 0)
+ mask_set_reg(iface, MASTER_GENx_PWR_MASK, 0);
+}
+
+static int ab5500_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ return 0;
+}
+
+static int ab5500_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ u8 iface = (codec_dai->id == 0) ? INTERFACE0 : INTERFACE1;
+ u8 val = 0;
+ dev_info(ab5500_dev, "%s called.\n", __func__);
+
+ switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
+ SND_SOC_DAIFMT_MASTER_MASK)) {
+
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
+ val |= 1 << I2Sx_MODE_SHIFT;
+ break;
+
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
+ break;
+
+ default:
+ dev_warn(ab5500_dev, "AB5500_dai: unsupported DAI format "
+ "0x%x\n", fmt);
+ return -EINVAL;
+ }
+ if (codec_dai->playback_active && codec_dai->capture_active) {
+ if ((read_reg(iface) & I2Sx_MODE_MASK) == val)
+ return 0;
+ else {
+ dev_err(ab5500_dev,
+ "%s: DAI format set differently "
+ "by an existing stream.\n", __func__);
+ return -EINVAL;
+ }
+ }
+ mask_set_reg(iface, I2Sx_MODE_MASK, val);
+ return 0;
+}
+
+struct snd_soc_dai_driver ab5500_dai_drv[] = {
+ {
+ .name = "ab5500-codec-dai.0",
+ .id = 0,
+ .playback = {
+ .stream_name = "ab5500.0 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB5500_SUPPORTED_RATE,
+ .formats = AB5500_SUPPORTED_FMT,
+ },
+ .capture = {
+ .stream_name = "ab5500.0 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB5500_SUPPORTED_RATE,
+ .formats = AB5500_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .startup = ab5500_pcm_startup,
+ .prepare = ab5500_pcm_prepare,
+ .hw_params = ab5500_pcm_hw_params,
+ .shutdown = ab5500_pcm_shutdown,
+ .set_sysclk = ab5500_set_dai_sysclk,
+ .set_fmt = ab5500_set_dai_fmt,
+ }
+ },
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "ab5500-codec-dai.1",
+ .id = 1,
+ .playback = {
+ .stream_name = "ab5500.1 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB5500_SUPPORTED_RATE,
+ .formats = AB5500_SUPPORTED_FMT,
+ },
+ .capture = {
+ .stream_name = "ab5500.1 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = AB5500_SUPPORTED_RATE,
+ .formats = AB5500_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .startup = ab5500_pcm_startup,
+ .prepare = ab5500_pcm_prepare,
+ .hw_params = ab5500_pcm_hw_params,
+ .shutdown = ab5500_pcm_shutdown,
+ .set_sysclk = ab5500_set_dai_sysclk,
+ .set_fmt = ab5500_set_dai_fmt,
+ }
+ },
+ .symmetric_rates = 1,
+ }
+};
+
+static int ab5500_codec_probe(struct snd_soc_codec *codec)
+{
+ int ret = ab5500_add_controls(codec);
+ if (ret < 0)
+ return ret;
+ ab5500_add_widgets(codec);
+ return 0;
+}
+
+static int ab5500_codec_remove(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_free(&codec->dapm);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ab5500_codec_suspend(struct snd_soc_codec *codec,
+ pm_message_t state)
+{
+ mask_set_reg(CLOCK, CLOCK_ENABLE_MASK, 0);
+ return 0;
+}
+
+static int ab5500_codec_resume(struct snd_soc_codec *codec)
+{
+ mask_set_reg(CLOCK, CLOCK_ENABLE_MASK, 0xff);
+ return 0;
+}
+#else
+#define ab5500_codec_resume NULL
+#define ab5500_codec_suspend NULL
+#endif
+
+/**
+ This function is only called by the SOC framework to
+ set registers associated to the mixer controls.
+*/
+static int ab5500_codec_write_reg(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ if (reg < MIC_BIAS1 || reg > INTERFACE_SWAP)
+ return -EINVAL;
+ switch (reg) {
+ u8 diff, oldval;
+ case ANALOG_LOOP_PGA1:
+ case ANALOG_LOOP_PGA2: {
+ enum enum_widget apga = reg == ANALOG_LOOP_PGA1 ?
+ widget_apga1 : widget_apga2;
+
+ oldval = read_reg(reg);
+ diff = value ^ oldval;
+
+ /*
+ * The APGA is to be turned on/off. The power bit and the
+ * other bits in the same register won't be changed at the
+ * same time since they belong to different controls.
+ */
+ if (diff & (1 << APGAx_PWR_SHIFT)) {
+ power_widget_locked(value >> APGAx_PWR_SHIFT & 1,
+ apga);
+ } else if (diff & APGAx_MUX_MASK) {
+ enum enum_widget old_source =
+ apga_source_translate(oldval);
+ enum enum_widget new_source =
+ apga_source_translate(value);
+ update_widgets_link(UNLINK, old_source, apga,
+ reg, APGAx_MUX_MASK, 0);
+ update_widgets_link(LINK, new_source, apga,
+ reg, APGAx_MUX_MASK, value);
+ } else {
+ set_reg(reg, value);
+ }
+ break;
+ }
+
+ case EAR_ADDER:
+ case AUXO1_ADDER:
+ case AUXO2_ADDER:
+ case AUXO3_ADDER:
+ case AUXO4_ADDER:
+ case SPKR1_ADDER:
+ case SPKR2_ADDER:
+ case LINE1_ADDER:
+ case LINE2_ADDER: {
+ int i;
+ enum enum_widget widgets[] = {
+ widget_dac1, widget_dac2, widget_dac3,
+ widget_apga1, widget_apga2
+ };
+ oldval = read_reg(reg);
+ diff = value ^ oldval;
+ for (i = 0; diff; i++) {
+ if (!(diff & 1 << i))
+ continue;
+ diff ^= 1 << i;
+ update_widgets_link(value >> i & 1, widgets[i],
+ adder_sink_translate(reg),
+ reg, 1 << i, value);
+ }
+ break;
+ }
+ case AB5500_VIRTUAL_REG3:
+ oldval = read_reg(reg);
+ diff = value ^ oldval;
+ /*
+ * The following changes won't take place in the same call,
+ * since they are arranged into different mixer controls.
+ */
+
+ /* changed between the two amplifier modes */
+ if (hweight8(diff & SPKR1_MODE_MASK) == 2) {
+ set_reg(reg, value);
+ break;
+ }
+
+ if (diff & SPKR1_MODE_MASK) {
+ update_widgets_link(
+ UNLINK,
+ (oldval & SPKR1_MODE_MASK) == 0 ?
+ widget_pwm_spkr1 : widget_spkr1_adder,
+ widget_spkr1,
+ reg, SPKR1_MODE_MASK, value);
+ update_widgets_link(
+ LINK,
+ (value & SPKR1_MODE_MASK) == 0 ?
+ widget_pwm_spkr1 : widget_spkr1_adder,
+ widget_spkr1,
+ DUMMY_REG, 0, 0);
+
+ }
+ if (diff & SPKR2_MODE_MASK) {
+ update_widgets_link(
+ UNLINK,
+ (oldval & SPKR2_MODE_MASK) == 0 ?
+ widget_pwm_spkr2 : widget_spkr2_adder,
+ widget_spkr2,
+ reg, SPKR2_MODE_MASK, value);
+ update_widgets_link(
+ LINK,
+ (value & SPKR2_MODE_MASK) == 0 ?
+ widget_pwm_spkr2 : widget_spkr2_adder,
+ widget_spkr2,
+ DUMMY_REG, 0, 0);
+
+ }
+ break;
+
+ case AB5500_VIRTUAL_REG4:
+ /* configure PWMCTRL_SPKR1, PWMCTRL_SPKR2, etc. */
+ break;
+ default:
+ set_reg(reg, value);
+ }
+ return 0;
+}
+
+static unsigned int ab5500_codec_read_reg(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return read_reg(reg);
+}
+
+
+static struct snd_soc_codec_driver ab5500_codec_drv = {
+ .probe = ab5500_codec_probe,
+ .remove = ab5500_codec_remove,
+ .suspend = ab5500_codec_suspend,
+ .resume = ab5500_codec_resume,
+ .read = ab5500_codec_read_reg,
+ .write = ab5500_codec_write_reg,
+};
+EXPORT_SYMBOL_GPL(ab5500_codec_drv);
+
+static inline void init_playback_route(void)
+{
+ /* if0_dld_l -> rx1 -> dac1 -> auxo1 */
+ update_widgets_link(LINK, widget_if0_dld_l, widget_rx1,
+ RX1, RXx_DATA_MASK, 0x03 << RXx_DATA_SHIFT);
+ update_widgets_link(LINK, widget_rx1, widget_dac1, 0, 0, 0);
+ update_widgets_link(LINK, widget_dac1, widget_auxo1,
+ AUXO1_ADDER, DAC1_TO_X_MASK, 0xff);
+
+ /* if0_dld_r -> rx2 -> dac2 -> auxo2 */
+ update_widgets_link(LINK, widget_if0_dld_r, widget_rx2,
+ RX2, RXx_DATA_MASK, 0x04 << RXx_DATA_SHIFT);
+ update_widgets_link(LINK, widget_rx2, widget_dac2, 0, 0, 0);
+ update_widgets_link(LINK, widget_dac2, widget_auxo2,
+ AUXO2_ADDER, DAC2_TO_X_MASK, 0xff);
+
+}
+
+static inline void init_capture_route(void)
+{
+ /* mic bias - > mic2 inputs */
+ update_widgets_link(LINK, widget_micbias1, widget_mic2p2,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_micbias1, widget_mic2n2,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_micbias2, widget_mic2p2,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_micbias2, widget_mic2n2,
+ 0, 0, 0);
+
+
+ /* mic2 inputs -> mic2 */
+ update_widgets_link(LINK, widget_mic2p2, widget_mic2,
+ MIC2_INPUT_SELECT, MICxP2_SEL_MASK, 0xff);
+ update_widgets_link(LINK, widget_mic2n2, widget_mic2,
+ MIC2_INPUT_SELECT, MICxN2_SEL_MASK, 0xff);
+
+ /* mic2 -> adc2 -> tx2 */
+ update_widgets_link(LINK, widget_mic2, widget_adc2,
+ 0, 0, 0);
+ update_widgets_link(LINK, widget_adc2, widget_tx2,
+ TX2, TXx_MUX_MASK, 0);
+
+ /* tx2 -> if0_uld_l & if0_uld_r */
+ update_widgets_link(LINK, widget_tx2, widget_if0_uld_l,
+ INTERFACE0_ULD, I2Sx_ULD_L_MASK,
+ 0x02 << I2Sx_ULD_L_SHIFT);
+ update_widgets_link(LINK, widget_tx2, widget_if0_uld_r,
+ INTERFACE0_ULD, I2Sx_ULD_R_MASK,
+ 0x02 << I2Sx_ULD_R_SHIFT);
+
+ /* mic2 -> apga2 */
+ update_widgets_link(LINK, widget_mic2, widget_apga2,
+ ANALOG_LOOP_PGA2, APGAx_MUX_MIC2_MASK,
+ 1 << APGAx_MUX_MIC2_SHIFT);
+
+ /* apga2 -> auxo1 & auxo2 */
+ update_widgets_link(LINK, widget_apga2, widget_auxo1,
+ AUXO1_ADDER, APGA2_TO_X_MASK,
+ 1 << APGA2_TO_X_SHIFT);
+ update_widgets_link(LINK, widget_apga2, widget_auxo2,
+ AUXO2_ADDER, APGA2_TO_X_MASK,
+ 1 << APGA2_TO_X_SHIFT);
+}
+
+static inline void init_playback_gain(void)
+{
+ /* 0x43, 0x0C: pure gain values */
+ mask_set_reg(RX1_DPGA, RXx_DPGA_MASK,
+ 0x43 << RXx_DPGA_SHIFT);
+ mask_set_reg(RX2_DPGA, RXx_DPGA_MASK,
+ 0x43 << RXx_DPGA_SHIFT);
+ mask_set_reg(AUXO1, AUXOx_GAIN_MASK, 0x0C << AUXOx_GAIN_SHIFT);
+ mask_set_reg(AUXO2, AUXOx_GAIN_MASK, 0x0C << AUXOx_GAIN_SHIFT);
+}
+
+static inline void init_capture_gain(void)
+{
+ /* 0x06, 0x0f: pure gain values */
+ mask_set_reg(MIC1_GAIN, MICx_GAIN_MASK, 0x06 << MICx_GAIN_SHIFT);
+ mask_set_reg(TX_DPGA1, TX_DPGAx_MASK, 0x0f << TX_DPGAx_SHIFT);
+}
+
+static int __devinit ab5500_platform_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ u8 reg;
+ struct ab5500_codec_dai_data *codec_drvdata;
+
+ pr_info("%s invoked with pdev = %p.\n", __func__, pdev);
+ ab5500_dev = &pdev->dev;
+ codec_drvdata = kzalloc(sizeof(struct ab5500_codec_dai_data),
+ GFP_KERNEL);
+ if (codec_drvdata == NULL)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, codec_drvdata);
+ ret = snd_soc_register_codec(ab5500_dev, &ab5500_codec_drv,
+ ab5500_dai_drv,
+ ARRAY_SIZE(ab5500_dai_drv));
+ if (ret < 0) {
+ dev_err(ab5500_dev, "%s: Failed to register codec. "
+ "Error %d.\n", __func__, ret);
+ snd_soc_unregister_codec(ab5500_dev);
+ kfree(codec_drvdata);
+ }
+ /* Initialize the codec registers */
+ for (reg = AB5500_FIRST_REG; reg <= AB5500_LAST_REG; reg++)
+ set_reg(reg, 0);
+
+ mask_set_reg(CLOCK, CLOCK_REF_SELECT_MASK | CLOCK_ENABLE_MASK,
+ 1 << CLOCK_REF_SELECT_SHIFT | 1 << CLOCK_ENABLE_SHIFT);
+ printk(KERN_ERR "Clock Setting ab5500\n");
+ init_playback_route();
+ init_playback_gain();
+ init_capture_route();
+ init_capture_gain();
+ memset(&pm_stack, 0, sizeof(pm_stack));
+ return ret;
+}
+
+static int __devexit ab5500_platform_remove(struct platform_device *pdev)
+{
+ pr_info("%s called.\n", __func__);
+ mask_set_reg(CLOCK, CLOCK_ENABLE_MASK, 0);
+ snd_soc_unregister_codec(ab5500_dev);
+ kfree(platform_get_drvdata(pdev));
+ ab5500_dev = NULL;
+ return 0;
+}
+
+static int ab5500_platform_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+static int ab5500_platform_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver ab5500_platform_driver = {
+ .driver = {
+ .name = "ab5500-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab5500_platform_probe,
+ .remove = ab5500_platform_remove,
+ .suspend = ab5500_platform_suspend,
+ .resume = ab5500_platform_resume,
+};
+
+static int __devinit ab5500_init(void)
+{
+ int ret;
+
+ pr_info("%s called.\n", __func__);
+
+ /* Register codec platform driver. */
+ ret = platform_driver_register(&ab5500_platform_driver);
+ if (ret) {
+ pr_err("%s: Error %d: Failed to register codec platform "
+ "driver.\n", __func__, ret);
+ }
+ return ret;
+}
+
+static void __devexit ab5500_exit(void)
+{
+ pr_info("%s called.\n", __func__);
+ platform_driver_unregister(&ab5500_platform_driver);
+}
+
+module_init(ab5500_init);
+module_exit(ab5500_exit);
+
+MODULE_DESCRIPTION("AB5500 Codec driver");
+MODULE_AUTHOR("Xie Xiaolei <xie.xiaolei@stericsson.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ab5500.h b/sound/soc/codecs/ab5500.h
new file mode 100644
index 00000000000..c410259d73a
--- /dev/null
+++ b/sound/soc/codecs/ab5500.h
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Register definitions for AB5500 codec
+ * Author: Xie Xiaolei <xie.xiaolei@etericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#ifndef AB5500_CODEC_REGISTERS_H
+#define AB5500_CODEC_REGISTERS_H
+
+#define AB5500_SUPPORTED_RATE (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
+ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+
+#define AB5500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+
+/* MIC BIAS */
+
+#define MIC_BIAS1 0x00
+#define MIC_BIAS2 0x01
+#define MBIAS2_OUT_V_MASK 0x04
+#define MBIAS2_OUT_V_SHIFT 2
+#define MBIASx_PWR_MASK 0x02
+#define MBIASx_PWR_SHIFT 1
+#define MBIASx_PDN_IMP_MASK 0x01
+#define MBIASx_PDN_IMP_SHIFT 0
+
+#define MIC_BIAS2_VAD 0x02
+#define MBIAS2_R_INT_MASK 0x01
+#define MBIAS2_R_INT_SHIFT 0
+
+/* MIC */
+#define MIC1_GAIN 0x03
+#define MIC2_GAIN 0x04
+#define MICx_GAIN_MASK 0xF0
+#define MICx_GAIN_SHIFT 4
+#define MICx_IN_IMP_MASK 0x0C
+#define MICx_IN_IMP_SHIFT 2
+#define MICx_PWR_MASK 0x01
+#define MICx_PWR_SHIFT 0
+
+#define MIC1_INPUT_SELECT 0x05
+#define MIC2_INPUT_SELECT 0x06
+#define MICxP1_SEL_MASK 0x80
+#define MICxP1_SEL_SHIFT 7
+#define MICxN1_SEL_MASK 0x40
+#define MICxN1_SEL_SHIFT 6
+#define MICxP2_SEL_MASK 0x20
+#define MICxP2_SEL_SHIFT 5
+#define MICxN2_SEL_MASK 0x10
+#define MICxN2_SEL_SHIFT 4
+#define LINEIN_SEL_MASK 0x03
+#define LINEIN_SEL_SHIFT 0
+
+#define MIC1_VMID_SELECT 0x07
+#define MIC2_VMID_SELECT 0x08
+#define VMIDx_ENABLE_MASK 0xC0
+#define VMIDx_ENABLE_SHIFT 6
+#define VMIDx_LINEIN1_N_MASK 0x20
+#define VMIDx_LINEIN1_N_SHIFT 5
+#define VMIDx_LINEIN2_N_MASK 0x10
+#define VMIDx_LINEIN2_N_SHIFT 4
+#define VMIDx_MICxP1_MASK 0x08
+#define VMIDx_MICxP1_SHIFT 3
+#define VMIDx_MICxP2_MASK 0x04
+#define VMIDx_MICxP2_SHIFT 2
+#define VMIDx_MICxN1_MASK 0x02
+#define VMIDx_MICxN1_SHIFT 1
+#define VMIDx_MICxN2_MASK 0x01
+#define VMIDx_MICxN2_SHIFT 0
+
+#define MIC2_TO_MIC1 0x09
+#define MIC2_TO_MIC1_MASK 0x03
+#define MIC2_TO_MIC1_SHIFT 0
+
+/* Analog Loop */
+#define ANALOG_LOOP_PGA1 0x0A
+#define ANALOG_LOOP_PGA2 0x0B
+#define APGAx_GAIN_MASK 0xF8
+#define APGAx_GAIN_SHIFT 3
+#define APGAx_PWR_MASK 0x04
+#define APGAx_PWR_SHIFT 2
+#define APGAx_MUX_MASK 0x03
+#define APGAx_MUX_SHIFT 0
+#define APGAx_MUX_MIC1_MASK 0x01
+#define APGAx_MUX_MIC1_SHIFT 0
+#define APGAx_MUX_MIC2_MASK 0x02
+#define APGAx_MUX_MIC2_SHIFT 1
+
+#define APGA_VMID_SELECT 0x0C
+#define VMID_APGA1_ENABLE_MASK 0xC0
+#define VMID_APGA1_ENABLE_SHIFT 6
+#define VMID_APGA1_LINEIN1_MASK 0x20
+#define VMID_APGA1_LINEIN1_SHIFT 5
+#define VMID_APGA2_ENABLE_MASK 0x0C
+#define VMID_APGA2_ENABLE_SHIFT 2
+#define VMID_APGA2_LINEIN2_MASK 0x02
+#define VMID_APGA2_LINEIN2_SHIFT 1
+
+/* Output Amplifiers */
+#define EAR_PWR 0x0D
+#define EAR_PWR_MODE_MASK 0xC0
+#define EAR_PWR_MODE_SHIFT 6
+#define EAR_PWR_VMID_MASK 0x30
+#define EAR_PWR_VMID_SHIFT 4
+#define EAR_PWR_MASK 0x01
+#define EAR_PWR_SHIFT 0
+
+#define EAR_GAIN 0x0E
+#define EAR_GAIN_MASK 0x1F
+#define EAR_GAIN_SHIFT 0
+
+#define AUXO1 0x0F
+#define AUXO2 0x10
+#define AUXO3 0x11
+#define AUXO4 0x12
+#define AUXOx_PWR_MASK 0x80
+#define AUXOx_PWR_SHIFT 7
+#define AUXOx_INV_MASK 0x40
+#define AUXOx_INV_SHIFT 6
+#define AUXOx_PULLDOWN_MASK 0x20
+#define AUXOx_PULLDOWN_SHIFT 5
+#define AUXOx_GAIN_MASK 0x0F
+#define AUXOx_GAIN_SHIFT 0
+
+#define AUXO12_PWR_MODE 0x13
+#define AUXO34_PWR_MODE 0x14
+#define AUXOxy_PWR_MODE_MASK 0x07
+#define AUXOxy_PWR_MODE_SHIFT 0
+
+#define NEG_CHARGE_PUMP 0x15
+#define NEG_CHARGE_PUMP_MODE_MASK 0x02
+#define NEG_CHARGE_PUMP_MODE_SHIFT 1
+#define NEG_CHARGE_PUMP_PWR_MASK 0x01
+#define NEG_CHARGE_PUMP_PWR_SHIFT 0
+
+#define ENV_THR 0x16
+#define ENV_THR_HIGH_MASK 0xF0
+#define ENV_THR_HIGH_SHIFT 4
+#define ENV_THR_LOW_MASK 0x0F
+#define ENV_THR_LOW_SHIFT 0
+
+#define ENV_DECAY_TIME 0x17
+#define ENV_DECAY_TIME_CP_LV_MASK 0x20
+#define ENV_DECAY_TIME_CP_LV_SHIFT 5
+#define ENV_DECAY_TIME_DET_CP_MASK 0x10
+#define ENV_DECAY_TIME_DET_CP_SHIFT 4
+#define ENV_DECAY_TIME_MASK 0x0F
+#define ENV_DECAY_TIME_SHIFT 0
+
+#define DC_CANCEL 0x18
+#define DC_CANCEL_SPKR2_MASK 0x10
+#define DC_CANCEL_SPKR2_SHIFT 4
+#define DC_CANCEL_SPKR1_MASK 0x08
+#define DC_CANCEL_SPKR1_SHIFT 3
+#define DC_CANCEL_AUXO34_MASK 0x04
+#define DC_CANCEL_AUXO34_SHIFT 2
+#define DC_CANCEL_AUXO12_MASK 0x02
+#define DC_CANCEL_AUXO12_SHIFT 1
+#define DC_CANCEL_OFFSET_CLOCK_MASK 0x01
+#define DC_CANCEL_OFFSET_CLOCK_SHIFT 0
+
+#define SPKR1 0x19
+#define SPKR2 0x1A
+#define SPKRx_PWR_MASK 0xC0
+#define SPKRx_PWR_SHIFT 6
+#define SPKRx_PWR_VBR_VALUE 0x40
+#define SPKRx_PWR_CLS_D_VALUE 0x80
+#define SPKRx_PWR_CLS_AB_VALUE 0xC0
+#define SPKR1_VMID_MASK 0x20
+#define SPKR1_VMID_SHIFT 5
+#define SPKRx_GAIN_MASK 0x1F
+#define SPKRx_GAIN_SHIFT 0
+
+#define SPKR_OVCR 0x1B
+#define SPKR_OVCR_PROT2_MASK 0x80
+#define SPKR_OVCR_PROT2_SHIFT 7
+#define SPKR_OVCR_TRIM2_MASK 0x70
+#define SPKR_OVCR_TRIM2_SHIFT 4
+#define SPKR_OVCR_PROT1_MASK 0x08
+#define SPKR_OVCR_PROT1_SHIFT 3
+#define SPKR_OVCR_TRIM1_MASK 0x07
+#define SPKR_OVCR_TRIM1_SHIFT 0
+
+#define PWMCTRL_SPKR1 0x1C
+#define PWMCTRL_SPKR2 0x1F
+#define PWMCTRL_SPKRx_N1_POL_MASK 0x80
+#define PWMCTRL_SPKRx_N1_POL_SHIFT 7
+#define PWMCTRL_SPKRx_P1_POL_MASK 0x40
+#define PWMCTRL_SPKRx_P1_POL_SHIFT 6
+#define PWMCTRL_SPKRx_MASK 0x04
+#define PWMCTRL_SPKRx_SHIFT 2
+#define PWMCTRL_SPKRxN_MASK 0x02
+#define PWMCTRL_SPKRxN_SHIFT 1
+#define PWMCTRL_SPKRxP_MASK 0x01
+#define PWMCTRL_SPKRxP_SHIFT 0
+
+#define PWM_SPKR1N 0x1D
+#define PWM_SPKR2N 0x20
+#define PWM_SPKR1P 0x1E
+#define PWM_SPKR2P 0x21
+#define PWM_SPKRxy_DUT_CYC_MASK 0xFF
+#define PWM_SPKRxy_DUT_CYC_SHIFT 0
+
+#define SPKR1_CLK_DIV 0x22
+#define SPKR2_CLK_DIV 0x23
+#define SPKRx_CLK_DIV_MASK 0x3F
+#define SPKRx_CLK_DIV_SHIFT 0
+
+#define LINE1 0x24
+#define LINE2 0x25
+#define LINEx_PWR_MASK 0x80
+#define LINEx_PWR_SHIFT 7
+#define LINEx_INV_MASK 0x40
+#define LINEx_INV_SHIFT 6
+#define LINEx_TO_USB_MASK 0x20
+#define LINEx_TO_USB_SHIFT 5
+#define LINEx_VMID_BUFF_MASK 0x10
+#define LINEx_VMID_BUFF_SHIFT 4
+#define LINEx_GAIN_MASK 0x0F
+#define LINEx_GAIN_SHIFT 0
+
+#define USB_AUDIO 0x26
+#define USB_AUDIO_MIC_MUX_MASK 0x03
+#define USB_AUDIO_MIC_MUX_SHIFT 0
+
+#define EAR_ADDER 0x28
+#define AUXO1_ADDER 0x29
+#define AUXO2_ADDER 0x2A
+#define AUXO3_ADDER 0x2B
+#define AUXO4_ADDER 0x2C
+#define SPKR1_ADDER 0x2D
+#define SPKR2_ADDER 0x2E
+#define LINE1_ADDER 0x2F
+#define LINE2_ADDER 0x30
+#define APGA2_TO_X_MASK 0x10
+#define APGA2_TO_X_SHIFT 4
+#define APGA1_TO_X_MASK 0x08
+#define APGA1_TO_X_SHIFT 3
+#define DAC3_TO_X_MASK 0x04
+#define DAC3_TO_X_SHIFT 2
+#define DAC2_TO_X_MASK 0x02
+#define DAC2_TO_X_SHIFT 1
+#define DAC1_TO_X_MASK 0x01
+#define DAC1_TO_X_SHIFT 0
+
+#define EAR_TO_MIC2 0x31
+#define SPKR1_TO_MIC2 0x32
+#define SPKR2_TO_MIC2 0x33
+#define EAR_TO_MIC2_MASK 0x01
+#define EAR_TO_MIC2_SHIFT 0
+
+#define ADC_LOW_PWR 0x35
+#define ADC_LOW_PWR_MASK 0x01
+#define ADC_LOW_PWR_SHIFT 0
+
+#define TX1 0x36
+#define TX2 0x37
+#define TXx_MUX_MASK 0x60
+#define TXx_MUX_SHIFT 6
+#define TXx_FS_MASK 0x10
+#define TXx_FS_SHIFT 4
+#define TXx_HP_FILTER_MASK 0x0C
+#define TXx_HP_FILTER_SHIFT 2
+#define TXx_PWR_MASK 0x02
+#define TXx_PWR_SHIFT 1
+#define ADCx_PWR_MASK 0x01
+#define ADCx_PWR_SHIFT 0
+
+#define RX1 0x38
+#define RX2 0x39
+#define RX3 0x3A
+#define RXx_DATA_MASK 0x70
+#define RXx_DATA_SHIFT 4
+#define RXx_PWR_MASK 0x08
+#define RXx_PWR_SHIFT 3
+#define DACx_PWR_MASK 0x04
+#define DACx_PWR_SHIFT 2
+#define DACx_PWR_MODE_MASK 0x03
+#define DACx_PWR_MODE_SHIFT 0
+
+#define TX_DPGA1 0x3B
+#define TX_DPGA2 0x3C
+#define TX_DPGAx_MASK 0x0F
+#define TX_DPGAx_SHIFT 0
+
+#define RX1_DPGA 0x3D
+#define RX2_DPGA 0x3E
+#define RX3_DPGA 0x3F
+#define RXx_DPGA_MASK 0x7F
+#define RXx_DPGA_SHIFT 0
+
+#define ST1_PGA 0x40
+#define ST2_PGA 0x41
+#define STx_HP_FILTER_MASK 0x60
+#define STx_HP_FILTER_SHIFT 6
+#define STx_MUX_MASK 0x10
+#define STx_MUX_SHIFT 4
+#define STx_PGA_MASK 0x0F
+#define STx_PGA_SHIFT 0
+
+#define CLOCK 0x42
+#define CLOCK_REF_SELECT_MASK 0x02
+#define CLOCK_REF_SELECT_SHIFT 1
+#define CLOCK_ENABLE_MASK 0x01
+#define CLOCK_ENABLE_SHIFT 0
+
+#define INTERFACE0 0x43
+#define INTERFACE1 0x45
+#define I2Sx_WORDLENGTH_MASK 0x40
+#define I2Sx_WORDLENGTH_SHIFT 6
+#define MASTER_GENx_PWR_MASK 0x20
+#define MASTER_GENx_PWR_SHIFT 5
+#define I2Sx_MODE_MASK 0x10
+#define I2Sx_MODE_SHIFT 4
+#define I2Sx_TRISTATE_MASK 0x08
+#define I2Sx_TRISTATE_SHIFT 3
+#define I2Sx_PULLDOWN_MASK 0x04
+#define I2Sx_PULLDOWN_SHIFT 2
+#define I2Sx_SR_MASK 0x03
+#define I2Sx_SR_SHIFT 0
+#define I2Sx_SR_8000Hz 0
+#define I2Sx_SR_16000Hz 1
+#define I2Sx_SR_44100Hz 2
+#define I2Sx_SR_48000Hz 3
+
+#define INTERFACE0_ULD 0x44
+#define INTERFACE1_ULD 0x46
+#define I2Sx_ULD_R_MASK 0x70
+#define I2Sx_ULD_R_SHIFT 4
+#define I2Sx_ULD_L_MASK 0x07
+#define I2Sx_ULD_L_SHIFT 0
+
+#define INTERFACE_SWAP 0x47
+#define IO_SWAP0_MASK 0x02
+#define IO_SWAP0_SHIFT 1
+#define IO_SWAP1_MASK 0x01
+#define IO_SWAP1_SHIFT 0
+
+#define AB5500_FIRST_REG MIC_BIAS1
+#define AB5500_LAST_REG INTERFACE_SWAP
+
+#define AB5500_VIRTUAL_REG1 (AB5500_LAST_REG + 1)
+#define IF0_DLD_L_PW_SHIFT 0
+#define IF0_DLD_R_PW_SHIFT 1
+#define IF0_ULD_L_PW_SHIFT 2
+#define IF0_ULD_R_PW_SHIFT 3
+#define IF1_DLD_L_PW_SHIFT 4
+#define IF1_DLD_R_PW_SHIFT 5
+#define IF1_ULD_L_PW_SHIFT 6
+#define IF1_ULD_R_PW_SHIFT 7
+
+#define AB5500_VIRTUAL_REG2 (AB5500_LAST_REG + 2)
+#define MIC1P1_PW_SHIFT 0
+#define MIC1N1_PW_SHIFT 1
+#define MIC1P2_PW_SHIFT 2
+#define MIC1N2_PW_SHIFT 3
+#define MIC2P1_PW_SHIFT 4
+#define MIC2N1_PW_SHIFT 5
+#define MIC2P2_PW_SHIFT 6
+#define MIC2N2_PW_SHIFT 7
+
+#define AB5500_VIRTUAL_REG3 (AB5500_LAST_REG + 3)
+#define SPKR1_MODE_MASK 0x03
+#define SPKR1_MODE_SHIFT 0
+#define SPKR1_MODE_VBR_VALUE 0
+#define SPKR1_MODE_CLS_D_VALUE 1
+#define SPKR1_MODE_CLS_AB_VALUE 2
+#define SPKR1_ADDER_PWR_SHIFT 2
+#define SPKR1_PWR_SHIFT 3
+#define SPKR2_MODE_MASK 0x10
+#define SPKR2_MODE_SHIFT 4
+#define SPKR2_MODE_VBR_VALUE 0
+#define SPKR2_MODE_CLS_D_VALUE 1
+#define SPKR2_ADDER_PWR_SHIFT 5
+#define SPKR2_PWR_SHIFT 6
+
+#define AB5500_VIRTUAL_REG4 (AB5500_LAST_REG + 4)
+#define PWM_SPKR1_PWR_SHIFT 0
+#define PWM_SPKR2_PWR_SHIFT 1
+#define PWM_SPKR1N_PWR_SHIFT 2
+#define PWM_SPKR1P_PWR_SHIFT 3
+#define PWM_SPKR2N_PWR_SHIFT 4
+#define PWM_SPKR2P_PWR_SHIFT 5
+
+#define AB5500_VIRTUAL_REG5 (AB5500_LAST_REG + 5)
+#define PWM_SPKR1N_SEL_SHIFT 0
+#define PWM_SPKR1P_SEL_SHIFT 1
+#define PWM_SPKR2N_SEL_SHIFT 2
+#define PWM_SPKR2P_SEL_SHIFT 3
+
+#define DUMMY_REG 0xff
+
+/* #define SPKR1_PWR_VBR_SHIFT 0 */
+/* #define SPKR1_PWR_CLS_D_SHIFT 1 */
+/* #define SPKR1_PWR_CLS_AB_SHIFT 2 */
+/* #define SPKR2_PWR_VBR_SHIFT 3 */
+/* #define SPKR2_PWR_CLS_D_SHIFT 4 */
+/* #define SPKR2_PWR_CLS_AB_SHIFT 5 */
+
+#endif
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c
new file mode 100644
index 00000000000..7a87890507c
--- /dev/null
+++ b/sound/soc/codecs/ab8500_audio.c
@@ -0,0 +1,2476 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Mikko J. Lehto <mikko.lehto@symbio.com>,
+ * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
+ * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>,
+ * Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/ab8500/sysctrl.h>
+#include "ab8500_audio.h"
+
+/* To convert register definition shifts to masks */
+#define BMASK(bsft) (1 << (bsft))
+
+/* Macrocell value definitions */
+#define CLK_32K_OUT2_DISABLE 0x01
+#define INACTIVE_RESET_AUDIO 0x02
+#define ENABLE_AUDIO_CLK_TO_AUDIO_BLK 0x10
+#define ENABLE_VINTCORE12_SUPPLY 0x04
+#define GPIO27_DIR_OUTPUT 0x04
+#define GPIO29_DIR_OUTPUT 0x10
+#define GPIO31_DIR_OUTPUT 0x40
+#define GPIO35_DIR_OUTPUT 0x04
+
+/* Macrocell register definitions */
+#define AB8500_CTRL3_REG 0x0200
+#define AB8500_GPIO_DIR4_REG 0x1013
+#define AB8500_GPIO_DIR5_REG 0x1014
+#define AB8500_GPIO_OUT5_REG 0x1024
+
+/*
+ * AB8500 register cache & default register settings
+ */
+static const u8 ab8500_reg_cache[AB8500_CACHEREGNUM] = {
+ 0x00, /* REG_POWERUP (0x00) */
+ 0x00, /* REG_AUDSWRESET (0x01) */
+ 0x00, /* REG_ADPATHENA (0x02) */
+ 0x00, /* REG_DAPATHENA (0x03) */
+ 0x00, /* REG_ANACONF1 (0x04) */
+ 0x0F, /* REG_ANACONF2 (0x05) */
+ 0x00, /* REG_DIGMICCONF (0x06) */
+ 0x00, /* REG_ANACONF3 (0x07) */
+ 0x00, /* REG_ANACONF4 (0x08) */
+ 0x00, /* REG_DAPATHCONF (0x09) */
+ 0x40, /* REG_MUTECONF (0x0A) */
+ 0x00, /* REG_SHORTCIRCONF (0x0B) */
+ 0x01, /* REG_ANACONF5 (0x0C) */
+ 0x00, /* REG_ENVCPCONF (0x0D) */
+ 0x00, /* REG_SIGENVCONF (0x0E) */
+ 0x3F, /* REG_PWMGENCONF1 (0x0F) */
+ 0x32, /* REG_PWMGENCONF2 (0x10) */
+ 0x32, /* REG_PWMGENCONF3 (0x11) */
+ 0x32, /* REG_PWMGENCONF4 (0x12) */
+ 0x32, /* REG_PWMGENCONF5 (0x13) */
+ 0x0F, /* REG_ANAGAIN1 (0x14) */
+ 0x0F, /* REG_ANAGAIN2 (0x15) */
+ 0x22, /* REG_ANAGAIN3 (0x16) */
+ 0x55, /* REG_ANAGAIN4 (0x17) */
+ 0x13, /* REG_DIGLINHSLGAIN (0x18) */
+ 0x13, /* REG_DIGLINHSRGAIN (0x19) */
+ 0x00, /* REG_ADFILTCONF (0x1A) */
+ 0x00, /* REG_DIGIFCONF1 (0x1B) */
+ 0x02, /* REG_DIGIFCONF2 (0x1C) */
+ 0x00, /* REG_DIGIFCONF3 (0x1D) */
+ 0x02, /* REG_DIGIFCONF4 (0x1E) */
+ 0xCC, /* REG_ADSLOTSEL1 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL2 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL3 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL4 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL5 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL6 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL7 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL8 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL9 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL10 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL11 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL12 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL13 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL14 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL15 (0xCC) */
+ 0xCC, /* REG_ADSLOTSEL16 (0xCC) */
+ 0x00, /* REG_ADSLOTHIZCTRL1 (0x2F) */
+ 0x00, /* REG_ADSLOTHIZCTRL2 (0x30) */
+ 0x00, /* REG_ADSLOTHIZCTRL3 (0x31) */
+ 0x00, /* REG_ADSLOTHIZCTRL4 (0x32) */
+ 0x08, /* REG_DASLOTCONF1 (0x33) */
+ 0x08, /* REG_DASLOTCONF2 (0x34) */
+ 0x08, /* REG_DASLOTCONF3 (0x35) */
+ 0x08, /* REG_DASLOTCONF4 (0x36) */
+ 0x08, /* REG_DASLOTCONF5 (0x37) */
+ 0x08, /* REG_DASLOTCONF6 (0x38) */
+ 0x08, /* REG_DASLOTCONF7 (0x39) */
+ 0x08, /* REG_DASLOTCONF8 (0x3A) */
+ 0x00, /* REG_CLASSDCONF1 (0x3B) */
+ 0x00, /* REG_CLASSDCONF2 (0x3C) */
+ 0x84, /* REG_CLASSDCONF3 (0x3D) */
+ 0x00, /* REG_DMICFILTCONF (0x3E) */
+ 0xFE, /* REG_DIGMULTCONF1 (0x3F) */
+ 0xC0, /* REG_DIGMULTCONF2 (0x40) */
+ 0x3F, /* REG_ADDIGGAIN1 (0x41) */
+ 0x3F, /* REG_ADDIGGAIN2 (0x42) */
+ 0x1F, /* REG_ADDIGGAIN3 (0x43) */
+ 0x1F, /* REG_ADDIGGAIN4 (0x44) */
+ 0x3F, /* REG_ADDIGGAIN5 (0x45) */
+ 0x3F, /* REG_ADDIGGAIN6 (0x46) */
+ 0x1F, /* REG_DADIGGAIN1 (0x47) */
+ 0x1F, /* REG_DADIGGAIN2 (0x48) */
+ 0x3F, /* REG_DADIGGAIN3 (0x49) */
+ 0x3F, /* REG_DADIGGAIN4 (0x4A) */
+ 0x3F, /* REG_DADIGGAIN5 (0x4B) */
+ 0x3F, /* REG_DADIGGAIN6 (0x4C) */
+ 0x3F, /* REG_ADDIGLOOPGAIN1 (0x4D) */
+ 0x3F, /* REG_ADDIGLOOPGAIN2 (0x4E) */
+ 0x00, /* REG_HSLEARDIGGAIN (0x4F) */
+ 0x00, /* REG_HSRDIGGAIN (0x50) */
+ 0x1F, /* REG_SIDFIRGAIN1 (0x51) */
+ 0x1F, /* REG_SIDFIRGAIN2 (0x52) */
+ 0x00, /* REG_ANCCONF1 (0x53) */
+ 0x00, /* REG_ANCCONF2 (0x54) */
+ 0x00, /* REG_ANCCONF3 (0x55) */
+ 0x00, /* REG_ANCCONF4 (0x56) */
+ 0x00, /* REG_ANCCONF5 (0x57) */
+ 0x00, /* REG_ANCCONF6 (0x58) */
+ 0x00, /* REG_ANCCONF7 (0x59) */
+ 0x00, /* REG_ANCCONF8 (0x5A) */
+ 0x00, /* REG_ANCCONF9 (0x5B) */
+ 0x00, /* REG_ANCCONF10 (0x5C) */
+ 0x00, /* REG_ANCCONF11 (0x5D) - read only */
+ 0x00, /* REG_ANCCONF12 (0x5E) - read only */
+ 0x00, /* REG_ANCCONF13 (0x5F) - read only */
+ 0x00, /* REG_ANCCONF14 (0x60) - read only */
+ 0x00, /* REG_SIDFIRADR (0x61) */
+ 0x00, /* REG_SIDFIRCOEF1 (0x62) */
+ 0x00, /* REG_SIDFIRCOEF2 (0x63) */
+ 0x00, /* REG_SIDFIRCONF (0x64) */
+ 0x00, /* REG_AUDINTMASK1 (0x65) */
+ 0x00, /* REG_AUDINTSOURCE1 (0x66) - read only */
+ 0x00, /* REG_AUDINTMASK2 (0x67) */
+ 0x00, /* REG_AUDINTSOURCE2 (0x68) - read only */
+ 0x00, /* REG_FIFOCONF1 (0x69) */
+ 0x00, /* REG_FIFOCONF2 (0x6A) */
+ 0x00, /* REG_FIFOCONF3 (0x6B) */
+ 0x00, /* REG_FIFOCONF4 (0x6C) */
+ 0x00, /* REG_FIFOCONF5 (0x6D) */
+ 0x00, /* REG_FIFOCONF6 (0x6E) */
+ 0x02, /* REG_AUDREV (0x6F) - read only */
+};
+
+static struct snd_soc_codec *ab8500_codec;
+
+
+/* Reads an arbitrary register from the ab8500 chip.
+*/
+static int ab8500_codec_read_reg(struct snd_soc_codec *codec, unsigned int bank,
+ unsigned int reg)
+{
+ u8 value;
+ int status = abx500_get_register_interruptible(
+ codec->dev, bank, reg, &value);
+
+ if (status < 0) {
+ pr_err("%s: Register (%02x:%02x) read failed (%d).\n",
+ __func__, (u8)bank, (u8)reg, status);
+ } else {
+ pr_debug("Read 0x%02x from register %02x:%02x\n",
+ (u8)value, (u8)bank, (u8)reg);
+ status = value;
+ }
+
+ return status;
+}
+
+/* Writes an arbitrary register to the ab8500 chip.
+ */
+static int ab8500_codec_write_reg(struct snd_soc_codec *codec, unsigned int bank,
+ unsigned int reg, unsigned int value)
+{
+ int status = abx500_set_register_interruptible(
+ codec->dev, bank, reg, value);
+
+ if (status < 0) {
+ pr_err("%s: Register (%02x:%02x) write failed (%d).\n",
+ __func__, (u8)bank, (u8)reg, status);
+ } else {
+ pr_debug("Wrote 0x%02x into register %02x:%02x\n",
+ (u8)value, (u8)bank, (u8)reg);
+ }
+
+ return status;
+}
+
+/* Reads an audio register from the cache.
+ */
+static unsigned int ab8500_codec_read_reg_audio(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u8 *cache = codec->reg_cache;
+ return cache[reg];
+}
+
+/* Reads an audio register from the hardware.
+ */
+static int ab8500_codec_read_reg_audio_nocache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u8 *cache = codec->reg_cache;
+ int value = ab8500_codec_read_reg(codec, AB8500_AUDIO, reg);
+
+ if (value >= 0)
+ cache[reg] = value;
+
+ return value;
+}
+
+/* Writes an audio register to the hardware and cache.
+ */
+static int ab8500_codec_write_reg_audio(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ u8 *cache = codec->reg_cache;
+ int status = ab8500_codec_write_reg(codec, AB8500_AUDIO, reg, value);
+
+ if (status >= 0)
+ cache[reg] = value;
+
+ return status;
+}
+
+/* Dumps all audio registers.
+ */
+static inline void ab8500_codec_dump_all_reg(struct snd_soc_codec *codec)
+{
+ int i;
+
+ pr_debug("%s Enter.\n", __func__);
+
+ for (i = AB8500_FIRST_REG; i <= AB8500_LAST_REG; i++)
+ ab8500_codec_read_reg_audio_nocache(codec, i);
+}
+
+/* Updates an audio register.
+ */
+static inline int ab8500_codec_update_reg_audio(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int clr, unsigned int ins)
+{
+ unsigned int new, old;
+
+ old = ab8500_codec_read_reg_audio(codec, reg);
+ new = (old & ~clr) | ins;
+ if (old == new)
+ return 0;
+
+ return ab8500_codec_write_reg_audio(codec, reg, new);
+}
+
+/* Whether widget's register definitions should be inverted or not */
+enum control_inversion {
+ NORMAL = 0,
+ INVERT = 1
+};
+
+/* HS left channel mute control */
+static const struct snd_kcontrol_new dapm_hsl_mute[] = {
+ SOC_DAPM_SINGLE("Playback Switch", REG_MUTECONF,
+ REG_MUTECONF_MUTHSL, 1, INVERT),
+};
+
+/* HS right channel mute control */
+static const struct snd_kcontrol_new dapm_hsr_mute[] = {
+ SOC_DAPM_SINGLE("Playback Switch", REG_MUTECONF,
+ REG_MUTECONF_MUTHSR, 1, INVERT),
+};
+
+/* Earpiece mute control */
+static const struct snd_kcontrol_new dapm_ear_mute[] = {
+ SOC_DAPM_SINGLE("Playback Switch", REG_MUTECONF,
+ REG_MUTECONF_MUTEAR, 1, INVERT),
+};
+
+/* IHF left channel mute control */
+static const struct snd_kcontrol_new dapm_ihfl_mute[] = {
+ SOC_DAPM_SINGLE("Playback Switch", REG_DIGMULTCONF2,
+ REG_DIGMULTCONF2_DATOHFLEN, 1, NORMAL),
+};
+
+/* IHF right channel mute control */
+static const struct snd_kcontrol_new dapm_ihfr_mute[] = {
+ SOC_DAPM_SINGLE("Playback Switch", REG_DIGMULTCONF2,
+ REG_DIGMULTCONF2_DATOHFREN, 1, NORMAL),
+};
+
+/* Mic 1 mute control */
+static const struct snd_kcontrol_new dapm_mic1_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_ANACONF2,
+ REG_ANACONF2_MUTMIC1, 1, INVERT),
+};
+
+/* Mic 2 mute control */
+static const struct snd_kcontrol_new dapm_mic2_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_ANACONF2,
+ REG_ANACONF2_MUTMIC2, 1, INVERT),
+};
+
+/* LineIn left channel mute control */
+static const struct snd_kcontrol_new dapm_linl_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_ANACONF2,
+ REG_ANACONF2_MUTLINL, 1, INVERT),
+};
+
+/* LineIn right channel mute control */
+static const struct snd_kcontrol_new dapm_linr_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_ANACONF2,
+ REG_ANACONF2_MUTLINR, 1, INVERT),
+};
+
+/* DMic 1 mute control */
+static const struct snd_kcontrol_new dapm_dmic1_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_DIGMICCONF,
+ REG_DIGMICCONF_ENDMIC1, 1, NORMAL),
+};
+
+/* DMic 2 mute control */
+static const struct snd_kcontrol_new dapm_dmic2_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_DIGMICCONF,
+ REG_DIGMICCONF_ENDMIC2, 1, NORMAL),
+};
+
+/* DMic 3 mute control */
+static const struct snd_kcontrol_new dapm_dmic3_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_DIGMICCONF,
+ REG_DIGMICCONF_ENDMIC3, 1, NORMAL),
+};
+
+/* DMic 4 mute control */
+static const struct snd_kcontrol_new dapm_dmic4_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_DIGMICCONF,
+ REG_DIGMICCONF_ENDMIC4, 1, NORMAL),
+};
+
+/* DMic 5 mute control */
+static const struct snd_kcontrol_new dapm_dmic5_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_DIGMICCONF,
+ REG_DIGMICCONF_ENDMIC5, 1, NORMAL),
+};
+
+/* DMic 6 mute control */
+static const struct snd_kcontrol_new dapm_dmic6_mute[] = {
+ SOC_DAPM_SINGLE("Capture Switch", REG_DIGMICCONF,
+ REG_DIGMICCONF_ENDMIC6, 1, NORMAL),
+};
+
+/* ANC to Earpiece mute control */
+static const struct snd_kcontrol_new dapm_anc_ear_mute[] = {
+ SOC_DAPM_SINGLE("Playback Switch", REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_ANCSEL, 1, NORMAL),
+};
+
+/* Earpiece source selector control */
+static const char *enum_ear_source[] = {"Headset Left", "IHF Left"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ear_source, REG_DMICFILTCONF,
+ REG_DMICFILTCONF_DA3TOEAR, enum_ear_source);
+
+static const struct snd_kcontrol_new dapm_ear_source[] = {
+ SOC_DAPM_ENUM("Earpiece Source", dapm_enum_ear_source),
+};
+
+/* IHF / ANC selector control */
+static const char *enum_ihfx_sel[] = {"Audio Path", "ANC"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ihfl_sel, REG_DIGMULTCONF2,
+ REG_DIGMULTCONF2_HFLSEL, enum_ihfx_sel);
+
+static const struct snd_kcontrol_new dapm_ihfl_select[] = {
+ SOC_DAPM_ENUM("IHF Left Source", dapm_enum_ihfl_sel),
+};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ihfr_sel, REG_DIGMULTCONF2,
+ REG_DIGMULTCONF2_HFRSEL, enum_ihfx_sel);
+
+static const struct snd_kcontrol_new dapm_ihfr_select[] = {
+ SOC_DAPM_ENUM("IHF Right Source", dapm_enum_ihfr_sel),
+};
+
+/* Mic 1A or 1B selector control */
+static const char *enum_mic1ab_sel[] = {"Mic 1A", "Mic 1B"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_mic1ab_sel, REG_ANACONF3,
+ REG_ANACONF3_MIC1SEL, enum_mic1ab_sel);
+
+static const struct snd_kcontrol_new dapm_mic1ab_select[] = {
+ SOC_DAPM_ENUM("Mic 1A or 1B Select", dapm_enum_mic1ab_sel),
+};
+
+/* Mic 2 or LineIn Right selector control */
+static const char *enum_mic2lr_sel[] = {"Mic 2", "LineIn Right"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_mic2lr_sel, REG_ANACONF3,
+ REG_ANACONF3_LINRSEL, enum_mic2lr_sel);
+
+static const struct snd_kcontrol_new dapm_mic2lr_select[] = {
+ SOC_DAPM_ENUM("Mic 2 or LINR Select", dapm_enum_mic2lr_sel),
+};
+
+/* AD1 selector control */
+static const char *enum_ad1_sel[] = {"LineIn Left", "DMic 1"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ad1_sel, REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_AD1SEL, enum_ad1_sel);
+
+static const struct snd_kcontrol_new dapm_ad1_select[] = {
+ SOC_DAPM_ENUM("AD 1 Select", dapm_enum_ad1_sel),
+};
+
+/* AD2 selector control */
+static const char *enum_ad2_sel[] = {"LineIn Right", "DMic 2"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ad2_sel, REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_AD2SEL, enum_ad2_sel);
+
+static const struct snd_kcontrol_new dapm_ad2_select[] = {
+ SOC_DAPM_ENUM("AD 2 Select", dapm_enum_ad2_sel),
+};
+
+/* AD3 selector control */
+static const char *enum_ad3_sel[] = {"Mic 1", "DMic 3"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ad3_sel, REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_AD3SEL, enum_ad3_sel);
+
+static const struct snd_kcontrol_new dapm_ad3_select[] = {
+ SOC_DAPM_ENUM("AD 3 Select", dapm_enum_ad3_sel),
+};
+
+/* AD5 selector control */
+static const char *enum_ad5_sel[] = {"Mic 2", "DMic 5"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ad5_sel, REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_AD5SEL, enum_ad5_sel);
+
+static const struct snd_kcontrol_new dapm_ad5_select[] = {
+ SOC_DAPM_ENUM("AD 5 Select", dapm_enum_ad5_sel),
+};
+
+/* AD6 selector control */
+static const char *enum_ad6_sel[] = {"Mic 1", "DMic 6"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_ad6_sel, REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_AD6SEL, enum_ad6_sel);
+
+static const struct snd_kcontrol_new dapm_ad6_select[] = {
+ SOC_DAPM_ENUM("AD 6 Select", dapm_enum_ad6_sel),
+};
+
+/* ANC input selector control */
+static const char *enum_anc_in_sel[] = {"Mic 1 / DMic 6", "Mic 2 / DMic 5"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_in_sel, REG_DMICFILTCONF,
+ REG_DMICFILTCONF_ANCINSEL, enum_anc_in_sel);
+
+static const struct snd_kcontrol_new dapm_anc_in_select[] = {
+ SOC_DAPM_ENUM("ANC Source", dapm_enum_anc_in_sel),
+};
+
+/* ANC enable control */
+static const char *enum_anc_dis_ena[] = {"Disabled", "Enabled"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_enable, REG_ANCCONF1,
+ REG_ANCCONF1_ENANC, enum_anc_dis_ena);
+
+static const struct snd_kcontrol_new dapm_anc_enable[] = {
+ SOC_DAPM_ENUM("ANC", dapm_enum_anc_enable),
+};
+
+/* Sidetone left input selector control */
+static const char *enum_stfir1_in_sel[] = {
+ "LineIn Left", "LineIn Right", "Mic 1", "Headset Left"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir1_in_sel, REG_DIGMULTCONF2,
+ REG_DIGMULTCONF2_FIRSID1SEL, enum_stfir1_in_sel);
+
+static const struct snd_kcontrol_new dapm_stfir1_in_select[] = {
+ SOC_DAPM_ENUM("Sidetone Left Source", dapm_enum_stfir1_in_sel),
+};
+
+/* Sidetone right input selector control */
+static const char *enum_stfir2_in_sel[] = {
+ "LineIn Right", "Mic 1", "DMic 4", "Headset Right"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir2_in_sel, REG_DIGMULTCONF2,
+ REG_DIGMULTCONF2_FIRSID2SEL, enum_stfir2_in_sel);
+
+static const struct snd_kcontrol_new dapm_stfir2_in_select[] = {
+ SOC_DAPM_ENUM("Sidetone Right Source", dapm_enum_stfir2_in_sel),
+};
+
+/* Vibra path selector control */
+static const char *enum_pwm2vibx[] = {"Audio Path", "PWM Generator"};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib1, REG_PWMGENCONF1,
+ REG_PWMGENCONF1_PWMTOVIB1, enum_pwm2vibx);
+
+static const struct snd_kcontrol_new dapm_pwm2vib1[] = {
+ SOC_DAPM_ENUM("Vibra 1 Controller", dapm_enum_pwm2vib1),
+};
+
+static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib2, REG_PWMGENCONF1,
+ REG_PWMGENCONF1_PWMTOVIB2, enum_pwm2vibx);
+
+static const struct snd_kcontrol_new dapm_pwm2vib2[] = {
+ SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2),
+};
+
+static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
+ /* Headset path */
+
+ SND_SOC_DAPM_AIF_IN("DA_IN1", "ab8500_0p", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("DA_IN2", "ab8500_0p", 0, SND_SOC_NOPM, 0, 0),
+
+ /* XXX SwapDA12_34 */
+
+ SND_SOC_DAPM_MIXER("DA1 Channel Gain", REG_DAPATHENA,
+ REG_DAPATHENA_ENDA1, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("DA2 Channel Gain", REG_DAPATHENA,
+ REG_DAPATHENA_ENDA2, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("HSL Digital Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("HSR Digital Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("HSL DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACHSL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("HSR DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACHSR, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("HSL DAC Driver", REG_ANACONF3,
+ REG_ANACONF3_ENDRVHSL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("HSR DAC Driver", REG_ANACONF3,
+ REG_ANACONF3_ENDRVHSR, 0, NULL, 0),
+
+ SND_SOC_DAPM_SWITCH("Headset Left", SND_SOC_NOPM, 0, 0, dapm_hsl_mute),
+ SND_SOC_DAPM_SWITCH("Headset Right", SND_SOC_NOPM, 0, 0, dapm_hsr_mute),
+
+ SND_SOC_DAPM_MIXER("HSL Enable", REG_ANACONF4,
+ REG_ANACONF4_ENHSL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("HSR Enable", REG_ANACONF4,
+ REG_ANACONF4_ENHSR, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("Charge Pump", REG_ANACONF5,
+ REG_ANACONF5_ENCPHS, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("HSL"),
+ SND_SOC_DAPM_OUTPUT("HSR"),
+
+
+ /* Earpiece path */
+
+ SND_SOC_DAPM_MUX("Earpiece Source Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_ear_source),
+
+ SND_SOC_DAPM_MIXER("EAR DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACEAR, 0, NULL, 0),
+
+ SND_SOC_DAPM_SWITCH("Earpiece", SND_SOC_NOPM, 0, 0, dapm_ear_mute),
+
+ SND_SOC_DAPM_MIXER("EAR Enable", REG_ANACONF4,
+ REG_ANACONF4_ENEAR, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("EAR"),
+
+
+ /* Handsfree path */
+
+ SND_SOC_DAPM_AIF_IN("DA_IN3", "ab8500_0p", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("DA_IN4", "ab8500_0p", 0, SND_SOC_NOPM, 0, 0),
+
+ /* XXX SwapDA12_34 */
+
+ SND_SOC_DAPM_MIXER("DA3 Channel Gain", REG_DAPATHENA,
+ REG_DAPATHENA_ENDA3, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("DA4 Channel Gain", REG_DAPATHENA,
+ REG_DAPATHENA_ENDA4, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("IHF Left Source Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_ihfl_select),
+ SND_SOC_DAPM_MUX("IHF Right Source Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_ihfr_select),
+
+ SND_SOC_DAPM_SWITCH("IHF Left", SND_SOC_NOPM, 0, 0, dapm_ihfl_mute),
+ SND_SOC_DAPM_SWITCH("IHF Right", SND_SOC_NOPM, 0, 0, dapm_ihfr_mute),
+
+ SND_SOC_DAPM_MIXER("IHFL DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACHFL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("IHFR DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACHFR, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("IHFL Enable", REG_ANACONF4,
+ REG_ANACONF4_ENHFL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("IHFR Enable", REG_ANACONF4,
+ REG_ANACONF4_ENHFR, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("IHFL"),
+ SND_SOC_DAPM_OUTPUT("IHFR"),
+
+
+ /* Vibrator path */
+
+ SND_SOC_DAPM_AIF_IN("DA_IN5", "ab8500_0p", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("DA_IN6", "ab8500_0p", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_MIXER("DA5 Channel Gain", REG_DAPATHENA,
+ REG_DAPATHENA_ENDA5, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("DA6 Channel Gain", REG_DAPATHENA,
+ REG_DAPATHENA_ENDA6, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("VIB1 DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACVIB1, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("VIB2 DAC", REG_DAPATHCONF,
+ REG_DAPATHCONF_ENDACVIB2, 0, NULL, 0),
+
+ SND_SOC_DAPM_INPUT("PWMGEN1"),
+ SND_SOC_DAPM_INPUT("PWMGEN2"),
+
+ SND_SOC_DAPM_MUX("Vibra 1 Controller Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_pwm2vib1),
+ SND_SOC_DAPM_MUX("Vibra 2 Controller Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_pwm2vib2),
+
+ SND_SOC_DAPM_MIXER("VIB1 Enable", REG_ANACONF4,
+ REG_ANACONF4_ENVIB1, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("VIB2 Enable", REG_ANACONF4,
+ REG_ANACONF4_ENVIB2, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("VIB1"),
+ SND_SOC_DAPM_OUTPUT("VIB2"),
+
+
+ /* LineIn & Microphone 2 path */
+
+ SND_SOC_DAPM_INPUT("LINL"),
+ SND_SOC_DAPM_INPUT("LINR"),
+ SND_SOC_DAPM_INPUT("MIC2"),
+
+ SND_SOC_DAPM_SWITCH("LineIn Left", SND_SOC_NOPM, 0, 0, dapm_linl_mute),
+ SND_SOC_DAPM_SWITCH("LineIn Right", SND_SOC_NOPM, 0, 0, dapm_linr_mute),
+ SND_SOC_DAPM_SWITCH("Mic 2", SND_SOC_NOPM, 0, 0, dapm_mic2_mute),
+
+ SND_SOC_DAPM_MIXER("LINL Enable", REG_ANACONF2,
+ REG_ANACONF2_ENLINL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("LINR Enable", REG_ANACONF2,
+ REG_ANACONF2_ENLINR, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("MIC2 Enable", REG_ANACONF2,
+ REG_ANACONF2_ENMIC2, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("Mic 2 or LINR Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_mic2lr_select),
+
+ SND_SOC_DAPM_MIXER("LINL ADC", REG_ANACONF3,
+ REG_ANACONF3_ENADCLINL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("LINR ADC", REG_ANACONF3,
+ REG_ANACONF3_ENADCLINR, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("AD 1 Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_ad1_select),
+ SND_SOC_DAPM_MUX("AD 2 Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_ad2_select),
+
+ SND_SOC_DAPM_MIXER("AD1 Channel Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AD2 Channel Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("AD1 Enable", REG_ADPATHENA,
+ REG_ADPATHENA_ENAD12, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AD2 Enable", REG_ADPATHENA,
+ REG_ADPATHENA_ENAD12, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_OUT("AD_OUT1", "ab8500_0c", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AD_OUT2", "ab8500_0c", 0, SND_SOC_NOPM, 0, 0),
+
+
+ /* Microphone 1 path */
+
+ SND_SOC_DAPM_INPUT("MIC1A"),
+ SND_SOC_DAPM_INPUT("MIC1B"),
+
+ SND_SOC_DAPM_MUX("Mic 1A or 1B Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_mic1ab_select),
+
+ SND_SOC_DAPM_SWITCH("Mic 1", SND_SOC_NOPM, 0, 0, dapm_mic1_mute),
+
+ SND_SOC_DAPM_MIXER("MIC1 Enable", REG_ANACONF2,
+ REG_ANACONF2_ENMIC1, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("MIC1 ADC", REG_ANACONF3,
+ REG_ANACONF3_ENADCMIC, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("AD 3 Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_ad3_select),
+
+ SND_SOC_DAPM_MIXER("AD3 Channel Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("AD3 Enable", REG_ADPATHENA,
+ REG_ADPATHENA_ENAD34, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_OUT("AD_OUT3", "ab8500_0c", 0, SND_SOC_NOPM, 0, 0),
+
+
+ /* HD Capture path */
+
+ SND_SOC_DAPM_MUX("AD 5 Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_ad5_select),
+ SND_SOC_DAPM_MUX("AD 6 Select Capture Route",
+ SND_SOC_NOPM, 0, 0, dapm_ad6_select),
+
+ SND_SOC_DAPM_MIXER("AD5 Channel Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AD6 Channel Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("AD57 Enable", REG_ADPATHENA,
+ REG_ADPATHENA_ENAD5768, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AD68 Enable", REG_ADPATHENA,
+ REG_ADPATHENA_ENAD5768, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_OUT("AD_OUT57", "ab8500_0c", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AD_OUT68", "ab8500_0c", 0, SND_SOC_NOPM, 0, 0),
+
+
+ /* Digital Microphone path */
+
+ SND_SOC_DAPM_INPUT("DMIC1"),
+ SND_SOC_DAPM_INPUT("DMIC2"),
+ SND_SOC_DAPM_INPUT("DMIC3"),
+ SND_SOC_DAPM_INPUT("DMIC4"),
+ SND_SOC_DAPM_INPUT("DMIC5"),
+ SND_SOC_DAPM_INPUT("DMIC6"),
+
+ SND_SOC_DAPM_SWITCH("DMic 1", SND_SOC_NOPM, 0, 0, dapm_dmic1_mute),
+ SND_SOC_DAPM_SWITCH("DMic 2", SND_SOC_NOPM, 0, 0, dapm_dmic2_mute),
+ SND_SOC_DAPM_SWITCH("DMic 3", SND_SOC_NOPM, 0, 0, dapm_dmic3_mute),
+ SND_SOC_DAPM_SWITCH("DMic 4", SND_SOC_NOPM, 0, 0, dapm_dmic4_mute),
+ SND_SOC_DAPM_SWITCH("DMic 5", SND_SOC_NOPM, 0, 0, dapm_dmic5_mute),
+ SND_SOC_DAPM_SWITCH("DMic 6", SND_SOC_NOPM, 0, 0, dapm_dmic6_mute),
+
+ SND_SOC_DAPM_MIXER("AD4 Channel Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("AD4 Enable", REG_ADPATHENA,
+ REG_ADPATHENA_ENAD34, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_OUT("AD_OUT4", "ab8500_0c", 0, SND_SOC_NOPM, 0, 0),
+
+
+ /* LineIn Bypass path */
+
+ SND_SOC_DAPM_MIXER("LINL to HSL Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("LINR to HSR Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+
+ /* Analog Loopback path */
+
+ SND_SOC_DAPM_MIXER("AD1 to IHFL Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AD2 to IHFR Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+
+ /* Acoustical Noise Cancellation path */
+
+ SND_SOC_DAPM_MUX("ANC Source Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_anc_in_select),
+
+ SND_SOC_DAPM_MUX("ANC Playback Switch",
+ SND_SOC_NOPM, 0, 0, dapm_anc_enable),
+
+ SND_SOC_DAPM_SWITCH("ANC to Earpiece",
+ SND_SOC_NOPM, 0, 0, dapm_anc_ear_mute),
+
+
+ /* Sidetone Filter path */
+
+ SND_SOC_DAPM_MUX("Sidetone Left Source Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_stfir1_in_select),
+ SND_SOC_DAPM_MUX("Sidetone Right Source Playback Route",
+ SND_SOC_NOPM, 0, 0, dapm_stfir2_in_select),
+
+ SND_SOC_DAPM_MIXER("STFIR1 Control", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("STFIR2 Control", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("STFIR1 Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("STFIR2 Gain", SND_SOC_NOPM, 0, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+ /* Headset path */
+
+ {"DA1 Channel Gain", NULL, "DA_IN1"},
+ {"DA2 Channel Gain", NULL, "DA_IN2"},
+
+ {"HSL Digital Gain", NULL, "DA1 Channel Gain"},
+ {"HSR Digital Gain", NULL, "DA2 Channel Gain"},
+
+ {"HSL DAC", NULL, "HSL Digital Gain"},
+ {"HSR DAC", NULL, "HSR Digital Gain"},
+
+ {"HSL DAC Driver", NULL, "HSL DAC"},
+ {"HSR DAC Driver", NULL, "HSR DAC"},
+
+ {"Headset Left", "Playback Switch", "HSL DAC Driver"},
+ {"Headset Right", "Playback Switch", "HSR DAC Driver"},
+
+ {"HSL Enable", NULL, "Headset Left"},
+ {"HSR Enable", NULL, "Headset Right"},
+
+ {"Charge Pump", NULL, "HSL Enable"},
+ {"Charge Pump", NULL, "HSR Enable"},
+
+ {"HSL", NULL, "Charge Pump"},
+ {"HSR", NULL, "Charge Pump"},
+
+
+ /* Earpiece path */
+
+ {"Earpiece Source Playback Route", "Headset Left", "HSL Digital Gain"},
+ {"Earpiece Source Playback Route", "IHF Left", "IHF Left"},
+
+ {"EAR DAC", NULL, "Earpiece Source Playback Route"},
+
+ {"Earpiece", "Playback Switch", "EAR DAC"},
+
+ {"EAR Enable", NULL, "Earpiece"},
+
+ {"EAR", NULL, "EAR Enable"},
+
+
+ /* Handsfree path */
+
+ {"DA3 Channel Gain", NULL, "DA_IN3"},
+ {"DA4 Channel Gain", NULL, "DA_IN4"},
+
+ {"IHF Left Source Playback Route", "Audio Path", "DA3 Channel Gain"},
+ {"IHF Right Source Playback Route", "Audio Path", "DA4 Channel Gain"},
+
+ {"IHF Left", "Playback Switch", "IHF Left Source Playback Route"},
+ {"IHF Right", "Playback Switch", "IHF Right Source Playback Route"},
+
+ {"IHFL DAC", NULL, "IHF Left"},
+ {"IHFR DAC", NULL, "IHF Right"},
+
+ {"IHFL Enable", NULL, "IHFL DAC"},
+ {"IHFR Enable", NULL, "IHFR DAC"},
+
+ {"IHFL", NULL, "IHFL Enable"},
+ {"IHFR", NULL, "IHFR Enable"},
+
+
+ /* Vibrator path */
+
+ {"DA5 Channel Gain", NULL, "DA_IN5"},
+ {"DA6 Channel Gain", NULL, "DA_IN6"},
+
+ {"VIB1 DAC", NULL, "DA5 Channel Gain"},
+ {"VIB2 DAC", NULL, "DA6 Channel Gain"},
+
+ {"Vibra 1 Controller Playback Route", "Audio Path", "VIB1 DAC"},
+ {"Vibra 2 Controller Playback Route", "Audio Path", "VIB2 DAC"},
+ {"Vibra 1 Controller Playback Route", "PWM Generator", "PWMGEN1"},
+ {"Vibra 2 Controller Playback Route", "PWM Generator", "PWMGEN2"},
+
+ {"VIB1 Enable", NULL, "Vibra 1 Controller Playback Route"},
+ {"VIB2 Enable", NULL, "Vibra 2 Controller Playback Route"},
+
+ {"VIB1", NULL, "VIB1 Enable"},
+ {"VIB2", NULL, "VIB2 Enable"},
+
+
+ /* LineIn & Microphone 2 path */
+
+ {"LineIn Left", "Capture Switch", "LINL"},
+ {"LineIn Right", "Capture Switch", "LINR"},
+ {"Mic 2", "Capture Switch", "MIC2"},
+
+ {"LINL Enable", NULL, "LineIn Left"},
+ {"LINR Enable", NULL, "LineIn Right"},
+ {"MIC2 Enable", NULL, "Mic 2"},
+
+ {"Mic 2 or LINR Select Capture Route", "LineIn Right", "LINR Enable"},
+ {"Mic 2 or LINR Select Capture Route", "Mic 2", "MIC2 Enable"},
+
+ {"LINL ADC", NULL, "LINL Enable"},
+ {"LINR ADC", NULL, "Mic 2 or LINR Select Capture Route"},
+
+ {"AD 1 Select Capture Route", "LineIn Left", "LINL ADC"},
+ {"AD 2 Select Capture Route", "LineIn Right", "LINR ADC"},
+
+ {"AD1 Channel Gain", NULL, "AD 1 Select Capture Route"},
+ {"AD2 Channel Gain", NULL, "AD 2 Select Capture Route"},
+
+ {"AD1 Enable", NULL, "AD1 Channel Gain"},
+ {"AD2 Enable", NULL, "AD2 Channel Gain"},
+
+ {"AD_OUT1", NULL, "AD1 Enable"},
+ {"AD_OUT2", NULL, "AD2 Enable"},
+
+
+ /* Microphone 1 path */
+
+ {"Mic 1A or 1B Select Capture Route", "Mic 1A", "MIC1A"},
+ {"Mic 1A or 1B Select Capture Route", "Mic 1B", "MIC1B"},
+
+ {"Mic 1", "Capture Switch", "Mic 1A or 1B Select Capture Route"},
+
+ {"MIC1 Enable", NULL, "Mic 1"},
+
+ {"MIC1 ADC", NULL, "MIC1 Enable"},
+
+ {"AD 3 Select Capture Route", "Mic 1", "MIC1 ADC"},
+
+ {"AD3 Channel Gain", NULL, "AD 3 Select Capture Route"},
+
+ {"AD3 Enable", NULL, "AD3 Channel Gain"},
+
+ {"AD_OUT3", NULL, "AD3 Enable"},
+
+
+ /* HD Capture path */
+
+ {"AD 5 Select Capture Route", "Mic 2", "LINR ADC"},
+ {"AD 6 Select Capture Route", "Mic 1", "MIC1 ADC"},
+
+ {"AD5 Channel Gain", NULL, "AD 5 Select Capture Route"},
+ {"AD6 Channel Gain", NULL, "AD 6 Select Capture Route"},
+
+ {"AD57 Enable", NULL, "AD5 Channel Gain"},
+ {"AD68 Enable", NULL, "AD6 Channel Gain"},
+
+ {"AD_OUT57", NULL, "AD57 Enable"},
+ {"AD_OUT68", NULL, "AD68 Enable"},
+
+
+ /* Digital Microphone path */
+
+ {"DMic 1", "Capture Switch", "DMIC1"},
+ {"DMic 2", "Capture Switch", "DMIC2"},
+ {"DMic 3", "Capture Switch", "DMIC3"},
+ {"DMic 4", "Capture Switch", "DMIC4"},
+ {"DMic 5", "Capture Switch", "DMIC5"},
+ {"DMic 6", "Capture Switch", "DMIC6"},
+
+ {"AD 1 Select Capture Route", "DMic 1", "DMic 1"},
+ {"AD 2 Select Capture Route", "DMic 2", "DMic 2"},
+ {"AD 3 Select Capture Route", "DMic 3", "DMic 3"},
+ {"AD 5 Select Capture Route", "DMic 5", "DMic 5"},
+ {"AD 6 Select Capture Route", "DMic 6", "DMic 6"},
+
+ {"AD4 Channel Gain", NULL, "DMic 4"},
+
+ {"AD4 Enable", NULL, "AD4 Channel Gain"},
+
+ {"AD_OUT4", NULL, "AD4 Enable"},
+
+
+ /* LineIn Bypass path */
+
+ {"LINL to HSL Gain", NULL, "LINL Enable"},
+ {"LINR to HSR Gain", NULL, "LINR Enable"},
+
+ {"HSL DAC Driver", NULL, "LINL to HSL Gain"},
+ {"HSR DAC Driver", NULL, "LINR to HSR Gain"},
+
+
+ /* Analog Loopback path */
+
+ {"AD1 to IHFL Gain", NULL, "AD1 Channel Gain"},
+ {"AD2 to IHFR Gain", NULL, "AD2 Channel Gain"},
+
+ {"IHFL DAC", NULL, "AD1 to IHFL Gain"},
+ {"IHFR DAC", NULL, "AD2 to IHFR Gain"},
+
+
+ /* Acoustical Noise Cancellation path */
+
+ {"ANC Source Playback Route", "Mic 2 / DMic 5", "AD5 Channel Gain"},
+ {"ANC Source Playback Route", "Mic 1 / DMic 6", "AD6 Channel Gain"},
+
+ {"ANC Playback Switch", "Enabled", "ANC Source Playback Route"},
+
+ {"IHF Left Source Playback Route", "ANC", "ANC Playback Switch"},
+ {"IHF Right Source Playback Route", "ANC", "ANC Playback Switch"},
+ {"ANC to Earpiece", "Playback Switch", "ANC Playback Switch"},
+
+ {"HSL Digital Gain", NULL, "ANC to Earpiece"},
+
+
+ /* Sidetone Filter path */
+
+ {"Sidetone Left Source Playback Route", "LineIn Left", "AD1 Enable"},
+ {"Sidetone Left Source Playback Route", "LineIn Right", "AD2 Enable"},
+ {"Sidetone Left Source Playback Route", "Mic 1", "AD3 Enable"},
+ {"Sidetone Left Source Playback Route", "Headset Left", "DA_IN1"},
+ {"Sidetone Right Source Playback Route", "LineIn Right", "AD2 Enable"},
+ {"Sidetone Right Source Playback Route", "Mic 1", "AD3 Enable"},
+ {"Sidetone Right Source Playback Route", "DMic 4", "AD4 Enable"},
+ {"Sidetone Right Source Playback Route", "Headset Right", "DA_IN2"},
+
+ {"STFIR1 Control", NULL, "Sidetone Left Source Playback Route"},
+ {"STFIR2 Control", NULL, "Sidetone Right Source Playback Route"},
+
+ {"STFIR1 Gain", NULL, "STFIR1 Control"},
+ {"STFIR2 Gain", NULL, "STFIR2 Control"},
+
+ {"DA1 Channel Gain", NULL, "STFIR1 Gain"},
+ {"DA2 Channel Gain", NULL, "STFIR2 Gain"},
+};
+
+/* from -31 to 31 dB in 1 dB steps (mute instead of -32 dB) */
+static DECLARE_TLV_DB_SCALE(adx_dig_gain_tlv, -3200, 100, 1);
+
+/* from -62 to 0 dB in 1 dB steps (mute instead of -63 dB) */
+static DECLARE_TLV_DB_SCALE(dax_dig_gain_tlv, -6300, 100, 1);
+
+/* from 0 to 8 dB in 1 dB steps (mute instead of -1 dB) */
+static DECLARE_TLV_DB_SCALE(hs_ear_dig_gain_tlv, -100, 100, 1);
+
+/* from -30 to 0 dB in 1 dB steps (mute instead of -31 dB) */
+static DECLARE_TLV_DB_SCALE(stfir_dig_gain_tlv, -3100, 100, 1);
+
+/* from -32 to -20 dB in 4 dB steps / from -18 to 2 dB in 2 dB steps */
+static const unsigned int hs_gain_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0, 3, TLV_DB_SCALE_ITEM(-3200, 400, 0),
+ 4, 15, TLV_DB_SCALE_ITEM(-1800, 200, 0),
+};
+
+/* from 0 to 31 dB in 1 dB steps */
+static DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
+
+/* from -10 to 20 dB in 2 dB steps */
+static DECLARE_TLV_DB_SCALE(lin_gain_tlv, -1000, 200, 0);
+
+/* from -36 to 0 dB in 2 dB steps (mute instead of -38 dB) */
+static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1);
+
+static const char *enum_ena_dis[] = {"Enabled", "Disabled"};
+static const char *enum_dis_ena[] = {"Disabled", "Enabled"};
+
+static SOC_ENUM_SINGLE_DECL(soc_enum_hshpen,
+ REG_ANACONF1, REG_ANACONF1_HSHPEN, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_hslowpow,
+ REG_ANACONF1, REG_ANACONF1_HSLOWPOW, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_daclowpow1,
+ REG_ANACONF1, REG_ANACONF1_DACLOWPOW1, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_daclowpow0,
+ REG_ANACONF1, REG_ANACONF1_DACLOWPOW0, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_eardaclowpow,
+ REG_ANACONF1, REG_ANACONF1_EARDACLOWPOW, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_eardrvlowpow,
+ REG_ANACONF1, REG_ANACONF1_EARDRVLOWPOW, enum_dis_ena);
+
+static const char *enum_earselcm[] = {"0.95V", "1.10V", "1.27V", "1.58V"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_earselcm,
+ REG_ANACONF1, REG_ANACONF1_EARSELCM, enum_earselcm);
+
+static const char *enum_hsfadspeed[] = {"2ms", "0.5ms", "10.6ms", "5ms"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_hsfadspeed,
+ REG_DIGMICCONF, REG_DIGMICCONF_HSFADSPEED, enum_hsfadspeed);
+
+static const char *enum_envdetthre[] = {
+ "250mV", "300mV", "350mV", "400mV",
+ "450mV", "500mV", "550mV", "600mV",
+ "650mV", "700mV", "750mV", "800mV",
+ "850mV", "900mV", "950mV", "1.00V" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_envdetcpen,
+ REG_SIGENVCONF, REG_SIGENVCONF_ENVDETCPEN, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_envdeththre,
+ REG_ENVCPCONF, REG_ENVCPCONF_ENVDETHTHRE, enum_envdetthre);
+static SOC_ENUM_SINGLE_DECL(soc_enum_envdetlthre,
+ REG_ENVCPCONF, REG_ENVCPCONF_ENVDETLTHRE, enum_envdetthre);
+
+static const char* enum_envdettime[] = {
+ "26.6us", "53.2us", "106us", "213us",
+ "426us", "851us", "1.70ms", "3.40ms",
+ "6.81ms", "13.6ms", "27.2ms", "54.5ms",
+ "109ms", "218ms", "436ms", "872ms" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_envdettime,
+ REG_SIGENVCONF, REG_SIGENVCONF_ENVDETTIME, enum_envdettime);
+
+static const char *enum_ensemicx[] = {"Differential", "Single Ended"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_ensemic1,
+ REG_ANAGAIN1, REG_ANAGAINX_ENSEMICX, enum_ensemicx);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ensemic2,
+ REG_ANAGAIN2, REG_ANAGAINX_ENSEMICX, enum_ensemicx);
+static SOC_ENUM_SINGLE_DECL(soc_enum_lowpowmic1,
+ REG_ANAGAIN1, REG_ANAGAINX_LOWPOWMICX, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_lowpowmic2,
+ REG_ANAGAIN2, REG_ANAGAINX_LOWPOWMICX, enum_dis_ena);
+
+static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12nh, REG_ADFILTCONF,
+ REG_ADFILTCONF_AD1NH, REG_ADFILTCONF_AD2NH, enum_ena_dis);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34nh, REG_ADFILTCONF,
+ REG_ADFILTCONF_AD3NH, REG_ADFILTCONF_AD4NH, enum_ena_dis);
+
+static const char *enum_av_mode[] = {"Audio", "Voice"};
+static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12voice, REG_ADFILTCONF,
+ REG_ADFILTCONF_AD1VOICE, REG_ADFILTCONF_AD2VOICE, enum_av_mode);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34voice, REG_ADFILTCONF,
+ REG_ADFILTCONF_AD3VOICE, REG_ADFILTCONF_AD4VOICE, enum_av_mode);
+
+static SOC_ENUM_SINGLE_DECL(soc_enum_da12voice,
+ REG_DASLOTCONF1, REG_DASLOTCONF1_DA12VOICE, enum_av_mode);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da34voice,
+ REG_DASLOTCONF3, REG_DASLOTCONF3_DA34VOICE, enum_av_mode);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da56voice,
+ REG_DASLOTCONF5, REG_DASLOTCONF5_DA56VOICE, enum_av_mode);
+
+static SOC_ENUM_SINGLE_DECL(soc_enum_swapda12_34,
+ REG_DASLOTCONF1, REG_DASLOTCONF1_SWAPDA12_34, enum_dis_ena);
+
+static SOC_ENUM_DOUBLE_DECL(soc_enum_vib12swap, REG_CLASSDCONF1,
+ REG_CLASSDCONF1_VIB1SWAPEN, REG_CLASSDCONF1_VIB2SWAPEN, enum_dis_ena);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_hflrswap, REG_CLASSDCONF1,
+ REG_CLASSDCONF1_HFLSWAPEN, REG_CLASSDCONF1_HFRSWAPEN, enum_dis_ena);
+
+static SOC_ENUM_DOUBLE_DECL(soc_enum_fir01byp, REG_CLASSDCONF2,
+ REG_CLASSDCONF2_FIRBYP0, REG_CLASSDCONF2_FIRBYP1, enum_dis_ena);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_fir23byp, REG_CLASSDCONF2,
+ REG_CLASSDCONF2_FIRBYP2, REG_CLASSDCONF2_FIRBYP3, enum_dis_ena);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_highvol01, REG_CLASSDCONF2,
+ REG_CLASSDCONF2_HIGHVOLEN0, REG_CLASSDCONF2_HIGHVOLEN1, enum_dis_ena);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_highvol23, REG_CLASSDCONF2,
+ REG_CLASSDCONF2_HIGHVOLEN2, REG_CLASSDCONF2_HIGHVOLEN3, enum_dis_ena);
+
+static const char *enum_sinc53[] = {"Sinc 5", "Sinc 3"};
+static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic12sinc, REG_DMICFILTCONF,
+ REG_DMICFILTCONF_DMIC1SINC3, REG_DMICFILTCONF_DMIC2SINC3, enum_sinc53);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic34sinc, REG_DMICFILTCONF,
+ REG_DMICFILTCONF_DMIC3SINC3, REG_DMICFILTCONF_DMIC4SINC3, enum_sinc53);
+static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic56sinc, REG_DMICFILTCONF,
+ REG_DMICFILTCONF_DMIC5SINC3, REG_DMICFILTCONF_DMIC6SINC3, enum_sinc53);
+
+static const char *enum_da2hslr[] = {"Sidetone", "Audio Path"};
+static SOC_ENUM_DOUBLE_DECL(soc_enum_da2hslr, REG_DIGMULTCONF1,
+ REG_DIGMULTCONF1_DATOHSLEN, REG_DIGMULTCONF1_DATOHSREN, enum_da2hslr);
+
+static const char *enum_sinc31[] = {"Sinc 3", "Sinc 1"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_hsesinc,
+ REG_HSLEARDIGGAIN, REG_HSLEARDIGGAIN_HSSINC1, enum_sinc31);
+
+static const char *enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed,
+ REG_HSRDIGGAIN, REG_HSRDIGGAIN_FADESPEED, enum_fadespeed);
+
+/* Digital interface controls */
+
+/* Clocks */
+static SOC_ENUM_SINGLE_DECL(soc_enum_mastgen,
+ REG_DIGIFCONF1, REG_DIGIFCONF1_ENMASTGEN, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_fsbitclk0,
+ REG_DIGIFCONF1, REG_DIGIFCONF1_ENFSBITCLK0, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_fsbitclk1,
+ REG_DIGIFCONF1, REG_DIGIFCONF1_ENFSBITCLK1, enum_dis_ena);
+
+/* DA from slot mapping */
+static const char *enum_da_from_slot_map[] = {"SLOT0",
+ "SLOT1",
+ "SLOT2",
+ "SLOT3",
+ "SLOT4",
+ "SLOT5",
+ "SLOT6",
+ "SLOT7",
+ "SLOT8",
+ "SLOT9",
+ "SLOT10",
+ "SLOT11",
+ "SLOT12",
+ "SLOT13",
+ "SLOT14",
+ "SLOT15",
+ "SLOT16",
+ "SLOT17",
+ "SLOT18",
+ "SLOT19",
+ "SLOT20",
+ "SLOT21",
+ "SLOT22",
+ "SLOT23",
+ "SLOT24",
+ "SLOT25",
+ "SLOT26",
+ "SLOT27",
+ "SLOT28",
+ "SLOT29",
+ "SLOT30",
+ "SLOT31"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_da1slotmap,
+ REG_DASLOTCONF1, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da2slotmap,
+ REG_DASLOTCONF2, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da3slotmap,
+ REG_DASLOTCONF3, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da4slotmap,
+ REG_DASLOTCONF4, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da5slotmap,
+ REG_DASLOTCONF5, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da6slotmap,
+ REG_DASLOTCONF6, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da7slotmap,
+ REG_DASLOTCONF7, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_da8slotmap,
+ REG_DASLOTCONF8, REG_DASLOTCONFX_SLTODAX_SHIFT, enum_da_from_slot_map);
+
+/* AD to slot mapping */
+static const char *enum_ad_to_slot_map[] = {"AD_OUT1",
+ "AD_OUT2",
+ "AD_OUT3",
+ "AD_OUT4",
+ "AD_OUT5",
+ "AD_OUT6",
+ "AD_OUT7",
+ "AD_OUT8",
+ "zeroes",
+ "tristate"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map,
+ REG_ADSLOTSEL1, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot1map,
+ REG_ADSLOTSEL1, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot2map,
+ REG_ADSLOTSEL2, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot3map,
+ REG_ADSLOTSEL2, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot4map,
+ REG_ADSLOTSEL3, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot5map,
+ REG_ADSLOTSEL3, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot6map,
+ REG_ADSLOTSEL4, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot7map,
+ REG_ADSLOTSEL4, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot8map,
+ REG_ADSLOTSEL5, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot9map,
+ REG_ADSLOTSEL5, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot10map,
+ REG_ADSLOTSEL6, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot11map,
+ REG_ADSLOTSEL6, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot12map,
+ REG_ADSLOTSEL7, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot13map,
+ REG_ADSLOTSEL7, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot14map,
+ REG_ADSLOTSEL8, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot15map,
+ REG_ADSLOTSEL8, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot16map,
+ REG_ADSLOTSEL9, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot17map,
+ REG_ADSLOTSEL9, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot18map,
+ REG_ADSLOTSEL10, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot19map,
+ REG_ADSLOTSEL10, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot20map,
+ REG_ADSLOTSEL11, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot21map,
+ REG_ADSLOTSEL11, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot22map,
+ REG_ADSLOTSEL12, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot23map,
+ REG_ADSLOTSEL12, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot24map,
+ REG_ADSLOTSEL13, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot25map,
+ REG_ADSLOTSEL13, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot26map,
+ REG_ADSLOTSEL14, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot27map,
+ REG_ADSLOTSEL14, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot28map,
+ REG_ADSLOTSEL15, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot29map,
+ REG_ADSLOTSEL15, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot30map,
+ REG_ADSLOTSEL16, REG_ADSLOTSELX_EVEN_SHIFT, enum_ad_to_slot_map);
+static SOC_ENUM_SINGLE_DECL(soc_enum_adslot31map,
+ REG_ADSLOTSEL16, REG_ADSLOTSELX_ODD_SHIFT, enum_ad_to_slot_map);
+
+/* Digital loopback */
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad1loop,
+ REG_DASLOTCONF1, REG_DASLOTCONF1_DAI7TOADO1, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad2loop,
+ REG_DASLOTCONF2, REG_DASLOTCONF2_DAI8TOADO2, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad3loop,
+ REG_DASLOTCONF3, REG_DASLOTCONF3_DAI7TOADO3, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad4loop,
+ REG_DASLOTCONF4, REG_DASLOTCONF4_DAI8TOADO4, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad5loop,
+ REG_DASLOTCONF5, REG_DASLOTCONF5_DAI7TOADO5, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad6loop,
+ REG_DASLOTCONF6, REG_DASLOTCONF6_DAI8TOADO6, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad7loop,
+ REG_DASLOTCONF7, REG_DASLOTCONF7_DAI8TOADO7, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_ad8loop,
+ REG_DASLOTCONF8, REG_DASLOTCONF8_DAI7TOADO8, enum_dis_ena);
+
+/* Burst mode */
+static SOC_ENUM_SINGLE_DECL(soc_enum_if0fifoen,
+ REG_DIGIFCONF3, REG_DIGIFCONF3_IF0BFIFOEN, enum_dis_ena);
+static const char *enum_mask[] = {"Unmasked", "Masked"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomask,
+ REG_FIFOCONF1, REG_FIFOCONF1_BFIFOMASK, enum_mask);
+static const char *enum_bitclk0[] = {"19_2_MHz", "38_4_MHz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bfifo19m2,
+ REG_FIFOCONF1, REG_FIFOCONF1_BFIFO19M2, enum_bitclk0);
+
+static const char *enum_slavemaster[] = {"Slave", "Master"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast,
+ REG_FIFOCONF3, REG_FIFOCONF3_BFIFOMAST_SHIFT, enum_slavemaster);
+static SOC_ENUM_SINGLE_DECL(soc_enum_bfifoint,
+ REG_FIFOCONF3, REG_FIFOCONF3_BFIFORUN_SHIFT, enum_dis_ena);
+
+/* Sidetone */
+
+static int st_fir_value_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = REG_MASK_ALL;
+
+ return 0;
+}
+
+static int st_fir_value_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int st_fir_value_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret;
+ unsigned int val_msb = (int)ucontrol->value.integer.value[0] / 256;
+ unsigned int val_lsb = (int)ucontrol->value.integer.value[0] - val_msb * 256;
+ ret = ab8500_codec_write_reg_audio(ab8500_codec, REG_SIDFIRCOEF1, val_msb);
+ ret |= ab8500_codec_write_reg_audio(ab8500_codec, REG_SIDFIRCOEF2, val_lsb);
+ if (ret < 0) {
+ pr_err("%s: ERROR: Failed to write FIR-coeffecient!\n", __func__);
+ return 0;
+ }
+ return 1;
+}
+
+static const struct snd_kcontrol_new st_fir_value_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Sidetone FIR Coeffecient Value",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = st_fir_value_control_info,
+ .get = st_fir_value_control_get,
+ .put = st_fir_value_control_put,
+ .private_value = 1 /* ULPCLK */
+};
+
+static int st_fir_apply_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item) {
+ uinfo->value.enumerated.item = 1;
+ strcpy(uinfo->value.enumerated.name, "Apply");
+ } else {
+ strcpy(uinfo->value.enumerated.name, "Ready");
+ }
+ return 0;
+}
+
+static int st_fir_apply_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int reg = ab8500_codec_read_reg_audio(ab8500_codec, REG_SIDFIRADR);
+ ucontrol->value.enumerated.item[0] = reg & BMASK(REG_SIDFIRADR_FIRSIDSET);
+
+ return 0;
+}
+
+static int st_fir_apply_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret;
+
+ if (ucontrol->value.enumerated.item[0] != 0) {
+ ret = ab8500_codec_write_reg_audio(ab8500_codec,
+ REG_SIDFIRADR,
+ BMASK(REG_SIDFIRADR_FIRSIDSET));
+ if (ret < 0) {
+ pr_err("%s: ERROR: Failed to apply FIR-coeffecients!\n", __func__);
+ return 0;
+ }
+ pr_debug("%s: FIR-coeffecients applied.\n", __func__);
+ }
+
+ ret = ab8500_codec_write_reg_audio(ab8500_codec, REG_SIDFIRADR, 0);
+ if (ret < 0)
+ pr_err("%s: ERROR: Going to ready failed!\n", __func__);
+
+ return 1;
+}
+
+static const struct snd_kcontrol_new st_fir_apply_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Sidetone FIR Apply Coeffecients",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = st_fir_apply_control_info,
+ .get = st_fir_apply_control_get,
+ .put = st_fir_apply_control_put,
+ .private_value = 0 /* Ready */
+};
+
+static const char *enum_coeffctrl[] = {"Ready", "Apply"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_coeffctrl,
+ REG_SIDFIRADR, REG_SIDFIRADR_FIRSIDSET, enum_coeffctrl);
+
+/* TODO: move to DAPM */
+static SOC_ENUM_SINGLE_DECL(soc_enum_enfirsids,
+ REG_SIDFIRCONF, REG_SIDFIRCONF_ENFIRSIDS, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_parlhf,
+ REG_CLASSDCONF1, REG_CLASSDCONF1_PARLHF, enum_dis_ena);
+static SOC_ENUM_SINGLE_DECL(soc_enum_parlvib,
+ REG_CLASSDCONF1, REG_CLASSDCONF1_PARLVIB, enum_dis_ena);
+
+static struct snd_kcontrol_new ab8500_snd_controls[] = {
+ SOC_ENUM("Headset High Pass Playback Switch", soc_enum_hshpen),
+ SOC_ENUM("Headset Low Power Playback Switch", soc_enum_hslowpow),
+ SOC_ENUM("Headset DAC Low Power Playback Switch", soc_enum_daclowpow1),
+ SOC_ENUM("Headset DAC Drv Low Power Playback Switch",
+ soc_enum_daclowpow0),
+ SOC_ENUM("Earpiece DAC Low Power Playback Switch",
+ soc_enum_eardaclowpow),
+ SOC_ENUM("Earpiece DAC Drv Low Power Playback Switch",
+ soc_enum_eardrvlowpow),
+ SOC_ENUM("Earpiece Common Mode Playback Switch", soc_enum_earselcm),
+
+ SOC_ENUM("Headset Fade Speed Playback Switch", soc_enum_hsfadspeed),
+
+ SOC_ENUM("Charge Pump High Threshold For Low Voltage",
+ soc_enum_envdeththre),
+ SOC_ENUM("Charge Pump Low Threshold For Low Voltage",
+ soc_enum_envdetlthre),
+ SOC_ENUM("Charge Pump Envelope Detection", soc_enum_envdetcpen),
+ SOC_ENUM("Charge Pump Envelope Detection Decay Time",
+ soc_enum_envdettime),
+
+ SOC_ENUM("Mic 1 Type Capture Switch", soc_enum_ensemic1),
+ SOC_ENUM("Mic 2 Type Capture Switch", soc_enum_ensemic2),
+ SOC_ENUM("Mic 1 Low Power Capture Switch", soc_enum_lowpowmic1),
+ SOC_ENUM("Mic 2 Low Power Capture Switch", soc_enum_lowpowmic2),
+
+ SOC_ENUM("LineIn High Pass Capture Switch", soc_enum_ad12nh),
+ SOC_ENUM("Mic High Pass Capture Switch", soc_enum_ad34nh),
+ SOC_ENUM("LineIn Mode Capture Switch", soc_enum_ad12voice),
+ SOC_ENUM("Mic Mode Capture Switch", soc_enum_ad34voice),
+
+ SOC_ENUM("Headset Mode Playback Switch", soc_enum_da12voice),
+ SOC_ENUM("IHF Mode Playback Switch", soc_enum_da34voice),
+ SOC_ENUM("Vibra Mode Playback Switch", soc_enum_da56voice),
+
+ SOC_ENUM("IHF and Headset Swap Playback Switch", soc_enum_swapda12_34),
+
+ SOC_ENUM("IHF Low EMI Mode Playback Switch", soc_enum_hflrswap),
+ SOC_ENUM("Vibra Low EMI Mode Playback Switch", soc_enum_vib12swap),
+
+ SOC_ENUM("IHF FIR Bypass Playback Switch", soc_enum_fir01byp),
+ SOC_ENUM("Vibra FIR Bypass Playback Switch", soc_enum_fir23byp),
+
+ /* TODO: Cannot be changed on the fly with digital channel enabled. */
+ SOC_ENUM("IHF High Volume Playback Switch", soc_enum_highvol01),
+ SOC_ENUM("Vibra High Volume Playback Switch", soc_enum_highvol23),
+
+ SOC_SINGLE("ClassD High Pass Gain Playback Volume",
+ REG_CLASSDCONF3, REG_CLASSDCONF3_DITHHPGAIN,
+ REG_CLASSDCONF3_DITHHPGAIN_MAX, NORMAL),
+ SOC_SINGLE("ClassD White Gain Playback Volume",
+ REG_CLASSDCONF3, REG_CLASSDCONF3_DITHWGAIN,
+ REG_CLASSDCONF3_DITHWGAIN_MAX, NORMAL),
+
+ SOC_ENUM("LineIn Filter Capture Switch", soc_enum_dmic12sinc),
+ SOC_ENUM("Mic Filter Capture Switch", soc_enum_dmic34sinc),
+ SOC_ENUM("HD Mic Filter Capture Switch", soc_enum_dmic56sinc),
+
+ SOC_ENUM("Headset Source Playback Route", soc_enum_da2hslr),
+
+ /* TODO: Cannot be changed on the fly with digital channel enabled. */
+ SOC_ENUM("Headset Filter Playback Switch", soc_enum_hsesinc),
+
+ SOC_ENUM("Digital Gain Fade Speed Switch", soc_enum_fadespeed),
+
+ SOC_DOUBLE_R("Vibra PWM Duty Cycle N Playback Volume",
+ REG_PWMGENCONF3, REG_PWMGENCONF5,
+ REG_PWMGENCONFX_PWMVIBXDUTCYC,
+ REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX, NORMAL),
+ SOC_DOUBLE_R("Vibra PWM Duty Cycle P Playback Volume",
+ REG_PWMGENCONF2, REG_PWMGENCONF4,
+ REG_PWMGENCONFX_PWMVIBXDUTCYC,
+ REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX, NORMAL),
+
+ /* TODO: move to DAPM */
+ SOC_ENUM("Sidetone Playback Switch", soc_enum_enfirsids),
+ SOC_ENUM("IHF L and R Bridge Playback Route", soc_enum_parlhf),
+ SOC_ENUM("Vibra 1 and 2 Bridge Playback Route", soc_enum_parlvib),
+
+ /* Digital gains for AD side */
+
+ SOC_DOUBLE_R_TLV("LineIn Master Gain Capture Volume",
+ REG_ADDIGGAIN1, REG_ADDIGGAIN2,
+ 0, REG_ADDIGGAINX_ADXGAIN_MAX, INVERT, adx_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("Mic Master Gain Capture Volume",
+ REG_ADDIGGAIN3, REG_ADDIGGAIN4,
+ 0, REG_ADDIGGAINX_ADXGAIN_MAX, INVERT, adx_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("HD Mic Master Gain Capture Volume",
+ REG_ADDIGGAIN5, REG_ADDIGGAIN6,
+ 0, REG_ADDIGGAINX_ADXGAIN_MAX, INVERT, adx_dig_gain_tlv),
+
+ /* Digital gains for DA side */
+
+ SOC_DOUBLE_R_TLV("Headset Master Gain Playback Volume",
+ REG_DADIGGAIN1, REG_DADIGGAIN2,
+ 0, REG_DADIGGAINX_DAXGAIN_MAX, INVERT, dax_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("IHF Master Gain Playback Volume",
+ REG_DADIGGAIN3, REG_DADIGGAIN4,
+ 0, REG_DADIGGAINX_DAXGAIN_MAX, INVERT, dax_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("Vibra Master Gain Playback Volume",
+ REG_DADIGGAIN5, REG_DADIGGAIN6,
+ 0, REG_DADIGGAINX_DAXGAIN_MAX, INVERT, dax_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("Analog Loopback Gain Playback Volume",
+ REG_ADDIGLOOPGAIN1, REG_ADDIGLOOPGAIN2,
+ 0, REG_ADDIGLOOPGAINX_ADXLBGAIN_MAX, INVERT, dax_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("Headset Digital Gain Playback Volume",
+ REG_HSLEARDIGGAIN, REG_HSRDIGGAIN,
+ 0, REG_HSLEARDIGGAIN_HSLDGAIN_MAX, INVERT, hs_ear_dig_gain_tlv),
+ SOC_DOUBLE_R_TLV("Sidetone Digital Gain Playback Volume",
+ REG_SIDFIRGAIN1, REG_SIDFIRGAIN2,
+ 0, REG_SIDFIRGAINX_FIRSIDXGAIN_MAX, INVERT, stfir_dig_gain_tlv),
+
+ /* Analog gains */
+
+ SOC_DOUBLE_TLV("Headset Gain Playback Volume",
+ REG_ANAGAIN3,
+ REG_ANAGAIN3_HSLGAIN, REG_ANAGAIN3_HSRGAIN,
+ REG_ANAGAIN3_HSXGAIN_MAX, INVERT, hs_gain_tlv),
+ SOC_SINGLE_TLV("Mic 1 Capture Volume",
+ REG_ANAGAIN1,
+ REG_ANAGAINX_MICXGAIN,
+ REG_ANAGAINX_MICXGAIN_MAX, NORMAL, mic_gain_tlv),
+ SOC_SINGLE_TLV("Mic 2 Capture Volume",
+ REG_ANAGAIN2,
+ REG_ANAGAINX_MICXGAIN,
+ REG_ANAGAINX_MICXGAIN_MAX, NORMAL, mic_gain_tlv),
+ SOC_DOUBLE_TLV("LineIn Capture Volume",
+ REG_ANAGAIN4,
+ REG_ANAGAIN4_LINLGAIN, REG_ANAGAIN4_LINRGAIN,
+ REG_ANAGAIN4_LINXGAIN_MAX, NORMAL, lin_gain_tlv),
+ SOC_DOUBLE_R_TLV("LineIn to Headset Bypass Playback Volume",
+ REG_DIGLINHSLGAIN, REG_DIGLINHSRGAIN,
+ REG_DIGLINHSXGAIN_LINTOHSXGAIN,
+ REG_DIGLINHSXGAIN_LINTOHSXGAIN_MAX, INVERT, lin2hs_gain_tlv),
+
+ /* Digital Interface controls */
+
+ /* Clocks */
+ SOC_ENUM("Digital Interface Master Generator Switch", soc_enum_mastgen),
+ SOC_ENUM("Digital Interface 0 Bit-clock Switch", soc_enum_fsbitclk0),
+ SOC_ENUM("Digital Interface 1 Bit-clock Switch", soc_enum_fsbitclk1),
+
+ /* DA from slot mapping */
+ SOC_ENUM("Digital Interface DA 1 From Slot Map", soc_enum_da1slotmap),
+ SOC_ENUM("Digital Interface DA 2 From Slot Map", soc_enum_da2slotmap),
+ SOC_ENUM("Digital Interface DA 3 From Slot Map", soc_enum_da3slotmap),
+ SOC_ENUM("Digital Interface DA 4 From Slot Map", soc_enum_da4slotmap),
+ SOC_ENUM("Digital Interface DA 5 From Slot Map", soc_enum_da5slotmap),
+ SOC_ENUM("Digital Interface DA 6 From Slot Map", soc_enum_da6slotmap),
+ SOC_ENUM("Digital Interface DA 7 From Slot Map", soc_enum_da7slotmap),
+ SOC_ENUM("Digital Interface DA 8 From Slot Map", soc_enum_da8slotmap),
+
+ /* AD to slot mapping */
+ SOC_ENUM("Digital Interface AD To Slot 0 Map", soc_enum_adslot0map),
+ SOC_ENUM("Digital Interface AD To Slot 1 Map", soc_enum_adslot1map),
+ SOC_ENUM("Digital Interface AD To Slot 2 Map", soc_enum_adslot2map),
+ SOC_ENUM("Digital Interface AD To Slot 3 Map", soc_enum_adslot3map),
+ SOC_ENUM("Digital Interface AD To Slot 4 Map", soc_enum_adslot4map),
+ SOC_ENUM("Digital Interface AD To Slot 5 Map", soc_enum_adslot5map),
+ SOC_ENUM("Digital Interface AD To Slot 6 Map", soc_enum_adslot6map),
+ SOC_ENUM("Digital Interface AD To Slot 7 Map", soc_enum_adslot7map),
+ SOC_ENUM("Digital Interface AD To Slot 8 Map", soc_enum_adslot8map),
+ SOC_ENUM("Digital Interface AD To Slot 9 Map", soc_enum_adslot9map),
+ SOC_ENUM("Digital Interface AD To Slot 10 Map", soc_enum_adslot10map),
+ SOC_ENUM("Digital Interface AD To Slot 11 Map", soc_enum_adslot11map),
+ SOC_ENUM("Digital Interface AD To Slot 12 Map", soc_enum_adslot12map),
+ SOC_ENUM("Digital Interface AD To Slot 13 Map", soc_enum_adslot13map),
+ SOC_ENUM("Digital Interface AD To Slot 14 Map", soc_enum_adslot14map),
+ SOC_ENUM("Digital Interface AD To Slot 15 Map", soc_enum_adslot15map),
+ SOC_ENUM("Digital Interface AD To Slot 16 Map", soc_enum_adslot16map),
+ SOC_ENUM("Digital Interface AD To Slot 17 Map", soc_enum_adslot17map),
+ SOC_ENUM("Digital Interface AD To Slot 18 Map", soc_enum_adslot18map),
+ SOC_ENUM("Digital Interface AD To Slot 19 Map", soc_enum_adslot19map),
+ SOC_ENUM("Digital Interface AD To Slot 20 Map", soc_enum_adslot20map),
+ SOC_ENUM("Digital Interface AD To Slot 21 Map", soc_enum_adslot21map),
+ SOC_ENUM("Digital Interface AD To Slot 22 Map", soc_enum_adslot22map),
+ SOC_ENUM("Digital Interface AD To Slot 23 Map", soc_enum_adslot23map),
+ SOC_ENUM("Digital Interface AD To Slot 24 Map", soc_enum_adslot24map),
+ SOC_ENUM("Digital Interface AD To Slot 25 Map", soc_enum_adslot25map),
+ SOC_ENUM("Digital Interface AD To Slot 26 Map", soc_enum_adslot26map),
+ SOC_ENUM("Digital Interface AD To Slot 27 Map", soc_enum_adslot27map),
+ SOC_ENUM("Digital Interface AD To Slot 28 Map", soc_enum_adslot28map),
+ SOC_ENUM("Digital Interface AD To Slot 29 Map", soc_enum_adslot29map),
+ SOC_ENUM("Digital Interface AD To Slot 30 Map", soc_enum_adslot30map),
+ SOC_ENUM("Digital Interface AD To Slot 31 Map", soc_enum_adslot31map),
+
+ /* Loopback */
+ SOC_ENUM("Digital Interface AD 1 Loopback Switch", soc_enum_ad1loop),
+ SOC_ENUM("Digital Interface AD 2 Loopback Switch", soc_enum_ad2loop),
+ SOC_ENUM("Digital Interface AD 3 Loopback Switch", soc_enum_ad3loop),
+ SOC_ENUM("Digital Interface AD 4 Loopback Switch", soc_enum_ad4loop),
+ SOC_ENUM("Digital Interface AD 5 Loopback Switch", soc_enum_ad5loop),
+ SOC_ENUM("Digital Interface AD 6 Loopback Switch", soc_enum_ad6loop),
+ SOC_ENUM("Digital Interface AD 7 Loopback Switch", soc_enum_ad7loop),
+ SOC_ENUM("Digital Interface AD 8 Loopback Switch", soc_enum_ad8loop),
+
+ /* Burst FIFO */
+ SOC_ENUM("Digital Interface 0 FIFO Enable Switch", soc_enum_if0fifoen),
+ SOC_ENUM("Burst FIFO Mask", soc_enum_bfifomask),
+ SOC_ENUM("Burst FIFO Bit-clock Frequency", soc_enum_bfifo19m2),
+ SOC_SINGLE("Burst FIFO Threshold",
+ REG_FIFOCONF1,
+ REG_FIFOCONF1_BFIFOINT_SHIFT,
+ REG_FIFOCONF1_BFIFOINT_MAX,
+ NORMAL),
+ SOC_SINGLE("Burst FIFO Length",
+ REG_FIFOCONF2,
+ REG_FIFOCONF2_BFIFOTX_SHIFT,
+ REG_FIFOCONF2_BFIFOTX_MAX,
+ NORMAL),
+ SOC_SINGLE("Burst FIFO EOS Extra Slots",
+ REG_FIFOCONF3,
+ REG_FIFOCONF3_BFIFOEXSL_SHIFT,
+ REG_FIFOCONF3_BFIFOEXSL_MAX,
+ NORMAL),
+ SOC_SINGLE("Burst FIFO FS Extra Bit-clocks",
+ REG_FIFOCONF3,
+ REG_FIFOCONF3_PREBITCLK0_SHIFT,
+ REG_FIFOCONF3_PREBITCLK0_MAX,
+ NORMAL),
+ SOC_ENUM("Burst FIFO Interface Mode", soc_enum_bfifomast),
+ SOC_ENUM("Burst FIFO Interface Switch", soc_enum_bfifoint),
+ SOC_SINGLE("Burst FIFO Switch Frame Number",
+ REG_FIFOCONF4,
+ REG_FIFOCONF4_BFIFOFRAMSW_SHIFT,
+ REG_FIFOCONF4_BFIFOFRAMSW_MAX,
+ NORMAL),
+ SOC_SINGLE("Burst FIFO Wake Up Delay",
+ REG_FIFOCONF5,
+ REG_FIFOCONF5_BFIFOWAKEUP_SHIFT,
+ REG_FIFOCONF5_BFIFOWAKEUP_MAX,
+ NORMAL),
+ SOC_SINGLE("Burst FIFO Samples In FIFO",
+ REG_FIFOCONF6,
+ REG_FIFOCONF6_BFIFOSAMPLE_SHIFT,
+ REG_FIFOCONF6_BFIFOSAMPLE_MAX,
+ NORMAL),
+
+ /* Sidetone */
+ SOC_SINGLE("Sidetone FIR Coeffecient Index",
+ REG_SIDFIRADR,
+ REG_SIDFIRADR_ADDRESS_SHIFT,
+ REG_SIDFIRADR_ADDRESS_MAX,
+ NORMAL),
+};
+
+static int ab8500_codec_set_format_if1(struct snd_soc_codec *codec, unsigned int fmt)
+{
+ unsigned int clear_mask, set_mask;
+
+ /* Master or slave */
+
+ clear_mask = BMASK(REG_DIGIFCONF3_IF1MASTER);
+ set_mask = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */
+ pr_debug("%s: IF1 Master-mode: AB8500 master.\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF3_IF1MASTER);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */
+ pr_debug("%s: IF1 Master-mode: AB8500 slave.\n", __func__);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */
+ case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
+ pr_err("%s: ERROR: The device is either a master or a slave.\n",
+ __func__);
+ default:
+ pr_err("%s: ERROR: Unsupporter master mask 0x%x\n",
+ __func__,
+ fmt & SND_SOC_DAIFMT_MASTER_MASK);
+ return -EINVAL;
+ }
+
+ ab8500_codec_update_reg_audio(codec,
+ REG_DIGIFCONF3,
+ BMASK(REG_DIGIFCONF3_IF1MASTER),
+ BMASK(REG_DIGIFCONF3_IF1MASTER));
+
+ /* I2S or TDM */
+
+ clear_mask = BMASK(REG_DIGIFCONF4_FSYNC1P) |
+ BMASK(REG_DIGIFCONF4_BITCLK1P) |
+ BMASK(REG_DIGIFCONF4_IF1FORMAT1) |
+ BMASK(REG_DIGIFCONF4_IF1FORMAT0);
+ set_mask = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S: /* I2S mode */
+ pr_debug("%s: IF1 Protocol: I2S\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF4_IF1FORMAT1);
+ break;
+ case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
+ pr_debug("%s: IF1 Protocol: DSP B (TDM)\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF4_IF1FORMAT0);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupported format (0x%x)!\n",
+ __func__,
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+ return -EINVAL;
+ }
+
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF4, clear_mask, set_mask);
+
+ return 0;
+}
+
+static int ab8500_codec_set_word_length_if1(struct snd_soc_codec *codec, unsigned int wl)
+{
+ unsigned int clear_mask, set_mask;
+
+ clear_mask = BMASK(REG_DIGIFCONF4_IF1WL1) | BMASK(REG_DIGIFCONF4_IF1WL0);
+ set_mask = 0;
+
+ switch (wl) {
+ case 16:
+ break;
+ case 20:
+ set_mask |= BMASK(REG_DIGIFCONF4_IF1WL0);
+ break;
+ case 24:
+ set_mask |= BMASK(REG_DIGIFCONF4_IF1WL1);
+ break;
+ case 32:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1) |
+ BMASK(REG_DIGIFCONF2_IF0WL0);
+ break;
+ default:
+ pr_err("%s: Unsupporter word-length 0x%x\n", __func__, wl);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: Word-length: %d bits.\n", __func__, wl);
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF4, clear_mask, set_mask);
+
+ return 0;
+}
+
+static int ab8500_codec_set_bit_delay_if1(struct snd_soc_codec *codec, unsigned int delay)
+{
+ unsigned int clear_mask, set_mask;
+
+ clear_mask = BMASK(REG_DIGIFCONF4_IF1DEL);
+ set_mask = 0;
+
+ switch (delay) {
+ case 0:
+ break;
+ case 1:
+ set_mask |= BMASK(REG_DIGIFCONF4_IF1DEL);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupported bit-delay (0x%x)!\n", __func__, delay);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: IF1 Bit-delay: %d bits.\n", __func__, delay);
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF4, clear_mask, set_mask);
+
+ return 0;
+}
+
+/* Configures audio macrocell into the AB8500 Chip */
+static void ab8500_codec_configure_audio_macrocell(struct snd_soc_codec *codec)
+{
+ int data, ret;
+
+ ret = ab8500_sysctrl_write(AB8500_STW4500CTRL3,
+ AB8500_STW4500CTRL3_CLK32KOUT2DIS | AB8500_STW4500CTRL3_RESETAUDN,
+ AB8500_STW4500CTRL3_RESETAUDN);
+ if (ret < 0)
+ pr_err("%s: WARN: Unable to set reg STW4500CTRL3!\n", __func__);
+
+ data = ab8500_codec_read_reg(codec, AB8500_MISC, AB8500_GPIO_DIR4_REG);
+ data |= GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | GPIO31_DIR_OUTPUT;
+ ab8500_codec_write_reg(codec, AB8500_MISC, AB8500_GPIO_DIR4_REG, data);
+}
+
+/* Extended interface for codec-driver */
+
+void ab8500_audio_power_control(bool power_on)
+{
+ if (ab8500_codec == NULL) {
+ pr_err("%s: ERROR: AB8500 ASoC-driver not yet probed!\n", __func__);
+ return;
+ }
+
+ if (power_on) {
+ unsigned int set_mask;
+ pr_debug("Enabling AB8500.");
+ set_mask = BMASK(REG_POWERUP_POWERUP) | BMASK(REG_POWERUP_ENANA);
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_POWERUP, 0x00, set_mask);
+ } else {
+ unsigned int clear_mask;
+ pr_debug("Disabling AB8500.");
+ clear_mask = BMASK(REG_POWERUP_POWERUP) | BMASK(REG_POWERUP_ENANA);
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_POWERUP, clear_mask, 0x00);
+ }
+}
+
+/* Extended interface for codec-driver */
+
+int ab8500_audio_set_word_length(struct snd_soc_dai *dai, unsigned int wl)
+{
+ unsigned int clear_mask, set_mask;
+ struct snd_soc_codec *codec = dai->codec;
+
+ clear_mask = BMASK(REG_DIGIFCONF2_IF0WL0) | BMASK(REG_DIGIFCONF2_IF0WL1);
+ set_mask = 0;
+
+ switch (wl) {
+ case 16:
+ break;
+ case 20:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL0);
+ break;
+ case 24:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1);
+ break;
+ case 32:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1) |
+ BMASK(REG_DIGIFCONF2_IF0WL0);
+ break;
+ default:
+ pr_err("%s: Unsupporter word-length 0x%x\n", __func__, wl);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: IF0 Word-length: %d bits.\n", __func__, wl);
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF2, clear_mask, set_mask);
+
+ return 0;
+}
+
+int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay)
+{
+ unsigned int clear_mask, set_mask;
+ struct snd_soc_codec *codec = dai->codec;
+
+ clear_mask = BMASK(REG_DIGIFCONF2_IF0DEL);
+ set_mask = 0;
+
+ switch (delay) {
+ case 0:
+ break;
+ case 1:
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0DEL);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupported bit-delay (0x%x)!\n", __func__, delay);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: IF0 Bit-delay: %d bits.\n", __func__, delay);
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF2, clear_mask, set_mask);
+
+ return 0;
+}
+
+int ab8500_audio_setup_if1(struct snd_soc_codec *codec,
+ unsigned int fmt,
+ unsigned int wl,
+ unsigned int delay)
+{
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ ret = ab8500_codec_set_format_if1(codec, fmt);
+ if (ret)
+ return -1;
+
+ ret = ab8500_codec_set_bit_delay_if1(codec, delay);
+ if (ret)
+ return -1;
+
+
+ ret = ab8500_codec_set_word_length_if1(codec, wl);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+bool ab8500_audio_dapm_path_active(enum ab8500_audio_dapm_path dapm_path)
+{
+ int reg, reg_mask;
+
+ switch (dapm_path) {
+ case AB8500_AUDIO_DAPM_PATH_DMIC:
+ reg = ab8500_codec_read_reg_audio(ab8500_codec, REG_DIGMICCONF);
+ reg_mask = BMASK(REG_DIGMICCONF_ENDMIC1) |
+ BMASK(REG_DIGMICCONF_ENDMIC2) |
+ BMASK(REG_DIGMICCONF_ENDMIC3) |
+ BMASK(REG_DIGMICCONF_ENDMIC4) |
+ BMASK(REG_DIGMICCONF_ENDMIC5) |
+ BMASK(REG_DIGMICCONF_ENDMIC6);
+ return reg & reg_mask;
+
+ case AB8500_AUDIO_DAPM_PATH_AMIC1:
+ reg = ab8500_codec_read_reg_audio(ab8500_codec, REG_ANACONF2);
+ reg_mask = BMASK(REG_ANACONF2_MUTMIC1);
+ return !(reg & reg_mask);
+
+ case AB8500_AUDIO_DAPM_PATH_AMIC2:
+ reg = ab8500_codec_read_reg_audio(ab8500_codec, REG_ANACONF2);
+ reg_mask = BMASK(REG_ANACONF2_MUTMIC2);
+ return !(reg & reg_mask);
+
+ default:
+ return false;
+ }
+}
+
+static int ab8500_codec_add_widgets(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(&codec->dapm, ab8500_dapm_widgets,
+ ARRAY_SIZE(ab8500_dapm_widgets));
+ if (ret < 0) {
+ pr_err("%s: Failed to create DAPM controls (%d).\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon));
+ if (ret < 0) {
+ pr_err("%s: Failed to add DAPM routes (%d).\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ab8500_codec_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
+{
+ pr_debug("%s Enter.\n", __func__);
+ return 0;
+}
+
+static int ab8500_codec_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ return 0;
+}
+
+static int ab8500_codec_pcm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ /* Clear interrupt status registers by reading them. */
+ ab8500_codec_read_reg_audio(dai->codec, REG_AUDINTSOURCE1);
+ ab8500_codec_read_reg_audio(dai->codec, REG_AUDINTSOURCE2);
+
+ return 0;
+}
+
+static void ab8500_codec_pcm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ ab8500_codec_dump_all_reg(dai->codec);
+}
+
+static int ab8500_codec_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ pr_err("%s Enter.\n", __func__);
+
+ return 0;
+}
+
+/* Gates clocking according format mask */
+static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec, unsigned int fmt)
+{
+ unsigned int clear_mask;
+ unsigned int set_mask;
+
+ clear_mask = BMASK(REG_DIGIFCONF1_ENMASTGEN) |
+ BMASK(REG_DIGIFCONF1_ENFSBITCLK0);
+
+ set_mask = BMASK(REG_DIGIFCONF1_ENMASTGEN);
+
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
+ case SND_SOC_DAIFMT_CONT: /* continuous clock */
+ pr_debug("%s: IF0 Clock is continous.\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF1_ENFSBITCLK0);
+ break;
+ case SND_SOC_DAIFMT_GATED: /* clock is gated */
+ pr_debug("%s: IF0 Clock is gated.\n", __func__);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupporter clock mask (0x%x)!\n",
+ __func__,
+ fmt & SND_SOC_DAIFMT_CLOCK_MASK);
+ return -EINVAL;
+ }
+
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF1, clear_mask, set_mask);
+
+ return 0;
+}
+
+static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ unsigned int clear_mask;
+ unsigned int set_mask;
+ struct snd_soc_codec *codec = dai->codec;
+ int err;
+
+ pr_debug("%s: Enter (fmt = 0x%x)\n", __func__, fmt);
+
+ clear_mask = BMASK(REG_DIGIFCONF3_IF1DATOIF0AD) |
+ BMASK(REG_DIGIFCONF3_IF1CLKTOIF0CLK) |
+ BMASK(REG_DIGIFCONF3_IF0BFIFOEN) |
+ BMASK(REG_DIGIFCONF3_IF0MASTER);
+ set_mask = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */
+ pr_debug("%s: IF0 Master-mode: AB8500 master.\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF3_IF0MASTER);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */
+ pr_debug("%s: IF0 Master-mode: AB8500 slave.\n", __func__);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */
+ case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
+ pr_err("%s: ERROR: The device is either a master or a slave.\n", __func__);
+ default:
+ pr_err("%s: ERROR: Unsupporter master mask 0x%x\n",
+ __func__,
+ (fmt & SND_SOC_DAIFMT_MASTER_MASK));
+ return -EINVAL;
+ break;
+ }
+
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF3, clear_mask, set_mask);
+
+ /* Set clock gating */
+ err = ab8500_codec_set_dai_clock_gate(codec, fmt);
+ if (err) {
+ pr_err("%s: ERRROR: Failed to set clock gate (%d).\n", __func__, err);
+ return err;
+ }
+
+ /* Setting data transfer format */
+
+ clear_mask = BMASK(REG_DIGIFCONF2_IF0FORMAT0) |
+ BMASK(REG_DIGIFCONF2_IF0FORMAT1) |
+ BMASK(REG_DIGIFCONF2_FSYNC0P) |
+ BMASK(REG_DIGIFCONF2_BITCLK0P);
+ set_mask = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S: /* I2S mode */
+ pr_debug("%s: IF0 Protocol: I2S\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT1);
+
+ /* 32 bit, 0 delay */
+ ab8500_audio_set_word_length(dai, 32);
+ ab8500_audio_set_bit_delay(dai, 0);
+
+ break;
+ case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
+ pr_debug("%s: IF0 Protocol: DSP A (TDM)\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT1);
+ break;
+ case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
+ pr_debug("%s: IF0 Protocol: DSP B (TDM)\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT0);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupporter format (0x%x)!\n",
+ __func__,
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
+ pr_debug("%s: IF0: Normal bit clock, normal frame\n", __func__);
+ break;
+ case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */
+ pr_debug("%s: IF0: Normal bit clock, inverted frame\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF2_FSYNC0P);
+ break;
+ case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */
+ pr_debug("%s: IF0: Inverted bit clock, normal frame\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF2_BITCLK0P);
+ break;
+ case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */
+ pr_debug("%s: IF0: Inverted bit clock, inverted frame\n", __func__);
+ set_mask |= BMASK(REG_DIGIFCONF2_FSYNC0P);
+ set_mask |= BMASK(REG_DIGIFCONF2_BITCLK0P);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupported INV mask 0x%x\n",
+ __func__,
+ (fmt & SND_SOC_DAIFMT_INV_MASK));
+ return -EINVAL;
+ break;
+ }
+
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF2, clear_mask, set_mask);
+
+ return 0;
+}
+
+static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ unsigned int set_mask, clear_mask, slots_active;
+
+ /* Only 16 bit slot width is supported at the moment in TDM mode */
+ if (slot_width != 16) {
+ pr_err("%s: ERROR: Unsupported slot_width %d.\n",
+ __func__, slot_width);
+ return -EINVAL;
+ }
+
+ /* Setup TDM clocking according to slot count */
+ pr_debug("%s: Slots, total: %d\n", __func__, slots);
+ clear_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) |
+ BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
+ switch (slots) {
+ case 2:
+ set_mask = REG_MASK_NONE;
+ break;
+ case 4:
+ set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0);
+ break;
+ case 8:
+ set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
+ break;
+ case 16:
+ set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) |
+ BMASK(REG_DIGIFCONF1_IF0BITCLKOS1);
+ break;
+ default:
+ pr_err("%s: ERROR: Unsupported number of slots (%d)!\n", __func__, slots);
+ return -EINVAL;
+ }
+ ab8500_codec_update_reg_audio(codec, REG_DIGIFCONF1, clear_mask, set_mask);
+
+ /* Setup TDM DA according to active tx slots */
+ clear_mask = REG_DASLOTCONFX_SLTODAX_MASK;
+ slots_active = hweight32(tx_mask);
+ pr_debug("%s: Slots, active, TX: %d\n", __func__, slots_active);
+ switch (slots_active) {
+ case 0:
+ break;
+ case 1:
+ /* Slot 9 -> DA_IN1 & DA_IN3 */
+ ab8500_codec_update_reg_audio(codec, REG_DASLOTCONF1, clear_mask, 9);
+ ab8500_codec_update_reg_audio(codec, REG_DASLOTCONF3, clear_mask, 9);
+ break;
+ case 2:
+ /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
+ ab8500_codec_update_reg_audio(codec, REG_DASLOTCONF1, clear_mask, 9);
+ ab8500_codec_update_reg_audio(codec, REG_DASLOTCONF3, clear_mask, 9);
+ ab8500_codec_update_reg_audio(codec, REG_DASLOTCONF2, clear_mask, 11);
+ ab8500_codec_update_reg_audio(codec, REG_DASLOTCONF4, clear_mask, 11);
+
+ break;
+ case 8:
+ pr_debug("%s: In 8-channel mode DA-from-slot mapping is set manually.", __func__);
+ break;
+ default:
+ pr_err("%s: Unsupported number of active TX-slots (%d)!\n", __func__, slots_active);
+ return -EINVAL;
+ }
+
+ /* Setup TDM AD according to active RX-slots */
+ slots_active = hweight32(rx_mask);
+ pr_debug("%s: Slots, active, RX: %d\n", __func__, slots_active);
+ switch (slots_active) {
+ case 0:
+ break;
+ case 1:
+ /* AD_OUT3 -> slot 0 & 1 */
+ ab8500_codec_update_reg_audio(codec, REG_ADSLOTSEL1,
+ REG_MASK_ALL,
+ REG_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
+ REG_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD);
+ break;
+ case 2:
+ /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
+ ab8500_codec_update_reg_audio(codec, REG_ADSLOTSEL1,
+ REG_MASK_ALL,
+ REG_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
+ REG_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD);
+ break;
+ case 8:
+ pr_debug("%s: In 8-channel mode AD-to-slot mapping is set manually.", __func__);
+ break;
+ default:
+ pr_err("%s: Unsupported number of active RX-slots (%d)!\n", __func__, slots_active);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct snd_soc_dai_driver ab8500_codec_dai[] = {
+ {
+ .name = "ab8500-codec-dai.0",
+ .id = 0,
+ .playback = {
+ .stream_name = "ab8500_0p",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = AB8500_SUPPORTED_RATE,
+ .formats = AB8500_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .startup = ab8500_codec_pcm_startup,
+ .prepare = ab8500_codec_pcm_prepare,
+ .hw_params = ab8500_codec_pcm_hw_params,
+ .shutdown = ab8500_codec_pcm_shutdown,
+ .set_sysclk = ab8500_codec_set_dai_sysclk,
+ .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
+ .set_fmt = ab8500_codec_set_dai_fmt,
+ }
+ },
+ .symmetric_rates = 1
+ },
+ {
+ .name = "ab8500-codec-dai.1",
+ .id = 1,
+ .capture = {
+ .stream_name = "ab8500_0c",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = AB8500_SUPPORTED_RATE,
+ .formats = AB8500_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .startup = ab8500_codec_pcm_startup,
+ .prepare = ab8500_codec_pcm_prepare,
+ .hw_params = ab8500_codec_pcm_hw_params,
+ .shutdown = ab8500_codec_pcm_shutdown,
+ .set_sysclk = ab8500_codec_set_dai_sysclk,
+ .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
+ .set_fmt = ab8500_codec_set_dai_fmt,
+ }
+ },
+ .symmetric_rates = 1
+ }
+};
+
+static int ab8500_codec_probe(struct snd_soc_codec *codec)
+{
+ int i, ret;
+ u8 *cache = codec->reg_cache;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ ab8500_codec_configure_audio_macrocell(codec);
+
+ for (i = REG_AUDREV; i >= REG_POWERUP; i--)
+ ab8500_codec_write_reg_audio(codec, i, cache[i]);
+
+ /* Add controls */
+ ret = snd_soc_add_controls(codec, ab8500_snd_controls,
+ ARRAY_SIZE(ab8500_snd_controls));
+ if (ret < 0) {
+ pr_err("%s: failed to add soc controls (%d).\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* Add controls with events */
+ snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&st_fir_value_control, codec));
+ snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&st_fir_apply_control, codec));
+
+ /* Add DAPM-widgets */
+ ret = ab8500_codec_add_widgets(codec);
+ if (ret < 0) {
+ pr_err("%s: Failed add widgets (%d).\n", __func__, ret);
+ return ret;
+ }
+
+ ab8500_codec = codec;
+
+ return ret;
+}
+
+static int ab8500_codec_remove(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_free(&codec->dapm);
+ ab8500_codec = NULL;
+
+ return 0;
+}
+
+static int ab8500_codec_suspend(struct snd_soc_codec *codec,
+ pm_message_t state)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ return 0;
+}
+
+static int ab8500_codec_resume(struct snd_soc_codec *codec)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ return 0;
+}
+
+struct snd_soc_codec_driver ab8500_codec_driver = {
+ .probe = ab8500_codec_probe,
+ .remove = ab8500_codec_remove,
+ .suspend = ab8500_codec_suspend,
+ .resume = ab8500_codec_resume,
+ .read = ab8500_codec_read_reg_audio,
+ .write = ab8500_codec_write_reg_audio,
+ .reg_cache_size = ARRAY_SIZE(ab8500_reg_cache),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ab8500_reg_cache,
+};
+
+static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev)
+{
+ int err;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ pr_info("%s: Register codec.\n", __func__);
+ err = snd_soc_register_codec(&pdev->dev,
+ &ab8500_codec_driver,
+ ab8500_codec_dai,
+ ARRAY_SIZE(ab8500_codec_dai));
+
+ if (err < 0) {
+ pr_err("%s: Error: Failed to register codec (%d).\n",
+ __func__, err);
+ }
+
+ return err;
+}
+
+static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev)
+{
+ pr_info("%s Enter.\n", __func__);
+
+ snd_soc_unregister_codec(&pdev->dev);
+
+ return 0;
+}
+
+static int ab8500_codec_driver_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ return 0;
+}
+
+static int ab8500_codec_driver_resume(struct platform_device *pdev)
+{
+ pr_debug("%s Enter.\n", __func__);
+
+ return 0;
+}
+
+static struct platform_driver ab8500_codec_platform_driver = {
+ .driver = {
+ .name = "ab8500-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab8500_codec_driver_probe,
+ .remove = __devexit_p(ab8500_codec_driver_remove),
+ .suspend = ab8500_codec_driver_suspend,
+ .resume = ab8500_codec_driver_resume,
+};
+
+static int __devinit ab8500_codec_platform_driver_init(void)
+{
+ int ret;
+
+ pr_info("%s: Enter.\n", __func__);
+
+ ret = platform_driver_register(&ab8500_codec_platform_driver);
+ if (ret != 0) {
+ pr_err("%s: Failed to register AB8500 platform driver (%d)!\n",
+ __func__, ret);
+ }
+
+ return ret;
+}
+
+static void __exit ab8500_codec_platform_driver_exit(void)
+{
+ pr_info("%s: Enter.\n", __func__);
+
+ platform_driver_unregister(&ab8500_codec_platform_driver);
+}
+
+module_init(ab8500_codec_platform_driver_init);
+module_exit(ab8500_codec_platform_driver_exit);
+
+MODULE_DESCRIPTION("AB8500 Codec driver");
+MODULE_ALIAS("platform:ab8500-codec");
+MODULE_AUTHOR("ST-Ericsson");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ab8500_audio.h b/sound/soc/codecs/ab8500_audio.h
new file mode 100644
index 00000000000..7cfdd1cc13a
--- /dev/null
+++ b/sound/soc/codecs/ab8500_audio.h
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Mikko J. Lehto <mikko.lehto@symbio.com>,
+ * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
+ * Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef AB8500_CODEC_REGISTERS_H
+#define AB8500_CODEC_REGISTERS_H
+
+#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
+#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
+
+extern struct snd_soc_dai_driver ab8500_codec_dai[];
+extern struct snd_soc_codec_driver soc_codec_dev_ab8500;
+
+/* Extended interface for codec-driver */
+
+void ab8500_audio_power_control(bool power_on);
+int ab8500_audio_set_word_length(struct snd_soc_dai *dai, unsigned int wl);
+int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay);
+int ab8500_audio_setup_if1(struct snd_soc_codec *codec,
+ unsigned int fmt,
+ unsigned int wl,
+ unsigned int delay);
+
+enum ab8500_audio_dapm_path {
+ AB8500_AUDIO_DAPM_PATH_DMIC,
+ AB8500_AUDIO_DAPM_PATH_AMIC1,
+ AB8500_AUDIO_DAPM_PATH_AMIC2
+};
+bool ab8500_audio_dapm_path_active(enum ab8500_audio_dapm_path dapm_path);
+
+/* AB8500 audio bank (0x0d) register definitions */
+
+#define REG_POWERUP 0x00
+#define REG_AUDSWRESET 0x01
+#define REG_ADPATHENA 0x02
+#define REG_DAPATHENA 0x03
+#define REG_ANACONF1 0x04
+#define REG_ANACONF2 0x05
+#define REG_DIGMICCONF 0x06
+#define REG_ANACONF3 0x07
+#define REG_ANACONF4 0x08
+#define REG_DAPATHCONF 0x09
+#define REG_MUTECONF 0x0A
+#define REG_SHORTCIRCONF 0x0B
+#define REG_ANACONF5 0x0C
+#define REG_ENVCPCONF 0x0D
+#define REG_SIGENVCONF 0x0E
+#define REG_PWMGENCONF1 0x0F
+#define REG_PWMGENCONF2 0x10
+#define REG_PWMGENCONF3 0x11
+#define REG_PWMGENCONF4 0x12
+#define REG_PWMGENCONF5 0x13
+#define REG_ANAGAIN1 0x14
+#define REG_ANAGAIN2 0x15
+#define REG_ANAGAIN3 0x16
+#define REG_ANAGAIN4 0x17
+#define REG_DIGLINHSLGAIN 0x18
+#define REG_DIGLINHSRGAIN 0x19
+#define REG_ADFILTCONF 0x1A
+#define REG_DIGIFCONF1 0x1B
+#define REG_DIGIFCONF2 0x1C
+#define REG_DIGIFCONF3 0x1D
+#define REG_DIGIFCONF4 0x1E
+#define REG_ADSLOTSEL1 0x1F
+#define REG_ADSLOTSEL2 0x20
+#define REG_ADSLOTSEL3 0x21
+#define REG_ADSLOTSEL4 0x22
+#define REG_ADSLOTSEL5 0x23
+#define REG_ADSLOTSEL6 0x24
+#define REG_ADSLOTSEL7 0x25
+#define REG_ADSLOTSEL8 0x26
+#define REG_ADSLOTSEL9 0x27
+#define REG_ADSLOTSEL10 0x28
+#define REG_ADSLOTSEL11 0x29
+#define REG_ADSLOTSEL12 0x2A
+#define REG_ADSLOTSEL13 0x2B
+#define REG_ADSLOTSEL14 0x2C
+#define REG_ADSLOTSEL15 0x2D
+#define REG_ADSLOTSEL16 0x2E
+#define REG_ADSLOTHIZCTRL1 0x2F
+#define REG_ADSLOTHIZCTRL2 0x30
+#define REG_ADSLOTHIZCTRL3 0x31
+#define REG_ADSLOTHIZCTRL4 0x32
+#define REG_DASLOTCONF1 0x33
+#define REG_DASLOTCONF2 0x34
+#define REG_DASLOTCONF3 0x35
+#define REG_DASLOTCONF4 0x36
+#define REG_DASLOTCONF5 0x37
+#define REG_DASLOTCONF6 0x38
+#define REG_DASLOTCONF7 0x39
+#define REG_DASLOTCONF8 0x3A
+#define REG_CLASSDCONF1 0x3B
+#define REG_CLASSDCONF2 0x3C
+#define REG_CLASSDCONF3 0x3D
+#define REG_DMICFILTCONF 0x3E
+#define REG_DIGMULTCONF1 0x3F
+#define REG_DIGMULTCONF2 0x40
+#define REG_ADDIGGAIN1 0x41
+#define REG_ADDIGGAIN2 0x42
+#define REG_ADDIGGAIN3 0x43
+#define REG_ADDIGGAIN4 0x44
+#define REG_ADDIGGAIN5 0x45
+#define REG_ADDIGGAIN6 0x46
+#define REG_DADIGGAIN1 0x47
+#define REG_DADIGGAIN2 0x48
+#define REG_DADIGGAIN3 0x49
+#define REG_DADIGGAIN4 0x4A
+#define REG_DADIGGAIN5 0x4B
+#define REG_DADIGGAIN6 0x4C
+#define REG_ADDIGLOOPGAIN1 0x4D
+#define REG_ADDIGLOOPGAIN2 0x4E
+#define REG_HSLEARDIGGAIN 0x4F
+#define REG_HSRDIGGAIN 0x50
+#define REG_SIDFIRGAIN1 0x51
+#define REG_SIDFIRGAIN2 0x52
+#define REG_ANCCONF1 0x53
+#define REG_ANCCONF2 0x54
+#define REG_ANCCONF3 0x55
+#define REG_ANCCONF4 0x56
+#define REG_ANCCONF5 0x57
+#define REG_ANCCONF6 0x58
+#define REG_ANCCONF7 0x59
+#define REG_ANCCONF8 0x5A
+#define REG_ANCCONF9 0x5B
+#define REG_ANCCONF10 0x5C
+#define REG_ANCCONF11 0x5D
+#define REG_ANCCONF12 0x5E
+#define REG_ANCCONF13 0x5F
+#define REG_ANCCONF14 0x60
+#define REG_SIDFIRADR 0x61
+#define REG_SIDFIRCOEF1 0x62
+#define REG_SIDFIRCOEF2 0x63
+#define REG_SIDFIRCONF 0x64
+#define REG_AUDINTMASK1 0x65
+#define REG_AUDINTSOURCE1 0x66
+#define REG_AUDINTMASK2 0x67
+#define REG_AUDINTSOURCE2 0x68
+#define REG_FIFOCONF1 0x69
+#define REG_FIFOCONF2 0x6A
+#define REG_FIFOCONF3 0x6B
+#define REG_FIFOCONF4 0x6C
+#define REG_FIFOCONF5 0x6D
+#define REG_FIFOCONF6 0x6E
+#define REG_AUDREV 0x6F
+
+#define AB8500_FIRST_REG REG_POWERUP
+#define AB8500_LAST_REG REG_AUDREV
+#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
+
+
+#define REG_MASK_ALL 0xFF
+#define REG_MASK_NONE 0x00
+
+/* REG_POWERUP */
+#define REG_POWERUP_POWERUP 7
+#define REG_POWERUP_ENANA 3
+
+/* REG_AUDSWRESET */
+#define REG_AUDSWRESET_SWRESET 7
+
+/* REG_ADPATHENA */
+#define REG_ADPATHENA_ENAD12 7
+#define REG_ADPATHENA_ENAD34 5
+#define REG_ADPATHENA_ENAD5768 3
+
+/* REG_DAPATHENA */
+#define REG_DAPATHENA_ENDA1 7
+#define REG_DAPATHENA_ENDA2 6
+#define REG_DAPATHENA_ENDA3 5
+#define REG_DAPATHENA_ENDA4 4
+#define REG_DAPATHENA_ENDA5 3
+#define REG_DAPATHENA_ENDA6 2
+
+/* REG_ANACONF1 */
+#define REG_ANACONF1_HSLOWPOW 7
+#define REG_ANACONF1_DACLOWPOW1 6
+#define REG_ANACONF1_DACLOWPOW0 5
+#define REG_ANACONF1_EARDACLOWPOW 4
+#define REG_ANACONF1_EARSELCM 2
+#define REG_ANACONF1_HSHPEN 1
+#define REG_ANACONF1_EARDRVLOWPOW 0
+
+/* REG_ANACONF2 */
+#define REG_ANACONF2_ENMIC1 7
+#define REG_ANACONF2_ENMIC2 6
+#define REG_ANACONF2_ENLINL 5
+#define REG_ANACONF2_ENLINR 4
+#define REG_ANACONF2_MUTMIC1 3
+#define REG_ANACONF2_MUTMIC2 2
+#define REG_ANACONF2_MUTLINL 1
+#define REG_ANACONF2_MUTLINR 0
+
+/* REG_DIGMICCONF */
+#define REG_DIGMICCONF_ENDMIC1 7
+#define REG_DIGMICCONF_ENDMIC2 6
+#define REG_DIGMICCONF_ENDMIC3 5
+#define REG_DIGMICCONF_ENDMIC4 4
+#define REG_DIGMICCONF_ENDMIC5 3
+#define REG_DIGMICCONF_ENDMIC6 2
+#define REG_DIGMICCONF_HSFADSPEED 0
+
+/* REG_ANACONF3 */
+#define REG_ANACONF3_MIC1SEL 7
+#define REG_ANACONF3_LINRSEL 6
+#define REG_ANACONF3_ENDRVHSL 5
+#define REG_ANACONF3_ENDRVHSR 4
+#define REG_ANACONF3_ENADCMIC 2
+#define REG_ANACONF3_ENADCLINL 1
+#define REG_ANACONF3_ENADCLINR 0
+
+/* REG_ANACONF4 */
+#define REG_ANACONF4_DISPDVSS 7
+#define REG_ANACONF4_ENEAR 6
+#define REG_ANACONF4_ENHSL 5
+#define REG_ANACONF4_ENHSR 4
+#define REG_ANACONF4_ENHFL 3
+#define REG_ANACONF4_ENHFR 2
+#define REG_ANACONF4_ENVIB1 1
+#define REG_ANACONF4_ENVIB2 0
+
+/* REG_DAPATHCONF */
+#define REG_DAPATHCONF_ENDACEAR 6
+#define REG_DAPATHCONF_ENDACHSL 5
+#define REG_DAPATHCONF_ENDACHSR 4
+#define REG_DAPATHCONF_ENDACHFL 3
+#define REG_DAPATHCONF_ENDACHFR 2
+#define REG_DAPATHCONF_ENDACVIB1 1
+#define REG_DAPATHCONF_ENDACVIB2 0
+
+/* REG_MUTECONF */
+#define REG_MUTECONF_MUTEAR 6
+#define REG_MUTECONF_MUTHSL 5
+#define REG_MUTECONF_MUTHSR 4
+
+/* REG_SHORTCIRCONF */
+/* REG_ANACONF5 */
+#define REG_ANACONF5_ENCPHS 7
+#define REG_ANACONF5_HSAUTOEN 0
+
+/* REG_ENVCPCONF */
+#define REG_ENVCPCONF_ENVDETHTHRE 4
+#define REG_ENVCPCONF_ENVDETLTHRE 0
+#define REG_ENVCPCONF_ENVDETHTHRE_MAX 0x0F
+#define REG_ENVCPCONF_ENVDETLTHRE_MAX 0x0F
+
+/* REG_SIGENVCONF */
+#define REG_SIGENVCONF_CPLVEN 5
+#define REG_SIGENVCONF_ENVDETCPEN 4
+#define REG_SIGENVCONF_ENVDETTIME 0
+#define REG_SIGENVCONF_ENVDETTIME_MAX 0x0F
+
+/* REG_PWMGENCONF1 */
+#define REG_PWMGENCONF1_PWMTOVIB1 7
+#define REG_PWMGENCONF1_PWMTOVIB2 6
+#define REG_PWMGENCONF1_PWM1CTRL 5
+#define REG_PWMGENCONF1_PWM2CTRL 4
+#define REG_PWMGENCONF1_PWM1NCTRL 3
+#define REG_PWMGENCONF1_PWM1PCTRL 2
+#define REG_PWMGENCONF1_PWM2NCTRL 1
+#define REG_PWMGENCONF1_PWM2PCTRL 0
+
+/* REG_PWMGENCONF2 */
+/* REG_PWMGENCONF3 */
+/* REG_PWMGENCONF4 */
+/* REG_PWMGENCONF5 */
+#define REG_PWMGENCONFX_PWMVIBXPOL 7
+#define REG_PWMGENCONFX_PWMVIBXDUTCYC 0
+#define REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX 0x64
+
+/* REG_ANAGAIN1 */
+/* REG_ANAGAIN2 */
+#define REG_ANAGAINX_ENSEMICX 7
+#define REG_ANAGAINX_LOWPOWMICX 6
+#define REG_ANAGAINX_MICXGAIN 0
+#define REG_ANAGAINX_MICXGAIN_MAX 0x1F
+
+/* REG_ANAGAIN3 */
+#define REG_ANAGAIN3_HSLGAIN 4
+#define REG_ANAGAIN3_HSRGAIN 0
+#define REG_ANAGAIN3_HSXGAIN_MAX 0x0F
+
+/* REG_ANAGAIN4 */
+#define REG_ANAGAIN4_LINLGAIN 4
+#define REG_ANAGAIN4_LINRGAIN 0
+#define REG_ANAGAIN4_LINXGAIN_MAX 0x0F
+
+/* REG_DIGLINHSLGAIN */
+/* REG_DIGLINHSRGAIN */
+#define REG_DIGLINHSXGAIN_LINTOHSXGAIN 0
+#define REG_DIGLINHSXGAIN_LINTOHSXGAIN_MAX 0x13
+
+/* REG_ADFILTCONF */
+#define REG_ADFILTCONF_AD1NH 7
+#define REG_ADFILTCONF_AD2NH 6
+#define REG_ADFILTCONF_AD3NH 5
+#define REG_ADFILTCONF_AD4NH 4
+#define REG_ADFILTCONF_AD1VOICE 3
+#define REG_ADFILTCONF_AD2VOICE 2
+#define REG_ADFILTCONF_AD3VOICE 1
+#define REG_ADFILTCONF_AD4VOICE 0
+
+/* REG_DIGIFCONF1 */
+#define REG_DIGIFCONF1_ENMASTGEN 7
+#define REG_DIGIFCONF1_IF1BITCLKOS1 6
+#define REG_DIGIFCONF1_IF1BITCLKOS0 5
+#define REG_DIGIFCONF1_ENFSBITCLK1 4
+#define REG_DIGIFCONF1_IF0BITCLKOS1 2
+#define REG_DIGIFCONF1_IF0BITCLKOS0 1
+#define REG_DIGIFCONF1_ENFSBITCLK0 0
+
+/* REG_DIGIFCONF2 */
+#define REG_DIGIFCONF2_FSYNC0P 6
+#define REG_DIGIFCONF2_BITCLK0P 5
+#define REG_DIGIFCONF2_IF0DEL 4
+#define REG_DIGIFCONF2_IF0FORMAT1 3
+#define REG_DIGIFCONF2_IF0FORMAT0 2
+#define REG_DIGIFCONF2_IF0WL1 1
+#define REG_DIGIFCONF2_IF0WL0 0
+
+/* REG_DIGIFCONF3 */
+#define REG_DIGIFCONF3_IF0DATOIF1AD 7
+#define REG_DIGIFCONF3_IF0CLKTOIF1CLK 6
+#define REG_DIGIFCONF3_IF1MASTER 5
+#define REG_DIGIFCONF3_IF1DATOIF0AD 3
+#define REG_DIGIFCONF3_IF1CLKTOIF0CLK 2
+#define REG_DIGIFCONF3_IF0MASTER 1
+#define REG_DIGIFCONF3_IF0BFIFOEN 0
+
+/* REG_DIGIFCONF4 */
+#define REG_DIGIFCONF4_FSYNC1P 6
+#define REG_DIGIFCONF4_BITCLK1P 5
+#define REG_DIGIFCONF4_IF1DEL 4
+#define REG_DIGIFCONF4_IF1FORMAT1 3
+#define REG_DIGIFCONF4_IF1FORMAT0 2
+#define REG_DIGIFCONF4_IF1WL1 1
+#define REG_DIGIFCONF4_IF1WL0 0
+
+/* REG_ADSLOTSELX */
+#define REG_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00
+#define REG_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x01
+#define REG_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x02
+#define REG_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x03
+#define REG_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x04
+#define REG_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x05
+#define REG_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x06
+#define REG_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x07
+#define REG_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x08
+#define REG_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F
+#define REG_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
+#define REG_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10
+#define REG_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20
+#define REG_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30
+#define REG_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40
+#define REG_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50
+#define REG_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60
+#define REG_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70
+#define REG_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x80
+#define REG_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0xF0
+#define REG_ADSLOTSELX_EVEN_SHIFT 0
+#define REG_ADSLOTSELX_ODD_SHIFT 4
+
+/* REG_ADSLOTHIZCTRL1 */
+/* REG_ADSLOTHIZCTRL2 */
+/* REG_ADSLOTHIZCTRL3 */
+/* REG_ADSLOTHIZCTRL4 */
+/* REG_DASLOTCONF1 */
+#define REG_DASLOTCONF1_DA12VOICE 7
+#define REG_DASLOTCONF1_SWAPDA12_34 6
+#define REG_DASLOTCONF1_DAI7TOADO1 5
+
+/* REG_DASLOTCONF2 */
+#define REG_DASLOTCONF2_DAI8TOADO2 5
+
+/* REG_DASLOTCONF3 */
+#define REG_DASLOTCONF3_DA34VOICE 7
+#define REG_DASLOTCONF3_DAI7TOADO3 5
+
+/* REG_DASLOTCONF4 */
+#define REG_DASLOTCONF4_DAI8TOADO4 5
+
+/* REG_DASLOTCONF5 */
+#define REG_DASLOTCONF5_DA56VOICE 7
+#define REG_DASLOTCONF5_DAI7TOADO5 5
+
+/* REG_DASLOTCONF6 */
+#define REG_DASLOTCONF6_DAI8TOADO6 5
+
+/* REG_DASLOTCONF7 */
+#define REG_DASLOTCONF7_DAI8TOADO7 5
+
+/* REG_DASLOTCONF8 */
+#define REG_DASLOTCONF8_DAI7TOADO8 5
+
+#define REG_DASLOTCONFX_SLTODAX_SHIFT 0
+#define REG_DASLOTCONFX_SLTODAX_MASK 0x1F
+
+/* REG_CLASSDCONF1 */
+#define REG_CLASSDCONF1_PARLHF 7
+#define REG_CLASSDCONF1_PARLVIB 6
+#define REG_CLASSDCONF1_VIB1SWAPEN 3
+#define REG_CLASSDCONF1_VIB2SWAPEN 2
+#define REG_CLASSDCONF1_HFLSWAPEN 1
+#define REG_CLASSDCONF1_HFRSWAPEN 0
+
+/* REG_CLASSDCONF2 */
+#define REG_CLASSDCONF2_FIRBYP3 7
+#define REG_CLASSDCONF2_FIRBYP2 6
+#define REG_CLASSDCONF2_FIRBYP1 5
+#define REG_CLASSDCONF2_FIRBYP0 4
+#define REG_CLASSDCONF2_HIGHVOLEN3 3
+#define REG_CLASSDCONF2_HIGHVOLEN2 2
+#define REG_CLASSDCONF2_HIGHVOLEN1 1
+#define REG_CLASSDCONF2_HIGHVOLEN0 0
+
+/* REG_CLASSDCONF3 */
+#define REG_CLASSDCONF3_DITHHPGAIN 4
+#define REG_CLASSDCONF3_DITHHPGAIN_MAX 0x0A
+#define REG_CLASSDCONF3_DITHWGAIN 0
+#define REG_CLASSDCONF3_DITHWGAIN_MAX 0x0A
+
+/* REG_DMICFILTCONF */
+#define REG_DMICFILTCONF_ANCINSEL 7
+#define REG_DMICFILTCONF_DA3TOEAR 6
+#define REG_DMICFILTCONF_DMIC1SINC3 5
+#define REG_DMICFILTCONF_DMIC2SINC3 4
+#define REG_DMICFILTCONF_DMIC3SINC3 3
+#define REG_DMICFILTCONF_DMIC4SINC3 2
+#define REG_DMICFILTCONF_DMIC5SINC3 1
+#define REG_DMICFILTCONF_DMIC6SINC3 0
+
+/* REG_DIGMULTCONF1 */
+#define REG_DIGMULTCONF1_DATOHSLEN 7
+#define REG_DIGMULTCONF1_DATOHSREN 6
+#define REG_DIGMULTCONF1_AD1SEL 5
+#define REG_DIGMULTCONF1_AD2SEL 4
+#define REG_DIGMULTCONF1_AD3SEL 3
+#define REG_DIGMULTCONF1_AD5SEL 2
+#define REG_DIGMULTCONF1_AD6SEL 1
+#define REG_DIGMULTCONF1_ANCSEL 0
+
+/* REG_DIGMULTCONF2 */
+#define REG_DIGMULTCONF2_DATOHFREN 7
+#define REG_DIGMULTCONF2_DATOHFLEN 6
+#define REG_DIGMULTCONF2_HFRSEL 5
+#define REG_DIGMULTCONF2_HFLSEL 4
+#define REG_DIGMULTCONF2_FIRSID1SEL 2
+#define REG_DIGMULTCONF2_FIRSID2SEL 0
+
+/* REG_ADDIGGAIN1 */
+/* REG_ADDIGGAIN2 */
+/* REG_ADDIGGAIN3 */
+/* REG_ADDIGGAIN4 */
+/* REG_ADDIGGAIN5 */
+/* REG_ADDIGGAIN6 */
+#define REG_ADDIGGAINX_FADEDISADX 6
+#define REG_ADDIGGAINX_ADXGAIN_MAX 0x3F
+
+/* REG_DADIGGAIN1 */
+/* REG_DADIGGAIN2 */
+/* REG_DADIGGAIN3 */
+/* REG_DADIGGAIN4 */
+/* REG_DADIGGAIN5 */
+/* REG_DADIGGAIN6 */
+#define REG_DADIGGAINX_FADEDISDAX 6
+#define REG_DADIGGAINX_DAXGAIN_MAX 0x3F
+
+/* REG_ADDIGLOOPGAIN1 */
+/* REG_ADDIGLOOPGAIN2 */
+#define REG_ADDIGLOOPGAINX_FADEDISADXL 6
+#define REG_ADDIGLOOPGAINX_ADXLBGAIN_MAX 0x3F
+
+/* REG_HSLEARDIGGAIN */
+#define REG_HSLEARDIGGAIN_HSSINC1 7
+#define REG_HSLEARDIGGAIN_FADEDISHSL 4
+#define REG_HSLEARDIGGAIN_HSLDGAIN_MAX 0x09
+
+/* REG_HSRDIGGAIN */
+#define REG_HSRDIGGAIN_FADESPEED 6
+#define REG_HSRDIGGAIN_FADEDISHSR 4
+#define REG_HSRDIGGAIN_HSRDGAIN_MAX 0x09
+
+/* REG_SIDFIRGAIN1 */
+/* REG_SIDFIRGAIN2 */
+#define REG_SIDFIRGAINX_FIRSIDXGAIN_MAX 0x1F
+
+/* REG_ANCCONF1 */
+#define REG_ANCCONF1_ANCIIRUPDATE 3
+#define REG_ANCCONF1_ENANC 2
+#define REG_ANCCONF1_ANCIIRINIT 1
+#define REG_ANCCONF1_ANCFIRUPDATE 0
+
+/* REG_ANCCONF2 */
+/* REG_ANCCONF3 */
+/* REG_ANCCONF4 */
+/* REG_ANCCONF5 */
+/* REG_ANCCONF6 */
+/* REG_ANCCONF7 */
+/* REG_ANCCONF8 */
+/* REG_ANCCONF9 */
+/* REG_ANCCONF10 */
+/* REG_ANCCONF11 */
+/* REG_ANCCONF12 */
+/* REG_ANCCONF13 */
+/* REG_ANCCONF14 */
+
+/* REG_SIDFIRADR */
+#define REG_SIDFIRADR_FIRSIDSET 7
+#define REG_SIDFIRADR_ADDRESS_SHIFT 0
+#define REG_SIDFIRADR_ADDRESS_MAX 0x7F
+
+/* REG_SIDFIRCOEF1 */
+/* REG_SIDFIRCOEF2 */
+#define REG_SIDFIRCOEFX_VALUE_SHIFT 0
+#define REG_SIDFIRCOEFX_VALUE_MAX 0xFF
+
+/* REG_SIDFIRCONF */
+#define REG_SIDFIRCONF_ENFIRSIDS 2
+#define REG_SIDFIRCONF_FIRSIDSTOIF1 1
+#define REG_SIDFIRCONF_FIRSIDBUSY 0
+
+/* REG_AUDINTMASK1 */
+/* REG_AUDINTSOURCE1 */
+/* REG_AUDINTMASK2 */
+/* REG_AUDINTSOURCE2 */
+
+/* REG_FIFOCONF1 */
+#define REG_FIFOCONF1_BFIFOMASK 0x80
+#define REG_FIFOCONF1_BFIFO19M2 0x40
+#define REG_FIFOCONF1_BFIFOINT_SHIFT 0
+#define REG_FIFOCONF1_BFIFOINT_MAX 0x3F
+
+/* REG_FIFOCONF2 */
+#define REG_FIFOCONF2_BFIFOTX_SHIFT 0
+#define REG_FIFOCONF2_BFIFOTX_MAX 0xFF
+
+/* REG_FIFOCONF3 */
+#define REG_FIFOCONF3_BFIFOEXSL_SHIFT 5
+#define REG_FIFOCONF3_BFIFOEXSL_MAX 0x5
+#define REG_FIFOCONF3_PREBITCLK0_SHIFT 2
+#define REG_FIFOCONF3_PREBITCLK0_MAX 0x7
+#define REG_FIFOCONF3_BFIFOMAST_SHIFT 1
+#define REG_FIFOCONF3_BFIFORUN_SHIFT 0
+
+/* REG_FIFOCONF4 */
+#define REG_FIFOCONF4_BFIFOFRAMSW_SHIFT 0
+#define REG_FIFOCONF4_BFIFOFRAMSW_MAX 0xFF
+
+/* REG_FIFOCONF5 */
+#define REG_FIFOCONF5_BFIFOWAKEUP_SHIFT 0
+#define REG_FIFOCONF5_BFIFOWAKEUP_MAX 0xFF
+
+/* REG_FIFOCONF6 */
+#define REG_FIFOCONF6_BFIFOSAMPLE_SHIFT 0
+#define REG_FIFOCONF6_BFIFOSAMPLE_MAX 0xFF
+
+/* REG_AUDREV */
+
+#endif
diff --git a/sound/soc/codecs/av8100_audio.c b/sound/soc/codecs/av8100_audio.c
new file mode 100644
index 00000000000..b163151efb7
--- /dev/null
+++ b/sound/soc/codecs/av8100_audio.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <video/av8100.h>
+#include <video/hdmi.h>
+
+#include "av8100_audio.h"
+
+/* codec private data */
+struct av8100_codec_dai_data {
+ struct hdmi_audio_settings as;
+};
+
+static struct av8100_codec_dai_data *get_dai_data_codec(struct snd_soc_codec *codec,
+ int dai_id)
+{
+ struct av8100_codec_dai_data *dai_data = snd_soc_codec_get_drvdata(codec);
+ return &dai_data[dai_id];
+}
+
+static struct av8100_codec_dai_data *get_dai_data(struct snd_soc_dai *codec_dai)
+{
+ return get_dai_data_codec(codec_dai->codec, codec_dai->id);
+}
+
+/* Extended interface for codec-driver */
+
+int av8100_audio_change_hdmi_audio_settings(struct snd_soc_dai *codec_dai,
+ struct hdmi_audio_settings *as)
+{
+ struct av8100_codec_dai_data *dai_data = get_dai_data(codec_dai);
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ dai_data->as.audio_coding_type = as->audio_coding_type;
+ dai_data->as.audio_channel_count = as->audio_channel_count;
+ dai_data->as.sampling_frequency = as->sampling_frequency;
+ dai_data->as.sample_size = as->sample_size;
+ dai_data->as.channel_allocation = as->channel_allocation;
+ dai_data->as.level_shift_value = as->level_shift_value;
+ dai_data->as.downmix_inhibit = as->downmix_inhibit;
+
+ return 0;
+}
+
+static int av8100_codec_powerup(void)
+{
+ struct av8100_status status;
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ status = av8100_status_get();
+ if (status.av8100_state < AV8100_OPMODE_STANDBY) {
+ pr_debug("%s: Powering up AV8100.", __func__);
+ ret = av8100_powerup();
+ if (ret != 0) {
+ pr_err("%s: Power up AV8100 failed "
+ "(av8100_powerup returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+ }
+ if (status.av8100_state < AV8100_OPMODE_INIT) {
+ ret = av8100_download_firmware(NULL, 0, I2C_INTERFACE);
+ if (ret != 0) {
+ pr_err("%s: Download firmware failed "
+ "(av8100_download_firmware returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int av8100_codec_setup_hdmi_format(void)
+{
+ union av8100_configuration config;
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ pr_debug("%s: hdmi_mode = AV8100_HDMI_ON.", __func__);
+ pr_debug("%s: hdmi_format = AV8100_HDMI.", __func__);
+ config.hdmi_format.hdmi_mode = AV8100_HDMI_ON;
+ config.hdmi_format.hdmi_format = AV8100_HDMI;
+ ret = av8100_conf_prep(AV8100_COMMAND_HDMI, &config);
+ if (ret != 0) {
+ pr_err("%s: Setting hdmi_format failed "
+ "(av8100_conf_prep returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+ ret = av8100_conf_w(AV8100_COMMAND_HDMI,
+ NULL,
+ NULL,
+ I2C_INTERFACE);
+ if (ret != 0) {
+ pr_err("%s: Setting hdmi_format failed "
+ "(av8100_conf_w returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int av8100_codec_pcm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ return 0;
+}
+
+static int av8100_codec_send_audio_infoframe(struct hdmi_audio_settings *as)
+{
+ union av8100_configuration config;
+ struct av8100_infoframes_format_cmd info_fr;
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ pr_debug("%s: HDMI-settings:\n", __func__);
+ pr_debug("%s: audio_coding_type = %d\n", __func__, as->audio_coding_type);
+ pr_debug("%s: audio_channel_count = %d\n", __func__, as->audio_channel_count);
+ pr_debug("%s: sampling_frequency = %d\n", __func__, as->sampling_frequency);
+ pr_debug("%s: sample_size = %d\n", __func__, as->sample_size);
+ pr_debug("%s: channel_allocation = %d\n", __func__, as->channel_allocation);
+ pr_debug("%s: level_shift_value = %d\n", __func__, as->level_shift_value);
+ pr_debug("%s: downmix_inhibit = %d\n", __func__, as->downmix_inhibit);
+
+ /* Prepare the infoframe from the hdmi_audio_settings struct */
+ pr_info("%s: Preparing audio info-frame.", __func__);
+ info_fr.type = 0x84;
+ info_fr.version = 0x01;
+ info_fr.length = 0x0a;
+ info_fr.data[0] = (as->audio_coding_type << 4) | as->audio_channel_count;
+ info_fr.data[1] = (as->sampling_frequency << 2) | as->sample_size;
+ info_fr.data[2] = 0;
+ info_fr.data[3] = as->channel_allocation;
+ info_fr.data[4] = ((int)as->downmix_inhibit << 7) |
+ (as->level_shift_value << 3);
+ info_fr.data[5] = 0;
+ info_fr.data[6] = 0;
+ info_fr.data[7] = 0;
+ info_fr.data[8] = 0;
+ info_fr.data[9] = 0;
+ info_fr.crc = info_fr.version +
+ info_fr.length +
+ info_fr.data[0] +
+ info_fr.data[1] +
+ info_fr.data[3] +
+ info_fr.data[4];
+ config.infoframes_format.type = info_fr.type;
+ config.infoframes_format.version = info_fr.version;
+ config.infoframes_format.crc = info_fr.crc;
+ config.infoframes_format.length = info_fr.length;
+ memcpy(&config.infoframes_format.data, info_fr.data, info_fr.length);
+
+ /* Send audio info-frame */
+ pr_info("%s: Sending audio info-frame.", __func__);
+ ret = av8100_conf_prep(AV8100_COMMAND_INFOFRAMES, &config);
+ if (ret != 0) {
+ pr_err("%s: Sending audio info-frame failed "
+ "(av8100_conf_prep returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+ ret = av8100_conf_w(AV8100_COMMAND_INFOFRAMES,
+ NULL,
+ NULL,
+ I2C_INTERFACE);
+ if (ret != 0) {
+ pr_err("%s: Sending audio info-frame failed "
+ "(av8100_conf_w returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int av8100_codec_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params,
+ struct snd_soc_dai *codec_dai)
+{
+ struct av8100_codec_dai_data *dai_data = get_dai_data(codec_dai);
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ av8100_codec_send_audio_infoframe(&dai_data->as);
+
+ return 0;
+}
+
+static int av8100_codec_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai)
+{
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ /* Startup AV8100 if it is not already started */
+ ret = av8100_codec_powerup();
+ if (ret != 0) {
+ pr_err("%s: Startup of AV8100 failed "
+ "(av8100_codec_powerupAV8100 returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void av8100_codec_pcm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai)
+{
+ pr_debug("%s: Enter.\n", __func__);
+}
+
+static int av8100_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id,
+ unsigned int freq, int dir)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ return 0;
+}
+
+static int av8100_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ union av8100_configuration config;
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ /* Set the HDMI format of AV8100 */
+ ret = av8100_codec_setup_hdmi_format();
+ if (ret != 0)
+ return ret;
+
+ /* Set the audio input format of AV8100 */
+ config.audio_input_format.audio_input_if_format =
+ ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_B) ?
+ AV8100_AUDIO_TDM_MODE : AV8100_AUDIO_I2SDELAYED_MODE;
+ config.audio_input_format.audio_if_mode =
+ ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) ?
+ AV8100_AUDIO_MASTER : AV8100_AUDIO_SLAVE;
+ pr_info("%s: Setting audio_input_format "
+ "(if_format = %d, if_mode = %d).",
+ __func__,
+ config.audio_input_format.audio_input_if_format,
+ config.audio_input_format.audio_if_mode);
+ config.audio_input_format.i2s_input_nb = 1;
+ config.audio_input_format.sample_audio_freq = AV8100_AUDIO_FREQ_48KHZ;
+ config.audio_input_format.audio_word_lg = AV8100_AUDIO_16BITS;
+ config.audio_input_format.audio_format = AV8100_AUDIO_LPCM_MODE;
+ config.audio_input_format.audio_mute = AV8100_AUDIO_MUTE_DISABLE;
+ ret = av8100_conf_prep(AV8100_COMMAND_AUDIO_INPUT_FORMAT, &config);
+ if (ret != 0) {
+ pr_err("%s: Setting audio_input_format failed "
+ "(av8100_conf_prep returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+ ret = av8100_conf_w(AV8100_COMMAND_AUDIO_INPUT_FORMAT,
+ NULL,
+ NULL,
+ I2C_INTERFACE);
+ if (ret != 0) {
+ pr_err("%s: Setting audio_input_format failed "
+ "(av8100_conf_w returned %d)!\n",
+ __func__,
+ ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct snd_soc_dai_driver av8100_dai_driver = {
+ .name = "av8100-codec-dai",
+ .playback = {
+ .stream_name = "AV8100 Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = AV8100_SUPPORTED_RATE,
+ .formats = AV8100_SUPPORTED_FMT,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .prepare = av8100_codec_pcm_prepare,
+ .hw_params = av8100_codec_pcm_hw_params,
+ .startup = av8100_codec_pcm_startup,
+ .shutdown = av8100_codec_pcm_shutdown,
+ .set_sysclk = av8100_codec_set_dai_sysclk,
+ .set_fmt = av8100_codec_set_dai_fmt,
+ }
+ },
+};
+EXPORT_SYMBOL_GPL(av8100_dai_driver);
+
+static int av8100_codec_probe(struct snd_soc_codec *codec)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+static int av8100_codec_remove(struct snd_soc_codec *codec)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+static int av8100_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+static int av8100_codec_resume(struct snd_soc_codec *codec)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+struct snd_soc_codec_driver av8100_codec_drv = {
+ .probe = av8100_codec_probe,
+ .remove = av8100_codec_remove,
+ .suspend = av8100_codec_suspend,
+ .resume = av8100_codec_resume
+};
+
+static __devinit int av8100_codec_drv_probe(struct platform_device *pdev)
+{
+ struct av8100_codec_dai_data *dai_data;
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ pr_info("%s: Init codec private data..\n", __func__);
+ dai_data = kzalloc(sizeof(struct av8100_codec_dai_data), GFP_KERNEL);
+ if (dai_data == NULL)
+ return -ENOMEM;
+
+ /* Setup hdmi_audio_settings default values */
+ dai_data[0].as.audio_coding_type = AV8100_CODEC_CT_IEC60958_PCM;
+ dai_data[0].as.audio_channel_count = AV8100_CODEC_CC_2CH;
+ dai_data[0].as.sampling_frequency = AV8100_CODEC_SF_48KHZ;
+ dai_data[0].as.sample_size = AV8100_CODEC_SS_16BIT;
+ dai_data[0].as.channel_allocation = AV8100_CODEC_CA_FL_FR;
+ dai_data[0].as.level_shift_value = AV8100_CODEC_LSV_0DB;
+ dai_data[0].as.downmix_inhibit = false;
+
+ platform_set_drvdata(pdev, dai_data);
+
+ pr_info("%s: Register codec.\n", __func__);
+ ret = snd_soc_register_codec(&pdev->dev, &av8100_codec_drv, &av8100_dai_driver, 1);
+ if (ret < 0) {
+ pr_debug("%s: Error: Failed to register codec (ret = %d).\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit av8100_codec_drv_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ kfree(platform_get_drvdata(pdev));
+ return 0;
+}
+
+static const struct platform_device_id av8100_codec_platform_id[] = {
+ { "av8100-codec", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, av8100_codec_platform_id);
+
+static struct platform_driver av8100_codec_platform_driver = {
+ .driver = {
+ .name = "av8100-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = av8100_codec_drv_probe,
+ .remove = __devexit_p(av8100_codec_drv_remove),
+ .id_table = av8100_codec_platform_id,
+};
+
+static int __devinit av8100_codec_platform_drv_init(void)
+{
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ ret = platform_driver_register(&av8100_codec_platform_driver);
+ if (ret != 0) {
+ pr_err("Failed to register AV8100 platform driver (%d)!\n", ret);
+ }
+
+ return ret;
+}
+
+static void __exit av8100_codec_platform_drv_exit(void)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ platform_driver_unregister(&av8100_codec_platform_driver);
+}
+
+module_init(av8100_codec_platform_drv_init);
+module_exit(av8100_codec_platform_drv_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/av8100_audio.h b/sound/soc/codecs/av8100_audio.h
new file mode 100644
index 00000000000..594d66e97ee
--- /dev/null
+++ b/sound/soc/codecs/av8100_audio.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#ifndef AV8100_AUDIO_CODEC_H
+#define AV8100_AUDIO_CODEC_H
+
+/* Supported sampling rates */
+#define AV8100_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
+
+/* Supported data formats */
+#define AV8100_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
+
+/* TDM-slot mask */
+#define AV8100_CODEC_MASK_MONO 0x0001
+#define AV8100_CODEC_MASK_STEREO 0x0005
+#define AV8100_CODEC_MASK_2DOT1 0x0015
+#define AV8100_CODEC_MASK_QUAD 0x0505
+#define AV8100_CODEC_MASK_5DOT0 0x0545
+#define AV8100_CODEC_MASK_5DOT1 0x0555
+#define AV8100_CODEC_MASK_7DOT0 0x5545
+#define AV8100_CODEC_MASK_7DOT1 0x5555
+
+enum hdmi_audio_coding_type {
+ AV8100_CODEC_CT_REFER,
+ AV8100_CODEC_CT_IEC60958_PCM,
+ AV8100_CODEC_CT_AC3,
+ AV8100_CODEC_CT_MP3,
+ AV8100_CODEC_CT_MPEG2,
+ AV8100_CODEC_CT_AAC,
+ AV8100_CODEC_CT_DTS_ATRAC,
+ AV8100_CODEC_CT_ONE_BIT_AUDIO,
+ AV8100_CODEC_CT_DOLBY_DIGITAL,
+ AV8100_CODEC_CT_DTS_HD,
+ AV8100_CODEC_CT_MAT,
+ AV8100_CODEC_CT_DTS,
+ AV8100_CODEC_CT_WMA_PRO
+};
+
+enum hdmi_audio_channel_count {
+ AV8100_CODEC_CC_REFER,
+ AV8100_CODEC_CC_2CH,
+ AV8100_CODEC_CC_3CH,
+ AV8100_CODEC_CC_4CH,
+ AV8100_CODEC_CC_5CH,
+ AV8100_CODEC_CC_6CH,
+ AV8100_CODEC_CC_7CH,
+ AV8100_CODEC_CC_8CH
+};
+
+enum hdmi_sampling_frequency {
+ AV8100_CODEC_SF_REFER,
+ AV8100_CODEC_SF_32KHZ,
+ AV8100_CODEC_SF_44_1KHZ,
+ AV8100_CODEC_SF_48KHZ,
+ AV8100_CODEC_SF_88_2KHZ,
+ AV8100_CODEC_SF_96KHZ,
+ AV8100_CODEC_SF_176_4KHZ,
+ AV8100_CODEC_SF_192KHZ
+};
+
+enum hdmi_sample_size {
+ AV8100_CODEC_SS_REFER,
+ AV8100_CODEC_SS_16BIT,
+ AV8100_CODEC_SS_20BIT,
+ AV8100_CODEC_SS_24BIT
+};
+
+enum hdmi_speaker_placement {
+ AV8100_CODEC_SP_FL, /* Front Left */
+ AV8100_CODEC_SP_FC, /* Front Center */
+ AV8100_CODEC_SP_FR, /* Front Right */
+ AV8100_CODEC_SP_FLC, /* Front Left Center */
+ AV8100_CODEC_SP_FRC, /* Front Right Center */
+ AV8100_CODEC_SP_RL, /* Rear Left */
+ AV8100_CODEC_SP_RC, /* Rear Center */
+ AV8100_CODEC_SP_RR, /* Rear Right */
+ AV8100_CODEC_SP_RLC, /* Rear Left Center */
+ AV8100_CODEC_SP_RRC, /* Rear Right Center */
+ AV8100_CODEC_SP_LFE, /* Low Frequency Effekt */
+};
+
+enum hdmi_channel_allocation {
+ AV8100_CODEC_CA_FL_FR, /* 0x00, Stereo */
+ AV8100_CODEC_CA_FL_FR_LFE, /* 0x01, 2.1 */
+ AV8100_CODEC_CA_FL_FR_FC, /* 0x02*/
+ AV8100_CODEC_CA_FL_FR_LFE_FC, /* 0x03*/
+ AV8100_CODEC_CA_FL_FR_RC, /* 0x04*/
+ AV8100_CODEC_CA_FL_FR_LFE_RC, /* 0x05*/
+ AV8100_CODEC_CA_FL_FR_FC_RC, /* 0x06*/
+ AV8100_CODEC_CA_FL_FR_LFE_FC_RC, /* 0x07*/
+ AV8100_CODEC_CA_FL_FR_RL_RR, /* 0x08, Quad */
+ AV8100_CODEC_CA_FL_FR_LFE_RL_RR, /* 0x09*/
+ AV8100_CODEC_CA_FL_FR_FC_RL_RR, /* 0x0a, 5.0*/
+ AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR, /* 0x0b, 5.1*/
+ AV8100_CODEC_CA_FL_FR_RL_RR_RC, /* 0x0c*/
+ AV8100_CODEC_CA_FL_FR_LFE_RL_RR_RC, /* 0x0d*/
+ AV8100_CODEC_CA_FL_FR_RC_RL_RR_RC, /* 0x0e*/
+ AV8100_CODEC_CA_FL_FR_LFE_RC_RL_RR_RC, /* 0x0f*/
+ AV8100_CODEC_CA_FL_FR_RL_RR_RLC_RRC, /* 0x10*/
+ AV8100_CODEC_CA_FL_FR_LFE_RL_RR_RLC_RRC, /* 0x11*/
+ AV8100_CODEC_CA_FL_FR_FC_RL_RR_RLC_RRC, /* 0x12*/
+ AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR_RLC_RRC, /* 0x13*/
+ AV8100_CODEC_CA_FL_FR_FLC_FRC, /* 0x14*/
+ AV8100_CODEC_CA_FL_FR_LFE_FLC_FRC, /* 0x15*/
+ AV8100_CODEC_CA_FL_FR_FC_FLC_FRC, /* 0x16*/
+ AV8100_CODEC_CA_FL_FR_LFE_FC_FLC_FRC, /* 0x17*/
+ AV8100_CODEC_CA_FL_FR_RC_FLC_FRC, /* 0x18*/
+ AV8100_CODEC_CA_FL_FR_LFE_RC_FLC_FRC, /* 0x19*/
+ AV8100_CODEC_CA_FL_FR_FC_RC_FLC_FRC, /* 0x1a*/
+ AV8100_CODEC_CA_FL_FR_LFE_FR_FC_RC_FLC_FRC, /* 0x1b*/
+ AV8100_CODEC_CA_FL_FR_RL_RR_FLC_FRC, /* 0x1c*/
+ AV8100_CODEC_CA_FL_FR_LFE_RL_RR_FLC_FRC, /* 0x1d*/
+ AV8100_CODEC_CA_FL_FR_FC_RL_RR_FLC_FRC, /* 0x1e*/
+ AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR_FLC_FRC /* 0x1f, 7.1 */
+};
+
+enum hdmi_level_shift_value {
+ AV8100_CODEC_LSV_0DB,
+ AV8100_CODEC_LSV_1DB,
+ AV8100_CODEC_LSV_2DB,
+ AV8100_CODEC_LSV_3DB,
+ AV8100_CODEC_LSV_4DB,
+ AV8100_CODEC_LSV_5DB,
+ AV8100_CODEC_LSV_6DB,
+ AV8100_CODEC_LSV_7DB,
+ AV8100_CODEC_LSV_8DB,
+ AV8100_CODEC_LSV_9DB,
+ AV8100_CODEC_LSV_10DB,
+ AV8100_CODEC_LSV_11DB,
+ AV8100_CODEC_LSV_12DB,
+ AV8100_CODEC_LSV_13DB,
+ AV8100_CODEC_LSV_14DB,
+ AV8100_CODEC_LSV_15DB
+};
+
+struct hdmi_audio_settings {
+ enum hdmi_audio_coding_type audio_coding_type;
+ enum hdmi_audio_channel_count audio_channel_count;
+ enum hdmi_sampling_frequency sampling_frequency;
+ enum hdmi_sample_size sample_size;
+ enum hdmi_channel_allocation channel_allocation;
+ enum hdmi_level_shift_value level_shift_value;
+ bool downmix_inhibit;
+};
+
+/* Extended interface for codec-driver */
+int av8100_audio_change_hdmi_audio_settings(struct snd_soc_dai *dai,
+ struct hdmi_audio_settings *as);
+
+#endif /* AV8100_AUDIO_CODEC_H */
+
+
+
diff --git a/sound/soc/codecs/cg29xx.c b/sound/soc/codecs/cg29xx.c
new file mode 100644
index 00000000000..1ee3f3c38af
--- /dev/null
+++ b/sound/soc/codecs/cg29xx.c
@@ -0,0 +1,773 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Roger Nilsson <roger.xr.nilsson@stericsson.com>,
+ * Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+ #include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/bitops.h>
+#include <../../../drivers/staging/cg2900/include/cg2900_audio.h>
+
+#include "cg29xx.h"
+
+#define CG29XX_NBR_OF_DAI 2
+#define CG29XX_SUPPORTED_RATE_PCM (SNDRV_PCM_RATE_8000 | \
+ SNDRV_PCM_RATE_16000)
+
+#define CG29XX_SUPPORTED_RATE (SNDRV_PCM_RATE_8000 | \
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+
+#define CG29XX_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
+
+enum cg29xx_dai_direction {
+ CG29XX_DAI_DIRECTION_TX,
+ CG29XX_DAI_DIRECTION_RX
+};
+
+static int cg29xx_dai_startup(
+ struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+
+static int cg29xx_dai_prepare(
+ struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+
+static int cg29xx_dai_hw_params(
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params,
+ struct snd_soc_dai *dai);
+
+static void cg29xx_dai_shutdown(
+ struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+
+static int cg29xx_set_dai_sysclk(
+ struct snd_soc_dai *codec_dai,
+ int clk_id,
+ unsigned int freq, int dir);
+
+static int cg29xx_set_dai_fmt(
+ struct snd_soc_dai *codec_dai,
+ unsigned int fmt);
+
+static int cg29xx_set_tdm_slot(
+ struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots,
+ int slot_width);
+
+static struct cg29xx_codec codec_private = {
+ .session = 0,
+};
+
+static struct snd_soc_dai_ops cg29xx_dai_driver_dai_ops = {
+ .startup = cg29xx_dai_startup,
+ .prepare = cg29xx_dai_prepare,
+ .hw_params = cg29xx_dai_hw_params,
+ .shutdown = cg29xx_dai_shutdown,
+ .set_sysclk = cg29xx_set_dai_sysclk,
+ .set_fmt = cg29xx_set_dai_fmt,
+ .set_tdm_slot = cg29xx_set_tdm_slot
+};
+
+struct snd_soc_dai_driver cg29xx_dai_driver[] = {
+ {
+ .name = "cg29xx-codec-dai.0",
+ .id = 0,
+ .playback = {
+ .stream_name = "CG29xx.0 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = CG29XX_SUPPORTED_RATE,
+ .formats = CG29XX_SUPPORTED_FMT,
+ },
+ .capture = {
+ .stream_name = "CG29xx.0 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = CG29XX_SUPPORTED_RATE,
+ .formats = CG29XX_SUPPORTED_FMT,
+ },
+ .ops = &cg29xx_dai_driver_dai_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "cg29xx-codec-dai.1",
+ .id = 1,
+ .playback = {
+ .stream_name = "CG29xx.1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CG29XX_SUPPORTED_RATE_PCM,
+ .formats = CG29XX_SUPPORTED_FMT,
+ },
+ .capture = {
+ .stream_name = "CG29xx.1 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CG29XX_SUPPORTED_RATE_PCM,
+ .formats = CG29XX_SUPPORTED_FMT,
+ },
+ .ops = &cg29xx_dai_driver_dai_ops,
+ .symmetric_rates = 1,
+ }
+};
+EXPORT_SYMBOL_GPL(cg29xx_dai_driver);
+
+static const char *enum_ifs_input_select[] = {
+ "BT_SCO", "FM_RX"
+};
+
+static const char *enum_ifs_output_select[] = {
+ "BT_SCO", "FM_TX"
+};
+
+/* If0 Input Select */
+static struct soc_enum if0_input_select =
+ SOC_ENUM_SINGLE(INTERFACE0_INPUT_SELECT, 0,
+ ARRAY_SIZE(enum_ifs_input_select),
+ enum_ifs_input_select);
+
+/* If1 Input Select */
+static struct soc_enum if1_input_select =
+ SOC_ENUM_SINGLE(INTERFACE1_INPUT_SELECT, 0,
+ ARRAY_SIZE(enum_ifs_input_select),
+ enum_ifs_input_select);
+
+/* If0 Output Select */
+static struct soc_enum if0_output_select =
+ SOC_ENUM_SINGLE(INTERFACE0_OUTPUT_SELECT, 0,
+ ARRAY_SIZE(enum_ifs_output_select),
+ enum_ifs_output_select);
+
+/* If1 Output Select */
+static struct soc_enum if1_output_select =
+ SOC_ENUM_SINGLE(INTERFACE1_OUTPUT_SELECT, 4,
+ ARRAY_SIZE(enum_ifs_output_select),
+ enum_ifs_output_select);
+
+static struct snd_kcontrol_new cg29xx_snd_controls[] = {
+ SOC_ENUM("If0 Input Select", if0_input_select),
+ SOC_ENUM("If1 Input Select", if1_input_select),
+ SOC_ENUM("If0 Output Select", if0_output_select),
+ SOC_ENUM("If1 Output Select", if1_output_select),
+};
+
+
+static struct cg29xx_codec_dai_data *get_dai_data_codec(struct snd_soc_codec *codec,
+ int dai_id)
+{
+ struct cg29xx_codec_dai_data *codec_drvdata = snd_soc_codec_get_drvdata(codec);
+ return &codec_drvdata[dai_id];
+}
+
+static struct cg29xx_codec_dai_data *get_dai_data(struct snd_soc_dai *codec_dai)
+{
+ return get_dai_data_codec(codec_dai->codec, codec_dai->id);
+}
+
+static int cg29xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id,
+ unsigned int freq, int dir)
+{
+ return 0;
+}
+
+static int cg29xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct cg29xx_codec_dai_data *dai_data = get_dai_data(codec_dai);
+ unsigned int prot;
+ unsigned int msel;
+
+ prot = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ msel = fmt & SND_SOC_DAIFMT_MASTER_MASK;
+
+ switch (prot) {
+ case SND_SOC_DAIFMT_I2S:
+ if (dai_data->config.port != PORT_0_I2S) {
+ pr_err("cg29xx_dai: unsupported DAI format 0x%x\n",
+ fmt);
+ return -EINVAL;
+ }
+
+ if (msel == SND_SOC_DAIFMT_CBM_CFM)
+ dai_data->config.conf.i2s.mode = DAI_MODE_MASTER;
+ else
+ dai_data->config.conf.i2s.mode = DAI_MODE_SLAVE;
+ break;
+
+ case SND_SOC_DAIFMT_DSP_A:
+ if (dai_data->config.port != PORT_1_I2S_PCM ||
+ msel == SND_SOC_DAIFMT_CBM_CFM) {
+ pr_err("cg29xx_dai: unsupported DAI format 0x%x\n",
+ fmt);
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int cg29xx_set_tdm_slot(struct snd_soc_dai *codec_dai,
+ unsigned int tx_mask,
+ unsigned int rx_mask,
+ int slots,
+ int slot_width)
+{
+ struct cg29xx_codec_dai_data *dai_data = get_dai_data(codec_dai);
+
+ if (dai_data->config.port != PORT_1_I2S_PCM)
+ return -EINVAL;
+
+ dai_data->config.conf.i2s_pcm.slot_0_used =
+ (tx_mask | rx_mask) & (1<<CG29XX_DAI_SLOT0_SHIFT) ?
+ true : false;
+ dai_data->config.conf.i2s_pcm.slot_1_used =
+ (tx_mask | rx_mask) & (1<<CG29XX_DAI_SLOT1_SHIFT) ?
+ true : false;
+ dai_data->config.conf.i2s_pcm.slot_2_used =
+ (tx_mask | rx_mask) & (1<<CG29XX_DAI_SLOT2_SHIFT) ?
+ true : false;
+ dai_data->config.conf.i2s_pcm.slot_3_used =
+ (tx_mask | rx_mask) & (1<<CG29XX_DAI_SLOT3_SHIFT) ?
+ true : false;
+
+ dai_data->config.conf.i2s_pcm.slot_0_start = 0;
+ dai_data->config.conf.i2s_pcm.slot_1_start = slot_width;
+ dai_data->config.conf.i2s_pcm.slot_2_start = 2 * slot_width;
+ dai_data->config.conf.i2s_pcm.slot_3_start = 3 * slot_width;
+
+ return 0;
+}
+
+static int cg29xx_configure_endp(struct cg29xx_codec_dai_data *dai_data,
+ enum cg2900_audio_endpoint_id endpid)
+{
+ struct cg2900_endpoint_config config;
+ int err;
+ enum cg2900_dai_sample_rate dai_sr;
+ enum cg2900_endpoint_sample_rate endp_sr;
+
+ switch (dai_data->config.port) {
+ default:
+ case PORT_0_I2S:
+ dai_sr = dai_data->config.conf.i2s.sample_rate;
+ break;
+
+ case PORT_1_I2S_PCM:
+ dai_sr = dai_data->config.conf.i2s_pcm.sample_rate;
+ break;
+ }
+
+ switch (dai_sr) {
+ default:
+ case SAMPLE_RATE_8:
+ endp_sr = ENDPOINT_SAMPLE_RATE_8_KHZ;
+ break;
+ case SAMPLE_RATE_16:
+ endp_sr = ENDPOINT_SAMPLE_RATE_16_KHZ;
+ break;
+ case SAMPLE_RATE_44_1:
+ endp_sr = ENDPOINT_SAMPLE_RATE_44_1_KHZ;
+ break;
+ case SAMPLE_RATE_48:
+ endp_sr = ENDPOINT_SAMPLE_RATE_48_KHZ;
+ break;
+ }
+
+ config.endpoint_id = endpid;
+
+ switch (endpid) {
+ default:
+ case ENDPOINT_BT_SCO_INOUT:
+ config.config.sco.sample_rate = endp_sr;
+ break;
+
+ case ENDPOINT_FM_TX:
+ case ENDPOINT_FM_RX:
+ config.config.fm.sample_rate = endp_sr;
+ break;
+ }
+
+ err = cg2900_audio_config_endpoint(codec_private.session, &config);
+
+ return err;
+}
+
+static int cg29xx_stop_if(struct cg29xx_codec_dai_data *dai_data,
+ enum cg29xx_dai_direction direction)
+{
+ int err = 0;
+ unsigned int *stream;
+
+ if (direction == CG29XX_DAI_DIRECTION_TX)
+ stream = &dai_data->tx_active;
+ else
+ stream = &dai_data->rx_active;
+
+ if (*stream) {
+ err = cg2900_audio_stop_stream(
+ codec_private.session,
+ *stream);
+ if (!err) {
+ *stream = 0;
+ } else {
+ pr_err("asoc cg29xx - %s - Failed to stop stream on interface %d.\n",
+ __func__,
+ dai_data->config.port);
+ }
+ }
+
+ return err;
+}
+
+static int cg29xx_start_if(struct cg29xx_codec_dai_data *dai_data,
+ enum cg29xx_dai_direction direction)
+{
+ enum cg2900_audio_endpoint_id if_endpid;
+ enum cg2900_audio_endpoint_id endpid;
+ unsigned int *stream;
+ int err;
+
+ if (dai_data->config.port == PORT_0_I2S)
+ if_endpid = ENDPOINT_PORT_0_I2S;
+ else
+ if_endpid = ENDPOINT_PORT_1_I2S_PCM;
+
+ if (direction == CG29XX_DAI_DIRECTION_RX) {
+ switch (dai_data->output_select) {
+ default:
+ case 0:
+ endpid = ENDPOINT_BT_SCO_INOUT;
+ break;
+ case 1:
+ endpid = ENDPOINT_FM_TX;
+ }
+ stream = &dai_data->rx_active;
+ } else {
+ switch (dai_data->input_select) {
+ default:
+ case 0:
+ endpid = ENDPOINT_BT_SCO_INOUT;
+ break;
+ case 1:
+ endpid = ENDPOINT_FM_RX;
+ }
+
+ stream = &dai_data->tx_active;
+ }
+
+ if (*stream || (endpid == ENDPOINT_BT_SCO_INOUT)) {
+ pr_debug("asoc cg29xx - %s - The interface has already been started.\n",
+ __func__);
+ return 0;
+ }
+
+ pr_debug("asoc cg29xx - %s - direction: %d, if_id: %d endpid: %d\n",
+ __func__,
+ direction,
+ if_endpid,
+ endpid);
+
+ err = cg29xx_configure_endp(dai_data, endpid);
+
+ if (err) {
+ pr_err("asoc cg29xx - %s - Configure endpoint id: %d failed.\n",
+ __func__,
+ endpid);
+
+ return err;
+ }
+
+ err = cg2900_audio_start_stream(codec_private.session,
+ if_endpid,
+ endpid,
+ stream);
+
+ return err;
+}
+
+static int cg29xx_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ int err = 0;
+
+ if (!codec_private.session)
+ err = cg2900_audio_open(&codec_private.session, NULL);
+
+ return err;
+}
+
+static int cg29xx_dai_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai)
+{
+ struct cg29xx_codec_dai_data *dai_data = get_dai_data(codec_dai);
+ int err = 0;
+ enum cg29xx_dai_direction direction;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ direction = CG29XX_DAI_DIRECTION_RX;
+ else
+ direction = CG29XX_DAI_DIRECTION_TX;
+
+ err = cg29xx_start_if(dai_data, direction);
+
+ return err;
+}
+
+static void cg29xx_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai)
+{
+ struct cg29xx_codec_dai_data *dai_data = get_dai_data(codec_dai);
+ enum cg29xx_dai_direction direction;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ direction = CG29XX_DAI_DIRECTION_RX;
+ else
+ direction = CG29XX_DAI_DIRECTION_TX;
+
+ (void) cg29xx_stop_if(dai_data, direction);
+}
+
+static int cg29xx_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params,
+ struct snd_soc_dai *codec_dai)
+{
+ struct cg29xx_codec_dai_data *dai_data = get_dai_data(codec_dai);
+ enum cg2900_dai_fs_duration duration = SYNC_DURATION_32;
+ enum cg2900_dai_bit_clk bclk = BIT_CLK_512;
+ int sr;
+ int err = 0;
+ enum cg2900_dai_stream_ratio ratio = STREAM_RATIO_FM48_VOICE16;
+
+ pr_debug("cg29xx asoc - %s called. Port: %d.\n",
+ __func__,
+ dai_data->config.port);
+
+ switch (params_rate(hw_params)) {
+ case 8000:
+ sr = SAMPLE_RATE_8;
+ bclk = BIT_CLK_512;
+ duration = SYNC_DURATION_32;
+ ratio = STREAM_RATIO_FM48_VOICE8;
+ break;
+ case 16000:
+ sr = SAMPLE_RATE_16;
+ bclk = BIT_CLK_512;
+ duration = SYNC_DURATION_32;
+ ratio = STREAM_RATIO_FM48_VOICE16;
+ break;
+ case 44100:
+ sr = SAMPLE_RATE_44_1;
+ break;
+ case 48000:
+ sr = SAMPLE_RATE_48;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (dai_data->config.port == PORT_0_I2S) {
+ dai_data->config.conf.i2s.sample_rate = sr;
+ } else {
+ dai_data->config.conf.i2s_pcm.sample_rate = sr;
+ dai_data->config.conf.i2s_pcm.duration = duration;
+ dai_data->config.conf.i2s_pcm.clk = bclk;
+ dai_data->config.conf.i2s_pcm.ratio = ratio;
+ }
+
+ if (!(dai_data->tx_active | dai_data->rx_active) && dai_data->config.port != PORT_1_I2S_PCM) {
+ err = cg2900_audio_set_dai_config(
+ codec_private.session,
+ &dai_data->config);
+
+ pr_debug("asoc cg29xx: cg2900_audio_set_dai_config"
+ "on port %d completed with result: %d.\n",
+ dai_data->config.port,
+ err);
+ }
+
+ return err;
+}
+
+static unsigned int cg29xx_codec_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ struct cg29xx_codec_dai_data *dai_data;
+
+ switch (reg) {
+ case INTERFACE0_INPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 0);
+ return dai_data->input_select;
+
+ case INTERFACE1_INPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 1);
+ return dai_data->input_select;
+
+ case INTERFACE0_OUTPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 0);
+ return dai_data->output_select;
+
+ case INTERFACE1_OUTPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 1);
+ return dai_data->output_select;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int cg29xx_codec_write(struct snd_soc_codec *codec,
+ unsigned int reg,
+ unsigned int value)
+{
+ struct cg29xx_codec_dai_data *dai_data;
+ enum cg29xx_dai_direction direction;
+ bool restart_if = false;
+ int old_value;
+
+ switch (reg) {
+ case INTERFACE0_INPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 0);
+ direction = CG29XX_DAI_DIRECTION_TX;
+
+ old_value = dai_data->input_select;
+ dai_data->input_select = value;
+
+ if ((old_value ^ value) && dai_data->tx_active)
+ restart_if = true;
+ break;
+
+ case INTERFACE1_INPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 1);
+ direction = CG29XX_DAI_DIRECTION_TX;
+
+ old_value = dai_data->input_select;
+ dai_data->input_select = value;
+
+ if ((old_value ^ value) && dai_data->tx_active)
+ restart_if = true;
+ break;
+
+ case INTERFACE0_OUTPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 0);
+ direction = CG29XX_DAI_DIRECTION_RX;
+
+ old_value = dai_data->output_select;
+ dai_data->output_select = value;
+
+ if ((old_value ^ value) && dai_data->rx_active)
+ restart_if = true;
+ break;
+
+ case INTERFACE1_OUTPUT_SELECT:
+ dai_data = get_dai_data_codec(codec, 1);
+ direction = CG29XX_DAI_DIRECTION_RX;
+
+ old_value = dai_data->output_select;
+ dai_data->output_select = value;
+
+ if ((old_value ^ value) && dai_data->rx_active)
+ restart_if = true;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (restart_if) {
+ (void) cg29xx_stop_if(dai_data, direction);
+ (void) cg29xx_start_if(dai_data, direction);
+ }
+
+ return 0;
+}
+
+static int cg29xx_codec_probe(struct snd_soc_codec *codec)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ snd_soc_add_controls(
+ codec,
+ cg29xx_snd_controls,
+ ARRAY_SIZE(cg29xx_snd_controls));
+
+ return 0;
+}
+
+static int cg29xx_codec_remove(struct snd_soc_codec *codec)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+static int cg29xx_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+static int cg29xx_codec_resume(struct snd_soc_codec *codec)
+{
+ pr_debug("%s: Enter (codec->name = %s).\n", __func__, codec->name);
+
+ return 0;
+}
+
+struct snd_soc_codec_driver cg29xx_codec_driver = {
+ .probe = cg29xx_codec_probe,
+ .remove = cg29xx_codec_remove,
+ .suspend = cg29xx_codec_suspend,
+ .resume = cg29xx_codec_resume,
+ .read = cg29xx_codec_read,
+ .write = cg29xx_codec_write,
+};
+
+static int __devinit cg29xx_codec_driver_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct cg29xx_codec_dai_data *dai_data;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ pr_info("%s: Init codec private data..\n", __func__);
+ dai_data = kzalloc(CG29XX_NBR_OF_DAI * sizeof(struct cg29xx_codec_dai_data),
+ GFP_KERNEL);
+ if (dai_data == NULL)
+ return -ENOMEM;
+
+ dai_data[0].tx_active = 0;
+ dai_data[0].rx_active = 0;
+ dai_data[0].input_select = 0;
+ dai_data[0].output_select = 0;
+ dai_data[0].config.port = PORT_0_I2S;
+ dai_data[0].config.conf.i2s.mode = DAI_MODE_SLAVE;
+ dai_data[0].config.conf.i2s.half_period = HALF_PER_DUR_16;
+ dai_data[0].config.conf.i2s.channel_sel = CHANNEL_SELECTION_BOTH;
+ dai_data[0].config.conf.i2s.sample_rate = SAMPLE_RATE_48;
+ dai_data[0].config.conf.i2s.word_width = WORD_WIDTH_32;
+ dai_data[1].tx_active = 0;
+ dai_data[1].rx_active = 0;
+ dai_data[1].input_select = 0;
+ dai_data[1].output_select = 0;
+ dai_data[1].config.port = PORT_1_I2S_PCM;
+ dai_data[1].config.conf.i2s_pcm.mode = DAI_MODE_SLAVE;
+ dai_data[1].config.conf.i2s_pcm.slot_0_dir = DAI_DIR_B_RX_A_TX;
+ dai_data[1].config.conf.i2s_pcm.slot_1_dir = DAI_DIR_B_TX_A_RX;
+ dai_data[1].config.conf.i2s_pcm.slot_2_dir = DAI_DIR_B_RX_A_TX;
+ dai_data[1].config.conf.i2s_pcm.slot_3_dir = DAI_DIR_B_RX_A_TX;
+ dai_data[1].config.conf.i2s_pcm.slot_0_used = true;
+ dai_data[1].config.conf.i2s_pcm.slot_1_used = false;
+ dai_data[1].config.conf.i2s_pcm.slot_2_used = false;
+ dai_data[1].config.conf.i2s_pcm.slot_3_used = false;
+ dai_data[1].config.conf.i2s_pcm.slot_0_start = 0;
+ dai_data[1].config.conf.i2s_pcm.slot_1_start = 16;
+ dai_data[1].config.conf.i2s_pcm.slot_2_start = 32;
+ dai_data[1].config.conf.i2s_pcm.slot_3_start = 48;
+ dai_data[1].config.conf.i2s_pcm.protocol = PORT_PROTOCOL_PCM;
+ dai_data[1].config.conf.i2s_pcm.ratio = STREAM_RATIO_FM48_VOICE16;
+ dai_data[1].config.conf.i2s_pcm.duration = SYNC_DURATION_32;
+ dai_data[1].config.conf.i2s_pcm.clk = BIT_CLK_512;
+ dai_data[1].config.conf.i2s_pcm.sample_rate = SAMPLE_RATE_16;
+
+ platform_set_drvdata(pdev, dai_data);
+
+ pr_info("%s: Register codec.\n", __func__);
+ ret = snd_soc_register_codec(&pdev->dev, &cg29xx_codec_driver, &cg29xx_dai_driver[0], 2);
+ if (ret < 0) {
+ pr_debug("%s: Error: Failed to register codec (ret = %d).\n",
+ __func__,
+ ret);
+ snd_soc_unregister_codec(&pdev->dev);
+ kfree(platform_get_drvdata(pdev));
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit cg29xx_codec_driver_remove(struct platform_device *pdev)
+{
+ (void)cg2900_audio_close(&codec_private.session);
+
+ snd_soc_unregister_codec(&pdev->dev);
+ kfree(platform_get_drvdata(pdev));
+
+ return 0;
+}
+
+static int cg29xx_codec_driver_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return 0;
+}
+
+static int cg29xx_codec_driver_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver cg29xx_codec_platform_driver = {
+ .driver = {
+ .name = "cg29xx-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = cg29xx_codec_driver_probe,
+ .remove = __devexit_p(cg29xx_codec_driver_remove),
+ .suspend = cg29xx_codec_driver_suspend,
+ .resume = cg29xx_codec_driver_resume,
+};
+
+
+static int __devinit cg29xx_codec_platform_driver_init(void)
+{
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ ret = platform_driver_register(&cg29xx_codec_platform_driver);
+ if (ret != 0)
+ pr_err("Failed to register CG29xx platform driver (%d)!\n", ret);
+
+ return ret;
+}
+
+static void __exit cg29xx_codec_platform_driver_exit(void)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ platform_driver_unregister(&cg29xx_codec_platform_driver);
+}
+
+
+module_init(cg29xx_codec_platform_driver_init);
+module_exit(cg29xx_codec_platform_driver_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/cg29xx.h b/sound/soc/codecs/cg29xx.h
new file mode 100644
index 00000000000..fec52d7cdd7
--- /dev/null
+++ b/sound/soc/codecs/cg29xx.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Roger Nilsson roger.xr.nilsson@stericsson.com
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#ifndef CG29XX_CODEC_H
+#define CG29XX_CODEC_H
+
+#include <../../../drivers/staging/cg2900/include/cg2900_audio.h>
+
+struct cg29xx_codec_dai_data {
+ struct mutex mutex;
+ unsigned int rx_active;
+ unsigned int tx_active;
+ int input_select;
+ int output_select;
+ struct cg2900_dai_config config;
+};
+
+struct cg29xx_codec{
+ unsigned int session;
+};
+
+#define CG29XX_DAI_SLOT0_SHIFT 0
+#define CG29XX_DAI_SLOT1_SHIFT 1
+#define CG29XX_DAI_SLOT2_SHIFT 2
+#define CG29XX_DAI_SLOT3_SHIFT 3
+
+#define INTERFACE0_INPUT_SELECT 0x00
+#define INTERFACE1_INPUT_SELECT 0x01
+#define INTERFACE0_OUTPUT_SELECT 0x02
+#define INTERFACE1_OUTPUT_SELECT 0x03
+
+#endif /* CG29XX_CODEC_H */
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig
new file mode 100644
index 00000000000..02239929879
--- /dev/null
+++ b/sound/soc/ux500/Kconfig
@@ -0,0 +1,57 @@
+#
+# Ux500 SoC audio configuration
+#
+
+menuconfig SND_SOC_UX500
+ bool "SoC Audio support for Ux500 platform"
+ depends on SND_SOC && STM_I2S && STM_MSP_I2S
+ default n
+ help
+ Say Y if you want to add support for the Ux500 platform.
+
+config SND_SOC_UX500_AB3550
+ bool "Codec - AB3550"
+ depends on SND_SOC_UX500 && (UX500_SOC_DB8500 || UX500_SOC_DB5500) && AB3550_CORE
+ select SND_SOC_AB3550
+ default n
+ help
+ Say Y if you want to include the AB3550 codec.
+
+config SND_SOC_UX500_AB5500
+ bool "Codec - AB5500"
+ depends on SND_SOC_UX500 && (UX500_SOC_DB8500 || UX500_SOC_DB5500) && AB5500_CORE
+ select SND_SOC_AB5500
+ default n
+ help
+ Say Y if you want to include the AB5500 codec.
+
+config SND_SOC_UX500_AB8500
+ bool "Codec - AB8500"
+ depends on SND_SOC_UX500 && UX500_SOC_DB8500 && AB8500_CORE && AB8500_GPADC
+ select SND_SOC_AB8500
+ default n
+ help
+ Say Y if you want to include AB8500 audio codec.
+
+config SND_SOC_UX500_CG29XX
+ bool "Codec - CG29xx"
+ depends on SND_SOC_UX500 && (UX500_SOC_DB8500 || UX500_SOC_DB5500) && CG2900_AUDIO
+ select SND_SOC_CG29XX
+ default n
+ help
+ Say Y if you want to include CG29xx codec (Combo chip).
+
+config SND_SOC_UX500_AV8100
+ bool "Codec - AV8100"
+ depends on SND_SOC_UX500 && (UX500_SOC_DB8500 || UX500_SOC_DB5500) && AV8100
+ select SND_SOC_AV8100
+ default n
+ help
+ Say Y if you want to include AV8100 codec (HDMI chip).
+
+config SND_SOC_UX500_DEBUG
+ bool "Activate Ux500 platform debug-mode (pr_debug)"
+ depends on SND_SOC_UX500
+ default n
+ help
+ Say Y if you want to add debug level prints for Ux500 code-files.
diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile
new file mode 100644
index 00000000000..255c0ecefdb
--- /dev/null
+++ b/sound/soc/ux500/Makefile
@@ -0,0 +1,47 @@
+# Ux500 Platform Support
+
+ifdef CONFIG_SND_SOC_UX500_DEBUG
+CFLAGS_ux500_pcm.o := -DDEBUG
+CFLAGS_ux500_msp_dai.o := -DDEBUG
+CFLAGS_ux500_ab3550.o := -DDEBUG
+CFLAGS_ux500_ab8500.o := -DDEBUG
+CFLAGS_ux500_av8100.o := -DDEBUG
+CFLAGS_ux500_cg29xx.o := -DDEBUG
+endif
+
+ifdef CONFIG_SND_SOC_UX500_AB3550
+snd-soc-ux500-ab3550-objs := ux500_ab3550.o
+obj-$(CONFIG_SND_SOC_UX500_AB3550) += ux500_ab3550.o
+endif
+
+ifdef CONFIG_SND_SOC_UX500_AB5500
+snd-soc-ux500-ab5500-objs := ux500_ab5500.o
+obj-$(CONFIG_SND_SOC_UX500_AB5500) += ux500_ab5500.o
+endif
+
+ifdef CONFIG_SND_SOC_UX500_AB8500
+snd-soc-ux500-ab8500-objs := ux500_ab8500.o
+obj-$(CONFIG_SND_SOC_UX500_AB8500) += ux500_ab8500.o
+endif
+
+ifdef CONFIG_SND_SOC_UX500_AV8100
+snd-soc-ux500-av8100-objs := ux500_av8100.o
+obj-$(CONFIG_SND_SOC_UX500_AV8100) += ux500_av8100.o
+endif
+
+ifdef CONFIG_SND_SOC_UX500_CG29XX
+snd-soc-ux500-cg29xx-objs := ux500_cg29xx.o
+obj-$(CONFIG_SND_SOC_UX500_CG29XX) += ux500_cg29xx.o
+endif
+
+snd-soc-ux500-objs := ux500_pcm.o ux500_msp_dai.o
+
+ifdef CONFIG_UX500_SOC_DB8500
+snd-soc-ux500-objs += u8500.o
+endif
+
+ifdef CONFIG_UX500_SOC_DB5500
+snd-soc-ux500-objs += u5500.o
+endif
+
+obj-$(CONFIG_UX500_SOC_DBX500) += snd-soc-ux500.o
diff --git a/sound/soc/ux500/u5500.c b/sound/soc/ux500/u5500.c
new file mode 100644
index 00000000000..fda8db3472b
--- /dev/null
+++ b/sound/soc/ux500/u5500.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Xie Xiaolei (xie.xiaolei@stericsson.com)
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <linux/io.h>
+#include <sound/soc.h>
+#include <asm/mach-types.h>
+
+#include "ux500_pcm.h"
+#include "ux500_msp_dai.h"
+
+#include <linux/spi/spi.h>
+#include <sound/initval.h>
+
+#ifdef CONFIG_SND_SOC_UX500_AB5500
+#include "ux500_ab5500.h"
+#endif
+
+static struct platform_device *u5500_platform_dev;
+/* Create dummy devices for platform drivers */
+
+static struct platform_device ux500_pcm = {
+ .name = "ux500-pcm",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+
+/* Define the whole U5500 soundcard, linking platform to the codec-drivers */
+struct snd_soc_dai_link u5500_dai_links[] = {
+#ifdef CONFIG_SND_SOC_UX500_AB5500
+ {
+ .name = "ab5500_0",
+ .stream_name = "ab5500_0",
+ .cpu_dai_name = "i2s.0",
+ .codec_dai_name = "ab5500-codec-dai.0",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "ab5500-codec.9",
+ .init = NULL,
+ .ops = (struct snd_soc_ops[]) {
+ {
+ .startup = ux500_ab5500_startup,
+ .shutdown = ux500_ab5500_shutdown,
+ .hw_params = ux500_ab5500_hw_params,
+ }
+ }
+#endif
+ }
+};
+
+static struct snd_soc_card u5500_drvdata = {
+ .name = "U5500-card",
+ .probe = NULL,
+ .dai_link = u5500_dai_links,
+ .num_links = ARRAY_SIZE(u5500_dai_links),
+};
+
+static int __init u5500_soc_init(void)
+{
+ int ret = 0;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ if (!machine_is_u5500())
+ return 0;
+
+ platform_device_register(&ux500_pcm);
+
+ u5500_platform_dev = platform_device_alloc("soc-audio", -1);
+ if (!u5500_platform_dev)
+ return -ENOMEM;
+
+ platform_set_drvdata(u5500_platform_dev, &u5500_drvdata);
+ u5500_drvdata.dev = &u5500_platform_dev->dev;
+
+ ret = platform_device_add(u5500_platform_dev);
+ if (ret) {
+ pr_err("%s: Error: Failed to add platform device (%s).\n",
+ __func__,
+ u5500_drvdata.name);
+ platform_device_put(u5500_platform_dev);
+ }
+
+ return ret;
+}
+
+static void __exit u5500_soc_exit(void)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ platform_device_unregister(u5500_platform_dev);
+}
+
+module_init(u5500_soc_init);
+module_exit(u5500_soc_exit);
+
+MODULE_LICENSE("GPLv2");
diff --git a/sound/soc/ux500/u8500.c b/sound/soc/ux500/u8500.c
new file mode 100644
index 00000000000..59324c878e4
--- /dev/null
+++ b/sound/soc/ux500/u8500.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja (ola.o.lilja@stericsson.com)
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <linux/io.h>
+#include <sound/soc.h>
+#include <asm/mach-types.h>
+
+#include "ux500_pcm.h"
+#include "ux500_msp_dai.h"
+
+#include <linux/spi/spi.h>
+#include <sound/initval.h>
+
+#ifdef CONFIG_SND_SOC_UX500_AB3550
+#include "ux500_ab3550.h"
+#endif
+
+#ifdef CONFIG_SND_SOC_UX500_AB8500
+#include <sound/ux500_ab8500.h>
+#endif
+
+#ifdef CONFIG_SND_SOC_UX500_AV8100
+#include "ux500_av8100.h"
+#endif
+
+#ifdef CONFIG_SND_SOC_UX500_CG29XX
+#include "ux500_cg29xx.h"
+#endif
+
+
+static struct platform_device *u8500_platform_dev;
+
+/* Create dummy devices for platform drivers */
+
+static struct platform_device ux500_pcm = {
+ .name = "ux500-pcm",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+#ifdef CONFIG_SND_SOC_UX500_AV8100
+static struct platform_device av8100_codec = {
+ .name = "av8100-codec",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+#endif
+
+#ifdef CONFIG_SND_SOC_UX500_CG29XX
+static struct platform_device cg29xx_codec = {
+ .name = "cg29xx-codec",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+#endif
+
+/* Define the whole U8500 soundcard, linking platform to the codec-drivers */
+struct snd_soc_dai_link u8500_dai_links[] = {
+ #ifdef CONFIG_SND_SOC_UX500_AV8100
+ {
+ .name = "hdmi",
+ .stream_name = "hdmi",
+ .cpu_dai_name = "i2s.2",
+ .codec_dai_name = "av8100-codec-dai",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "av8100-codec.0",
+ .init = NULL,
+ .ops = ux500_av8100_ops,
+ },
+ #endif
+ #ifdef CONFIG_SND_SOC_UX500_AB3550
+ {
+ .name = "ab3550_0",
+ .stream_name = "ab3550_0",
+ .cpu_dai_name = "i2s.0",
+ .codec_dai_name = "ab3550-codec-dai.0",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "ab3550-codec.11",
+ .init = NULL,
+ .ops = ux500_ab3550_ops,
+ },
+ {
+ .name = "ab3550_1",
+ .stream_name = "ab3550_1",
+ .cpu_dai_name = "i2s.1",
+ .codec_dai_name = "ab3550-codec-dai.1",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "ab3550-codec.11",
+ .init = NULL,
+ .ops = ux500_ab3550_ops,
+ },
+ #endif
+ #ifdef CONFIG_SND_SOC_UX500_AB8500
+ {
+ .name = "ab8500_0",
+ .stream_name = "ab8500_0",
+ .cpu_dai_name = "i2s.1",
+ .codec_dai_name = "ab8500-codec-dai.0",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "ab8500-codec.0",
+ .init = ux500_ab8500_machine_codec_init,
+ .ops = ux500_ab8500_ops,
+ },
+ {
+ .name = "ab8500_1",
+ .stream_name = "ab8500_1",
+ .cpu_dai_name = "i2s.3",
+ .codec_dai_name = "ab8500-codec-dai.1",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "ab8500-codec.0",
+ .init = NULL,
+ .ops = ux500_ab8500_ops,
+ },
+ #endif
+ #ifdef CONFIG_SND_SOC_UX500_CG29XX
+ {
+ .name = "cg29xx_0",
+ .stream_name = "cg29xx_0",
+ .cpu_dai_name = "i2s.0",
+ .codec_dai_name = "cg29xx-codec-dai.1",
+ .platform_name = "ux500-pcm.0",
+ .codec_name = "cg29xx-codec.0",
+ .init = NULL,
+ .ops = ux500_cg29xx_ops,
+ },
+ #endif
+};
+
+static struct snd_soc_card u8500_drvdata = {
+ .name = "U8500-card",
+ .probe = NULL,
+ .dai_link = u8500_dai_links,
+ .num_links = ARRAY_SIZE(u8500_dai_links),
+};
+
+static int __init u8500_soc_init(void)
+{
+ int ret;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ if (machine_is_u5500())
+ return 0;
+
+ #ifdef CONFIG_SND_SOC_UX500_AV8100
+ pr_debug("%s: Register device to generate a probe for AV8100 codec.\n",
+ __func__);
+ platform_device_register(&av8100_codec);
+ #endif
+
+ #ifdef CONFIG_SND_SOC_UX500_CG29XX
+ pr_debug("%s: Register device to generate a probe for CG29xx codec.\n",
+ __func__);
+ platform_device_register(&cg29xx_codec);
+ #endif
+
+ #ifdef CONFIG_SND_SOC_UX500_AB8500
+ pr_debug("%s: Calling init-function for AB8500 machine driver.\n",
+ __func__);
+ ret = ux500_ab8500_soc_machine_drv_init();
+ if (ret)
+ pr_err("%s: ux500_ab8500_soc_machine_drv_init failed (%d).\n",
+ __func__, ret);
+ #endif
+
+ pr_debug("%s: Register device to generate a probe for Ux500-pcm platform.\n",
+ __func__);
+ platform_device_register(&ux500_pcm);
+
+ pr_debug("%s: Allocate platform device 'soc-audio'.\n",
+ __func__);
+ u8500_platform_dev = platform_device_alloc("soc-audio", -1);
+ if (!u8500_platform_dev)
+ return -ENOMEM;
+
+ pr_debug("%s: Card %s: num_links = %d\n",
+ __func__,
+ u8500_drvdata.name,
+ u8500_drvdata.num_links);
+ pr_debug("%s: Card %s: DAI-link 0: name = %s\n",
+ __func__,
+ u8500_drvdata.name,
+ u8500_drvdata.dai_link[0].name);
+ pr_debug("%s: Card %s: DAI-link 0: stream_name = %s\n",
+ __func__,
+ u8500_drvdata.name,
+ u8500_drvdata.dai_link[0].stream_name);
+
+ pr_debug("%s: Card %s: Set platform drvdata.\n",
+ __func__,
+ u8500_drvdata.name);
+ platform_set_drvdata(u8500_platform_dev, &u8500_drvdata);
+ u8500_drvdata.dev = &u8500_platform_dev->dev;
+
+ pr_debug("%s: Card %s: Add platform device.\n",
+ __func__,
+ u8500_drvdata.name);
+ ret = platform_device_add(u8500_platform_dev);
+ if (ret) {
+ pr_err("%s: Error: Failed to add platform device (%s).\n",
+ __func__,
+ u8500_drvdata.name);
+ platform_device_put(u8500_platform_dev);
+ }
+
+ return ret;
+}
+
+static void __exit u8500_soc_exit(void)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ #ifdef CONFIG_SND_SOC_UX500_AB8500
+ pr_debug("%s: Calling exit-function for AB8500 machine driver.\n",
+ __func__);
+ ux500_ab8500_soc_machine_drv_cleanup();
+ #endif
+
+ pr_debug("%s: Unregister platform device (%s).\n",
+ __func__,
+ u8500_drvdata.name);
+ platform_device_unregister(u8500_platform_dev);
+}
+
+module_init(u8500_soc_init);
+module_exit(u8500_soc_exit);
+
+MODULE_LICENSE("GPLv2");
diff --git a/sound/soc/ux500/ux500_ab3550.c b/sound/soc/ux500/ux500_ab3550.c
new file mode 100644
index 00000000000..7e144c0e4d2
--- /dev/null
+++ b/sound/soc/ux500/ux500_ab3550.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja ola.o.lilja@stericsson.com,
+ * Roger Nilsson roger.xr.nilsson@stericsson.com
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <sound/soc.h>
+#include "../codecs/ab3550.h"
+
+static int ux500_ab3550_startup(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ return 0;
+}
+
+static void ux500_ab3550_shutdown(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s: Enter.\n", __func__);
+}
+
+static int ux500_ab3550_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+
+ int channels = params_channels(params);
+
+ pr_debug("%s: Enter.\n", __func__);
+ pr_debug("%s: substream->pcm->name = %s.\n", __func__, substream->pcm->name);
+ pr_debug("%s: substream->pcm->id = %s.\n", __func__, substream->pcm->id);
+ pr_debug("%s: substream->name = %s.\n", __func__, substream->name);
+ pr_debug("%s: substream->number = %d.\n", __func__, substream->number);
+ pr_debug("%s: channels = %d.\n", __func__, channels);
+ pr_debug("%s: DAI-index (Codec): %d\n", __func__, codec_dai->id);
+ pr_debug("%s: DAI-index (Platform): %d\n", __func__, cpu_dai->id);
+
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0) {
+ pr_debug("%s: snd_soc_dai_set_fmt failed with %d.\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0) {
+ pr_debug("%s: snd_soc_dai_set_fmt failed with %d.\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+struct snd_soc_ops ux500_ab3550_ops[] = {
+ {
+ .startup = ux500_ab3550_startup,
+ .shutdown = ux500_ab3550_shutdown,
+ .hw_params = ux500_ab3550_hw_params,
+ }
+};
diff --git a/sound/soc/ux500/ux500_ab3550.h b/sound/soc/ux500/ux500_ab3550.h
new file mode 100644
index 00000000000..53ea3902d36
--- /dev/null
+++ b/sound/soc/ux500/ux500_ab3550.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef UX500_AB3550_H
+#define UX500_AB3550_H
+
+extern struct snd_soc_ops ux500_ab3550_ops[];
+
+#endif
diff --git a/sound/soc/ux500/ux500_ab5500.c b/sound/soc/ux500/ux500_ab5500.c
new file mode 100644
index 00000000000..551ec05fcb5
--- /dev/null
+++ b/sound/soc/ux500/ux500_ab5500.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Ola Lilja ola.o.lilja@stericsson.com,
+ * Roger Nilsson roger.xr.nilsson@stericsson.com
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <sound/soc.h>
+#include "../codecs/ab5500.h"
+int ux500_ab5500_startup(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+void ux500_ab5500_shutdown(struct snd_pcm_substream *substream)
+{
+ printk(KERN_DEBUG "%s: Enter.\n", __func__);
+}
+
+int ux500_ab5500_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+
+ int channels = params_channels(params);
+
+ printk(KERN_DEBUG "%s: Enter.\n", __func__);
+ printk(KERN_DEBUG "%s: substream->pcm->name = %s.\n", __func__, substream->pcm->name);
+ printk(KERN_DEBUG "%s: substream->pcm->id = %s.\n", __func__, substream->pcm->id);
+ printk(KERN_DEBUG "%s: substream->name = %s.\n", __func__, substream->name);
+ printk(KERN_DEBUG "%s: substream->number = %d.\n", __func__, substream->number);
+ printk(KERN_DEBUG "%s: channels = %d.\n", __func__, channels);
+ printk(KERN_DEBUG "%s: DAI-index (Codec): %d\n", __func__, codec_dai->id);
+ printk(KERN_DEBUG "%s: DAI-index (Platform): %d\n", __func__, cpu_dai->id);
+
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
diff --git a/sound/soc/ux500/ux500_ab5500.h b/sound/soc/ux500/ux500_ab5500.h
new file mode 100644
index 00000000000..ea69f1a048c
--- /dev/null
+++ b/sound/soc/ux500/ux500_ab5500.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Xie Xiaolei (xie.xiaolei@stericsson.com)
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef UX500_AB5500_H
+#define UX500_AB5500_H
+
+int ux500_ab5500_startup(struct snd_pcm_substream *substream);
+
+void ux500_ab5500_shutdown(struct snd_pcm_substream *substream);
+
+int ux500_ab5500_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+
+#endif
diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c
new file mode 100644
index 00000000000..be647daeeed
--- /dev/null
+++ b/sound/soc/ux500/ux500_ab8500.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Mikko J. Lehto <mikko.lehto@symbio.com>,
+ * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
+ * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>.
+ * Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <sound/soc.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <mach/hardware.h>
+#include "ux500_pcm.h"
+#include "ux500_msp_dai.h"
+#include "../codecs/ab8500_audio.h"
+
+#define TX_SLOT_MONO 0x0008
+#define TX_SLOT_STEREO 0x000a
+#define RX_SLOT_MONO 0x0001
+#define RX_SLOT_STEREO 0x0003
+#define TX_SLOT_8CH 0x00FF
+#define RX_SLOT_8CH 0x00FF
+
+#define DEF_TX_SLOTS TX_SLOT_STEREO
+#define DEF_RX_SLOTS RX_SLOT_MONO
+
+#define DRIVERMODE_NORMAL 0
+#define DRIVERMODE_CODEC_ONLY 1
+
+static struct snd_soc_jack jack;
+
+/* Power-control */
+static DEFINE_MUTEX(power_lock);
+static int ab8500_power_count;
+
+/* Clocks */
+/* audioclk -> intclk -> sysclk/ulpclk */
+static int master_clock_sel;
+static struct clk *clk_ptr_audioclk;
+static struct clk *clk_ptr_intclk;
+static struct clk *clk_ptr_sysclk;
+static struct clk *clk_ptr_ulpclk;
+
+/* Regulators */
+static enum regulator_idx {
+ REGULATOR_AUDIO,
+ REGULATOR_DMIC,
+ REGULATOR_AMIC1,
+ REGULATOR_AMIC2
+};
+static struct regulator_bulk_data reg_info[4] = {
+ { .supply = "v-audio" },
+ { .supply = "v-dmic" },
+ { .supply = "v-amic1" },
+ { .supply = "v-amic2" }
+};
+static bool reg_enabled[4] = {
+ false,
+ false,
+ false,
+ false
+};
+
+/* Slot configuration */
+static unsigned int tx_slots = DEF_TX_SLOTS;
+static unsigned int rx_slots = DEF_RX_SLOTS;
+
+/* Machine-driver ALSA-controls */
+
+static int mclk_input_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item) {
+ uinfo->value.enumerated.item = 1;
+ strcpy(uinfo->value.enumerated.name, "ULPCLK");
+ } else {
+ strcpy(uinfo->value.enumerated.name, "SYSCLK");
+ }
+ return 0;
+}
+
+static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.enumerated.item[0] = master_clock_sel;
+ return 0;
+}
+
+static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned int val;
+
+ val = (ucontrol->value.enumerated.item[0] != 0);
+ if (master_clock_sel == val)
+ return 0;
+
+ master_clock_sel = val;
+
+ return 1;
+}
+
+static const struct snd_kcontrol_new mclk_input_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Master Clock Select",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = mclk_input_control_info,
+ .get = mclk_input_control_get,
+ .put = mclk_input_control_put,
+ .private_value = 1 /* ULPCLK */
+};
+
+/* Regulators */
+
+static int enable_regulator(enum regulator_idx idx)
+{
+ int ret;
+
+ if (reg_enabled[idx])
+ return 0;
+
+ ret = regulator_enable(reg_info[idx].consumer);
+ if (ret != 0) {
+ pr_err("%s: Failure to enable regulator '%s' (ret = %d)\n",
+ __func__, reg_info[idx].supply, ret);
+ return ret;
+ };
+
+ reg_enabled[idx] = true;
+ pr_debug("%s: Enabled regulator '%s', status: %d, %d, %d, %d\n",
+ __func__,
+ reg_info[idx].supply,
+ (int)reg_enabled[0],
+ (int)reg_enabled[1],
+ (int)reg_enabled[2],
+ (int)reg_enabled[3]);
+ return 0;
+}
+
+static void disable_regulator(enum regulator_idx idx)
+{
+ if (!reg_enabled[idx])
+ return;
+
+ regulator_disable(reg_info[idx].consumer);
+
+ reg_enabled[idx] = false;
+ pr_debug("%s: Disabled regulator '%s', status: %d, %d, %d, %d\n",
+ __func__,
+ reg_info[idx].supply,
+ (int)reg_enabled[0],
+ (int)reg_enabled[1],
+ (int)reg_enabled[2],
+ (int)reg_enabled[3]);
+}
+
+static int create_regulators(void)
+{
+ int i, status = 0;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(reg_info); ++i)
+ reg_info[i].consumer = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(reg_info); ++i) {
+ reg_info[i].consumer = regulator_get(NULL, reg_info[i].supply);
+ if (IS_ERR(reg_info[i].consumer)) {
+ status = PTR_ERR(reg_info[i].consumer);
+ pr_err("%s: ERROR: Failed to get regulator '%s' (ret = %d)!\n",
+ __func__, reg_info[i].supply, status);
+ reg_info[i].consumer = NULL;
+ goto err_get;
+ }
+ }
+
+ return 0;
+
+err_get:
+
+ for (i = 0; i < ARRAY_SIZE(reg_info); ++i) {
+ if (reg_info[i].consumer) {
+ regulator_put(reg_info[i].consumer);
+ reg_info[i].consumer = NULL;
+ }
+ }
+
+ return status;
+}
+
+/* Power/clock control */
+
+static int ux500_ab8500_power_control_inc(void)
+{
+ int ret;
+
+ mutex_lock(&power_lock);
+
+ ab8500_power_count++;
+ pr_debug("%s: ab8500_power_count changed from %d to %d",
+ __func__,
+ ab8500_power_count-1,
+ ab8500_power_count);
+
+ if (ab8500_power_count == 1) {
+ ret = clk_set_parent(clk_ptr_intclk,
+ (master_clock_sel == 0) ? clk_ptr_sysclk : clk_ptr_ulpclk);
+ if (ret) {
+ pr_err("%s: ERROR: Setting master-clock to %s failed (ret = %d)!",
+ __func__,
+ (master_clock_sel == 0) ? "SYSCLK" : "ULPCLK",
+ ret);
+ return ret;
+ }
+
+ pr_debug("%s: Enabling master-clock (%s).",
+ __func__,
+ (master_clock_sel == 0) ? "SYSCLK" : "ULPCLK");
+
+ /* Enable audio-clock */
+ ret = clk_enable(clk_ptr_audioclk);
+ if (ret) {
+ pr_err("%s: ERROR: clk_enable failed (ret = %d)!", __func__, ret);
+ ab8500_power_count = 0;
+ return ret;
+ }
+
+ /* Power on audio-parts of AB8500 */
+ ab8500_audio_power_control(true);
+
+ /* Turn on audio-regulator */
+ ret = enable_regulator(REGULATOR_AUDIO);
+ }
+
+ mutex_unlock(&power_lock);
+
+ return 0;
+}
+
+static void ux500_ab8500_power_control_dec(void)
+{
+ mutex_lock(&power_lock);
+
+ ab8500_power_count--;
+
+ pr_debug("%s: ab8500_power_count changed from %d to %d",
+ __func__,
+ ab8500_power_count+1,
+ ab8500_power_count);
+
+ if (ab8500_power_count == 0) {
+ pr_debug("%s: Disabling master-clock (%s).",
+ __func__,
+ (master_clock_sel == 0) ? "SYSCLK" : "ULPCLK");
+
+ /* Disable audio-clock */
+ clk_disable(clk_ptr_audioclk);
+
+ /* Power off audio-parts of AB8500 */
+ ab8500_audio_power_control(false);
+
+ /* Turn off audio-regulator */
+ disable_regulator(REGULATOR_AUDIO);
+ }
+
+ mutex_unlock(&power_lock);
+}
+
+/* ASoC */
+
+int ux500_ab8500_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ pr_debug("%s: Enter\n", __func__);
+
+ /* If we start recording we better enable the needed mic-regulators */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (ab8500_audio_dapm_path_active(AB8500_AUDIO_DAPM_PATH_DMIC))
+ ret += enable_regulator(REGULATOR_DMIC);
+ if (ab8500_audio_dapm_path_active(AB8500_AUDIO_DAPM_PATH_AMIC1))
+ ret += enable_regulator(REGULATOR_AMIC1);
+ if (ab8500_audio_dapm_path_active(AB8500_AUDIO_DAPM_PATH_AMIC2))
+ ret += enable_regulator(REGULATOR_AMIC2);
+ if (ret != 0)
+ return ret;
+ }
+
+ return ux500_ab8500_power_control_inc();
+
+ return ret;
+}
+
+void ux500_ab8500_shutdown(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s: Enter\n", __func__);
+
+ /* Reset slots configuration to default(s) */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ tx_slots = DEF_TX_SLOTS;
+ else
+ rx_slots = DEF_RX_SLOTS;
+
+ /* Disable all mic-regulators that were enabled when we stop recording */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ disable_regulator(REGULATOR_DMIC);
+ disable_regulator(REGULATOR_AMIC1);
+ disable_regulator(REGULATOR_AMIC2);
+ }
+
+ ux500_ab8500_power_control_dec();
+}
+
+int ux500_ab8500_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ unsigned int fmt, fmt_if1;
+ int channels, ret = 0, slots, slot_width, driver_mode;
+ bool streamIsPlayback;
+
+ pr_debug("%s: Enter\n", __func__);
+
+ pr_debug("%s: substream->pcm->name = %s\n"
+ "substream->pcm->id = %s.\n"
+ "substream->name = %s.\n"
+ "substream->number = %d.\n",
+ __func__,
+ substream->pcm->name,
+ substream->pcm->id,
+ substream->name,
+ substream->number);
+
+ channels = params_channels(params);
+
+ /* Setup codec depending on driver-mode */
+ driver_mode = (channels == 8) ?
+ DRIVERMODE_CODEC_ONLY : DRIVERMODE_NORMAL;
+ pr_debug("%s: Driver-mode: %s.\n",
+ __func__,
+ (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
+ if (driver_mode == DRIVERMODE_NORMAL) {
+ ab8500_audio_set_bit_delay(codec_dai, 0);
+ ab8500_audio_set_word_length(codec_dai, 16);
+ fmt = SND_SOC_DAIFMT_DSP_B |
+ SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CONT;
+ } else {
+ ab8500_audio_set_bit_delay(codec_dai, 1);
+ ab8500_audio_set_word_length(codec_dai, 20);
+ fmt = SND_SOC_DAIFMT_DSP_B |
+ SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_GATED;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ pr_err("%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret < 0) {
+ pr_err("%s: ERROR: snd_soc_dai_set_fmt for cpu_dai (ret = %d)!\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ /* Setup TDM-slots */
+
+ streamIsPlayback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ switch (channels) {
+ case 1:
+ slots = 16;
+ slot_width = 16;
+ tx_slots = (streamIsPlayback) ? TX_SLOT_MONO : 0;
+ rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_MONO;
+ break;
+ case 2:
+ slots = 16;
+ slot_width = 16;
+ tx_slots = (streamIsPlayback) ? TX_SLOT_STEREO : 0;
+ rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_STEREO;
+ break;
+ case 8:
+ slots = 16;
+ slot_width = 16;
+ tx_slots = (streamIsPlayback) ? TX_SLOT_8CH : 0;
+ rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_8CH;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ pr_debug("%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n",
+ __func__, tx_slots, rx_slots);
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots, slot_width);
+ if (ret)
+ return ret;
+
+ pr_debug("%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n",
+ __func__, tx_slots, rx_slots);
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots, slot_width);
+ if (ret)
+ return ret;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pr_debug("%s: Setup IF1 for FM-radio.\n", __func__);
+ fmt_if1 = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_I2S;
+ ret = ab8500_audio_setup_if1(codec_dai->codec, fmt_if1, 16, 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+struct snd_soc_ops ux500_ab8500_ops[] = {
+ {
+ .hw_params = ux500_ab8500_hw_params,
+ .startup = ux500_ab8500_startup,
+ .shutdown = ux500_ab8500_shutdown,
+ }
+};
+
+int ux500_ab8500_machine_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret;
+
+ pr_debug("%s Enter.\n", __func__);
+
+ /* TODO: Add required DAPM routes to control regulators on demand */
+
+ ret = snd_soc_jack_new(codec,
+ "AB8500 Hs Status",
+ SND_JACK_HEADPHONE |
+ SND_JACK_MICROPHONE |
+ SND_JACK_HEADSET |
+ SND_JACK_LINEOUT |
+ SND_JACK_MECHANICAL |
+ SND_JACK_VIDEOOUT,
+ &jack);
+ if (ret < 0) {
+ pr_err("%s: ERROR: Failed to create Jack (ret = %d)!\n", __func__, ret);
+ return ret;
+ }
+
+ /* Add controls */
+ snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&mclk_input_control, codec));
+
+ /* Get references to clock-nodes */
+ clk_ptr_sysclk = NULL;
+ clk_ptr_ulpclk = NULL;
+ clk_ptr_intclk = NULL;
+ clk_ptr_audioclk = NULL;
+ clk_ptr_sysclk = clk_get(codec->dev, "sysclk");
+ if (IS_ERR(clk_ptr_sysclk)) {
+ pr_err("ERROR: clk_get failed (ret = %d)!", -EFAULT);
+ return -EFAULT;
+ }
+ clk_ptr_ulpclk = clk_get(codec->dev, "ulpclk");
+ if (IS_ERR(clk_ptr_sysclk)) {
+ pr_err("ERROR: clk_get failed (ret = %d)!", -EFAULT);
+ return -EFAULT;
+ }
+ clk_ptr_intclk = clk_get(codec->dev, "intclk");
+ if (IS_ERR(clk_ptr_audioclk)) {
+ pr_err("ERROR: clk_get failed (ret = %d)!", -EFAULT);
+ return -EFAULT;
+ }
+ clk_ptr_audioclk = clk_get(codec->dev, "audioclk");
+ if (IS_ERR(clk_ptr_audioclk)) {
+ pr_err("ERROR: clk_get failed (ret = %d)!", -EFAULT);
+ return -EFAULT;
+ }
+
+ /* Set intclk default parent to ulpclk */
+ ret = clk_set_parent(clk_ptr_intclk, clk_ptr_ulpclk);
+ if (ret) {
+ pr_err("%s: ERROR: Setting intclk parent to ulpclk failed (ret = %d)!",
+ __func__,
+ ret);
+ return -EFAULT;
+ }
+
+ master_clock_sel = 1;
+
+ ab8500_power_count = 0;
+
+ return 0;
+}
+
+int ux500_ab8500_soc_machine_drv_init(void)
+{
+ int status = 0;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ status = create_regulators();
+ if (status < 0) {
+ pr_err("%s: ERROR: Failed to instantiate regulators (ret = %d)!\n",
+ __func__, status);
+ return status;
+ }
+
+ return 0;
+}
+
+void ux500_ab8500_soc_machine_drv_cleanup(void)
+{
+ pr_debug("%s: Enter.\n", __func__);
+
+ regulator_bulk_free(ARRAY_SIZE(reg_info), reg_info);
+
+ if (clk_ptr_sysclk != NULL)
+ clk_put(clk_ptr_sysclk);
+ if (clk_ptr_ulpclk != NULL)
+ clk_put(clk_ptr_ulpclk);
+ if (clk_ptr_intclk != NULL)
+ clk_put(clk_ptr_intclk);
+ if (clk_ptr_audioclk != NULL)
+ clk_put(clk_ptr_audioclk);
+}
+
+/* Extended interface */
+
+void ux500_ab8500_jack_report(int value)
+{
+ if (jack.jack)
+ snd_soc_jack_report(&jack, value, 0xFF);
+}
+EXPORT_SYMBOL_GPL(ux500_ab8500_jack_report);
+
diff --git a/sound/soc/ux500/ux500_av8100.c b/sound/soc/ux500/ux500_av8100.c
new file mode 100644
index 00000000000..efb6318e1a7
--- /dev/null
+++ b/sound/soc/ux500/ux500_av8100.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <sound/soc.h>
+#include "../codecs/av8100_audio.h"
+#include "ux500_av8100.h"
+#include "ux500_msp_dai.h"
+
+static const char *stream_str(struct snd_pcm_substream *substream)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ return "Playback";
+ else
+ return "Capture";
+}
+
+static int ux500_av8100_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int channels = params_channels(params);
+ unsigned int tx_mask, fmt;
+ enum hdmi_channel_allocation hdmi_ca;
+ enum hdmi_audio_channel_count hdmi_cc;
+ struct hdmi_audio_settings as;
+ int ret;
+
+ pr_debug("%s: Enter (%s).\n", __func__, stream_str(substream));
+ pr_debug("%s: substream->pcm->name = %s.\n", __func__, substream->pcm->name);
+ pr_debug("%s: substream->pcm->id = %s.\n", __func__, substream->pcm->id);
+ pr_debug("%s: substream->name = %s.\n", __func__, substream->name);
+ pr_debug("%s: substream->number = %d.\n", __func__, substream->number);
+ pr_debug("%s: channels = %d.\n", __func__, channels);
+ pr_debug("%s: DAI-index (Codec): %d\n", __func__, codec_dai->id);
+ pr_debug("%s: DAI-index (Platform): %d\n", __func__, cpu_dai->id);
+
+ switch (channels) {
+ case 1:
+ hdmi_cc = AV8100_CODEC_CC_2CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR; /* Stereo-setup */
+ tx_mask = AV8100_CODEC_MASK_MONO;
+ break;
+ case 2:
+ hdmi_cc = AV8100_CODEC_CC_2CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR; /* Stereo */
+ tx_mask = AV8100_CODEC_MASK_STEREO;
+ break;
+ case 3:
+ hdmi_cc = AV8100_CODEC_CC_6CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR; /* 5.1-setup */
+ tx_mask = AV8100_CODEC_MASK_2DOT1;
+ break;
+ case 4:
+ hdmi_cc = AV8100_CODEC_CC_6CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR; /* 5.1-setup */
+ tx_mask = AV8100_CODEC_MASK_QUAD;
+ break;
+ case 5:
+ hdmi_cc = AV8100_CODEC_CC_6CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR; /* 5.1-setup */
+ tx_mask = AV8100_CODEC_MASK_5DOT0;
+ break;
+ case 6:
+ hdmi_cc = AV8100_CODEC_CC_6CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR; /* 5.1 */
+ tx_mask = AV8100_CODEC_MASK_5DOT1;
+ break;
+ case 7:
+ hdmi_cc = AV8100_CODEC_CC_8CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR_RLC_RRC; /* 7.1 */
+ tx_mask = AV8100_CODEC_MASK_7DOT0;
+ break;
+ case 8:
+ hdmi_cc = AV8100_CODEC_CC_8CH;
+ hdmi_ca = AV8100_CODEC_CA_FL_FR_LFE_FC_RL_RR_RLC_RRC; /* 7.1 */
+ tx_mask = AV8100_CODEC_MASK_7DOT1;
+ break;
+ default:
+ pr_err("%s: Unsupported number of channels (channels = %d)!\n",
+ __func__,
+ channels);
+ return -EINVAL;
+ }
+
+ /* Change HDMI audio-settings for codec-DAI. */
+ pr_debug("%s: Change HDMI audio-settings for codec-DAI.\n", __func__);
+ as.audio_coding_type = AV8100_CODEC_CT_IEC60958_PCM;
+ as.audio_channel_count = hdmi_cc;
+ as.sampling_frequency = AV8100_CODEC_SF_48KHZ;
+ as.sample_size = AV8100_CODEC_SS_16BIT;
+ as.channel_allocation = hdmi_ca;
+ as.level_shift_value = AV8100_CODEC_LSV_0DB;
+ as.downmix_inhibit = false;
+ ret = av8100_audio_change_hdmi_audio_settings(codec_dai, &as);
+ if (ret < 0) {
+ pr_err("%s: Unable to change HDMI audio-settings for codec-DAI "
+ "(av8100_codec_change_hdmi_audio_settings returned %d)!\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ /* Set format for codec-DAI */
+ fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM;
+ pr_debug("%s: Setting format for codec-DAI (fmt = %d).\n",
+ __func__,
+ fmt);
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ pr_err("%s: Unable to set format for codec-DAI "
+ "(snd_soc_dai_set_tdm_slot returned %d)!\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ /* Set TDM-slot for CPU-DAI */
+ pr_debug("%s: Setting TDM-slot for codec-DAI (tx_mask = %d).\n",
+ __func__,
+ tx_mask);
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_mask, 0, 16, 16);
+ if (ret < 0) {
+ pr_err("%s: Unable to set TDM-slot for codec-DAI "
+ "(snd_soc_dai_set_tdm_slot returned %d)!\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ /* Set format for CPU-DAI */
+ fmt = SND_SOC_DAIFMT_DSP_B |
+ SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_NB_IF;
+ pr_debug("%s: Setting DAI-format for Ux500-platform (fmt = %d).\n",
+ __func__,
+ fmt);
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret < 0) {
+ pr_err("%s: Unable to set DAI-format for Ux500-platform "
+ "(snd_soc_dai_set_fmt returned %d).\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ ux500_msp_dai_set_data_delay(cpu_dai, MSP_DELAY_1);
+
+ return ret;
+}
+
+struct snd_soc_ops ux500_av8100_ops[] = {
+ {
+ .hw_params = ux500_av8100_hw_params,
+ }
+};
+
diff --git a/sound/soc/ux500/ux500_av8100.h b/sound/soc/ux500/ux500_av8100.h
new file mode 100644
index 00000000000..b107b2e1be7
--- /dev/null
+++ b/sound/soc/ux500/ux500_av8100.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef UX500_AV8100_H
+#define UX500_AV8100_H
+
+extern struct snd_soc_ops ux500_av8100_ops[];
+
+#endif
diff --git a/sound/soc/ux500/ux500_cg29xx.c b/sound/soc/ux500/ux500_cg29xx.c
new file mode 100644
index 00000000000..e83a6869c5a
--- /dev/null
+++ b/sound/soc/ux500/ux500_cg29xx.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <sound/soc.h>
+#include "../codecs/cg29xx.h"
+#include "ux500_msp_dai.h"
+
+#define UX500_CG29XX_MSP_CLOCK_FREQ 18900000
+#define UX500_CG29XX_DAI_SLOT_WIDTH 16
+#define UX500_CG29XX_DAI_SLOTS 2
+#define UX500_CG29XX_DAI_ACTIVE_SLOTS 0x01
+
+int ux500_cg29xx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int channels = params_channels(params);
+ int err;
+
+ pr_debug("%s: Enter.\n", __func__);
+ pr_debug("%s: substream->pcm->name = %s.\n", __func__, substream->pcm->name);
+ pr_debug("%s: substream->pcm->id = %s.\n", __func__, substream->pcm->id);
+ pr_debug("%s: substream->name = %s.\n", __func__, substream->name);
+ pr_debug("%s: substream->number = %d.\n", __func__, substream->number);
+ pr_debug("%s: channels = %d.\n", __func__, channels);
+ pr_debug("%s: DAI-index (Codec): %d\n", __func__, codec_dai->id);
+ pr_debug("%s: DAI-index (Platform): %d\n", __func__, cpu_dai->id);
+
+ err = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS);
+
+ if (err) {
+ pr_err("%s: snd_soc_dai_set_fmt(codec) failed with %d.\n",
+ __func__,
+ err);
+ goto out_err;
+ }
+
+ err = snd_soc_dai_set_tdm_slot(codec_dai,
+ 1 << CG29XX_DAI_SLOT0_SHIFT,
+ 1 << CG29XX_DAI_SLOT0_SHIFT,
+ UX500_CG29XX_DAI_SLOTS,
+ UX500_CG29XX_DAI_SLOT_WIDTH);
+
+ if (err) {
+ pr_err("%s: cg29xx_set_tdm_slot(codec_dai) failed with %d.\n",
+ __func__,
+ err);
+ goto out_err;
+ }
+
+ err = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS |
+ SND_SOC_DAIFMT_NB_NF);
+
+ if (err) {
+ pr_err("%s: snd_soc_dai_set_fmt(cpu_dai) failed with %d.\n",
+ __func__,
+ err);
+ goto out_err;
+ }
+
+ err = snd_soc_dai_set_sysclk(cpu_dai,
+ UX500_MSP_MASTER_CLOCK,
+ UX500_CG29XX_MSP_CLOCK_FREQ,
+ 0);
+
+ if (err) {
+ pr_err("%s: snd_soc_dai_set_sysclk(cpu_dai) failed with %d.\n",
+ __func__,
+ err);
+ goto out_err;
+ }
+
+ err = snd_soc_dai_set_tdm_slot(cpu_dai,
+ UX500_CG29XX_DAI_ACTIVE_SLOTS,
+ UX500_CG29XX_DAI_ACTIVE_SLOTS,
+ UX500_CG29XX_DAI_SLOTS,
+ UX500_CG29XX_DAI_SLOT_WIDTH);
+
+ if (err) {
+ pr_err("%s: cg29xx_set_tdm_slot(cpu_dai) failed with %d.\n",
+ __func__,
+ err);
+ goto out_err;
+ }
+
+out_err:
+ return err;
+}
+
+struct snd_soc_ops ux500_cg29xx_ops[] = {
+ {
+ .hw_params = ux500_cg29xx_hw_params,
+ }
+};
+
diff --git a/sound/soc/ux500/ux500_cg29xx.h b/sound/soc/ux500/ux500_cg29xx.h
new file mode 100644
index 00000000000..49a8c3e0478
--- /dev/null
+++ b/sound/soc/ux500/ux500_cg29xx.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef UX500_CG29XX_H
+#define UX500_CG29XX_H
+
+extern struct snd_soc_ops ux500_cg29xx_ops[];
+
+#endif
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
new file mode 100644
index 00000000000..53f3982343b
--- /dev/null
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <linux/slab.h>
+#include <asm/dma.h>
+#include <linux/bitops.h>
+#include <mach/hardware.h>
+#include <mach/msp.h>
+#include <linux/i2s/i2s.h>
+#include <asm/mach-types.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include "ux500_msp_dai.h"
+#include "ux500_pcm.h"
+
+static struct ux500_platform_drvdata platform_drvdata[UX500_NBR_OF_DAI] = {
+ {
+ .i2s = NULL,
+ .fmt = 0,
+ .slots = 1,
+ .tx_mask = 0x01,
+ .rx_mask = 0x01,
+ .slot_width = 16,
+ .playback_active = false,
+ .capture_active = false,
+ .configured = 0,
+ .data_delay = MSP_DELAY_0,
+ .master_clk = UX500_MSP_U8500_INTERNAL_CLOCK_FREQ,
+ },
+ {
+ .i2s = NULL,
+ .fmt = 0,
+ .slots = 1,
+ .tx_mask = 0x01,
+ .rx_mask = 0x01,
+ .slot_width = 16,
+ .playback_active = false,
+ .capture_active = false,
+ .configured = 0,
+ .data_delay = MSP_DELAY_0,
+ .master_clk = UX500_MSP_U8500_INTERNAL_CLOCK_FREQ,
+ },
+ {
+ .i2s = NULL,
+ .fmt = 0,
+ .slots = 1,
+ .tx_mask = 0x01,
+ .rx_mask = 0x01,
+ .slot_width = 16,
+ .playback_active = false,
+ .capture_active = false,
+ .configured = 0,
+ .data_delay = MSP_DELAY_0,
+ .master_clk = UX500_MSP_U8500_INTERNAL_CLOCK_FREQ,
+ },
+ {
+ .i2s = NULL,
+ .fmt = 0,
+ .slots = 1,
+ .tx_mask = 0x01,
+ .rx_mask = 0x01,
+ .slot_width = 16,
+ .playback_active = false,
+ .capture_active = false,
+ .configured = 0,
+ .data_delay = MSP_DELAY_0,
+ .master_clk = UX500_MSP_U8500_INTERNAL_CLOCK_FREQ,
+ },
+};
+
+bool ux500_msp_dai_i2s_get_underrun_status(int dai_idx)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai_idx];
+ int status = i2s_hw_status(drvdata->i2s->controller);
+ return (bool)(status & TRANSMIT_UNDERRUN_ERR_INT);
+}
+
+dma_addr_t ux500_msp_dai_i2s_get_pointer(int dai_idx, int stream_id)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai_idx];
+ return i2s_get_pointer(drvdata->i2s->controller,
+ (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
+ I2S_DIRECTION_TX :
+ I2S_DIRECTION_RX);
+}
+
+int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
+ int period_cnt,
+ size_t period_len,
+ int dai_idx,
+ int stream_id)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai_idx];
+ struct i2s_message message;
+ struct i2s_device *i2s_dev;
+ int ret = 0;
+ bool playback_req_valid =
+ (drvdata->playback_active &&
+ stream_id == SNDRV_PCM_STREAM_PLAYBACK);
+ bool capture_req_valid =
+ (drvdata->capture_active &&
+ stream_id == SNDRV_PCM_STREAM_CAPTURE);
+
+ pr_debug("%s: Enter (MSP Index: %u, period-cnt: %u, period-len: %u).\n",
+ __func__,
+ dai_idx,
+ period_cnt,
+ period_len);
+
+ if (!playback_req_valid && !capture_req_valid) {
+ pr_err("%s: The I2S controller is not available."
+ "MSP index:%d\n",
+ __func__,
+ dai_idx);
+ return ret;
+ }
+
+ i2s_dev = drvdata->i2s;
+
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_CYCLIC_DMA;
+ message.i2s_direction = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
+ I2S_DIRECTION_TX :
+ I2S_DIRECTION_RX;
+ message.buf_addr = dma_addr;
+ message.buf_len = period_cnt * period_len;
+ message.period_len = period_len;
+
+ ret = i2s_transfer(i2s_dev->controller, &message);
+ if (ret < 0) {
+ pr_err("%s: Error: i2s_transfer failed. MSP index: %d\n",
+ __func__,
+ dai_idx);
+ }
+
+ return ret;
+}
+
+static const char *stream_str(struct snd_pcm_substream *substream)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ return "Playback";
+ else
+ return "Capture";
+}
+
+static int ux500_msp_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+ bool mode_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+
+ pr_debug("%s: MSP %d (%s): Enter.\n", __func__, dai->id, stream_str(substream));
+
+ if ((mode_playback && drvdata->playback_active) ||
+ (!mode_playback && drvdata->capture_active)) {
+ pr_err("%s: Error: MSP %d (%s): Stream already active.\n",
+ __func__,
+ dai->id,
+ stream_str(substream));
+ return -EBUSY;
+ }
+
+ if (mode_playback)
+ drvdata->playback_active = true;
+ else
+ drvdata->capture_active = true;
+
+ return 0;
+}
+
+static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+ bool mode_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+
+ pr_debug("%s: MSP %d (%s): Enter.\n", __func__, dai->id, stream_str(substream));
+
+ if (drvdata == NULL)
+ return;
+
+ if (mode_playback)
+ drvdata->playback_active = false;
+ else
+ drvdata->capture_active = false;
+
+ if (i2s_cleanup(drvdata->i2s->controller,
+ mode_playback ? DISABLE_TRANSMIT : DISABLE_RECEIVE)) {
+ pr_err("%s: Error: MSP %d (%s): Unable to close i2s.\n",
+ __func__,
+ dai->id,
+ stream_str(substream));
+ }
+
+ if (mode_playback)
+ drvdata->configured &= ~PLAYBACK_CONFIGURED;
+ else
+ drvdata->configured &= ~CAPTURE_CONFIGURED;
+}
+
+static void ux500_msp_dai_setup_multichannel(struct ux500_platform_drvdata *private,
+ struct msp_config *msp_config)
+{
+ struct msp_multichannel_config *multi = &msp_config->multichannel_config;
+
+ if (private->slots > 1) {
+ msp_config->multichannel_configured = 1;
+
+ multi->tx_multichannel_enable = true;
+ multi->rx_multichannel_enable = true;
+ multi->rx_comparison_enable_mode = MSP_COMPARISON_DISABLED;
+
+ multi->tx_channel_0_enable = private->tx_mask;
+ multi->tx_channel_1_enable = 0;
+ multi->tx_channel_2_enable = 0;
+ multi->tx_channel_3_enable = 0;
+
+ multi->rx_channel_0_enable = private->rx_mask;
+ multi->rx_channel_1_enable = 0;
+ multi->rx_channel_2_enable = 0;
+ multi->rx_channel_3_enable = 0;
+
+ pr_debug("%s: Multichannel enabled."
+ "Slots: %d TX: %u RX: %u\n",
+ __func__,
+ private->slots,
+ multi->tx_channel_0_enable,
+ multi->rx_channel_0_enable);
+ }
+}
+
+static void ux500_msp_dai_setup_frameper(struct ux500_platform_drvdata *private,
+ unsigned int rate,
+ struct msp_protocol_desc *prot_desc)
+{
+ switch (private->slots) {
+ default:
+ case 1:
+ switch (rate) {
+ case 8000:
+ prot_desc->frame_period =
+ FRAME_PER_SINGLE_SLOT_8_KHZ;
+ break;
+ case 16000:
+ prot_desc->frame_period =
+ FRAME_PER_SINGLE_SLOT_16_KHZ;
+ break;
+ case 44100:
+ prot_desc->frame_period =
+ FRAME_PER_SINGLE_SLOT_44_1_KHZ;
+ break;
+ case 48000:
+ default:
+ prot_desc->frame_period =
+ FRAME_PER_SINGLE_SLOT_48_KHZ;
+ break;
+ }
+ break;
+
+ case 2:
+ prot_desc->frame_period = FRAME_PER_2_SLOTS;
+ break;
+
+ case 8:
+ prot_desc->frame_period =
+ FRAME_PER_8_SLOTS;
+ break;
+
+ case 16:
+ prot_desc->frame_period =
+ FRAME_PER_16_SLOTS;
+ break;
+ }
+
+ prot_desc->total_clocks_for_one_frame =
+ prot_desc->frame_period+1;
+
+ pr_debug("%s: Total clocks per frame: %u\n",
+ __func__,
+ prot_desc->total_clocks_for_one_frame);
+}
+
+static void ux500_msp_dai_setup_framing_pcm(struct ux500_platform_drvdata *private,
+ unsigned int rate,
+ struct msp_protocol_desc *prot_desc)
+{
+ u32 frame_length = MSP_FRAME_LENGTH_1;
+ prot_desc->frame_width = 0;
+
+ switch (private->slots) {
+ default:
+ case 1:
+ frame_length = MSP_FRAME_LENGTH_1;
+ break;
+
+ case 2:
+ frame_length = MSP_FRAME_LENGTH_2;
+ break;
+
+ case 8:
+ frame_length = MSP_FRAME_LENGTH_8;
+ break;
+
+ case 16:
+ frame_length = MSP_FRAME_LENGTH_16;
+ break;
+ }
+
+ prot_desc->tx_frame_length_1 = frame_length;
+ prot_desc->rx_frame_length_1 = frame_length;
+ prot_desc->tx_frame_length_2 = frame_length;
+ prot_desc->rx_frame_length_2 = frame_length;
+
+ prot_desc->tx_element_length_1 = MSP_ELEM_LENGTH_16;
+ prot_desc->rx_element_length_1 = MSP_ELEM_LENGTH_16;
+ prot_desc->tx_element_length_2 = MSP_ELEM_LENGTH_16;
+ prot_desc->rx_element_length_2 = MSP_ELEM_LENGTH_16;
+
+ ux500_msp_dai_setup_frameper(private, rate, prot_desc);
+}
+
+static void ux500_msp_dai_setup_clocking(unsigned int fmt,
+ struct msp_config *msp_config)
+{
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ default:
+ case SND_SOC_DAIFMT_NB_NF:
+ msp_config->tx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL(MSP_FRAME_SYNC_POL_ACTIVE_HIGH);
+ msp_config->rx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH << RFSPOL_SHIFT;
+ break;
+
+ case SND_SOC_DAIFMT_NB_IF:
+ msp_config->tx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL(MSP_FRAME_SYNC_POL_ACTIVE_LOW);
+ msp_config->rx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL_ACTIVE_LOW << RFSPOL_SHIFT;
+ break;
+ }
+
+ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) {
+ pr_debug("%s: Codec is MASTER.\n",
+ __func__);
+
+ msp_config->rx_frame_sync_sel = 0;
+ msp_config->tx_frame_sync_sel = 1 << TFSSEL_SHIFT;
+ msp_config->tx_clock_sel = 0;
+ msp_config->rx_clock_sel = 0;
+ msp_config->srg_clock_sel = 0x2 << SCKSEL_SHIFT;
+ } else {
+ pr_debug("%s: Codec is SLAVE.\n",
+ __func__);
+
+ msp_config->tx_clock_sel = TX_CLK_SEL_SRG;
+ msp_config->tx_frame_sync_sel = TX_SYNC_SRG_PROG;
+ msp_config->rx_clock_sel = RX_CLK_SEL_SRG;
+ msp_config->rx_frame_sync_sel = RX_SYNC_SRG;
+ msp_config->srg_clock_sel = 1 << SCKSEL_SHIFT;
+ }
+}
+
+static void ux500_msp_dai_compile_prot_desc_pcm(unsigned int fmt,
+ struct msp_protocol_desc *prot_desc)
+{
+ prot_desc->rx_phase_mode = MSP_SINGLE_PHASE;
+ prot_desc->tx_phase_mode = MSP_SINGLE_PHASE;
+ prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE;
+ prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE;
+ prot_desc->rx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+ prot_desc->tx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+
+ if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) {
+ pr_debug("%s: DSP_A.\n",
+ __func__);
+ prot_desc->tx_clock_pol = MSP_FALLING_EDGE;
+ prot_desc->rx_clock_pol = MSP_FALLING_EDGE;
+ } else {
+ pr_debug("%s: DSP_B.\n",
+ __func__);
+ prot_desc->tx_clock_pol = MSP_RISING_EDGE;
+ prot_desc->rx_clock_pol = MSP_RISING_EDGE;
+ }
+
+ prot_desc->rx_half_word_swap = MSP_HWS_NO_SWAP;
+ prot_desc->tx_half_word_swap = MSP_HWS_NO_SWAP;
+ prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR;
+ prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR;
+ prot_desc->spi_clk_mode = MSP_SPI_CLOCK_MODE_NON_SPI;
+ prot_desc->spi_burst_mode = MSP_SPI_BURST_MODE_DISABLE;
+ prot_desc->frame_sync_ignore = MSP_FRAME_SYNC_IGNORE;
+}
+
+static void ux500_msp_dai_compile_prot_desc_i2s(struct msp_protocol_desc *prot_desc)
+{
+ prot_desc->rx_phase_mode = MSP_DUAL_PHASE;
+ prot_desc->tx_phase_mode = MSP_DUAL_PHASE;
+ prot_desc->rx_phase2_start_mode =
+ MSP_PHASE2_START_MODE_FRAME_SYNC;
+ prot_desc->tx_phase2_start_mode =
+ MSP_PHASE2_START_MODE_FRAME_SYNC;
+ prot_desc->rx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+ prot_desc->tx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+
+ prot_desc->rx_frame_length_1 = MSP_FRAME_LENGTH_1;
+ prot_desc->rx_frame_length_2 = MSP_FRAME_LENGTH_1;
+ prot_desc->tx_frame_length_1 = MSP_FRAME_LENGTH_1;
+ prot_desc->tx_frame_length_2 = MSP_FRAME_LENGTH_1;
+ prot_desc->rx_element_length_1 = MSP_ELEM_LENGTH_16;
+ prot_desc->rx_element_length_2 = MSP_ELEM_LENGTH_16;
+ prot_desc->tx_element_length_1 = MSP_ELEM_LENGTH_16;
+ prot_desc->tx_element_length_2 = MSP_ELEM_LENGTH_16;
+
+ prot_desc->rx_clock_pol = MSP_RISING_EDGE;
+ prot_desc->tx_clock_pol = MSP_RISING_EDGE;
+
+ prot_desc->tx_half_word_swap = MSP_HWS_NO_SWAP;
+ prot_desc->rx_half_word_swap = MSP_HWS_NO_SWAP;
+ prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR;
+ prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR;
+ prot_desc->spi_clk_mode = MSP_SPI_CLOCK_MODE_NON_SPI;
+ prot_desc->spi_burst_mode = MSP_SPI_BURST_MODE_DISABLE;
+ prot_desc->frame_sync_ignore = MSP_FRAME_SYNC_IGNORE;
+}
+
+static void ux500_msp_dai_compile_msp_config(struct snd_pcm_substream *substream,
+ struct ux500_platform_drvdata *private,
+ unsigned int rate,
+ struct msp_config *msp_config)
+{
+ struct msp_protocol_desc *prot_desc = &msp_config->protocol_desc;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned int fmt = private->fmt;
+
+ memset(msp_config, 0, sizeof(*msp_config));
+
+ if (machine_is_u5500())
+ msp_config->input_clock_freq = UX500_MSP_U5500_INTERNAL_CLOCK_FREQ;
+ else
+ msp_config->input_clock_freq = private->master_clk;
+
+ msp_config->tx_fifo_config = TX_FIFO_ENABLE;
+ msp_config->rx_fifo_config = RX_FIFO_ENABLE;
+ msp_config->spi_clk_mode = SPI_CLK_MODE_NORMAL;
+ msp_config->spi_burst_mode = 0;
+ msp_config->handler = ux500_pcm_dma_eot_handler;
+ msp_config->tx_callback_data =
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ substream : NULL;
+ msp_config->rx_callback_data =
+ substream->stream == SNDRV_PCM_STREAM_CAPTURE ?
+ substream : NULL;
+ msp_config->def_elem_len = 1;
+ msp_config->direction =
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ MSP_TRANSMIT_MODE : MSP_RECEIVE_MODE;
+ msp_config->data_size = MSP_DATA_BITS_32;
+ msp_config->work_mode = MSP_DMA_MODE;
+ msp_config->frame_freq = rate;
+
+ printk(KERN_INFO "%s: input_clock_freq = %u, frame_freq = %u.\n",
+ __func__, msp_config->input_clock_freq, msp_config->frame_freq);
+ /* To avoid division by zero in I2S-driver (i2s_setup) */
+ prot_desc->total_clocks_for_one_frame = 1;
+
+ prot_desc->rx_data_delay = private->data_delay;
+ prot_desc->tx_data_delay = private->data_delay;
+
+ pr_debug("%s: rate: %u channels: %d.\n",
+ __func__,
+ rate,
+ runtime->channels);
+ switch (fmt &
+ (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
+
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
+ pr_debug("%s: SND_SOC_DAIFMT_I2S.\n",
+ __func__);
+
+ msp_config->default_protocol_desc = 1;
+ msp_config->protocol = MSP_I2S_PROTOCOL;
+ break;
+
+ default:
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
+ pr_debug("%s: SND_SOC_DAIFMT_I2S.\n",
+ __func__);
+
+ msp_config->data_size = MSP_DATA_BITS_16;
+ msp_config->protocol = MSP_I2S_PROTOCOL;
+
+ ux500_msp_dai_compile_prot_desc_i2s(prot_desc);
+ break;
+
+ case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
+ case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS:
+ case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM:
+ pr_debug("%s: PCM format.\n",
+ __func__);
+ msp_config->data_size = MSP_DATA_BITS_16;
+ msp_config->protocol = MSP_PCM_PROTOCOL;
+
+ ux500_msp_dai_compile_prot_desc_pcm(fmt, prot_desc);
+ ux500_msp_dai_setup_multichannel(private, msp_config);
+ ux500_msp_dai_setup_framing_pcm(private, rate, prot_desc);
+ break;
+ }
+
+ ux500_msp_dai_setup_clocking(fmt, msp_config);
+}
+
+static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct msp_config msp_config;
+ bool mode_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+
+ pr_debug("%s: MSP %d (%s): Enter.\n", __func__, dai->id, stream_str(substream));
+
+ /* If already configured -> not errors reported */
+ if (mode_playback) {
+ if ((drvdata->configured & PLAYBACK_CONFIGURED) &&
+ (drvdata->playback_active))
+ goto cleanup;
+ } else {
+ if ((drvdata->configured & CAPTURE_CONFIGURED) &&
+ (drvdata->capture_active))
+ goto cleanup;
+ }
+
+ pr_debug("%s: Setup dai (Rate: %u).\n", __func__, runtime->rate);
+ ux500_msp_dai_compile_msp_config(substream,
+ drvdata,
+ runtime->rate,
+ &msp_config);
+
+ ret = i2s_setup(drvdata->i2s->controller, &msp_config);
+ if (ret < 0) {
+ pr_err("%s: Error: i2s_setup failed (ret = %d)!\n", __func__, ret);
+ goto cleanup;
+ }
+
+ drvdata->configured |= mode_playback ?
+ PLAYBACK_CONFIGURED : CAPTURE_CONFIGURED;
+
+cleanup:
+ return ret;
+}
+
+static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ unsigned int mask, slots_active;
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+
+ pr_debug("%s: MSP %d (%s): Enter.\n",
+ __func__,
+ dai->id,
+ stream_str(substream));
+
+ switch (drvdata->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ if (params_channels(params) != 2) {
+ pr_err("%s: Error: I2S requires channels = 2 "
+ "(channels = %d)!\n",
+ __func__,
+ params_channels(params));
+ return -EINVAL;
+ }
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ case SND_SOC_DAIFMT_DSP_A:
+
+ mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ drvdata->tx_mask :
+ drvdata->rx_mask;
+
+ slots_active = hweight32(mask);
+
+ pr_debug("TDM slots active: %d", slots_active);
+
+ if (params_channels(params) != slots_active) {
+ pr_err("%s: Error: PCM TDM format requires channels "
+ "to match active slots "
+ "(channels = %d, active slots = %d)!\n",
+ __func__,
+ params_channels(params),
+ slots_active);
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int ux500_msp_dai_set_data_delay(struct snd_soc_dai *dai, int delay)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+
+ pr_debug("%s: MSP %d: Enter.\n", __func__, dai->id);
+
+ switch (delay) {
+ case MSP_DELAY_0:
+ case MSP_DELAY_1:
+ case MSP_DELAY_2:
+ case MSP_DELAY_3:
+ break;
+ default:
+ goto unsupported_delay;
+ }
+
+ drvdata->data_delay = delay;
+ return 0;
+
+unsupported_delay:
+ pr_err("%s: MSP %d: Error: Unsupported DAI delay (%d)!\n",
+ __func__,
+ dai->id,
+ delay);
+ return -EINVAL;
+}
+
+static int ux500_msp_dai_set_dai_fmt(struct snd_soc_dai *dai,
+ unsigned int fmt)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+
+ pr_debug("%s: MSP %d: Enter.\n", __func__, dai->id);
+
+ switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS:
+ case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
+ case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
+ break;
+
+ default:
+ goto unsupported_format;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+
+ default:
+ goto unsupported_format;
+ }
+
+ drvdata->fmt = fmt;
+ return 0;
+
+unsupported_format:
+ pr_err("%s: MSP %d: Error: Unsupported DAI format (0x%x)!\n",
+ __func__,
+ dai->id,
+ fmt);
+ return -EINVAL;
+}
+
+static int ux500_msp_dai_set_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask,
+ unsigned int rx_mask,
+ int slots,
+ int slot_width)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+ unsigned int cap;
+
+ if (!(slots == 1 || slots == 2 || slots == 8 || slots == 16)) {
+ pr_err("%s: Error: Unsupported slots (%d)! "
+ "Supported values are 1/2/8/16.\n",
+ __func__,
+ slots);
+ return -EINVAL;
+ }
+ drvdata->slots = slots;
+
+ if (!(slot_width == 16)) {
+ pr_err("%s: Error: Unsupported slots_width (%d)!. "
+ "Supported value is 16.\n",
+ __func__,
+ slot_width);
+ return -EINVAL;
+ }
+ drvdata->slot_width = slot_width;
+
+ switch (slots) {
+ default:
+ case 1:
+ cap = 0x01;
+ break;
+ case 2:
+ cap = 0x03;
+ break;
+ case 8:
+ cap = 0xFF;
+ break;
+ case 16:
+ cap = 0xFFFF;
+ break;
+ }
+
+ drvdata->tx_mask = tx_mask & cap;
+ drvdata->rx_mask = rx_mask & cap;
+
+ return 0;
+}
+
+static int ux500_msp_dai_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id,
+ unsigned int freq,
+ int dir)
+{
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+
+ pr_debug("%s: MSP %d: Enter. Clk id: %d, freq: %u.\n",
+ __func__,
+ dai->id,
+ clk_id,
+ freq);
+
+ switch (clk_id) {
+ case UX500_MSP_MASTER_CLOCK:
+ drvdata->master_clk = freq;
+ break;
+
+ default:
+ pr_err("%s: MSP %d: Invalid clkid: %d.\n",
+ __func__,
+ dai->id,
+ clk_id);
+ }
+
+ return 0;
+}
+
+static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd,
+ struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id];
+
+ pr_debug("%s: MSP %d (%s): Enter (chip_select = %d, cmd = %d).\n",
+ __func__,
+ dai->id,
+ stream_str(substream),
+ (int)drvdata->i2s->chip_select,
+ cmd);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ret = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = {
+ {
+ .name = "ux500-msp.0",
+ .id = 0,
+ .suspend = NULL,
+ .resume = NULL,
+ .playback = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .capture = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .set_sysclk = ux500_msp_dai_set_dai_sysclk,
+ .set_fmt = ux500_msp_dai_set_dai_fmt,
+ .set_tdm_slot = ux500_msp_dai_set_tdm_slot,
+ .startup = ux500_msp_dai_startup,
+ .shutdown = ux500_msp_dai_shutdown,
+ .prepare = ux500_msp_dai_prepare,
+ .trigger = ux500_msp_dai_trigger,
+ .hw_params = ux500_msp_dai_hw_params,
+ }
+ },
+ },
+ {
+ .name = "ux500-msp.1",
+ .id = 1,
+ .suspend = NULL,
+ .resume = NULL,
+ .playback = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .capture = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .set_sysclk = ux500_msp_dai_set_dai_sysclk,
+ .set_fmt = ux500_msp_dai_set_dai_fmt,
+ .set_tdm_slot = ux500_msp_dai_set_tdm_slot,
+ .startup = ux500_msp_dai_startup,
+ .shutdown = ux500_msp_dai_shutdown,
+ .prepare = ux500_msp_dai_prepare,
+ .trigger = ux500_msp_dai_trigger,
+ .hw_params = ux500_msp_dai_hw_params,
+ }
+ },
+ },
+ {
+ .name = "ux500-msp.2",
+ .id = 2,
+ .suspend = NULL,
+ .resume = NULL,
+ .playback = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .capture = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .set_sysclk = ux500_msp_dai_set_dai_sysclk,
+ .set_fmt = ux500_msp_dai_set_dai_fmt,
+ .set_tdm_slot = ux500_msp_dai_set_tdm_slot,
+ .startup = ux500_msp_dai_startup,
+ .shutdown = ux500_msp_dai_shutdown,
+ .prepare = ux500_msp_dai_prepare,
+ .trigger = ux500_msp_dai_trigger,
+ .hw_params = ux500_msp_dai_hw_params,
+ }
+ },
+ },
+ {
+ .name = "ux500-msp.3",
+ .id = 3,
+ .suspend = NULL,
+ .resume = NULL,
+ .playback = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .capture = {
+ .channels_min = UX500_MSP_MIN_CHANNELS,
+ .channels_max = UX500_MSP_MAX_CHANNELS,
+ .rates = UX500_I2S_RATES,
+ .formats = UX500_I2S_FORMATS,
+ },
+ .ops = (struct snd_soc_dai_ops[]) {
+ {
+ .set_sysclk = ux500_msp_dai_set_dai_sysclk,
+ .set_fmt = ux500_msp_dai_set_dai_fmt,
+ .set_tdm_slot = ux500_msp_dai_set_tdm_slot,
+ .startup = ux500_msp_dai_startup,
+ .shutdown = ux500_msp_dai_shutdown,
+ .prepare = ux500_msp_dai_prepare,
+ .trigger = ux500_msp_dai_trigger,
+ .hw_params = ux500_msp_dai_hw_params,
+ }
+ },
+ },
+};
+EXPORT_SYMBOL(ux500_msp_dai_drv);
+
+static int ux500_msp_drv_probe(struct i2s_device *i2s_dev)
+{
+ int ret = 0;
+ struct ux500_platform_drvdata *drvdata;
+ int msp_idx = i2s_dev->chip_select;
+
+ pr_info("%s: Enter (idx: %d, dev-name: %s, drv-name: %s).\n",
+ __func__,
+ msp_idx,
+ dev_name(&i2s_dev->dev),
+ i2s_dev->dev.driver->name);
+
+ drvdata = &platform_drvdata[msp_idx];
+ drvdata->i2s = i2s_dev;
+
+ try_module_get(i2s_dev->controller->dev.parent->driver->owner);
+ i2s_set_drvdata(i2s_dev, drvdata);
+
+ pr_debug("%s: Register MSP %d.\n", __func__, msp_idx);
+ ret = snd_soc_register_dai(&i2s_dev->dev, &ux500_msp_dai_drv[msp_idx]);
+ if (ret < 0) {
+ pr_err("Error: %s: Failed to register MSP %d.\n", __func__, msp_idx);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int ux500_msp_drv_remove(struct i2s_device *i2s_dev)
+{
+ struct ux500_platform_drvdata *drvdata = i2s_get_drvdata(i2s_dev);
+ int msp_idx = i2s_dev->chip_select;
+
+ pr_info("%s: Enter (idx: %d, dev-name: %s, drv-name: %s).\n",
+ __func__,
+ msp_idx,
+ dev_name(&i2s_dev->dev),
+ i2s_dev->dev.driver->name);
+
+ drvdata->i2s = NULL;
+ i2s_set_drvdata(i2s_dev, NULL);
+
+ pr_debug("%s: Calling module_put.\n", __func__);
+ module_put(i2s_dev->controller->dev.parent->driver->owner);
+
+ pr_debug("%s: Unregister ux500-pcm SoC platform driver.\n", __func__);
+ snd_soc_unregister_dais(&i2s_dev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
+
+ return 0;
+}
+
+static const struct i2s_device_id dev_id_table[] = {
+ { "i2s_device.0", 0, 0 },
+ { "i2s_device.1", 1, 0 },
+ { "i2s_device.2", 2, 0 },
+ { "i2s_device.3", 3, 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2s, dev_id_table);
+
+static struct i2s_driver i2sdrv_i2s = {
+ .driver = {
+ .name = "i2s",
+ .owner = THIS_MODULE,
+ },
+ .probe = ux500_msp_drv_probe,
+ .remove = __devexit_p(ux500_msp_drv_remove),
+ .id_table = dev_id_table,
+};
+
+static int __init ux500_msp_init(void)
+{
+ return i2s_register_driver(&i2sdrv_i2s);
+}
+
+static void __exit ux500_msp_exit(void)
+{
+ i2s_unregister_driver(&i2sdrv_i2s);
+}
+
+module_init(ux500_msp_init);
+module_exit(ux500_msp_exit);
+
+MODULE_LICENSE("GPLv2");
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
new file mode 100644
index 00000000000..64a23506bca
--- /dev/null
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#ifndef UX500_msp_dai_H
+#define UX500_msp_dai_H
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/i2s/i2s.h>
+#include <mach/msp.h>
+
+#define UX500_NBR_OF_DAI 4
+
+#define UX500_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
+ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+
+#define UX500_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+
+#define FRAME_PER_SINGLE_SLOT_8_KHZ 31
+#define FRAME_PER_SINGLE_SLOT_16_KHZ 124
+#define FRAME_PER_SINGLE_SLOT_44_1_KHZ 63
+#define FRAME_PER_SINGLE_SLOT_48_KHZ 49
+#define FRAME_PER_2_SLOTS 31
+#define FRAME_PER_8_SLOTS 138
+#define FRAME_PER_16_SLOTS 277
+
+#define UX500_MSP_U5500_INTERNAL_CLOCK_FREQ 13000000
+#define UX500_MSP_U8500_INTERNAL_CLOCK_FREQ 40000000
+
+#define UX500_MSP_MIN_CHANNELS 1
+#define UX500_MSP_MAX_CHANNELS 8
+
+#define PLAYBACK_CONFIGURED 1
+#define CAPTURE_CONFIGURED 2
+
+enum ux500_msp_clock_id {
+ UX500_MSP_MASTER_CLOCK,
+};
+
+struct ux500_platform_drvdata {
+ struct i2s_device *i2s;
+ unsigned int fmt;
+ unsigned int tx_mask;
+ unsigned int rx_mask;
+ int slots;
+ int slot_width;
+ bool playback_active;
+ bool capture_active;
+ u8 configured;
+ int data_delay;
+ unsigned int master_clk;
+};
+
+extern struct snd_soc_dai ux500_msp_dai[UX500_NBR_OF_DAI];
+
+bool ux500_msp_dai_i2s_get_underrun_status(int dai_idx);
+dma_addr_t ux500_msp_dai_i2s_get_pointer(int dai_idx, int stream_id);
+int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
+ int perod_cnt,
+ size_t period_len,
+ int dai_idx,
+ int stream_id);
+int ux500_msp_dai_i2s_send_data(void *data, size_t bytes, int dai_idx);
+int ux500_msp_dai_i2s_receive_data(void *data, size_t bytes, int dai_idx);
+
+int ux500_msp_dai_set_data_delay(struct snd_soc_dai *dai, int delay);
+
+#endif
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
new file mode 100644
index 00000000000..ee953f1b5e5
--- /dev/null
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+#include <asm/page.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "ux500_pcm.h"
+#include "ux500_msp_dai.h"
+
+static struct snd_pcm_hardware ux500_pcm_hw_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_PAUSE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE |
+ SNDRV_PCM_FMTBIT_U16_BE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
+ .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
+ .channels_min = UX500_PLATFORM_MIN_CHANNELS,
+ .channels_max = UX500_PLATFORM_MAX_CHANNELS,
+ .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
+ .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
+ .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
+ .periods_min = UX500_PLATFORM_PERIODS_MIN,
+ .periods_max = UX500_PLATFORM_PERIODS_MAX,
+};
+
+static struct snd_pcm_hardware ux500_pcm_hw_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_PAUSE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE |
+ SNDRV_PCM_FMTBIT_U16_BE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
+ .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
+ .channels_min = UX500_PLATFORM_MIN_CHANNELS,
+ .channels_max = UX500_PLATFORM_MAX_CHANNELS,
+ .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
+ .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
+ .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
+ .periods_min = UX500_PLATFORM_PERIODS_MIN,
+ .periods_max = UX500_PLATFORM_PERIODS_MAX,
+};
+
+static const char *stream_str(struct snd_pcm_substream *substream)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ return "Playback";
+ else
+ return "Capture";
+}
+
+static void ux500_pcm_dma_hw_free(struct device *dev,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_dma_buffer *buf = runtime->dma_buffer_p;
+
+ if (runtime->dma_area == NULL)
+ return;
+
+ if (buf != &substream->dma_buffer) {
+ dma_free_coherent(
+ buf->dev.dev,
+ buf->bytes,
+ buf->area,
+ buf->addr);
+ kfree(runtime->dma_buffer_p);
+ }
+
+ snd_pcm_set_runtime_buffer(substream, NULL);
+}
+
+void ux500_pcm_dma_eot_handler(void *data)
+{
+ struct snd_pcm_substream *substream = data;
+ struct snd_pcm_runtime *runtime;
+ struct ux500_pcm_private *private;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *dai = rtd->cpu_dai;
+
+ pr_debug("%s: MSP %d (%s): Enter.\n", __func__, dai->id, stream_str(substream));
+
+ if (substream) {
+ runtime = substream->runtime;
+ private = substream->runtime->private_data;
+
+ if (ux500_msp_dai_i2s_get_underrun_status(private->msp_id)) {
+ private->no_of_underruns++;
+ pr_debug("%s: Nr of underruns (%d)\n", __func__,
+ private->no_of_underruns);
+ }
+
+ /* calc the offset in the circular buffer */
+ private->offset += frames_to_bytes(runtime,
+ runtime->period_size);
+ private->offset %= frames_to_bytes(runtime,
+ runtime->period_size) * runtime->periods;
+
+ snd_pcm_period_elapsed(substream);
+ }
+}
+EXPORT_SYMBOL(ux500_pcm_dma_eot_handler);
+
+static int ux500_pcm_open(struct snd_pcm_substream *substream)
+{
+ int stream_id = substream->pstr->stream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct ux500_pcm_private *private;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *dai = rtd->cpu_dai;
+ int ret;
+
+ pr_debug("%s: MSP %d (%s): Enter.\n", __func__, dai->id, stream_str(substream));
+
+ pr_debug("%s: Set runtime hwparams.\n", __func__);
+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
+ snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_playback);
+ else
+ snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_capture);
+
+ /* ensure that buffer size is a multiple of period size */
+ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ pr_err("%s: Error: snd_pcm_hw_constraints failed (%d)\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ pr_debug("%s: Init runtime private data.\n", __func__);
+ private = kzalloc(sizeof(struct ux500_pcm_private), GFP_KERNEL);
+ if (private == NULL)
+ return -ENOMEM;
+ private->msp_id = dai->id;
+ runtime->private_data = private;
+
+ pr_debug("%s: Set hw-struct for %s.\n", __func__, stream_str(substream));
+ runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
+ ux500_pcm_hw_playback : ux500_pcm_hw_capture;
+
+ return 0;
+}
+
+static int ux500_pcm_close(struct snd_pcm_substream *substream)
+{
+ struct ux500_pcm_private *private = substream->runtime->private_data;
+
+ pr_debug("%s: Enter\n", __func__);
+
+ kfree(private);
+
+ return 0;
+}
+
+static int ux500_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_dma_buffer *buf = runtime->dma_buffer_p;
+ int ret = 0;
+ int size;
+
+ pr_debug("%s: Enter\n", __func__);
+
+ size = params_buffer_bytes(hw_params);
+
+ if (buf) {
+ if (buf->bytes >= size)
+ goto out;
+ ux500_pcm_dma_hw_free(NULL, substream);
+ }
+
+ if (substream->dma_buffer.area != NULL &&
+ substream->dma_buffer.bytes >= size) {
+ buf = &substream->dma_buffer;
+ } else {
+ buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
+ if (!buf)
+ goto nomem;
+
+ buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ buf->dev.dev = NULL;
+ buf->area = dma_alloc_coherent(
+ NULL,
+ size,
+ &buf->addr,
+ GFP_KERNEL);
+ buf->bytes = size;
+ buf->private_data = NULL;
+
+ if (!buf->area)
+ goto free;
+ }
+ snd_pcm_set_runtime_buffer(substream, buf);
+ ret = 1;
+ out:
+ runtime->dma_bytes = size;
+ return ret;
+
+ free:
+ kfree(buf);
+ nomem:
+ return -ENOMEM;
+}
+
+static int ux500_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s: Enter\n", __func__);
+
+ ux500_pcm_dma_hw_free(NULL, substream);
+
+ return 0;
+}
+
+static int ux500_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s: Enter\n", __func__);
+ return 0;
+}
+
+static int ux500_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ int ret;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct ux500_pcm_private *private = runtime->private_data;
+ int stream_id = substream->pstr->stream;
+
+ pr_debug("%s: Enter\n", __func__);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ pr_debug("%s: START/PAUSE-RELEASE\n", __func__);
+ if (runtime->status->state == SNDRV_PCM_STATE_XRUN) {
+ pr_debug("XRUN occurred\n");
+ return 0;
+ }
+
+ private->no_of_underruns = 0;
+ private->offset = 0;
+ ret = ux500_msp_dai_i2s_configure_sg(runtime->dma_addr,
+ runtime->periods,
+ frames_to_bytes(runtime, runtime->period_size),
+ private->msp_id,
+ stream_id);
+ if (ret) {
+ pr_err("%s: Failed to configure sg-list!\n", __func__);
+ return -EINVAL;
+ }
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ pr_debug("%s: SNDRV_PCM_TRIGGER_STOP\n", __func__);
+ pr_debug("%s: no_of_underruns = %u\n",
+ __func__,
+ private->no_of_underruns);
+ break;
+
+ default:
+ pr_err("%s: Invalid command in pcm trigger\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_uframes_t ux500_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct ux500_pcm_private *private = runtime->private_data;
+
+ pr_debug("%s: dma_offset %d frame %ld\n", __func__, private->offset,
+ bytes_to_frames(substream->runtime, private->offset));
+
+ return bytes_to_frames(substream->runtime, private->offset);
+}
+
+static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ pr_debug("%s: Enter.\n", __func__);
+
+ return dma_mmap_coherent(
+ NULL,
+ vma,
+ runtime->dma_area,
+ runtime->dma_addr,
+ runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops ux500_pcm_ops = {
+ .open = ux500_pcm_open,
+ .close = ux500_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = ux500_pcm_hw_params,
+ .hw_free = ux500_pcm_hw_free,
+ .prepare = ux500_pcm_prepare,
+ .trigger = ux500_pcm_trigger,
+ .pointer = ux500_pcm_pointer,
+ .mmap = ux500_pcm_mmap
+};
+
+int ux500_pcm_new(struct snd_card *card,
+ struct snd_soc_dai *dai,
+ struct snd_pcm *pcm)
+{
+ pr_debug("%s: pcm = %d\n", __func__, (int)pcm);
+
+ pcm->info_flags = 0;
+ strcpy(pcm->name, "UX500_PCM");
+
+ pr_debug("%s: pcm->name = %s.\n", __func__, pcm->name);
+
+ return 0;
+}
+
+static void ux500_pcm_free(struct snd_pcm *pcm)
+{
+ pr_debug("%s: Enter\n", __func__);
+}
+
+static int ux500_pcm_suspend(struct snd_soc_dai *dai)
+{
+ pr_debug("%s: Enter\n", __func__);
+
+ return 0;
+}
+
+static int ux500_pcm_resume(struct snd_soc_dai *dai)
+{
+ pr_debug("%s: Enter\n", __func__);
+
+ return 0;
+}
+
+struct snd_soc_platform_driver ux500_pcm_soc_drv = {
+ .ops = &ux500_pcm_ops,
+ .pcm_new = ux500_pcm_new,
+ .pcm_free = ux500_pcm_free,
+ .suspend = ux500_pcm_suspend,
+ .resume = ux500_pcm_resume,
+};
+EXPORT_SYMBOL(ux500_pcm_soc_drv);
+
+static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ pr_info("%s: Register ux500-pcm SoC platform driver.\n", __func__);
+ ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv);
+ if (ret < 0) {
+ pr_err("%s: Error: Failed to register "
+ "ux500-pcm SoC platform driver (%d)!\n",
+ __func__,
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev)
+{
+ pr_info("%s: Unregister ux500-pcm SoC platform driver.\n", __func__);
+ snd_soc_unregister_platform(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver ux500_pcm_driver = {
+ .driver = {
+ .name = "ux500-pcm",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = ux500_pcm_drv_probe,
+ .remove = __devexit_p(ux500_pcm_drv_remove),
+};
+
+static int __init ux500_pcm_drv_init(void)
+{
+ pr_debug("%s: Register ux500-pcm platform driver.\n", __func__);
+
+ return platform_driver_register(&ux500_pcm_driver);
+}
+
+static void __exit ux500_pcm_drv_exit(void)
+{
+ pr_debug("%s: Unregister ux500-pcm platform driver.\n", __func__);
+
+ platform_driver_unregister(&ux500_pcm_driver);
+}
+
+module_init(ux500_pcm_drv_init);
+module_exit(ux500_pcm_drv_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
new file mode 100644
index 00000000000..50f46615275
--- /dev/null
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * Roger Nilsson <roger.xr.nilsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+#ifndef UX500_PCM_H
+#define UX500_PCM_H
+
+#include <mach/msp.h>
+
+#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
+#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
+#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
+#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
+
+#define UX500_PLATFORM_MIN_CHANNELS 1
+#define UX500_PLATFORM_MAX_CHANNELS 8
+
+#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
+#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
+#define UX500_PLATFORM_PERIODS_MIN 2
+#define UX500_PLATFORM_PERIODS_MAX 48
+#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
+
+extern struct snd_soc_platform ux500_soc_platform;
+
+struct ux500_pcm_private {
+ int msp_id;
+ int stream_id;
+ unsigned int no_of_underruns;
+ unsigned int offset;
+};
+
+void ux500_pcm_dma_eot_handler(void *data);
+
+#endif
diff --git a/sound/u8500_acodec_ab8500.c b/sound/u8500_acodec_ab8500.c
new file mode 100644
index 00000000000..c75da368832
--- /dev/null
+++ b/sound/u8500_acodec_ab8500.c
@@ -0,0 +1,2523 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Deepak Karda
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+/*-----------------------------------------------------------------------------
+* Common Includes
+*---------------------------------------------------------------------------*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/soundcard.h>
+#include <linux/sound.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/i2s/i2s.h>
+#include <mach/msp.h>
+#include <linux/gpio.h>
+/*#include <mach/i2c.h>*/
+#include <mach/debug.h>
+#include <mach/u8500_acodec_ab8500.h>
+#include <mach/ab8500.h>
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+#include <mach/ab8500_codec_v1_0.h>
+#endif
+#ifdef CONFIG_U8500_AB8500_ED
+#include <mach/ab8500_codec.h>
+#endif
+
+#define ELEMENT_SIZE 0
+#define FRAME_SIZE -1
+#define MSP_NUM 0
+
+/* Debugging stuff */
+
+#define ACODEC_NAME "DRIVER ACODEC"
+#define DRIVER_DEBUG CONFIG_STM_ACODEC_DEBUG /* enables/disables debug msgs */
+#define DRIVER_DEBUG_PFX ACODEC_NAME /* msg header represents this module */
+#define DRIVER_DBG KERN_ERR /* message level */
+#define NMDK_DEBUG CONFIG_STM_ACODEC_DEBUG
+extern struct driver_debug_st DBG_ST;
+
+#if NMDK_DEBUG > 0
+t_ab8500_codec_error dump_acodec_registers(void);
+t_ab8500_codec_error dump_msp_registers(void);
+#endif
+
+#ifdef CONFIG_U8500_ACODEC_DMA
+static void u8500_digital_lpbk_tx_dma_start(void);
+static void u8500_digital_lpbk_rx_dma_start(void);
+#endif
+
+int second_config;
+/*----------------------------------------------------------------------------
+* global declarations
+*---------------------------------------------------------------------------*/
+t_u8500_codec_system_context g_codec_system_context;
+
+int u8500_acodec_rates[MAX_NO_OF_RATES] = { 48000 };
+
+char *codec_dest_texts[NUMBER_OUTPUT_DEVICE] = {
+ "CODEC_DEST_HEADSET", "CODEC_DEST_EARPIECE", "CODEC_DEST_HANDSFREE",
+ "CODEC_DEST_VIBRATOR1", "CODEC_DEST_VIBRATOR2"
+};
+
+char *codec_in_texts[NUMBER_INPUT_DEVICE] = {
+ "CODEC_SRC_LINEIN", "CODEC_SRC_MICROPHONE_1A",
+ "CODEC_SRC_MICROPHONE_1B",
+ "CODEC_SRC_MICROPHONE_2", "CODEC_SRC_D_MICROPHONE_1",
+ "CODEC_SRC_D_MICROPHONE_2",
+ "CODEC_SRC_D_MICROPHONE_3", "CODEC_SRC_D_MICROPHONE_4",
+ "CODEC_SRC_D_MICROPHONE_5",
+ "CODEC_SRC_D_MICROPHONE_6", "CODEC_SRC_D_MICROPHONE_12",
+ "CODEC_SRC_D_MICROPHONE_34",
+ "CODEC_SRC_D_MICROPHONE_56"
+};
+
+char *lpbk_state_in_texts[NUMBER_LOOPBACK_STATE] = { "DISABLE", "ENABLE" };
+char *switch_state_in_texts[NUMBER_SWITCH_STATE] = { "DISABLE", "ENABLE" };
+char *power_state_in_texts[NUMBER_POWER_STATE] = { "DISABLE", "ENABLE" };
+char *tdm_mode_state_in_texts[NUMBER_POWER_STATE] = { "DISABLE", "ENABLE" };
+char *direct_rendering_state_in_texts[NUMBER_DIRECT_RENDERING_STATE] =
+ { "DISABLE", "ENABLE" };
+char *pcm_rendering_state_in_texts[NUMBER_PCM_RENDERING_STATE] =
+ { "DISABLE", "ENABLE", "PENDING" };
+
+EXPORT_SYMBOL(codec_dest_texts);
+EXPORT_SYMBOL(codec_in_texts);
+
+static void ab8500_codec_power_init(void);
+static int check_device_id();
+t_ab8500_codec_error perform_src_routing(t_ab8500_codec_src input_device);
+t_ab8500_codec_error
+ u8500_acodec_allocate_all_mono_slots
+ (t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line1);
+t_ab8500_codec_error
+ u8500_acodec_allocate_all_stereo_slots
+ (t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line1,
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line2);
+
+#if 0 //from Arnaud
+/* For Codec in Master mode for recording*/
+struct msp_protocol_desc protocol_desc_tdm_mode = {
+ MSP_DATA_TRANSFER_WIDTH_HALFWORD, /*rx_data_transfer_width */
+ MSP_DATA_TRANSFER_WIDTH_HALFWORD, /*tx_data_transfer_width */
+ MSP_SINGLE_PHASE, /*rx_phase_mode */
+ MSP_SINGLE_PHASE, /*tx_phase_mode */
+ MSP_PHASE2_START_MODE_IMEDIATE, /*rx_phase2_start_mode */
+ MSP_PHASE2_START_MODE_IMEDIATE, /*tx_phase2_start_mode */
+ MSP_BTF_MS_BIT_FIRST, /*rx_endianess */
+ MSP_BTF_MS_BIT_FIRST, /*tx_endianess */
+ MSP_FRAME_LENGTH_2, /*rx_frame_length_1 */
+ MSP_FRAME_LENGTH_2, /*rx_frame_length_2 */
+ MSP_FRAME_LENGTH_2, /*tx_frame_length_1 */
+ MSP_FRAME_LENGTH_2, /*tx_frame_length_2 */
+ MSP_ELEM_LENGTH_16, /*rx_element_length_1 */
+ MSP_ELEM_LENGTH_16, /*rx_element_length_2 */
+ MSP_ELEM_LENGTH_16, /*tx_element_length_1 */
+ MSP_ELEM_LENGTH_16, /*tx_element_length_2 */
+ MSP_DELAY_0, /*rx_data_delay */
+ MSP_DELAY_0, /*tx_data_delay */
+ MSP_FALLING_EDGE, /*rx_clock_pol */
+ MSP_RISING_EDGE, /*tx_clock_pol */
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH, /*rx_msp_frame_pol */
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH, /*tx_msp_frame_pol */
+ MSP_HWS_NO_SWAP, /*rx_half_word_swap */
+ MSP_HWS_NO_SWAP, /*tx_half_word_swap */
+ MSP_COMPRESS_MODE_LINEAR, /*compression_mode */
+ MSP_EXPAND_MODE_LINEAR, /*expansion_mode */
+ MSP_SPI_CLOCK_MODE_NON_SPI, /*spi_clk_mode */
+ MSP_SPI_BURST_MODE_DISABLE, /*spi_burst_mode */
+ 63, /*frame_period */
+ 31, /*frame_width */
+ 64, /*total_clocks_for_one_frame */
+};
+#endif
+
+#if 0 //from HCL
+/* For Codec in Master mode for recording*/
+struct msp_protocol_desc protocol_desc_tdm_mode = {
+ MSP_DATA_TRANSFER_WIDTH_WORD, /*rx_data_transfer_width */
+ MSP_DATA_TRANSFER_WIDTH_WORD, /*tx_data_transfer_width */
+ MSP_DUAL_PHASE, /*rx_phase_mode */
+ MSP_DUAL_PHASE, /*tx_phase_mode */
+ MSP_PHASE2_START_MODE_FRAME_SYNC, /*rx_phase2_start_mode */
+ MSP_PHASE2_START_MODE_FRAME_SYNC, /*tx_phase2_start_mode */
+ MSP_BTF_MS_BIT_FIRST, /*rx_endianess */
+ MSP_BTF_MS_BIT_FIRST, /*tx_endianess */
+ MSP_FRAME_LENGTH_1, /*rx_frame_length_1 */
+ MSP_FRAME_LENGTH_1, /*rx_frame_length_2 */
+ MSP_FRAME_LENGTH_1, /*tx_frame_length_1 */
+ MSP_FRAME_LENGTH_1, /*tx_frame_length_2 */
+ MSP_ELEM_LENGTH_16, /*rx_element_length_1 */
+ MSP_ELEM_LENGTH_16, /*rx_element_length_2 */
+ MSP_ELEM_LENGTH_16, /*tx_element_length_1 */
+ MSP_ELEM_LENGTH_16, /*tx_element_length_2 */
+ MSP_DELAY_0, /*rx_data_delay */
+ MSP_DELAY_0, /*tx_data_delay */
+ MSP_RISING_EDGE, /*rx_clock_pol */
+ MSP_RISING_EDGE, /*tx_clock_pol */
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH, /*rx_msp_frame_pol */
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH, /*tx_msp_frame_pol */
+ MSP_HWS_NO_SWAP, /*rx_half_word_swap */
+ MSP_HWS_NO_SWAP, /*tx_half_word_swap */
+ MSP_COMPRESS_MODE_LINEAR, /*compression_mode */
+ MSP_EXPAND_MODE_LINEAR, /*expansion_mode */
+ MSP_SPI_CLOCK_MODE_NON_SPI, /*spi_clk_mode */
+ MSP_SPI_BURST_MODE_DISABLE, /*spi_burst_mode */
+ 255, /*frame_period */
+ 0, /*frame_width */
+ 256, /*total_clocks_for_one_frame */
+};
+
+#endif
+
+#if 0 //from STS
+struct msp_protocol_desc protocol_desc_tdm_mode = {
+ MSP_DATA_TRANSFER_WIDTH_HALFWORD, /*rx_data_transfer_width */
+ MSP_DATA_TRANSFER_WIDTH_HALFWORD, /*tx_data_transfer_width */
+ MSP_SINGLE_PHASE, /*rx_phase_mode */
+ MSP_SINGLE_PHASE, /*tx_phase_mode */
+ MSP_PHASE2_START_MODE_IMEDIATE, /*rx_phase2_start_mode */
+ MSP_PHASE2_START_MODE_IMEDIATE, /*tx_phase2_start_mode */
+ MSP_BTF_MS_BIT_FIRST, /*rx_endianess */
+ MSP_BTF_MS_BIT_FIRST, /*tx_endianess */
+ MSP_FRAME_LENGTH_2, /*rx_frame_length_1 */
+ MSP_FRAME_LENGTH_1, /*rx_frame_length_2 */
+ MSP_FRAME_LENGTH_2, /*tx_frame_length_1 */
+ MSP_FRAME_LENGTH_1, /*tx_frame_length_2 */
+ MSP_ELEM_LENGTH_16, /*rx_element_length_1 */
+ MSP_ELEM_LENGTH_16, /*rx_element_length_2 */
+ MSP_ELEM_LENGTH_16, /*tx_element_length_1 */
+ MSP_ELEM_LENGTH_16, /*tx_element_length_2 */
+ MSP_DELAY_0, /*rx_data_delay */
+ MSP_DELAY_0, /*tx_data_delay */
+ MSP_FALLING_EDGE, /*rx_clock_pol */
+ MSP_RISING_EDGE, /*tx_clock_pol */
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH, /*rx_msp_frame_pol */
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH, /*tx_msp_frame_pol */
+ MSP_HWS_NO_SWAP, /*rx_half_word_swap */
+ MSP_HWS_NO_SWAP, /*tx_half_word_swap */
+ MSP_COMPRESS_MODE_LINEAR, /*compression_mode */
+ MSP_EXPAND_MODE_LINEAR, /*expansion_mode */
+ MSP_SPI_CLOCK_MODE_NON_SPI, /*spi_clk_mode */
+ MSP_SPI_BURST_MODE_DISABLE, /*spi_burst_mode */
+ 25, /*frame_period */
+ 32, /*frame_width */
+ 32, /*total_clocks_for_one_frame */
+};
+#endif
+
+#define DIGITAL_LPBK_MAX_BIFFERS 3
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+#define NB_OF_CHANNEL_USED 8
+#else
+#define NB_OF_CHANNEL_USED 6
+#endif
+
+#define MONO_SRC 1
+#define STEREO_SRC 2
+
+typedef struct {
+ unsigned char *area; /* virtual pointer */
+ dma_addr_t addr; /* physical address */
+} t_dma_buffer;
+
+typedef struct {
+ struct completion tx_dma_com;
+ struct completion rx_dma_com;
+ volatile int rx_active;
+ volatile int tx_active;
+ t_dma_buffer buffer;
+ int data_size;
+ int rx_index;
+ int tx_index;
+} t_digital_lpbk_cnxt;
+
+const int play_flag = 1;
+const int capture_flag = 2;
+
+t_digital_lpbk_cnxt digital_lpbk_cnxt;
+
+void u8500_set_defaults()
+{
+ int i;
+
+ for (i = 0; i < NUMBER_INPUT_DEVICE; i++) {
+ g_codec_system_context.input_config[i].left_volume = 0;
+ g_codec_system_context.input_config[i].right_volume = 0;
+ g_codec_system_context.input_config[i].mute_state = DISABLE;
+ g_codec_system_context.input_config[i].power_state = DISABLE;
+ }
+
+ for (i = 0; i < NUMBER_OUTPUT_DEVICE; i++) {
+ g_codec_system_context.output_config[i].left_volume = 0;
+ g_codec_system_context.output_config[i].right_volume = 0;
+ g_codec_system_context.output_config[i].mute_state = DISABLE;
+ g_codec_system_context.output_config[i].power_state = DISABLE;
+ }
+
+} //END OF FUNCTION
+
+struct i2sdrv_data *i2sdrv[MAX_I2S_CLIENTS];
+
+t_ab8500_codec_error u8500_acodec_open(int client_id, int stream_id)
+{
+ struct i2sdrv_data *p_i2sdrv_data = NULL;
+ struct i2s_device *i2s;
+
+ p_i2sdrv_data = i2sdrv[client_id];
+
+ if (!p_i2sdrv_data)
+ return (-1);
+
+ i2s = p_i2sdrv_data->i2s;
+
+ if (stream_id == 0) //PLAYBACK
+ {
+ if (p_i2sdrv_data->tx_status)
+ return -1;
+ else {
+ p_i2sdrv_data->tx_status = 1;
+ }
+ } else if (stream_id == 1) //CAPTURE
+ {
+ if (p_i2sdrv_data->rx_status)
+ return -1;
+ else {
+ p_i2sdrv_data->rx_status = 1;
+ }
+ }
+
+ p_i2sdrv_data->flag = 0;
+
+ return 0;
+}
+
+t_ab8500_codec_error u8500_acodec_send_data(int client_id, void *data,
+ size_t bytes, int dma_flag)
+{
+ struct i2sdrv_data *p_i2sdrv_data = NULL;
+ struct i2s_device *i2s_dev = NULL;
+ int bytes_transmit;
+ struct i2s_message message;
+
+ p_i2sdrv_data = i2sdrv[client_id];
+
+ if (!p_i2sdrv_data)
+ return (-1);
+
+ i2s_dev = p_i2sdrv_data->i2s;
+
+ if (p_i2sdrv_data->flag) {
+ stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
+ return -1;
+ }
+
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_SINGLE_DMA;
+ message.i2s_direction = I2S_DIRECTION_TX;
+ message.txbytes = bytes;
+ message.txdata = data;
+ message.dma_flag = dma_flag;
+
+ bytes_transmit = i2s_transfer(i2s_dev->controller, &message);
+
+ if (bytes_transmit < 0) {
+ printk("error in transfer\n");
+ return -1;
+ }
+ return bytes_transmit;
+
+}
+
+t_ab8500_codec_error u8500_acodec_loopback_configure(int client_id, void *data,
+ size_t bytes, int dma_flag)
+{
+ struct i2sdrv_data *p_i2sdrv_data = NULL;
+ struct i2s_device *i2s_dev = NULL;
+ int bytes_receive;
+ struct i2s_message message;
+
+ p_i2sdrv_data = i2sdrv[client_id];
+
+ if (!p_i2sdrv_data)
+ return (-1);
+
+ i2s_dev = p_i2sdrv_data->i2s;
+
+ if (p_i2sdrv_data->flag) {
+ stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
+ return -1;
+ }
+
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_INF_LOOPBACK;
+ message.rxbytes = bytes;
+ message.rxdata = data;
+ message.txbytes = bytes;
+ message.txdata = data;
+ message.dma_flag = dma_flag;
+
+ bytes_receive = i2s_transfer(i2s_dev->controller, &message);
+
+ if (bytes_receive < 0) {
+ printk(" not get\n");
+ return -1;
+ }
+ return bytes_receive;
+
+}
+
+t_ab8500_codec_error u8500_acodec_receive_data(int client_id, void *data,
+ size_t bytes, int dma_flag)
+{
+ struct i2sdrv_data *p_i2sdrv_data = NULL;
+ struct i2s_device *i2s_dev = NULL;
+ int bytes_receive;
+ struct i2s_message message;
+
+ p_i2sdrv_data = i2sdrv[client_id];
+
+ if (!p_i2sdrv_data)
+ return (-1);
+
+ i2s_dev = p_i2sdrv_data->i2s;
+
+ if (p_i2sdrv_data->flag) {
+ stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
+ return -1;
+ }
+
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_SINGLE_DMA;
+ message.i2s_direction = I2S_DIRECTION_RX;
+ message.rxbytes = bytes;
+ message.rxdata = data;
+ message.dma_flag = dma_flag;
+
+ bytes_receive = i2s_transfer(i2s_dev->controller, &message);
+
+ if (bytes_receive < 0) {
+ printk(" not get\n");
+ return -1;
+ }
+ return bytes_receive;
+
+}
+
+t_ab8500_codec_error u8500_acodec_close(int client_id, t_acodec_disable flag)
+{
+ struct i2sdrv_data *p_i2sdrv_data = NULL;
+ struct i2s_device *i2s_dev = NULL;
+ int status = 0;
+
+ p_i2sdrv_data = i2sdrv[client_id];
+
+ if (!p_i2sdrv_data)
+ return (-1);
+
+ i2s_dev = p_i2sdrv_data->i2s;
+
+ if (p_i2sdrv_data->flag) {
+ stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
+ return -1;
+ }
+
+ if (flag == DISABLE_ALL) {
+ p_i2sdrv_data->flag = -1;
+ p_i2sdrv_data->tx_status = 0;
+ p_i2sdrv_data->rx_status = 0;
+ } else if (flag == DISABLE_TRANSMIT) {
+ p_i2sdrv_data->tx_status = 0;
+ } else if (flag == DISABLE_RECEIVE) {
+ p_i2sdrv_data->rx_status = 0;
+ }
+ status = i2s_cleanup(i2s_dev->controller, flag);
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+* u8500_acodec_enable_audio_mode
+*
+* @direction - direction of data flow (from/to) audiocode
+* @mspClockSel - clock for MSP
+* @mspInClockFreq - input clock for MSP
+* @channels - number of channel, 1 for mono and 2 for stereo
+*
+* It configures the audiocodec in audio mode. In this case,the I2S
+* protocol is used for data exchanges.
+*/
+
+t_ab8500_codec_error u8500_acodec_enable_audio_mode(struct acodec_configuration
+ * acodec_config)
+{
+ struct i2s_device *i2s_dev = NULL;
+ t_ab8500_codec_error error_status = AB8500_CODEC_OK;
+ struct msp_config msp_config;
+ t_ab8500_codec_error codec_error;
+ t_ab8500_codec_mode codec_in_mode = AB8500_CODEC_MODE_MANUAL_SETTING;
+ t_ab8500_codec_mode codec_out_mode = AB8500_CODEC_MODE_MANUAL_SETTING;
+ t_ab8500_codec_direction codec_direction;
+/*#ifdef CONFIG_U8500_AB8500_CUT10*/
+#if 1
+ t_ab8500_codec_tdm_config tdm_config;
+#endif
+
+ memset(&msp_config, 0, sizeof(msp_config));
+
+ FUNC_ENTER();
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_enable_audio_mode()\n");
+
+ if (i2sdrv[I2S_CLIENT_MSP1]->flag) {
+ stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
+ return -1;
+ }
+
+ i2s_dev = i2sdrv[I2S_CLIENT_MSP1]->i2s;
+
+ if (g_codec_system_context.cur_user == NO_USER) {
+ stm_error("Audiocodec not yet configured by any user\n");
+ return (AB8500_CODEC_ERROR);
+ } else if (g_codec_system_context.cur_user != acodec_config->user) {
+ stm_error
+ (" Trying to acces audiocodec already in use by user %d\n",
+ g_codec_system_context.cur_user);
+ return (AB8500_CODEC_ERROR);
+ }
+
+ switch (acodec_config->direction) {
+ case AB8500_CODEC_DIRECTION_INOUT:
+ codec_direction = AB8500_CODEC_DIRECTION_INOUT;
+ codec_in_mode = AB8500_CODEC_MODE_VOICE; //HIFI
+ codec_out_mode = AB8500_CODEC_MODE_VOICE; //VOICE
+ break;
+ case AB8500_CODEC_DIRECTION_IN:
+ codec_direction = AB8500_CODEC_DIRECTION_IN;
+ codec_in_mode = AB8500_CODEC_MODE_VOICE; //HIFI
+ break;
+ case AB8500_CODEC_DIRECTION_OUT:
+ codec_direction = AB8500_CODEC_DIRECTION_OUT;
+ codec_out_mode = AB8500_CODEC_MODE_VOICE; //HIFI
+ break;
+ default:
+ stm_error("Invalid direction\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ /* MSP configuration */
+
+ msp_config.tx_clock_sel = 0; //TX_CLK_SEL_SRG;
+ msp_config.rx_clock_sel = 0; //RX_CLK_SEL_SRG;
+
+ msp_config.tx_frame_sync_sel = 0; //0x00000400; Frame synchronization signal is provided by an external source. MSPTFS is an input pin
+ msp_config.rx_frame_sync_sel = 0; //0: Rx Frame synchronization signal is provided by an external source. MSPRFS is an input pin
+
+ msp_config.input_clock_freq = MSP_INPUT_FREQ_48MHZ;
+
+ msp_config.srg_clock_sel = 0; //0x000C0000
+
+ //msp_config.rx_endianess = MSP_BIG_ENDIAN;
+ //msp_config.tx_endianess = MSP_BIG_ENDIAN;
+
+ msp_config.rx_frame_sync_pol = RX_FIFO_SYNC_HI;
+ msp_config.tx_frame_sync_pol = TX_FIFO_SYNC_HI;
+
+ //msp_config.rx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE;
+ //msp_config.tx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE;
+
+ msp_config.rx_fifo_config = RX_FIFO_ENABLE;
+ msp_config.tx_fifo_config = TX_FIFO_ENABLE;
+
+ msp_config.spi_clk_mode = SPI_CLK_MODE_NORMAL;
+ msp_config.spi_burst_mode = 0;
+
+ msp_config.handler = acodec_config->handler;
+ msp_config.tx_callback_data = acodec_config->tx_callback_data;
+ msp_config.tx_data_enable = 0;
+ msp_config.rx_callback_data = acodec_config->rx_callback_data;
+
+ msp_config.loopback_enable = 0;
+ msp_config.multichannel_configured = 0;
+
+ msp_config.def_elem_len = 0;
+ //msp_config.loopback_enable = g_codec_system_context.msp_loopback;
+
+ stm_dbg(DBG_ST.acodec, " msp_config.loopback_enable = 0x%x \n",
+ msp_config.loopback_enable);
+
+#if 0
+ msp_config.default_protocol_desc = 1;
+#else
+ msp_config.default_protocol_desc = 0;
+ msp_config.protocol_desc.rx_phase_mode = MSP_SINGLE_PHASE;
+ msp_config.protocol_desc.tx_phase_mode = MSP_SINGLE_PHASE;
+ msp_config.protocol_desc.rx_phase2_start_mode =
+ MSP_PHASE2_START_MODE_IMEDIATE;
+ msp_config.protocol_desc.tx_phase2_start_mode =
+ MSP_PHASE2_START_MODE_IMEDIATE;
+ msp_config.protocol_desc.rx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+ msp_config.protocol_desc.tx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST;
+ msp_config.protocol_desc.rx_frame_length_1 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.rx_frame_length_2 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.tx_frame_length_1 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.tx_frame_length_2 = MSP_FRAME_LENGTH_1;
+ msp_config.protocol_desc.rx_element_length_1 = MSP_ELEM_LENGTH_32;
+ msp_config.protocol_desc.rx_element_length_2 = MSP_ELEM_LENGTH_32;
+ msp_config.protocol_desc.tx_element_length_1 = MSP_ELEM_LENGTH_32;
+ msp_config.protocol_desc.tx_element_length_2 = MSP_ELEM_LENGTH_32;
+ msp_config.protocol_desc.rx_data_delay = MSP_DELAY_0;
+ msp_config.protocol_desc.tx_data_delay = MSP_DELAY_0;
+ msp_config.protocol_desc.rx_clock_pol = MSP_RISING_EDGE;
+ msp_config.protocol_desc.tx_clock_pol = MSP_FALLING_EDGE;
+ msp_config.protocol_desc.rx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH;
+ msp_config.protocol_desc.tx_frame_sync_pol =
+ MSP_FRAME_SYNC_POL_ACTIVE_HIGH;
+ msp_config.protocol_desc.rx_half_word_swap = MSP_HWS_NO_SWAP;
+ msp_config.protocol_desc.tx_half_word_swap = MSP_HWS_NO_SWAP;
+ msp_config.protocol_desc.compression_mode = MSP_COMPRESS_MODE_LINEAR;
+ msp_config.protocol_desc.expansion_mode = MSP_EXPAND_MODE_LINEAR;
+ msp_config.protocol_desc.spi_clk_mode = MSP_SPI_CLOCK_MODE_NON_SPI;
+ msp_config.protocol_desc.spi_burst_mode = MSP_SPI_BURST_MODE_DISABLE;
+ msp_config.protocol_desc.frame_sync_ignore = MSP_FRAME_SYNC_IGNORE;
+ msp_config.protocol_desc.frame_period = 63;
+ msp_config.protocol_desc.frame_width = 31;
+ msp_config.protocol_desc.total_clocks_for_one_frame = 64;
+
+#endif
+
+ msp_config.direction = MSP_BOTH_T_R_MODE;
+ msp_config.protocol = MSP_PCM_PROTOCOL; //MSP_I2S_PROTOCOL
+ msp_config.frame_size = ELEMENT_SIZE;
+ // msp_config.frame_freq = freq; $kardad$
+ msp_config.frame_freq = CODEC_SAMPLING_FREQ_48KHZ;
+
+ /* enable msp for both tr and rx mode with dma data transfer. THIS IS NOW DONE SEPARATELY from SAA. */
+
+ if (acodec_config->channels == 1)
+ msp_config.data_size = MSP_DATA_SIZE_16BIT;
+ else
+ msp_config.data_size = MSP_DATA_SIZE_32BIT;
+
+#ifdef CONFIG_U8500_ACODEC_DMA
+ msp_config.work_mode = MSP_DMA_MODE;
+#elif defined(CONFIG_U8500_ACODEC_POLL)
+ msp_config.work_mode = MSP_POLLING_MODE;
+#else
+ msp_config.work_mode = MSP_INTERRUPT_MODE;
+#endif
+
+ if (DISABLE == acodec_config->direct_rendering_mode) {
+ msp_config.multichannel_configured = 1;
+ msp_config.multichannel_config.tx_multichannel_enable = 1;
+ if (acodec_config->channels == 1) {
+ msp_config.multichannel_config.tx_channel_0_enable =
+ 0x0000001;
+ } else {
+ msp_config.multichannel_config.tx_channel_0_enable =
+ 0x0000003;
+ }
+ msp_config.multichannel_config.tx_channel_1_enable = 0x0000000;
+ msp_config.multichannel_config.tx_channel_2_enable = 0x0000000;
+ msp_config.multichannel_config.tx_channel_3_enable = 0x0000000;
+
+ msp_config.multichannel_config.rx_multichannel_enable = 1;
+
+ if (acodec_config->channels == 1) {
+ msp_config.multichannel_config.rx_channel_0_enable =
+ 0x0000001;
+ } else {
+ msp_config.multichannel_config.rx_channel_0_enable =
+ 0x0000003;
+ }
+ msp_config.multichannel_config.rx_channel_1_enable = 0x0000000;
+ msp_config.multichannel_config.rx_channel_2_enable = 0x0000000;
+ msp_config.multichannel_config.rx_channel_3_enable = 0x0000000;
+
+ if (acodec_config->tdm8_ch_mode == ENABLE) {
+ msp_config.def_elem_len = 1;
+
+ msp_config.protocol_desc.tx_element_length_1 =
+ MSP_ELEM_LENGTH_20;
+ msp_config.protocol_desc.tx_frame_length_1 =
+ MSP_FRAME_LENGTH_8;
+ msp_config.protocol_desc.tx_data_delay = MSP_DELAY_1;
+
+ msp_config.protocol_desc.tx_element_length_2 =
+ MSP_ELEM_LENGTH_8;
+ msp_config.protocol_desc.tx_frame_length_2 =
+ MSP_FRAME_LENGTH_1;
+
+ msp_config.protocol_desc.rx_element_length_1 =
+ MSP_ELEM_LENGTH_20;
+ msp_config.protocol_desc.rx_frame_length_1 =
+ MSP_FRAME_LENGTH_8;
+ msp_config.protocol_desc.rx_data_delay = MSP_DELAY_1;
+
+ msp_config.protocol_desc.rx_element_length_2 =
+ MSP_ELEM_LENGTH_8;
+ msp_config.protocol_desc.rx_frame_length_2 =
+ MSP_FRAME_LENGTH_1;
+
+ msp_config.protocol_desc.frame_sync_ignore =
+ MSP_FRAME_SYNC_UNIGNORE;
+ msp_config.protocol_desc.rx_clock_pol = MSP_RISING_EDGE;
+
+ //if(acodec_config->digital_loopback == ENABLE) {
+ if (1) {
+ msp_config.multichannel_config.
+ tx_channel_0_enable =
+ (1 << NB_OF_CHANNEL_USED) - 1;
+ msp_config.multichannel_config.
+ rx_channel_0_enable =
+ (1 << NB_OF_CHANNEL_USED) - 1;
+ } else {
+ msp_config.multichannel_config.
+ tx_channel_0_enable = 0x3;
+ msp_config.multichannel_config.
+ rx_channel_0_enable = 0x3;
+ }
+ }
+
+ if (acodec_config->tdm8_ch_mode == ENABLE) {
+ /* TFSDLY = 2 delay units */
+ msp_config.iodelay = 0x20;
+ }
+
+ error_status = i2s_setup(i2s_dev->controller, &msp_config);
+ if (error_status < 0) {
+ stm_error("error in msp enable, error_status is %d\n",
+ error_status);
+ return error_status;
+ }
+ } else if (ENABLE == acodec_config->direct_rendering_mode) {
+ writel(0x00, ((char *)(IO_ADDRESS(U8500_MSP1_BASE) + 0x04))); //MSP_GCR
+ }
+
+ if (ACODEC_CONFIG_REQUIRED == acodec_config->acodec_config_need) {
+ AB8500_CODEC_SelectInterface(AB8500_CODEC_AUDIO_INTERFACE_0);
+
+ codec_error = AB8500_CODEC_PowerUp();
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_PowerUp failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+/*#ifdef CONFIG_U8500_AB8500_CUT10*/
+#if 1
+ tdm_config.cr27_if1_bitclk_osr =
+ AB8500_CODEC_CR27_IF1_BITCLK_OSR_32;
+ tdm_config.cr27_if0_bitclk_osr =
+ AB8500_CODEC_CR27_IF0_BITCLK_OSR_32;
+ tdm_config.cr28_if0wl = AB8500_CODEC_CR28_IF0WL_16BITS;
+ tdm_config.cr30_if1wl = AB8500_CODEC_CR30_IF1WL_16BITS;
+
+ switch (acodec_config->direction) {
+ case AB8500_CODEC_DIRECTION_INOUT:
+ tdm_config.cr28_bitclk0p =
+ AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE;
+ tdm_config.cr28_if0del =
+ AB8500_CODEC_CR28_IF0DEL_DELAYED;
+ break;
+ case AB8500_CODEC_DIRECTION_IN:
+ tdm_config.cr28_bitclk0p =
+ AB8500_CODEC_CR28_BITCLK0P_RISING_EDGE;
+ tdm_config.cr28_if0del =
+ AB8500_CODEC_CR28_IF0DEL_NOT_DELAYED;
+ break;
+ case AB8500_CODEC_DIRECTION_OUT:
+ tdm_config.cr28_bitclk0p =
+ AB8500_CODEC_CR28_BITCLK0P_FALLING_EDGE;
+ tdm_config.cr28_if0del =
+ AB8500_CODEC_CR28_IF0DEL_DELAYED;
+ break;
+ default:
+ stm_error("Invalid direction\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ if (acodec_config->tdm8_ch_mode == ENABLE) {
+ tdm_config.cr27_if0_bitclk_osr =
+ AB8500_CODEC_CR27_IF0_BITCLK_OSR_256;
+ tdm_config.cr28_if0wl = AB8500_CODEC_CR28_IF0WL_20BITS;
+ tdm_config.cr28_bitclk0p =
+ AB8500_CODEC_CR28_BITCLK0P_RISING_EDGE;
+ tdm_config.cr28_if0del =
+ AB8500_CODEC_CR28_IF0DEL_DELAYED;
+ codec_in_mode = AB8500_CODEC_MODE_VOICE;
+ codec_out_mode = AB8500_CODEC_MODE_VOICE;
+ acodec_config->direction = AB8500_CODEC_DIRECTION_INOUT;
+ }
+
+ codec_error =
+ AB8500_CODEC_SetModeAndDirection(acodec_config->direction,
+ codec_in_mode,
+ codec_out_mode,
+ &tdm_config);
+#else
+ codec_error =
+ AB8500_CODEC_SetModeAndDirection(acodec_config->direction,
+ codec_in_mode,
+ codec_out_mode);
+#endif
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("set mode and direction failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ codec_error =
+ AB8500_CODEC_SetMasterMode(AB8500_CODEC_MASTER_MODE_ENABLE);
+
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("set mode and direction failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ /*codec_error = trg_codec_set_sample_frequency(0); */
+
+ /*u8500_acodec_set_volume(g_codec_system_context.in_left_volume,
+ g_codec_system_context.in_right_volume,
+ g_codec_system_context.out_left_volume,
+ g_codec_system_context.out_right_volume,
+ user); */
+#if 0
+ if (AB8500_CODEC_DIRECTION_IN == acodec_config->direction
+ || AB8500_CODEC_DIRECTION_INOUT ==
+ acodec_config->direction) {
+
+ u8500_acodec_allocate_ad_slot
+ (AB8500_CODEC_SRC_D_MICROPHONE_1, TDM_8_CH_MODE);
+ u8500_acodec_allocate_ad_slot
+ (AB8500_CODEC_SRC_D_MICROPHONE_2, TDM_8_CH_MODE);
+
+ /*codec_error = AB8500_CODEC_ADSlotAllocation (AB8500_CODEC_SLOT0,
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT3);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ codec_error = AB8500_CODEC_ADSlotAllocation (AB8500_CODEC_SLOT1,
+ AB8500_CODEC_CR31_TO_CR46_SLOT_IS_TRISTATE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ } */
+
+ }
+
+ if (AB8500_CODEC_DIRECTION_OUT == acodec_config->direction
+ || AB8500_CODEC_DIRECTION_INOUT ==
+ acodec_config->direction) {
+ u8500_acodec_allocate_da_slot(AB8500_CODEC_DEST_HEADSET,
+ TDM_8_CH_MODE);
+ /*codec_error = AB8500_CODEC_DASlotAllocation (AB8500_CODEC_DA_CHANNEL_NUMBER_1,
+ AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT08);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error
+ ("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ codec_error = AB8500_CODEC_DASlotAllocation (AB8500_CODEC_DA_CHANNEL_NUMBER_2,
+ AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT09);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error
+ ("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ } */
+
+ }
+#endif
+
+ } //END of if acodec_config_need
+
+/*#if DRIVER_DEBUG > 0
+ {
+ dump_msp_registers();
+ dump_acodec_registers();
+ }
+#endif*/
+
+ stm_dbg(DBG_ST.acodec,
+ "leaving in u8500_acodec_enable_audio_mode() \n");
+
+ FUNC_EXIT();
+ return AB8500_CODEC_OK;
+}
+
+/**
+* u8500_acodec_set_output_volume - configures the volume level for both speakers
+* @in_left_volume - volume for left channel of mic
+* @in_right_volume - volume for right channel of mic
+* @out_left_volume - volume for left speaker
+* @out_right_volume - volume for right speaker
+*/
+t_ab8500_codec_error u8500_acodec_set_output_volume(t_ab8500_codec_dest
+ dest_device,
+ int left_volume,
+ int right_volume,
+ t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_set_output_volume()\n");
+
+ FUNC_ENTER();
+
+ user = user; //keep compiler happy
+
+ g_codec_system_context.output_config[dest_device].left_volume =
+ left_volume;
+ g_codec_system_context.output_config[dest_device].right_volume =
+ right_volume;
+
+ AB8500_CODEC_SetDestVolume(dest_device, left_volume, right_volume);
+
+ FUNC_EXIT();
+ return codec_error;
+}
+
+/*u8500_acodec_get_output_volume*/
+
+t_ab8500_codec_error u8500_acodec_get_output_volume(t_ab8500_codec_dest
+ dest_device,
+ int *p_left_volume,
+ int *p_right_volume,
+ t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_set_output_volume()\n");
+
+ user = user; //keep compiler happy
+
+ *p_left_volume =
+ g_codec_system_context.output_config[dest_device].left_volume;
+ *p_right_volume =
+ g_codec_system_context.output_config[dest_device].right_volume;
+
+ return codec_error;
+}
+
+/**
+* u8500_acodec_set_input_volume - configures the volume level for both speakers
+* @in_left_volume - volume for left channel of mic
+* @in_right_volume - volume for right channel of mic
+* @out_left_volume - volume for left speaker
+* @out_right_volume - volume for right speaker
+*/
+t_ab8500_codec_error u8500_acodec_set_input_volume(t_ab8500_codec_src
+ src_device, int left_volume,
+ int right_volume,
+ t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_set_input_volume()\n");
+
+ user = user; //keep compiler happy
+
+ g_codec_system_context.input_config[src_device].left_volume =
+ left_volume;
+ g_codec_system_context.input_config[src_device].right_volume =
+ right_volume;
+
+ AB8500_CODEC_SetSrcVolume(src_device, left_volume, right_volume);
+
+ return codec_error;
+}
+
+/**
+* u8500_acodec_get_input_volume - configures the volume level for both speakers
+* @in_left_volume - volume for left channel of mic
+* @in_right_volume - volume for right channel of mic
+* @out_left_volume - volume for left speaker
+* @out_right_volume - volume for right speaker
+*/
+t_ab8500_codec_error u8500_acodec_get_input_volume(t_ab8500_codec_src
+ src_device,
+ int *p_left_volume,
+ int *p_right_volume,
+ t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_get_input_volume()\n");
+
+ user = user; //keep compiler happy
+
+ *p_left_volume =
+ g_codec_system_context.input_config[src_device].left_volume;
+ *p_right_volume =
+ g_codec_system_context.input_config[src_device].right_volume;
+
+ return codec_error;
+}
+
+/**
+* u8500_acodec_toggle_playback_mute_control - configures the mute for both speakers
+* @in_left_volume - volume for left channel of mic
+* @in_right_volume - volume for right channel of mic
+* @out_left_volume - volume for left speaker
+* @out_right_volume - volume for right speaker
+*/
+t_ab8500_codec_error
+u8500_acodec_toggle_playback_mute_control(t_ab8500_codec_dest dest_device,
+ t_u8500_bool_state mute_state,
+ t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_toggle_playback_mute_control \n");
+
+ user = user; //keep compiler happy
+
+ g_codec_system_context.output_config[dest_device].mute_state =
+ mute_state;
+
+ if (ENABLE == mute_state) {
+ AB8500_CODEC_DestPowerControl(dest_device,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+ } else {
+ AB8500_CODEC_DestPowerControl(dest_device,
+ AB8500_CODEC_SRC_STATE_DISABLE);
+ }
+
+ return codec_error;
+}
+
+/**
+* u8500_acodec_toggle_capture_mute_control - configures the mute for both speakers
+* @in_left_volume - volume for left channel of mic
+* @in_right_volume - volume for right channel of mic
+* @out_left_volume - volume for left speaker
+* @out_right_volume - volume for right speaker
+*/
+t_ab8500_codec_error u8500_acodec_toggle_capture_mute_control(t_ab8500_codec_src
+ src_device,
+ t_u8500_bool_state
+ mute_state,
+ t_acodec_user
+ user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering in u8500_acodec_toggle_capture_mute_control \n");
+
+ user = user; //keep compiler happy
+
+ g_codec_system_context.input_config[src_device].mute_state = mute_state;
+
+ if (ENABLE == mute_state) {
+ AB8500_CODEC_SrcPowerControl(src_device,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+ } else {
+ AB8500_CODEC_SrcPowerControl(src_device,
+ AB8500_CODEC_SRC_STATE_DISABLE);
+ }
+
+ return codec_error;
+}
+
+/**
+* u8500_acodec_select_input
+* @input_device: MIC or linein.
+*
+* This routine selects the input device mic or linein.
+*/
+
+t_ab8500_codec_error u8500_acodec_select_input(t_ab8500_codec_src
+ input_device,
+ t_acodec_user user,
+ t_u8500_mode mode)
+{
+
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec, " Entering u8500_acodec_select_input\n");
+
+ if (TDM_8_CH_MODE == mode)
+ u8500_acodec_allocate_ad_slot(input_device, TDM_8_CH_MODE);
+ else
+ u8500_acodec_allocate_ad_slot(input_device, CLASSICAL_MODE);
+
+ codec_error = AB8500_CODEC_SelectInput(input_device);
+
+ stm_dbg(DBG_ST.acodec, " leaving u8500_acodec_select_input\n");
+ return codec_error;
+}
+
+/**
+* u8500_acodec_select_output
+* @output_device: output device HP/LSP
+*
+* This routine selects the output device Headphone or loud speaker
+*/
+
+t_ab8500_codec_error u8500_acodec_select_output(t_ab8500_codec_dest
+ output_device,
+ t_acodec_user user,
+ t_u8500_mode mode)
+{
+
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ FUNC_ENTER();
+ stm_dbg(DBG_ST.acodec, " Entering u8500_acodec_select_output()\n");
+
+ if (TDM_8_CH_MODE == mode)
+ u8500_acodec_allocate_da_slot(output_device, TDM_8_CH_MODE);
+ else
+ u8500_acodec_allocate_da_slot(output_device, CLASSICAL_MODE);
+
+ codec_error = AB8500_CODEC_SelectOutput(output_device);
+
+ stm_dbg(DBG_ST.acodec, " leaving u8500_acodec_select_output()\n");
+ FUNC_EXIT();
+ return codec_error;
+}
+
+t_ab8500_codec_error u8500_acodec_allocate_ad_slot(t_ab8500_codec_src
+ input_device,
+ t_u8500_mode mode)
+{
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line1,
+ ad_data_line2;
+ t_ab8500_codec_slot slot1, slot2;
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ slot1 = AB8500_CODEC_SLOT_UNDEFINED;
+ slot2 = AB8500_CODEC_SLOT_UNDEFINED;
+
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_UNDEFINED;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_UNDEFINED;
+
+ switch (input_device) {
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ {
+ slot1 = AB8500_CODEC_SLOT0;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT1;
+ }
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ {
+ slot1 = AB8500_CODEC_SLOT1;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT2;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ {
+ slot1 = AB8500_CODEC_SLOT2;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT3;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ {
+ slot1 = AB8500_CODEC_SLOT3;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT4;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ {
+ slot1 = AB8500_CODEC_SLOT4;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT5;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ {
+ slot1 = AB8500_CODEC_SLOT5;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT6;
+ }
+ break;
+ case AB8500_CODEC_SRC_LINEIN:
+ {
+ slot1 = AB8500_CODEC_SLOT0;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT1;
+
+ slot2 = AB8500_CODEC_SLOT1;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT2;
+ }
+ case AB8500_CODEC_SRC_FM_RX:
+ {
+ slot1 = AB8500_CODEC_SLOT6;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT7;
+
+ slot2 = AB8500_CODEC_SLOT7;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT8;
+ }
+ break;
+ case AB8500_CODEC_SRC_ALL:
+ break;
+ }
+
+ if ((AB8500_CODEC_SLOT_UNDEFINED != slot1)
+ && (AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_UNDEFINED !=
+ ad_data_line1)) {
+ if (CLASSICAL_MODE == mode) {
+ slot1 = AB8500_CODEC_SLOT0;
+ }
+ codec_error =
+ AB8500_CODEC_ADSlotAllocation(slot1, ad_data_line1);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ if ((AB8500_CODEC_SLOT_UNDEFINED != slot2)
+ && (AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_UNDEFINED !=
+ ad_data_line2)) {
+ if (CLASSICAL_MODE == mode) {
+ slot2 = AB8500_CODEC_SLOT1;
+ }
+ codec_error =
+ AB8500_CODEC_ADSlotAllocation(slot2, ad_data_line2);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ return AB8500_CODEC_OK;
+}
+
+t_ab8500_codec_error u8500_acodec_unallocate_ad_slot(t_ab8500_codec_src
+ input_device,
+ t_u8500_mode mode)
+{
+ t_ab8500_codec_slot slot1, slot2;
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ slot1 = AB8500_CODEC_SLOT_UNDEFINED;
+ slot2 = AB8500_CODEC_SLOT_UNDEFINED;
+
+ switch (input_device) {
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ {
+ slot1 = AB8500_CODEC_SLOT0;
+ }
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ {
+ slot1 = AB8500_CODEC_SLOT1;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ {
+ slot1 = AB8500_CODEC_SLOT2;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ {
+ slot1 = AB8500_CODEC_SLOT3;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ {
+ slot1 = AB8500_CODEC_SLOT4;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ {
+ slot1 = AB8500_CODEC_SLOT5;
+ }
+ break;
+ case AB8500_CODEC_SRC_LINEIN:
+ {
+ slot1 = AB8500_CODEC_SLOT0;
+ slot2 = AB8500_CODEC_SLOT1;
+ }
+ break;
+ case AB8500_CODEC_SRC_ALL:
+ break;
+ }
+
+ if (AB8500_CODEC_SLOT_UNDEFINED != slot1) {
+ if (CLASSICAL_MODE == mode) {
+ slot1 = AB8500_CODEC_SLOT0;
+ }
+ codec_error =
+ AB8500_CODEC_ADSlotAllocation(slot1,
+ AB8500_CODEC_CR31_TO_CR46_SLOT_IS_TRISTATE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ if (AB8500_CODEC_SLOT_UNDEFINED != slot2) {
+ if (CLASSICAL_MODE == mode) {
+ slot2 = AB8500_CODEC_SLOT1;
+ }
+ codec_error =
+ AB8500_CODEC_ADSlotAllocation(slot2,
+ AB8500_CODEC_CR31_TO_CR46_SLOT_IS_TRISTATE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ return AB8500_CODEC_OK;
+}
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+t_ab8500_codec_error u8500_acodec_allocate_da_slot(t_ab8500_codec_dest
+ output_device,
+ t_u8500_mode mode)
+{
+ t_ab8500_codec_da_channel_number da_ch_no1, da_ch_no2;
+ t_ab8500_codec_cr51_to_cr58_sltoda da_slot1, da_slot2;
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED;
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED;
+
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT_UNDEFINED;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT_UNDEFINED;
+
+ switch (output_device) {
+ case AB8500_CODEC_DEST_HEADSET:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_1;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT08;
+
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_2;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT09;
+ }
+ break;
+ case AB8500_CODEC_DEST_EARPIECE:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_1;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT08;
+ }
+ break;
+ case AB8500_CODEC_DEST_HANDSFREE:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_3;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT10;
+
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_4;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT11;
+ }
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_5;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT12;
+ }
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_6;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT13;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_FM_TX:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_7;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT14;
+
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_8;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT15;
+ }
+
+ case AB8500_CODEC_DEST_ALL:
+ break;
+ }
+
+ if ((AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED != da_ch_no1)
+ && (AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT_UNDEFINED != da_slot1)) {
+ if (CLASSICAL_MODE == mode) {
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT08;
+ }
+ codec_error =
+ AB8500_CODEC_DASlotAllocation(da_ch_no1, da_slot1);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ if ((AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED != da_ch_no2)
+ && (AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT_UNDEFINED != da_slot2)) {
+ if (CLASSICAL_MODE == mode) {
+ da_slot1 = AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT09;
+ }
+ codec_error =
+ AB8500_CODEC_DASlotAllocation(da_ch_no2, da_slot2);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ return AB8500_CODEC_OK;
+}
+
+#else
+t_ab8500_codec_error u8500_acodec_allocate_da_slot(t_ab8500_codec_dest
+ output_device,
+ t_u8500_mode mode)
+{
+ t_ab8500_codec_da_channel_number da_ch_no1, da_ch_no2;
+ t_ab8500_codec_cr51_to_cr56_sltoda da_slot1, da_slot2;
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED;
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED;
+
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT_UNDEFINED;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT_UNDEFINED;
+
+ switch (output_device) {
+ case AB8500_CODEC_DEST_HEADSET:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_1;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT08;
+
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_2;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT09;
+ }
+ break;
+ case AB8500_CODEC_DEST_EARPIECE:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_1;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT08;
+ }
+ break;
+ case AB8500_CODEC_DEST_HANDSFREE:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_3;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT10;
+
+ da_ch_no2 = AB8500_CODEC_DA_CHANNEL_NUMBER_4;
+ da_slot2 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT11;
+ }
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_L:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_5;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT12;
+ }
+ break;
+ case AB8500_CODEC_DEST_VIBRATOR_R:
+ {
+ da_ch_no1 = AB8500_CODEC_DA_CHANNEL_NUMBER_6;
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT13;
+ }
+ break;
+
+ case AB8500_CODEC_DEST_ALL:
+ break;
+ }
+
+ if ((AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED != da_ch_no1)
+ && (AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT_UNDEFINED != da_slot1)) {
+ if (CLASSICAL_MODE == mode) {
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT08;
+ }
+ codec_error =
+ AB8500_CODEC_DASlotAllocation(da_ch_no1, da_slot1);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ if ((AB8500_CODEC_DA_CHANNEL_NUMBER_UNDEFINED != da_ch_no2)
+ && (AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT_UNDEFINED != da_slot2)) {
+ if (CLASSICAL_MODE == mode) {
+ da_slot1 = AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT09;
+ }
+ codec_error =
+ AB8500_CODEC_DASlotAllocation(da_ch_no2, da_slot2);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+
+ return AB8500_CODEC_OK;
+}
+#endif
+
+t_ab8500_codec_error u8500_acodec_unallocate_da_slot(t_ab8500_codec_dest
+ output_device,
+ t_u8500_mode mode)
+{
+ return AB8500_CODEC_OK;
+}
+
+t_ab8500_codec_error u8500_acodec_set_src_power_cntrl(t_ab8500_codec_src
+ input_device,
+ t_u8500_bool_state
+ pwr_state)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ if (ENABLE == pwr_state) {
+ u8500_acodec_allocate_ad_slot(input_device, TDM_8_CH_MODE);
+ codec_error =
+ AB8500_CODEC_SrcPowerControl(input_device,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_SrcPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.input_config[input_device].power_state =
+ ENABLE;
+ } else {
+ u8500_acodec_unallocate_ad_slot(input_device, TDM_8_CH_MODE);
+ codec_error =
+ AB8500_CODEC_SrcPowerControl(input_device,
+ AB8500_CODEC_SRC_STATE_DISABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_SrcPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.input_config[input_device].power_state =
+ DISABLE;
+ }
+
+ return AB8500_CODEC_OK;
+}
+
+t_u8500_bool_state u8500_acodec_get_src_power_state(t_ab8500_codec_src
+ input_device)
+{
+ return (g_codec_system_context.input_config[input_device].power_state);
+}
+
+t_ab8500_codec_error u8500_acodec_set_dest_power_cntrl(t_ab8500_codec_dest
+ output_device,
+ t_u8500_bool_state
+ pwr_state)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ if (ENABLE == pwr_state) {
+ AB8500_CODEC_SelectInterface(AB8500_CODEC_AUDIO_INTERFACE_0);
+
+ codec_error = AB8500_CODEC_PowerUp();
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_PowerUp failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ u8500_acodec_allocate_da_slot(output_device, TDM_8_CH_MODE);
+
+ codec_error =
+ AB8500_CODEC_DestPowerControl(output_device,
+ AB8500_CODEC_DEST_STATE_ENABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_DestPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.output_config[output_device].
+ power_state = ENABLE;
+ } else {
+ u8500_acodec_unallocate_da_slot(output_device, TDM_8_CH_MODE);
+ codec_error =
+ AB8500_CODEC_DestPowerControl(output_device,
+ AB8500_CODEC_DEST_STATE_DISABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_DestPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.output_config[output_device].
+ power_state = DISABLE;
+ }
+
+ return AB8500_CODEC_OK;
+}
+
+t_u8500_bool_state u8500_acodec_get_dest_power_state(t_ab8500_codec_dest
+ output_device)
+{
+ return (g_codec_system_context.output_config[output_device].
+ power_state);
+}
+
+/**
+* u8500_acodec_toggle_analog_lpbk
+* @output_device: output device HP/LSP
+*
+* This routine selects the output device Headphone or loud speaker
+*/
+t_ab8500_codec_error u8500_acodec_toggle_analog_lpbk(t_u8500_bool_state
+ lpbk_state,
+ t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering inu8500_acodec_toggle_analog_lpbk() \n");
+
+ user = user; //keep compiler happy
+
+ if (ENABLE == lpbk_state) {
+ /* Reset CODEC */
+ codec_error = AB8500_CODEC_Reset();
+
+ AB8500_CODEC_SelectInterface(AB8500_CODEC_AUDIO_INTERFACE_0);
+
+ codec_error = AB8500_CODEC_PowerUp();
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_PowerUp failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ codec_error = AB8500_CODEC_SelectInput(AB8500_CODEC_SRC_LINEIN);
+
+ codec_error =
+ AB8500_CODEC_SrcPowerControl(AB8500_CODEC_SRC_LINEIN,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+
+ //codec_error = AB8500_CODEC_SetSrcVolume(AB8500_CODEC_SRC_LINEIN,VOL_MAX,VOL_MAX);
+
+ codec_error =
+ AB8500_CODEC_SelectOutput(AB8500_CODEC_DEST_HEADSET);
+
+ codec_error =
+ AB8500_CODEC_DestPowerControl(AB8500_CODEC_DEST_HEADSET,
+ AB8500_CODEC_DEST_STATE_ENABLE);
+
+ //codec_error = AB8500_CODEC_SetDestVolume(AB8500_CODEC_DEST_HEADSET,0,0);
+
+ codec_error = AB8500_CODEC_SetAnalogLoopback(VOL_MAX, VOL_MAX);
+
+ ab8500_write(AB8500_AUDIO, 0xd05, 0x30);
+ ab8500_write(AB8500_AUDIO, 0xd07, 0xf3);
+ ab8500_write(AB8500_AUDIO, 0xd16, 0xdd);
+ ab8500_write(AB8500_AUDIO, 0xd17, 0x55);
+ ab8500_write(AB8500_AUDIO, 0xd3f, 0xc0);
+
+ } else {
+ codec_error = AB8500_CODEC_RemoveAnalogLoopback();
+ }
+
+#if DRIVER_DEBUG > 0
+ {
+ dump_acodec_registers();
+ }
+#endif
+
+ return codec_error;
+}
+
+#ifdef CONFIG_U8500_ACODEC_POLL
+
+static int digital_lpbk_msp_rx_tx_thread(void *data)
+{
+ t_digital_lpbk_cnxt *p_cnxt = (t_digital_lpbk_cnxt *) data;
+ unsigned int sample[8], count = 32;
+
+ daemonize("digital_lpbk_msp_rx_tx_thread");
+ allow_signal(SIGKILL);
+
+ printk("\n Rx-Tx : digital_lpbk_msp_rx_tx_thread started \n");
+
+ while ((!signal_pending(current)) && (p_cnxt->rx_active)) {
+
+// ret_val = u8500_msp_receive_data(alsa_msp_adev,p_cnxt->buffer[p_cnxt->rx_index],p_cnxt->data_size);
+
+ //u8500_msp_transceive_data(alsa_msp_adev,p_cnxt->buffer[0], p_cnxt->data_size,p_cnxt->buffer[1], p_cnxt->data_size);
+
+ //u8500_msp_transceive_data(alsa_msp_adev,p_cnxt->buffer[1], p_cnxt->data_size,p_cnxt->buffer[0], p_cnxt->data_size);
+
+#if DRIVER_DEBUG > 1
+ stm_dbg(DBG_ST.alsa, " Receiving \n");
+#endif
+ u8500_acodec_receive_data(I2S_CLIENT_MSP1, (void *)sample,
+ count, 0);
+
+#if DRIVER_DEBUG > 1
+ stm_dbg(DBG_ST.alsa, " Transmitting \n");
+#endif
+ u8500_acodec_send_data(I2S_CLIENT_MSP1, (void *)sample, count,
+ 0);
+
+ }
+ printk("\n Rx-Tx : digital_lpbk_msp_rx_tx_thread ended \n");
+ return 0;
+}
+
+#endif
+
+#ifdef CONFIG_U8500_ACODEC_DMA
+
+static void u8500_digital_lpbk_dma_start()
+{
+ u8500_acodec_loopback_configure(I2S_CLIENT_MSP1,
+ (void *)digital_lpbk_cnxt.buffer.addr,
+ digital_lpbk_cnxt.data_size, 1);
+
+ stm_dbg(DBG_ST.alsa, " Rx DMA Transfer started\n");
+ stm_dbg(DBG_ST.alsa, " Rx : add = %x size=%d\n",
+ (int)(digital_lpbk_cnxt.buffer.addr),
+ digital_lpbk_cnxt.data_size);
+
+}
+#endif
+
+/**
+* u8500_acodec_toggle_digital_lpbk
+* @output_device: output device HP/LSP
+*
+* This routine selects the output device Headphone or loud speaker
+*/
+
+t_ab8500_codec_error u8500_acodec_toggle_digital_lpbk(t_u8500_bool_state
+ lpbk_state,
+ t_ab8500_codec_dest
+ dest_device,
+ t_ab8500_codec_src
+ src_device,
+ t_acodec_user user,
+ t_u8500_bool_state
+ tdm8_ch_mode)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+ struct acodec_configuration acodec_config;
+ int status = 0;
+
+ stm_dbg(DBG_ST.acodec,
+ " Entering u8500_acodec_toggle_digital_lpbk() \n");
+
+ user = user; //keep compiler happy
+
+ if (ENABLE == lpbk_state) {
+ //data_size = 1024*100;
+
+ //data[0] = (unsigned char *)kmalloc(data_size, GFP_KERNEL);
+
+ codec_error = AB8500_CODEC_Reset();
+
+ //AB8500_CODEC_SelectInterface(AB8500_CODEC_AUDIO_INTERFACE_0);
+
+ //codec_error = AB8500_CODEC_PowerUp();
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_PowerUp failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ status = u8500_acodec_open(I2S_CLIENT_MSP1, 0);
+ if (status) {
+ printk("failed in getting acodec playback open\n");
+ return -1;
+ }
+ status = u8500_acodec_open(I2S_CLIENT_MSP1, 1);
+ if (status) {
+ printk("failed in getting acdoec capture open\n");
+ return -1;
+ }
+
+ u8500_acodec_setuser(USER_ALSA);
+
+ if (ENABLE == tdm8_ch_mode) {
+ printk("\n 20 bit 8 ch Digital Loopback");
+ printk("\n DMIC1 -> HS-L");
+ printk("\n DMIC2 -> HS-R");
+ printk("\n DMIC3 -> IHF-L");
+ printk("\n DMIC5 -> Vibra-L\n");
+ printk("\n DMIC6 -> Vibra-R\n");
+ printk("\n FM -> FM Tx\n");
+ } else {
+ printk("\n 16 bit 2 ch Digital Loopback");
+ printk("\n DMIC1 -> HS-L");
+ printk("\n DMIC2 -> HS-R");
+ }
+
+ stm_dbg(DBG_ST.alsa, "enabling audiocodec audio mode\n");
+ acodec_config.direction = AB8500_CODEC_DIRECTION_INOUT;
+ acodec_config.input_frequency = T_CODEC_SAMPLING_FREQ_48KHZ;
+ acodec_config.output_frequency = T_CODEC_SAMPLING_FREQ_48KHZ;
+ acodec_config.mspClockSel = CODEC_MSP_APB_CLOCK;
+ acodec_config.mspInClockFreq = CODEC_MSP_INPUT_FREQ_48MHZ;
+ acodec_config.channels = 2;
+ acodec_config.user = 2;
+ acodec_config.acodec_config_need = ACODEC_CONFIG_REQUIRED;
+ acodec_config.direct_rendering_mode = DISABLE;
+ acodec_config.tdm8_ch_mode = tdm8_ch_mode;
+ acodec_config.digital_loopback = ENABLE;
+#ifdef CONFIG_U8500_ACODEC_POLL
+ acodec_config.handler = NULL;
+ acodec_config.tx_callback_data = NULL;
+ acodec_config.rx_callback_data = NULL;
+#endif
+ u8500_acodec_enable_audio_mode(&acodec_config);
+
+ /*turn on src devices */
+
+ perform_src_routing(src_device);
+
+/* u8500_acodec_set_src_power_cntrl(src_device,ENABLE);
+ u8500_acodec_set_input_volume(src_device,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_2,ENABLE);
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_2,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_3,ENABLE);
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_3,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_4,ENABLE);
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_4,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_5,ENABLE);
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_5,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_6,ENABLE);
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_6,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_D_MICROPHONE_6,ENABLE);
+ u8500_acodec_set_input_volume(AB8500_CODEC_SRC_D_MICROPHONE_6,50,50,USER_ALSA);
+
+ u8500_acodec_set_src_power_cntrl(AB8500_CODEC_SRC_FM_RX,ENABLE); */
+
+ /*turn on dest devices */
+
+ //u8500_acodec_set_dest_power_cntrl(dest_device,ENABLE);
+ u8500_acodec_allocate_da_slot(dest_device, TDM_8_CH_MODE);
+ codec_error = AB8500_CODEC_SelectOutput(dest_device);
+ u8500_acodec_set_output_volume(dest_device, 100, 100,
+ USER_ALSA);
+
+ /*u8500_acodec_set_dest_power_cntrl(AB8500_CODEC_DEST_HEADSET,ENABLE);
+ u8500_acodec_set_output_volume(AB8500_CODEC_DEST_HEADSET,100,100,USER_ALSA); */
+
+ /*u8500_acodec_set_dest_power_cntrl(AB8500_CODEC_DEST_HANDSFREE,ENABLE);
+ u8500_acodec_set_output_volume(AB8500_CODEC_DEST_HANDSFREE,100,100,USER_ALSA); */
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+ codec_error =
+ AB8500_CODEC_DASlotAllocation
+ (AB8500_CODEC_DA_CHANNEL_NUMBER_5,
+ AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT12);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ codec_error =
+ AB8500_CODEC_DASlotAllocation
+ (AB8500_CODEC_DA_CHANNEL_NUMBER_6,
+ AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT13);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ codec_error =
+ AB8500_CODEC_DASlotAllocation
+ (AB8500_CODEC_DA_CHANNEL_NUMBER_7,
+ AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT14);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ codec_error =
+ AB8500_CODEC_DASlotAllocation
+ (AB8500_CODEC_DA_CHANNEL_NUMBER_8,
+ AB8500_CODEC_CR51_TO_CR58_SLTODA_SLOT15);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+#else
+ codec_error =
+ AB8500_CODEC_DASlotAllocation
+ (AB8500_CODEC_DA_CHANNEL_NUMBER_5,
+ AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT12);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+
+ codec_error =
+ AB8500_CODEC_DASlotAllocation
+ (AB8500_CODEC_DA_CHANNEL_NUMBER_6,
+ AB8500_CODEC_CR51_TO_CR56_SLTODA_SLOT13);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_daslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+#endif
+
+ digital_lpbk_cnxt.data_size = 2048;
+
+ digital_lpbk_cnxt.rx_active = 1;
+ digital_lpbk_cnxt.tx_active = 1;
+
+ digital_lpbk_cnxt.rx_index = 0;
+ digital_lpbk_cnxt.tx_index = 2;
+
+ digital_lpbk_cnxt.buffer.area =
+ dma_alloc_coherent(NULL, digital_lpbk_cnxt.data_size,
+ &digital_lpbk_cnxt.buffer.addr,
+ GFP_KERNEL);
+ if (NULL == digital_lpbk_cnxt.buffer.area) {
+ printk("\n dma_alloc_coherent failed \n");
+ }
+#if DRIVER_DEBUG > 0
+ {
+ dump_msp_registers();
+ dump_acodec_registers();
+ }
+#endif
+
+#ifdef CONFIG_U8500_ACODEC_POLL
+ {
+ pid_t pid_rx_tx;
+ pid_rx_tx =
+ kernel_thread(digital_lpbk_msp_rx_tx_thread,
+ &digital_lpbk_cnxt,
+ CLONE_FS | CLONE_SIGHAND);
+ }
+#elif defined(CONFIG_U8500_ACODEC_DMA)
+ {
+ u8500_digital_lpbk_dma_start();
+ }
+#endif
+ } else //lpbk is disable
+ {
+
+ digital_lpbk_cnxt.rx_active = 0;
+ digital_lpbk_cnxt.tx_active = 0;
+
+ dma_free_coherent(NULL, digital_lpbk_cnxt.data_size,
+ digital_lpbk_cnxt.buffer.area,
+ digital_lpbk_cnxt.buffer.addr);
+
+ u8500_acodec_set_src_power_cntrl
+ (AB8500_CODEC_SRC_D_MICROPHONE_1, DISABLE);
+ u8500_acodec_set_src_power_cntrl
+ (AB8500_CODEC_SRC_D_MICROPHONE_2, DISABLE);
+ u8500_acodec_set_src_power_cntrl
+ (AB8500_CODEC_SRC_D_MICROPHONE_3, DISABLE);
+ u8500_acodec_set_src_power_cntrl
+ (AB8500_CODEC_SRC_D_MICROPHONE_4, DISABLE);
+
+ u8500_acodec_set_dest_power_cntrl(AB8500_CODEC_DEST_HEADSET,
+ DISABLE);
+ u8500_acodec_set_dest_power_cntrl(AB8500_CODEC_DEST_HANDSFREE,
+ DISABLE);
+
+ u8500_acodec_unsetuser(USER_ALSA);
+ u8500_acodec_close(I2S_CLIENT_MSP1, ACODEC_DISABLE_ALL);
+ }
+ return codec_error;
+}
+
+t_ab8500_codec_error perform_src_routing(t_ab8500_codec_src input_device)
+{
+ int src_type = 0;
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line1;
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line2;
+ t_ab8500_codec_src input_device1;
+ t_ab8500_codec_src input_device2;
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ switch (input_device) {
+ case AB8500_CODEC_SRC_D_MICROPHONE_1:
+ {
+ src_type = MONO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT1;
+ }
+ break;
+ case AB8500_CODEC_SRC_MICROPHONE_2:
+ case AB8500_CODEC_SRC_D_MICROPHONE_2:
+ {
+ src_type = MONO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT2;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_3:
+ case AB8500_CODEC_SRC_MICROPHONE_1A:
+ case AB8500_CODEC_SRC_MICROPHONE_1B:
+ {
+ src_type = MONO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT3;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_4:
+ {
+ src_type = MONO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT4;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_5:
+ {
+ src_type = MONO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT5;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_6:
+ {
+ src_type = MONO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT6;
+ }
+ break;
+ case AB8500_CODEC_SRC_LINEIN:
+ {
+ src_type = STEREO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT1;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT2;
+ input_device1 = AB8500_CODEC_SRC_LINEIN;
+ input_device2 = AB8500_CODEC_SRC_LINEIN;
+ }
+ break;
+#ifdef CONFIG_U8500_AB8500_CUT10
+ case AB8500_CODEC_SRC_D_MICROPHONE_12:
+ {
+ src_type = STEREO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT1;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT2;
+ input_device1 = AB8500_CODEC_SRC_D_MICROPHONE_1;
+ input_device2 = AB8500_CODEC_SRC_D_MICROPHONE_2;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_34:
+ {
+ src_type = STEREO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT3;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT4;
+ input_device1 = AB8500_CODEC_SRC_D_MICROPHONE_3;
+ input_device2 = AB8500_CODEC_SRC_D_MICROPHONE_4;
+ }
+ break;
+ case AB8500_CODEC_SRC_D_MICROPHONE_56:
+ {
+ src_type = STEREO_SRC;
+ ad_data_line1 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT5;
+ ad_data_line2 =
+ AB8500_CODEC_CR31_TO_CR46_SLOT_OUTPUTS_DATA_FROM_AD_OUT6;
+ input_device1 = AB8500_CODEC_SRC_D_MICROPHONE_5;
+ input_device2 = AB8500_CODEC_SRC_D_MICROPHONE_6;
+ }
+ break;
+#endif /* #ifdef CONFIG_U8500_AB8500_CUT10 */
+ }
+ if (STEREO_SRC == src_type) {
+ u8500_acodec_allocate_all_stereo_slots(ad_data_line1,
+ ad_data_line2);
+ codec_error =
+ AB8500_CODEC_SrcPowerControl(input_device1,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_SrcPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.input_config[input_device1].power_state =
+ ENABLE;
+
+ u8500_acodec_set_input_volume(input_device1, 50, 50, USER_ALSA);
+
+ codec_error =
+ AB8500_CODEC_SrcPowerControl(input_device2,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_SrcPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.input_config[input_device2].power_state =
+ ENABLE;
+
+ u8500_acodec_set_input_volume(input_device2, 50, 50, USER_ALSA);
+ } else {
+ u8500_acodec_allocate_all_mono_slots(ad_data_line1);
+ codec_error =
+ AB8500_CODEC_SrcPowerControl(input_device,
+ AB8500_CODEC_SRC_STATE_ENABLE);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("AB8500_CODEC_SrcPowerControl failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ g_codec_system_context.input_config[input_device].power_state =
+ ENABLE;
+
+ u8500_acodec_set_input_volume(input_device, 50, 50, USER_ALSA);
+ }
+ return AB8500_CODEC_OK;
+}
+
+t_ab8500_codec_error
+ u8500_acodec_allocate_all_mono_slots
+ (t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line1) {
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+ int i;
+
+ for (i = AB8500_CODEC_SLOT0; i <= AB8500_CODEC_SLOT7; i++) {
+ codec_error = AB8500_CODEC_ADSlotAllocation(i, ad_data_line1);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+ return AB8500_CODEC_OK;
+}
+
+t_ab8500_codec_error
+ u8500_acodec_allocate_all_stereo_slots
+ (t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line1,
+ t_ab8500_codec_cr31_to_cr46_ad_data_allocation ad_data_line2) {
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+ int i;
+
+ for (i = AB8500_CODEC_SLOT0; i <= AB8500_CODEC_SLOT7; i += 2) {
+ codec_error = AB8500_CODEC_ADSlotAllocation(i, ad_data_line1);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ codec_error =
+ AB8500_CODEC_ADSlotAllocation(i + 1, ad_data_line2);
+ if (AB8500_CODEC_OK != codec_error) {
+ stm_error("ab8500_codec_adslot_allocation failed\n");
+ return AB8500_CODEC_ERROR;
+ }
+ }
+ return AB8500_CODEC_OK;
+}
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+t_ab8500_codec_error
+u8500_acodec_set_burst_mode_fifo(t_u8500_pmc_rendering_state fifo_state)
+{
+
+}
+#else
+t_ab8500_codec_error
+u8500_acodec_set_burst_mode_fifo(t_u8500_pmc_rendering_state fifo_state)
+{
+ t_ab8500_codec_error ab8500_codec_error;
+ t_ab8500_codec_burst_fifo_config burst_fifo_config;
+
+ if (RENDERING_ENABLE == fifo_state) {
+ burst_fifo_config.cr104_bfifoint = 0x1;
+ burst_fifo_config.cr105_bfifotx = 0xC0;
+ burst_fifo_config.cr106_bfifofsext =
+ AB8500_CODEC_CR106_BFIFOFSEXT_6SLOT_EXTRA_CLK;
+ burst_fifo_config.cr106_bfifomsk =
+ AB8500_CODEC_CR106_BFIFOMSK_AD_DATA0_UNMASKED;
+ burst_fifo_config.cr106_bfifomstr =
+ AB8500_CODEC_CR106_BFIFOMSTR_MASTER_MODE;
+ burst_fifo_config.cr106_bfifostrt =
+ AB8500_CODEC_CR106_BFIFOSTRT_RUNNING;
+ burst_fifo_config.cr107_bfifosampnr = 0x100;
+ burst_fifo_config.cr108_bfifowakeup = 0x1;
+
+ ab8500_codec_error =
+ AB8500_CODEC_ConfigureBurstFifo(&burst_fifo_config);
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return ab8500_codec_error;
+ }
+
+ ab8500_codec_error = AB8500_CODEC_EnableBurstFifo();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return ab8500_codec_error;
+ }
+
+ printk("\n Burst mode activated\n");
+ } else if (RENDERING_DISABLE == fifo_state) {
+ ab8500_codec_error = AB8500_CODEC_DisableBurstFifo();
+ if (AB8500_CODEC_OK != ab8500_codec_error) {
+ return ab8500_codec_error;
+ }
+ printk("\n Burst mode deactivated\n");
+ }
+ return AB8500_CODEC_OK;
+}
+#endif
+/**
+* u8500_acodec_set_user
+*
+* Set the current user for acodec.
+*/
+
+t_ab8500_codec_error u8500_acodec_setuser(t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ FUNC_ENTER();
+
+ if ((g_codec_system_context.cur_user == NO_USER)
+ || (g_codec_system_context.cur_user == user))
+ g_codec_system_context.cur_user = user;
+ else {
+ stm_error
+ (" Trying to acces audiocodec already in use by user %d\n",
+ g_codec_system_context.cur_user);
+ return AB8500_CODEC_ERROR;
+ }
+ FUNC_EXIT();
+ return (codec_error);
+}
+
+/**
+* u8500_acodec_unset_user
+*
+* Unset the current user for acodec.
+*/
+
+t_ab8500_codec_error u8500_acodec_unsetuser(t_acodec_user user)
+{
+ t_ab8500_codec_error codec_error = AB8500_CODEC_OK;
+
+ if (g_codec_system_context.cur_user != user) {
+ stm_error
+ (" Trying to free audiocodec already in use by other user %d\n",
+ g_codec_system_context.cur_user);
+ return AB8500_CODEC_ERROR;
+ } else
+ g_codec_system_context.cur_user = NO_USER;
+
+ return (codec_error);
+}
+
+#if DRIVER_DEBUG > 0
+t_ab8500_codec_error dump_acodec_registers()
+{
+ u8 i;
+
+ for (i = 0; i <= 0x6D; i++)
+ stm_dbg(DBG_ST.acodec, "block=0x0D, adr=%x = %x\n", i,
+ ab8500_read(AB8500_AUDIO, i));
+
+ /*for (i = 0; i < 0x5e; i++)
+ stm_dbg(DBG_ST.acodec,"\n block 1,reg =%d val %x", i, ab8500_read(AB8500_AUDIO, i));
+ */
+ return 0;
+}
+
+t_ab8500_codec_error dump_msp_registers()
+{
+ int i;
+
+ stm_dbg(DBG_ST.acodec, "\nMSP_1 base add = 0x%x\n",
+ (unsigned int)U8500_MSP1_BASE);
+
+ for (i = 0; i < 0x40; i += 4)
+ stm_dbg(DBG_ST.acodec, "msp[0x%x]=0x%x\n", i,
+ readl((char *)(IO_ADDRESS(U8500_MSP1_BASE) + i)));
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dump_msp_registers);
+EXPORT_SYMBOL(dump_acodec_registers);
+#endif
+
+/**
+* u8500_acodec_powerdown
+*
+* This function power off the audio codec.
+*/
+void u8500_acodec_powerdown()
+{
+ AB8500_CODEC_PowerDown();
+}
+
+/**
+* u8500_acodec_init
+*
+* This is the init function for STW5098 audiocodec driver.
+*/
+
+static int i2sdrv_probe(struct i2s_device *i2s)
+{
+
+ /* Allocate driver data */
+ try_module_get(i2s->controller->dev.parent->driver->owner);
+
+ /* Allocate memory to i2sdrv structure */
+ i2sdrv[i2s->chip_select] =
+ kzalloc(sizeof(*i2sdrv[i2s->chip_select]), GFP_KERNEL);
+ if (!i2sdrv[i2s->chip_select])
+ return -ENOMEM;
+
+ /* Initialize the driver data */
+ i2sdrv[i2s->chip_select]->i2s = i2s;
+ i2sdrv[i2s->chip_select]->flag = -1;
+ i2sdrv[i2s->chip_select]->tx_status = 0;
+ i2sdrv[i2s->chip_select]->rx_status = 0;
+ spin_lock_init(&i2sdrv[i2s->chip_select]->i2s_lock);
+
+ i2s_set_drvdata(i2s, (void *)i2sdrv[i2s->chip_select]);
+ return 0;
+}
+
+static int i2sdrv_remove(struct i2s_device *i2s)
+{
+ struct i2sdrv_data *i2sdrv = i2s_get_drvdata(i2s);
+
+ spin_lock_irq(&i2sdrv->i2s_lock);
+ i2sdrv->i2s = NULL;
+ i2s_set_drvdata(i2s, NULL);
+ spin_unlock_irq(&i2sdrv->i2s_lock);
+
+ stm_dbg(DBG_ST.acodec, "Entering AUDIOTRG_CODEC_DeIni\n");
+ stm_dbg(DBG_ST.acodec, "leaving AUDIOTRG_CODEC_DeIni\n");
+ module_put(i2s->controller->dev.parent->driver->owner);
+ printk("Remove of I2S gets called\n");
+ return 0;
+}
+static const struct i2s_device_id acodec_id_table[] = {
+ {"i2s_device.2", 0, 0},
+ {"i2s_device.1", 0, 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2s, acodec_id_table);
+
+static struct i2s_driver i2sdrv_i2s = {
+ .driver = {
+ .name = "u8500_acodec",
+ .owner = THIS_MODULE,
+ },
+ .probe = i2sdrv_probe,
+ .remove = __devexit_p(i2sdrv_remove),
+ .id_table = acodec_id_table,
+
+};
+
+static void ab8500_codec_power_init(void)
+{
+ __u8 data, old_data;
+
+ old_data =
+ ab8500_read(AB8500_SYS_CTRL2_BLOCK, (AB8500_CTRL3_REG & 0xFF));
+
+ data = 0xFE & old_data;
+ ab8500_write(AB8500_SYS_CTRL2_BLOCK, (AB8500_CTRL3_REG & 0xFF), data); //0x0200
+
+ data = 0x02 | old_data;
+ ab8500_write(AB8500_SYS_CTRL2_BLOCK, (AB8500_CTRL3_REG & 0xFF), data); //0x0200
+
+ old_data =
+ ab8500_read(AB8500_SYS_CTRL2_BLOCK,
+ (AB8500_SYSULPCLK_CTRL1_REG & 0xFF));
+#ifdef CONFIG_U8500_AB8500_CUT10
+ data = 0x18 | old_data;
+#else
+ data = 0x10 | old_data;
+#endif
+ ab8500_write(AB8500_SYS_CTRL2_BLOCK, (AB8500_SYSULPCLK_CTRL1_REG & 0xFF), data); //0x020B
+
+ old_data =
+ ab8500_read(AB8500_REGU_CTRL1, (AB8500_REGU_MISC1_REG & 0xFF));
+ data = 0x04 | old_data;
+ ab8500_write(AB8500_REGU_CTRL1, (AB8500_REGU_MISC1_REG & 0xFF), data); //0x380
+
+ old_data =
+ ab8500_read(AB8500_REGU_CTRL1,
+ (AB8500_REGU_VAUDIO_SUPPLY_REG & 0xFF));
+ data = 0x5E | old_data;
+ ab8500_write(AB8500_REGU_CTRL1, (AB8500_REGU_VAUDIO_SUPPLY_REG & 0xFF), data); //0x0383
+
+#ifdef CONFIG_U8500_AB8500_CUT10
+ old_data = ab8500_read(AB8500_MISC, (AB8500_GPIO_DIR4_REG & 0xFF));
+ data = 0x54 | old_data;
+ ab8500_write(AB8500_MISC, (AB8500_GPIO_DIR4_REG & 0xFF), data); //0x1013
+#endif
+}
+
+/**
+* u8500_acodec_deinit
+*
+* exit function for STW5098 audiocodec driver.
+*/
+static int check_device_id()
+{
+ __u8 data;
+
+ data = ab8500_read(AB8500_MISC, (0x80 & 0xFF));
+ if (((data & 0xF0) == 0x10) || ((data & 0xF0) == 0x11)) {
+ /* V1 version */
+#ifndef CONFIG_U8500_AB8500_CUT10
+ printk("ERROR: AB8500 hardware detected is CUT1x\n");
+ return -ENODEV;
+#endif
+ } else {
+#ifndef CONFIG_U8500_AB8500_ED
+ /* ED version */
+ printk("ERROR: AB8500 hardware detected is EarlyDrop\n");
+ return -ENODEV;
+#endif
+ }
+ return 0;
+}
+
+static int __init u8500_acodec_init(void)
+{
+ int status, ret_val;
+ t_ab8500_codec_error error;
+
+ ret_val = check_device_id();
+ if (0 != ret_val)
+ return ret_val;
+
+ status = i2s_register_driver(&i2sdrv_i2s);
+ if (status < 0) {
+ printk("Unable to register i2s driver\n");
+ return status;
+ }
+
+ /*Initialize Audiocodec */
+
+ ab8500_codec_power_init();
+
+ AB8500_CODEC_Init(TRG_CODEC_ADDRESS_ON_SPI_BUS);
+
+ /* Reset CODEC */
+ error = AB8500_CODEC_Reset();
+ if (AB8500_CODEC_OK != error) {
+ stm_error("Error in AB8500_CODEC_Reset\n");
+ return -1;
+ }
+
+ stm_dbg(DBG_ST.acodec, " leaving u8500_acodec_init() \n");
+ return 0;
+}
+
+static void __exit u8500_acodec_deinit(void)
+{
+ stm_dbg(DBG_ST.acodec, "Entering AUDIOTRG_CODEC_DeIni\n");
+ stm_dbg(DBG_ST.acodec, "leaving AUDIOTRG_CODEC_DeIni\n");
+ i2s_unregister_driver(&i2sdrv_i2s);
+}
+
+module_init(u8500_acodec_init);
+module_exit(u8500_acodec_deinit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AB8500 stw5098 audiocodec driver");
+
+/* exported function by audiocodec to be used by SAA driver and ALSA driver */
+
+EXPORT_SYMBOL(u8500_acodec_open);
+EXPORT_SYMBOL(u8500_acodec_close);
+EXPORT_SYMBOL(u8500_acodec_send_data);
+EXPORT_SYMBOL(u8500_acodec_receive_data);
+EXPORT_SYMBOL(u8500_acodec_rates);
+EXPORT_SYMBOL(u8500_acodec_powerdown);
+EXPORT_SYMBOL(u8500_acodec_setuser);
+EXPORT_SYMBOL(u8500_acodec_unsetuser);
+EXPORT_SYMBOL(u8500_acodec_enable_audio_mode);
+//EXPORT_SYMBOL(u8500_acodec_enable_voice_mode);
+EXPORT_SYMBOL(u8500_acodec_get_output_volume);
+EXPORT_SYMBOL(u8500_acodec_get_input_volume);
+EXPORT_SYMBOL(u8500_acodec_set_output_volume);
+EXPORT_SYMBOL(u8500_acodec_set_input_volume);
+EXPORT_SYMBOL(u8500_acodec_select_input);
+EXPORT_SYMBOL(u8500_acodec_select_output);
+
+t_ab8500_codec_error AB8500_CODEC_Write(IN t_uint8 register_offset,
+ IN t_uint8 count, IN t_uint8 * ptr_data)
+{
+ int i;
+ u32 address;
+
+ for (i = 0; i < count; i++) {
+ address = (AB8500_AUDIO << 8) | (register_offset + i);
+ ab8500_write(AB8500_AUDIO, address, ptr_data[i]);
+ }
+ return AB8500_CODEC_OK;
+}
+
+t_ab8500_codec_error AB8500_CODEC_Read(IN t_uint8 register_offset,
+ IN t_uint8 count,
+ IN t_uint8 * dummy_data,
+ IN t_uint8 * ptr_data)
+{
+ int i;
+ u32 address;
+
+ dummy_data = dummy_data; /*keep compiler happy */
+
+ for (i = 0; i < count; i++) {
+ address = (AB8500_AUDIO << 8) | (register_offset + i);
+ ptr_data[i] = ab8500_read(AB8500_AUDIO, address);
+ }
+
+ return AB8500_CODEC_OK;
+}
+
+EXPORT_SYMBOL(u8500_acodec_set_src_power_cntrl);
+EXPORT_SYMBOL(u8500_acodec_set_burst_mode_fifo);
+EXPORT_SYMBOL(u8500_acodec_get_dest_power_state);
+EXPORT_SYMBOL(lpbk_state_in_texts);
+EXPORT_SYMBOL(u8500_acodec_toggle_playback_mute_control);
+EXPORT_SYMBOL(u8500_acodec_set_dest_power_cntrl);
+EXPORT_SYMBOL(power_state_in_texts);
+EXPORT_SYMBOL(u8500_acodec_toggle_capture_mute_control);
+EXPORT_SYMBOL(u8500_acodec_toggle_analog_lpbk);
+EXPORT_SYMBOL(u8500_acodec_toggle_digital_lpbk);
+EXPORT_SYMBOL(tdm_mode_state_in_texts);
+EXPORT_SYMBOL(switch_state_in_texts);
+EXPORT_SYMBOL(pcm_rendering_state_in_texts);
+EXPORT_SYMBOL(direct_rendering_state_in_texts);
+EXPORT_SYMBOL(u8500_acodec_get_src_power_state);
+EXPORT_SYMBOL(i2sdrv);
+EXPORT_SYMBOL(second_config);