From cdac37540498dcaef47e79f14a8cc06712872b7e Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 17 Mar 2016 18:22:41 +0800 Subject: [PATCH] ASoC: es8316: add codec driver Change-Id: I6896036a7af922747180535939074f399f8c38d1 Signed-off-by: Sugar Zhang --- .../devicetree/bindings/sound/es8316.txt | 23 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es8316.c | 745 ++++++------------ sound/soc/codecs/es8316.h | 26 + 5 files changed, 297 insertions(+), 504 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/es8316.txt diff --git a/Documentation/devicetree/bindings/sound/es8316.txt b/Documentation/devicetree/bindings/sound/es8316.txt new file mode 100644 index 000000000000..313d87fb9a01 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/es8316.txt @@ -0,0 +1,23 @@ +Everest ES8316 audio CODEC + +Required properties: + + - compatible: "everest,es8316" + - reg: the I2C address of the device for I2C + - spk-con-gpio: spk mute enable/disable + - hp-det-gpio: headphone detect gpio +Optional properties: + +- clocks: The phandle of the master clock to the CODEC +- clock-names: Should be "mclk" + +Example: + +codec: es8316@10 { + compatible = "everest,es8316"; + reg = <0x10>; + clocks = <&cru SCLK_I2S_8CH_OUT>; + clock-names = "mclk"; + spk-con-gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>; + hp-det-gpio = <&gpio4 28 GPIO_ACTIVE_HIGH>; +}; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 48173b198a93..f6f944aaf7af 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -63,6 +63,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DA9055 if I2C select SND_SOC_DMIC select SND_SOC_BT_SCO + select SND_SOC_ES8316 if I2C select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C select SND_SOC_GTM601 @@ -454,6 +455,10 @@ config SND_SOC_BT_SCO config SND_SOC_DMIC tristate +config SND_SOC_ES8316 + tristate "Everest Semi ES8316 CODEC" + depends on I2C + config SND_SOC_ES8328 tristate "Everest Semi ES8328 CODEC" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index f632fc42f59f..4682308b912f 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -55,6 +55,7 @@ snd-soc-da732x-objs := da732x.o snd-soc-da9055-objs := da9055.o snd-soc-bt-sco-objs := bt-sco.o snd-soc-dmic-objs := dmic.o +snd-soc-es8316-objs := es8316.o snd-soc-es8328-objs := es8328.o snd-soc-es8328-i2c-objs := es8328-i2c.o snd-soc-es8328-spi-objs := es8328-spi.o @@ -250,6 +251,7 @@ obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o +obj-$(CONFIG_SND_SOC_ES8316) += snd-soc-es8316.o obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index eb8357be0ed5..1e082f39e97b 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -34,36 +35,10 @@ #include #include "es8316.h" -#if 1 -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif -#define alsa_dbg DBG - -#define dmic_used 1 -#define amic_used 0 - #define INVALID_GPIO -1 - -#define ES8316_CODEC_SET_SPK 1 -#define ES8316_CODEC_SET_HP 2 - - -int HP_IRQ = 0; -int hp_irq_flag = 0; -int es8316_init_reg = 0; - #define GPIO_LOW 0 #define GPIO_HIGH 1 -#ifndef es8316_DEF_VOL #define es8316_DEF_VOL 0x1e -#endif - -struct snd_soc_codec *es8316_codec; -static int es8316_init_regs(struct snd_soc_codec *codec); -static int es8316_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level); static const struct reg_default es8316_reg_defaults[] = { {0x00, 0x03}, {0x01, 0x03}, {0x02, 0x00}, {0x03, 0x20}, @@ -89,40 +64,26 @@ static const struct reg_default es8316_reg_defaults[] = { {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, }; -static int es8316_readable(struct snd_soc_codec *codec, unsigned int reg) -{ - if (reg <= 90) - return 1; - else - return 0; -} -static int es8316_volatile(struct snd_soc_codec *codec, unsigned int reg) -{ - if (reg <= 90) - return 1; - else - return 0; -} /* codec private data */ struct es8316_priv { struct regmap *regmap; unsigned int dmic_amic; unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; + struct clk *mclk; + int debounce_time; + int hp_det_invert; + struct delayed_work work; int spk_ctl_gpio; - int hp_ctl_gpio; int hp_det_gpio; - - bool spk_gpio_level; - bool hp_gpio_level; - bool hp_det_level; + bool muted; + bool hp_inserted; + bool spk_active_level; int pwr_count; }; -struct es8316_priv *es8316_private; - /* * es8316_reset * write value 0xff to reg0x00, the chip will be in reset mode @@ -135,73 +96,19 @@ static int es8316_reset(struct snd_soc_codec *codec) return snd_soc_write(codec, ES8316_RESET_REG00, 0x03); } -static int es8316_set_gpio(int gpio, bool level) -{ - struct es8316_priv *es8316 = es8316_private; - - if (!es8316) { - DBG("%s : es8316_priv is NULL\n", __func__); - return 0; - } - DBG("%s : set %s %s ctl gpio %s\n", __func__, - gpio & ES8316_CODEC_SET_SPK ? "spk" : "", - gpio & ES8316_CODEC_SET_HP ? "hp" : "", - level ? "HIGH" : "LOW"); - if ((gpio & ES8316_CODEC_SET_SPK) - && es8316 && es8316->spk_ctl_gpio != INVALID_GPIO) { - DBG("%d,set_value%s\n", es8316->spk_ctl_gpio, level ? - "HIGH" : "LOW"); - gpio_set_value(es8316->spk_ctl_gpio, level); - } - return 0; -} - -static char mute_flag = 1; -static irqreturn_t hp_det_irq_handler(int irq, void *dev_id) +static void es8316_enable_spk(struct es8316_priv *es8316, bool enable) { - int ret; - unsigned int type; - struct es8316_priv *es8316 = es8316_private; - - disable_irq_nosync(irq); - - type = gpio_get_value(es8316->hp_det_gpio) ? - IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; - ret = irq_set_irq_type(irq, type); - if (ret < 0) { - DBG("%s: irq_set_irq_type(%d, %d) failed\n", - __func__, irq, type); - return -1; - } - - if (es8316->hp_det_level != gpio_get_value(es8316->hp_det_gpio)) - hp_irq_flag = 0; - else - hp_irq_flag = 1; - if (mute_flag == 0) { - if (es8316->hp_det_level == gpio_get_value(es8316->hp_det_gpio)) - es8316_set_gpio(ES8316_CODEC_SET_SPK, - !es8316->spk_gpio_level); - else - es8316_set_gpio(ES8316_CODEC_SET_SPK, - es8316->spk_gpio_level); - } - enable_irq(irq); + bool level; - return IRQ_HANDLED; + level = enable ? es8316->spk_active_level : !es8316->spk_active_level; + gpio_set_value(es8316->spk_ctl_gpio, level); } -/* -* es8316S Controls -*/ -/*#define DECLARE_TLV_DB_SCALE(name, min, step, mute) */ -/*static const DECLARE_TLV_DB_SCALE(hpout_vol_tlv, -4800, 1200, 0);*/ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9600, 50, 1); static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -9600, 50, 1); static const DECLARE_TLV_DB_SCALE(hpmixer_gain_tlv, -1200, 150, 0); static const DECLARE_TLV_DB_SCALE(mic_bst_tlv, 0, 1200, 0); -/*static const DECLARE_TLV_DB_SCALE(linin_pga_tlv, 0, 300, 0);*/ -/* {0, +3, +6, +9, +12, +15, +18, +21, +24,+27,+30,+33} dB */ + static unsigned int linin_pga_tlv[] = { TLV_DB_RANGE_HEAD(12), 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), @@ -214,24 +121,31 @@ static unsigned int linin_pga_tlv[] = { 7, 7, TLV_DB_SCALE_ITEM(2100, 0, 0), 8, 8, TLV_DB_SCALE_ITEM(2400, 0, 0), }; + static unsigned int hpout_vol_tlv[] = { TLV_DB_RANGE_HEAD(1), 0, 3, TLV_DB_SCALE_ITEM(-4800, 1200, 0), }; -static const char *const alc_func_txt[] = {"Off", "On"}; + +static const char *const alc_func_txt[] = { "Off", "On" }; + static const struct soc_enum alc_func = SOC_ENUM_SINGLE(ES8316_ADC_ALC1_REG29, 6, 2, alc_func_txt); -static const char *const ng_type_txt[] = {"Constant PGA Gain", - "Mute ADC Output"}; +static const char *const ng_type_txt[] = { + "Constant PGA Gain", "Mute ADC Output" }; + static const struct soc_enum ng_type = SOC_ENUM_SINGLE(ES8316_ADC_ALC6_REG2E, 6, 2, ng_type_txt); -static const char *const adcpol_txt[] = {"Normal", "Invert"}; +static const char *const adcpol_txt[] = { "Normal", "Invert" }; + static const struct soc_enum adcpol = SOC_ENUM_SINGLE(ES8316_ADC_MUTE_REG26, 1, 2, adcpol_txt); -static const char *const dacpol_txt[] = {"Normal", "R Invert", "L Invert", - "L + R Invert"}; + +static const char *const dacpol_txt[] = { + "Normal", "R Invert", "L Invert", "L + R Invert" }; + static const struct soc_enum dacpol = SOC_ENUM_SINGLE(ES8316_DAC_SET1_REG30, 0, 4, dacpol_txt); @@ -285,41 +199,38 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = { /* Analog Input MUX */ static const char * const es8316_analog_in_txt[] = { - "lin1-rin1", - "lin2-rin2", - "lin1-rin1 with 20db Boost", - "lin2-rin2 with 20db Boost" -}; -static const unsigned int es8316_analog_in_values[] = { - 0,/*1,*/ - 1, - 2, - 3 + "lin1-rin1", + "lin2-rin2", + "lin1-rin1 with 20db Boost", + "lin2-rin2 with 20db Boost" }; + +static const unsigned int es8316_analog_in_values[] = { 0, 1, 2, 3 }; + static const struct soc_enum es8316_analog_input_enum = SOC_VALUE_ENUM_SINGLE(ES8316_ADC_PDN_LINSEL_REG22, 4, 3, ARRAY_SIZE(es8316_analog_in_txt), es8316_analog_in_txt, es8316_analog_in_values); + static const struct snd_kcontrol_new es8316_analog_in_mux_controls = SOC_DAPM_ENUM("Route", es8316_analog_input_enum); /* Dmic MUX */ static const char * const es8316_dmic_txt[] = { - "dmic disable", - "dmic data at high level", - "dmic data at low level", -}; -static const unsigned int es8316_dmic_values[] = { - 0,/*1,*/ - 1, - 2 + "dmic disable", + "dmic data at high level", + "dmic data at low level", }; + +static const unsigned int es8316_dmic_values[] = { 0, 1, 2 }; + static const struct soc_enum es8316_dmic_src_enum = SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC_REG25, 0, 3, ARRAY_SIZE(es8316_dmic_txt), es8316_dmic_txt, es8316_dmic_values); + static const struct snd_kcontrol_new es8316_dmic_src_controls = SOC_DAPM_ENUM("Route", es8316_dmic_src_enum); @@ -331,23 +242,25 @@ static const char *const es8316_hpmux_texts[] = { "lin-rin with Boost and PGA" }; -static const unsigned int es8316_hpmux_values[] = {0, 1, 2, 3}; +static const unsigned int es8316_hpmux_values[] = { 0, 1, 2, 3 }; static const struct soc_enum es8316_left_hpmux_enum = SOC_VALUE_ENUM_SINGLE(ES8316_HPMIX_SEL_REG13, 4, 7, ARRAY_SIZE(es8316_hpmux_texts), es8316_hpmux_texts, es8316_hpmux_values); + static const struct snd_kcontrol_new es8316_left_hpmux_controls = - SOC_DAPM_VALUE_ENUM("Route", es8316_left_hpmux_enum); + SOC_DAPM_ENUM("Route", es8316_left_hpmux_enum); static const struct soc_enum es8316_right_hpmux_enum = SOC_VALUE_ENUM_SINGLE(ES8316_HPMIX_SEL_REG13, 0, 7, ARRAY_SIZE(es8316_hpmux_texts), es8316_hpmux_texts, es8316_hpmux_values); + static const struct snd_kcontrol_new es8316_right_hpmux_controls = - SOC_DAPM_VALUE_ENUM("Route", es8316_right_hpmux_enum); + SOC_DAPM_ENUM("Route", es8316_right_hpmux_enum); /* headphone Output Mixer */ static const struct snd_kcontrol_new es8316_out_left_mix[] = { @@ -356,6 +269,7 @@ static const struct snd_kcontrol_new es8316_out_left_mix[] = { SOC_DAPM_SINGLE("Left DAC Switch", ES8316_HPMIX_SWITCH_REG14, 7, 1, 0), }; + static const struct snd_kcontrol_new es8316_out_right_mix[] = { SOC_DAPM_SINGLE("RLIN Switch", ES8316_HPMIX_SWITCH_REG14, 2, 1, 0), @@ -371,8 +285,7 @@ static const char * const es8316_dacsrc_texts[] = { "RDATA TO LDAC, LDATA TO RDAC", }; -static const unsigned int es8316_dacsrc_values[] = { - 0, 1, 2, 3}; +static const unsigned int es8316_dacsrc_values[] = { 0, 1, 2, 3 }; static const struct soc_enum es8316_dacsrc_mux_enum = SOC_VALUE_ENUM_SINGLE(ES8316_DAC_SET1_REG30, 6, 4, @@ -380,8 +293,7 @@ static const struct soc_enum es8316_dacsrc_mux_enum = es8316_dacsrc_texts, es8316_dacsrc_values); static const struct snd_kcontrol_new es8316_dacsrc_mux_controls = - SOC_DAPM_VALUE_ENUM("Route", es8316_dacsrc_mux_enum); - + SOC_DAPM_ENUM("Route", es8316_dacsrc_mux_enum); static const struct snd_soc_dapm_widget es8316_dapm_widgets[] = { /* Input Lines */ @@ -439,7 +351,7 @@ static const struct snd_soc_dapm_widget es8316_dapm_widgets[] = { 0, 1, &es8316_out_right_mix[0], ARRAY_SIZE(es8316_out_right_mix)), - /* Ouput charge pump */ + /* Output charge pump */ SND_SOC_DAPM_PGA("HPCP L", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -451,13 +363,13 @@ static const struct snd_soc_dapm_widget es8316_dapm_widgets[] = { SND_SOC_DAPM_PGA("HPCP R", ES8316_CPHP_OUTEN_REG17, 2, 0, NULL, 0), - /* Ouput Driver */ + /* Output Driver */ SND_SOC_DAPM_PGA("HPVOL L", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("HPVOL R", SND_SOC_NOPM, 0, 0, NULL, 0), - /* Ouput Driver */ + /* Output Driver */ SND_SOC_DAPM_PGA("HPVOL L", ES8316_CPHP_OUTEN_REG17, 5, 0, NULL, 0), SND_SOC_DAPM_PGA("HPVOL R", ES8316_CPHP_OUTEN_REG17, @@ -533,61 +445,61 @@ struct _coeff_div { u8 osr; /*adc osr*/ }; - /* codec hifi mclk clock divider coefficients */ static const struct _coeff_div coeff_div[] = { /* 8k */ - {12288000, 8000 , 6 , 0x06, 0x00, 21, 32}, - {11289600, 8000 , 6 , 0x05, 0x83, 20, 29}, - {18432000, 8000 , 9 , 0x09, 0x00, 27, 32}, - {16934400, 8000 , 8 , 0x08, 0x44, 25, 33}, - {12000000, 8000 , 7 , 0x05, 0xdc, 21, 25}, - {19200000, 8000 , 12, 0x09, 0x60, 27, 25}, + { 12288000, 8000, 6, 0x06, 0x00, 21, 32 }, + { 11289600, 8000, 6, 0x05, 0x83, 20, 29 }, + { 18432000, 8000, 9, 0x09, 0x00, 27, 32 }, + { 16934400, 8000, 8, 0x08, 0x44, 25, 33 }, + { 12000000, 8000, 7, 0x05, 0xdc, 21, 25 }, + { 19200000, 8000, 12, 0x09, 0x60, 27, 25 }, /* 11.025k */ - {11289600, 11025, 4 , 0x04, 0x00, 16, 32}, - {16934400, 11025, 6 , 0x06, 0x00, 21, 32}, - {12000000, 11025, 4 , 0x04, 0x40, 17, 34}, + { 11289600, 11025, 4, 0x04, 0x00, 16, 32 }, + { 16934400, 11025, 6, 0x06, 0x00, 21, 32 }, + { 12000000, 11025, 4, 0x04, 0x40, 17, 34 }, /* 16k */ - {12288000, 16000, 3 , 0x03, 0x00, 12, 32}, - {18432000, 16000, 5 , 0x04, 0x80, 18, 25}, - {12000000, 16000, 3 , 0x02, 0xee, 12, 31}, - {19200000, 16000, 6 , 0x04, 0xb0, 18, 25}, + { 12288000, 16000, 3, 0x03, 0x00, 12, 32 }, + { 18432000, 16000, 5, 0x04, 0x80, 18, 25 }, + { 12000000, 16000, 3, 0x02, 0xee, 12, 31 }, + { 19200000, 16000, 6, 0x04, 0xb0, 18, 25 }, /* 22.05k */ - {11289600, 22050, 2 , 0x02, 0x00, 8 , 32}, - {16934400, 22050, 3 , 0x03, 0x00, 12, 32}, - {12000000, 22050, 2 , 0x02, 0x20, 8 , 34}, + { 11289600, 22050, 2, 0x02, 0x00, 8, 32 }, + { 16934400, 22050, 3, 0x03, 0x00, 12, 32 }, + { 12000000, 22050, 2, 0x02, 0x20, 8, 34 }, /* 32k */ - {12288000, 32000, 1 , 0x01, 0x80, 6 , 48}, - {18432000, 32000, 2 , 0x02, 0x40, 9 , 32}, - {12000000, 32000, 1 , 0x01, 0x77, 6 , 31}, - {19200000, 32000, 3 , 0x02, 0x58, 10, 25}, + { 12288000, 32000, 1, 0x01, 0x80, 6, 48 }, + { 18432000, 32000, 2, 0x02, 0x40, 9, 32 }, + { 12000000, 32000, 1, 0x01, 0x77, 6, 31 }, + { 19200000, 32000, 3, 0x02, 0x58, 10, 25 }, /* 44.1k */ - {11289600, 44100, 1 , 0x01, 0x00, 4 , 32}, - {16934400, 44100, 1 , 0x01, 0x80, 6 , 32}, - {12000000, 44100, 1 , 0x01, 0x10, 4 , 34}, + { 11289600, 44100, 1, 0x01, 0x00, 4, 32 }, + { 16934400, 44100, 1, 0x01, 0x80, 6, 32 }, + { 12000000, 44100, 1, 0x01, 0x10, 4, 34 }, /* 48k */ - {12288000, 48000, 1 , 0x01, 0x00, 4 , 32}, - {18432000, 48000, 1 , 0x01, 0x80, 6 , 32}, - {12000000, 48000, 1 , 0x00, 0xfa, 4 , 31}, - {19200000, 48000, 2 , 0x01, 0x90, 6, 25}, + { 12288000, 48000, 1, 0x01, 0x00, 4, 32 }, + { 18432000, 48000, 1, 0x01, 0x80, 6, 32 }, + { 12000000, 48000, 1, 0x00, 0xfa, 4, 31 }, + { 19200000, 48000, 2, 0x01, 0x90, 6, 25 }, /* 88.2k */ - {11289600, 88200, 1 , 0x00, 0x80, 2 , 32}, - {16934400, 88200, 1 , 0x00, 0xc0, 3 , 48}, - {12000000, 88200, 1 , 0x00, 0x88, 2 , 34}, + { 11289600, 88200, 1, 0x00, 0x80, 2, 32 }, + { 16934400, 88200, 1, 0x00, 0xc0, 3, 48 }, + { 12000000, 88200, 1, 0x00, 0x88, 2, 34 }, /* 96k */ - {12288000, 96000, 1 , 0x00, 0x80, 2 , 32}, - {18432000, 96000, 1 , 0x00, 0xc0, 3 , 48}, - {12000000, 96000, 1 , 0x00, 0x7d, 1 , 31}, - {19200000, 96000, 1 , 0x00, 0xc8, 3 , 25}, + { 12288000, 96000, 1, 0x00, 0x80, 2, 32 }, + { 18432000, 96000, 1, 0x00, 0xc0, 3, 48 }, + { 12000000, 96000, 1, 0x00, 0x7d, 1, 31 }, + { 19200000, 96000, 1, 0x00, 0xc8, 3, 25 }, }; + static inline int get_coeff(int mclk, int rate) { int i; @@ -631,8 +543,8 @@ static struct snd_pcm_hw_constraint_list constraints_12 = { }; /* -* Note that this should be called from init rather than from hw_params. -*/ + * Note that this should be called from init rather than from hw_params. + */ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -672,8 +584,6 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai, u8 adciface = 0; u8 daciface = 0; - alsa_dbg("%s----%d, fmt[%02x]\n", __func__, __LINE__, fmt); - iface = snd_soc_read(codec, ES8316_IFACE); adciface = snd_soc_read(codec, ES8316_ADC_IFACE); daciface = snd_soc_read(codec, ES8316_DAC_IFACE); @@ -681,18 +591,15 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: - alsa_dbg("es8316 in master mode"); iface |= 0x80; break; case SND_SOC_DAIFMT_CBS_CFS: - alsa_dbg("es8316 in slave mode"); iface &= 0x7F; break; default: return -EINVAL; } - /* interface format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -724,7 +631,6 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - /* clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: @@ -763,8 +669,6 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream, struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - DBG("Enter::%s----%d es8316->sysclk=%d\n", - __func__, __LINE__, es8316->sysclk); snd_soc_write(codec, ES8316_RESET_REG00, 0xC0); snd_soc_write(codec, ES8316_SYS_PDN_REG0D, 0x00); /* es8316: both playback and capture need dac mclk */ @@ -792,7 +696,6 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream, ES8316_CLKMGR_DAC_MCLK_EN | ES8316_CLKMGR_DAC_ANALOG_EN); msleep(50); - DBG("%s playback\n", __func__); } else { snd_soc_update_bits(codec, ES8316_ADC_PDN_LINSEL_REG22, 0xC0, 0x20); @@ -801,22 +704,8 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream, ES8316_CLKMGR_ADC_ANALOG_MASK, ES8316_CLKMGR_ADC_MCLK_EN | ES8316_CLKMGR_ADC_ANALOG_EN); - DBG("%s capture\n", __func__); } - /* The set of sample rates that can be supported depends on the - * MCLK supplied to the CODEC - enforce this. - */ - if (!es8316->sysclk) { - dev_err(codec->dev, - "No MCLK configured, call set_sysclk() on init\n"); - return -EINVAL; - } - - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - es8316->sysclk_constraints); - return 0; } @@ -843,7 +732,6 @@ static void es8316_pcm_shutdown(struct snd_pcm_substream *substream, snd_soc_update_bits(codec, ES8316_CLKMGR_CLKSW_REG01, ES8316_CLKMGR_DAC_ANALOG_MASK, ES8316_CLKMGR_DAC_ANALOG_DIS); - DBG("%s playback\n", __func__); } else { snd_soc_write(codec, ES8316_ADC_PDN_LINSEL_REG22, 0xc0); snd_soc_update_bits(codec, ES8316_CLKMGR_CLKSW_REG01, @@ -851,15 +739,11 @@ static void es8316_pcm_shutdown(struct snd_pcm_substream *substream, ES8316_CLKMGR_ADC_ANALOG_MASK, ES8316_CLKMGR_ADC_MCLK_DIS | ES8316_CLKMGR_ADC_ANALOG_DIS); - DBG("%s capture\n", __func__); } - if (--es8316->pwr_count) { - DBG("%s pwr count: %d\n", __func__, es8316->pwr_count); - } else { + if (--es8316->pwr_count == 0) { snd_soc_write(codec, ES8316_SYS_PDN_REG0D, 0x3F); snd_soc_write(codec, ES8316_CLKMGR_CLKSW_REG01, 0xF3); - DBG("%s pwr count close ES8316_SYS_PDN_REG0D\n", __func__); } } @@ -867,113 +751,49 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); - int retv; - - u16 osrate = snd_soc_read(codec, - ES8316_CLKMGR_ADCOSR_REG03) & 0xc0; - u16 mclkdiv = snd_soc_read(codec, - ES8316_CLKMGR_CLKSW_REG01) & 0x7f; - u16 srate = snd_soc_read(codec, - ES8316_SDP_MS_BCKDIV_REG09) & 0xE0; - u16 adciface = snd_soc_read(codec, - ES8316_SDP_ADCFMT_REG0A) & 0xE3; - u16 daciface = snd_soc_read(codec, - ES8316_SDP_DACFMT_REG0B) & 0xE3; - u16 adcdiv = snd_soc_read(codec, - ES8316_CLKMGR_ADCDIV1_REG04); - u16 adclrckdiv_l = snd_soc_read(codec, - ES8316_CLKMGR_ADCDIV2_REG05) & 0x00; - u16 dacdiv = snd_soc_read(codec, ES8316_CLKMGR_DACDIV1_REG06); - u16 daclrckdiv_l = snd_soc_read(codec, - ES8316_CLKMGR_DACDIV2_REG07) & 0x00; - int coeff; - u16 adclrckdiv_h = adcdiv & 0xf0; - u16 daclrckdiv_h = dacdiv & 0xf0; - - adcdiv &= 0x0f; - dacdiv &= 0x0f; - - - coeff = get_coeff(es8316->sysclk, params_rate(params)); - if (coeff < 0) { - coeff = get_coeff(es8316->sysclk / 2, params_rate(params)); - mclkdiv |= 0x80; - } - if (coeff < 0) { - dev_err(codec->dev, - "Unable to configure sample rate %dHz with %dHz MCLK\n", - params_rate(params), es8316->sysclk); - return coeff; - } + struct snd_soc_codec *codec = dai->codec; + int val; - /* bit size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - adciface |= 0x000C; - daciface |= 0x000C; + val = ES8316_DACWL_16; break; case SNDRV_PCM_FORMAT_S20_3LE: - adciface |= 0x0004; - daciface |= 0x0004; + val = ES8316_DACWL_20; break; case SNDRV_PCM_FORMAT_S24_LE: + val = ES8316_DACWL_24; break; case SNDRV_PCM_FORMAT_S32_LE: - adciface |= 0x0010; - daciface |= 0x0010; + val = ES8316_DACWL_32; break; } - /* set iface & srate*/ - snd_soc_update_bits(codec, ES8316_SDP_DACFMT_REG0B, 0xe3, daciface); - snd_soc_update_bits(codec, ES8316_SDP_ADCFMT_REG0A, 0xe3, adciface); - snd_soc_update_bits(codec, ES8316_CLKMGR_CLKSW_REG01, 0x80, mclkdiv); - if (coeff >= 0) { - osrate = coeff_div[coeff].osr; - osrate &= 0x3f; - - srate |= coeff_div[coeff].sr; - srate &= 0x1f; - - adcdiv |= (coeff_div[coeff].div << 4); - adclrckdiv_h |= coeff_div[coeff].lrck_h; - adcdiv &= 0xf0; - adclrckdiv_h &= 0x0f; - adcdiv |= adclrckdiv_h; - adclrckdiv_l = coeff_div[coeff].lrck_l; - - dacdiv |= (coeff_div[coeff].div << 4); - daclrckdiv_h |= coeff_div[coeff].lrck_h; - dacdiv &= 0xf0; - daclrckdiv_h &= 0x0f; - dacdiv |= daclrckdiv_h; - daclrckdiv_l = coeff_div[coeff].lrck_l; - } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_update_bits(codec, ES8316_SDP_DACFMT_REG0B, + ES8316_DACWL_MASK, val); + else + snd_soc_update_bits(codec, ES8316_SDP_ADCFMT_REG0A, + ES8316_ADCWL_MASK, val); - retv = snd_soc_read(codec, ES8316_GPIO_FLAG); return 0; } static int es8316_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - struct es8316_priv *es8316 = es8316_private; + struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); - mute_flag = mute; + es8316->muted = mute; if (mute) { - es8316_set_gpio(ES8316_CODEC_SET_SPK, !es8316->spk_gpio_level); + es8316_enable_spk(es8316, false); msleep(100); snd_soc_write(codec, ES8316_DAC_SET1_REG30, 0x20); } else if (dai->playback_active) { snd_soc_write(codec, ES8316_DAC_SET1_REG30, 0x00); msleep(130); - if (hp_irq_flag == 0) - es8316_set_gpio(ES8316_CODEC_SET_SPK, - es8316->spk_gpio_level); - msleep(150); + if (!es8316->hp_inserted) + es8316_enable_spk(es8316, true); } return 0; } @@ -981,18 +801,30 @@ static int es8316_mute(struct snd_soc_dai *dai, int mute) static int es8316_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); + int ret; + switch (level) { case SND_SOC_BIAS_ON: - dev_dbg(codec->dev, "%s on\n", __func__); break; + case SND_SOC_BIAS_PREPARE: - dev_dbg(codec->dev, "%s prepare\n", __func__); + if (IS_ERR(es8316->mclk)) + break; + + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) { + clk_disable_unprepare(es8316->mclk); + } else { + ret = clk_prepare_enable(es8316->mclk); + if (ret) + return ret; + } break; + case SND_SOC_BIAS_STANDBY: - dev_dbg(codec->dev, "%s standby\n", __func__); break; + case SND_SOC_BIAS_OFF: - dev_dbg(codec->dev, "%s off\n", __func__); snd_soc_write(codec, ES8316_CPHP_OUTEN_REG17, 0x00); snd_soc_write(codec, ES8316_DAC_PDN_REG2F, 0x11); snd_soc_write(codec, ES8316_CPHP_LDOCTL_REG1B, 0x03); @@ -1008,7 +840,6 @@ static int es8316_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, ES8316_RESET_REG00, 0x00); break; } - codec->dapm.bias_level = level; return 0; } @@ -1047,11 +878,8 @@ static struct snd_soc_dai_driver es8316_dai = { .symmetric_rates = 1, }; - static int es8316_init_regs(struct snd_soc_codec *codec) { - dev_dbg(codec->dev, "%s\n", __func__); - snd_soc_write(codec, ES8316_RESET_REG00, 0x3f); usleep_range(5000, 5500); snd_soc_write(codec, ES8316_RESET_REG00, 0x00); @@ -1121,21 +949,13 @@ static int es8316_suspend(struct snd_soc_codec *codec) static int es8316_resume(struct snd_soc_codec *codec) { - struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); - int retv; + int ret; - pr_info("%s: %d\n", __func__, __LINE__); - retv = es8316_reset(codec); /* UPDATED BY DAVID,15-3-5 */ - retv = snd_soc_read(codec, ES8316_CLKMGR_ADCDIV2_REG05); - if (retv == 0) { + es8316_reset(codec); /* UPDATED BY DAVID,15-3-5 */ + ret = snd_soc_read(codec, ES8316_CLKMGR_ADCDIV2_REG05); + if (!ret) { es8316_init_regs(codec); - if (es8316->dmic_amic == dmic_used) { - /* set gpio2 to DMIC CLK */ - snd_soc_write(codec, ES8316_GPIO_SEL_REG4D, 0x02); - } else { - /* set gpio2 to GM SHORT */ - snd_soc_write(codec, ES8316_GPIO_SEL_REG4D, 0x00); - } + snd_soc_write(codec, ES8316_GPIO_SEL_REG4D, 0x00); /* max debance time, enable interrupt, low active */ snd_soc_write(codec, ES8316_GPIO_DEBUNCE_INT_REG4E, 0xf3); /* es8316_set_bias_level(codec, SND_SOC_BIAS_OFF); */ @@ -1152,40 +972,58 @@ static int es8316_resume(struct snd_soc_codec *codec) snd_soc_write(codec, ES8316_SYS_LP2_REG0F, 0xFF); snd_soc_write(codec, ES8316_CLKMGR_CLKSW_REG01, 0xF3); snd_soc_write(codec, ES8316_ADC_PDN_LINSEL_REG22, 0xc0); - es8316_init_reg = 1; } return 0; } -static int es8316_probe(struct snd_soc_codec *codec) +static irqreturn_t es8316_irq_handler(int irq, void *data) { - int ret = 0, retv; - struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); + struct es8316_priv *es8316 = data; + + queue_delayed_work(system_power_efficient_wq, &es8316->work, + msecs_to_jiffies(es8316->debounce_time)); + + return IRQ_HANDLED; +} - DBG("---%s--start--\n", __func__); +static void hp_work(struct work_struct *work) +{ + struct es8316_priv *es8316; + int enable; - ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); + es8316 = container_of(work, struct es8316_priv, work.work); + enable = gpio_get_value(es8316->hp_det_gpio); + if (es8316->hp_det_invert) + enable = !enable; - if (ret < 0) { - dev_err(codec->dev, "fail to reset audio (%d)\n", ret); - goto err; + es8316->hp_inserted = enable ? true : false; + if (!es8316->muted) { + if (es8316->hp_inserted) + es8316_enable_spk(es8316, false); + else + es8316_enable_spk(es8316, true); } - retv = snd_soc_read(codec, ES8316_CLKMGR_ADCDIV2_REG05); - if (retv == 0) { - retv = es8316_reset(codec); /* UPDATED BY DAVID,15-3-5 */ - retv = snd_soc_read(codec, ES8316_CLKMGR_ADCDIV2_REG05); - pr_err("%s: %d, retv=%x\n", __func__, __LINE__, retv); - if (retv == 0) { +} + +static int es8316_probe(struct snd_soc_codec *codec) +{ + struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + es8316->mclk = devm_clk_get(codec->dev, "mclk"); + if (PTR_ERR(es8316->mclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + ret = clk_prepare_enable(es8316->mclk); + if (ret) + return ret; + ret = snd_soc_read(codec, ES8316_CLKMGR_ADCDIV2_REG05); + if (!ret) { + es8316_reset(codec); /* UPDATED BY DAVID,15-3-5 */ + ret = snd_soc_read(codec, ES8316_CLKMGR_ADCDIV2_REG05); + if (!ret) { es8316_init_regs(codec); - if (es8316->dmic_amic == dmic_used) { - /* set gpio2 to DMIC CLK */ - snd_soc_write(codec, - ES8316_GPIO_SEL_REG4D, 0x02); - } else { - /* set gpio2 to GM SHORT */ - snd_soc_write(codec, - ES8316_GPIO_SEL_REG4D, 0x00); - } + snd_soc_write(codec, ES8316_GPIO_SEL_REG4D, 0x00); /* max debance time, enable interrupt, low active */ snd_soc_write(codec, ES8316_GPIO_DEBUNCE_INT_REG4E, 0xf3); @@ -1205,16 +1043,9 @@ static int es8316_probe(struct snd_soc_codec *codec) snd_soc_write(codec, ES8316_CLKMGR_CLKSW_REG01, 0xF3); snd_soc_write(codec, ES8316_ADC_PDN_LINSEL_REG22, 0xc0); - es8316_init_reg = 1; } } - codec->dapm.idle_bias_off = 0; -#if defined(HS_IRQ) - det_initalize(); -#elif defined(HS_TIMER) - hsdet_init(); -#endif -err: + return ret; } @@ -1224,17 +1055,21 @@ static int es8316_remove(struct snd_soc_codec *codec) return 0; } +const struct regmap_config es8316_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ES8316_TEST3_REG53, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = es8316_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(es8316_reg_defaults), +}; + static struct snd_soc_codec_driver soc_codec_dev_es8316 = { .probe = es8316_probe, .remove = es8316_remove, .suspend = es8316_suspend, .resume = es8316_resume, .set_bias_level = es8316_set_bias_level, - .reg_cache_size = ARRAY_SIZE(es8316_reg_defaults), - .reg_word_size = sizeof(u8), - .reg_cache_default = es8316_reg_defaults, - .volatile_register = es8316_volatile, - .readable_register = es8316_readable, .controls = es8316_snd_controls, .num_controls = ARRAY_SIZE(es8316_snd_controls), @@ -1244,160 +1079,85 @@ static struct snd_soc_codec_driver soc_codec_dev_es8316 = { .num_dapm_routes = ARRAY_SIZE(es8316_dapm_routes), }; -#if defined(CONFIG_SPI_MASTER) -static int es8316_spi_probe(struct spi_device *spi) -{ - struct es8316_priv *es8316; - int ret; - - es8316 = kzalloc(sizeof(*es8316), GFP_KERNEL); - if (es8316 == NULL) - return -ENOMEM; - - spi_set_drvdata(spi, es8316); - ret = snd_soc_register_codec(&spi->dev, - &soc_codec_dev_es8316, - &es8316_dai, 1); - if (ret < 0) - kfree(es8316); - return ret; -} - -static int es8316_spi_remove(struct spi_device *spi) -{ - snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); - return 0; -} - -static struct spi_driver es8316_spi_driver = { - .driver = { - .name = "es8316", - .owner = THIS_MODULE, - }, - .probe = es8316_spi_probe, - .remove = es8316_spi_remove, -}; -#endif /* CONFIG_SPI_MASTER */ - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - -static void es8316_i2c_shutdown(struct i2c_client *i2c) -{ - struct snd_soc_codec *codec; - struct es8316_priv *es8316 = es8316_private; - - if (!es8316_codec) - goto err; - - es8316_set_gpio(ES8316_CODEC_SET_SPK, !es8316->spk_gpio_level); - mdelay(150); - - - codec = es8316_codec; - snd_soc_write(codec, ES8316_CPHP_ICAL_VOL_REG18, 0x33); - snd_soc_write(codec, ES8316_CPHP_OUTEN_REG17, 0x00); - snd_soc_write(codec, ES8316_CPHP_LDOCTL_REG1B, 0x03); - snd_soc_write(codec, ES8316_CPHP_PDN2_REG1A, 0x22); - snd_soc_write(codec, ES8316_CPHP_PDN1_REG19, 0x06); - snd_soc_write(codec, ES8316_HPMIX_SWITCH_REG14, 0x00); - snd_soc_write(codec, ES8316_HPMIX_PDN_REG15, 0x33); - snd_soc_write(codec, ES8316_HPMIX_VOL_REG16, 0x00); - snd_soc_write(codec, ES8316_ADC_PDN_LINSEL_REG22, 0xC0); - snd_soc_write(codec, ES8316_DAC_PDN_REG2F, 0x11); - snd_soc_write(codec, ES8316_SYS_PDN_REG0D, 0x3F); - snd_soc_write(codec, ES8316_CLKMGR_CLKSW_REG01, 0x03); - snd_soc_write(codec, ES8316_RESET_REG00, 0x7F); -err: - return; -} - -static int es8316_i2c_probe(struct i2c_client *i2c_client, +static int es8316_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct es8316_priv *es8316; int ret = -1; - unsigned long irq_flag = 0; - int hp_irq = 0; - int val = 0; + int hp_irq; enum of_gpio_flags flags; - struct device_node *np = i2c_client->dev.of_node; - - DBG("---%s---probe start\n", __func__); + struct device_node *np = i2c->dev.of_node; - es8316 = kzalloc(sizeof(*es8316), GFP_KERNEL); - if (es8316 == NULL) + es8316 = devm_kzalloc(&i2c->dev, sizeof(*es8316), GFP_KERNEL); + if (!es8316) return -ENOMEM; - else - es8316_private = es8316; - es8316->dmic_amic = amic_used; /*if internal mic is amic*/ + es8316->debounce_time = 200; + es8316->hp_det_invert = 0; es8316->pwr_count = 0; - i2c_set_clientdata(i2c_client, es8316); + es8316->hp_inserted = false; + es8316->muted = true; + + es8316->regmap = devm_regmap_init_i2c(i2c, &es8316_regmap_config); + if (IS_ERR(es8316->regmap)) { + ret = PTR_ERR(es8316->regmap); + dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); + return ret; + } + i2c_set_clientdata(i2c, es8316); es8316->spk_ctl_gpio = of_get_named_gpio_flags(np, - "spk-con-gpio", 0, &flags); + "spk-con-gpio", + 0, + &flags); if (es8316->spk_ctl_gpio < 0) { - DBG("%s() Can not read property spk codec-en-gpio\n", __func__); + dev_info(&i2c->dev, "Can not read property spk_ctl_gpio\n"); es8316->spk_ctl_gpio = INVALID_GPIO; } else { - es8316->spk_gpio_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; - ret = gpio_request(es8316->spk_ctl_gpio, NULL); - gpio_direction_output(es8316->spk_ctl_gpio, - !es8316->spk_gpio_level); - } - - es8316->hp_ctl_gpio = of_get_named_gpio_flags(np, - "hp-con-gpio", 0, &flags); - if (es8316->hp_ctl_gpio < 0) { - DBG("%s() Can not read property hp codec-en-gpio\n", __func__); - es8316->hp_ctl_gpio = INVALID_GPIO; - } else { - es8316->hp_gpio_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; - ret = gpio_request(es8316->hp_ctl_gpio, NULL); - gpio_direction_output(es8316->hp_ctl_gpio, !es8316->hp_gpio_level); + es8316->spk_active_level = !(flags & OF_GPIO_ACTIVE_LOW); + ret = devm_gpio_request_one(&i2c->dev, es8316->spk_ctl_gpio, + GPIOF_DIR_OUT, NULL); + if (ret) { + dev_err(&i2c->dev, "Failed to request spk_ctl_gpio\n"); + return ret; + } + es8316_enable_spk(es8316, false); } es8316->hp_det_gpio = of_get_named_gpio_flags(np, - "hp-det-gpio", 0, &flags); + "hp-det-gpio", + 0, + &flags); if (es8316->hp_det_gpio < 0) { - DBG("%s() Can not read property hp_det gpio\n", __func__); + dev_info(&i2c->dev, "Can not read property hp_det_gpio\n"); es8316->hp_det_gpio = INVALID_GPIO; } else { - es8316->hp_det_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; - ret = gpio_request(es8316->hp_det_gpio, NULL); - if (ret != 0) { - DBG("%s request HP_DET error", __func__); + INIT_DELAYED_WORK(&es8316->work, hp_work); + es8316->hp_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW); + ret = devm_gpio_request_one(&i2c->dev, es8316->hp_det_gpio, + GPIOF_IN, "hp det"); + if (ret < 0) return ret; - } - gpio_direction_input(es8316->hp_det_gpio); - - irq_flag = IRQF_TRIGGER_LOW | IRQF_ONESHOT; hp_irq = gpio_to_irq(es8316->hp_det_gpio); - - val = gpio_get_value(es8316->hp_det_gpio); - if (val == es8316->hp_det_level) { - pr_info("hp inserted.\n"); - hp_irq_flag = 1; - es8316_set_gpio(ES8316_CODEC_SET_SPK, - !es8316->spk_gpio_level); + ret = devm_request_threaded_irq(&i2c->dev, hp_irq, NULL, + es8316_irq_handler, + IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | + IRQF_ONESHOT, + "es8316_interrupt", es8316); + if (ret < 0) { + dev_err(&i2c->dev, "request_irq failed: %d\n", ret); + return ret; } - if (hp_irq) - ret = request_threaded_irq(hp_irq, NULL, - hp_det_irq_handler, irq_flag, "ES8316", NULL); + schedule_delayed_work(&es8316->work, + msecs_to_jiffies(es8316->debounce_time)); } - ret = snd_soc_register_codec(&i2c_client->dev, + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_es8316, &es8316_dai, 1); - if (ret < 0) { - kfree(es8316); - return ret; - } - - return ret; } @@ -1405,11 +1165,9 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client, static int es8316_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } -static const unsigned short normal_i2c[] = {0x10, I2C_CLIENT_END}; static const struct i2c_device_id es8316_i2c_id[] = { {"es8316", 0}, {"10ES8316:00", 0}, @@ -1418,44 +1176,23 @@ static const struct i2c_device_id es8316_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, es8316_i2c_id); +static const struct of_device_id es8316_of_match[] = { + { .compatible = "everest,es8316", }, + { } +}; +MODULE_DEVICE_TABLE(of, es8316_of_match); + static struct i2c_driver es8316_i2c_driver = { .driver = { - .name = "es8316", - .owner = THIS_MODULE, + .name = "es8316", + .of_match_table = es8316_of_match, }, - .shutdown = es8316_i2c_shutdown, - .probe = es8316_i2c_probe, - .remove = es8316_i2c_remove, + .probe = es8316_i2c_probe, + .remove = es8316_i2c_remove, .id_table = es8316_i2c_id, - .class = I2C_CLASS_HWMON, - .address_list = normal_i2c, }; -#endif - -static int __init es8316_init(void) -{ - DBG("--%s--start--\n", __func__); -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - return i2c_add_driver(&es8316_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - return spi_register_driver(&es8316_spi_driver); -#endif -} - -static void __exit es8316_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - return i2c_del_driver(&es8316_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - return spi_unregister_driver(&es8316_spi_driver); -#endif -} - -module_init(es8316_init); -module_exit(es8316_exit); +module_i2c_driver(es8316_i2c_driver); MODULE_DESCRIPTION("ASoC es8316 driver"); MODULE_AUTHOR("Will "); diff --git a/sound/soc/codecs/es8316.h b/sound/soc/codecs/es8316.h index aa1cc9051888..8b3e9533dc38 100644 --- a/sound/soc/codecs/es8316.h +++ b/sound/soc/codecs/es8316.h @@ -131,4 +131,30 @@ #define ES8316_CLKMGR_DAC_ANALOG_EN (0X1<<0) #define ES8316_CLKMGR_DAC_ANALOG_DIS (0X0<<0) +/* REGISTER 0X0A */ +#define ES8316_ADCWL_MASK (0x7 << 2) +#define ES8316_ADCWL_32 (0x4 << 2) +#define ES8316_ADCWL_24 (0x0 << 2) +#define ES8316_ADCWL_20 (0x1 << 2) +#define ES8316_ADCWL_18 (0x2 << 2) +#define ES8316_ADCWL_16 (0x3 << 2) +#define ES8316_ADCFMT_MASK (0x3 << 0) +#define ES8316_ADCFMT_I2S (0x0 << 0) +#define ES8316_ADCWL_LEFT (0x1 << 0) +#define ES8316_ADCWL_RIGHT (0x2 << 0) +#define ES8316_ADCWL_PCM (0x3 << 0) + +/* REGISTER 0X0B */ +#define ES8316_DACWL_MASK (0x7 << 2) +#define ES8316_DACWL_32 (0x4 << 2) +#define ES8316_DACWL_24 (0x0 << 2) +#define ES8316_DACWL_20 (0x1 << 2) +#define ES8316_DACWL_18 (0x2 << 2) +#define ES8316_DACWL_16 (0x3 << 2) +#define ES8316_DACFMT_MASK (0x3 << 0) +#define ES8316_DACFMT_I2S (0x0 << 0) +#define ES8316_DACWL_LEFT (0x1 << 0) +#define ES8316_DACWL_RIGHT (0x2 << 0) +#define ES8316_DACWL_PCM (0x3 << 0) + #endif -- 2.34.1