From 5574b659236121833f78d32387c77f6188dac4d5 Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Fri, 2 Feb 2018 15:03:56 +0800 Subject: [PATCH] audio: codec: add ad82584f driver PD#156734: audio: codec: add ad82584f driver Change-Id: I1e2d8b452e5560c84c60d965e7a916fa0ff03bf4 Signed-off-by: Xing Wang --- MAINTAINERS | 7 +- arch/arm64/configs/meson64_defconfig | 1 + sound/soc/codecs/amlogic/Kconfig | 11 + sound/soc/codecs/amlogic/Makefile | 2 + sound/soc/codecs/amlogic/ad82584f.c | 994 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/amlogic/ad82584f.h | 20 + 6 files changed, 1034 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/amlogic/ad82584f.c create mode 100644 sound/soc/codecs/amlogic/ad82584f.h diff --git a/MAINTAINERS b/MAINTAINERS index a6a469d..e817e7d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14329,4 +14329,9 @@ F: include/dt-bindings/clock/amlogic,g12a-audio-clk.h F: include/linux/amlogic/media/sound/auge_utils.h F: sound/soc/amlogic/auge/* F: sound/soc/amlogic/common/* -F: sound/soc/codecs/amlogic/aml_codec_t9015.c \ No newline at end of file +F: sound/soc/codecs/amlogic/aml_codec_t9015.c + +AMLOGIC Audio codec AD82584F driver +M: Peipeng Zhao +F: sound/soc/codecs/amlogic/ad82584f.c +F: sound/soc/codecs/amlogic/ad82584f.h \ No newline at end of file diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 6778261..41cb86a 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -450,6 +450,7 @@ CONFIG_AMLOGIC_SND_SOC_PCM186X=y CONFIG_AMLOGIC_SND_SOC_SSM3525=y CONFIG_AMLOGIC_SND_SOC_SSM3515=y CONFIG_AMLOGIC_SND_SOC_TAS575X=y +CONFIG_AMLOGIC_SND_SOC_AD82584F=y CONFIG_AMLOGIC_SND_SOC=y CONFIG_AMLOGIC_SND_SOC_MESON=y CONFIG_AMLOGIC_SND_SOC_AUGE=y diff --git a/sound/soc/codecs/amlogic/Kconfig b/sound/soc/codecs/amlogic/Kconfig index 482e082..b87ae1d 100644 --- a/sound/soc/codecs/amlogic/Kconfig +++ b/sound/soc/codecs/amlogic/Kconfig @@ -135,6 +135,7 @@ config AMLOGIC_SND_SOC_TAS575X Select this if your TAS575X is connected via an I2C bus. Enable Support for Texas INstruments TAS575X CODEC. Select this if your TAS575X is connected via an I2C bus. + config AMLOGIC_SND_SOC_ES7243 bool "EVEREST SEMI ES7243" depends on AMLOGIC_SND_SOC_CODECS @@ -145,4 +146,14 @@ config AMLOGIC_SND_SOC_ES7243 Select this if your ES7243 is connected via an I2C bus. Enable Support for EVEREST SEMI ES7243 CODEC. Select this if your ES7243 is connected via an I2C bus. + +config AMLOGIC_SND_SOC_AD82584F + bool "ESMT AD82584F" + depends on AMLOGIC_SND_SOC_CODECS + depends on I2C + default n + help + Enable Support for ESMT AD82584f CODEC. + Select this if your AD82584F is connected via an I2C bus. + #endif #AMLOGIC_SND_SOC_CODECS diff --git a/sound/soc/codecs/amlogic/Makefile b/sound/soc/codecs/amlogic/Makefile index 2f5d8ec..4002111 100644 --- a/sound/soc/codecs/amlogic/Makefile +++ b/sound/soc/codecs/amlogic/Makefile @@ -15,6 +15,7 @@ snd-soc-tlv320adc3101-objs := tlv320adc3101.o snd-soc-pcm186x-objs := pcm186x.o pcm186x-i2c.o pcm186x-spi.o snd-soc-ssm3515-objs := ssm3515.o snd-soc-ssm3525-objs := ssm3525.o +snd-soc-ad82584f-objs := ad82584f.o # Amlogic obj-$(CONFIG_AMLOGIC_SND_CODEC_DUMMY_CODEC) += snd-soc-dummy_codec.o @@ -32,3 +33,4 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_SSM3515) += snd-soc-ssm3515.o obj-$(CONFIG_AMLOGIC_SND_SOC_SSM3525) += snd-soc-ssm3525.o obj-$(CONFIG_AMLOGIC_SND_SOC_TAS575X) += tas575x.o obj-$(CONFIG_AMLOGIC_SND_SOC_ES7243) += es7243.o +obj-$(CONFIG_AMLOGIC_SND_SOC_AD82584F) += ad82584f.o diff --git a/sound/soc/codecs/amlogic/ad82584f.c b/sound/soc/codecs/amlogic/ad82584f.c new file mode 100644 index 0000000..59ab225 --- /dev/null +++ b/sound/soc/codecs/amlogic/ad82584f.c @@ -0,0 +1,994 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ad82584f.h" + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +static void ad82584f_early_suspend(struct early_suspend *h); +static void ad82584f_late_resume(struct early_suspend *h); +#endif + +#define AD82584F_RATES (SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_64000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000) + +#define AD82584F_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +static const DECLARE_TLV_DB_SCALE(mvol_tlv, -10300, 50, 1); +static const DECLARE_TLV_DB_SCALE(chvol_tlv, -10300, 50, 1); + +static const struct snd_kcontrol_new ad82584f_snd_controls[] = { + SOC_SINGLE_TLV("Master Volume", MVOL, 0, + 0xff, 1, mvol_tlv), + SOC_SINGLE_TLV("Ch1 Volume", C1VOL, 0, + 0xff, 1, chvol_tlv), + SOC_SINGLE_TLV("Ch2 Volume", C2VOL, 0, + 0xff, 1, chvol_tlv), +}; + +static int ad82584f_reg_init(struct snd_soc_codec *codec); +static int ad82584f_set_eq_drc(struct snd_soc_codec *codec); +//static int reset_ad82584f(struct snd_soc_codec *codec); +/* Power-up register defaults */ +struct reg_default ad82584f_reg_defaults[AD82584F_REGISTER_COUNT] = { + {0x00, 0x00},//##State_Control_1 + {0x01, 0x04},//##State_Control_2 + {0x02, 0x00},//##State_Control_3 + {0x03, 0x4e},//##Master_volume_control + {0x04, 0x00},//##Channel_1_volume_control + {0x05, 0x00},//##Channel_2_volume_control + {0x06, 0x18},//##Channel_3_volume_control + {0x07, 0x18},//##Channel_4_volume_control + {0x08, 0x18},//##Channel_5_volume_control + {0x09, 0x18},//##Channel_6_volume_control + {0x0a, 0x10},//##Bass_Tone_Boost_and_Cut + {0x0b, 0x10},//##treble_Tone_Boost_and_Cut + {0x0c, 0x90},//##State_Control_4 + {0x0d, 0x00},//##Channel_1_configuration_registers + {0x0e, 0x00},//##Channel_2_configuration_registers + {0x0f, 0x00},//##Channel_3_configuration_registers + {0x10, 0x00},//##Channel_4_configuration_registers + {0x11, 0x00},//##Channel_5_configuration_registers + {0x12, 0x00},//##Channel_6_configuration_registers + {0x13, 0x00},//##Channel_7_configuration_registers + {0x14, 0x00},//##Channel_8_configuration_registers + {0x15, 0x6a},//##DRC1_limiter_attack/release_rate + {0x16, 0x6a},//##DRC2_limiter_attack/release_rate + {0x17, 0x6a},//##DRC3_limiter_attack/release_rate + {0x18, 0x6a},//##DRC4_limiter_attack/release_rate + {0x19, 0x06},//##Error_Delay + {0x1a, 0x32},//##State_Control_5 + {0x1b, 0x01},//##HVUV_selection + {0x1c, 0x00},//##State_Control_6 + {0x1d, 0x7f},//##Coefficient_RAM_Base_Address + {0x1e, 0x00},//##Top_8-bits_of_coefficients_A1 + {0x1f, 0x00},//##Middle_8-bits_of_coefficients_A1 + {0x20, 0x00},//##Bottom_8-bits_of_coefficients_A1 + {0x21, 0x00},//##Top_8-bits_of_coefficients_A2 + {0x22, 0x00},//##Middle_8-bits_of_coefficients_A2 + {0x23, 0x00},//##Bottom_8-bits_of_coefficients_A2 + {0x24, 0x00},//##Top_8-bits_of_coefficients_B1 + {0x25, 0x00},//##Middle_8-bits_of_coefficients_B1 + {0x26, 0x00},//##Bottom_8-bits_of_coefficients_B1 + {0x27, 0x00},//##Top_8-bits_of_coefficients_B2 + {0x28, 0x00},//##Middle_8-bits_of_coefficients_B2 + {0x29, 0x00},//##Bottom_8-bits_of_coefficients_B2 + {0x2a, 0x40},//##Top_8-bits_of_coefficients_A0 + {0x2b, 0x00},//##Middle_8-bits_of_coefficients_A0 + {0x2c, 0x00},//##Bottom_8-bits_of_coefficients_A0 + {0x2d, 0x40},//##Coefficient_R/W_control + {0x2e, 0x00},//##Protection_Enable/Disable + {0x2f, 0x00},//##Memory_BIST_status + {0x30, 0x00},//##Power_Stage_Status(Read_only) + {0x31, 0x00},//##PWM_Output_Control + {0x32, 0x00},//##Test_Mode_Control_Reg. + {0x33, 0x6d},//##Qua-Ternary/Ternary_Switch_Level + {0x34, 0x00},//##Volume_Fine_tune + {0x35, 0x00},//##Volume_Fine_tune + {0x36, 0x60},//##OC_bypass_&_GVDD_selection + {0x37, 0x52},//##Device_ID_register + {0x38, 0x00},//##RAM1_test_register_address + {0x39, 0x00},//##Top_8-bits_of_RAM1_Data + {0x3a, 0x00},//##Middle_8-bits_of_RAM1_Data + {0x3b, 0x00},//##Bottom_8-bits_of_RAM1_Data + {0x3c, 0x00},//##RAM1_test_r/w_control + {0x3d, 0x00},//##RAM2_test_register_address + {0x3e, 0x00},//##Top_8-bits_of_RAM2_Data + {0x3f, 0x00},//##Middle_8-bits_of_RAM2_Data + {0x40, 0x00},//##Bottom_8-bits_of_RAM2_Data + {0x41, 0x00},//##RAM2_test_r/w_control + {0x42, 0x00},//##Level_Meter_Clear + {0x43, 0x00},//##Power_Meter_Clear + {0x44, 0x02},//##TOP_of_C1_Level_Meter + {0x45, 0xea},//##Middle_of_C1_Level_Meter + {0x46, 0x49},//##Bottom_of_C1_Level_Meter + {0x47, 0x02},//##TOP_of_C2_Level_Meter + {0x48, 0xea},//##Middle_of_C2_Level_Meter + {0x49, 0x49},//##Bottom_of_C2_Level_Meter + {0x4a, 0x00},//##TOP_of_C3_Level_Meter + {0x4b, 0x00},//##Middle_of_C3_Level_Meter + {0x4c, 0x00},//##Bottom_of_C3_Level_Meter + {0x4d, 0x00},//##TOP_of_C4_Level_Meter + {0x4e, 0x00},//##Middle_of_C4_Level_Meter + {0x4f, 0x00},//##Bottom_of_C4_Level_Meter + {0x50, 0x00},//##TOP_of_C5_Level_Meter + {0x51, 0x00},//##Middle_of_C5_Level_Meter + {0x52, 0x00},//##Bottom_of_C5_Level_Meter + {0x53, 0x00},//##TOP_of_C6_Level_Meter + {0x54, 0x00},//##Middle_of_C6_Level_Meter + {0x55, 0x00},//##Bottom_of_C6_Level_Meter + {0x56, 0x00},//##TOP_of_C7_Level_Meter + {0x57, 0x00},//##Middle_of_C7_Level_Meter + {0x58, 0x00},//##Bottom_of_C7_Level_Meter + {0x59, 0x00},//##TOP_of_C8_Level_Meter + {0x5a, 0x00},//##Middle_of_C8_Level_Meter + {0x5b, 0x00},//##Bottom_of_C8_Level_Meter + {0x5c, 0x06},//##I2S_Data_Output_Selection_Register + {0x5d, 0x00},//##Reserve + {0x5e, 0x00},//##Reserve + {0x5f, 0x00},//##Reserve + {0x60, 0x00},//##Reserve + {0x61, 0x00},//##Reserve + {0x62, 0x00},//##Reserve + {0x63, 0x00},//##Reserve + {0x64, 0x00},//##Reserve + {0x65, 0x00},//##Reserve + {0x66, 0x00},//##Reserve + {0x67, 0x00},//##Reserve + {0x68, 0x00},//##Reserve + {0x69, 0x00},//##Reserve + {0x6a, 0x00},//##Reserve + {0x6b, 0x00},//##Reserve + {0x6c, 0x00},//##Reserve + {0x6d, 0x00},//##Reserve + {0x6e, 0x00},//##Reserve + {0x6f, 0x00},//##Reserve + {0x70, 0x00},//##Reserve + {0x71, 0x00},//##Reserve + {0x72, 0x00},//##Reserve + {0x73, 0x00},//##Reserve + {0x74, 0x00},//##Mono_Key_High_Byte + {0x75, 0x00},//##Mono_Key_Low_Byte + {0x76, 0x00},//##Boost_Control + {0x77, 0x07},//##Hi-res_Item + {0x78, 0x40},//##Test_Mode_register + {0x79, 0x62},//##Boost_Strap_OV/UV_Selection + {0x7a, 0x8c},//##OC_Selection_2 + {0x7b, 0x55},//##MBIST_User_Program_Top_Byte_Even + {0x7c, 0x55},//##MBIST_User_Program_Middle_Byte_Even + {0x7d, 0x55},//##MBIST_User_Program_Bottom_Byte_Even + {0x7e, 0x55},//##MBIST_User_Program_Top_Byte_Odd + {0x7f, 0x55},//##MBIST_User_Program_Middle_Byte_Odd + {0x80, 0x55},//##MBIST_User_Program_Bottom_Byte_Odd + {0x81, 0x00},//##ERROR_clear_register + {0x82, 0x0c},//##Minimum_duty_test + {0x83, 0x06},//##Reserve + {0x84, 0xfe},//##Reserve + {0x85, 0x6a},//##Reserve + +}; + +static int m_reg_tab[AD82584F_REGISTER_COUNT][2] = { + {0x00, 0x00},//##State_Control_1 + {0x01, 0x04},//##State_Control_2 + {0x02, 0x00},//##State_Control_3 + {0x03, 0x4e},//##Master_volume_control + {0x04, 0x00},//##Channel_1_volume_control + {0x05, 0x00},//##Channel_2_volume_control + {0x06, 0x18},//##Channel_3_volume_control + {0x07, 0x18},//##Channel_4_volume_control + {0x08, 0x18},//##Channel_5_volume_control + {0x09, 0x18},//##Channel_6_volume_control + {0x0a, 0x10},//##Bass_Tone_Boost_and_Cut + {0x0b, 0x10},//##treble_Tone_Boost_and_Cut + {0x0c, 0x90},//##State_Control_4 + {0x0d, 0x00},//##Channel_1_configuration_registers + {0x0e, 0x00},//##Channel_2_configuration_registers + {0x0f, 0x00},//##Channel_3_configuration_registers + {0x10, 0x00},//##Channel_4_configuration_registers + {0x11, 0x00},//##Channel_5_configuration_registers + {0x12, 0x00},//##Channel_6_configuration_registers + {0x13, 0x00},//##Channel_7_configuration_registers + {0x14, 0x00},//##Channel_8_configuration_registers + {0x15, 0x6a},//##DRC1_limiter_attack/release_rate + {0x16, 0x6a},//##DRC2_limiter_attack/release_rate + {0x17, 0x6a},//##DRC3_limiter_attack/release_rate + {0x18, 0x6a},//##DRC4_limiter_attack/release_rate + {0x19, 0x06},//##Error_Delay + {0x1a, 0x32},//##State_Control_5 + {0x1b, 0x01},//##HVUV_selection + {0x1c, 0x00},//##State_Control_6 + {0x1d, 0x7f},//##Coefficient_RAM_Base_Address + {0x1e, 0x00},//##Top_8-bits_of_coefficients_A1 + {0x1f, 0x00},//##Middle_8-bits_of_coefficients_A1 + {0x20, 0x00},//##Bottom_8-bits_of_coefficients_A1 + {0x21, 0x00},//##Top_8-bits_of_coefficients_A2 + {0x22, 0x00},//##Middle_8-bits_of_coefficients_A2 + {0x23, 0x00},//##Bottom_8-bits_of_coefficients_A2 + {0x24, 0x00},//##Top_8-bits_of_coefficients_B1 + {0x25, 0x00},//##Middle_8-bits_of_coefficients_B1 + {0x26, 0x00},//##Bottom_8-bits_of_coefficients_B1 + {0x27, 0x00},//##Top_8-bits_of_coefficients_B2 + {0x28, 0x00},//##Middle_8-bits_of_coefficients_B2 + {0x29, 0x00},//##Bottom_8-bits_of_coefficients_B2 + {0x2a, 0x40},//##Top_8-bits_of_coefficients_A0 + {0x2b, 0x00},//##Middle_8-bits_of_coefficients_A0 + {0x2c, 0x00},//##Bottom_8-bits_of_coefficients_A0 + {0x2d, 0x40},//##Coefficient_R/W_control + {0x2e, 0x00},//##Protection_Enable/Disable + {0x2f, 0x00},//##Memory_BIST_status + {0x30, 0x00},//##Power_Stage_Status(Read_only) + {0x31, 0x00},//##PWM_Output_Control + {0x32, 0x00},//##Test_Mode_Control_Reg. + {0x33, 0x6d},//##Qua-Ternary/Ternary_Switch_Level + {0x34, 0x00},//##Volume_Fine_tune + {0x35, 0x00},//##Volume_Fine_tune + {0x36, 0x60},//##OC_bypass_&_GVDD_selection + {0x37, 0x52},//##Device_ID_register + {0x38, 0x00},//##RAM1_test_register_address + {0x39, 0x00},//##Top_8-bits_of_RAM1_Data + {0x3a, 0x00},//##Middle_8-bits_of_RAM1_Data + {0x3b, 0x00},//##Bottom_8-bits_of_RAM1_Data + {0x3c, 0x00},//##RAM1_test_r/w_control + {0x3d, 0x00},//##RAM2_test_register_address + {0x3e, 0x00},//##Top_8-bits_of_RAM2_Data + {0x3f, 0x00},//##Middle_8-bits_of_RAM2_Data + {0x40, 0x00},//##Bottom_8-bits_of_RAM2_Data + {0x41, 0x00},//##RAM2_test_r/w_control + {0x42, 0x00},//##Level_Meter_Clear + {0x43, 0x00},//##Power_Meter_Clear + {0x44, 0x02},//##TOP_of_C1_Level_Meter + {0x45, 0xea},//##Middle_of_C1_Level_Meter + {0x46, 0x49},//##Bottom_of_C1_Level_Meter + {0x47, 0x02},//##TOP_of_C2_Level_Meter + {0x48, 0xea},//##Middle_of_C2_Level_Meter + {0x49, 0x49},//##Bottom_of_C2_Level_Meter + {0x4a, 0x00},//##TOP_of_C3_Level_Meter + {0x4b, 0x00},//##Middle_of_C3_Level_Meter + {0x4c, 0x00},//##Bottom_of_C3_Level_Meter + {0x4d, 0x00},//##TOP_of_C4_Level_Meter + {0x4e, 0x00},//##Middle_of_C4_Level_Meter + {0x4f, 0x00},//##Bottom_of_C4_Level_Meter + {0x50, 0x00},//##TOP_of_C5_Level_Meter + {0x51, 0x00},//##Middle_of_C5_Level_Meter + {0x52, 0x00},//##Bottom_of_C5_Level_Meter + {0x53, 0x00},//##TOP_of_C6_Level_Meter + {0x54, 0x00},//##Middle_of_C6_Level_Meter + {0x55, 0x00},//##Bottom_of_C6_Level_Meter + {0x56, 0x00},//##TOP_of_C7_Level_Meter + {0x57, 0x00},//##Middle_of_C7_Level_Meter + {0x58, 0x00},//##Bottom_of_C7_Level_Meter + {0x59, 0x00},//##TOP_of_C8_Level_Meter + {0x5a, 0x00},//##Middle_of_C8_Level_Meter + {0x5b, 0x00},//##Bottom_of_C8_Level_Meter + {0x5c, 0x06},//##I2S_Data_Output_Selection_Register + {0x5d, 0x00},//##Reserve + {0x5e, 0x00},//##Reserve + {0x5f, 0x00},//##Reserve + {0x60, 0x00},//##Reserve + {0x61, 0x00},//##Reserve + {0x62, 0x00},//##Reserve + {0x63, 0x00},//##Reserve + {0x64, 0x00},//##Reserve + {0x65, 0x00},//##Reserve + {0x66, 0x00},//##Reserve + {0x67, 0x00},//##Reserve + {0x68, 0x00},//##Reserve + {0x69, 0x00},//##Reserve + {0x6a, 0x00},//##Reserve + {0x6b, 0x00},//##Reserve + {0x6c, 0x00},//##Reserve + {0x6d, 0x00},//##Reserve + {0x6e, 0x00},//##Reserve + {0x6f, 0x00},//##Reserve + {0x70, 0x00},//##Reserve + {0x71, 0x00},//##Reserve + {0x72, 0x00},//##Reserve + {0x73, 0x00},//##Reserve + {0x74, 0x00},//##Mono_Key_High_Byte + {0x75, 0x00},//##Mono_Key_Low_Byte + {0x76, 0x00},//##Boost_Control + {0x77, 0x07},//##Hi-res_Item + {0x78, 0x40},//##Test_Mode_register + {0x79, 0x62},//##Boost_Strap_OV/UV_Selection + {0x7a, 0x8c},//##OC_Selection_2 + {0x7b, 0x55},//##MBIST_User_Program_Top_Byte_Even + {0x7c, 0x55},//##MBIST_User_Program_Middle_Byte_Even + {0x7d, 0x55},//##MBIST_User_Program_Bottom_Byte_Even + {0x7e, 0x55},//##MBIST_User_Program_Top_Byte_Odd + {0x7f, 0x55},//##MBIST_User_Program_Middle_Byte_Odd + {0x80, 0x55},//##MBIST_User_Program_Bottom_Byte_Odd + {0x81, 0x00},//##ERROR_clear_register + {0x82, 0x0c},//##Minimum_duty_test + {0x83, 0x06},//##Reserve + {0x84, 0xfe},//##Reserve + {0x85, 0x6a},//##Reserve + +}; + +static int m_ram1_tab[][4] = { + {0x00, 0x00, 0x00, 0x00},//##Channel_1_EQ1_A1 + {0x01, 0x00, 0x00, 0x00},//##Channel_1_EQ1_A2 + {0x02, 0x00, 0x00, 0x00},//##Channel_1_EQ1_B1 + {0x03, 0x00, 0x00, 0x00},//##Channel_1_EQ1_B2 + {0x04, 0x20, 0x00, 0x00},//##Channel_1_EQ1_A0 + {0x05, 0x00, 0x00, 0x00},//##Channel_1_EQ2_A1 + {0x06, 0x00, 0x00, 0x00},//##Channel_1_EQ2_A2 + {0x07, 0x00, 0x00, 0x00},//##Channel_1_EQ2_B1 + {0x08, 0x00, 0x00, 0x00},//##Channel_1_EQ2_B2 + {0x09, 0x20, 0x00, 0x00},//##Channel_1_EQ2_A0 + {0x0a, 0x00, 0x00, 0x00},//##Channel_1_EQ3_A1 + {0x0b, 0x00, 0x00, 0x00},//##Channel_1_EQ3_A2 + {0x0c, 0x00, 0x00, 0x00},//##Channel_1_EQ3_B1 + {0x0d, 0x00, 0x00, 0x00},//##Channel_1_EQ3_B2 + {0x0e, 0x20, 0x00, 0x00},//##Channel_1_EQ3_A0 + {0x0f, 0x00, 0x00, 0x00},//##Channel_1_EQ4_A1 + {0x10, 0x00, 0x00, 0x00},//##Channel_1_EQ4_A2 + {0x11, 0x00, 0x00, 0x00},//##Channel_1_EQ4_B1 + {0x12, 0x00, 0x00, 0x00},//##Channel_1_EQ4_B2 + {0x13, 0x20, 0x00, 0x00},//##Channel_1_EQ4_A0 + {0x14, 0x00, 0x00, 0x00},//##Channel_1_EQ5_A1 + {0x15, 0x00, 0x00, 0x00},//##Channel_1_EQ5_A2 + {0x16, 0x00, 0x00, 0x00},//##Channel_1_EQ5_B1 + {0x17, 0x00, 0x00, 0x00},//##Channel_1_EQ5_B2 + {0x18, 0x20, 0x00, 0x00},//##Channel_1_EQ5_A0 + {0x19, 0x00, 0x00, 0x00},//##Channel_1_EQ6_A1 + {0x1a, 0x00, 0x00, 0x00},//##Channel_1_EQ6_A2 + {0x1b, 0x00, 0x00, 0x00},//##Channel_1_EQ6_B1 + {0x1c, 0x00, 0x00, 0x00},//##Channel_1_EQ6_B2 + {0x1d, 0x20, 0x00, 0x00},//##Channel_1_EQ6_A0 + {0x1e, 0x00, 0x00, 0x00},//##Channel_1_EQ7_A1 + {0x1f, 0x00, 0x00, 0x00},//##Channel_1_EQ7_A2 + {0x20, 0x00, 0x00, 0x00},//##Channel_1_EQ7_B1 + {0x21, 0x00, 0x00, 0x00},//##Channel_1_EQ7_B2 + {0x22, 0x20, 0x00, 0x00},//##Channel_1_EQ7_A0 + {0x23, 0x00, 0x00, 0x00},//##Channel_1_EQ8_A1 + {0x24, 0x00, 0x00, 0x00},//##Channel_1_EQ8_A2 + {0x25, 0x00, 0x00, 0x00},//##Channel_1_EQ8_B1 + {0x26, 0x00, 0x00, 0x00},//##Channel_1_EQ8_B2 + {0x27, 0x20, 0x00, 0x00},//##Channel_1_EQ8_A0 + {0x28, 0x00, 0x00, 0x00},//##Channel_1_EQ9_A1 + {0x29, 0x00, 0x00, 0x00},//##Channel_1_EQ9_A2 + {0x2a, 0x00, 0x00, 0x00},//##Channel_1_EQ9_B1 + {0x2b, 0x00, 0x00, 0x00},//##Channel_1_EQ9_B2 + {0x2c, 0x20, 0x00, 0x00},//##Channel_1_EQ9_A0 + {0x2d, 0x00, 0x00, 0x00},//##Channel_1_EQ10_A1 + {0x2e, 0x00, 0x00, 0x00},//##Channel_1_EQ10_A2 + {0x2f, 0x00, 0x00, 0x00},//##Channel_1_EQ10_B1 + {0x30, 0x00, 0x00, 0x00},//##Channel_1_EQ10_B2 + {0x31, 0x20, 0x00, 0x00},//##Channel_1_EQ10_A0 + {0x32, 0x00, 0x00, 0x00},//##Channel_1_EQ11_A1 + {0x33, 0x00, 0x00, 0x00},//##Channel_1_EQ11_A2 + {0x34, 0x00, 0x00, 0x00},//##Channel_1_EQ11_B1 + {0x35, 0x00, 0x00, 0x00},//##Channel_1_EQ11_B2 + {0x36, 0x20, 0x00, 0x00},//##Channel_1_EQ11_A0 + {0x37, 0x00, 0x00, 0x00},//##Channel_1_EQ12_A1 + {0x38, 0x00, 0x00, 0x00},//##Channel_1_EQ12_A2 + {0x39, 0x00, 0x00, 0x00},//##Channel_1_EQ12_B1 + {0x3a, 0x00, 0x00, 0x00},//##Channel_1_EQ12_B2 + {0x3b, 0x20, 0x00, 0x00},//##Channel_1_EQ12_A0 + {0x3c, 0x00, 0x00, 0x00},//##Channel_1_EQ13_A1 + {0x3d, 0x00, 0x00, 0x00},//##Channel_1_EQ13_A2 + {0x3e, 0x00, 0x00, 0x00},//##Channel_1_EQ13_B1 + {0x3f, 0x00, 0x00, 0x00},//##Channel_1_EQ13_B2 + {0x40, 0x20, 0x00, 0x00},//##Channel_1_EQ13_A0 + {0x41, 0x00, 0x00, 0x00},//##Channel_1_EQ14_A1 + {0x42, 0x00, 0x00, 0x00},//##Channel_1_EQ14_A2 + {0x43, 0x00, 0x00, 0x00},//##Channel_1_EQ14_B1 + {0x44, 0x00, 0x00, 0x00},//##Channel_1_EQ14_B2 + {0x45, 0x20, 0x00, 0x00},//##Channel_1_EQ14_A0 + {0x46, 0x00, 0x00, 0x00},//##Channel_1_EQ15_A1 + {0x47, 0x00, 0x00, 0x00},//##Channel_1_EQ15_A2 + {0x48, 0x00, 0x00, 0x00},//##Channel_1_EQ15_B1 + {0x49, 0x00, 0x00, 0x00},//##Channel_1_EQ15_B2 + {0x4a, 0x20, 0x00, 0x00},//##Channel_1_EQ15_A0 + {0x4b, 0x7f, 0xff, 0xff},//##Channel_1_Mixer1 + {0x4c, 0x00, 0x00, 0x00},//##Channel_1_Mixer2 + {0x4d, 0x7f, 0xff, 0xff},//##Channel_1_Prescale + {0x4e, 0x7f, 0xff, 0xff},//##Channel_1_Postscale + {0x4f, 0xc7, 0xb6, 0x91},//##A0_of_L_channel_SRS_HPF + {0x50, 0x38, 0x49, 0x6e},//##A1_of_L_channel_SRS_HPF + {0x51, 0x0c, 0x46, 0xf8},//##B1_of_L_channel_SRS_HPF + {0x52, 0x0e, 0x81, 0xb9},//##A0_of_L_channel_SRS_LPF + {0x53, 0xf2, 0x2c, 0x12},//##A1_of_L_channel_SRS_LPF + {0x54, 0x0f, 0xca, 0xbb},//##B1_of_L_channel_SRS_LPF + {0x55, 0x20, 0x00, 0x00},//##CH1.2_Power_Clipping + {0x56, 0x20, 0x00, 0x00},//##CCH1.2_DRC1_Attack_threshold + {0x57, 0x08, 0x00, 0x00},//##CH1.2_DRC1_Release_threshold + {0x58, 0x20, 0x00, 0x00},//##CH3.4_DRC2_Attack_threshold + {0x59, 0x08, 0x00, 0x00},//##CH3.4_DRC2_Release_threshold + {0x5a, 0x20, 0x00, 0x00},//##CH5.6_DRC3_Attack_threshold + {0x5b, 0x08, 0x00, 0x00},//##CH5.6_DRC3_Release_threshold + {0x5c, 0x20, 0x00, 0x00},//##CH7.8_DRC4_Attack_threshold + {0x5d, 0x08, 0x00, 0x00},//##CH7.8_DRC4_Release_threshold + {0x5e, 0x00, 0x00, 0x1a},//##Noise_Gate_Attack_Level + {0x5f, 0x00, 0x00, 0x53},//##Noise_Gate_Release_Level + {0x60, 0x00, 0x80, 0x00},//##DRC1_Energy_Coefficient + {0x61, 0x00, 0x20, 0x00},//##DRC2_Energy_Coefficient + {0x62, 0x00, 0x80, 0x00},//##DRC3_Energy_Coefficient + {0x63, 0x00, 0x80, 0x00},//##DRC4_Energy_Coefficient + {0x64, 0x00, 0x81, 0x99},//DRC1_Power_Meter + {0x65, 0x00, 0x00, 0x00},//DRC3_Power_Mete + {0x66, 0x00, 0x00, 0x00},//DRC5_Power_Meter + {0x67, 0x00, 0x00, 0x00},//DRC7_Power_Meter + {0x68, 0x00, 0x00, 0x00},//##Channel_1_DEQ1_A1 + {0x69, 0x00, 0x00, 0x00},//##Channel_1_DEQ1_A2 + {0x6a, 0x00, 0x00, 0x00},//##Channel_1_DEQ1_B1 + {0x6b, 0x00, 0x00, 0x00},//##Channel_1_DEQ1_B2 + {0x6c, 0x20, 0x00, 0x00},//##Channel_1_DEQ1_A0 + {0x6d, 0x00, 0x00, 0x00},//##Channel_1_DEQ2_A1 + {0x6e, 0x00, 0x00, 0x00},//##Channel_1_DEQ2_A2 + {0x6f, 0x00, 0x00, 0x00},//##Channel_1_DEQ2_B1 + {0x70, 0x00, 0x00, 0x00},//##Channel_1_DEQ2_B2 + {0x71, 0x20, 0x00, 0x00},//##Channel_1_DEQ2_A0 + {0x72, 0x00, 0x00, 0x00},//##Channel_1_DEQ3_A1 + {0x73, 0x00, 0x00, 0x00},//##Channel_1_DEQ3_A2 + {0x74, 0x00, 0x00, 0x00},//##Channel_1_DEQ3_B1 + {0x75, 0x00, 0x00, 0x00},//##Channel_1_DEQ3_B2 + {0x76, 0x20, 0x00, 0x00},//##Channel_1_DEQ3_A0 + {0x77, 0x00, 0x00, 0x00},//##Channel_1_DEQ4_A1 + {0x78, 0x00, 0x00, 0x00},//##Channel_1_DEQ4_A2 + {0x79, 0x00, 0x00, 0x00},//##Channel_1_DEQ4_B1 + {0x7a, 0x00, 0x00, 0x00},//##Channel_1_DEQ4_B2 + {0x7b, 0x20, 0x00, 0x00},//##Channel_1_DEQ4_A0 + {0x7c, 0x00, 0x00, 0x00},//##Reserve + {0x7d, 0x00, 0x00, 0x00},//##Reserve + {0x7e, 0x00, 0x00, 0x00},//##Reserve + {0x7f, 0x00, 0x00, 0x00},//##Reserve +}; + +static int m_ram2_tab[][4] = { + {0x00, 0x00, 0x00, 0x00},//##Channel_2_EQ1_A1 + {0x01, 0x00, 0x00, 0x00},//##Channel_2_EQ1_A2 + {0x02, 0x00, 0x00, 0x00},//##Channel_2_EQ1_B1 + {0x03, 0x00, 0x00, 0x00},//##Channel_2_EQ1_B2 + {0x04, 0x20, 0x00, 0x00},//##Channel_2_EQ1_A0 + {0x05, 0x00, 0x00, 0x00},//##Channel_2_EQ2_A1 + {0x06, 0x00, 0x00, 0x00},//##Channel_2_EQ2_A2 + {0x07, 0x00, 0x00, 0x00},//##Channel_2_EQ2_B1 + {0x08, 0x00, 0x00, 0x00},//##Channel_2_EQ2_B2 + {0x09, 0x20, 0x00, 0x00},//##Channel_2_EQ2_A0 + {0x0a, 0x00, 0x00, 0x00},//##Channel_2_EQ3_A1 + {0x0b, 0x00, 0x00, 0x00},//##Channel_2_EQ3_A2 + {0x0c, 0x00, 0x00, 0x00},//##Channel_2_EQ3_B1 + {0x0d, 0x00, 0x00, 0x00},//##Channel_2_EQ3_B2 + {0x0e, 0x20, 0x00, 0x00},//##Channel_2_EQ3_A0 + {0x0f, 0x00, 0x00, 0x00},//##Channel_2_EQ4_A1 + {0x10, 0x00, 0x00, 0x00},//##Channel_2_EQ4_A2 + {0x11, 0x00, 0x00, 0x00},//##Channel_2_EQ4_B1 + {0x12, 0x00, 0x00, 0x00},//##Channel_2_EQ4_B2 + {0x13, 0x20, 0x00, 0x00},//##Channel_2_EQ4_A0 + {0x14, 0x00, 0x00, 0x00},//##Channel_2_EQ5_A1 + {0x15, 0x00, 0x00, 0x00},//##Channel_2_EQ5_A2 + {0x16, 0x00, 0x00, 0x00},//##Channel_2_EQ5_B1 + {0x17, 0x00, 0x00, 0x00},//##Channel_2_EQ5_B2 + {0x18, 0x20, 0x00, 0x00},//##Channel_2_EQ5_A0 + {0x19, 0x00, 0x00, 0x00},//##Channel_2_EQ6_A1 + {0x1a, 0x00, 0x00, 0x00},//##Channel_2_EQ6_A2 + {0x1b, 0x00, 0x00, 0x00},//##Channel_2_EQ6_B1 + {0x1c, 0x00, 0x00, 0x00},//##Channel_2_EQ6_B2 + {0x1d, 0x20, 0x00, 0x00},//##Channel_2_EQ6_A0 + {0x1e, 0x00, 0x00, 0x00},//##Channel_2_EQ7_A1 + {0x1f, 0x00, 0x00, 0x00},//##Channel_2_EQ7_A2 + {0x20, 0x00, 0x00, 0x00},//##Channel_2_EQ7_B1 + {0x21, 0x00, 0x00, 0x00},//##Channel_2_EQ7_B2 + {0x22, 0x20, 0x00, 0x00},//##Channel_2_EQ7_A0 + {0x23, 0x00, 0x00, 0x00},//##Channel_2_EQ8_A1 + {0x24, 0x00, 0x00, 0x00},//##Channel_2_EQ8_A2 + {0x25, 0x00, 0x00, 0x00},//##Channel_2_EQ8_B1 + {0x26, 0x00, 0x00, 0x00},//##Channel_2_EQ8_B2 + {0x27, 0x20, 0x00, 0x00},//##Channel_2_EQ8_A0 + {0x28, 0x00, 0x00, 0x00},//##Channel_2_EQ9_A1 + {0x29, 0x00, 0x00, 0x00},//##Channel_2_EQ9_A2 + {0x2a, 0x00, 0x00, 0x00},//##Channel_2_EQ9_B1 + {0x2b, 0x00, 0x00, 0x00},//##Channel_2_EQ9_B2 + {0x2c, 0x20, 0x00, 0x00},//##Channel_2_EQ9_A0 + {0x2d, 0x00, 0x00, 0x00},//##Channel_2_EQ10_A1 + {0x2e, 0x00, 0x00, 0x00},//##Channel_2_EQ10_A2 + {0x2f, 0x00, 0x00, 0x00},//##Channel_2_EQ10_B1 + {0x30, 0x00, 0x00, 0x00},//##Channel_2_EQ10_B2 + {0x31, 0x20, 0x00, 0x00},//##Channel_2_EQ10_A0 + {0x32, 0x00, 0x00, 0x00},//##Channel_2_EQ11_A1 + {0x33, 0x00, 0x00, 0x00},//##Channel_2_EQ11_A2 + {0x34, 0x00, 0x00, 0x00},//##Channel_2_EQ11_B1 + {0x35, 0x00, 0x00, 0x00},//##Channel_2_EQ11_B2 + {0x36, 0x20, 0x00, 0x00},//##Channel_2_EQ11_A0 + {0x37, 0x00, 0x00, 0x00},//##Channel_2_EQ12_A1 + {0x38, 0x00, 0x00, 0x00},//##Channel_2_EQ12_A2 + {0x39, 0x00, 0x00, 0x00},//##Channel_2_EQ12_B1 + {0x3a, 0x00, 0x00, 0x00},//##Channel_2_EQ12_B2 + {0x3b, 0x20, 0x00, 0x00},//##Channel_2_EQ12_A0 + {0x3c, 0x00, 0x00, 0x00},//##Channel_2_EQ13_A1 + {0x3d, 0x00, 0x00, 0x00},//##Channel_2_EQ13_A2 + {0x3e, 0x00, 0x00, 0x00},//##Channel_2_EQ13_B1 + {0x3f, 0x00, 0x00, 0x00},//##Channel_2_EQ13_B2 + {0x40, 0x20, 0x00, 0x00},//##Channel_2_EQ13_A0 + {0x41, 0x00, 0x00, 0x00},//##Channel_2_EQ14_A1 + {0x42, 0x00, 0x00, 0x00},//##Channel_2_EQ14_A2 + {0x43, 0x00, 0x00, 0x00},//##Channel_2_EQ14_B1 + {0x44, 0x00, 0x00, 0x00},//##Channel_2_EQ14_B2 + {0x45, 0x20, 0x00, 0x00},//##Channel_2_EQ14_A0 + {0x46, 0x00, 0x00, 0x00},//##Channel_2_EQ15_A1 + {0x47, 0x00, 0x00, 0x00},//##Channel_2_EQ15_A2 + {0x48, 0x00, 0x00, 0x00},//##Channel_2_EQ15_B1 + {0x49, 0x00, 0x00, 0x00},//##Channel_2_EQ15_B2 + {0x4a, 0x20, 0x00, 0x00},//##Channel_2_EQ15_A0 + {0x4b, 0x00, 0x00, 0x00},//##Channel_2_Mixer1 + {0x4c, 0x7f, 0xff, 0xff},//##Channel_2_Mixer2 + {0x4d, 0x7f, 0xff, 0xff},//##Channel_2_Prescale + {0x4e, 0x7f, 0xff, 0xff},//##Channel_2_Postscale + {0x4f, 0xc7, 0xb6, 0x91},//##A0_of_R_channel_SRS_HPF + {0x50, 0x38, 0x49, 0x6e},//##A1_of_R_channel_SRS_HPF + {0x51, 0x0c, 0x46, 0xf8},//##B1_of_R_channel_SRS_HPF + {0x52, 0x0e, 0x81, 0xb9},//##A0_of_R_channel_SRS_LPF + {0x53, 0xf2, 0x2c, 0x12},//##A1_of_R_channel_SRS_LPF + {0x54, 0x0f, 0xca, 0xbb},//##B1_of_R_channel_SRS_LPF + {0x55, 0x00, 0x00, 0x00},//##Reserve + {0x56, 0x00, 0x00, 0x00},//##Reserve + {0x57, 0x00, 0x00, 0x00},//##Reserve + {0x58, 0x00, 0x00, 0x00},//##Reserve + {0x59, 0x00, 0x00, 0x00},//##Reserve + {0x5a, 0x00, 0x00, 0x00},//##Reserve + {0x5b, 0x00, 0x00, 0x00},//##Reserve + {0x5c, 0x00, 0x00, 0x00},//##Reserve + {0x5d, 0x00, 0x00, 0x00},//##Reserve + {0x5e, 0x00, 0x00, 0x00},//##Reserve + {0x5f, 0x00, 0x00, 0x00},//##Reserve + {0x60, 0x00, 0x00, 0x00},//##Reserve + {0x61, 0x00, 0x00, 0x00},//##Reserve + {0x62, 0x00, 0x00, 0x00},//##Reserve + {0x63, 0x00, 0x00, 0x00},//##Reserve + {0x64, 0x00, 0x84, 0x1b},//DRC2_Power_Meter + {0x65, 0x00, 0x00, 0x00},//DRC4_Power_Mete + {0x66, 0x00, 0x00, 0x00},//DRC6_Power_Meter + {0x67, 0x00, 0x00, 0x00},//DRC8_Power_Meter + {0x68, 0x00, 0x00, 0x00},//##Channel_2_DEQ1_A1 + {0x69, 0x00, 0x00, 0x00},//##Channel_2_DEQ1_A2 + {0x6a, 0x00, 0x00, 0x00},//##Channel_2_DEQ1_B1 + {0x6b, 0x00, 0x00, 0x00},//##Channel_2_DEQ1_B2 + {0x6c, 0x20, 0x00, 0x00},//##Channel_2_DEQ1_A0 + {0x6d, 0x00, 0x00, 0x00},//##Channel_2_DEQ2_A1 + {0x6e, 0x00, 0x00, 0x00},//##Channel_2_DEQ2_A2 + {0x6f, 0x00, 0x00, 0x00},//##Channel_2_DEQ2_B1 + {0x70, 0x00, 0x00, 0x00},//##Channel_2_DEQ2_B2 + {0x71, 0x20, 0x00, 0x00},//##Channel_2_DEQ2_A0 + {0x72, 0x00, 0x00, 0x00},//##Channel_2_DEQ3_A1 + {0x73, 0x00, 0x00, 0x00},//##Channel_2_DEQ3_A2 + {0x74, 0x00, 0x00, 0x00},//##Channel_2_DEQ3_B1 + {0x75, 0x00, 0x00, 0x00},//##Channel_2_DEQ3_B2 + {0x76, 0x20, 0x00, 0x00},//##Channel_2_DEQ3_A0 + {0x77, 0x00, 0x00, 0x00},//##Channel_2_DEQ4_A1 + {0x78, 0x00, 0x00, 0x00},//##Channel_2_DEQ4_A2 + {0x79, 0x00, 0x00, 0x00},//##Channel_2_DEQ4_B1 + {0x7a, 0x00, 0x00, 0x00},//##Channel_2_DEQ4_B2 + {0x7b, 0x20, 0x00, 0x00},//##Channel_2_DEQ4_A0 + {0x7c, 0x00, 0x00, 0x00},//##Reserve + {0x7d, 0x00, 0x00, 0x00},//##Reserve + {0x7e, 0x00, 0x00, 0x00},//##Reserve + {0x7f, 0x00, 0x00, 0x00},//##Reserve +}; +/* codec private data */ +struct ad82584f_priv { + struct regmap *regmap; + struct snd_soc_codec *codec; + struct ad82584f_platform_data *pdata; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif +}; + +static int ad82584f_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + return 0; +} + +static int ad82584f_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return 0; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + break; + default: + return 0; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + break; + default: + return 0; + } + + return 0; +} + +static int ad82584f_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + unsigned int rate; + + rate = params_rate(params); + pr_debug("rate: %u\n", rate); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_BE: + pr_debug("24bit\n"); + /* fall through */ + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S20_3LE: + case SNDRV_PCM_FORMAT_S20_3BE: + pr_debug("20bit\n"); + + break; + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_S16_BE: + pr_debug("16bit\n"); + + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ad82584f_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + pr_debug("level = %d\n", level); + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* Full power on */ + break; + + case SND_SOC_BIAS_STANDBY: + break; + + case SND_SOC_BIAS_OFF: + /* The chip runs through the power down sequence for us. */ + break; + } + codec->component.dapm.bias_level = level; + + return 0; +} + +static int ad82584f_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ +#if 0 + struct snd_soc_codec *codec = dai->codec; + + reset_ad82584f(codec); + ad82584f_reg_init(codec); + + /*eq and drc*/ + ad82584f_set_eq_drc(codec); + + /*unmute,default power-on is mute.*/ + snd_soc_write(codec, 0x02, 0x00); +#endif + return 0; + +} +static const struct snd_soc_dai_ops ad82584f_dai_ops = { + .hw_params = ad82584f_hw_params, + .set_sysclk = ad82584f_set_dai_sysclk, + .set_fmt = ad82584f_set_dai_fmt, + .prepare = ad82584f_prepare, +}; + +static struct snd_soc_dai_driver ad82584f_dai = { + .name = "ad82584f", + .playback = { + .stream_name = "HIFI Playback", + .channels_min = 2, + .channels_max = 8, + .rates = AD82584F_RATES, + .formats = AD82584F_FORMATS, + }, + .ops = &ad82584f_dai_ops, +}; + + +static int ad82584f_set_eq_drc(struct snd_soc_codec *codec) +{ + u8 i; + + for (i = 0; i < AD82584F_RAM_TABLE_COUNT; i++) { + snd_soc_write(codec, CFADDR, m_ram1_tab[i][0]); + snd_soc_write(codec, A1CF1, m_ram1_tab[i][1]); + snd_soc_write(codec, A1CF2, m_ram1_tab[i][2]); + snd_soc_write(codec, A1CF3, m_ram1_tab[i][3]); + snd_soc_write(codec, CFUD, 0x01); + } + for (i = 0; i < AD82584F_RAM_TABLE_COUNT; i++) { + snd_soc_write(codec, CFADDR, m_ram2_tab[i][0]); + snd_soc_write(codec, A1CF1, m_ram2_tab[i][1]); + snd_soc_write(codec, A1CF2, m_ram2_tab[i][2]); + snd_soc_write(codec, A1CF3, m_ram2_tab[i][3]); + snd_soc_write(codec, CFUD, 0x41); + } + return 0; +} + +static int reset_ad82584f_GPIO(struct snd_soc_codec *codec) +{ + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + struct ad82584f_platform_data *pdata = ad82584f->pdata; + int ret = 0; + + if (pdata->reset_pin < 0) + return 0; + + ret = devm_gpio_request_one(codec->dev, pdata->reset_pin, + GPIOF_OUT_INIT_LOW, + "ad82584f-reset-pin"); + if (ret < 0) + return -1; + + gpio_direction_output(pdata->reset_pin, GPIOF_OUT_INIT_LOW); + mdelay(10); + gpio_direction_output(pdata->reset_pin, GPIOF_OUT_INIT_HIGH); + mdelay(15); + + return 0; +} +#if 0 +static int reset_ad82584f(struct snd_soc_codec *codec) +{ + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + struct ad82584f_platform_data *pdata = ad82584f->pdata; + + if (pdata->reset_pin < 0) + return 0; + + gpio_direction_output(pdata->reset_pin, GPIOF_OUT_INIT_LOW); + mdelay(10); + gpio_direction_output(pdata->reset_pin, GPIOF_OUT_INIT_HIGH); + mdelay(15); + + return 0; +} +#endif +static int ad82584f_reg_init(struct snd_soc_codec *codec) +{ + int i = 0; + + for (i = 0; i < AD82584F_REGISTER_COUNT; i++) { + snd_soc_write(codec, m_reg_tab[i][0], m_reg_tab[i][1]); + }; + return 0; + +} +static int ad82584f_init(struct snd_soc_codec *codec) +{ + reset_ad82584f_GPIO(codec); + + dev_info(codec->dev, "ad82584f_init!\n"); + + ad82584f_reg_init(codec); + + /*eq and drc*/ + ad82584f_set_eq_drc(codec); + + /*unmute,default power-on is mute.*/ + snd_soc_write(codec, 0x02, 0x00); + + return 0; +} + +static int ad82584f_probe(struct snd_soc_codec *codec) +{ + +#ifdef CONFIG_HAS_EARLYSUSPEND + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + + ad82584f->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; + ad82584f->early_suspend.suspend = ad82584f_early_suspend; + ad82584f->early_suspend.resume = ad82584f_late_resume; + ad82584f->early_suspend.param = codec; + register_early_suspend(&(ad82584f->early_suspend)); +#endif + ad82584f_init(codec); + + return 0; +} + +static int ad82584f_remove(struct snd_soc_codec *codec) +{ +#ifdef CONFIG_HAS_EARLYSUSPEND + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + + unregister_early_suspend(&(ad82584f->early_suspend)); +#endif + return 0; +} + +#ifdef CONFIG_PM +static int ad82584f_suspend(struct snd_soc_codec *codec) +{ + dev_info(codec->dev, "ad82584f_suspend!\n"); + + return 0; +} + +static int ad82584f_resume(struct snd_soc_codec *codec) +{ + dev_info(codec->dev, "ad82584f_resume!\n"); + + return 0; +} +#else +#define ad82584f_suspend NULL +#define ad82584f_resume NULL +#endif + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void ad82584f_early_suspend(struct early_suspend *h) +{ +} + +static void ad82584f_late_resume(struct early_suspend *h) +{ +} +#endif + +static const struct snd_soc_dapm_widget ad82584f_dapm_widgets[] = { + SND_SOC_DAPM_DAC("DAC", "HIFI Playback", SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_codec_driver soc_codec_dev_ad82584f = { + .probe = ad82584f_probe, + .remove = ad82584f_remove, + .suspend = ad82584f_suspend, + .resume = ad82584f_resume, + .set_bias_level = ad82584f_set_bias_level, + .component_driver = { + .controls = ad82584f_snd_controls, + .num_controls = ARRAY_SIZE(ad82584f_snd_controls), + .dapm_widgets = ad82584f_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ad82584f_dapm_widgets), + } +}; + +static const struct regmap_config ad82584f_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = AD82584F_REGISTER_COUNT, + .reg_defaults = ad82584f_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(ad82584f_reg_defaults), + .cache_type = REGCACHE_RBTREE, +}; + +static int ad82584f_parse_dt( + struct ad82584f_priv *ad82584f, + struct device_node *np) +{ + int ret = 0; + int reset_pin = -1; + + reset_pin = of_get_named_gpio(np, "reset_pin", 0); + if (reset_pin < 0) { + pr_err("%s fail to get reset pin from dts!\n", __func__); + ret = -1; + } else { + pr_info("%s pdata->reset_pin = %d!\n", __func__, + ad82584f->pdata->reset_pin); + } + ad82584f->pdata->reset_pin = reset_pin; + + return ret; +} + +static int ad82584f_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct ad82584f_priv *ad82584f; + struct ad82584f_platform_data *pdata; + int ret; + + ad82584f = devm_kzalloc(&i2c->dev, sizeof(struct ad82584f_priv), + GFP_KERNEL); + if (!ad82584f) + return -ENOMEM; + + ad82584f->regmap = devm_regmap_init_i2c(i2c, &ad82584f_regmap); + if (IS_ERR(ad82584f->regmap)) { + ret = PTR_ERR(ad82584f->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + i2c_set_clientdata(i2c, ad82584f); + + pdata = devm_kzalloc(&i2c->dev, + sizeof(struct ad82584f_platform_data), + GFP_KERNEL); + if (!pdata) { + pr_err("%s failed to kzalloc for ad82584f pdata\n", __func__); + return -ENOMEM; + } + ad82584f->pdata = pdata; + + ad82584f_parse_dt(ad82584f, i2c->dev.of_node); + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ad82584f, + &ad82584f_dai, 1); + if (ret != 0) + dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret); + + return ret; +} + +static int ad82584f_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + + return 0; +} + +static const struct i2c_device_id ad82584f_i2c_id[] = { + { " ad82584f", 0 }, + {} +}; + +static const struct of_device_id ad82584f_of_id[] = { + { .compatible = "ESMT, ad82584f", }, + { /* senitel */ } +}; +MODULE_DEVICE_TABLE(of, ad82584f_of_id); + +static struct i2c_driver ad82584f_i2c_driver = { + .driver = { + .name = "ad82584f", + .of_match_table = ad82584f_of_id, + .owner = THIS_MODULE, + }, + .probe = ad82584f_i2c_probe, + .remove = ad82584f_i2c_remove, + .id_table = ad82584f_i2c_id, +}; + +module_i2c_driver(ad82584f_i2c_driver); + +MODULE_DESCRIPTION("ASoC ad82584f driver"); +MODULE_AUTHOR("AML MM team"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/amlogic/ad82584f.h b/sound/soc/codecs/amlogic/ad82584f.h new file mode 100644 index 0000000..f363938a --- /dev/null +++ b/sound/soc/codecs/amlogic/ad82584f.h @@ -0,0 +1,20 @@ +#ifndef _AD82584F_H +#define _AD82584F_H + +#define MVOL 0x03 +#define C1VOL 0x04 +#define C2VOL 0x05 +#define CFADDR 0x1d +#define A1CF1 0x1e +#define A1CF2 0x1f +#define A1CF3 0x20 +#define CFUD 0x2d + +#define AD82584F_REGISTER_COUNT 0x86 +#define AD82584F_RAM_TABLE_COUNT 0x80 + +struct ad82584f_platform_data { + int reset_pin; +}; + +#endif -- 2.7.4