From ec49d469586384bf56caeb49623e081210913df5 Mon Sep 17 00:00:00 2001 From: Nickey Yang Date: Thu, 28 Jul 2016 09:56:14 +0800 Subject: [PATCH] ASoC: es8323: update codec es8323 driver This patch update the es8323 codec drivers as follows: o Remove snd_soc_control_type: Now that upstream remove definition of snd_soc_control_type. o Replace SOC_DAPM_VALUE_ENUM: SOC_DAPM_VALUE_ENUM is replaced by SOC_DAPM_ENUM. o Remove codec->dapm.bias_level = level: The line at the end of the set_bias_level callback to update the bias_level state. Now that upstream move this update into snd_soc_dapm_force_bias_level(). o Remove .owner = THIS_MODULE: No need to set .owner here.The i2c_driver core will do. o module_i2c_driver: Convert to use module_i2c_driver is simple. o Add match table: Add a device tree match table for es8323 codec driver. o Add mclk: The I2S block provide the output clock as the mclk,so add it. o Adjust code format: Adjust some problems of code format. Change-Id: I8e0647310eb11325c39ebb408f75cc9ed28df71d Signed-off-by: Nickey Yang --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/es8323.c | 1011 ++++++++++++++++--------------------- 3 files changed, 445 insertions(+), 573 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 08772aeba8a8..3646d9db685a 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -64,6 +64,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DMIC select SND_SOC_BT_SCO select SND_SOC_ES8316 if I2C + select SND_SOC_ES8323 if I2C select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C select SND_SOC_GTM601 @@ -465,6 +466,10 @@ config SND_SOC_ES8316 tristate "Everest Semi ES8316 CODEC" depends on I2C +config SND_SOC_ES8323 + tristate "Everest Semi ES8323 CODEC" + depends on I2C + config SND_SOC_HDMI_CODEC tristate select SND_PCM_ELD diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 107d2f344379..eb4dffb10d68 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -57,6 +57,7 @@ snd-soc-dw-hdmi-audio-objs := dw-hdmi-audio.o snd-soc-bt-sco-objs := bt-sco.o snd-soc-dmic-objs := dmic.o snd-soc-es8316-objs := es8316.o +snd-soc-es8323-objs := es8323.o snd-soc-es8328-objs := es8328.o snd-soc-es8328-i2c-objs := es8328-i2c.o snd-soc-es8328-spi-objs := es8328-spi.o @@ -256,6 +257,7 @@ obj-$(CONFIG_SND_SOC_DW_HDMI_AUDIO) += snd-soc-dw-hdmi-audio.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_ES8323) += snd-soc-es8323.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/es8323.c b/sound/soc/codecs/es8323.c index 3bdcacb29d87..0ceb7ac465f9 100755 --- a/sound/soc/codecs/es8323.c +++ b/sound/soc/codecs/es8323.c @@ -1,10 +1,11 @@ /* * es8323.c -- es8323 ALSA SoC audio driver * - * Copyright 2009 Wolfson Microelectronics plc - * Copyright 2005 Openedhand Ltd. + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. * - * Author: Mark Brown + * Author: Mark Brown + * Author: Jianqun Xu + * Author: Nickey Yang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -33,26 +35,15 @@ #include #include "es8323.h" -#if 0 -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif -#define alsa_dbg DBG - #define INVALID_GPIO -1 #define ES8323_CODEC_SET_SPK 1 #define ES8323_CODEC_SET_HP 2 -static bool hp_irq_flag = 0; - -//SPK HP vol control -#ifndef es8323_DEF_VOL #define es8323_DEF_VOL 0x1b -#endif -static int es8323_set_bias_level(struct snd_soc_codec *codec,enum snd_soc_bias_level level); +static int es8323_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level); /* * es8323 register cache @@ -60,118 +51,86 @@ static int es8323_set_bias_level(struct snd_soc_codec *codec,enum snd_soc_bias_l * are using 2 wire for device control, so we cache them instead. */ static u16 es8323_reg[] = { - 0x06, 0x1C, 0xC3, 0xFC, /* 0 *////0x0100 0x0180 - 0xC0, 0x00, 0x00, 0x7C, /* 4 */ - 0x80, 0x00, 0x00, 0x06, /* 8 */ - 0x00, 0x06, 0x30, 0x30, /* 12 */ - 0xC0, 0xC0, 0x38, 0xB0, /* 16 */ - 0x32, 0x06, 0x00, 0x00, /* 20 */ - 0x06, 0x30, 0xC0, 0xC0, /* 24 */ - 0x08, 0x06, 0x1F, 0xF7, /* 28 */ - 0xFD, 0xFF, 0x1F, 0xF7, /* 32 */ - 0xFD, 0xFF, 0x00, 0x38, /* 36 */ - 0x38, 0x38, 0x38, 0x38, /* 40 */ - 0x38, 0x00, 0x00, 0x00, /* 44 */ - 0x00, 0x00, 0x00, 0x00, /* 48 */ - 0x00, 0x00, 0x00, 0x00, /* 52 */ + 0x06, 0x1C, 0xC3, 0xFC, /* 0 */ + 0xC0, 0x00, 0x00, 0x7C, /* 4 */ + 0x80, 0x00, 0x00, 0x06, /* 8 */ + 0x00, 0x06, 0x30, 0x30, /* 12 */ + 0xC0, 0xC0, 0x38, 0xB0, /* 16 */ + 0x32, 0x06, 0x00, 0x00, /* 20 */ + 0x06, 0x30, 0xC0, 0xC0, /* 24 */ + 0x08, 0x06, 0x1F, 0xF7, /* 28 */ + 0xFD, 0xFF, 0x1F, 0xF7, /* 32 */ + 0xFD, 0xFF, 0x00, 0x38, /* 36 */ + 0x38, 0x38, 0x38, 0x38, /* 40 */ + 0x38, 0x00, 0x00, 0x00, /* 44 */ + 0x00, 0x00, 0x00, 0x00, /* 48 */ + 0x00, 0x00, 0x00, 0x00, /* 52 */ }; /* codec private data */ struct es8323_priv { unsigned int sysclk; - enum snd_soc_control_type control_type; + struct clk *mclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; int spk_ctl_gpio; - int hp_ctl_gpio; int hp_det_gpio; + bool muted; + bool hp_inserted; bool spk_gpio_level; - bool hp_gpio_level; bool hp_det_level; }; -struct es8323_priv *es8323_private; +static struct es8323_priv *es8323_private; static int es8323_set_gpio(int gpio, bool level) { struct es8323_priv *es8323 = es8323_private; if (!es8323) { - printk("%s : es8323_priv is NULL\n", __func__); return 0; } - DBG("%s : set %s %s ctl gpio %s\n", __func__, - gpio & ES8323_CODEC_SET_SPK ? "spk" : "", - gpio & ES8323_CODEC_SET_HP ? "hp" : "", - level ? "HIGH" : "LOW"); - - if ((gpio & ES8323_CODEC_SET_SPK) && es8323 && es8323->spk_ctl_gpio != INVALID_GPIO) { + if ((gpio & ES8323_CODEC_SET_SPK) && es8323 + && es8323->spk_ctl_gpio != INVALID_GPIO) { gpio_set_value(es8323->spk_ctl_gpio, level); } - if ((gpio & ES8323_CODEC_SET_HP) && es8323 && es8323->hp_ctl_gpio != INVALID_GPIO) { - gpio_set_value(es8323->hp_ctl_gpio, level); - } - return 0; } -static char mute_flag = 1; static irqreturn_t hp_det_irq_handler(int irq, void *dev_id) { - int ret; - unsigned int type; struct es8323_priv *es8323 = es8323_private; - disable_irq_nosync(irq); - - type = gpio_get_value(es8323->hp_det_gpio) ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; - ret = irq_set_irq_type(irq, type); - if (ret < 0) { - pr_err("%s: irq_set_irq_type(%d, %d) failed\n", __func__, irq, type); - return -1; - } - - if (type == IRQ_TYPE_EDGE_FALLING) - hp_irq_flag = 0; + if (gpio_get_value(es8323->hp_det_gpio)) + es8323->hp_inserted = 0; else - hp_irq_flag = 1; - - if (mute_flag == 0) - { - if(es8323->hp_det_level == gpio_get_value(es8323->hp_det_gpio)){ - DBG("hp_det_level = 0,insert hp\n"); - es8323_set_gpio(ES8323_CODEC_SET_SPK,!es8323->spk_gpio_level); - es8323_set_gpio(ES8323_CODEC_SET_HP,es8323->hp_gpio_level); - }else{ - DBG("hp_det_level = 1,deinsert hp\n"); - es8323_set_gpio(ES8323_CODEC_SET_SPK,es8323->spk_gpio_level); - es8323_set_gpio(ES8323_CODEC_SET_HP,!es8323->hp_gpio_level); - } - } - enable_irq(irq); + es8323->hp_inserted = 1; + if (es8323->muted == 0) { + if (es8323->hp_det_level != es8323->hp_inserted) + es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level); + else + es8323_set_gpio(ES8323_CODEC_SET_SPK, es8323->spk_gpio_level); + } return IRQ_HANDLED; } static unsigned int es8323_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) + unsigned int reg) { - //u16 *cache = codec->reg_cache; if (reg >= ARRAY_SIZE(es8323_reg)) return -1; return es8323_reg[reg]; } static int es8323_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) + unsigned int value) { - //u16 *cache = codec->reg_cache; u8 data[2]; int ret; - BUG_ON(codec->volatile_register); data[0] = reg; data[1] = value & 0x00ff; @@ -186,41 +145,45 @@ static int es8323_write(struct snd_soc_codec *codec, unsigned int reg, return -EIO; } -//#define es8323_reset(c) snd_soc_write(c, es8323_RESET, 0) - static int es8323_reset(struct snd_soc_codec *codec) - { - snd_soc_write(codec, ES8323_CONTROL1, 0x80); - return snd_soc_write(codec, ES8323_CONTROL1, 0x00); - } +static int es8323_reset(struct snd_soc_codec *codec) +{ + snd_soc_write(codec, ES8323_CONTROL1, 0x80); + return snd_soc_write(codec, ES8323_CONTROL1, 0x00); +} static const char *es8323_line_texts[] = { - "Line 1", "Line 2", "PGA"}; + "Line 1", "Line 2", "PGA" +}; static const unsigned int es8323_line_values[] = { - 0, 1, 3}; -static const char *es8323_pga_sel[] = {"Line 1", "Line 2", "Differential"}; -static const char *stereo_3d_txt[] = {"No 3D ", "Level 1","Level 2","Level 3","Level 4","Level 5","Level 6","Level 7"}; -static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"}; -static const char *ng_type_txt[] = {"Constant PGA Gain","Mute ADC Output"}; -static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"}; -static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert","L + R Invert"}; -static const char *es8323_mono_mux[] = {"Stereo", "Mono (Left)","Mono (Right)"}; -static const char *es8323_diff_sel[] = {"Line 1", "Line 2"}; - -static const struct soc_enum es8323_enum[]={ - SOC_VALUE_ENUM_SINGLE(ES8323_DACCONTROL16, 3, 7, ARRAY_SIZE(es8323_line_texts), es8323_line_texts, es8323_line_values),/* LLINE */ - SOC_VALUE_ENUM_SINGLE(ES8323_DACCONTROL16, 0, 7, ARRAY_SIZE(es8323_line_texts), es8323_line_texts, es8323_line_values),/* rline */ - SOC_VALUE_ENUM_SINGLE(ES8323_ADCCONTROL2, 6, 3, ARRAY_SIZE(es8323_pga_sel), es8323_line_texts, es8323_line_values),/* Left PGA Mux */ - SOC_VALUE_ENUM_SINGLE(ES8323_ADCCONTROL2, 4, 3, ARRAY_SIZE(es8323_pga_sel), es8323_line_texts, es8323_line_values),/* Right PGA Mux */ - SOC_ENUM_SINGLE(ES8323_DACCONTROL7, 2, 8, stereo_3d_txt),/* stereo-3d */ - SOC_ENUM_SINGLE(ES8323_ADCCONTROL10, 6, 4, alc_func_txt),/*alc func*/ - SOC_ENUM_SINGLE(ES8323_ADCCONTROL14, 1, 2, ng_type_txt),/*noise gate type*/ - SOC_ENUM_SINGLE(ES8323_DACCONTROL6, 6, 4, deemph_txt),/*Playback De-emphasis*/ + 0, 1, 3 +}; +static const char *es8323_pga_sel[] = { "Line 1", "Line 2", "Differential" }; +static const char *stereo_3d_txt[] = + { "No 3D ", "Level 1", "Level 2", "Level 3", "Level 4", "Level 5", +"Level 6", "Level 7" }; +static const char *alc_func_txt[] = { "Off", "Right", "Left", "Stereo" }; +static const char *ng_type_txt[] = { "Constant PGA Gain", "Mute ADC Output" }; +static const char *deemph_txt[] = { "None", "32Khz", "44.1Khz", "48Khz" }; +static const char *adcpol_txt[] = + { "Normal", "L Invert", "R Invert", "L + R Invert" }; +static const char *es8323_mono_mux[] = + { "Stereo", "Mono (Left)", "Mono (Right)" }; +static const char *es8323_diff_sel[] = { "Line 1", "Line 2" }; + +static const struct soc_enum es8323_enum[] = { + SOC_VALUE_ENUM_SINGLE(ES8323_DACCONTROL16, 3, 7, ARRAY_SIZE(es8323_line_texts), es8323_line_texts, es8323_line_values), /* LLINE */ + SOC_VALUE_ENUM_SINGLE(ES8323_DACCONTROL16, 0, 7, ARRAY_SIZE(es8323_line_texts), es8323_line_texts, es8323_line_values), /* RLINE */ + SOC_VALUE_ENUM_SINGLE(ES8323_ADCCONTROL2, 6, 3, ARRAY_SIZE(es8323_pga_sel), es8323_line_texts, es8323_line_values), /* Left PGA Mux */ + SOC_VALUE_ENUM_SINGLE(ES8323_ADCCONTROL2, 4, 3, ARRAY_SIZE(es8323_pga_sel), es8323_line_texts, es8323_line_values), /* Right PGA Mux */ + SOC_ENUM_SINGLE(ES8323_DACCONTROL7, 2, 8, stereo_3d_txt), /* stereo-3d */ + SOC_ENUM_SINGLE(ES8323_ADCCONTROL10, 6, 4, alc_func_txt), /* alc func */ + SOC_ENUM_SINGLE(ES8323_ADCCONTROL14, 1, 2, ng_type_txt), /* noise gate type */ + SOC_ENUM_SINGLE(ES8323_DACCONTROL6, 6, 4, deemph_txt), /* Playback De-emphasis */ SOC_ENUM_SINGLE(ES8323_ADCCONTROL6, 6, 4, adcpol_txt), SOC_ENUM_SINGLE(ES8323_ADCCONTROL3, 3, 3, es8323_mono_mux), SOC_ENUM_SINGLE(ES8323_ADCCONTROL3, 7, 2, es8323_diff_sel), - }; - +}; static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); static const DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 50, 1); @@ -229,50 +192,58 @@ static const DECLARE_TLV_DB_SCALE(out_tlv, -4500, 150, 0); static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); static const struct snd_kcontrol_new es8323_snd_controls[] = { -SOC_ENUM("3D Mode", es8323_enum[4]), -SOC_SINGLE("ALC Capture Target Volume", ES8323_ADCCONTROL11, 4, 15, 0), -SOC_SINGLE("ALC Capture Max PGA", ES8323_ADCCONTROL10, 3, 7, 0), -SOC_SINGLE("ALC Capture Min PGA", ES8323_ADCCONTROL10, 0, 7, 0), -SOC_ENUM("ALC Capture Function", es8323_enum[5]), -SOC_SINGLE("ALC Capture ZC Switch", ES8323_ADCCONTROL13, 6, 1, 0), -SOC_SINGLE("ALC Capture Hold Time", ES8323_ADCCONTROL11, 0, 15, 0), -SOC_SINGLE("ALC Capture Decay Time", ES8323_ADCCONTROL12, 4, 15, 0), -SOC_SINGLE("ALC Capture Attack Time", ES8323_ADCCONTROL12, 0, 15, 0), -SOC_SINGLE("ALC Capture NG Threshold", ES8323_ADCCONTROL14, 3, 31, 0), -SOC_ENUM("ALC Capture NG Type",es8323_enum[6]), -SOC_SINGLE("ALC Capture NG Switch", ES8323_ADCCONTROL14, 0, 1, 0), -SOC_SINGLE("ZC Timeout Switch", ES8323_ADCCONTROL13, 6, 1, 0), -SOC_DOUBLE_R_TLV("Capture Digital Volume", ES8323_ADCCONTROL8, ES8323_ADCCONTROL9,0, 255, 1, adc_tlv), -SOC_SINGLE("Capture Mute", ES8323_ADCCONTROL7, 2, 1, 0), -SOC_SINGLE_TLV("Left Channel Capture Volume", ES8323_ADCCONTROL1, 4, 15, 0, bypass_tlv), -SOC_SINGLE_TLV("Right Channel Capture Volume", ES8323_ADCCONTROL1, 0, 15, 0, bypass_tlv), -SOC_ENUM("Playback De-emphasis", es8323_enum[7]), -SOC_ENUM("Capture Polarity", es8323_enum[8]), -SOC_DOUBLE_R_TLV("PCM Volume", ES8323_DACCONTROL4, ES8323_DACCONTROL5, 0, 255, 1, dac_tlv), -SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", ES8323_DACCONTROL17, 3, 7, 1, bypass_tlv), -SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", ES8323_DACCONTROL20, 3, 7, 1, bypass_tlv), -SOC_DOUBLE_R_TLV("Output 1 Playback Volume", ES8323_DACCONTROL24, ES8323_DACCONTROL25, 0, 64, 0, out_tlv), -SOC_DOUBLE_R_TLV("Output 2 Playback Volume", ES8323_DACCONTROL26, ES8323_DACCONTROL27, 0, 64, 0, out_tlv), + SOC_ENUM("3D Mode", es8323_enum[4]), + SOC_SINGLE("ALC Capture Target Volume", ES8323_ADCCONTROL11, 4, 15, 0), + SOC_SINGLE("ALC Capture Max PGA", ES8323_ADCCONTROL10, 3, 7, 0), + SOC_SINGLE("ALC Capture Min PGA", ES8323_ADCCONTROL10, 0, 7, 0), + SOC_ENUM("ALC Capture Function", es8323_enum[5]), + SOC_SINGLE("ALC Capture ZC Switch", ES8323_ADCCONTROL13, 6, 1, 0), + SOC_SINGLE("ALC Capture Hold Time", ES8323_ADCCONTROL11, 0, 15, 0), + SOC_SINGLE("ALC Capture Decay Time", ES8323_ADCCONTROL12, 4, 15, 0), + SOC_SINGLE("ALC Capture Attack Time", ES8323_ADCCONTROL12, 0, 15, 0), + SOC_SINGLE("ALC Capture NG Threshold", ES8323_ADCCONTROL14, 3, 31, 0), + SOC_ENUM("ALC Capture NG Type", es8323_enum[6]), + SOC_SINGLE("ALC Capture NG Switch", ES8323_ADCCONTROL14, 0, 1, 0), + SOC_SINGLE("ZC Timeout Switch", ES8323_ADCCONTROL13, 6, 1, 0), + SOC_DOUBLE_R_TLV("Capture Digital Volume", ES8323_ADCCONTROL8, + ES8323_ADCCONTROL9, 0, 255, 1, adc_tlv), + SOC_SINGLE("Capture Mute", ES8323_ADCCONTROL7, 2, 1, 0), + SOC_SINGLE_TLV("Left Channel Capture Volume", ES8323_ADCCONTROL1, 4, 15, + 0, bypass_tlv), + SOC_SINGLE_TLV("Right Channel Capture Volume", ES8323_ADCCONTROL1, 0, + 15, 0, bypass_tlv), + SOC_ENUM("Playback De-emphasis", es8323_enum[7]), + SOC_ENUM("Capture Polarity", es8323_enum[8]), + SOC_DOUBLE_R_TLV("PCM Volume", ES8323_DACCONTROL4, ES8323_DACCONTROL5, + 0, 255, 1, dac_tlv), + SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", ES8323_DACCONTROL17, 3, + 7, 1, bypass_tlv), + SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", ES8323_DACCONTROL20, + 3, 7, 1, bypass_tlv), + SOC_DOUBLE_R_TLV("Output 1 Playback Volume", ES8323_DACCONTROL24, + ES8323_DACCONTROL25, 0, 64, 0, out_tlv), + SOC_DOUBLE_R_TLV("Output 2 Playback Volume", ES8323_DACCONTROL26, + ES8323_DACCONTROL27, 0, 64, 0, out_tlv), }; - static const struct snd_kcontrol_new es8323_left_line_controls = - SOC_DAPM_VALUE_ENUM("Route", es8323_enum[0]); +SOC_DAPM_ENUM("Route", es8323_enum[0]); static const struct snd_kcontrol_new es8323_right_line_controls = - SOC_DAPM_VALUE_ENUM("Route", es8323_enum[1]); +SOC_DAPM_ENUM("Route", es8323_enum[1]); /* Left PGA Mux */ static const struct snd_kcontrol_new es8323_left_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", es8323_enum[2]); +SOC_DAPM_ENUM("Route", es8323_enum[2]); + /* Right PGA Mux */ static const struct snd_kcontrol_new es8323_right_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", es8323_enum[3]); +SOC_DAPM_ENUM("Route", es8323_enum[3]); /* Left Mixer */ static const struct snd_kcontrol_new es8323_left_mixer_controls[] = { SOC_DAPM_SINGLE("Left Playback Switch", ES8323_DACCONTROL17, 7, 1, 0), - SOC_DAPM_SINGLE("Left Bypass Switch", ES8323_DACCONTROL17, 6, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8323_DACCONTROL17, 6, 1, 0), }; /* Right Mixer */ @@ -282,39 +253,38 @@ static const struct snd_kcontrol_new es8323_right_mixer_controls[] = { }; /* Differential Mux */ -//static const char *es8323_diff_sel[] = {"Line 1", "Line 2"}; static const struct snd_kcontrol_new es8323_diffmux_controls = - SOC_DAPM_ENUM("Route", es8323_enum[10]); +SOC_DAPM_ENUM("Route", es8323_enum[10]); /* Mono ADC Mux */ static const struct snd_kcontrol_new es8323_monomux_controls = - SOC_DAPM_ENUM("Route", es8323_enum[9]); +SOC_DAPM_ENUM("Route", es8323_enum[9]); static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = { SND_SOC_DAPM_INPUT("LINPUT1"), SND_SOC_DAPM_INPUT("LINPUT2"), SND_SOC_DAPM_INPUT("RINPUT1"), SND_SOC_DAPM_INPUT("RINPUT2"), - + SND_SOC_DAPM_MICBIAS("Mic Bias", ES8323_ADCPOWER, 3, 1), SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, - &es8323_diffmux_controls), - + &es8323_diffmux_controls), + SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, - &es8323_monomux_controls), + &es8323_monomux_controls), SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, - &es8323_monomux_controls), - + &es8323_monomux_controls), + SND_SOC_DAPM_MUX("Left PGA Mux", ES8323_ADCPOWER, 7, 1, - &es8323_left_pga_controls), + &es8323_left_pga_controls), SND_SOC_DAPM_MUX("Right PGA Mux", ES8323_ADCPOWER, 6, 1, - &es8323_right_pga_controls), + &es8323_right_pga_controls), SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, - &es8323_left_line_controls), + &es8323_left_line_controls), SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, - &es8323_right_line_controls), + &es8323_right_line_controls), SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8323_ADCPOWER, 4, 1), SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ES8323_ADCPOWER, 5, 1), @@ -324,11 +294,11 @@ static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = { SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8323_DACPOWER, 8, 0), SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, - &es8323_left_mixer_controls[0], - ARRAY_SIZE(es8323_left_mixer_controls)), + &es8323_left_mixer_controls[0], + ARRAY_SIZE(es8323_left_mixer_controls)), SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, - &es8323_right_mixer_controls[0], - ARRAY_SIZE(es8323_right_mixer_controls)), + &es8323_right_mixer_controls[0], + ARRAY_SIZE(es8323_right_mixer_controls)), SND_SOC_DAPM_PGA("Right Out 2", ES8323_DACPOWER, 2, 0, NULL, 0), SND_SOC_DAPM_PGA("Left Out 2", ES8323_DACPOWER, 3, 0, NULL, 0), @@ -346,61 +316,59 @@ static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = { static const struct snd_soc_dapm_route audio_map[] = { - { "Left Line Mux", "NULL", "LINPUT1" }, - { "Left Line Mux", "NULL", "LINPUT2" }, - { "Left Line Mux", "NULL", "Left PGA Mux" }, - - { "Right Line Mux", "NULL", "RINPUT1" }, - { "Right Line Mux", "NULL", "RINPUT2" }, - { "Right Line Mux", "NULL", "Right PGA Mux" }, - - { "Left PGA Mux", "LAMP", "LINPUT1" }, - { "Left PGA Mux", "LAMP", "LINPUT2" }, - { "Left PGA Mux", "LAMP", "Differential Mux" }, - - { "Right PGA Mux", "RAMP", "RINPUT1" }, - { "Right PGA Mux", "RAMP", "RINPUT2" }, - { "Right PGA Mux", "RAMP", "Differential Mux" }, - - { "Differential Mux", "LAMP", "LINPUT1" }, - { "Differential Mux", "RAMP", "RINPUT1" }, - { "Differential Mux", "LAMP", "LINPUT2" }, - { "Differential Mux", "RAMP", "RINPUT2" }, - - { "Left ADC Mux", "Stereo", "Left PGA Mux" }, - { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, - //{ "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, - - { "Right ADC Mux", "Stereo", "Right PGA Mux" }, - { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, - //{ "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, - - { "Left ADC", NULL, "Left ADC Mux" }, - { "Right ADC", NULL, "Right ADC Mux" }, - - { "Left Line Mux", "LAMP", "LINPUT1" }, - { "Left Line Mux", "LAMP", "LINPUT2" }, - { "Left Line Mux", "LAMP", "Left PGA Mux" }, - - { "Right Line Mux", "RAMP", "RINPUT1" }, - { "Right Line Mux", "RAMP", "RINPUT2" }, - { "Right Line Mux", "RAMP", "Right PGA Mux" }, - - { "Left Mixer", "Left Playback Switch", "Left DAC" }, - { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, - - { "Right Mixer", "Right Playback Switch", "Right DAC" }, - { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, - - { "Left Out 1", NULL, "Left Mixer" }, - { "LOUT1", NULL, "Left Out 1" }, - { "Right Out 1", NULL, "Right Mixer" }, - { "ROUT1", NULL, "Right Out 1" }, - - { "Left Out 2", NULL, "Left Mixer" }, - { "LOUT2", NULL, "Left Out 2" }, - { "Right Out 2", NULL, "Right Mixer" }, - { "ROUT2", NULL, "Right Out 2" }, + {"Left Line Mux", "NULL", "LINPUT1"}, + {"Left Line Mux", "NULL", "LINPUT2"}, + {"Left Line Mux", "NULL", "Left PGA Mux"}, + + {"Right Line Mux", "NULL", "RINPUT1"}, + {"Right Line Mux", "NULL", "RINPUT2"}, + {"Right Line Mux", "NULL", "Right PGA Mux"}, + + {"Left PGA Mux", "LAMP", "LINPUT1"}, + {"Left PGA Mux", "LAMP", "LINPUT2"}, + {"Left PGA Mux", "LAMP", "Differential Mux"}, + + {"Right PGA Mux", "RAMP", "RINPUT1"}, + {"Right PGA Mux", "RAMP", "RINPUT2"}, + {"Right PGA Mux", "RAMP", "Differential Mux"}, + + {"Differential Mux", "LAMP", "LINPUT1"}, + {"Differential Mux", "RAMP", "RINPUT1"}, + {"Differential Mux", "LAMP", "LINPUT2"}, + {"Differential Mux", "RAMP", "RINPUT2"}, + + {"Left ADC Mux", "Stereo", "Left PGA Mux"}, + {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"}, + + {"Right ADC Mux", "Stereo", "Right PGA Mux"}, + {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"}, + + {"Left ADC", NULL, "Left ADC Mux"}, + {"Right ADC", NULL, "Right ADC Mux"}, + + {"Left Line Mux", "LAMP", "LINPUT1"}, + {"Left Line Mux", "LAMP", "LINPUT2"}, + {"Left Line Mux", "LAMP", "Left PGA Mux"}, + + {"Right Line Mux", "RAMP", "RINPUT1"}, + {"Right Line Mux", "RAMP", "RINPUT2"}, + {"Right Line Mux", "RAMP", "Right PGA Mux"}, + + {"Left Mixer", "Left Playback Switch", "Left DAC"}, + {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, + + {"Right Mixer", "Right Playback Switch", "Right DAC"}, + {"Right Mixer", "Right Bypass Switch", "Right Line Mux"}, + + {"Left Out 1", NULL, "Left Mixer"}, + {"LOUT1", NULL, "Left Out 1"}, + {"Right Out 1", NULL, "Right Mixer"}, + {"ROUT1", NULL, "Right Out 1"}, + + {"Left Out 2", NULL, "Left Mixer"}, + {"LOUT2", NULL, "Left Out 2"}, + {"Right Out 2", NULL, "Right Mixer"}, + {"ROUT2", NULL, "Right Out 2"}, }; struct _coeff_div { @@ -411,7 +379,6 @@ struct _coeff_div { u8 usb:1; }; - /* codec hifi mclk clock divider coefficients */ static const struct _coeff_div coeff_div[] = { /* 8k */ @@ -475,14 +442,13 @@ static inline int get_coeff(int mclk, int rate) } /* The set of rates we can generate from the above for each SYSCLK */ - static unsigned int rates_12288[] = { 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, }; static struct snd_pcm_hw_constraint_list constraints_12288 = { - .count = ARRAY_SIZE(rates_12288), - .list = rates_12288, + .count = ARRAY_SIZE(rates_12288), + .list = rates_12288, }; static unsigned int rates_112896[] = { @@ -490,8 +456,8 @@ static unsigned int rates_112896[] = { }; static struct snd_pcm_hw_constraint_list constraints_112896 = { - .count = ARRAY_SIZE(rates_112896), - .list = rates_112896, + .count = ARRAY_SIZE(rates_112896), + .list = rates_112896, }; static unsigned int rates_12[] = { @@ -500,21 +466,19 @@ static unsigned int rates_12[] = { }; static struct snd_pcm_hw_constraint_list constraints_12 = { - .count = ARRAY_SIZE(rates_12), - .list = rates_12, + .count = ARRAY_SIZE(rates_12), + .list = rates_12, }; /* * Note that this should be called from init rather than from hw_params. */ static int es8323_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) + int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; struct es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec); - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - switch (freq) { case 11289600: case 18432000: @@ -541,90 +505,78 @@ static int es8323_set_dai_sysclk(struct snd_soc_dai *codec_dai, return -EINVAL; } -static int es8323_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) +static int es8323_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { - struct snd_soc_codec *codec = codec_dai->codec; - u8 iface = 0; - u8 adciface = 0; - u8 daciface = 0; - alsa_dbg("%s----%d, fmt[%02x]\n",__FUNCTION__,__LINE__,fmt); - - iface = snd_soc_read(codec, ES8323_IFACE); - adciface = snd_soc_read(codec, ES8323_ADC_IFACE); - daciface = snd_soc_read(codec, ES8323_DAC_IFACE); - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: // MASTER MODE - alsa_dbg("es8323 in master mode"); + struct snd_soc_codec *codec = codec_dai->codec; + u8 iface = 0; + u8 adciface = 0; + u8 daciface = 0; + + iface = snd_soc_read(codec, ES8323_IFACE); + adciface = snd_soc_read(codec, ES8323_ADC_IFACE); + daciface = snd_soc_read(codec, ES8323_DAC_IFACE); + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: /* MASTER MODE */ iface |= 0x80; break; - case SND_SOC_DAIFMT_CBS_CFS: // SLAVE MODE - alsa_dbg("es8323 in slave mode"); + case SND_SOC_DAIFMT_CBS_CFS: /* SLAVE MODE */ iface &= 0x7F; break; - default: - return -EINVAL; - } - - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - adciface &= 0xFC; - //daciface &= 0xF9; //updated by david-everest,5-25 - daciface &= 0xF9; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - break; - case SND_SOC_DAIFMT_DSP_A: - break; - case SND_SOC_DAIFMT_DSP_B: - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - iface &= 0xDF; - adciface &= 0xDF; - //daciface &= 0xDF; //UPDATED BY david-everest,5-25 - daciface &= 0xBF; - break; - case SND_SOC_DAIFMT_IB_IF: - iface |= 0x20; - //adciface &= 0xDF; //UPDATED BY david-everest,5-25 - adciface |= 0x20; - //daciface &= 0xDF; //UPDATED BY david-everest,5-25 - daciface |= 0x40; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x20; - // adciface |= 0x40; //UPDATED BY david-everest,5-25 - adciface &= 0xDF; - //daciface |= 0x40; //UPDATED BY david-everest,5-25 - daciface &= 0xBF; - break; - case SND_SOC_DAIFMT_NB_IF: - iface &= 0xDF; - adciface |= 0x20; - //daciface |= 0x20; //UPDATED BY david-everest,5-25 - daciface |= 0x40; - break; - default: - return -EINVAL; - } - - snd_soc_write(codec, ES8323_IFACE, iface); - snd_soc_write(codec, ES8323_ADC_IFACE, adciface); - snd_soc_write(codec, ES8323_DAC_IFACE, daciface); - - return 0; + default: + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + adciface &= 0xFC; + daciface &= 0xF9; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + break; + case SND_SOC_DAIFMT_DSP_A: + break; + case SND_SOC_DAIFMT_DSP_B: + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + iface &= 0xDF; + adciface &= 0xDF; + daciface &= 0xBF; + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= 0x20; + adciface |= 0x20; + daciface |= 0x40; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= 0x20; + adciface &= 0xDF; + daciface &= 0xBF; + break; + case SND_SOC_DAIFMT_NB_IF: + iface &= 0xDF; + adciface |= 0x20; + daciface |= 0x40; + break; + default: + return -EINVAL; + } + + snd_soc_write(codec, ES8323_IFACE, iface); + snd_soc_write(codec, ES8323_ADC_IFACE, adciface); + snd_soc_write(codec, ES8323_DAC_IFACE, daciface); + + return 0; } static int es8323_pcm_startup(struct snd_pcm_substream *substream, @@ -632,8 +584,6 @@ static int es8323_pcm_startup(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec); - - DBG("Enter::%s----%d es8323->sysclk=%d\n",__FUNCTION__,__LINE__,es8323->sysclk); /* The set of sample rates that can be supported depends on the * MCLK supplied to the CODEC - enforce this. @@ -654,7 +604,7 @@ static int es8323_pcm_startup(struct snd_pcm_substream *substream, static int es8323_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 es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec); @@ -693,14 +643,18 @@ static int es8323_pcm_hw_params(struct snd_pcm_substream *substream, break; } - /* set iface & srate*/ + /* set iface & srate */ snd_soc_write(codec, ES8323_DAC_IFACE, daciface); snd_soc_write(codec, ES8323_ADC_IFACE, adciface); if (coeff >= 0) { snd_soc_write(codec, ES8323_IFACE, srate); - snd_soc_write(codec, ES8323_ADCCONTROL5, coeff_div[coeff].sr | (coeff_div[coeff].usb) << 4); - snd_soc_write(codec, ES8323_DACCONTROL2, coeff_div[coeff].sr | (coeff_div[coeff].usb) << 4); + snd_soc_write(codec, ES8323_ADCCONTROL5, + coeff_div[coeff].sr | (coeff_div[coeff]. + usb) << 4); + snd_soc_write(codec, ES8323_DACCONTROL2, + coeff_div[coeff].sr | (coeff_div[coeff]. + usb) << 4); } return 0; @@ -709,62 +663,62 @@ static int es8323_pcm_hw_params(struct snd_pcm_substream *substream, static int es8323_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - struct es8323_priv *es8323 = es8323_private; - // u16 mute_reg = snd_soc_read(codec, ES8323_DACCONTROL3) & 0xfb; - - DBG("Enter::%s----%d--hp_irq_flag=%d mute=%d\n",__FUNCTION__,__LINE__,hp_irq_flag,mute); - - mute_flag = mute; + struct es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec); - if (mute) - { - es8323_set_gpio(ES8323_CODEC_SET_SPK,!es8323->spk_gpio_level); - es8323_set_gpio(ES8323_CODEC_SET_HP,!es8323->hp_gpio_level); - msleep(100); - snd_soc_write(codec, ES8323_DACCONTROL3, 0x06); - } - else - { + es8323->muted = mute; + if (mute) { + es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level); + usleep_range(18000, 20000); + snd_soc_write(codec, ES8323_DACCONTROL3, 0x06); + } else { snd_soc_write(codec, ES8323_DACCONTROL3, 0x02); - snd_soc_write(codec, 0x30,es8323_DEF_VOL); - snd_soc_write(codec, 0x31,es8323_DEF_VOL); - - msleep(130); - - if(hp_irq_flag == 0) - es8323_set_gpio(ES8323_CODEC_SET_SPK,es8323->spk_gpio_level); - else - es8323_set_gpio(ES8323_CODEC_SET_HP,es8323->hp_gpio_level); - - msleep(150); + snd_soc_write(codec, 0x30, es8323_DEF_VOL); + snd_soc_write(codec, 0x31, es8323_DEF_VOL); + msleep(50); + if (!es8323->hp_inserted) + es8323_set_gpio(ES8323_CODEC_SET_SPK, es8323->spk_gpio_level); + usleep_range(18000, 20000); } return 0; } static int es8323_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) -{ +{ + struct es8323_priv *es8323 = 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(es8323->mclk)) + break; + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) { + clk_disable_unprepare(es8323->mclk); + } else { + ret = clk_prepare_enable(es8323->mclk); + if (ret) + return ret; + } snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); snd_soc_write(codec, ES8323_CHIPLOPOW2, 0x00); - snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); + snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); snd_soc_write(codec, ES8323_ADCPOWER, 0x59); break; case SND_SOC_BIAS_STANDBY: dev_dbg(codec->dev, "%s standby\n", __func__); - snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); - snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); - snd_soc_write(codec, ES8323_CHIPLOPOW2, 0x00); - snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); + snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); + snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); + snd_soc_write(codec, ES8323_CHIPLOPOW2, 0x00); + snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); snd_soc_write(codec, ES8323_ADCPOWER, 0x59); break; case SND_SOC_BIAS_OFF: + if (es8323->mclk) + clk_disable_unprepare(es8323->mclk); dev_dbg(codec->dev, "%s off\n", __func__); snd_soc_write(codec, ES8323_ADCPOWER, 0xFF); snd_soc_write(codec, ES8323_DACPOWER, 0xC0); @@ -774,12 +728,9 @@ static int es8323_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7B); break; } - codec->dapm.bias_level = level; return 0; } - - #define es8323_RATES SNDRV_PCM_RATE_8000_96000 #define es8323_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ @@ -796,72 +747,73 @@ static struct snd_soc_dai_ops es8323_ops = { static struct snd_soc_dai_driver es8323_dai = { .name = "ES8323 HiFi", .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = es8323_RATES, - .formats = es8323_FORMATS, - }, + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = es8323_RATES, + .formats = es8323_FORMATS, + }, .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = es8323_RATES, - .formats = es8323_FORMATS, - }, + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = es8323_RATES, + .formats = es8323_FORMATS, + }, .ops = &es8323_ops, .symmetric_rates = 1, }; static int es8323_suspend(struct snd_soc_codec *codec) { - // u16 i; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - snd_soc_write(codec, 0x19, 0x06); - snd_soc_write(codec, 0x30, 0x00); - snd_soc_write(codec, 0x31, 0x00); - snd_soc_write(codec, ES8323_ADCPOWER, 0xFF); - snd_soc_write(codec, ES8323_DACPOWER, 0xc0); + snd_soc_write(codec, 0x19, 0x06); + snd_soc_write(codec, 0x30, 0x00); + snd_soc_write(codec, 0x31, 0x00); + snd_soc_write(codec, ES8323_ADCPOWER, 0xFF); + snd_soc_write(codec, ES8323_DACPOWER, 0xc0); snd_soc_write(codec, ES8323_CHIPPOWER, 0xF3); snd_soc_write(codec, 0x00, 0x00); snd_soc_write(codec, 0x01, 0x58); - snd_soc_write(codec, 0x2b, 0x9c); - msleep(50); - + snd_soc_write(codec, 0x2b, 0x9c); + usleep_range(18000, 20000); return 0; } static int es8323_resume(struct snd_soc_codec *codec) { - snd_soc_write(codec, 0x2b, 0x80); + snd_soc_write(codec, 0x2b, 0x80); snd_soc_write(codec, 0x01, 0x50); snd_soc_write(codec, 0x00, 0x32); - snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); - snd_soc_write(codec, ES8323_DACPOWER, 0x0c); + snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); + snd_soc_write(codec, ES8323_DACPOWER, 0x0c); snd_soc_write(codec, ES8323_ADCPOWER, 0x59); snd_soc_write(codec, 0x31, es8323_DEF_VOL); snd_soc_write(codec, 0x30, es8323_DEF_VOL); - snd_soc_write(codec, 0x19, 0x02); + snd_soc_write(codec, 0x19, 0x02); return 0; } static struct snd_soc_codec *es8323_codec; static int es8323_probe(struct snd_soc_codec *codec) { - // struct es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec); + struct es8323_priv *es8323 = snd_soc_codec_get_drvdata(codec); int ret = 0; - printk("%s\n", __func__); - if (codec == NULL) { dev_err(codec->dev, "Codec device not registered\n"); return -ENODEV; } - codec->read = es8323_read_reg_cache; - codec->write = es8323_write; - codec->hw_write = (hw_write_t)i2c_master_send; + es8323->mclk = devm_clk_get(codec->dev, "mclk"); + if (IS_ERR(es8323->mclk)) { + dev_err(codec->dev, "%s mclk is missing or invalid\n", __func__); + return PTR_ERR(es8323->mclk); + } + ret = clk_prepare_enable(es8323->mclk); + if (ret) + return ret; + codec->hw_write = (hw_write_t) i2c_master_send; codec->control_data = container_of(codec->dev, struct i2c_client, dev); es8323_codec = codec; @@ -870,72 +822,54 @@ static int es8323_probe(struct snd_soc_codec *codec) dev_err(codec->dev, "Failed to issue reset\n"); return ret; } - - #if 1 - //snd_soc_write(codec, 0x35 , 0xa0); - //snd_soc_write(codec, 0x36 , 0x08); //for 1.8V VDD - //snd_soc_write(codec, 0x08,0x80); //ES8388 salve - msleep(100); - snd_soc_write(codec, 0x02,0xf3); - snd_soc_write(codec, 0x2B,0x80); - snd_soc_write(codec, 0x08,0x00); //ES8388 salve - snd_soc_write(codec, 0x00,0x35); // - snd_soc_write(codec, 0x01,0x50); //PLAYBACK & RECORD Mode,EnRefr=1 - snd_soc_write(codec, 0x03,0x59); //pdn_ana=0,ibiasgen_pdn=0 - snd_soc_write(codec, 0x05,0x00); //pdn_ana=0,ibiasgen_pdn=0 - snd_soc_write(codec, 0x06,0x00); //pdn_ana=0,ibiasgen_pdn=0 - snd_soc_write(codec, 0x07,0x7c); - snd_soc_write(codec, 0x09,0x88); //ADC L/R PGA = +24dB - snd_soc_write(codec, 0x0a,0xf0); //ADC INPUT=LIN2/RIN2 - snd_soc_write(codec, 0x0b,0x82); //ADC INPUT=LIN2/RIN2 //82 - snd_soc_write(codec, 0x0C,0x4c); //I2S-24BIT - snd_soc_write(codec, 0x0d,0x02); //MCLK/LRCK=256 - snd_soc_write(codec, 0x10,0x00); //ADC Left Volume=0db - snd_soc_write(codec, 0x11,0x00); //ADC Right Volume=0db - snd_soc_write(codec, 0x12,0xea); // ALC stereo MAXGAIN: 35.5dB, MINGAIN: +6dB (Record Volume increased!) - snd_soc_write(codec, 0x13,0xc0); - snd_soc_write(codec, 0x14,0x05); - snd_soc_write(codec, 0x15,0x06); - snd_soc_write(codec, 0x16,0x53); - snd_soc_write(codec, 0x17,0x18); //I2S-16BIT - snd_soc_write(codec, 0x18,0x02); - snd_soc_write(codec, 0x1A,0x0A); //DAC VOLUME=0DB - snd_soc_write(codec, 0x1B,0x0A); - /* - snd_soc_write(codec, 0x1E,0x01); //for 47uF capacitors ,15db Bass@90Hz,Fs=44100 - snd_soc_write(codec, 0x1F,0x84); - snd_soc_write(codec, 0x20,0xED); - snd_soc_write(codec, 0x21,0xAF); - snd_soc_write(codec, 0x22,0x20); - snd_soc_write(codec, 0x23,0x6C); - snd_soc_write(codec, 0x24,0xE9); - snd_soc_write(codec, 0x25,0xBE); - */ - snd_soc_write(codec, 0x26,0x12); //Left DAC TO Left IXER - snd_soc_write(codec, 0x27,0xb8); //Left DAC TO Left MIXER - snd_soc_write(codec, 0x28,0x38); - snd_soc_write(codec, 0x29,0x38); - snd_soc_write(codec, 0x2A,0xb8); - snd_soc_write(codec, 0x02,0x00); //aa //START DLL and state-machine,START DSM - snd_soc_write(codec, 0x19,0x02); //SOFT RAMP RATE=32LRCKS/STEP,Enable ZERO-CROSS CHECK,DAC MUTE - snd_soc_write(codec, 0x04,0x0c); //pdn_ana=0,ibiasgen_pdn=0 - msleep(100); - snd_soc_write(codec, 0x2e,0x00); - snd_soc_write(codec, 0x2f,0x00); - snd_soc_write(codec, 0x30,0x08); - snd_soc_write(codec, 0x31,0x08); - msleep(200); - snd_soc_write(codec, 0x30,0x0f); - snd_soc_write(codec, 0x31,0x0f); - msleep(200); - snd_soc_write(codec, 0x30,0x18); - snd_soc_write(codec, 0x31,0x18); - msleep(100); - snd_soc_write(codec, 0x04,0x2c); //pdn_ana=0,ibiasgen_pdn=0 - - snd_soc_write(codec, ES8323_DACCONTROL3, 0x06); - #endif - + usleep_range(18000, 20000); + snd_soc_write(codec, 0x02, 0xf3); + snd_soc_write(codec, 0x2B, 0x80); + snd_soc_write(codec, 0x08, 0x00); /* ES8388 salve */ + snd_soc_write(codec, 0x00, 0x35); + snd_soc_write(codec, 0x01, 0x50); /* PLAYBACK & RECORD Mode,EnRefr=1 */ + snd_soc_write(codec, 0x03, 0x59); /* pdn_ana=0,ibiasgen_pdn=0 */ + snd_soc_write(codec, 0x05, 0x00); /* pdn_ana=0,ibiasgen_pdn=0 */ + snd_soc_write(codec, 0x06, 0x00); /* pdn_ana=0,ibiasgen_pdn=0 */ + snd_soc_write(codec, 0x07, 0x7c); + snd_soc_write(codec, 0x09, 0x88); /* ADC L/R PGA = +24dB */ + snd_soc_write(codec, 0x0a, 0xf0); /* ADC INPUT=LIN2/RIN2 */ + snd_soc_write(codec, 0x0b, 0x82); /* ADC INPUT=LIN2/RIN2 */ + snd_soc_write(codec, 0x0C, 0x4c); /* I2S-24BIT */ + snd_soc_write(codec, 0x0d, 0x02); /* MCLK/LRCK=256 */ + snd_soc_write(codec, 0x10, 0x00); /* ADC Left Volume=0db */ + snd_soc_write(codec, 0x11, 0x00); /* ADC Right Volume=0db */ + snd_soc_write(codec, 0x12, 0xea); /* ALC stereo MAXGAIN: 35.5dB, MINGAIN: +6dB (Record Volume increased!) */ + snd_soc_write(codec, 0x13, 0xc0); + snd_soc_write(codec, 0x14, 0x05); + snd_soc_write(codec, 0x15, 0x06); + snd_soc_write(codec, 0x16, 0x53); + snd_soc_write(codec, 0x17, 0x18); /* I2S-16BIT */ + snd_soc_write(codec, 0x18, 0x02); + snd_soc_write(codec, 0x1A, 0x0A); /* DAC VOLUME=0DB */ + snd_soc_write(codec, 0x1B, 0x0A); + snd_soc_write(codec, 0x26, 0x12); /* Left DAC TO Left IXER */ + snd_soc_write(codec, 0x27, 0xb8); /* Left DAC TO Left MIXER */ + snd_soc_write(codec, 0x28, 0x38); + snd_soc_write(codec, 0x29, 0x38); + snd_soc_write(codec, 0x2A, 0xb8); + snd_soc_write(codec, 0x02, 0x00); /* START DLL and state-machine,START DSM */ + snd_soc_write(codec, 0x19, 0x02); /* SOFT RAMP RATE=32LRCKS/STEP,Enable ZERO-CROSS CHECK,DAC MUTE */ + snd_soc_write(codec, 0x04, 0x0c); /* pdn_ana=0,ibiasgen_pdn=0 */ + usleep_range(18000, 20000); + snd_soc_write(codec, 0x2e, 0x00); + snd_soc_write(codec, 0x2f, 0x00); + snd_soc_write(codec, 0x30, 0x08); + snd_soc_write(codec, 0x31, 0x08); + usleep_range(18000, 20000); + snd_soc_write(codec, 0x30, 0x0f); + snd_soc_write(codec, 0x31, 0x0f); + usleep_range(18000, 20000); + snd_soc_write(codec, 0x30, 0x18); + snd_soc_write(codec, 0x31, 0x18); + usleep_range(18000, 20000); + snd_soc_write(codec, 0x04, 0x2c); /* pdn_ana=0,ibiasgen_pdn=0 */ + es8323_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -947,210 +881,141 @@ static int es8323_remove(struct snd_soc_codec *codec) } static struct snd_soc_codec_driver soc_codec_dev_es8323 = { - .probe = es8323_probe, - .remove = es8323_remove, - .suspend = es8323_suspend, - .resume = es8323_resume, + .probe = es8323_probe, + .remove = es8323_remove, + .suspend = es8323_suspend, + .resume = es8323_resume, .set_bias_level = es8323_set_bias_level, .reg_cache_size = ARRAY_SIZE(es8323_reg), .reg_word_size = sizeof(u16), .reg_cache_default = es8323_reg, - //------------------------------------------ - //.volatile_register = es8323_volatile_register, - //.readable_register = es8323_readable_register, .reg_cache_step = 1, -#if 0 - .controls = es8323_snd_controls, - .num_controls = ARRAY_SIZE(es8323_snd_controls), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .dapm_widgets = es8323_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(es8323_dapm_widgets), - - //-------------------------------------------------- - .read = es8323_read_reg_cache, - .write = es8323_write, -#endif -}; + .read = es8323_read_reg_cache, + .write = es8323_write, -/* -dts: - codec@10 { - compatible = "es8323"; - reg = <0x10>; - spk-con-gpio = <&gpio2 GPIO_D7 GPIO_ACTIVE_HIGH>; - hp-con-gpio = <&gpio2 GPIO_D7 GPIO_ACTIVE_HIGH>; - hp-det-gpio = <&gpio0 GPIO_B5 GPIO_ACTIVE_HIGH>; - }; -*/ +}; static int es8323_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct es8323_priv *es8323; int ret = -1; - unsigned long irq_flag=0; int hp_irq = 0; enum of_gpio_flags flags; struct i2c_adapter *adapter = to_i2c_adapter(i2c->dev.parent); char reg; - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } - es8323 = devm_kzalloc(&i2c->dev,sizeof(struct es8323_priv), GFP_KERNEL); + es8323 = devm_kzalloc(&i2c->dev, sizeof(struct es8323_priv), GFP_KERNEL); if (es8323 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, es8323); - es8323->control_type = SND_SOC_I2C; reg = ES8323_DACCONTROL18; - ret = i2c_master_recv(i2c, ®, 1); - if (ret < 0){ - printk("es8323 probe error\n"); + ret = i2c_master_recv(i2c, ®, 1); + if (ret < 0) { + dev_err(&i2c->dev, "i2c recv Failed\n"); return ret; } - + es8323_private = es8323; es8323->spk_ctl_gpio = of_get_named_gpio_flags(i2c->dev.of_node, "spk-con-gpio", 0, &flags); if (es8323->spk_ctl_gpio < 0) { - DBG("%s() Can not read property spk codec-en-gpio\n", __FUNCTION__); + dev_info(&i2c->dev, "Can not read property spk_ctl_gpio\n"); es8323->spk_ctl_gpio = INVALID_GPIO; - } - else - { - es8323->spk_gpio_level = (flags & OF_GPIO_ACTIVE_LOW)? 0:1; - ret = gpio_request(es8323->spk_ctl_gpio, NULL); - if (ret != 0) { - printk("%s request SPK_CON error", __func__); - return ret; - } - gpio_direction_output(es8323->spk_ctl_gpio,!es8323->spk_gpio_level); - } - - es8323->hp_ctl_gpio = of_get_named_gpio_flags(i2c->dev.of_node, "hp-con-gpio", 0, &flags); - if (es8323->hp_ctl_gpio < 0) { - DBG("%s() Can not read property hp codec-en-gpio\n", __FUNCTION__); - es8323->hp_ctl_gpio = INVALID_GPIO; - } - else - { - es8323->hp_gpio_level = (flags & OF_GPIO_ACTIVE_LOW)? 0:1; - ret = gpio_request(es8323->hp_ctl_gpio, NULL); - if (ret != 0) { - printk("%s request hp_ctl error", __func__); - return ret; - } - gpio_direction_output(es8323->hp_ctl_gpio,!es8323->hp_gpio_level); + } else { + es8323->spk_gpio_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; + ret = devm_gpio_request_one(&i2c->dev, es8323->spk_ctl_gpio, GPIOF_DIR_OUT, NULL); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request spk_ctl_gpio\n"); + return ret; + } + es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level); } es8323->hp_det_gpio = of_get_named_gpio_flags(i2c->dev.of_node, "hp-det-gpio", 0, &flags); if (es8323->hp_det_gpio < 0) { - DBG("%s() Can not read property hp_det gpio\n", __FUNCTION__); + dev_info(&i2c->dev, "Can not read property hp_det_gpio\n"); es8323->hp_det_gpio = INVALID_GPIO; - } - else - { - es8323->hp_det_level = (flags & OF_GPIO_ACTIVE_LOW)? 0:1; - ret = gpio_request(es8323->hp_det_gpio, NULL); + } else { + es8323->hp_det_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; + ret = devm_gpio_request_one(&i2c->dev, es8323->hp_det_gpio, GPIOF_IN, NULL); if (ret != 0) { - printk("%s request HP_DET error", __func__); + dev_err(&i2c->dev, "Failed to request hp_det_gpio\n"); return ret; } - gpio_direction_input(es8323->hp_det_gpio); - - irq_flag = IRQF_TRIGGER_LOW |IRQF_ONESHOT; hp_irq = gpio_to_irq(es8323->hp_det_gpio); - if (hp_irq){ - ret = request_threaded_irq(hp_irq, NULL, hp_det_irq_handler, irq_flag, "ES8323", NULL); - if(ret == 0){ - printk("%s:register ISR (irq=%d)\n", __FUNCTION__,hp_irq); + if (hp_irq) { + ret = devm_request_threaded_irq(&i2c->dev, hp_irq, NULL, hp_det_irq_handler, + IRQ_TYPE_EDGE_BOTH | IRQF_ONESHOT,"ES8323", NULL); + if (ret < 0) { + dev_err(&i2c->dev, "request_irq failed: %d\n", ret); + return ret; + } } - else - printk("request_irq hp_irq failed\n"); - } } - - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_es8323, &es8323_dai, 1); - if (ret < 0) { - return ret; - } - - printk("es8323 probe i2c recv ok\n"); - - #ifdef CONFIG_MACH_RK_FAC - es8323_hdmi_ctrl=1; - #endif + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_es8323, + &es8323_dai, 1); return ret; } static int es8323_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } static const struct i2c_device_id es8323_i2c_id[] = { - { "es8323", 0 }, - { } + {"es8323", 0}, + {} }; + MODULE_DEVICE_TABLE(i2c, es8323_i2c_id); void es8323_i2c_shutdown(struct i2c_client *client) { struct es8323_priv *es8323 = es8323_private; - es8323_set_gpio(ES8323_CODEC_SET_SPK,!es8323->spk_gpio_level); - es8323_set_gpio(ES8323_CODEC_SET_HP,!es8323->hp_gpio_level); - mdelay(150); - snd_soc_write(es8323_codec, ES8323_CONTROL2, 0x58); - snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x32); - snd_soc_write(es8323_codec, ES8323_CHIPPOWER, 0xf3); - snd_soc_write(es8323_codec, ES8323_DACPOWER, 0xc0); - mdelay(150); - snd_soc_write(es8323_codec, ES8323_DACCONTROL26, 0x00); - snd_soc_write(es8323_codec, ES8323_DACCONTROL27, 0x00); - mdelay(150); - snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x30); - snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x34); - mdelay(150); - mdelay(150); - mdelay(150); + es8323_set_gpio(ES8323_CODEC_SET_SPK, !es8323->spk_gpio_level); + mdelay(20); + snd_soc_write(es8323_codec, ES8323_CONTROL2, 0x58); + snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x32); + snd_soc_write(es8323_codec, ES8323_CHIPPOWER, 0xf3); + snd_soc_write(es8323_codec, ES8323_DACPOWER, 0xc0); + mdelay(50); + snd_soc_write(es8323_codec, ES8323_DACCONTROL26, 0x00); + snd_soc_write(es8323_codec, ES8323_DACCONTROL27, 0x00); + mdelay(50); + snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x30); + snd_soc_write(es8323_codec, ES8323_CONTROL1, 0x34); } +static const struct of_device_id es8323_of_match[] = { + { .compatible = "everest,es8323", }, + { } +}; +MODULE_DEVICE_TABLE(of, es8323_of_match); + static struct i2c_driver es8323_i2c_driver = { .driver = { .name = "ES8323", - .owner = THIS_MODULE, - }, + .of_match_table = of_match_ptr(es8323_of_match), + }, .shutdown = es8323_i2c_shutdown, .probe = es8323_i2c_probe, .remove = es8323_i2c_remove, .id_table = es8323_i2c_id, }; - -static int __init es8323_init(void) -{ - return i2c_add_driver(&es8323_i2c_driver); -} - -static void __exit es8323_exit(void) -{ - i2c_del_driver(&es8323_i2c_driver); -} - -module_init(es8323_init); -module_exit(es8323_exit); - +module_i2c_driver(es8323_i2c_driver); MODULE_DESCRIPTION("ASoC es8323 driver"); MODULE_AUTHOR("Mark Brown "); MODULE_LICENSE("GPL"); - -- 2.34.1