diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0348bdde60cc91da9c0c22e5cf9fb4e51d81345e..7c7969a6ffdeead191f470c390889567f78a2fde 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -50,6 +50,8 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_AK5558
 	imply SND_SOC_ALC5623
 	imply SND_SOC_ALC5632
+	imply SND_SOC_ALC655
+	imply SND_SOC_AC97_STANDARD
 	imply SND_SOC_BT_SCO
 	imply SND_SOC_BD28623
 	imply SND_SOC_CQ0093VC
@@ -1466,6 +1468,16 @@ config SND_SOC_WCD934X
 config SND_SOC_WL1273
 	tristate
 
+config SND_SOC_ALC655
+	depends on SND_SOC_AC97_BUS
+        select REGMAP_AC97
+        tristate
+        
+config SND_SOC_AC97_STANDARD
+	depends on SND_SOC_AC97_BUS
+        select REGMAP_AC97
+        tristate
+
 config SND_SOC_WM0010
 	tristate
 	depends on SPI_MASTER
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 6cd9ddbb5a1829b5c83934383017990e05a3bb8f..d368c85c065d1e200354162913e959ed4ecc39eb 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -191,6 +191,8 @@ snd-soc-rt715-objs := rt715.o rt715-sdw.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
+snd-soc-alc655-objs := alc655.o
+snd-soc-ac97_standard-objs := ac97_standard.o
 snd-soc-sigmadsp-objs := sigmadsp.o
 snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
 snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
@@ -551,6 +553,8 @@ obj-$(CONFIG_SND_SOC_UDA134X)	+= snd-soc-uda134x.o
 obj-$(CONFIG_SND_SOC_UDA1380)	+= snd-soc-uda1380.o
 obj-$(CONFIG_SND_SOC_WCD9335)	+= snd-soc-wcd9335.o
 obj-$(CONFIG_SND_SOC_WCD934X)	+= snd-soc-wcd934x.o
+obj-$(CONFIG_SND_SOC_ALC655)    += snd-soc-alc655.o
+obj-$(CONFIG_SND_SOC_AC97_STANDARD)    += snd-soc-ac97_standard.o
 obj-$(CONFIG_SND_SOC_WL1273)	+= snd-soc-wl1273.o
 obj-$(CONFIG_SND_SOC_WM0010)	+= snd-soc-wm0010.o
 obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
diff --git a/sound/soc/codecs/ac97_standard.c b/sound/soc/codecs/ac97_standard.c
new file mode 100644
index 0000000000000000000000000000000000000000..494f5c10dcf84cde6a6807bf3624a0c0313d5b48
--- /dev/null
+++ b/sound/soc/codecs/ac97_standard.c
@@ -0,0 +1,483 @@
+/*
+* ac97std.c  --  ALSA SoC ac97std AC'97 codec support
+*
+* Copyright 2010-2015 Seco s.r.l.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/ac97_codec.h>
+
+#include "ac97_standard.h"
+#define DRV_NAME "ac97-standard-codec"
+
+
+struct ac97std_priv {
+	struct snd_ac97 *ac97;
+	struct regmap   *regmap;
+};
+
+static struct reg_default ac97std_reg[] = {
+	{ 0x00 , 0x0140 },  /* Reset */
+	{ 0x02 , 0x8000 },  /* Stereo Output Volume */
+	{ 0x04 , 0x8000 },  /* HP Stereo Output Volume */
+	{ 0x0A , 0x0000 },  /* PC Beep Volume */
+	{ 0x0C , 0x8008 },  /* Phone Volume */
+	{ 0x0E , 0x8008 },  /* MIC Volume */
+	{ 0x10 , 0x8808 },  /* Line In Volume */
+	{ 0x12 , 0x8808 },  /* CD Volume */
+	{ 0x16 , 0x8808 },  /* AUX Volume */
+	{ 0x18 , 0x8808 },  /* PCM out Volume */
+	{ 0x1A , 0x0000 },  /* Record Select */
+	{ 0x1C , 0x8000 },  /* Record Gain */
+	{ 0x20 , 0x0000 },  /* General Purpose */
+	{ 0x24 , 0x0001 },  /* Audio Interrupt & Paging (AC'97 2.3) */
+	{ 0x26 , 0x0000 },  /* Powerdown control / status */
+	{ 0x28 , 0x097C },  /* Extended Audio ID */
+	{ 0x2A , 0x3830 },  /* Extended Audio Status and Control */
+	{ 0x2C , 0xBB80 },  /* PCM Front DAC Rate */
+	{ 0x32 , 0xBB80 },  /* PCM LR ADC Rate */
+	{ 0x3A , 0x2000 },  /* S/PDIF Control */
+	{ 0x5A , 0x0000 },  /* Vendor Reserved Register */
+	{ 0x5C , 0x00A9 },  /* Vendor Reserved Register */
+	{ 0x62 , 0xFFFF },  /*  PCI SVID  Page ID = 01h */
+	{ 0x64 , 0xFFFF },  /*  PCI SID   Page ID = 01h */
+	{ 0x66 , 0x0000 },  /* S/PDIF RX Status    Page ID = 00h */
+	{ 0x68 , 0x0000 },  /* S/PDIF RX Status    Page ID = 00h */
+	{ 0x6A , 0x0000 },  /* S/PDIF RX Control   Page ID = 00h */
+	{ 0x6C , 0x376A },  /* DAC Slot Mapping  Page ID = 01h */
+	{ 0x6E , 0x0000 },  /* ADC Slot Mapping  Page ID = 01h */
+	{ 0x70 , 0x0000 },  /* ADC / SPDIF RX Left Peak */
+	{ 0x74 , 0x0000 },  /* PLL Setting /Debugging */
+	{ 0x76 , 0x1182 },  /* Miscellaneous */
+	{ 0x78 , 0x0070 },  /* GPIO Control */
+	{ 0x7A , 0x0070 },  /* GPIO Status */
+	{ 0x7C , 0x5649 },  /* Vendor ID1 */
+	{ 0x7E , 0x4120 },  /* Vendor ID2 */
+};
+
+
+static bool ac97std_volatile_reg( struct device *dev, unsigned int reg ) {
+	return true;
+}
+
+
+static bool ac97std_readable_reg ( struct device *dev, unsigned int reg ) {
+	switch (reg) {
+		case AC97_RESET ... AC97_HEADPHONE:
+		case AC97_PC_BEEP ... AC97_CD:
+		case AC97_AUX ... AC97_GENERAL_PURPOSE:
+		case AC97_INT_PAGING ... AC97_PCM_LR_ADC_RATE:
+		case AC97_SPDIF:
+		case AC97_AD_TEST:
+		case AC97_AC97STD_STEREO_MIC:
+		case AC97_PCI_SVID ... AC97_SENSE_INFO:
+		case AC97_AC97STD_DAC_SLOT_MAP:
+		case AC97_AC97STD_ADC_SLOT_MAP:
+		case AC97_AD_CODEC_CFG:
+		case AC97_AD_SERIAL_CFG:
+		case AC97_AD_MISC:
+		case AC97_AC97STD_GPIO_CTRL:
+		case AC97_AC97STD_GPIO_STATUS:
+		case AC97_VENDOR_ID1:
+		case AC97_VENDOR_ID2:
+			return true;
+		default:
+			return false;
+	}
+}
+
+
+static bool ac97std_writeable_reg ( struct device *dev, unsigned int reg ) {
+	switch (reg) {
+		case AC97_RESET:
+		case AC97_EXTENDED_ID:
+		case AC97_PCM_SURR_DAC_RATE:
+		case AC97_PCM_LFE_DAC_RATE:
+		case AC97_FUNC_SELECT:
+		case AC97_FUNC_INFO:
+		case AC97_AC97STD_ADC_SLOT_MAP:
+		case AC97_VENDOR_ID1:
+		case AC97_VENDOR_ID2:
+			return false;
+		default:
+			return true;
+	}
+}
+
+
+static const struct regmap_config ac97std_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register      = AC97_VENDOR_ID2,
+	.reg_defaults      = ac97std_reg,
+	.num_reg_defaults  = ARRAY_SIZE(ac97std_reg),
+
+	.readable_reg      = ac97std_readable_reg,
+	.writeable_reg     = ac97std_writeable_reg,
+	.volatile_reg      = ac97std_volatile_reg,
+
+	.cache_type        = REGCACHE_RBTREE,
+};
+
+
+static const char *ac97std_record_mux[] = {"Mic", "CD", "--", "AUX",
+	"Line", "Stereo Mix", "Mono Mix", "Phone"};
+static SOC_ENUM_DOUBLE_DECL(ac97std_record_enum,
+		AC97_REC_SEL, 8, 0, ac97std_record_mux);
+
+static const char *ac97std_mic_mux[] = {"Mic1", "Mic2"};
+static SOC_ENUM_SINGLE_DECL(ac97std_mic_enum,
+		AC97_GENERAL_PURPOSE, 8, ac97std_mic_mux);
+
+static const char *ac97std_boost[] = {"0dB", "20dB"};
+static SOC_ENUM_SINGLE_DECL(ac97std_boost_enum,
+		AC97_MIC, 6, ac97std_boost);
+
+static const char *ac97std_mic_sel[] = {"MonoMic", "StereoMic"};
+static SOC_ENUM_SINGLE_DECL(ac97std_mic_sel_enum,
+		AC97_AC97STD_STEREO_MIC, 2, ac97std_mic_sel);
+
+static const DECLARE_TLV_DB_LINEAR(master_tlv, -4650, 0);
+static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250);
+static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0);
+static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200);
+
+static const struct snd_kcontrol_new ac97std_snd_ac97_controls[] = {
+	SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv),
+	SOC_SINGLE("Speaker Playback Switch", AC97_MASTER, 15, 1, 1),
+
+	SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1, master_tlv),
+	SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
+
+	SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1, mix_tlv),
+	SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
+
+	SOC_DOUBLE_TLV("Record Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0, record_tlv),
+	SOC_SINGLE("Record Capture Switch", AC97_REC_GAIN, 15, 1, 1),
+
+	SOC_SINGLE_TLV("Beep Volume", AC97_PC_BEEP, 1, 15, 1, beep_tlv),
+	SOC_SINGLE("Beep Switch", AC97_PC_BEEP, 15, 1, 1),
+	SOC_SINGLE_TLV("Phone Volume", AC97_PHONE, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("Phone Switch", AC97_PHONE, 15, 1, 1),
+
+	/* Mono Mic and Stereo Mic's right channel controls */
+	SOC_SINGLE_TLV("Mic/StereoMic_R Volume", AC97_MIC, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("Mic/StereoMic_R Switch", AC97_MIC, 15, 1, 1),
+
+	/* Stereo Mic's left channel controls */
+	SOC_SINGLE("StereoMic_L Switch", AC97_MIC, 7, 1, 1),
+	SOC_SINGLE_TLV("StereoMic_L Volume", AC97_MIC, 8, 31, 0, mix_tlv),
+
+	SOC_DOUBLE_TLV("Line Volume", AC97_LINE, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("Line Switch", AC97_LINE, 15, 1, 1),
+	SOC_DOUBLE_TLV("CD Volume", AC97_CD, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("CD Switch", AC97_CD, 15, 1, 1),
+	SOC_DOUBLE_TLV("AUX Volume", AC97_AUX, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("AUX Switch", AC97_AUX, 15, 1, 1),
+
+	SOC_SINGLE("Analog Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0),
+
+	SOC_ENUM("Mic Boost", ac97std_boost_enum),
+	SOC_ENUM("Mic1/2 Mux", ac97std_mic_enum),
+	SOC_ENUM("Mic Select", ac97std_mic_sel_enum),
+	SOC_ENUM("Record Mux", ac97std_record_enum),
+};
+
+
+static const unsigned int ac97std_rates[] = {
+	48000, 48000
+};
+
+
+static const struct snd_pcm_hw_constraint_list ac97std_rate_constraints = {
+	.count	= ARRAY_SIZE(ac97std_rates),
+	.list	= ac97std_rates,
+};
+
+
+static int ac97std_analog_prepare (struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {
+	struct snd_soc_component *component = dai->component;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	//struct ac97std_priv *ac97std = snd_soc_codec_get_drvdata(codec);
+	int reg;
+
+	/* enable variable rate audio (VRA) and disable S/PDIF output */
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0005);
+	// soc_ac97_ops->write(ac97std->ac97, AC97_EXTENDED_STATUS,
+	// 		(soc_ac97_ops->read(ac97std->ac97, AC97_EXTENDED_STATUS) | 0x1) & ~0x4);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
+		reg = AC97_PCM_FRONT_DAC_RATE;
+	} else {
+		reg = AC97_PCM_LR_ADC_RATE;
+	}
+
+	return snd_soc_component_write(component, reg, runtime->rate);
+	// soc_ac97_ops->write(ac97std->ac97, reg, runtime->rate);
+	// return 0;
+}
+
+
+static int ac97std_digital_prepare (struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {
+	struct snd_soc_component *component = dai->component;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	snd_soc_component_write(component, AC97_SPDIF, 0x2002);
+
+	/* enable VRA and S/PDIF output */
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0005, 0x0005);
+	//ac97std_write (codec,  AC97_EXTENDED_STATUS, ac97std_read (codec, AC97_EXTENDED_STATUS) | 0x5);
+
+	return snd_soc_component_write(component, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
+}
+
+
+static int ac97std_set_bias_level( struct snd_soc_component *component,	enum snd_soc_bias_level level ) {
+	switch (level) {
+		case SND_SOC_BIAS_ON: /* full On */
+		case SND_SOC_BIAS_PREPARE: /* partial On */
+		case SND_SOC_BIAS_STANDBY: /* Off, with power */
+			snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
+			break;
+		case SND_SOC_BIAS_OFF: /* Off, without power */
+			/* disable everything including AC link */
+			snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
+			break;
+	}
+	//codec->dapm.bias_level = level;
+	return 0;
+}
+
+
+static int ac97std_reset (struct snd_soc_component *component, int try_warm) {
+	struct ac97std_priv *ac97std = snd_soc_component_get_drvdata( component );
+
+	if (try_warm && soc_ac97_ops->warm_reset) {
+		soc_ac97_ops->warm_reset(ac97std->ac97);
+		if (  snd_soc_component_read( component, AC97_RESET ) == 0x140 )
+			return 1;
+	}
+	soc_ac97_ops->reset(ac97std->ac97);
+
+	if (soc_ac97_ops->warm_reset)
+		soc_ac97_ops->warm_reset(ac97std->ac97);
+
+	return 0;
+}
+
+
+static struct snd_soc_dai_ops ac97std_dai_ops_analog = {
+//	.startup = ac97std_startup,
+	.prepare = ac97std_analog_prepare,
+};
+
+
+static struct snd_soc_dai_ops ac97std_dai_ops_digital = {
+	.prepare = ac97std_digital_prepare,
+};
+
+
+static struct snd_soc_dai_driver ac97std_dai[] = {
+	{
+ 		.name = "ac97std-hifi-analog",
+
+		.playback = {
+			.stream_name = "Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_48000, //SNDRV_PCM_RATE_KNOT,
+			.formats = SND_SOC_STD_AC97_FMTS,
+		},
+		.capture = {
+			.stream_name = "Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_KNOT,
+			.formats = SND_SOC_STD_AC97_FMTS,
+		},
+
+		.ops = &ac97std_dai_ops_analog,
+	},
+	{
+		.name = "ac97std-hifi-IEC958",
+		///.ac97_control = 1,
+
+		.playback = {
+			.stream_name = "ac97std IEC958",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_32000 |
+				SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+			.formats = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,
+		},
+
+		.ops = &ac97std_dai_ops_digital,
+	},
+};
+
+
+static int ac97std_soc_probe( struct snd_soc_component *component ) {
+ 	int ret = 0;
+	u32 reg1, reg2;
+
+	struct ac97std_priv *ac97std = snd_soc_component_get_drvdata( component );
+
+	// ac97std->regmap = devm_regmap_init( &pdev->dev, NULL, ac97std, &ac97std_regmap );
+	// if ( IS_ERR( ac97std->regmap ) ) {
+	// 	ret = PTR_ERR( ac97std->regmap );
+	// 	return ret;
+	// }
+
+#ifdef CONFIG_SND_SOC_AC97_BUS
+ 		ac97std->ac97 = snd_soc_new_ac97_component( component, 0x0,
+						      0x0);
+		if ( IS_ERR( ac97std->ac97 ) )
+			return PTR_ERR( ac97std->ac97 );
+		ac97std->regmap = regmap_init_ac97( ac97std->ac97, &ac97std_regmap );
+		if ( IS_ERR( ac97std->regmap ) ) {
+			snd_soc_free_ac97_component( ac97std->ac97 );
+			return PTR_ERR( ac97std->regmap );
+		}
+#endif
+
+	snd_soc_component_init_regmap( component, ac97std->regmap );
+	// regcache_mark_dirty(component->regmap);
+	// snd_soc_component_cache_sync(component);
+
+
+
+// 	if ( !soc_ac97_ops ){
+// 		dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
+// 		return -ENOMEM;
+// 	}
+
+
+// 	snd_soc_codec_set_drvdata (codec, ac97std->ac97);
+
+ 	/* do a cold reset for the controller and then try
+ 	 * a warm reset followed by an optional cold reset for codec */
+ 	ac97std_reset (component, 0);
+ 	ret = ac97std_reset (component, 1);
+ 	if ( ret < 0 ) {
+ 		printk(KERN_ERR "Failed to reset ac97std: AC97 link error\n");
+ 		goto err_put_device;
+ 	}
+
+ 	// ret = device_add(&ac97std->ac97->dev);
+ 	// if (ret)
+ 	// 	goto err_put_device;
+
+ 	/* Read out vendor IDs */
+	reg1 = snd_soc_component_read( component, AC97_VENDOR_ID1 );
+	reg2 = snd_soc_component_read( component, AC97_VENDOR_ID2 );
+ 	printk( KERN_INFO "ac97std SoC Audio Codec [ID = %04x - %04x]\n", reg1, reg2 );
+
+	if (reg1 == 0x414c)
+		ac97std_dai->playback.rates = SNDRV_PCM_RATE_48000;
+	else if (reg1 == 0x5649)
+		ac97std_dai->playback.rates = SNDRV_PCM_RATE_44100;
+	else
+		printk(KERN_ERR "ac97_standard: Unrecognized vendor ID, bitrate could be wrong");
+
+ 	/*  Set initial state of the codec  */
+ 	ac97std_set_bias_level( component, SND_SOC_BIAS_STANDBY );
+
+	/* unmute captures and playbacks volume */
+	snd_soc_component_write( component, AC97_MASTER, 0x0000 );
+	snd_soc_component_write( component, AC97_PCM, 0x0000 );
+	snd_soc_component_write( component, AC97_REC_GAIN, 0x0000 );
+
+ 	/* At 3.3V analog supply, for the bits 3:2 should be set 10b for the lowest power instead of default 00b */
+ 	snd_soc_component_update_bits(component, AC97_AD_TEST, 0x0008, 0x0008);
+
+ 	/* To maximize recording quality by removing white noise */
+ 	snd_soc_component_update_bits(component, AC97_AD_TEST, 0x0400, 0x0400);
+
+ 	return 0;
+
+err_put_device:
+//  	put_device(&ac97std->ac97->dev);
+	return ret;
+}
+
+struct snd_soc_component_driver ac97std_codec = {
+ 	.probe             = ac97std_soc_probe,
+ 	.set_bias_level    = ac97std_set_bias_level,
+
+	.controls          = ac97std_snd_ac97_controls,
+	.num_controls      = ARRAY_SIZE(ac97std_snd_ac97_controls),
+};
+
+
+static int ac97std_probe (struct platform_device *pdev) {
+	int                ret;
+	struct ac97std_priv *ac97std;
+	
+	ac97std = devm_kzalloc( &pdev->dev, sizeof(*ac97std), GFP_KERNEL );
+	if ( ac97std == NULL )
+	 	return -ENOMEM;
+
+	platform_set_drvdata( pdev, ac97std );
+
+	ret = devm_snd_soc_register_component( &pdev->dev,
+			&ac97std_codec, ac97std_dai, ARRAY_SIZE(ac97std_dai) );
+
+	return ret;
+}
+
+
+static int ac97std_remove (struct platform_device *pdev) {
+	//snd_soc_unregister_codec (&pdev->dev);
+	return 0;
+}
+
+
+static const struct of_device_id ac97_standard_of_match[] = {
+	{ .compatible = "seco,ac97_standard", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ac97_standard_of_match);
+
+
+static struct platform_driver ac97std_codec_driver = {
+	.driver = {
+		.name           = DRV_NAME,
+		.owner          = THIS_MODULE,
+		.of_match_table = ac97_standard_of_match,
+	},
+	.probe  = ac97std_probe,
+	.remove = ac97std_remove,
+};
+
+module_platform_driver(ac97std_codec_driver);
+
+
+MODULE_DESCRIPTION("ASoC AC'97 standard codec driver");
+MODULE_AUTHOR("Seco s.r.l.");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/ac97_standard.h b/sound/soc/codecs/ac97_standard.h
new file mode 100644
index 0000000000000000000000000000000000000000..0321e16f8d4a6f92e615b5cb0750c56050a24dd4
--- /dev/null
+++ b/sound/soc/codecs/ac97_standard.h
@@ -0,0 +1,28 @@
+/*
+ * vt1613.h - AC97STD audio codec interface
+ *
+ * Copyright 2010-2015 Seco s.r.l.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef _AC97STD_H
+#define _AC97STD_H
+
+#define AC97_AC97STD_DAC_SLOT_MAP  0x6C
+#define AC97_AC97STD_ADC_SLOT_MAP  0x6E 
+
+#define AC97_AC97STD_GPIO_CTRL     0x78
+#define AC97_AC97STD_GPIO_STATUS   0x7A
+
+#define AC97_AC97STD_STEREO_MIC    0x5C
+
+/* 	AC97STD DAI ID's */
+#define AC97STD_DAI_AC97_ANALOG          0
+#define AC97STD_DAI_AC97_DIGITAL         1
+
+
+#endif
diff --git a/sound/soc/codecs/alc655.c b/sound/soc/codecs/alc655.c
new file mode 100644
index 0000000000000000000000000000000000000000..28e994082bb1f4c69f41dec5d8181407e641e537
--- /dev/null
+++ b/sound/soc/codecs/alc655.c
@@ -0,0 +1,469 @@
+/*
+* alc655.c  --  ALSA SoC alc655 AC'97 codec support
+*
+* Copyright 2010-2015 Seco s.r.l.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/ac97_codec.h>
+
+#include "alc655.h"
+#define DRV_NAME "alc655-codec"
+
+
+struct alc655_priv {
+	struct snd_ac97 *ac97;
+	struct regmap   *regmap;
+};
+
+
+static const struct reg_default alc655_reg[] = {
+	{ 0x00 , 0x0000 },  /*  Reset */
+	{ 0x02 , 0x8000 },  /*  Master Volume */
+	{ 0x06 , 0x8000 },  /*  Mono-Out Volume */
+	{ 0x0A , 0x0000 },  /*  PC Beep Volume */
+	{ 0x0C , 0x8008 },  /*  Phone Volume */
+	{ 0x0E , 0x8008 },  /*  MIC Volume */
+	{ 0x10 , 0x8808 },  /*  Line In Volume */
+	{ 0x12 , 0x8808 },  /*  CD Volume */
+	{ 0x16 , 0x8808 },  /*  AUX Volume */
+	{ 0x18 , 0x8808 },  /*  PCM out Volume */
+	{ 0x1A , 0x0000 },  /*  Record Select */
+	{ 0x1C , 0x8000 },  /*  Record Gain */
+	{ 0x20 , 0x0000 },  /*  General Purpose */
+	{ 0x24 , 0x0001 },  /*  Audio Interrupt & Paging (AC'97 2.3) */
+	{ 0x26 , 0x0000 },  /*  Powerdown control / status */
+	{ 0x28 , 0x097C },  /*  Extended Audio ID */
+	{ 0x2A , 0x3830 },  /*  Extended Audio Status and Control */
+	{ 0x2C , 0xBB80 },  /*  PCM Front DAC Rate */
+	{ 0x2E , 0XBB80 },  /*  PCM Surround Sample Rate */
+	{ 0x30 , 0XBB80 },  /*  PCM LFE Sample Rate */
+	{ 0x32 , 0xBB80 },  /*  PCM Input Sample Rate */
+	{ 0x36 , 0x8080 },  /*  Center/LFE Volume */
+	{ 0x3A , 0x2000 },  /*  S/PDIF Control */
+	{ 0x64 , 0xFFFF },  /*  Sorrount DAC Volume */
+	{ 0x66 , 0x0000 },  /*  S/PDIF RX Status */
+	{ 0x6A , 0x0000 },  /*  Multi Channel Ctl */
+	{ 0x7A , 0x60A2 },  /*  Extension Control */
+	{ 0x7C , 0x414C },  /*  Vendor ID1 */
+	{ 0x7E , 0x4760 },  /*  Vendor ID2 */
+};
+
+
+
+static bool alc655_volatile_reg( struct device *dev, unsigned int reg ) {
+	return true;
+}
+
+
+static bool alc655_readable_reg( struct device *dev, unsigned int reg ) {
+	switch (reg) {
+		case AC97_RESET ... AC97_HEADPHONE:
+		case AC97_PC_BEEP ... AC97_CD:
+		case AC97_AUX ... AC97_GENERAL_PURPOSE:
+		case AC97_INT_PAGING ... AC97_PCM_LR_ADC_RATE:
+		case AC97_SPDIF:
+		case AC97_AD_TEST:
+		case AC97_ALC655_STEREO_MIC:
+		case AC97_PCI_SVID ... AC97_SENSE_INFO:
+		case AC97_ALC655_DAC_SLOT_MAP:
+		case AC97_ALC655_ADC_SLOT_MAP:
+		case AC97_AD_CODEC_CFG:
+		case AC97_AD_SERIAL_CFG:
+		case AC97_AD_MISC:
+		case AC97_ALC655_GPIO_CTRL:
+		case AC97_ALC655_GPIO_STATUS:
+		case AC97_VENDOR_ID1:
+		case AC97_VENDOR_ID2:
+			return true;
+		default:
+			return false;
+	}
+}
+
+
+static bool alc655_writeable_reg( struct device *dev, unsigned int reg ) {
+	switch (reg) {
+		case AC97_RESET:
+		case AC97_EXTENDED_ID:
+		case AC97_PCM_SURR_DAC_RATE:
+		case AC97_PCM_LFE_DAC_RATE:
+		case AC97_FUNC_SELECT:
+		case AC97_FUNC_INFO:
+		case AC97_ALC655_ADC_SLOT_MAP:
+		case AC97_VENDOR_ID1:
+		case AC97_VENDOR_ID2:
+			return false;
+		default:
+			return true;
+	}
+}
+
+
+static const struct regmap_config alc655_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register      = AC97_VENDOR_ID2,
+	.reg_defaults      = alc655_reg,
+	.num_reg_defaults  = ARRAY_SIZE(alc655_reg),
+
+	.readable_reg      = alc655_readable_reg,
+	.writeable_reg     = alc655_writeable_reg,
+	.volatile_reg      = alc655_volatile_reg,
+
+	.cache_type        = REGCACHE_RBTREE,
+};
+
+
+static const char *alc655_record_mux[] = {"Mic", "CD", "--", "AUX",
+	"Line", "Stereo Mix", "Mono Mix", "Phone"};
+static SOC_ENUM_DOUBLE_DECL(alc655_record_enum,
+		AC97_REC_SEL, 8, 0, alc655_record_mux);
+
+static const char *alc655_mic_mux[] = {"Mic1", "Mic2"};
+static SOC_ENUM_SINGLE_DECL(alc655_mic_enum,
+		AC97_GENERAL_PURPOSE, 8, alc655_mic_mux);
+
+static const char *alc655_boost[] = {"0dB", "20dB"};
+static SOC_ENUM_SINGLE_DECL(alc655_boost_enum,
+		AC97_MIC, 6, alc655_boost);
+
+static const char *alc655_mic_sel[] = {"MonoMic", "StereoMic"};
+static SOC_ENUM_SINGLE_DECL(alc655_mic_sel_enum,
+		AC97_ALC655_STEREO_MIC, 2, alc655_mic_sel);
+
+static const DECLARE_TLV_DB_LINEAR(master_tlv, -4650, 0);
+static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250);
+static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0);
+static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200);
+
+static const struct snd_kcontrol_new alc655_snd_ac97_controls[] = {
+	SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv),
+	SOC_SINGLE("Speaker Playback Switch", AC97_MASTER, 15, 1, 1),
+
+	SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1, master_tlv),
+	SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
+
+	SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PCM, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
+
+	SOC_DOUBLE_TLV("Record Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0, record_tlv),
+	SOC_SINGLE("Record Capture Switch", AC97_REC_GAIN, 15, 1, 1),
+
+	SOC_SINGLE_TLV("Beep Volume", AC97_PC_BEEP, 1, 15, 1, beep_tlv),
+	SOC_SINGLE("Beep Switch", AC97_PC_BEEP, 15, 1, 1),
+	SOC_SINGLE_TLV("Phone Volume", AC97_PHONE, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("Phone Switch", AC97_PHONE, 15, 1, 1),
+
+	/* Mono Mic and Stereo Mic's right channel controls */
+	SOC_SINGLE_TLV("Mic/StereoMic_R Volume", AC97_MIC, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("Mic/StereoMic_R Switch", AC97_MIC, 15, 1, 1),
+
+	/* Stereo Mic's left channel controls */
+	SOC_SINGLE("StereoMic_L Switch", AC97_MIC, 7, 1, 1),
+	SOC_SINGLE_TLV("StereoMic_L Volume", AC97_MIC, 8, 31, 0, mix_tlv),
+
+	SOC_DOUBLE_TLV("Line Volume", AC97_LINE, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("Line Switch", AC97_LINE, 15, 1, 1),
+	SOC_DOUBLE_TLV("CD Volume", AC97_CD, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("CD Switch", AC97_CD, 15, 1, 1),
+	SOC_DOUBLE_TLV("AUX Volume", AC97_AUX, 8, 0, 31, 0, mix_tlv),
+	SOC_SINGLE("AUX Switch", AC97_AUX, 15, 1, 1),
+
+	SOC_SINGLE("Analog Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0),
+
+	SOC_ENUM("Mic Boost", alc655_boost_enum),
+	SOC_ENUM("Mic1/2 Mux", alc655_mic_enum),
+	SOC_ENUM("Mic Select", alc655_mic_sel_enum),
+	SOC_ENUM("Record Mux", alc655_record_enum),
+};
+
+
+static const unsigned int alc655_rates[] = {
+	48000, 48000
+};
+
+
+static const struct snd_pcm_hw_constraint_list alc655_rate_constraints = {
+	.count	= ARRAY_SIZE(alc655_rates),
+	.list	= alc655_rates,
+};
+
+
+static int alc655_analog_prepare (struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {
+	struct snd_soc_component *component = dai->component;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int reg;
+
+	/* enable variable rate audio (VRA) and disable S/PDIF output */
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0005);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
+		reg = AC97_PCM_FRONT_DAC_RATE;
+	} else {
+		reg = AC97_PCM_LR_ADC_RATE;
+	}
+
+	return snd_soc_component_write(component, reg, runtime->rate);
+}
+
+
+static int alc655_digital_prepare (struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {
+	struct snd_soc_component *component = dai->component;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	snd_soc_component_write(component, AC97_SPDIF, 0x2002);
+
+	/* enable VRA and S/PDIF output */
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0005, 0x0005);
+	//alc655_write (codec,  AC97_EXTENDED_STATUS, alc655_read (codec, AC97_EXTENDED_STATUS) | 0x5);
+
+	return snd_soc_component_write(component, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
+}
+
+
+static int alc655_set_bias_level( struct snd_soc_component *component,	enum snd_soc_bias_level level ) {
+	switch (level) {
+		case SND_SOC_BIAS_ON: /* full On */
+		case SND_SOC_BIAS_PREPARE: /* partial On */
+		case SND_SOC_BIAS_STANDBY: /* Off, with power */
+			snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
+			break;
+		case SND_SOC_BIAS_OFF: /* Off, without power */
+			/* disable everything including AC link */
+			snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
+			break;
+	}
+	//codec->dapm.bias_level = level;
+	return 0;
+}
+
+
+static int alc655_reset (struct snd_soc_component *component, int try_warm) {
+	struct alc655_priv *alc655 = snd_soc_component_get_drvdata( component );
+
+	if (try_warm && soc_ac97_ops->warm_reset) {
+		soc_ac97_ops->warm_reset(alc655->ac97);
+		if (  snd_soc_component_read( component, AC97_RESET ) == 0x0 )
+			return 1;
+	}
+	soc_ac97_ops->reset(alc655->ac97);
+
+	if (soc_ac97_ops->warm_reset)
+		soc_ac97_ops->warm_reset(alc655->ac97);
+
+	if ( snd_soc_component_read( component, AC97_RESET ) == 0x0 )
+		return 0;
+
+	return -EIO;
+}
+
+
+static struct snd_soc_dai_ops alc655_dai_ops_analog = {
+//	.startup = alc655_startup,
+	.prepare = alc655_analog_prepare,
+};
+
+
+static struct snd_soc_dai_ops alc655_dai_ops_digital = {
+	.prepare = alc655_digital_prepare,
+};
+
+
+static struct snd_soc_dai_driver alc655_dai[] = {
+	{
+ 		.name = "alc655-hifi-analog",
+
+		.playback = {
+			.stream_name = "Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_48000, //SNDRV_PCM_RATE_KNOT,
+			.formats = SND_SOC_STD_AC97_FMTS,
+		},
+		.capture = {
+			.stream_name = "Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_KNOT,
+			.formats = SND_SOC_STD_AC97_FMTS,
+		},
+
+		.ops = &alc655_dai_ops_analog,
+	},
+	{
+		.name = "alc655-hifi-IEC958",
+		///.ac97_control = 1,
+
+		.playback = {
+			.stream_name = "alc655 IEC958",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_32000 |
+				SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+			.formats = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,
+		},
+
+		.ops = &alc655_dai_ops_digital,
+	},
+};
+
+
+static int alc655_soc_probe( struct snd_soc_component *component ) {
+ 	int ret = 0;
+	u32 reg1, reg2;
+
+	struct alc655_priv *alc655 = snd_soc_component_get_drvdata( component );
+
+	// alc655->regmap = devm_regmap_init( &pdev->dev, NULL, alc655, &alc655_regmap );
+	// if ( IS_ERR( alc655->regmap ) ) {
+	// 	ret = PTR_ERR( alc655->regmap );
+	// 	return ret;
+	// }
+
+#ifdef CONFIG_SND_SOC_AC97_BUS
+ 		alc655->ac97 = snd_soc_new_ac97_component( component, 0x0,
+						      0x0);
+		if ( IS_ERR( alc655->ac97 ) )
+			return PTR_ERR( alc655->ac97 );
+		alc655->regmap = regmap_init_ac97( alc655->ac97, &alc655_regmap );
+		if ( IS_ERR( alc655->regmap ) ) {
+			snd_soc_free_ac97_component( alc655->ac97 );
+			return PTR_ERR( alc655->regmap );
+		}
+#endif
+
+	snd_soc_component_init_regmap( component, alc655->regmap );
+	// regcache_mark_dirty(component->regmap);
+	// snd_soc_component_cache_sync(component);
+
+
+
+// 	if ( !soc_ac97_ops ){
+// 		dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
+// 		return -ENOMEM;
+// 	}
+
+
+// 	snd_soc_codec_set_drvdata (codec, alc655->ac97);
+
+ 	/* do a cold reset for the controller and then try
+ 	 * a warm reset followed by an optional cold reset for codec */
+ 	alc655_reset (component, 0);
+ 	ret = alc655_reset (component, 1);
+ 	if ( ret < 0 ) {
+ 		printk(KERN_ERR "Failed to reset alc655: AC97 link error\n");
+ 		goto err_put_device;
+ 	}
+
+ 	// ret = device_add(&alc655->ac97->dev);
+ 	// if (ret)
+ 	// 	goto err_put_device;
+
+ 	/* Read out vendor IDs */
+	reg1 = snd_soc_component_read( component, AC97_VENDOR_ID1 );
+	reg2 = snd_soc_component_read( component, AC97_VENDOR_ID2 );
+ 	printk( KERN_INFO "alc655 SoC Audio Codec [ID = %04x - %04x]\n", reg1, reg2 );
+
+ 	/*  Set initial state of the codec  */
+ 	alc655_set_bias_level( component, SND_SOC_BIAS_STANDBY );
+
+	/* unmute captures and playbacks volume */
+	snd_soc_component_write( component, AC97_MASTER, 0x0000 );
+	snd_soc_component_write( component, AC97_PCM, 0x0000 );
+	snd_soc_component_write( component, AC97_REC_GAIN, 0x0000 );
+
+ 	/* At 3.3V analog supply, for the bits 3:2 should be set 10b for the lowest power instead of default 00b */
+ 	snd_soc_component_update_bits(component, AC97_AD_TEST, 0x0008, 0x0008);
+
+ 	/* To maximize recording quality by removing white noise */
+ 	snd_soc_component_update_bits(component, AC97_AD_TEST, 0x0400, 0x0400);
+
+ 	return 0;
+
+err_put_device:
+//  	put_device(&alc655->ac97->dev);
+	return ret;
+}
+
+
+struct snd_soc_component_driver alc655_codec = {
+ 	.probe             = alc655_soc_probe,
+ 	.set_bias_level    = alc655_set_bias_level,
+	.controls          = alc655_snd_ac97_controls,
+	.num_controls      = ARRAY_SIZE(alc655_snd_ac97_controls),
+};
+
+
+static int alc655_probe (struct platform_device *pdev) {
+	int                ret;
+	struct alc655_priv *alc655;
+	
+	alc655 = devm_kzalloc( &pdev->dev, sizeof(*alc655), GFP_KERNEL );
+	if ( alc655 == NULL )
+	 	return -ENOMEM;
+
+	platform_set_drvdata( pdev, alc655 );
+
+	ret = devm_snd_soc_register_component( &pdev->dev,
+			&alc655_codec, alc655_dai, ARRAY_SIZE(alc655_dai) );
+
+	return ret;
+}
+
+
+static int alc655_remove (struct platform_device *pdev) {
+	//snd_soc_unregister_codec (&pdev->dev);
+	return 0;
+}
+
+
+static const struct of_device_id alc655_of_match[] = {
+	{ .compatible = "seco,alc655", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, alc655_of_match);
+
+
+static struct platform_driver alc655_codec_driver = {
+	.driver = {
+		.name           = DRV_NAME,
+		.owner          = THIS_MODULE,
+		.of_match_table = alc655_of_match,
+	},
+	.probe  = alc655_probe,
+	.remove = alc655_remove,
+};
+
+module_platform_driver(alc655_codec_driver);
+
+
+MODULE_DESCRIPTION("ASoC AC'97 ALC655 codec driver");
+MODULE_AUTHOR("Seco s.r.l.");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/alc655.h b/sound/soc/codecs/alc655.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2da36c78d1c19ca0a003f5154ca296a868ddf8b
--- /dev/null
+++ b/sound/soc/codecs/alc655.h
@@ -0,0 +1,28 @@
+/*
+ * vt1613.h - ALC655 audio codec interface
+ *
+ * Copyright 2010-2015 Seco s.r.l.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef _ALC655_H
+#define _ALC655_H
+
+#define AC97_ALC655_DAC_SLOT_MAP  0x6C
+#define AC97_ALC655_ADC_SLOT_MAP  0x6E 
+
+#define AC97_ALC655_GPIO_CTRL     0x78
+#define AC97_ALC655_GPIO_STATUS   0x7A
+
+#define AC97_ALC655_STEREO_MIC    0x5C
+
+/* 	ALC655 DAI ID's */
+#define ALC655_DAI_AC97_ANALOG          0
+#define ALC655_DAI_AC97_DIGITAL         1
+
+
+#endif
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index bb5aac95f548b041aa8f4e30c0ce5250f27af62e..4099cd8656ed85e34c286afebd7e1bbc502c4b1d 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -395,6 +395,32 @@ config SND_SOC_IMX_WM8958
 	 Say Y if you want to add support for SoC audio on an i.MX board with
 	 a wm8958 codec.
 
+
+config SND_SOC_SECO_AC97_STANDARD
+        tristate "SoC Audio support for i.MX SECO boards with STANDARD AC'97"
+        depends on OF
+        select SND_SOC_AC97_BUS
+        select SND_SOC_AC97_STANDARD
+        select SND_SOC_IMX_PCM_DMA
+        select SND_SOC_IMX_AUDMUX
+        select SND_SOC_FSL_SSI
+        help
+          Say Y if you want to add support for SoC audio on an i.MX board with
+          a standard codec in AC97 mode.
+
+config SND_SOC_SECO_AC97_ALC655
+        tristate "SoC Audio support for i.MX SECO boards with ALC655 AC'97"
+        depends on OF
+        select SND_SOC_AC97_BUS
+        select SND_SOC_ALC655
+        select SND_SOC_IMX_PCM_DMA
+        select SND_SOC_IMX_AUDMUX
+        select SND_SOC_FSL_SSI
+        help
+          Say Y if you want to add support for SoC audio on an i.MX board with
+          a ALC655 codec in AC97 mode.
+
+
 config SND_SOC_IMX_MICFIL
 	tristate "SoC Audio support for i.MX boards with micfil"
 	depends on OF && I2C
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 98bf58311964b8ec932daa4123edd8cfc3b2b2dc..032cbe32a16aa719d02068bac6b77bcefb634288 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -34,6 +34,12 @@ snd-soc-fsl-esai-client-objs := fsl_esai_client.o
 snd-soc-fsl-aud2htx-objs := fsl_aud2htx.o
 snd-soc-fsl-rpmsg-objs := fsl_rpmsg.o
 
+snd-soc-seco-ac97-alc655-objs := seco-ac97-alc655.o
+snd-soc-seco-ac97-standard-objs := seco-ac97-standard.o
+
+obj-$(CONFIG_SND_SOC_SECO_AC97_ALC655) += snd-soc-seco-ac97-alc655.o
+#obj-$(CONFIG_SND_SOC_SECO_AC97_STANDARD) += snd-soc-seco-ac97-standard.o
+
 obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
 snd-soc-fsl-hdmi-objs := fsl_hdmi.o
diff --git a/sound/soc/fsl/seco-ac97-alc655.c b/sound/soc/fsl/seco-ac97-alc655.c
new file mode 100644
index 0000000000000000000000000000000000000000..250b617644a564017bc2812c21fe4ac60f1f5012
--- /dev/null
+++ b/sound/soc/fsl/seco-ac97-alc655.c
@@ -0,0 +1,273 @@
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/clk.h>
+#include <sound/pcm_params.h>
+
+#include "../codecs/alc655.h"
+#include "imx-audmux.h"
+#include "fsl_ssi.h"
+
+#define DRV_NAME "imx-ac97-alc655"
+#define DAI_NAME_SIZE	32
+
+struct imx_alc655_data {
+	struct snd_soc_dai_link dai;
+	struct snd_soc_card     card;
+	char                    codec_dai_name[DAI_NAME_SIZE];
+	char                    platform_name[DAI_NAME_SIZE];
+	struct clk              *codec_clk;
+	unsigned int            clk_frequency;
+};
+
+
+static int imx_alc655_dai_init(struct snd_soc_pcm_runtime *rtd) {
+	return 0;
+}
+
+
+static int imx_alc655_audio_params (struct snd_pcm_substream *substream,
+        struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_soc_dai *codec_dai = asoc_rtd_to_cpu(rtd, 0);
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 1);
+	struct snd_soc_card *card = rtd->card;
+	struct device *dev = card->dev;
+	unsigned int fmt;
+	int ret = 0;
+
+	// struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	// struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	// int ret;
+
+	fmt = SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFS;
+	ret = snd_soc_dai_set_fmt( cpu_dai, fmt );
+	if ( ret ) {
+		dev_err( dev, "failed to set cpu dai fmt: %d\n", ret );
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+
+	ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2,
+									params_physical_width(params));
+	if (ret) {
+			dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+			return ret;
+	}
+	ret = snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_IN);
+
+    return ret;
+}
+
+
+static int imx_audmux_ac97_config (struct platform_device *pdev, int intPort, int extPort) {
+	int ret;
+	unsigned int ptcr, pdcr;
+
+	intPort = intPort - 1;
+	extPort = extPort - 1;
+
+	ptcr = IMX_AUDMUX_V2_PTCR_SYN | IMX_AUDMUX_V2_PTCR_TCLKDIR | IMX_AUDMUX_V2_PTCR_TCSEL(extPort);
+	pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(extPort);
+
+	ret = imx_audmux_v2_configure_port (intPort, ptcr, pdcr);
+	if ( ret ) {
+		dev_err (&pdev->dev, "Audmux internal port setup failed\n");
+		return ret;
+	}
+
+	ptcr = IMX_AUDMUX_V2_PTCR_SYN | IMX_AUDMUX_V2_PTCR_TFSDIR | IMX_AUDMUX_V2_PTCR_TFSEL(intPort);
+
+	pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL (intPort);
+
+	ret = imx_audmux_v2_configure_port (extPort, ptcr, pdcr);
+	if ( ret ) {
+		dev_err (&pdev->dev, "Audmux external port setup failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+
+static int imx_alc655_probe (struct platform_device *pdev) {
+	struct device_node *ssi_np, *codec_np, *np = pdev->dev.of_node;
+
+	struct platform_device *codec_pdev;
+	struct platform_device *ssi_pdev;
+	struct imx_alc655_data *data = NULL;
+	struct snd_soc_dai_link_component *comp;
+	int int_port, ext_port;
+	int ret;
+
+	ret = of_property_read_u32 (np, "mux-int-port", &int_port);
+	if ( ret ) {
+		dev_err (&pdev->dev, "mux-int-port property missing or invalid\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32 (np, "mux-ext-port", &ext_port);
+	if ( ret ) {
+		dev_err (&pdev->dev, "mux-ext-port property missing or invalid\n");
+		return ret;
+	}
+
+	ret = imx_audmux_ac97_config (pdev, int_port, ext_port);
+	if ( ret ) {
+		dev_err (&pdev->dev, "Audmux port setup failed\n");
+		return ret;
+	}
+
+	ssi_np = of_parse_phandle (np, "ssi-controller", 0);
+	if ( !ssi_np ) {
+		dev_err (&pdev->dev, "ssi-controller phandle missing or invalid\n");
+		return -EINVAL;
+	}
+	ssi_pdev = of_find_device_by_node (ssi_np);
+	if ( !ssi_pdev ) {
+		dev_err (&pdev->dev, "Failed to find SSI platform device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	codec_np = of_parse_phandle (np, "audio-codec", 0);
+	if ( !codec_np ) {
+		dev_err (&pdev->dev, "audio-codec phandle missing or invalid\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+	codec_pdev = of_find_device_by_node (codec_np);
+	if ( !codec_pdev ) {
+		dev_err (&pdev->dev, "Failed to find codec device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto fail_data;
+	}
+
+	comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
+	if (!comp) {
+		ret = -ENOMEM;
+		goto fail_comp;
+	}
+
+	data->dai.cpus		= &comp[0];
+	data->dai.codecs	= &comp[1];
+	data->dai.platforms	= &comp[2];
+
+	data->dai.num_cpus	= 1;
+	data->dai.num_codecs	= 1;
+	data->dai.num_platforms	= 1;
+
+	data->dai.name =  "alc655-AC97";
+	data->dai.stream_name = "ALC655-analog";
+	data->dai.codecs->dai_name = "alc655-hifi-analog";
+	data->dai.codecs->of_node = codec_np;
+	data->dai.cpus->of_node = ssi_np;
+	data->dai.platforms->of_node = ssi_np;
+	data->dai.init = &imx_alc655_dai_init;
+	//data->dai.ops = &imx_alc655_audio_params;
+
+	data->card.dev = &pdev->dev;
+	ret = snd_soc_of_parse_card_name(&data->card, "model");
+	if (ret) {
+		dev_err(&pdev->dev, "unable to parse model\n");
+		goto fail;
+	}
+	// ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
+	// if (ret)
+	// 	goto fail;
+	data->card.num_links = 1;
+	data->card.owner = THIS_MODULE;
+	data->card.dai_link = &data->dai;
+
+
+
+	platform_set_drvdata(pdev, &data->card);
+	snd_soc_card_set_drvdata(&data->card, data);
+
+	ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+				ret);
+		goto fail;
+	}
+
+	of_node_put(ssi_np);
+	of_node_put(codec_np);
+
+	return 0;
+	// imx_alc655_dai.codecs->dai_name = dev_name (&codec_pdev->dev);
+	// imx_alc655_dai.cpu_of_node = ssi_np;
+	// imx_alc655_dai.cpus->dai_name = dev_name (&ssi_pdev->dev);
+	// imx_alc655_dai.platforms->of_node = ssi_np;
+	// imx_alc655_dai.ops = &imx_alc655_audio_ops;
+	// imx_alc655_dai.dai_fmt = SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFS;
+
+	// imx_alc655_card.dev = &pdev->dev;
+
+	// platform_set_drvdata (pdev, &imx_alc655_card);
+
+	// ret = snd_soc_register_card (&imx_alc655_card);
+	// if ( ret )
+	// 	dev_err (&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+	return 0;
+
+fail_comp:
+	kfree( data );
+fail_data:
+fail:
+	if ( ssi_np )
+		of_node_put (ssi_np);
+	if ( codec_np )
+		of_node_put (codec_np);
+
+	return ret;
+}
+
+
+static int imx_alc655_remove (struct platform_device *pdev) {
+	int ret;
+	struct snd_soc_card *card = platform_get_drvdata (pdev);
+
+	ret = snd_soc_unregister_card (card);
+
+	return ret;
+}
+
+
+static const struct of_device_id imx_alc655_audio_match[] = {
+	{ .compatible = "seco,imx-alc655-audio", },
+	{}
+};
+
+
+MODULE_DEVICE_TABLE(of, imx_alc655_audio_match);
+
+
+static struct platform_driver imx_alc655_driver = {
+	.driver = {
+		.name           = DRV_NAME,
+		.owner          = THIS_MODULE,
+		.of_match_table = imx_alc655_audio_match,
+	},
+	.probe  = imx_alc655_probe,
+	.remove = imx_alc655_remove,
+};
+module_platform_driver(imx_alc655_driver);
+
+
+MODULE_AUTHOR("Seco <info@seco.it>");
+MODULE_DESCRIPTION(DRV_NAME ": Freescale i.MX ALC655 AC97 ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-alc655");
diff --git a/sound/soc/fsl/seco-ac97-standard.c b/sound/soc/fsl/seco-ac97-standard.c
new file mode 100644
index 0000000000000000000000000000000000000000..7bb3fc515f6ca8478496ef42fa21cc394e6820d9
--- /dev/null
+++ b/sound/soc/fsl/seco-ac97-standard.c
@@ -0,0 +1,204 @@
+/*
+ * imx-ac97-ac97_standard.c -- SoC audio for i.MX Seco UDOO board with
+ *                                      STANDARD AC'97 codec 
+ * Copyright:	Seco s.r.l.
+
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include "../codecs/ac97_standard.h"
+#include "imx-audmux.h"
+#include "fsl_ssi.h"
+
+#define DRV_NAME "imx-ac97-ac97_standard"
+
+static int imx_ac97_standard_audio_params (struct snd_pcm_substream *substream,
+        struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret;
+
+	ret = snd_soc_dai_set_fmt (cpu_dai, SND_SOC_DAIFMT_AC97
+			| SND_SOC_DAIFMT_NB_NF
+			| SND_SOC_DAIFMT_CBM_CFS);
+
+	if ( ret < 0 ) {
+		dev_err (cpu_dai->dev,
+				"Failed to set cpu dai format: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+
+static struct snd_soc_ops imx_ac97_standard_audio_ops = {
+	.hw_params = imx_ac97_standard_audio_params,
+};
+
+
+static struct snd_soc_dai_link imx_ac97_standard_dai = {
+	.name		    = "ac97std_standard-AC97",
+	.stream_name	= "AC97std-analog",
+};
+
+
+static struct snd_soc_card imx_ac97_standard_card = {
+	.name		= "imx-ac97_standard-audio",
+	.owner  	= THIS_MODULE,
+	.dai_link	= &imx_ac97_standard_dai,
+	.num_links	= 1,
+};
+
+
+static int imx_audmux_ac97_config (struct platform_device *pdev, int intPort, int extPort) {
+	int ret;
+	unsigned int ptcr, pdcr;
+
+	intPort = intPort - 1;
+	extPort = extPort - 1;
+
+	ptcr = IMX_AUDMUX_V2_PTCR_SYN | IMX_AUDMUX_V2_PTCR_TCLKDIR | IMX_AUDMUX_V2_PTCR_TCSEL(extPort);
+	pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(extPort);
+
+	ret = imx_audmux_v2_configure_port (intPort, ptcr, pdcr);
+	if ( ret ) {
+		dev_err (&pdev->dev, "Audmux internal port setup failed\n");
+		return ret;
+	}
+
+	ptcr = IMX_AUDMUX_V2_PTCR_SYN | IMX_AUDMUX_V2_PTCR_TFSDIR | IMX_AUDMUX_V2_PTCR_TFSEL(intPort);
+
+	pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL (intPort);
+
+	ret = imx_audmux_v2_configure_port (extPort, ptcr, pdcr);
+	if ( ret ) {
+		dev_err (&pdev->dev, "Audmux external port setup failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+
+static int imx_ac97_standard_probe (struct platform_device *pdev) {
+	struct device_node *ssi_np, *codec_np, *np = pdev->dev.of_node;
+
+	struct platform_device *codec_pdev;
+	struct platform_device *ssi_pdev;
+	int int_port, ext_port;
+	int ret;
+
+	ret = of_property_read_u32 (np, "mux-int-port", &int_port);
+	if ( ret ) {
+		dev_err (&pdev->dev, "mux-int-port property missing or invalid\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32 (np, "mux-ext-port", &ext_port);
+	if ( ret ) {
+		dev_err (&pdev->dev, "mux-ext-port property missing or invalid\n");
+		return ret;
+	}
+
+	ret = imx_audmux_ac97_config (pdev, int_port, ext_port);
+	if ( ret ) {
+		dev_err (&pdev->dev, "Audmux port setup failed\n");
+		return ret;
+	}
+
+	ssi_np = of_parse_phandle (np, "ssi-controller", 0);
+	if ( !ssi_np ) {
+		dev_err (&pdev->dev, "ssi-controller phandle missing or invalid\n");
+		return -EINVAL;
+	}
+	ssi_pdev = of_find_device_by_node (ssi_np);
+	if ( !ssi_pdev ) {
+		dev_err (&pdev->dev, "Failed to find SSI platform device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	codec_np = of_parse_phandle (np, "audio-codec", 0);
+	if ( !codec_np ) {
+		dev_err (&pdev->dev, "audio-codec phandle missing or invalid\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+	codec_pdev = of_find_device_by_node (codec_np);
+	if ( !codec_pdev ) {
+		dev_err (&pdev->dev, "Failed to find codec device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	imx_ac97_standard_dai.codec_name = dev_name (&codec_pdev->dev);
+	imx_ac97_standard_dai.cpu_of_node = ssi_np;
+	imx_ac97_standard_dai.cpu_dai_name = dev_name (&ssi_pdev->dev);
+	imx_ac97_standard_dai.platform_of_node = ssi_np;
+	imx_ac97_standard_dai.ops = &imx_ac97_standard_audio_ops;
+	imx_ac97_standard_dai.dai_fmt = SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFS;
+
+	imx_ac97_standard_card.dev = &pdev->dev;
+
+	platform_set_drvdata (pdev, &imx_ac97_standard_card);
+
+	ret = snd_soc_register_card (&imx_ac97_standard_card);
+	if ( ret )
+		dev_err (&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+fail:
+	if ( ssi_np )
+		of_node_put (ssi_np);
+	if ( codec_np )
+		of_node_put (codec_np);
+
+	return ret;
+}
+
+
+static int imx_ac97_standard_remove (struct platform_device *pdev) {
+	int ret;
+	struct snd_soc_card *card = platform_get_drvdata (pdev);
+
+	ret = snd_soc_unregister_card (card);
+
+	return ret;
+}
+
+
+static const struct of_device_id imx_ac97_standard_audio_match[] = {
+	{ .compatible = "fsl,imx-ac97_standard-audio", },
+	{}
+};
+
+
+MODULE_DEVICE_TABLE(of, imx_ac97_standard_audio_match);
+
+
+static struct platform_driver imx_ac97_standard_driver = {
+	.driver = {
+		.name           = DRV_NAME,
+		.owner          = THIS_MODULE,
+		.of_match_table = imx_ac97_standard_audio_match,
+	},
+	.probe  = imx_ac97_standard_probe,
+	.remove = imx_ac97_standard_remove,
+};
+module_platform_driver(imx_ac97_standard_driver);
+
+
+MODULE_AUTHOR("Seco <info@seco.it>");
+MODULE_DESCRIPTION(DRV_NAME ": Freescale i.MX standard AC97 ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-ac97_standard");