ASoC: es8316: add codec driver
authorSugar Zhang <sugar.zhang@rock-chips.com>
Thu, 17 Mar 2016 10:22:41 +0000 (18:22 +0800)
committerGerrit Code Review <gerrit@rock-chips.com>
Tue, 29 Mar 2016 10:34:52 +0000 (18:34 +0800)
Change-Id: I6896036a7af922747180535939074f399f8c38d1
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Documentation/devicetree/bindings/sound/es8316.txt [new file with mode: 0644]
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/es8316.c
sound/soc/codecs/es8316.h

diff --git a/Documentation/devicetree/bindings/sound/es8316.txt b/Documentation/devicetree/bindings/sound/es8316.txt
new file mode 100644 (file)
index 0000000..313d87f
--- /dev/null
@@ -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>;
+};
index 48173b198a93e573bea794cb49bfc23a7cdefc48..f6f944aaf7af580a9b9ad4e4d9b51a7a0025d578 100644 (file)
@@ -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"
 
index f632fc42f59f08d9d6c72f6aac045d9fe28176a1..4682308b912f7fc6bc0c2d40d6db8531d69145c4 100644 (file)
@@ -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
index eb8357be0ed5c1b871b2d5267a0c2f3353156987..1e082f39e97b3a1d35a3ab482f523d0e2ceb7b12 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/regmap.h>
 #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 <will@everset-semi.com>");
index aa1cc905188847d7179b893bf89c92d13e215ab8..8b3e9533dc38af511e80ca77b66b6f76e86053d6 100644 (file)
 #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