diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm-var-dart.dts b/arch/arm64/boot/dts/freescale/fsl-imx8mm-var-dart.dts
index f206989..ab0e267 100644
--- a/arch/arm64/boot/dts/freescale/fsl-imx8mm-var-dart.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-var-dart.dts
@@ -22,7 +22,7 @@
 	compatible = "variscite,dart-mx8mm", "fsl,imx8mm";
 
 	chosen {
-		bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200";
+		bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200,isolcpus=2,3";
 		stdout-path = &uart1;
 	};
 
@@ -111,25 +111,67 @@
 			"IN1L", "Mic Jack",
 			"Playback", "CPU-Playback",
 			"CPU-Capture", "Capture";
-		status = "okay";
+		status = "disabled";
 	};
 
-	backlight: backlight {
-		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 1000000 0>;
-		brightness-levels = < 0  1  2  3  4  5  6  7  8  9
-				     10 11 12 13 14 15 16 17 18 19
-				     20 21 22 23 24 25 26 27 28 29
-				     30 31 32 33 34 35 36 37 38 39
-				     40 41 42 43 44 45 46 47 48 49
-				     50 51 52 53 54 55 56 57 58 59
-				     60 61 62 63 64 65 66 67 68 69
-				     70 71 72 73 74 75 76 77 78 79
-				     80 81 82 83 84 85 86 87 88 89
-				     90 91 92 93 94 95 96 97 98 99
-				    100>;
-		default-brightness-level = <80>;
+	/*sound {
+                compatible = "fsl,imx-audio-tlv320aic3x";
+                model = "tlv320-audio-U";
+                ssi-controller = <&sai2>;
+                cpu-dai = <&sai2>;
+                audio-codec = <&codec>;
+                mux-int-port = <2>;
+                mux-ext-port = <5>;
+                audio-routing =
+                    "LINE1L", "Mic Jack",
+                    "Headphone Jack", "HPLOUT",
+                    "Headphone Jack", "HPROUT",
+                    "Line Out Jack", "LLOUT",
+                    "Line Out Jack", "RLOUT",
+                    "Mic Jack", "Mic Bias";
+		status = "okay";
+        };*/
+
+	/*sound-tlv320aic31xx {
+		compatible = "ti,tlv320aic31xx";
+		audio-cpu = <&sai2>;
+		audio-codec = <&tlv320aic31xx>;
+		audio-routing =
+			"Headphone Jack", "HPOUTL",
+			"Headphone Jack", "HPOUTR",
+			"IN2L", "Line In Jack",
+			"IN2R", "Line In Jack",
+			"IN1L", "Mic Jack",
+			"Playback", "CPU-Playback",
+			"CPU-Capture", "Capture";
+		status = "okay";
+	};*/
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "tdm-audio";
+        	simple-audio-card,format = "tdm";
+		simple-audio-card,routing =
+				"Headphone Jack", "HPOUTL",
+				"Headphone Jack", "HPCOMR",
+				"IN2L", "Line In Jack",
+				"IN2R", "Line In Jack",
+				"IN1L", "Mic Jack",
+				"Playback", "CPU-Playback",
+				"CPU-Capture", "Capture";
 		status = "okay";
+		
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+			dai-tdm-slot-num = <16>;
+			dai-tdm-slot-width = <16>;
+		};
+		
+		simple-audio-card,codec {
+			audio-codec = <&codec>;
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			clock-names = "bclk";
+		};
 	};
 
 	gpio-keys {
@@ -154,12 +196,6 @@
 			gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;
 			linux,code = <KEY_HOME>;
 		};
-
-		back {
-			label = "Back";
-			gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_BACK>;
-		};
 	};
 
 	leds {
@@ -189,7 +225,6 @@
 		pinctrl_csi1: csi1grp {
 			fsl,pins = <
 				MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8		0x19
-				MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28		0x19
 			>;
 		};
 
@@ -277,6 +312,18 @@
 			>;
 		};
 
+		pinctrl_sai2: sai2grp {
+			fsl,pins = <
+				MX8MM_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC		0xd6
+				MX8MM_IOMUXC_SAI2_RXC_SAI2_RX_BCLK		0xd6
+				MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0		0xd6
+				MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC		0xd6
+				MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK		0xd6
+				MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0		0xd6
+				MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK		0xd6
+			>;
+		};
+
 		pinctrl_pdm: pdmgrp {
 			fsl,pins = <
 				MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK		0xd6
@@ -310,21 +357,7 @@
 			>;
 		};
 
-		pinctrl_uart3: uart3grp {
-			fsl,pins = <
-				MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX		0x140
-				MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX		0x140
-			>;
-		};
 
-		pinctrl_uart4: uart4grp {
-			fsl,pins = <
-				MX8MM_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX		0x140
-				MX8MM_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX		0x140
-				MX8MM_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B		0x140
-				MX8MM_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B	0x140
-			>;
-		};
 
 		pinctrl_usdhc1: usdhc1grp {
 			fsl,pins = <
@@ -484,12 +517,6 @@
 			>;
 		};
 
-		pinctrl_pwm1: pwm1grp {
-			fsl,pins = <
-				MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT		0x06
-			>;
-		};
-
 		pinctrl_captouch: captouchgrp {
 			fsl,pins = <
 				MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5		0x16
@@ -499,11 +526,19 @@
 
 		pinctrl_ecspi1: ecspi1grp {
 			fsl,pins = <
-				MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK		0x13
-				MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI		0x13
-				MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO		0x13
-				MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9		0x13
-				MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12		0x13
+				MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK		0x10
+				MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI		0x10
+				MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO		0x10
+				MX8MM_IOMUXC_ECSPI1_SS0_ECSPI1_SS0		0x10
+			>;
+		};
+
+		pinctrl_ecspi2: ecspi2grp {
+			fsl,pins = <
+				MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK		0x10
+				MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI		0x10
+				MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO		0x10
+				MX8MM_IOMUXC_ECSPI2_SS0_ECSPI2_SS0		0x10
 			>;
 		};
 
@@ -698,7 +733,7 @@
 		enable-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_lvds>;
-		status = "okay";
+		status = "disabled";
 
 		display-timings {
 			lvds {
@@ -734,7 +769,7 @@
 
 	/* Capacitive touch controller */
 	ft5x06_ts: ft5x06_ts@38 {
-		status = "okay";
+		status = "disabled";
 		compatible = "edt,edt-ft5x06";
 		reg = <0x38>;
 		reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
@@ -749,7 +784,7 @@
 	};
 
 	ov5640_mipi1: ov5640_mipi1@3c {
-		status = "okay";
+		status = "disabled";
 		compatible = "ovti,ov5640_mipi";
 		reg = <0x3c>;
 		pinctrl-names = "default";
@@ -779,7 +814,7 @@
 
 	/* DS1337 RTC module */
 	rtc@0x68 {
-		status = "okay";
+		status = "disabled";
 		compatible = "dallas,ds1337";
 		reg = <0x68>;
 		pinctrl-names = "default";
@@ -806,7 +841,7 @@
 		AVDD-supply = <&ldo5_reg>;
 		CPVDD-supply = <&ldo5_reg>;
 		MICVDD-supply = <&ldo5_reg>;
-		status = "okay";
+		status = "disabled";
 		gpio-cfg = <
 			0x0018 /* GPIO1 => DMIC_CLK */
 			0xffff /* GPIO2 => don't touch */
@@ -814,6 +849,34 @@
 			0xffff /* GPIO4 => don't touch */
 		>;
 	};
+
+	codec: tlv320aic3x@18 {
+                /*   ai3x-micbias-vg = <2>; */
+                compatible = "ti,tlv320aic3104";
+                reg = <0x18>;
+                /*	gpio-reset = <&gpio5 0 GPIO_ACTIVE_LOW>; */
+		#sound-dai-cells = <0>;
+               clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+		clock-names = "bclk";
+		AVDD-supply = <&reg_audio>;
+		IOVDD-supply = <&reg_audio>;
+		DRVDD-supply = <&reg_audio>;
+		DVDD-supply = <&ldo5_reg>;
+               status = "okay";
+        };
+
+	/*tlv320aic31xx: codec@18 {
+		compatible = "ti,tlv320aic31xx";
+		reg = <0x18>;
+		clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+		clock-names = "mclk";
+		AVDD-supply = <&reg_audio>;
+		IOVDD-supply = <&reg_audio>;
+		DRVDD-supply = <&reg_audio>;
+		DVDD-supply = <&ldo5_reg>;
+		status = "okay";
+	};*/
+	
 };
 
 &i2c4 {
@@ -836,7 +899,7 @@
 &mipi_csi_1 {
 	#address-cells = <1>;
 	#size-cells = <0>;
-	status = "okay";
+	status = "disabled";
 	port {
 		mipi1_sensor_ep: endpoint1 {
 			remote-endpoint = <&ov5640_mipi1_ep>;
@@ -856,6 +919,29 @@
 	status = "okay";
 };
 
+&sai2 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_sai2>;
+	
+	assigned-clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+	assigned-clock-parents = <&clk IMX8MM_CLK_EXT3>;
+   	assigned-clock-rates = <4096000>;
+        /* assigned-clock-rates = <0>, <4096000>; tlv320aic3104 */
+        status = "okay";
+};
+
+/*&sai2 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+	assigned-clocks = <&clk IMX8MM_CLK_SAI2_SRC>,
+			<&clk IMX8MM_CLK_SAI2_DIV>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <0>, <1536000>;
+	status = "okay";
+	fsl,sai-asynchronous;
+};*/
+
 &sai3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sai3>;
@@ -863,7 +949,7 @@
 			<&clk IMX8MM_CLK_SAI3_DIV>;
 	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
 	assigned-clock-rates = <0>, <1536000>;
-	status = "okay";
+	status = "disabled";
 };
 
 &spdif1 {
@@ -931,35 +1017,21 @@
 	status = "okay";
 };
 
-/* Header */
-&uart3 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart3>;
-	status = "okay";
-};
 
 /* BT */
-&uart4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart4>;
-	assigned-clocks = <&clk IMX8MM_CLK_UART4_SRC>;
-	assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
-	uart-has-rtscts;
-	status = "okay";
-};
 
 &usbotg1 {
 	dr_mode = "otg";
 	picophy,pre-emp-curr-control = <3>;
 	picophy,dc-vol-level-adjust = <7>;
-	status = "okay";
+	status = "disabled";
 };
 
 &usbotg2 {
 	dr_mode = "host";
 	picophy,pre-emp-curr-control = <3>;
 	picophy,dc-vol-level-adjust = <7>;
-	status = "okay";
+	status = "disabled";
 };
 
 /* WIFI */
@@ -970,7 +1042,7 @@
 	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
 	bus-width = <4>;
 	vmmc-supply = <&reg_wifi_en>;
-	status = "okay";
+	status = "disabled";
 };
 
 /* SD */
@@ -1008,7 +1080,7 @@
 };
 
 &gpu {
-	status = "okay";
+	status = "disabled";
 };
 
 &vpu_g1 {
@@ -1033,7 +1105,7 @@
 };
 
 &lcdif {
-	status = "okay";
+	status = "disabled";
 };
 
 &mipi_dsi {
@@ -1046,58 +1118,45 @@
 	};
 };
 
-&pwm1 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pwm1>;
-};
-
 &ecspi1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi1>;
-	cs-gpios = <&gpio5  9 GPIO_ACTIVE_HIGH>,
-		   <&gpio1 12 GPIO_ACTIVE_HIGH>;
-	fsl,spi-num-chipselects = <2>;
+	fsl,spi-num-chipselects = <1>;
 	/delete-property/ dmas;
 	/delete-property/ dma-names;
 	status = "okay";
 
-	/* Resistive touch controller */
-	ads7846@0 {
+	spidev@0x00 {
+		compatible = "spidev";
+		spi-max-frequency = <20000000>;
 		reg = <0>;
-		compatible = "ti,ads7846";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_restouch>;
-		interrupt-parent = <&gpio1>;
-		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
-		spi-max-frequency = <1500000>;
-		pendown-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-		ti,x-min = /bits/ 16 <125>;
-		ti,x-max = /bits/ 16 <4008>;
-		ti,y-min = /bits/ 16 <282>;
-		ti,y-max = /bits/ 16 <3864>;
-		ti,x-plate-ohms = /bits/ 16 <180>;
-		ti,pressure-max = /bits/ 16 <255>;
-		ti,debounce-max = /bits/ 16 <10>;
-		ti,debounce-tol = /bits/ 16 <3>;
-		ti,debounce-rep = /bits/ 16 <1>;
-		ti,settle-delay-usec = /bits/ 16 <150>;
-		ti,keep-vref-on;
-		wakeup-source;
-		status = "disabled";
+		status = "okay";
+                spi-cs-low;
+		spi-cpol = <0>;
+		spi-cpha = <0>;
 	};
+};
 
-	can0: can@1 {
-		compatible = "microchip,mcp2517fd";
-		reg = <1>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_can>;
-		clocks = <&can0_osc>;
-		interrupt-parent = <&gpio1>;
-		interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+&ecspi2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	fsl,spi-num-chipselects = <1>;
+	cs-gpios = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+	status = "okay";
+	spidev@0x00 {
+		compatible = "spidev";
 		spi-max-frequency = <20000000>;
+		spi-cs-low;
+		spi-cpol = <0>;
+		spi-cpha = <0>;
+		reg = <0>;
 		status = "okay";
-	};
+
+      };
 };
 
 &flexspi {
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi
index d9c4622..143cc0f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi
@@ -179,7 +179,7 @@
 			compatible = "fixed-clock";
 			reg = <5>;
 			#clock-cells = <0>;
-			clock-frequency = <133000000>;
+			clock-frequency = <4096000>;
 			clock-output-names = "clk_ext3";
 		};
 
@@ -190,6 +190,7 @@
 			clock-frequency= <133000000>;
 			clock-output-names = "clk_ext4";
 		};
+		
 	};
 
 	power-domains {
diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq-var-dart-common.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq-var-dart-common.dtsi
index f2ba900..674fecd 100644
--- a/arch/arm64/boot/dts/freescale/fsl-imx8mq-var-dart-common.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq-var-dart-common.dtsi
@@ -21,7 +21,7 @@
 	compatible = "variscite,imx8m-dart", "fsl,imx8mq";
 
 	chosen {
-		bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200";
+		bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200,isolcpus=2,3";
 		stdout-path = &uart1;
 	};
 
@@ -142,12 +142,6 @@
 			gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;
 			linux,code = <KEY_HOME>;
 		};
-
-		back {
-			label = "Back";
-			gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_BACK>;
-		};
 	};
 
 	leds {
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 5709bfc..001cde8 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -980,6 +980,9 @@ static void __init imx8mm_clocks_init(struct device_node *ccm_node)
 	clk_set_parent(clks[IMX8MM_CLK_DISP_APB_SRC], clks[IMX8MM_SYS_PLL1_800M]);
 	clk_set_rate(clks[IMX8MM_CLK_DISP_APB_PRE_DIV], 200000000);
 
+	pr_info("i.MX*MM clock driver before setting CLK_EXT3");
+	clk_set_parent(clks[IMX8MM_CLK_SAI2_ROOT], clks[IMX8MM_CLK_EXT3]);
+	pr_info("i.MX*MM clock driver after setting CLK_EXT3");
 	imx_register_uart_clocks(uart_clks);
 
 	pr_info("i.MX8MM clock driver init done\n");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f378dc3..b89c586 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -936,10 +936,21 @@ config SND_SOC_TLV320AIC26
 	tristate
 	depends on SPI
 
-config SND_SOC_TLV320AIC31XX
-	tristate "Texas Instruments TLV320AIC31xx CODECs"
-	depends on I2C
-	select REGMAP_I2C
+config SND_SOC_IMX_TLV320AIC31XX
+        tristate "Texas Instruments TLV320AIC31xx CODECs"
+        depends on OF && I2C
+        select SND_SOC_TLV320AIC31XX
+        select SND_SOC_IMX_PCM_DMA
+        select SND_SOC_IMX_AUDMUX
+        select SND_SOC_FSL_SSI
+        help
+          SoC audio for i.MX8 boards with codec TLV320AIC31xx attached over
+          SSI interface.
+          
+#config SND_SOC_TLV320AIC31XX
+#	tristate "Texas Instruments TLV320AIC31xx CODECs"
+#	depends on I2C
+#	select REGMAP_I2C
 
 config SND_SOC_TLV320AIC32X4
 	tristate
@@ -954,9 +965,22 @@ config SND_SOC_TLV320AIC32X4_SPI
 	depends on SPI_MASTER
 	select SND_SOC_TLV320AIC32X4
 
-config SND_SOC_TLV320AIC3X
-	tristate "Texas Instruments TLV320AIC3x CODECs"
-	depends on I2C
+config SND_SOC_IMX_TLV320AIC3X
+        tristate "Texas Instruments TLV320AIC3x CODECs"
+        depends on OF && I2C
+        select SND_SOC_TLV320AIC3X
+        select SND_SOC_IMX_PCM_DMA
+        select SND_SOC_IMX_AUDMUX
+        select SND_SOC_FSL_SSI
+        help
+          SoC audio for i.MX8 boards with codec TLV320AIC3x attached over
+          SSI interface.
+          Say Y if you want to add support for SoC audio on phyFLEX-i.MX8
+          boards.
+
+#config SND_SOC_TLV320AIC3X
+#	tristate "Texas Instruments TLV320AIC3x CODECs"
+#	depends on I2C
 
 config SND_SOC_TLV320DAC33
 	tristate
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 897f23d..9947eb0 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -68,6 +68,8 @@ obj-$(CONFIG_SND_SOC_IMX_HDMI_DMA) += imx-hdmi-dma.o hdmi_pcm.o
 
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
+#snd-soc-imx-tlv320aic31xx-objs := imx-tlv320aic31xx.o
+snd-soc-imx-tlv320aic3x-objs := imx-tlv320aic3x.o
 snd-soc-phycore-ac97-objs := phycore-ac97.o
 snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
@@ -97,6 +99,8 @@ snd-soc-imx-micfil-objs := imx-micfil.o
 snd-soc-imx-dsp-objs := imx-dsp.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
+#obj-$(CONFIG_SND_SOC_IMX_TLV320AIC31XX) += snd-soc-imx-tlv320aic31xx.o
+obj-$(CONFIG_SND_SOC_IMX_TLV320AIC3X) += snd-soc-imx-tlv320aic3x.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
 obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/fsl/imx-tlv320aic3x.c b/sound/soc/fsl/imx-tlv320aic3x.c
index e69de29..5e339d8 100644
--- a/sound/soc/fsl/imx-tlv320aic3x.c
+++ b/sound/soc/fsl/imx-tlv320aic3x.c
@@ -0,0 +1,239 @@
+/*
+ * 2014 Variscite, Ltd. All Rights Reserved.
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 2012 Variscite, Ltd. All Rights Reserved.
+ * Based on imx-wm8962.c
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+
+#include "../codecs/tlv320aic3x.h"
+#include "imx-audmux.h"
+
+#define DAI_NAME_SIZE	32
+
+struct imx_tlv320aic3x_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_tlv320aic3x_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct imx_tlv320aic3x_data *data = container_of(rtd->card,
+					struct imx_tlv320aic3x_data, card);
+	struct device *dev = rtd->card->dev;
+	int ret;
+
+	ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0,
+				     data->clk_frequency, SND_SOC_CLOCK_IN);
+	if (ret) {
+		dev_err(dev, "could not set codec driver clock params\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget imx_tlv320aic3x_dapm_widgets[] = {
+	SND_SOC_DAPM_MIC("Mic Jack", NULL),
+	SND_SOC_DAPM_LINE("Line In Jack", NULL),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
+	SND_SOC_DAPM_SPK("Line Out Jack", NULL),
+	SND_SOC_DAPM_SPK("Ext Spk", NULL),
+};
+
+static int imx_tlv320aic3x_audmux_config(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	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 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 missing or invalid\n");
+		return ret;
+	}
+
+	/*
+	 * The port numbering in the hardware manual starts at 1, while
+	 * the audmux API expects it starts at 0.
+	 */
+	int_port--;
+	ext_port--;
+	ret = imx_audmux_v2_configure_port(int_port,
+			IMX_AUDMUX_V2_PTCR_SYN |
+			IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
+			IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
+			IMX_AUDMUX_V2_PTCR_TFSDIR |
+			IMX_AUDMUX_V2_PTCR_TCLKDIR,
+			IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
+	if (ret) {
+		dev_err(&pdev->dev, "audmux internal port setup failed\n");
+		return ret;
+	}
+	ret = imx_audmux_v2_configure_port(ext_port,
+			IMX_AUDMUX_V2_PTCR_SYN,
+			IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
+	if (ret) {
+		dev_err(&pdev->dev, "audmux external port setup failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx_tlv320aic3x_probe(struct platform_device *pdev)
+{
+	struct device_node *cpu_np, *codec_np;
+	struct platform_device *cpu_pdev;
+	struct i2c_client *codec_dev;
+	struct imx_tlv320aic3x_data *data;
+	int ret;
+
+	cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 0);
+	codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+	if (!cpu_np || !codec_np) {
+		dev_err(&pdev->dev, "phandle missing or invalid\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	if (strstr(cpu_np->name, "ssi")) {
+		ret = imx_tlv320aic3x_audmux_config(pdev);
+		if (ret)
+			goto fail;
+	}
+
+	cpu_pdev = of_find_device_by_node(cpu_np);
+	if (!cpu_pdev) {
+		dev_err(&pdev->dev, "failed to find SSI platform device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+	codec_dev = of_find_i2c_device_by_node(codec_np);
+	if (!codec_dev) {
+		dev_err(&pdev->dev, "failed to find codec platform device\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	data->codec_clk = clk_get(&codec_dev->dev, NULL);
+	if (IS_ERR(data->codec_clk)) {
+		/* assuming clock enabled by default */
+		data->codec_clk = NULL;
+		ret = of_property_read_u32(codec_np, "clock-frequency",
+					&data->clk_frequency);
+		if (ret) {
+			dev_err(&codec_dev->dev,
+				"clock-frequency missing or invalid\n");
+			goto fail;
+		}
+	} else {
+		data->clk_frequency = clk_get_rate(data->codec_clk);
+		clk_prepare_enable(data->codec_clk);
+	}
+
+	data->dai.name = "HiFi";
+	data->dai.stream_name = "HiFi";
+	data->dai.codec_dai_name = "tlv320aic3x-hifi";
+	data->dai.codec_of_node = codec_np;
+	data->dai.cpu_of_node = cpu_np;
+	data->dai.platform_of_node = cpu_np;
+	data->dai.init = &imx_tlv320aic3x_dai_init;
+	data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+			    SND_SOC_DAIFMT_CBM_CFM;
+
+	data->card.dev = &pdev->dev;
+	ret = snd_soc_of_parse_card_name(&data->card, "model");
+	if (ret)
+		goto clk_fail;
+	ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
+	if (ret)
+		goto clk_fail;
+	data->card.num_links = 1;
+	data->card.owner = THIS_MODULE;
+	data->card.dai_link = &data->dai;
+	data->card.dapm_widgets = imx_tlv320aic3x_dapm_widgets;
+	data->card.num_dapm_widgets = ARRAY_SIZE(imx_tlv320aic3x_dapm_widgets);
+
+	ret = snd_soc_register_card(&data->card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+		goto clk_fail;
+	}
+
+	platform_set_drvdata(pdev, data);
+clk_fail:
+	clk_put(data->codec_clk);
+fail:
+	if (cpu_np)
+		of_node_put(cpu_np);
+	if (codec_np)
+		of_node_put(codec_np);
+
+	return ret;
+}
+
+static int imx_tlv320aic3x_remove(struct platform_device *pdev)
+{
+	struct imx_tlv320aic3x_data *data = platform_get_drvdata(pdev);
+
+	if (data->codec_clk) {
+		clk_disable_unprepare(data->codec_clk);
+		clk_put(data->codec_clk);
+	}
+	snd_soc_unregister_card(&data->card);
+
+	return 0;
+}
+
+static const struct of_device_id imx_tlv320aic3x_dt_ids[] = {
+	{ .compatible = "fsl,imx-audio-tlv320aic3x", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_tlv320aic3x_dt_ids);
+
+static struct platform_driver imx_tlv320aic3x_driver = {
+	.driver = {
+		.name = "imx-tlv320aic3x",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_tlv320aic3x_dt_ids,
+	},
+	.probe = imx_tlv320aic3x_probe,
+	.remove = imx_tlv320aic3x_remove,
+};
+module_platform_driver(imx_tlv320aic3x_driver);
+
+MODULE_AUTHOR("ron.d@variscite.com. Variscite Ltd.");
+MODULE_DESCRIPTION("Variscite i.MX TLV320aic3x ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-tlv320aic3x");
