[oe] [PATCH] linux-atmel: Add support for latest AT91 kernel

Ulf Samuelsson ulf.samuelsson at atmel.com
Fri Mar 12 23:03:54 UTC 2010


Add support for building AT91 2.6.30 kernel
Vanilla 2.6.30 recipe has moved on to 2.6.30.x

Add maxim.org.za patches + Atmel experimental patches.
(With the exception of the SAM9M10-EK support)
Add support for configurable NAND flash partitions
Add support for sam9m10g45-ek

The contents of the maxim & experimental patches
to the kernel has various authors.

Signed-off-by: Ulf Samuelsson <ulf.samuelsson at atmel.com>
---
 .../linux-atmel-2.6.30/at91/2.6.30-at91-exp.patch  |36510 ++++++++++++++++++++
 ...linux-2.6.30-at91-exp-002-NAND-partitions.patch |  100 +
 ...-004-NAND-001-configurable-partition-size.patch |  214 +
 ...-2.6.30-at91-exp-005-at91sam9m10g45ek_BSP.patch |   30 +
 ....30-at91-exp-006-at91sam9m10g45ek_machine.patch |   39 +
 .../linux-atmel-2.6.30/at91sam9g45ek/defconfig     | 1798 +
 recipes/linux/linux-atmel_2.6.30.bb                |   27 +
 7 files changed, 38718 insertions(+), 0 deletions(-)
 create mode 100644 recipes/linux/linux-atmel-2.6.30/at91/2.6.30-at91-exp.patch
 create mode 100644 recipes/linux/linux-atmel-2.6.30/at91/linux-2.6.30-at91-exp-002-NAND-partitions.patch
 create mode 100644 recipes/linux/linux-atmel-2.6.30/at91/linux-2.6.30-at91-exp-004-NAND-001-configurable-partition-size.patch
 create mode 100644 recipes/linux/linux-atmel-2.6.30/at91/linux-2.6.30-at91-exp-005-at91sam9m10g45ek_BSP.patch
 create mode 100644 recipes/linux/linux-atmel-2.6.30/at91/linux-2.6.30-at91-exp-006-at91sam9m10g45ek_machine.patch
 create mode 100644 recipes/linux/linux-atmel-2.6.30/at91sam9g45ek/defconfig
 create mode 100644 recipes/linux/linux-atmel_2.6.30.bb

diff --git a/recipes/linux/linux-atmel-2.6.30/at91/2.6.30-at91-exp.patch b/recipes/linux/linux-atmel-2.6.30/at91/2.6.30-at91-exp.patch
new file mode 100644
index 0000000..3fa23df
--- /dev/null
+++ b/recipes/linux/linux-atmel-2.6.30/at91/2.6.30-at91-exp.patch
@@ -0,0 +1,36510 @@
+From 460964e13607480ec141bd72fc76c5af52989175 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:17 +0000
+Subject: [PATCH] at91: dm9000 initialization update
+
+Add information in dm9000 mac/phy chip initialization:
+- irq resource details
+- platform data details
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11572 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9261ek.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
+index ef392bb..9d82c22 100644
+--- a/arch/arm/mach-at91/board-sam9261ek.c
++++ b/arch/arm/mach-at91/board-sam9261ek.c
+@@ -93,11 +93,12 @@ static struct resource dm9000_resource[] = {
+ 		.start	= AT91_PIN_PC11,
+ 		.end	= AT91_PIN_PC11,
+ 		.flags	= IORESOURCE_IRQ
++			| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
+ 	}
+ };
+ 
+ static struct dm9000_plat_data dm9000_platdata = {
+-	.flags		= DM9000_PLATF_16BITONLY,
++	.flags		= DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+ };
+ 
+ static struct platform_device dm9000_device = {
+-- 
+1.5.6.5
+
+From 7ee075f18835d4ad9a7da886b26bdf306f50c00f Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:18 +0000
+Subject: [PATCH] at91: add gpio button support for at91sam9g20ek
+
+This adds input keyboard gpio support on at91sam9g20ek board. It adds button 3
+and 4.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11573 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9g20ek.c |   52 ++++++++++++++++++++++++++++++++++
+ 1 files changed, 52 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
+index 438efbb..88c724d 100644
+--- a/arch/arm/mach-at91/board-sam9g20ek.c
++++ b/arch/arm/mach-at91/board-sam9g20ek.c
+@@ -37,6 +37,8 @@
+ 
+ #include <mach/board.h>
+ #include <mach/gpio.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
+ #include <mach/at91sam9_smc.h>
+ 
+ #include "sam9_smc.h"
+@@ -218,6 +220,54 @@ static struct gpio_led ek_leds[] = {
+ 	}
+ };
+ 
++/*
++ * GPIO Buttons
++ */
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++static struct gpio_keys_button ek_buttons[] = {
++	{
++		.gpio		= AT91_PIN_PA30,
++		.code		= BTN_3,
++		.desc		= "Button 3",
++		.active_low	= 1,
++		.wakeup		= 1,
++	},
++	{
++		.gpio		= AT91_PIN_PA31,
++		.code		= BTN_4,
++		.desc		= "Button 4",
++		.active_low	= 1,
++		.wakeup		= 1,
++	}
++};
++
++static struct gpio_keys_platform_data ek_button_data = {
++	.buttons	= ek_buttons,
++	.nbuttons	= ARRAY_SIZE(ek_buttons),
++};
++
++static struct platform_device ek_button_device = {
++	.name		= "gpio-keys",
++	.id		= -1,
++	.num_resources	= 0,
++	.dev		= {
++		.platform_data	= &ek_button_data,
++	}
++};
++
++static void __init ek_add_device_buttons(void)
++{
++	at91_set_gpio_input(AT91_PIN_PA30, 1);	/* btn3 */
++	at91_set_deglitch(AT91_PIN_PA30, 1);
++	at91_set_gpio_input(AT91_PIN_PA31, 1);	/* btn4 */
++	at91_set_deglitch(AT91_PIN_PA31, 1);
++
++	platform_device_register(&ek_button_device);
++}
++#else
++static void __init ek_add_device_buttons(void) {}
++#endif
++
+ static void __init ek_board_init(void)
+ {
+ 	/* Serial */
+@@ -238,6 +288,8 @@ static void __init ek_board_init(void)
+ 	at91_add_device_i2c(NULL, 0);
+ 	/* LEDs */
+ 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++	/* Push Buttons */
++	ek_add_device_buttons();
+ 	/* PCK0 provides MCLK to the WM8731 */
+ 	at91_set_B_periph(AT91_PIN_PC1, 0);
+ 	/* SSC (for WM8731) */
+-- 
+1.5.6.5
+
+From b6bd69b65c722f006da46d226d6fce1644f214a8 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:18 +0000
+Subject: [PATCH] at91: add gpio button and leds support for at91sam9rlek
+
+This adds input keyboard gpio support on at91sam9rlek board. It adds button 1
+and 2 (left and right click).
+It also adds gpio leds ds1, ds2 and ds3.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11574 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9rlek.c |   79 +++++++++++++++++++++++++++++++++++
+ 1 files changed, 79 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
+index d34e343..ee4137b 100644
+--- a/arch/arm/mach-at91/board-sam9rlek.c
++++ b/arch/arm/mach-at91/board-sam9rlek.c
+@@ -15,6 +15,8 @@
+ #include <linux/spi/spi.h>
+ #include <linux/fb.h>
+ #include <linux/clk.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
+ 
+ #include <video/atmel_lcdc.h>
+ 
+@@ -206,6 +208,79 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+ #endif
+ 
+ 
++/*
++ * LEDs
++ */
++static struct gpio_led ek_leds[] = {
++	{	/* "bottom" led, green, userled1 to be defined */
++		.name			= "ds1",
++		.gpio			= AT91_PIN_PD15,
++		.active_low		= 1,
++		.default_trigger	= "none",
++	},
++	{	/* "bottom" led, green, userled2 to be defined */
++		.name			= "ds2",
++		.gpio			= AT91_PIN_PD16,
++		.active_low		= 1,
++		.default_trigger	= "none",
++	},
++	{	/* "power" led, yellow */
++		.name			= "ds3",
++		.gpio			= AT91_PIN_PD14,
++		.default_trigger	= "heartbeat",
++	}
++};
++
++
++/*
++ * GPIO Buttons
++ */
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++static struct gpio_keys_button ek_buttons[] = {
++	{
++		.gpio		= AT91_PIN_PB0,
++		.code		= BTN_2,
++		.desc		= "Right Click",
++		.active_low	= 1,
++		.wakeup		= 1,
++	},
++	{
++		.gpio		= AT91_PIN_PB1,
++		.code		= BTN_1,
++		.desc		= "Left Click",
++		.active_low	= 1,
++		.wakeup		= 1,
++	}
++};
++
++static struct gpio_keys_platform_data ek_button_data = {
++	.buttons	= ek_buttons,
++	.nbuttons	= ARRAY_SIZE(ek_buttons),
++};
++
++static struct platform_device ek_button_device = {
++	.name		= "gpio-keys",
++	.id		= -1,
++	.num_resources	= 0,
++	.dev		= {
++		.platform_data	= &ek_button_data,
++	}
++};
++
++static void __init ek_add_device_buttons(void)
++{
++	at91_set_gpio_input(AT91_PIN_PB1, 1);	/* btn1 */
++	at91_set_deglitch(AT91_PIN_PB1, 1);
++	at91_set_gpio_input(AT91_PIN_PB0, 1);	/* btn2 */
++	at91_set_deglitch(AT91_PIN_PB0, 1);
++
++	platform_device_register(&ek_button_device);
++}
++#else
++static void __init ek_add_device_buttons(void) {}
++#endif
++
++
+ static void __init ek_board_init(void)
+ {
+ 	/* Serial */
+@@ -224,6 +299,10 @@ static void __init ek_board_init(void)
+ 	at91_add_device_lcdc(&ek_lcdc_data);
+ 	/* Touch Screen Controller */
+ 	at91_add_device_tsadcc();
++	/* LEDs */
++	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++	/* Push Buttons */
++	ek_add_device_buttons();
+ 	/* shutdown controller, wakeup button (5 msec low) */
+ 	at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ 				| AT91_SHDW_RTTWKEN);
+-- 
+1.5.6.5
+
+From 88178da92bd7bb5512a6b2f068fb231e928ac4a4 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:19 +0000
+Subject: [PATCH] at91: at91sam9rlek lcd interface correction
+
+Here is a little update to the at91sam9rlek lcd interface.
+This will correct the power pin of the LCD.
+It will also add precision to the struct atmel_lcdfb_info
+scructure: backlight enabling  and wiring mode
+correction: RGB wiring on the -EK board.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11575 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9rlek.c |    6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
+index ee4137b..450a7be 100644
+--- a/arch/arm/mach-at91/board-sam9rlek.c
++++ b/arch/arm/mach-at91/board-sam9rlek.c
+@@ -188,19 +188,21 @@ static struct fb_monspecs at91fb_default_monspecs = {
+ static void at91_lcdc_power_control(int on)
+ {
+ 	if (on)
+-		at91_set_gpio_value(AT91_PIN_PA30, 0);	/* power up */
++		at91_set_gpio_value(AT91_PIN_PC1, 0);	/* power up */
+ 	else
+-		at91_set_gpio_value(AT91_PIN_PA30, 1);	/* power down */
++		at91_set_gpio_value(AT91_PIN_PC1, 1);	/* power down */
+ }
+ 
+ /* Driver datas */
+ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++	.lcdcon_is_backlight            = true,
+ 	.default_bpp			= 16,
+ 	.default_dmacon			= ATMEL_LCDC_DMAEN,
+ 	.default_lcdcon2		= AT91SAM9RL_DEFAULT_LCDCON2,
+ 	.default_monspecs		= &at91fb_default_monspecs,
+ 	.atmel_lcdfb_power_control	= at91_lcdc_power_control,
+ 	.guard_time			= 1,
++	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
+ };
+ 
+ #else
+-- 
+1.5.6.5
+
+From 6581ef8f58379ff0d02afe8b0359ecf91b116f7d Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:20 +0000
+Subject: [PATCH] avr32: add two new at91 to cpu.h definition
+
+Somme common drivers will need those at91 cpu_is_xxx() definitions. As
+at91sam9g10 and at91sam9g45 are on the way to linus' tree, here is the patch
+that adds those chips to cpu.h in AVR32 architecture.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11576 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/avr32/mach-at32ap/include/mach/cpu.h |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h
+index 44d0bfa..c253e9b 100644
+--- a/arch/avr32/mach-at32ap/include/mach/cpu.h
++++ b/arch/avr32/mach-at32ap/include/mach/cpu.h
+@@ -31,5 +31,7 @@
+ #define cpu_is_at91sam9263()	(0)
+ #define cpu_is_at91sam9rl()	(0)
+ #define cpu_is_at91cap9()	(0)
++#define cpu_is_at91sam9g10()	(0)
++#define cpu_is_at91sam9g45()	(0)
+ 
+ #endif /* __ASM_ARCH_CPU_H */
+-- 
+1.5.6.5
+
+From 39cdfe9f86b4ff30c151de1f55afc1f5a6aaf63c Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:20 +0000
+Subject: [PATCH] 5438/1: AT91: manage clock by functionality instead of CPUs
+
+In clock.c file the clock management is grouped by cpu with cpu_is_xxx()
+function. This lead to some kind of difficulties to read this file and
+maintainability issues as the number of AT91 cpus & PLLs/clocks is growing.
+
+In this patch, I try to group clock functionality together and match cpus with
+this functionality set.
+An update to at91_pmc.h is needed to cover some new PMC possibilities (and
+some update in comments).
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <avictor.za at gmail.com>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11577 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/clock.c                 |  152 ++++++++++++++++++++-------
+ arch/arm/mach-at91/include/mach/at91_pmc.h |   26 ++++-
+ 2 files changed, 132 insertions(+), 46 deletions(-)
+
+diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
+index 611e2a7..c09148c 100644
+--- a/arch/arm/mach-at91/clock.c
++++ b/arch/arm/mach-at91/clock.c
+@@ -44,6 +44,25 @@
+ #define clk_is_sys(x)		((x)->type & CLK_TYPE_SYSTEM)
+ 
+ 
++/*
++ * Chips have some kind of clocks : group them by functionality
++ */
++#define cpu_has_utmi()		(  cpu_is_at91cap9() \
++				|| cpu_is_at91sam9rl())
++
++#define cpu_has_800M_plla()	(cpu_is_at91sam9g20())
++
++#define cpu_has_pllb()		(!cpu_is_at91sam9rl())
++
++#define cpu_has_upll()		(0)
++
++/* USB host HS & FS */
++#define cpu_has_uhp()		(!cpu_is_at91sam9rl())
++
++/* USB device FS only */
++#define cpu_has_udpfs()		(!cpu_is_at91sam9rl())
++
++
+ static LIST_HEAD(clocks);
+ static DEFINE_SPINLOCK(clk_lock);
+ 
+@@ -141,7 +160,7 @@ static struct clk utmi_clk = {
+ };
+ static struct clk uhpck = {
+ 	.name		= "uhpck",
+-	.parent		= &pllb,
++	/*.parent		= ... we choose parent at runtime */
+ 	.mode		= pmc_sys_mode,
+ };
+ 
+@@ -174,7 +193,11 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
+ 		case AT91_PMC_CSS_PLLA:
+ 			return &plla;
+ 		case AT91_PMC_CSS_PLLB:
+-			return &pllb;
++			if (cpu_has_upll())
++				/* CSS_PLLB == CSS_UPLL */
++				return &utmi_clk;
++			else if (cpu_has_pllb())
++				return &pllb;
+ 	}
+ 
+ 	return NULL;
+@@ -340,7 +363,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
+ 			u32	pckr;
+ 
+ 			pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+-			pckr &= AT91_PMC_CSS_PLLB;	/* clock selection */
++			pckr &= AT91_PMC_CSS;	/* clock selection */
+ 			pckr |= prescale << 2;
+ 			at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
+ 			clk->rate_hz = actual;
+@@ -379,7 +402,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
+ }
+ EXPORT_SYMBOL(clk_set_parent);
+ 
+-/* establish PCK0..PCK4 parentage and rate */
++/* establish PCK0..PCKN parentage and rate */
+ static void __init init_programmable_clock(struct clk *clk)
+ {
+ 	struct clk	*parent;
+@@ -407,11 +430,13 @@ static int at91_clk_show(struct seq_file *s, void *unused)
+ 	seq_printf(s, "MOR  = %8x\n", at91_sys_read(AT91_CKGR_MOR));
+ 	seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
+ 	seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
+-	if (!cpu_is_at91sam9rl())
++	if (cpu_has_pllb())
+ 		seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
+-	if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
++	if (cpu_has_utmi())
+ 		seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR));
+ 	seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
++	if (cpu_has_upll())
++		seq_printf(s, "USB  = %8x\n", at91_sys_read(AT91_PMC_USB));
+ 	seq_printf(s, "SR   = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
+ 
+ 	seq_printf(s, "\n");
+@@ -572,16 +597,60 @@ static struct clk *const standard_pmc_clocks[] __initdata = {
+ 	&clk32k,
+ 	&main_clk,
+ 	&plla,
+-	&pllb,
+-
+-	/* PLLB children (USB) */
+-	&udpck,
+-	&uhpck,
+ 
+ 	/* MCK */
+ 	&mck
+ };
+ 
++/* PLLB generated USB full speed clock init */
++static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
++{
++	/*
++	 * USB clock init:  choose 48 MHz PLLB value,
++	 * disable 48MHz clock during usb peripheral suspend.
++	 *
++	 * REVISIT:  assumes MCK doesn't derive from PLLB!
++	 */
++	uhpck.parent = &pllb;
++
++	at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
++	pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
++	if (cpu_is_at91rm9200()) {
++		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
++		udpck.pmc_mask = AT91RM9200_PMC_UDP;
++		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
++	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at572d940hf()) {
++		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
++		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
++	} else if (cpu_is_at91cap9()) {
++		uhpck.pmc_mask = AT91CAP9_PMC_UHP;
++	}
++	at91_sys_write(AT91_CKGR_PLLBR, 0);
++
++	udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
++	uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
++}
++
++/* UPLL generated USB full speed clock init */
++static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
++{
++	/*
++	 * USB clock init: choose 480 MHz from UPLL,
++	 */
++	unsigned int usbr = AT91_PMC_USBS_UPLL;
++
++	/* Setup divider by 10 to reach 48 MHz */
++	usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV;
++
++	at91_sys_write(AT91_PMC_USB, usbr);
++
++	/* Now set uhpck values */
++	uhpck.parent = &utmi_clk;
++	uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
++	uhpck.rate_hz = utmi_clk.parent->rate_hz;
++	uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
++}
++
+ int __init at91_clock_init(unsigned long main_clock)
+ {
+ 	unsigned tmp, freq, mckr;
+@@ -603,43 +672,36 @@ int __init at91_clock_init(unsigned long main_clock)
+ 
+ 	/* report if PLLA is more than mildly overclocked */
+ 	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
+-	if ((!cpu_is_at91sam9g20() && plla.rate_hz > 209000000)
+-	   || (cpu_is_at91sam9g20() && plla.rate_hz > 800000000))
++	if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000)
++	   || (cpu_has_800M_plla() && plla.rate_hz > 800000000))
+ 		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
+ 
+-	/*
+-	 * USB clock init:  choose 48 MHz PLLB value,
+-	 * disable 48MHz clock during usb peripheral suspend.
+-	 *
+-	 * REVISIT:  assumes MCK doesn't derive from PLLB!
+-	 */
+-	at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
+-	pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
+-	if (cpu_is_at91rm9200()) {
+-		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
+-		udpck.pmc_mask = AT91RM9200_PMC_UDP;
+-		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
+-	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at572d940hf()) {
+-		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+-		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
+-	} else if (cpu_is_at91cap9()) {
+-		uhpck.pmc_mask = AT91CAP9_PMC_UHP;
++	if (cpu_has_upll() && !cpu_has_pllb()) {
++		/* setup UTMI clock as the fourth primary clock
++		 * (instead of pllb) */
++		utmi_clk.type |= CLK_TYPE_PRIMARY;
++		utmi_clk.id = 3;
+ 	}
+-	at91_sys_write(AT91_CKGR_PLLBR, 0);
+ 
+-	udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+-	uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+ 
+ 	/*
+ 	 * USB HS clock init
+ 	 */
+-	if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) {
++	if (cpu_has_utmi())
+ 		/*
+ 		 * multiplier is hard-wired to 40
+ 		 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
+ 		 */
+ 		utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+-	}
++
++	/*
++	 * USB FS clock init
++	 */
++	if (cpu_has_pllb())
++		at91_pllb_usbfs_clock_init(main_clock);
++	if (cpu_has_upll())
++		/* assumes that we choose UPLL for USB and not PLLA */
++		at91_upll_usbfs_clock_init(main_clock);
+ 
+ 	/*
+ 	 * MCK and CPU derive from one of those primary clocks.
+@@ -649,21 +711,31 @@ int __init at91_clock_init(unsigned long main_clock)
+ 	mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
+ 	freq = mck.parent->rate_hz;
+ 	freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2));				/* prescale */
+-	if (cpu_is_at91rm9200())
++	if (cpu_is_at91rm9200()) {
+ 		mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
+-	else if (cpu_is_at91sam9g20()) {
++	} else if (cpu_is_at91sam9g20()) {
+ 		mck.rate_hz = (mckr & AT91_PMC_MDIV) ?
+ 			freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq;	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
+ 		if (mckr & AT91_PMC_PDIV)
+ 			freq /= 2;		/* processor clock division */
+-	} else
+-		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
++	} else {
++		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      /* mdiv */
++	}
+ 
+ 	/* Register the PMC's standard clocks */
+ 	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
+ 		list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
+ 
+-	if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
++	if (cpu_has_pllb())
++		list_add_tail(&pllb.node, &clocks);
++
++	if (cpu_has_uhp())
++		list_add_tail(&uhpck.node, &clocks);
++
++	if (cpu_has_udpfs())
++		list_add_tail(&udpck.node, &clocks);
++
++	if (cpu_has_utmi())
+ 		list_add_tail(&utmi_clk.node, &clocks);
+ 
+ 	/* MCK and CPU clock are "always on" */
+diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
+index e803376..ba429f7 100644
+--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
++++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
+@@ -23,7 +23,7 @@
+ #define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
+ #define		AT91RM9200_PMC_UDP	(1 <<  1)		/* USB Devcice Port Clock [AT91RM9200 only] */
+ #define		AT91RM9200_PMC_MCKUDP	(1 <<  2)		/* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
+-#define		AT91CAP9_PMC_DDR	(1 <<  2)		/* DDR Clock [AT91CAP9 revC only] */
++#define		AT91CAP9_PMC_DDR	(1 <<  2)		/* DDR Clock [CAP9 revC & some SAM9 only] */
+ #define		AT91RM9200_PMC_UHP	(1 <<  4)		/* USB Host Port Clock [AT91RM9200 only] */
+ #define		AT91SAM926x_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91SAM926x only] */
+ #define		AT91CAP9_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91CAP9 only] */
+@@ -40,11 +40,11 @@
+ #define	AT91_PMC_PCDR		(AT91_PMC + 0x14)	/* Peripheral Clock Disable Register */
+ #define	AT91_PMC_PCSR		(AT91_PMC + 0x18)	/* Peripheral Clock Status Register */
+ 
+-#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [SAM9RL, CAP9] */
++#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [some SAM9, CAP9] */
+ #define		AT91_PMC_UPLLEN		(1   << 16)		/* UTMI PLL Enable */
+ #define		AT91_PMC_UPLLCOUNT	(0xf << 20)		/* UTMI PLL Start-up Time */
+ #define		AT91_PMC_BIASEN		(1   << 24)		/* UTMI BIAS Enable */
+-#define		AT91_PMC_BIASCOUNT	(0xf << 28)		/* UTMI PLL Start-up Time */
++#define		AT91_PMC_BIASCOUNT	(0xf << 28)		/* UTMI BIAS Start-up Time */
+ 
+ #define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register [not on SAM9RL] */
+ #define		AT91_PMC_MOSCEN		(1    << 0)		/* Main Oscillator Enable */
+@@ -73,6 +73,7 @@
+ #define			AT91_PMC_CSS_MAIN		(1 << 0)
+ #define			AT91_PMC_CSS_PLLA		(2 << 0)
+ #define			AT91_PMC_CSS_PLLB		(3 << 0)
++#define			AT91_PMC_CSS_UPLL		(3 << 0)	/* [some SAM9 only] */
+ #define		AT91_PMC_PRES		(7 <<  2)		/* Master Clock Prescaler */
+ #define			AT91_PMC_PRES_1			(0 << 2)
+ #define			AT91_PMC_PRES_2			(1 << 2)
+@@ -89,12 +90,25 @@
+ #define			AT91SAM9_PMC_MDIV_1		(0 << 8)	/* [SAM9,CAP9 only] */
+ #define			AT91SAM9_PMC_MDIV_2		(1 << 8)
+ #define			AT91SAM9_PMC_MDIV_4		(2 << 8)
+-#define			AT91SAM9_PMC_MDIV_6		(3 << 8)
++#define			AT91SAM9_PMC_MDIV_6		(3 << 8)	/* [some SAM9 only] */
++#define			AT91SAM9_PMC_MDIV_3		(3 << 8)	/* [some SAM9 only] */
+ #define		AT91_PMC_PDIV		(1 << 12)		/* Processor Clock Division [some SAM9 only] */
+ #define			AT91_PMC_PDIV_1			(0 << 12)
+ #define			AT91_PMC_PDIV_2			(1 << 12)
++#define		AT91_PMC_PLLADIV2	(1 << 12)		/* PLLA divisor by 2 [some SAM9 only] */
++#define			AT91_PMC_PLLADIV2_OFF		(0 << 12)
++#define			AT91_PMC_PLLADIV2_ON		(1 << 12)
+ 
+-#define	AT91_PMC_PCKR(n)	(AT91_PMC + 0x40 + ((n) * 4))	/* Programmable Clock 0-4 Registers */
++#define	AT91_PMC_USB		(AT91_PMC + 0x38)	/* USB Clock Register [some SAM9 only] */
++#define		AT91_PMC_USBS		(0x1 <<  0)		/* USB OHCI Input clock selection */
++#define			AT91_PMC_USBS_PLLA		(0 << 0)
++#define			AT91_PMC_USBS_UPLL		(1 << 0)
++#define		AT91_PMC_OHCIUSBDIV	(0xF <<  8)		/* Divider for USB OHCI Clock */
++
++#define	AT91_PMC_PCKR(n)	(AT91_PMC + 0x40 + ((n) * 4))	/* Programmable Clock 0-N Registers */
++#define		AT91_PMC_CSSMCK		(0x1 <<  8)		/* CSS or Master Clock Selection */
++#define			AT91_PMC_CSSMCK_CSS		(0 << 8)
++#define			AT91_PMC_CSSMCK_MCK		(1 << 8)
+ 
+ #define	AT91_PMC_IER		(AT91_PMC + 0x60)	/* Interrupt Enable Register */
+ #define	AT91_PMC_IDR		(AT91_PMC + 0x64)	/* Interrupt Disable Register */
+@@ -103,7 +117,7 @@
+ #define		AT91_PMC_LOCKA		(1 <<  1)		/* PLLA Lock */
+ #define		AT91_PMC_LOCKB		(1 <<  2)		/* PLLB Lock */
+ #define		AT91_PMC_MCKRDY		(1 <<  3)		/* Master Clock */
+-#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [AT91CAP9 only] */
++#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [some SAM9, AT91CAP9 only] */
+ #define		AT91_PMC_OSCSEL		(1 <<  7)		/* Slow Clock Oscillator [AT91CAP9 revC only] */
+ #define		AT91_PMC_PCK0RDY	(1 <<  8)		/* Programmable Clock 0 */
+ #define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
+-- 
+1.5.6.5
+
+From 4651aaf6d53d6e17b323e6ccc929f34bb50aedf9 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:21 +0000
+Subject: [PATCH] atmel_serial: fix hang in set_termios when crtscts is enabled
+
+After enabling hardware flow control, any subsequent termios call may hang
+waiting for the transmitter to drain.  This appears to be caused by a
+busy-loop in set_termios() waiting for the transmitter to become empty,
+which may take a very long time (or hang indefinitely) if the device at
+the other end is blocking us.
+
+A quick look through the tty and serial_core code indicates that any
+necessary flushing (which is optional) has already been done at this
+point, so there's no need for the driver to flush the transmitter on its
+own.
+
+Fix it by removing the busy-loop altogether.
+
+Tested-by: Eirik Aanonsen <eaa at wprmedical.com>
+Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen at atmel.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Alan Cox <alan at linux.intel.com>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+(cherry picked from commit 0ccad87012c6c2e7446e4dc0f0894cf182a5270a)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11578 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/serial/atmel_serial.c |    8 +++++---
+ 1 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
+index b3497d7..338b15c 100644
+--- a/drivers/serial/atmel_serial.c
++++ b/drivers/serial/atmel_serial.c
+@@ -1104,11 +1104,13 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
+ 	/* update the per-port timeout */
+ 	uart_update_timeout(port, termios->c_cflag, baud);
+ 
+-	/* save/disable interrupts and drain transmitter */
++	/*
++	 * save/disable interrupts. The tty layer will ensure that the
++	 * transmitter is empty if requested by the caller, so there's
++	 * no need to wait for it here.
++	 */
+ 	imr = UART_GET_IMR(port);
+ 	UART_PUT_IDR(port, -1);
+-	while (!(UART_GET_CSR(port) & ATMEL_US_TXEMPTY))
+-		cpu_relax();
+ 
+ 	/* disable receiver and transmitter */
+ 	UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
+-- 
+1.5.6.5
+
+From 3302b2f2b77f3672be5977b89d3a4c5dc65f5793 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:22 +0000
+Subject: [PATCH] USB: atmel_usba_udc: change way of specifying bias function
+
+The toggle_bias() function was specified differently for avr32 and at91
+architectures. Now, new at91 have the same behavior as avr32.
+Consequently, we change to a particular chip function definition: only for
+at91sam9rl.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Haavard Skinnemoen <haavard.skinnemoen at atmel.com>
+Acked-by: David Brownell <dbrownell at users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+(cherry picked from commit e60c65d35951ef3527596442338c371ea16d55ed)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11579 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/usb/gadget/atmel_usba_udc.c |   16 ++++++++--------
+ 1 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
+index 05c913c..d6ef3d5 100644
+--- a/drivers/usb/gadget/atmel_usba_udc.c
++++ b/drivers/usb/gadget/atmel_usba_udc.c
+@@ -326,13 +326,7 @@ static int vbus_is_present(struct usba_udc *udc)
+ 	return 1;
+ }
+ 
+-#if defined(CONFIG_AVR32)
+-
+-static void toggle_bias(int is_on)
+-{
+-}
+-
+-#elif defined(CONFIG_ARCH_AT91)
++#if defined(CONFIG_ARCH_AT91SAM9RL)
+ 
+ #include <mach/at91_pmc.h>
+ 
+@@ -346,7 +340,13 @@ static void toggle_bias(int is_on)
+ 		at91_sys_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+ }
+ 
+-#endif /* CONFIG_ARCH_AT91 */
++#else
++
++static void toggle_bias(int is_on)
++{
++}
++
++#endif /* CONFIG_ARCH_AT91SAM9RL */
+ 
+ static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req)
+ {
+-- 
+1.5.6.5
+
+From 280aab6bc59331ee30ca7864101bbe4ba674569b Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:23 +0000
+Subject: [PATCH] Add MACB TX Buffer in SRAM support
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11580 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/net/Kconfig |    6 ++++
+ drivers/net/macb.c  |   72 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ drivers/net/macb.h  |    9 ++++++
+ 3 files changed, 85 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 7048037..bd6e9f2 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -228,6 +228,12 @@ config MACB
+ 	  To compile this driver as a module, choose M here: the module
+ 	  will be called macb.
+ 
++config MACB_TX_SRAM
++	bool "Atmel MACB TX buffers in internal SRAM"
++	depends on NET_ETHERNET && MACB && (ARCH_AT91SAM9260 || ARCH_AT91SAM9263)
++	help
++		Use internal SRAM for TX buffers.
++
+ source "drivers/net/arm/Kconfig"
+ 
+ config AX88796
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index e82aee4..8bfe99a 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -33,9 +33,21 @@
+ /* Make the IP header word-aligned (the ethernet header is 14 bytes) */
+ #define RX_OFFSET		2
+ 
+-#define TX_RING_SIZE		128
++#if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
++	#if defined(CONFIG_ARCH_AT91SAM9260)
++		#define TX_RING_SIZE       2
++	#elif defined(CONFIG_ARCH_AT91SAM9263)
++		#define TX_RING_SIZE       32
++	#endif
++	#define TX_BUFFER_SIZE       1536
++	#define TX_RING_BYTES        (sizeof(struct dma_desc) * TX_RING_SIZE)
++	#define TX_DMA_SIZE      ((TX_RING_BYTES) + (TX_RING_SIZE) * (TX_BUFFER_SIZE))
++#else
++	#define TX_RING_SIZE     128
++	#define TX_RING_BYTES        (sizeof(struct dma_desc) * TX_RING_SIZE)
++#endif
++
+ #define DEF_TX_RING_PENDING	(TX_RING_SIZE - 1)
+-#define TX_RING_BYTES		(sizeof(struct dma_desc) * TX_RING_SIZE)
+ 
+ #define TX_RING_GAP(bp)						\
+ 	(TX_RING_SIZE - (bp)->tx_pending)
+@@ -378,8 +390,10 @@ static void macb_tx(struct macb *bp)
+ 
+ 		dev_dbg(&bp->pdev->dev, "skb %u (data %p) TX complete\n",
+ 			tail, skb->data);
++#if !defined(CONFIG_MACB_TX_SRAM)
+ 		dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
+ 				 DMA_TO_DEVICE);
++#endif
+ 		bp->stats.tx_packets++;
+ 		bp->stats.tx_bytes += skb->len;
+ 		rp->skb = NULL;
+@@ -635,8 +649,13 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ 	entry = bp->tx_head;
+ 	dev_dbg(&bp->pdev->dev, "Allocated ring entry %u\n", entry);
++#if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
++	mapping = bp->tx_ring[entry].addr;
++	memcpy(bp->tx_buffers + entry * TX_BUFFER_SIZE, skb->data, len);
++#else
+ 	mapping = dma_map_single(&bp->pdev->dev, skb->data,
+ 				 len, DMA_TO_DEVICE);
++#endif
+ 	bp->tx_skb[entry].skb = skb;
+ 	bp->tx_skb[entry].mapping = mapping;
+ 	dev_dbg(&bp->pdev->dev, "Mapped skb data %p to DMA addr %08lx\n",
+@@ -647,7 +666,9 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	if (entry == (TX_RING_SIZE - 1))
+ 		ctrl |= MACB_BIT(TX_WRAP);
+ 
++#if !defined(CONFIG_MACB_TX_SRAM)
+ 	bp->tx_ring[entry].addr = mapping;
++#endif
+ 	bp->tx_ring[entry].ctrl = ctrl;
+ 	wmb();
+ 
+@@ -678,8 +699,12 @@ static void macb_free_consistent(struct macb *bp)
+ 		bp->rx_ring = NULL;
+ 	}
+ 	if (bp->tx_ring) {
++#if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
++		iounmap((void *)bp->tx_ring);
++#else
+ 		dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES,
+ 				  bp->tx_ring, bp->tx_ring_dma);
++#endif
+ 		bp->tx_ring = NULL;
+ 	}
+ 	if (bp->rx_buffers) {
+@@ -688,6 +713,11 @@ static void macb_free_consistent(struct macb *bp)
+ 				  bp->rx_buffers, bp->rx_buffers_dma);
+ 		bp->rx_buffers = NULL;
+ 	}
++
++#if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
++	if (bp->tx_ring_dma)
++		release_mem_region(bp->tx_ring_dma, TX_DMA_SIZE);
++#endif
+ }
+ 
+ static int macb_alloc_consistent(struct macb *bp)
+@@ -708,14 +738,44 @@ static int macb_alloc_consistent(struct macb *bp)
+ 		"Allocated RX ring of %d bytes at %08lx (mapped %p)\n",
+ 		size, (unsigned long)bp->rx_ring_dma, bp->rx_ring);
+ 
++#if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
++#if  defined(CONFIG_ARCH_AT91SAM9260)
++	if (request_mem_region(AT91SAM9260_SRAM0_BASE, TX_DMA_SIZE, "macb")) {
++		bp->tx_ring_dma = AT91SAM9260_SRAM0_BASE;
++	} else {
++		if (request_mem_region(AT91SAM9260_SRAM1_BASE, TX_DMA_SIZE, "macb")) {
++			bp->tx_ring_dma = AT91SAM9260_SRAM1_BASE;
++		} else {
++			printk(KERN_WARNING "Cannot request SRAM memory for TX ring, already used\n");
++			return -EBUSY;
++		}
++	}
++#elif defined(CONFIG_ARCH_AT91SAM9263)
++	if (request_mem_region(AT91SAM9263_SRAM0_BASE, TX_DMA_SIZE, "macb")) {
++		bp->tx_ring_dma = AT91SAM9263_SRAM0_BASE;
++	} else {
++		printk(KERN_WARNING "Cannot request SRAM memory for TX ring, already used\n");
++		return -EBUSY;
++	}
++#endif
++
++	bp->tx_ring = ioremap(bp->tx_ring_dma, TX_DMA_SIZE);
++	if (!bp->tx_ring)
++		return -ENOMEM;
++
++	bp->tx_buffers_dma = bp->tx_ring_dma + TX_RING_BYTES;
++	bp->tx_buffers = (char *) bp->tx_ring + TX_RING_BYTES;
++#else
+ 	size = TX_RING_BYTES;
+ 	bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
+ 					 &bp->tx_ring_dma, GFP_KERNEL);
+ 	if (!bp->tx_ring)
+ 		goto out_err;
++
+ 	dev_dbg(&bp->pdev->dev,
+ 		"Allocated TX ring of %d bytes at %08lx (mapped %p)\n",
+ 		size, (unsigned long)bp->tx_ring_dma, bp->tx_ring);
++#endif
+ 
+ 	size = RX_RING_SIZE * RX_BUFFER_SIZE;
+ 	bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
+@@ -746,10 +806,18 @@ static void macb_init_rings(struct macb *bp)
+ 	}
+ 	bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+ 
++#if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
++	for (i = 0; i < TX_RING_SIZE; i++) {
++		bp->tx_ring[i].addr = bp->tx_buffers_dma + i * TX_BUFFER_SIZE;
++		bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
++	}
++#else
+ 	for (i = 0; i < TX_RING_SIZE; i++) {
+ 		bp->tx_ring[i].addr = 0;
+ 		bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ 	}
++#endif
++
+ 	bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+ 
+ 	bp->rx_tail = bp->tx_head = bp->tx_tail = 0;
+diff --git a/drivers/net/macb.h b/drivers/net/macb.h
+index d3212f6..e27dd43 100644
+--- a/drivers/net/macb.h
++++ b/drivers/net/macb.h
+@@ -369,8 +369,13 @@ struct macb {
+ 	struct dma_desc		*tx_ring;
+ 	struct ring_info	*tx_skb;
+ 
++#if defined(CONFIG_ARCH_AT91)
++	void            *tx_buffers;
++#endif
++
+ 	spinlock_t		lock;
+ 	struct platform_device	*pdev;
++	struct clk      *macb_clk;
+ 	struct clk		*pclk;
+ 	struct clk		*hclk;
+ 	struct net_device	*dev;
+@@ -382,6 +387,10 @@ struct macb {
+ 	dma_addr_t		tx_ring_dma;
+ 	dma_addr_t		rx_buffers_dma;
+ 
++#if defined(CONFIG_ARCH_AT91)
++	dma_addr_t      tx_buffers_dma;
++#endif
++
+ 	unsigned int		rx_pending, tx_pending;
+ 
+ 	struct mii_bus		*mii_bus;
+-- 
+1.5.6.5
+
+From e0490c5300f12e886b89224bb41f03ffff02de04 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:23 +0000
+Subject: [PATCH] 5569/1: at91: Support for at91sam9g45: clocks management
+
+Add the at91sam9g45 series support to the AT91 generic clock file.
+This takes care of the particularities of the PMC for this series.
+It also takes advantage of the management by functionalities of
+those PLLs and clocks.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11581 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/clock.c |   61 +++++++++++++++++++++++++++++++++++++------
+ 1 files changed, 52 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
+index c09148c..b83bfad 100644
+--- a/arch/arm/mach-at91/clock.c
++++ b/arch/arm/mach-at91/clock.c
+@@ -48,20 +48,25 @@
+  * Chips have some kind of clocks : group them by functionality
+  */
+ #define cpu_has_utmi()		(  cpu_is_at91cap9() \
+-				|| cpu_is_at91sam9rl())
++				|| cpu_is_at91sam9rl() \
++				|| cpu_is_at91sam9g45())
+ 
+-#define cpu_has_800M_plla()	(cpu_is_at91sam9g20())
++#define cpu_has_800M_plla()	(  cpu_is_at91sam9g20() \
++				|| cpu_is_at91sam9g45())
+ 
+-#define cpu_has_pllb()		(!cpu_is_at91sam9rl())
++#define cpu_has_300M_plla()	(0)
+ 
+-#define cpu_has_upll()		(0)
++#define cpu_has_pllb()		(!(cpu_is_at91sam9rl() \
++				|| cpu_is_at91sam9g45()))
++
++#define cpu_has_upll()		(cpu_is_at91sam9g45())
+ 
+ /* USB host HS & FS */
+ #define cpu_has_uhp()		(!cpu_is_at91sam9rl())
+ 
+ /* USB device FS only */
+-#define cpu_has_udpfs()		(!cpu_is_at91sam9rl())
+-
++#define cpu_has_udpfs()		(!(cpu_is_at91sam9rl() \
++				|| cpu_is_at91sam9g45()))
+ 
+ static LIST_HEAD(clocks);
+ static DEFINE_SPINLOCK(clk_lock);
+@@ -134,6 +139,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
+ {
+ 	unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
+ 
++	if (cpu_is_at91sam9g45()) {
++		if (is_on)
++			uckr |= AT91_PMC_BIASEN;
++		else
++			uckr &= ~AT91_PMC_BIASEN;
++	}
++
+ 	if (is_on) {
+ 		is_on = AT91_PMC_LOCKU;
+ 		at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
+@@ -328,6 +340,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
+ 	unsigned long	flags;
+ 	unsigned	prescale;
+ 	unsigned long	actual;
++	unsigned long	prev = ULONG_MAX;
+ 
+ 	if (!clk_is_programmable(clk))
+ 		return -EINVAL;
+@@ -335,8 +348,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
+ 
+ 	actual = clk->parent->rate_hz;
+ 	for (prescale = 0; prescale < 7; prescale++) {
+-		if (actual && actual <= rate)
++		if (actual > rate)
++			prev = actual;
++
++		if (actual && actual <= rate) {
++			if ((prev - rate) < (rate - actual)) {
++				actual = prev;
++				prescale--;
++			}
+ 			break;
++		}
+ 		actual >>= 1;
+ 	}
+ 
+@@ -391,6 +412,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
+ 		return -EBUSY;
+ 	if (!clk_is_primary(parent) || !clk_is_programmable(clk))
+ 		return -EINVAL;
++
++	if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB)
++		return -EINVAL;
++
+ 	spin_lock_irqsave(&clk_lock, flags);
+ 
+ 	clk->rate_hz = parent->rate_hz;
+@@ -655,6 +680,7 @@ int __init at91_clock_init(unsigned long main_clock)
+ {
+ 	unsigned tmp, freq, mckr;
+ 	int i;
++	int pll_overclock = false;
+ 
+ 	/*
+ 	 * When the bootloader initialized the main oscillator correctly,
+@@ -672,10 +698,24 @@ int __init at91_clock_init(unsigned long main_clock)
+ 
+ 	/* report if PLLA is more than mildly overclocked */
+ 	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
+-	if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000)
+-	   || (cpu_has_800M_plla() && plla.rate_hz > 800000000))
++	if (cpu_has_300M_plla()) {
++		if (plla.rate_hz > 300000000)
++			pll_overclock = true;
++	} else if (cpu_has_800M_plla()) {
++		if (plla.rate_hz > 800000000)
++			pll_overclock = true;
++	} else {
++		if (plla.rate_hz > 209000000)
++			pll_overclock = true;
++	}
++	if (pll_overclock)
+ 		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
+ 
++	if (cpu_is_at91sam9g45()) {
++		mckr = at91_sys_read(AT91_PMC_MCKR);
++		plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12));	/* plla divisor by 2 */
++	}
++
+ 	if (cpu_has_upll() && !cpu_has_pllb()) {
+ 		/* setup UTMI clock as the fourth primary clock
+ 		 * (instead of pllb) */
+@@ -718,6 +758,9 @@ int __init at91_clock_init(unsigned long main_clock)
+ 			freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq;	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
+ 		if (mckr & AT91_PMC_PDIV)
+ 			freq /= 2;		/* processor clock division */
++	} else if (cpu_is_at91sam9g45()) {
++		mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
++			freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
+ 	} else {
+ 		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      /* mdiv */
+ 	}
+-- 
+1.5.6.5
+
+From a5496d94f287f8d5e9e7fa626c2839a4d6aff097 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:24 +0000
+Subject: [PATCH] 5571/1: at91: Basic support for at91sam9g45 series: header files.
+
+AT91sam9g45 series is an ARM 926ej-s SOC family clocked at 400/133MHz.
+It embedds USB high speed host and device, LCD, DDR2 RAM, and a full set of
+peripherals.
+
+Here is the basic header file support for this product series.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+(cherry picked from commit fddcc0ae58edefeb7ac1e460411d7dfbe8ebdacc)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11582 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/include/mach/at91sam9g45.h      |  138 ++++++++++++++++++
+ .../mach-at91/include/mach/at91sam9g45_matrix.h    |  153 ++++++++++++++++++++
+ arch/arm/mach-at91/include/mach/cpu.h              |   16 ++
+ arch/arm/mach-at91/include/mach/hardware.h         |    2 +
+ arch/arm/mach-at91/include/mach/timex.h            |    5 +
+ 5 files changed, 314 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-at91/include/mach/at91sam9g45.h
+ create mode 100644 arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
+
+diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
+new file mode 100644
+index 0000000..2c42cf5
+--- /dev/null
++++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
+@@ -0,0 +1,138 @@
++/*
++ * Chip-specific header file for the AT91SAM9G45 family
++ *
++ *  Copyright (C) 2008-2009 Atmel Corporation.
++ *
++ * Common definitions.
++ * Based on AT91SAM9G45 preliminary datasheet.
++ *
++ * 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 AT91SAM9G45_H
++#define AT91SAM9G45_H
++
++/*
++ * Peripheral identifiers/interrupts.
++ */
++#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
++#define AT91_ID_SYS		1	/* System Controller Interrupt */
++#define AT91SAM9G45_ID_PIOA	2	/* Parallel I/O Controller A */
++#define AT91SAM9G45_ID_PIOB	3	/* Parallel I/O Controller B */
++#define AT91SAM9G45_ID_PIOC	4	/* Parallel I/O Controller C */
++#define AT91SAM9G45_ID_PIODE	5	/* Parallel I/O Controller D and E */
++#define AT91SAM9G45_ID_TRNG	6	/* True Random Number Generator */
++#define AT91SAM9G45_ID_US0	7	/* USART 0 */
++#define AT91SAM9G45_ID_US1	8	/* USART 1 */
++#define AT91SAM9G45_ID_US2	9	/* USART 2 */
++#define AT91SAM9G45_ID_US3	10	/* USART 3 */
++#define AT91SAM9G45_ID_MCI0	11	/* High Speed Multimedia Card Interface 0 */
++#define AT91SAM9G45_ID_TWI0	12	/* Two-Wire Interface 0 */
++#define AT91SAM9G45_ID_TWI1	13	/* Two-Wire Interface 1 */
++#define AT91SAM9G45_ID_SPI0	14	/* Serial Peripheral Interface 0 */
++#define AT91SAM9G45_ID_SPI1	15	/* Serial Peripheral Interface 1 */
++#define AT91SAM9G45_ID_SSC0	16	/* Synchronous Serial Controller 0 */
++#define AT91SAM9G45_ID_SSC1	17	/* Synchronous Serial Controller 1 */
++#define AT91SAM9G45_ID_TCB	18	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
++#define AT91SAM9G45_ID_PWMC	19	/* Pulse Width Modulation Controller */
++#define AT91SAM9G45_ID_TSC	20	/* Touch Screen ADC Controller */
++#define AT91SAM9G45_ID_DMA	21	/* DMA Controller */
++#define AT91SAM9G45_ID_UHPHS	22	/* USB Host High Speed */
++#define AT91SAM9G45_ID_LCDC	23	/* LCD Controller */
++#define AT91SAM9G45_ID_AC97C	24	/* AC97 Controller */
++#define AT91SAM9G45_ID_EMAC	25	/* Ethernet MAC */
++#define AT91SAM9G45_ID_ISI	26	/* Image Sensor Interface */
++#define AT91SAM9G45_ID_UDPHS	27	/* USB Device High Speed */
++#define AT91SAM9G45_ID_AESTDESSHA 28	/* AES + T-DES + SHA */
++#define AT91SAM9G45_ID_MCI1	29	/* High Speed Multimedia Card Interface 1 */
++#define AT91SAM9G45_ID_VDEC	30	/* Video Decoder */
++#define AT91SAM9G45_ID_IRQ0	31	/* Advanced Interrupt Controller */
++
++/*
++ * User Peripheral physical base addresses.
++ */
++#define AT91SAM9G45_BASE_UDPHS		0xfff78000
++#define AT91SAM9G45_BASE_TCB0		0xfff7c000
++#define AT91SAM9G45_BASE_TC0		0xfff7c000
++#define AT91SAM9G45_BASE_TC1		0xfff7c040
++#define AT91SAM9G45_BASE_TC2		0xfff7c080
++#define AT91SAM9G45_BASE_MCI0		0xfff80000
++#define AT91SAM9G45_BASE_TWI0		0xfff84000
++#define AT91SAM9G45_BASE_TWI1		0xfff88000
++#define AT91SAM9G45_BASE_US0		0xfff8c000
++#define AT91SAM9G45_BASE_US1		0xfff90000
++#define AT91SAM9G45_BASE_US2		0xfff94000
++#define AT91SAM9G45_BASE_US3		0xfff98000
++#define AT91SAM9G45_BASE_SSC0		0xfff9c000
++#define AT91SAM9G45_BASE_SSC1		0xfffa0000
++#define AT91SAM9G45_BASE_SPI0		0xfffa4000
++#define AT91SAM9G45_BASE_SPI1		0xfffa8000
++#define AT91SAM9G45_BASE_AC97C		0xfffac000
++#define AT91SAM9G45_BASE_TSC		0xfffb0000
++#define AT91SAM9G45_BASE_ISI		0xfffb4000
++#define AT91SAM9G45_BASE_PWMC		0xfffb8000
++#define AT91SAM9G45_BASE_EMAC		0xfffbc000
++#define AT91SAM9G45_BASE_AES		0xfffc0000
++#define AT91SAM9G45_BASE_TDES		0xfffc4000
++#define AT91SAM9G45_BASE_SHA		0xfffc8000
++#define AT91SAM9G45_BASE_TRNG		0xfffcc000
++#define AT91SAM9G45_BASE_MCI1		0xfffd0000
++#define AT91SAM9G45_BASE_TCB1		0xfffd4000
++#define AT91SAM9G45_BASE_TC3		0xfffd4000
++#define AT91SAM9G45_BASE_TC4		0xfffd4040
++#define AT91SAM9G45_BASE_TC5		0xfffd4080
++#define AT91_BASE_SYS			0xffffe200
++
++/*
++ * System Peripherals (offset from AT91_BASE_SYS)
++ */
++#define AT91_ECC	(0xffffe200 - AT91_BASE_SYS)
++#define AT91_DDRSDRC1	(0xffffe400 - AT91_BASE_SYS)
++#define AT91_DDRSDRC0	(0xffffe600 - AT91_BASE_SYS)
++#define AT91_SMC	(0xffffe800 - AT91_BASE_SYS)
++#define AT91_MATRIX	(0xffffea00 - AT91_BASE_SYS)
++#define AT91_DMA	(0xffffec00 - AT91_BASE_SYS)
++#define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
++#define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
++#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
++#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
++#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
++#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
++#define AT91_PIOE	(0xfffffa00 - AT91_BASE_SYS)
++#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
++#define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
++#define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
++#define AT91_RTT	(0xfffffd20 - AT91_BASE_SYS)
++#define AT91_PIT	(0xfffffd30 - AT91_BASE_SYS)
++#define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
++#define AT91_GPBR	(0xfffffd60 - AT91_BASE_SYS)
++#define AT91_RTC	(0xfffffdb0 - AT91_BASE_SYS)
++
++#define AT91_USART0	AT91SAM9G45_BASE_US0
++#define AT91_USART1	AT91SAM9G45_BASE_US1
++#define AT91_USART2	AT91SAM9G45_BASE_US2
++#define AT91_USART3	AT91SAM9G45_BASE_US3
++
++/*
++ * Internal Memory.
++ */
++#define AT91SAM9G45_SRAM_BASE	0x00300000	/* Internal SRAM base address */
++#define AT91SAM9G45_SRAM_SIZE	SZ_64K		/* Internal SRAM size (64Kb) */
++
++#define AT91SAM9G45_ROM_BASE	0x00400000	/* Internal ROM base address */
++#define AT91SAM9G45_ROM_SIZE	SZ_64K		/* Internal ROM size (64Kb) */
++
++#define AT91SAM9G45_LCDC_BASE	0x00500000	/* LCD Controller */
++#define AT91SAM9G45_UDPHS_FIFO	0x00600000	/* USB Device HS controller */
++#define AT91SAM9G45_OHCI_BASE	0x00700000	/* USB Host controller (OHCI) */
++#define AT91SAM9G45_EHCI_BASE	0x00800000	/* USB Host controller (EHCI) */
++#define AT91SAM9G45_VDEC_BASE	0x00900000	/* Video Decoder Controller */
++
++#define CONFIG_DRAM_BASE	AT91_CHIPSELECT_6
++
++#define CONSISTENT_DMA_SIZE	SZ_4M
++
++#endif
+diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
+new file mode 100644
+index 0000000..c972d60
+--- /dev/null
++++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
+@@ -0,0 +1,153 @@
++/*
++ * Matrix-centric header file for the AT91SAM9G45 family
++ *
++ *  Copyright (C) 2008-2009 Atmel Corporation.
++ *
++ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
++ * Based on AT91SAM9G45 preliminary datasheet.
++ *
++ * 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 AT91SAM9G45_MATRIX_H
++#define AT91SAM9G45_MATRIX_H
++
++#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
++#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
++#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
++#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
++#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
++#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
++#define AT91_MATRIX_MCFG6	(AT91_MATRIX + 0x18)	/* Master Configuration Register 6 */
++#define AT91_MATRIX_MCFG7	(AT91_MATRIX + 0x1C)	/* Master Configuration Register 7 */
++#define AT91_MATRIX_MCFG8	(AT91_MATRIX + 0x20)	/* Master Configuration Register 8 */
++#define AT91_MATRIX_MCFG9	(AT91_MATRIX + 0x24)	/* Master Configuration Register 9 */
++#define AT91_MATRIX_MCFG10	(AT91_MATRIX + 0x28)	/* Master Configuration Register 10 */
++#define AT91_MATRIX_MCFG11	(AT91_MATRIX + 0x2C)	/* Master Configuration Register 11 */
++#define		AT91_MATRIX_ULBT	(7 << 0)	/* Undefined Length Burst Type */
++#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
++#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
++#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
++#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
++#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
++#define			AT91_MATRIX_ULBT_THIRTYTWO	(5 << 0)
++#define			AT91_MATRIX_ULBT_SIXTYFOUR	(6 << 0)
++#define			AT91_MATRIX_ULBT_128		(7 << 0)
++
++#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
++#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
++#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
++#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
++#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
++#define AT91_MATRIX_SCFG5	(AT91_MATRIX + 0x54)	/* Slave Configuration Register 5 */
++#define AT91_MATRIX_SCFG6	(AT91_MATRIX + 0x58)	/* Slave Configuration Register 6 */
++#define AT91_MATRIX_SCFG7	(AT91_MATRIX + 0x5C)	/* Slave Configuration Register 7 */
++#define		AT91_MATRIX_SLOT_CYCLE		(0x1ff << 0)	/* Maximum Number of Allowed Cycles for a Burst */
++#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
++#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
++#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
++#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
++#define		AT91_MATRIX_FIXED_DEFMSTR	(0xf  << 18)	/* Fixed Index of Default Master */
++
++#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
++#define AT91_MATRIX_PRBS0	(AT91_MATRIX + 0x84)	/* Priority Register B for Slave 0 */
++#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
++#define AT91_MATRIX_PRBS1	(AT91_MATRIX + 0x8C)	/* Priority Register B for Slave 1 */
++#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
++#define AT91_MATRIX_PRBS2	(AT91_MATRIX + 0x94)	/* Priority Register B for Slave 2 */
++#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
++#define AT91_MATRIX_PRBS3	(AT91_MATRIX + 0x9C)	/* Priority Register B for Slave 3 */
++#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
++#define AT91_MATRIX_PRBS4	(AT91_MATRIX + 0xA4)	/* Priority Register B for Slave 4 */
++#define AT91_MATRIX_PRAS5	(AT91_MATRIX + 0xA8)	/* Priority Register A for Slave 5 */
++#define AT91_MATRIX_PRBS5	(AT91_MATRIX + 0xAC)	/* Priority Register B for Slave 5 */
++#define AT91_MATRIX_PRAS6	(AT91_MATRIX + 0xB0)	/* Priority Register A for Slave 6 */
++#define AT91_MATRIX_PRBS6	(AT91_MATRIX + 0xB4)	/* Priority Register B for Slave 6 */
++#define AT91_MATRIX_PRAS7	(AT91_MATRIX + 0xB8)	/* Priority Register A for Slave 7 */
++#define AT91_MATRIX_PRBS7	(AT91_MATRIX + 0xBC)	/* Priority Register B for Slave 7 */
++#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
++#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
++#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
++#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
++#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
++#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
++#define		AT91_MATRIX_M6PR		(3 << 24)	/* Master 6 Priority */
++#define		AT91_MATRIX_M7PR		(3 << 28)	/* Master 7 Priority */
++#define		AT91_MATRIX_M8PR		(3 << 0)	/* Master 8 Priority (in Register B) */
++#define		AT91_MATRIX_M9PR		(3 << 4)	/* Master 9 Priority (in Register B) */
++#define		AT91_MATRIX_M10PR		(3 << 8)	/* Master 10 Priority (in Register B) */
++#define		AT91_MATRIX_M11PR		(3 << 12)	/* Master 11 Priority (in Register B) */
++
++#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
++#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
++#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
++#define		AT91_MATRIX_RCB2		(1 << 2)
++#define		AT91_MATRIX_RCB3		(1 << 3)
++#define		AT91_MATRIX_RCB4		(1 << 4)
++#define		AT91_MATRIX_RCB5		(1 << 5)
++#define		AT91_MATRIX_RCB6		(1 << 6)
++#define		AT91_MATRIX_RCB7		(1 << 7)
++#define		AT91_MATRIX_RCB8		(1 << 8)
++#define		AT91_MATRIX_RCB9		(1 << 9)
++#define		AT91_MATRIX_RCB10		(1 << 10)
++#define		AT91_MATRIX_RCB11		(1 << 11)
++
++#define AT91_MATRIX_TCMR	(AT91_MATRIX + 0x110)	/* TCM Configuration Register */
++#define		AT91_MATRIX_ITCM_SIZE		(0xf << 0)	/* Size of ITCM enabled memory block */
++#define			AT91_MATRIX_ITCM_0		(0 << 0)
++#define			AT91_MATRIX_ITCM_32		(6 << 0)
++#define		AT91_MATRIX_DTCM_SIZE		(0xf << 4)	/* Size of DTCM enabled memory block */
++#define			AT91_MATRIX_DTCM_0		(0 << 4)
++#define			AT91_MATRIX_DTCM_32		(6 << 4)
++#define			AT91_MATRIX_DTCM_64		(7 << 4)
++#define		AT91_MATRIX_TCM_NWS		(0x1 << 11)	/* Wait state TCM register */
++#define			AT91_MATRIX_TCM_NO_WS		(0x0 << 11)
++#define			AT91_MATRIX_TCM_ONE_WS		(0x1 << 11)
++
++#define AT91_MATRIX_VIDEO	(AT91_MATRIX + 0x118)	/* Video Mode Configuration Register */
++#define		AT91C_VDEC_SEL			(0x1 <<  0) /* Video Mode Selection */
++#define			AT91C_VDEC_SEL_OFF		(0 << 0)
++#define			AT91C_VDEC_SEL_ON		(1 << 0)
++
++#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x128)	/* EBI Chip Select Assignment Register */
++#define		AT91_MATRIX_EBI_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
++#define			AT91_MATRIX_EBI_CS1A_SMC		(0 << 1)
++#define			AT91_MATRIX_EBI_CS1A_SDRAMC		(1 << 1)
++#define		AT91_MATRIX_EBI_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
++#define			AT91_MATRIX_EBI_CS3A_SMC		(0 << 3)
++#define			AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
++#define		AT91_MATRIX_EBI_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
++#define			AT91_MATRIX_EBI_CS4A_SMC		(0 << 4)
++#define			AT91_MATRIX_EBI_CS4A_SMC_CF0		(1 << 4)
++#define		AT91_MATRIX_EBI_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
++#define			AT91_MATRIX_EBI_CS5A_SMC		(0 << 5)
++#define			AT91_MATRIX_EBI_CS5A_SMC_CF1		(1 << 5)
++#define		AT91_MATRIX_EBI_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
++#define			AT91_MATRIX_EBI_DBPU_ON			(0 << 8)
++#define			AT91_MATRIX_EBI_DBPU_OFF		(1 << 8)
++#define		AT91_MATRIX_EBI_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
++#define			AT91_MATRIX_EBI_VDDIOMSEL_1_8V		(0 << 16)
++#define			AT91_MATRIX_EBI_VDDIOMSEL_3_3V		(1 << 16)
++#define		AT91_MATRIX_EBI_EBI_IOSR	(1 << 17)	/* EBI I/O slew rate selection */
++#define			AT91_MATRIX_EBI_EBI_IOSR_REDUCED	(0 << 17)
++#define			AT91_MATRIX_EBI_EBI_IOSR_NORMAL		(1 << 17)
++#define		AT91_MATRIX_EBI_DDR_IOSR	(1 << 18)	/* DDR2 dedicated port I/O slew rate selection */
++#define			AT91_MATRIX_EBI_DDR_IOSR_REDUCED	(0 << 18)
++#define			AT91_MATRIX_EBI_DDR_IOSR_NORMAL		(1 << 18)
++
++#define AT91_MATRIX_WPMR	(AT91_MATRIX + 0x1E4)	/* Write Protect Mode Register */
++#define		AT91_MATRIX_WPMR_WPEN		(1 << 0)	/* Write Protect ENable */
++#define			AT91_MATRIX_WPMR_WP_WPDIS		(0 << 0)
++#define			AT91_MATRIX_WPMR_WP_WPEN		(1 << 0)
++#define		AT91_MATRIX_WPMR_WPKEY		(0xFFFFFF << 8)	/* Write Protect KEY */
++
++#define AT91_MATRIX_WPSR	(AT91_MATRIX + 0x1E8)	/* Write Protect Status Register */
++#define		AT91_MATRIX_WPSR_WPVS		(1 << 0)	/* Write Protect Violation Status */
++#define			AT91_MATRIX_WPSR_NO_WPV		(0 << 0)
++#define			AT91_MATRIX_WPSR_WPV		(1 << 0)
++#define		AT91_MATRIX_WPSR_WPVSRC		(0xFFFF << 8)	/* Write Protect Violation Source */
++
++#endif
+diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
+index 43d88fb..64af079 100644
+--- a/arch/arm/mach-at91/include/mach/cpu.h
++++ b/arch/arm/mach-at91/include/mach/cpu.h
+@@ -23,6 +23,7 @@
+ #define ARCH_ID_AT91SAM9263	0x019607a0
+ #define ARCH_ID_AT91SAM9G20	0x019905a0
+ #define ARCH_ID_AT91SAM9RL64	0x019b03a0
++#define ARCH_ID_AT91SAM9G45	0x819b05a0
+ #define ARCH_ID_AT91CAP9	0x039A03A0
+ 
+ #define ARCH_ID_AT91SAM9XE128	0x329973a0
+@@ -41,6 +42,15 @@ static inline unsigned long at91_cpu_identify(void)
+ 	return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
+ }
+ 
++#define ARCH_EXID_AT91SAM9M11	0x00000001
++#define ARCH_EXID_AT91SAM9M10	0x00000002
++#define ARCH_EXID_AT91SAM9G45	0x00000004
++
++static inline unsigned long at91_exid_identify(void)
++{
++	return at91_sys_read(AT91_DBGU_EXID);
++}
++
+ 
+ #define ARCH_FAMILY_AT91X92	0x09200000
+ #define ARCH_FAMILY_AT91SAM9	0x01900000
+@@ -101,6 +111,12 @@ static inline unsigned long at91cap9_rev_identify(void)
+ #define cpu_is_at91sam9rl()	(0)
+ #endif
+ 
++#ifdef CONFIG_ARCH_AT91SAM9G45
++#define cpu_is_at91sam9g45()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
++#else
++#define cpu_is_at91sam9g45()	(0)
++#endif
++
+ #ifdef CONFIG_ARCH_AT91CAP9
+ #define cpu_is_at91cap9()	(at91_cpu_identify() == ARCH_ID_AT91CAP9)
+ #define cpu_is_at91cap9_revB()	(at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
+diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
+index e045996..a747d37 100644
+--- a/arch/arm/mach-at91/include/mach/hardware.h
++++ b/arch/arm/mach-at91/include/mach/hardware.h
+@@ -26,6 +26,8 @@
+ #include <mach/at91sam9263.h>
+ #elif defined(CONFIG_ARCH_AT91SAM9RL)
+ #include <mach/at91sam9rl.h>
++#elif defined(CONFIG_ARCH_AT91SAM9G45)
++#include <mach/at91sam9g45.h>
+ #elif defined(CONFIG_ARCH_AT91CAP9)
+ #include <mach/at91cap9.h>
+ #elif defined(CONFIG_ARCH_AT91X40)
+diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
+index 55b6b9e..5abdf73 100644
+--- a/arch/arm/mach-at91/include/mach/timex.h
++++ b/arch/arm/mach-at91/include/mach/timex.h
+@@ -66,6 +66,11 @@
+ #endif
+ #define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
+ 
++#elif defined(CONFIG_ARCH_AT91SAM9G45)
++
++#define AT91SAM9_MASTER_CLOCK	133333333
++#define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
++
+ #elif defined(CONFIG_ARCH_AT91CAP9)
+ 
+ #define AT91CAP9_MASTER_CLOCK	100000000
+-- 
+1.5.6.5
+
+From 2d79574469d7a58cad231b77a7c709be2e275b44 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:25 +0000
+Subject: [PATCH] 5572/1: at91: Support for at91sam9g45 series: core chip & board support
+
+Here are the at91 specific files dedicated to the at91sam9g45 series. They
+mimic the traditional at91 way of managing chips & boards.
+
+The first board that embeds at91sam9g45 chip is the AT91SAM9G45-EKES. In
+the future, the main board for this 9g45 series will be the
+AT91SAM9M10G45-EK (I choose this last name for the board file).
+
+Simple drivers are enabled in _devices and board- files. Newer peripheral
+support will be added in future patches.
+
+Incuded peripherals support (for now):
+- USART
+- SPI
+- Ethernet
+- NAND flash
+- LCD
+- gpio/joystick/buttons
+- leds and pwm
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11583 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/Kconfig               |   26 +-
+ arch/arm/mach-at91/Makefile              |    4 +
+ arch/arm/mach-at91/Makefile.boot         |    4 +
+ arch/arm/mach-at91/at91sam9g45.c         |  360 +++++++++
+ arch/arm/mach-at91/at91sam9g45_devices.c | 1230 ++++++++++++++++++++++++++++++
+ arch/arm/mach-at91/board-sam9m10g45ek.c  |  389 ++++++++++
+ arch/arm/mach-at91/generic.h             |    2 +
+ arch/arm/mach-at91/include/mach/board.h  |    8 +-
+ drivers/net/Kconfig                      |    2 +-
+ drivers/video/Kconfig                    |    2 +-
+ 10 files changed, 2022 insertions(+), 5 deletions(-)
+ create mode 100644 arch/arm/mach-at91/at91sam9g45.c
+ create mode 100644 arch/arm/mach-at91/at91sam9g45_devices.c
+ create mode 100644 arch/arm/mach-at91/board-sam9m10g45ek.c
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index 9db021e..6ea88b4 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -41,6 +41,12 @@ config ARCH_AT91SAM9G20
+ 	select GENERIC_TIME
+ 	select GENERIC_CLOCKEVENTS
+ 
++config ARCH_AT91SAM9G45
++	bool "AT91SAM9G45"
++	select CPU_ARM926T
++	select GENERIC_TIME
++	select GENERIC_CLOCKEVENTS
++
+ config ARCH_AT91CAP9
+ 	bool "AT91CAP9"
+ 	select CPU_ARM926T
+@@ -359,6 +365,22 @@ endif
+ 
+ # ----------------------------------------------------------
+ 
++if ARCH_AT91SAM9G45
++
++comment "AT91SAM9G45 Board Type"
++
++config MACH_AT91SAM9G45EKES
++	bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
++	depends on ARCH_AT91SAM9G45
++	help
++	  Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
++	  "ES" at the end of the name means that this board is an
++	  Engineering Sample.
++
++endif
++
++# ----------------------------------------------------------
++
+ if ARCH_AT91CAP9
+ 
+ comment "AT91CAP9 Board Type"
+@@ -415,7 +437,7 @@ config MTD_AT91_DATAFLASH_CARD
+ 
+ config MTD_NAND_ATMEL_BUSWIDTH_16
+ 	bool "Enable 16-bit data bus interface to NAND flash"
+-	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK || MACH_AT572D940HFEB)
++	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK || MACH_AT572D940HFEB)
+ 	help
+ 	  On AT91SAM926x boards both types of NAND flash can be present
+ 	  (8 and 16 bit data bus width).
+@@ -477,7 +499,7 @@ config AT91_EARLY_USART2
+ 
+ config AT91_EARLY_USART3
+ 	bool "USART3"
+-	depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
++	depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45)
+ 
+ config AT91_EARLY_USART4
+ 	bool "USART4"
+diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
+index cd2c2f1..cf31340 100644
+--- a/arch/arm/mach-at91/Makefile
++++ b/arch/arm/mach-at91/Makefile
+@@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261.o at91sam926x_time.o at91sam9261_d
+ obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
++ obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
+@@ -66,6 +67,9 @@ obj-$(CONFIG_MACH_USB_A9G20)	 += board-usb-a9g20.o
+ obj-$(CONFIG_MACH_QIL_A9G20)	 += board-qil-a9g20.o
+ obj-$(CONFIG_MACH_SBC35_A9G20)	 += board-sbc35-a9g20.o
+ 
++# AT91SAM9G45 board-specific support
++obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
++
+ # AT91CAP9 board-specific support
+ obj-$(CONFIG_MACH_AT91CAP9ADK)	+= board-cap9adk.o
+ 
+diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
+index 071a250..3462b81 100644
+--- a/arch/arm/mach-at91/Makefile.boot
++++ b/arch/arm/mach-at91/Makefile.boot
+@@ -7,6 +7,10 @@ ifeq ($(CONFIG_ARCH_AT91CAP9),y)
+    zreladdr-y	:= 0x70008000
+ params_phys-y	:= 0x70000100
+ initrd_phys-y	:= 0x70410000
++else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
++   zreladdr-y	:= 0x70008000
++params_phys-y	:= 0x70000100
++initrd_phys-y	:= 0x70410000
+ else
+    zreladdr-y	:= 0x20008000
+ params_phys-y	:= 0x20000100
+diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
+new file mode 100644
+index 0000000..85166b7
+--- /dev/null
++++ b/arch/arm/mach-at91/at91sam9g45.c
+@@ -0,0 +1,360 @@
++/*
++ *  Chip-specific setup code for the AT91SAM9G45 family
++ *
++ *  Copyright (C) 2009 Atmel Corporation.
++ *
++ * 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/pm.h>
++
++#include <asm/irq.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <mach/at91sam9g45.h>
++#include <mach/at91_pmc.h>
++#include <mach/at91_rstc.h>
++#include <mach/at91_shdwc.h>
++
++#include "generic.h"
++#include "clock.h"
++
++static struct map_desc at91sam9g45_io_desc[] __initdata = {
++	{
++		.virtual	= AT91_VA_BASE_SYS,
++		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
++		.length		= SZ_16K,
++		.type		= MT_DEVICE,
++	}, {
++		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
++		.pfn		= __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
++		.length		= AT91SAM9G45_SRAM_SIZE,
++		.type		= MT_DEVICE,
++	}
++};
++
++/* --------------------------------------------------------------------
++ *  Clocks
++ * -------------------------------------------------------------------- */
++
++/*
++ * The peripheral clocks.
++ */
++static struct clk pioA_clk = {
++	.name		= "pioA_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_PIOA,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk pioB_clk = {
++	.name		= "pioB_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_PIOB,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk pioC_clk = {
++	.name		= "pioC_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_PIOC,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk pioDE_clk = {
++	.name		= "pioDE_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_PIODE,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk usart0_clk = {
++	.name		= "usart0_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_US0,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk usart1_clk = {
++	.name		= "usart1_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_US1,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk usart2_clk = {
++	.name		= "usart2_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_US2,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk usart3_clk = {
++	.name		= "usart3_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_US3,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk mmc0_clk = {
++	.name		= "mci0_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_MCI0,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk twi0_clk = {
++	.name		= "twi0_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_TWI0,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk twi1_clk = {
++	.name		= "twi1_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_TWI1,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk spi0_clk = {
++	.name		= "spi0_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_SPI0,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk spi1_clk = {
++	.name		= "spi1_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_SPI1,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk ssc0_clk = {
++	.name		= "ssc0_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_SSC0,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk ssc1_clk = {
++	.name		= "ssc1_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_SSC1,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk tcb_clk = {
++	.name		= "tcb_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_TCB,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk pwm_clk = {
++	.name		= "pwm_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_PWMC,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk tsc_clk = {
++	.name		= "tsc_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_TSC,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk dma_clk = {
++	.name		= "dma_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_DMA,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk uhphs_clk = {
++	.name		= "uhphs_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_UHPHS,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk lcdc_clk = {
++	.name		= "lcdc_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_LCDC,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk ac97_clk = {
++	.name		= "ac97_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_AC97C,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk macb_clk = {
++	.name		= "macb_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_EMAC,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk isi_clk = {
++	.name		= "isi_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_ISI,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk udphs_clk = {
++	.name		= "udphs_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_UDPHS,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++static struct clk mmc1_clk = {
++	.name		= "mci1_clk",
++	.pmc_mask	= 1 << AT91SAM9G45_ID_MCI1,
++	.type		= CLK_TYPE_PERIPHERAL,
++};
++
++/* One additional fake clock for ohci */
++static struct clk ohci_clk = {
++	.name		= "ohci_clk",
++	.pmc_mask	= 0,
++	.type		= CLK_TYPE_PERIPHERAL,
++	.parent		= &uhphs_clk,
++};
++
++static struct clk *periph_clocks[] __initdata = {
++	&pioA_clk,
++	&pioB_clk,
++	&pioC_clk,
++	&pioDE_clk,
++	&usart0_clk,
++	&usart1_clk,
++	&usart2_clk,
++	&usart3_clk,
++	&mmc0_clk,
++	&twi0_clk,
++	&twi1_clk,
++	&spi0_clk,
++	&spi1_clk,
++	&ssc0_clk,
++	&ssc1_clk,
++	&tcb_clk,
++	&pwm_clk,
++	&tsc_clk,
++	&dma_clk,
++	&uhphs_clk,
++	&lcdc_clk,
++	&ac97_clk,
++	&macb_clk,
++	&isi_clk,
++	&udphs_clk,
++	&mmc1_clk,
++	// irq0
++	&ohci_clk,
++};
++
++/*
++ * The two programmable clocks.
++ * You must configure pin multiplexing to bring these signals out.
++ */
++static struct clk pck0 = {
++	.name		= "pck0",
++	.pmc_mask	= AT91_PMC_PCK0,
++	.type		= CLK_TYPE_PROGRAMMABLE,
++	.id		= 0,
++};
++static struct clk pck1 = {
++	.name		= "pck1",
++	.pmc_mask	= AT91_PMC_PCK1,
++	.type		= CLK_TYPE_PROGRAMMABLE,
++	.id		= 1,
++};
++
++static void __init at91sam9g45_register_clocks(void)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
++		clk_register(periph_clocks[i]);
++
++	clk_register(&pck0);
++	clk_register(&pck1);
++}
++
++/* --------------------------------------------------------------------
++ *  GPIO
++ * -------------------------------------------------------------------- */
++
++static struct at91_gpio_bank at91sam9g45_gpio[] = {
++	{
++		.id		= AT91SAM9G45_ID_PIOA,
++		.offset		= AT91_PIOA,
++		.clock		= &pioA_clk,
++	}, {
++		.id		= AT91SAM9G45_ID_PIOB,
++		.offset		= AT91_PIOB,
++		.clock		= &pioB_clk,
++	}, {
++		.id		= AT91SAM9G45_ID_PIOC,
++		.offset		= AT91_PIOC,
++		.clock		= &pioC_clk,
++	}, {
++		.id		= AT91SAM9G45_ID_PIODE,
++		.offset		= AT91_PIOD,
++		.clock		= &pioDE_clk,
++	}, {
++		.id		= AT91SAM9G45_ID_PIODE,
++		.offset		= AT91_PIOE,
++		.clock		= &pioDE_clk,
++	}
++};
++
++static void at91sam9g45_reset(void)
++{
++	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
++}
++
++static void at91sam9g45_poweroff(void)
++{
++	at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
++}
++
++
++/* --------------------------------------------------------------------
++ *  AT91SAM9G45 processor initialization
++ * -------------------------------------------------------------------- */
++
++void __init at91sam9g45_initialize(unsigned long main_clock)
++{
++	/* Map peripherals */
++	iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
++
++	at91_arch_reset = at91sam9g45_reset;
++	pm_power_off = at91sam9g45_poweroff;
++	at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
++
++	/* Init clock subsystem */
++	at91_clock_init(main_clock);
++
++	/* Register the processor-specific clocks */
++	at91sam9g45_register_clocks();
++
++	/* Register GPIO subsystem */
++	at91_gpio_init(at91sam9g45_gpio, 5);
++}
++
++/* --------------------------------------------------------------------
++ *  Interrupt initialization
++ * -------------------------------------------------------------------- */
++
++/*
++ * The default interrupt priority levels (0 = lowest, 7 = highest).
++ */
++static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
++	7,	/* Advanced Interrupt Controller (FIQ) */
++	7,	/* System Peripherals */
++	1,	/* Parallel IO Controller A */
++	1,	/* Parallel IO Controller B */
++	1,	/* Parallel IO Controller C */
++	1,	/* Parallel IO Controller D and E */
++	0,
++	5,	/* USART 0 */
++	5,	/* USART 1 */
++	5,	/* USART 2 */
++	5,	/* USART 3 */
++	0,	/* Multimedia Card Interface 0 */
++	6,	/* Two-Wire Interface 0 */
++	6,	/* Two-Wire Interface 1 */
++	5,	/* Serial Peripheral Interface 0 */
++	5,	/* Serial Peripheral Interface 1 */
++	4,	/* Serial Synchronous Controller 0 */
++	4,	/* Serial Synchronous Controller 1 */
++	0,	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
++	0,	/* Pulse Width Modulation Controller */
++	0,	/* Touch Screen Controller */
++	0,	/* DMA Controller */
++	2,	/* USB Host High Speed port */
++	3,	/* LDC Controller */
++	5,	/* AC97 Controller */
++	3,	/* Ethernet */
++	0,	/* Image Sensor Interface */
++	2,	/* USB Device High speed port */
++	0,
++	0,	/* Multimedia Card Interface 1 */
++	0,
++	0,	/* Advanced Interrupt Controller (IRQ0) */
++};
++
++void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
++{
++	if (!priority)
++		priority = at91sam9g45_default_irq_priority;
++
++	/* Initialize the AIC interrupt controller */
++	at91_aic_init(priority);
++
++	/* Enable GPIO interrupts */
++	at91_gpio_irq_setup();
++}
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+new file mode 100644
+index 0000000..d746e86
+--- /dev/null
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -0,0 +1,1230 @@
++/*
++ *  On-Chip devices setup code for the AT91SAM9G45 family
++ *
++ *  Copyright (C) 2009 Atmel Corporation.
++ *
++ * 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 <asm/mach/arch.h>
++#include <asm/mach/map.h>
++
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <linux/i2c-gpio.h>
++
++#include <linux/fb.h>
++#include <video/atmel_lcdc.h>
++
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9g45.h>
++#include <mach/at91sam9g45_matrix.h>
++#include <mach/at91sam9_smc.h>
++
++#include "generic.h"
++
++
++/* --------------------------------------------------------------------
++ *  USB Host (OHCI)
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
++static u64 ohci_dmamask = DMA_BIT_MASK(32);
++static struct at91_usbh_data usbh_ohci_data;
++
++static struct resource usbh_ohci_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_OHCI_BASE,
++		.end	= AT91SAM9G45_OHCI_BASE + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_UHPHS,
++		.end	= AT91SAM9G45_ID_UHPHS,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91_usbh_ohci_device = {
++	.name		= "at91_ohci",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &ohci_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &usbh_ohci_data,
++	},
++	.resource	= usbh_ohci_resources,
++	.num_resources	= ARRAY_SIZE(usbh_ohci_resources),
++};
++
++void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
++{
++	int i;
++
++	if (!data)
++		return;
++
++	/* Enable VBus control for UHP ports */
++	for (i = 0; i < data->ports; i++) {
++		if (data->vbus_pin[i])
++			at91_set_gpio_output(data->vbus_pin[i], 0);
++	}
++
++	usbh_ohci_data = *data;
++	platform_device_register(&at91_usbh_ohci_device);
++}
++#else
++void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  USB HS Device (Gadget)
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
++static struct resource usba_udc_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_UDPHS_FIFO,
++		.end	= AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_BASE_UDPHS,
++		.end	= AT91SAM9G45_BASE_UDPHS + SZ_1K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[2] = {
++		.start	= AT91SAM9G45_ID_UDPHS,
++		.end	= AT91SAM9G45_ID_UDPHS,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++#define EP(nam, idx, maxpkt, maxbk, dma, isoc)			\
++	[idx] = {						\
++		.name		= nam,				\
++		.index		= idx,				\
++		.fifo_size	= maxpkt,			\
++		.nr_banks	= maxbk,			\
++		.can_dma	= dma,				\
++		.can_isoc	= isoc,				\
++	}
++
++static struct usba_ep_data usba_udc_ep[] __initdata = {
++	EP("ep0", 0, 64, 1, 0, 0),
++	EP("ep1", 1, 1024, 2, 1, 1),
++	EP("ep2", 2, 1024, 2, 1, 1),
++	EP("ep3", 3, 1024, 3, 1, 0),
++	EP("ep4", 4, 1024, 3, 1, 0),
++	EP("ep5", 5, 1024, 3, 1, 1),
++	EP("ep6", 6, 1024, 3, 1, 1),
++};
++
++#undef EP
++
++/*
++ * pdata doesn't have room for any endpoints, so we need to
++ * append room for the ones we need right after it.
++ */
++static struct {
++	struct usba_platform_data pdata;
++	struct usba_ep_data ep[7];
++} usba_udc_data;
++
++static struct platform_device at91_usba_udc_device = {
++	.name		= "atmel_usba_udc",
++	.id		= -1,
++	.dev		= {
++				.platform_data	= &usba_udc_data.pdata,
++	},
++	.resource	= usba_udc_resources,
++	.num_resources	= ARRAY_SIZE(usba_udc_resources),
++};
++
++void __init at91_add_device_usba(struct usba_platform_data *data)
++{
++	usba_udc_data.pdata.vbus_pin = -EINVAL;
++	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
++	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
++
++	if (data && data->vbus_pin > 0) {
++		at91_set_gpio_input(data->vbus_pin, 0);
++		at91_set_deglitch(data->vbus_pin, 1);
++		usba_udc_data.pdata.vbus_pin = data->vbus_pin;
++	}
++
++	/* Pullup pin is handled internally by USB device peripheral */
++
++	/* Clocks */
++	at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
++	at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
++
++	platform_device_register(&at91_usba_udc_device);
++}
++#else
++void __init at91_add_device_usba(struct usba_platform_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  Ethernet
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
++static u64 eth_dmamask = DMA_BIT_MASK(32);
++static struct at91_eth_data eth_data;
++
++static struct resource eth_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_EMAC,
++		.end	= AT91SAM9G45_BASE_EMAC + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_EMAC,
++		.end	= AT91SAM9G45_ID_EMAC,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_eth_device = {
++	.name		= "macb",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &eth_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &eth_data,
++	},
++	.resource	= eth_resources,
++	.num_resources	= ARRAY_SIZE(eth_resources),
++};
++
++void __init at91_add_device_eth(struct at91_eth_data *data)
++{
++	if (!data)
++		return;
++
++	if (data->phy_irq_pin) {
++		at91_set_gpio_input(data->phy_irq_pin, 0);
++		at91_set_deglitch(data->phy_irq_pin, 1);
++	}
++
++	/* Pins used for MII and RMII */
++	at91_set_A_periph(AT91_PIN_PA17, 0);	/* ETXCK_EREFCK */
++	at91_set_A_periph(AT91_PIN_PA15, 0);	/* ERXDV */
++	at91_set_A_periph(AT91_PIN_PA12, 0);	/* ERX0 */
++	at91_set_A_periph(AT91_PIN_PA13, 0);	/* ERX1 */
++	at91_set_A_periph(AT91_PIN_PA16, 0);	/* ERXER */
++	at91_set_A_periph(AT91_PIN_PA14, 0);	/* ETXEN */
++	at91_set_A_periph(AT91_PIN_PA10, 0);	/* ETX0 */
++	at91_set_A_periph(AT91_PIN_PA11, 0);	/* ETX1 */
++	at91_set_A_periph(AT91_PIN_PA19, 0);	/* EMDIO */
++	at91_set_A_periph(AT91_PIN_PA18, 0);	/* EMDC */
++
++	if (!data->is_rmii) {
++		at91_set_B_periph(AT91_PIN_PA29, 0);	/* ECRS */
++		at91_set_B_periph(AT91_PIN_PA30, 0);	/* ECOL */
++		at91_set_B_periph(AT91_PIN_PA8,  0);	/* ERX2 */
++		at91_set_B_periph(AT91_PIN_PA9,  0);	/* ERX3 */
++		at91_set_B_periph(AT91_PIN_PA28, 0);	/* ERXCK */
++		at91_set_B_periph(AT91_PIN_PA6,  0);	/* ETX2 */
++		at91_set_B_periph(AT91_PIN_PA7,  0);	/* ETX3 */
++		at91_set_B_periph(AT91_PIN_PA27, 0);	/* ETXER */
++	}
++
++	eth_data = *data;
++	platform_device_register(&at91sam9g45_eth_device);
++}
++#else
++void __init at91_add_device_eth(struct at91_eth_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  NAND / SmartMedia
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
++static struct atmel_nand_data nand_data;
++
++#define NAND_BASE	AT91_CHIPSELECT_3
++
++static struct resource nand_resources[] = {
++	[0] = {
++		.start	= NAND_BASE,
++		.end	= NAND_BASE + SZ_256M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91_BASE_SYS + AT91_ECC,
++		.end	= AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
++		.flags	= IORESOURCE_MEM,
++	}
++};
++
++static struct platform_device at91sam9g45_nand_device = {
++	.name		= "atmel_nand",
++	.id		= -1,
++	.dev		= {
++				.platform_data	= &nand_data,
++	},
++	.resource	= nand_resources,
++	.num_resources	= ARRAY_SIZE(nand_resources),
++};
++
++void __init at91_add_device_nand(struct atmel_nand_data *data)
++{
++	unsigned long csa;
++
++	if (!data)
++		return;
++
++	csa = at91_sys_read(AT91_MATRIX_EBICSA);
++	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
++
++	/* enable pin */
++	if (data->enable_pin)
++		at91_set_gpio_output(data->enable_pin, 1);
++
++	/* ready/busy pin */
++	if (data->rdy_pin)
++		at91_set_gpio_input(data->rdy_pin, 1);
++
++	/* card detect pin */
++	if (data->det_pin)
++		at91_set_gpio_input(data->det_pin, 1);
++
++	nand_data = *data;
++	platform_device_register(&at91sam9g45_nand_device);
++}
++#else
++void __init at91_add_device_nand(struct atmel_nand_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  TWI (i2c)
++ * -------------------------------------------------------------------- */
++
++/*
++ * Prefer the GPIO code since the TWI controller isn't robust
++ * (gets overruns and underruns under load) and can only issue
++ * repeated STARTs in one scenario (the driver doesn't yet handle them).
++ */
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++static struct i2c_gpio_platform_data pdata_i2c0 = {
++	.sda_pin		= AT91_PIN_PA20,
++	.sda_is_open_drain	= 1,
++	.scl_pin		= AT91_PIN_PA21,
++	.scl_is_open_drain	= 1,
++	.udelay			= 2,		/* ~100 kHz */
++};
++
++static struct platform_device at91sam9g45_twi0_device = {
++	.name			= "i2c-gpio",
++	.id			= 0,
++	.dev.platform_data	= &pdata_i2c0,
++};
++
++static struct i2c_gpio_platform_data pdata_i2c1 = {
++	.sda_pin		= AT91_PIN_PB10,
++	.sda_is_open_drain	= 1,
++	.scl_pin		= AT91_PIN_PB11,
++	.scl_is_open_drain	= 1,
++	.udelay			= 2,		/* ~100 kHz */
++};
++
++static struct platform_device at91sam9g45_twi1_device = {
++	.name			= "i2c-gpio",
++	.id			= 1,
++	.dev.platform_data	= &pdata_i2c1,
++};
++
++void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
++{
++	i2c_register_board_info(i2c_id, devices, nr_devices);
++
++	if (i2c_id == 0) {
++		at91_set_GPIO_periph(AT91_PIN_PA20, 1);		/* TWD (SDA) */
++		at91_set_multi_drive(AT91_PIN_PA20, 1);
++
++		at91_set_GPIO_periph(AT91_PIN_PA21, 1);		/* TWCK (SCL) */
++		at91_set_multi_drive(AT91_PIN_PA21, 1);
++
++		platform_device_register(&at91sam9g45_twi0_device);
++	} else {
++		at91_set_GPIO_periph(AT91_PIN_PB10, 1);		/* TWD (SDA) */
++		at91_set_multi_drive(AT91_PIN_PB10, 1);
++
++		at91_set_GPIO_periph(AT91_PIN_PB11, 1);		/* TWCK (SCL) */
++		at91_set_multi_drive(AT91_PIN_PB11, 1);
++
++		platform_device_register(&at91sam9g45_twi1_device);
++	}
++}
++
++#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
++static struct resource twi0_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_TWI0,
++		.end	= AT91SAM9G45_BASE_TWI0 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_TWI0,
++		.end	= AT91SAM9G45_ID_TWI0,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_twi0_device = {
++	.name		= "at91_i2c",
++	.id		= 0,
++	.resource	= twi0_resources,
++	.num_resources	= ARRAY_SIZE(twi0_resources),
++};
++
++static struct resource twi1_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_TWI1,
++		.end	= AT91SAM9G45_BASE_TWI1 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_TWI1,
++		.end	= AT91SAM9G45_ID_TWI1,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_twi1_device = {
++	.name		= "at91_i2c",
++	.id		= 1,
++	.resource	= twi1_resources,
++	.num_resources	= ARRAY_SIZE(twi1_resources),
++};
++
++void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
++{
++	i2c_register_board_info(i2c_id, devices, nr_devices);
++
++	/* pins used for TWI interface */
++	if (i2c_id == 0) {
++		at91_set_A_periph(AT91_PIN_PA20, 0);		/* TWD */
++		at91_set_multi_drive(AT91_PIN_PA20, 1);
++
++		at91_set_A_periph(AT91_PIN_PA21, 0);		/* TWCK */
++		at91_set_multi_drive(AT91_PIN_PA21, 1);
++
++		platform_device_register(&at91sam9g45_twi0_device);
++	} else {
++		at91_set_A_periph(AT91_PIN_PB10, 0);		/* TWD */
++		at91_set_multi_drive(AT91_PIN_PB10, 1);
++
++		at91_set_A_periph(AT91_PIN_PB11, 0);		/* TWCK */
++		at91_set_multi_drive(AT91_PIN_PB11, 1);
++
++		platform_device_register(&at91sam9g45_twi1_device);
++	}
++}
++#else
++void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  SPI
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
++static u64 spi_dmamask = DMA_BIT_MASK(32);
++
++static struct resource spi0_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_SPI0,
++		.end	= AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_SPI0,
++		.end	= AT91SAM9G45_ID_SPI0,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_spi0_device = {
++	.name		= "atmel_spi",
++	.id		= 0,
++	.dev		= {
++				.dma_mask		= &spi_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++	.resource	= spi0_resources,
++	.num_resources	= ARRAY_SIZE(spi0_resources),
++};
++
++static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
++
++static struct resource spi1_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_SPI1,
++		.end	= AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_SPI1,
++		.end	= AT91SAM9G45_ID_SPI1,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_spi1_device = {
++	.name		= "atmel_spi",
++	.id		= 1,
++	.dev		= {
++				.dma_mask		= &spi_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++	.resource	= spi1_resources,
++	.num_resources	= ARRAY_SIZE(spi1_resources),
++};
++
++static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
++
++void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
++{
++	int i;
++	unsigned long cs_pin;
++	short enable_spi0 = 0;
++	short enable_spi1 = 0;
++
++	/* Choose SPI chip-selects */
++	for (i = 0; i < nr_devices; i++) {
++		if (devices[i].controller_data)
++			cs_pin = (unsigned long) devices[i].controller_data;
++		else if (devices[i].bus_num == 0)
++			cs_pin = spi0_standard_cs[devices[i].chip_select];
++		else
++			cs_pin = spi1_standard_cs[devices[i].chip_select];
++
++		if (devices[i].bus_num == 0)
++			enable_spi0 = 1;
++		else
++			enable_spi1 = 1;
++
++		/* enable chip-select pin */
++		at91_set_gpio_output(cs_pin, 1);
++
++		/* pass chip-select pin to driver */
++		devices[i].controller_data = (void *) cs_pin;
++	}
++
++	spi_register_board_info(devices, nr_devices);
++
++	/* Configure SPI bus(es) */
++	if (enable_spi0) {
++		at91_set_A_periph(AT91_PIN_PB0, 0);	/* SPI0_MISO */
++		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI0_MOSI */
++		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI0_SPCK */
++
++		at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk");
++		platform_device_register(&at91sam9g45_spi0_device);
++	}
++	if (enable_spi1) {
++		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_MISO */
++		at91_set_A_periph(AT91_PIN_PB15, 0);	/* SPI1_MOSI */
++		at91_set_A_periph(AT91_PIN_PB16, 0);	/* SPI1_SPCK */
++
++		at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk");
++		platform_device_register(&at91sam9g45_spi1_device);
++	}
++}
++#else
++void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  LCD Controller
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static u64 lcdc_dmamask = DMA_BIT_MASK(32);
++static struct atmel_lcdfb_info lcdc_data;
++
++static struct resource lcdc_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_LCDC_BASE,
++		.end	= AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_LCDC,
++		.end	= AT91SAM9G45_ID_LCDC,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91_lcdc_device = {
++	.name		= "atmel_lcdfb",
++	.id		= 0,
++	.dev		= {
++				.dma_mask		= &lcdc_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &lcdc_data,
++	},
++	.resource	= lcdc_resources,
++	.num_resources	= ARRAY_SIZE(lcdc_resources),
++};
++
++void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
++{
++	if (!data)
++		return;
++
++	at91_set_A_periph(AT91_PIN_PE0, 0);	/* LCDDPWR */
++
++	at91_set_A_periph(AT91_PIN_PE2, 0);	/* LCDCC */
++	at91_set_A_periph(AT91_PIN_PE3, 0);	/* LCDVSYNC */
++	at91_set_A_periph(AT91_PIN_PE4, 0);	/* LCDHSYNC */
++	at91_set_A_periph(AT91_PIN_PE5, 0);	/* LCDDOTCK */
++	at91_set_A_periph(AT91_PIN_PE6, 0);	/* LCDDEN */
++	at91_set_A_periph(AT91_PIN_PE7, 0);	/* LCDD0 */
++	at91_set_A_periph(AT91_PIN_PE8, 0);	/* LCDD1 */
++	at91_set_A_periph(AT91_PIN_PE9, 0);	/* LCDD2 */
++	at91_set_A_periph(AT91_PIN_PE10, 0);	/* LCDD3 */
++	at91_set_A_periph(AT91_PIN_PE11, 0);	/* LCDD4 */
++	at91_set_A_periph(AT91_PIN_PE12, 0);	/* LCDD5 */
++	at91_set_A_periph(AT91_PIN_PE13, 0);	/* LCDD6 */
++	at91_set_A_periph(AT91_PIN_PE14, 0);	/* LCDD7 */
++	at91_set_A_periph(AT91_PIN_PE15, 0);	/* LCDD8 */
++	at91_set_A_periph(AT91_PIN_PE16, 0);	/* LCDD9 */
++	at91_set_A_periph(AT91_PIN_PE17, 0);	/* LCDD10 */
++	at91_set_A_periph(AT91_PIN_PE18, 0);	/* LCDD11 */
++	at91_set_A_periph(AT91_PIN_PE19, 0);	/* LCDD12 */
++	at91_set_A_periph(AT91_PIN_PE20, 0);	/* LCDD13 */
++	at91_set_A_periph(AT91_PIN_PE21, 0);	/* LCDD14 */
++	at91_set_A_periph(AT91_PIN_PE22, 0);	/* LCDD15 */
++	at91_set_A_periph(AT91_PIN_PE23, 0);	/* LCDD16 */
++	at91_set_A_periph(AT91_PIN_PE24, 0);	/* LCDD17 */
++	at91_set_A_periph(AT91_PIN_PE25, 0);	/* LCDD18 */
++	at91_set_A_periph(AT91_PIN_PE26, 0);	/* LCDD19 */
++	at91_set_A_periph(AT91_PIN_PE27, 0);	/* LCDD20 */
++	at91_set_A_periph(AT91_PIN_PE28, 0);	/* LCDD21 */
++	at91_set_A_periph(AT91_PIN_PE29, 0);	/* LCDD22 */
++	at91_set_A_periph(AT91_PIN_PE30, 0);	/* LCDD23 */
++
++	lcdc_data = *data;
++	platform_device_register(&at91_lcdc_device);
++}
++#else
++void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  Timer/Counter block
++ * -------------------------------------------------------------------- */
++
++#ifdef CONFIG_ATMEL_TCLIB
++static struct resource tcb0_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_TCB0,
++		.end	= AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_TCB,
++		.end	= AT91SAM9G45_ID_TCB,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_tcb0_device = {
++	.name		= "atmel_tcb",
++	.id		= 0,
++	.resource	= tcb0_resources,
++	.num_resources	= ARRAY_SIZE(tcb0_resources),
++};
++
++/* TCB1 begins with TC3 */
++static struct resource tcb1_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_TCB1,
++		.end	= AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_TCB,
++		.end	= AT91SAM9G45_ID_TCB,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_tcb1_device = {
++	.name		= "atmel_tcb",
++	.id		= 1,
++	.resource	= tcb1_resources,
++	.num_resources	= ARRAY_SIZE(tcb1_resources),
++};
++
++static void __init at91_add_device_tc(void)
++{
++	/* this chip has one clock and irq for all six TC channels */
++	at91_clock_associate("tcb_clk", &at91sam9g45_tcb0_device.dev, "t0_clk");
++	platform_device_register(&at91sam9g45_tcb0_device);
++	at91_clock_associate("tcb_clk", &at91sam9g45_tcb1_device.dev, "t0_clk");
++	platform_device_register(&at91sam9g45_tcb1_device);
++}
++#else
++static void __init at91_add_device_tc(void) { }
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  RTC
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
++static struct platform_device at91sam9g45_rtc_device = {
++	.name		= "at91_rtc",
++	.id		= -1,
++	.num_resources	= 0,
++};
++
++static void __init at91_add_device_rtc(void)
++{
++	platform_device_register(&at91sam9g45_rtc_device);
++}
++#else
++static void __init at91_add_device_rtc(void) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  RTT
++ * -------------------------------------------------------------------- */
++
++static struct resource rtt_resources[] = {
++	{
++		.start	= AT91_BASE_SYS + AT91_RTT,
++		.end	= AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
++		.flags	= IORESOURCE_MEM,
++	}
++};
++
++static struct platform_device at91sam9g45_rtt_device = {
++	.name		= "at91_rtt",
++	.id		= 0,
++	.resource	= rtt_resources,
++	.num_resources	= ARRAY_SIZE(rtt_resources),
++};
++
++static void __init at91_add_device_rtt(void)
++{
++	platform_device_register(&at91sam9g45_rtt_device);
++}
++
++
++/* --------------------------------------------------------------------
++ *  Watchdog
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
++static struct platform_device at91sam9g45_wdt_device = {
++	.name		= "at91_wdt",
++	.id		= -1,
++	.num_resources	= 0,
++};
++
++static void __init at91_add_device_watchdog(void)
++{
++	platform_device_register(&at91sam9g45_wdt_device);
++}
++#else
++static void __init at91_add_device_watchdog(void) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  PWM
++ * --------------------------------------------------------------------*/
++
++#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
++static u32 pwm_mask;
++
++static struct resource pwm_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_PWMC,
++		.end	= AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_PWMC,
++		.end	= AT91SAM9G45_ID_PWMC,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_pwm0_device = {
++	.name	= "atmel_pwm",
++	.id	= -1,
++	.dev	= {
++		.platform_data		= &pwm_mask,
++	},
++	.resource	= pwm_resources,
++	.num_resources	= ARRAY_SIZE(pwm_resources),
++};
++
++void __init at91_add_device_pwm(u32 mask)
++{
++	if (mask & (1 << AT91_PWM0))
++		at91_set_B_periph(AT91_PIN_PD24, 1);	/* enable PWM0 */
++
++	if (mask & (1 << AT91_PWM1))
++		at91_set_B_periph(AT91_PIN_PD31, 1);	/* enable PWM1 */
++
++	if (mask & (1 << AT91_PWM2))
++		at91_set_B_periph(AT91_PIN_PD26, 1);	/* enable PWM2 */
++
++	if (mask & (1 << AT91_PWM3))
++		at91_set_B_periph(AT91_PIN_PD0, 1);	/* enable PWM3 */
++
++	pwm_mask = mask;
++
++	platform_device_register(&at91sam9g45_pwm0_device);
++}
++#else
++void __init at91_add_device_pwm(u32 mask) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  SSC -- Synchronous Serial Controller
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
++static u64 ssc0_dmamask = DMA_BIT_MASK(32);
++
++static struct resource ssc0_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_SSC0,
++		.end	= AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_SSC0,
++		.end	= AT91SAM9G45_ID_SSC0,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_ssc0_device = {
++	.name	= "ssc",
++	.id	= 0,
++	.dev	= {
++		.dma_mask		= &ssc0_dmamask,
++		.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++	.resource	= ssc0_resources,
++	.num_resources	= ARRAY_SIZE(ssc0_resources),
++};
++
++static inline void configure_ssc0_pins(unsigned pins)
++{
++	if (pins & ATMEL_SSC_TF)
++		at91_set_A_periph(AT91_PIN_PD1, 1);
++	if (pins & ATMEL_SSC_TK)
++		at91_set_A_periph(AT91_PIN_PD0, 1);
++	if (pins & ATMEL_SSC_TD)
++		at91_set_A_periph(AT91_PIN_PD2, 1);
++	if (pins & ATMEL_SSC_RD)
++		at91_set_A_periph(AT91_PIN_PD3, 1);
++	if (pins & ATMEL_SSC_RK)
++		at91_set_A_periph(AT91_PIN_PD4, 1);
++	if (pins & ATMEL_SSC_RF)
++		at91_set_A_periph(AT91_PIN_PD5, 1);
++}
++
++static u64 ssc1_dmamask = DMA_BIT_MASK(32);
++
++static struct resource ssc1_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_SSC1,
++		.end	= AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_SSC1,
++		.end	= AT91SAM9G45_ID_SSC1,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_ssc1_device = {
++	.name	= "ssc",
++	.id	= 1,
++	.dev	= {
++		.dma_mask		= &ssc1_dmamask,
++		.coherent_dma_mask	= DMA_BIT_MASK(32),
++	},
++	.resource	= ssc1_resources,
++	.num_resources	= ARRAY_SIZE(ssc1_resources),
++};
++
++static inline void configure_ssc1_pins(unsigned pins)
++{
++	if (pins & ATMEL_SSC_TF)
++		at91_set_A_periph(AT91_PIN_PD14, 1);
++	if (pins & ATMEL_SSC_TK)
++		at91_set_A_periph(AT91_PIN_PD12, 1);
++	if (pins & ATMEL_SSC_TD)
++		at91_set_A_periph(AT91_PIN_PD10, 1);
++	if (pins & ATMEL_SSC_RD)
++		at91_set_A_periph(AT91_PIN_PD11, 1);
++	if (pins & ATMEL_SSC_RK)
++		at91_set_A_periph(AT91_PIN_PD13, 1);
++	if (pins & ATMEL_SSC_RF)
++		at91_set_A_periph(AT91_PIN_PD15, 1);
++}
++
++/*
++ * SSC controllers are accessed through library code, instead of any
++ * kind of all-singing/all-dancing driver.  For example one could be
++ * used by a particular I2S audio codec's driver, while another one
++ * on the same system might be used by a custom data capture driver.
++ */
++void __init at91_add_device_ssc(unsigned id, unsigned pins)
++{
++	struct platform_device *pdev;
++
++	/*
++	 * NOTE: caller is responsible for passing information matching
++	 * "pins" to whatever will be using each particular controller.
++	 */
++	switch (id) {
++	case AT91SAM9G45_ID_SSC0:
++		pdev = &at91sam9g45_ssc0_device;
++		configure_ssc0_pins(pins);
++		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
++		break;
++	case AT91SAM9G45_ID_SSC1:
++		pdev = &at91sam9g45_ssc1_device;
++		configure_ssc1_pins(pins);
++		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
++		break;
++	default:
++		return;
++	}
++
++	platform_device_register(pdev);
++}
++
++#else
++void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
++#endif
++
++
++/* --------------------------------------------------------------------
++ *  UART
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SERIAL_ATMEL)
++static struct resource dbgu_resources[] = {
++	[0] = {
++		.start	= AT91_VA_BASE_SYS + AT91_DBGU,
++		.end	= AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91_ID_SYS,
++		.end	= AT91_ID_SYS,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct atmel_uart_data dbgu_data = {
++	.use_dma_tx	= 0,
++	.use_dma_rx	= 0,
++	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
++};
++
++static u64 dbgu_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device at91sam9g45_dbgu_device = {
++	.name		= "atmel_usart",
++	.id		= 0,
++	.dev		= {
++				.dma_mask		= &dbgu_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &dbgu_data,
++	},
++	.resource	= dbgu_resources,
++	.num_resources	= ARRAY_SIZE(dbgu_resources),
++};
++
++static inline void configure_dbgu_pins(void)
++{
++	at91_set_A_periph(AT91_PIN_PB12, 0);		/* DRXD */
++	at91_set_A_periph(AT91_PIN_PB13, 1);		/* DTXD */
++}
++
++static struct resource uart0_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_US0,
++		.end	= AT91SAM9G45_BASE_US0 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_US0,
++		.end	= AT91SAM9G45_ID_US0,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct atmel_uart_data uart0_data = {
++	.use_dma_tx	= 1,
++	.use_dma_rx	= 1,
++};
++
++static u64 uart0_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device at91sam9g45_uart0_device = {
++	.name		= "atmel_usart",
++	.id		= 1,
++	.dev		= {
++				.dma_mask		= &uart0_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &uart0_data,
++	},
++	.resource	= uart0_resources,
++	.num_resources	= ARRAY_SIZE(uart0_resources),
++};
++
++static inline void configure_usart0_pins(unsigned pins)
++{
++	at91_set_A_periph(AT91_PIN_PB19, 1);		/* TXD0 */
++	at91_set_A_periph(AT91_PIN_PB18, 0);		/* RXD0 */
++
++	if (pins & ATMEL_UART_RTS)
++		at91_set_B_periph(AT91_PIN_PB17, 0);	/* RTS0 */
++	if (pins & ATMEL_UART_CTS)
++		at91_set_B_periph(AT91_PIN_PB15, 0);	/* CTS0 */
++}
++
++static struct resource uart1_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_US1,
++		.end	= AT91SAM9G45_BASE_US1 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_US1,
++		.end	= AT91SAM9G45_ID_US1,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct atmel_uart_data uart1_data = {
++	.use_dma_tx	= 1,
++	.use_dma_rx	= 1,
++};
++
++static u64 uart1_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device at91sam9g45_uart1_device = {
++	.name		= "atmel_usart",
++	.id		= 2,
++	.dev		= {
++				.dma_mask		= &uart1_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &uart1_data,
++	},
++	.resource	= uart1_resources,
++	.num_resources	= ARRAY_SIZE(uart1_resources),
++};
++
++static inline void configure_usart1_pins(unsigned pins)
++{
++	at91_set_A_periph(AT91_PIN_PB4, 1);		/* TXD1 */
++	at91_set_A_periph(AT91_PIN_PB5, 0);		/* RXD1 */
++
++	if (pins & ATMEL_UART_RTS)
++		at91_set_A_periph(AT91_PIN_PD16, 0);	/* RTS1 */
++	if (pins & ATMEL_UART_CTS)
++		at91_set_A_periph(AT91_PIN_PD17, 0);	/* CTS1 */
++}
++
++static struct resource uart2_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_US2,
++		.end	= AT91SAM9G45_BASE_US2 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_US2,
++		.end	= AT91SAM9G45_ID_US2,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct atmel_uart_data uart2_data = {
++	.use_dma_tx	= 1,
++	.use_dma_rx	= 1,
++};
++
++static u64 uart2_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device at91sam9g45_uart2_device = {
++	.name		= "atmel_usart",
++	.id		= 3,
++	.dev		= {
++				.dma_mask		= &uart2_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &uart2_data,
++	},
++	.resource	= uart2_resources,
++	.num_resources	= ARRAY_SIZE(uart2_resources),
++};
++
++static inline void configure_usart2_pins(unsigned pins)
++{
++	at91_set_A_periph(AT91_PIN_PB6, 1);		/* TXD2 */
++	at91_set_A_periph(AT91_PIN_PB7, 0);		/* RXD2 */
++
++	if (pins & ATMEL_UART_RTS)
++		at91_set_B_periph(AT91_PIN_PC9, 0);	/* RTS2 */
++	if (pins & ATMEL_UART_CTS)
++		at91_set_B_periph(AT91_PIN_PC11, 0);	/* CTS2 */
++}
++
++static struct resource uart3_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_US3,
++		.end	= AT91SAM9G45_BASE_US3 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_US3,
++		.end	= AT91SAM9G45_ID_US3,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct atmel_uart_data uart3_data = {
++	.use_dma_tx	= 1,
++	.use_dma_rx	= 1,
++};
++
++static u64 uart3_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device at91sam9g45_uart3_device = {
++	.name		= "atmel_usart",
++	.id		= 4,
++	.dev		= {
++				.dma_mask		= &uart3_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &uart3_data,
++	},
++	.resource	= uart3_resources,
++	.num_resources	= ARRAY_SIZE(uart3_resources),
++};
++
++static inline void configure_usart3_pins(unsigned pins)
++{
++	at91_set_A_periph(AT91_PIN_PB8, 1);		/* TXD3 */
++	at91_set_A_periph(AT91_PIN_PB9, 0);		/* RXD3 */
++
++	if (pins & ATMEL_UART_RTS)
++		at91_set_B_periph(AT91_PIN_PA23, 0);	/* RTS3 */
++	if (pins & ATMEL_UART_CTS)
++		at91_set_B_periph(AT91_PIN_PA24, 0);	/* CTS3 */
++}
++
++static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
++struct platform_device *atmel_default_console_device;	/* the serial console device */
++
++void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
++{
++	struct platform_device *pdev;
++
++	switch (id) {
++		case 0:		/* DBGU */
++			pdev = &at91sam9g45_dbgu_device;
++			configure_dbgu_pins();
++			at91_clock_associate("mck", &pdev->dev, "usart");
++			break;
++		case AT91SAM9G45_ID_US0:
++			pdev = &at91sam9g45_uart0_device;
++			configure_usart0_pins(pins);
++			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
++			break;
++		case AT91SAM9G45_ID_US1:
++			pdev = &at91sam9g45_uart1_device;
++			configure_usart1_pins(pins);
++			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
++			break;
++		case AT91SAM9G45_ID_US2:
++			pdev = &at91sam9g45_uart2_device;
++			configure_usart2_pins(pins);
++			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
++			break;
++		case AT91SAM9G45_ID_US3:
++			pdev = &at91sam9g45_uart3_device;
++			configure_usart3_pins(pins);
++			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
++			break;
++		default:
++			return;
++	}
++	pdev->id = portnr;		/* update to mapped ID */
++
++	if (portnr < ATMEL_MAX_UART)
++		at91_uarts[portnr] = pdev;
++}
++
++void __init at91_set_serial_console(unsigned portnr)
++{
++	if (portnr < ATMEL_MAX_UART)
++		atmel_default_console_device = at91_uarts[portnr];
++}
++
++void __init at91_add_device_serial(void)
++{
++	int i;
++
++	for (i = 0; i < ATMEL_MAX_UART; i++) {
++		if (at91_uarts[i])
++			platform_device_register(at91_uarts[i]);
++	}
++
++	if (!atmel_default_console_device)
++		printk(KERN_INFO "AT91: No default serial console defined.\n");
++}
++#else
++void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
++void __init at91_set_serial_console(unsigned portnr) {}
++void __init at91_add_device_serial(void) {}
++#endif
++
++
++/* -------------------------------------------------------------------- */
++/*
++ * These devices are always present and don't need any board-specific
++ * setup.
++ */
++static int __init at91_add_standard_devices(void)
++{
++	at91_add_device_rtc();
++	at91_add_device_rtt();
++	at91_add_device_watchdog();
++	at91_add_device_tc();
++	return 0;
++}
++
++arch_initcall(at91_add_standard_devices);
+diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
+new file mode 100644
+index 0000000..b8558ea
+--- /dev/null
++++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
+@@ -0,0 +1,389 @@
++/*
++ *  Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
++ *
++ *  Covers: * AT91SAM9G45-EKES  board
++ *          * AT91SAM9M10G45-EK board
++ *
++ *  Copyright (C) 2009 Atmel Corporation.
++ *
++ * 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/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/fb.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
++#include <linux/leds.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <video/atmel_lcdc.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++#include <mach/at91_shdwc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++
++static void __init ek_map_io(void)
++{
++	/* Initialize processor: 12.000 MHz crystal */
++	at91sam9g45_initialize(12000000);
++
++	/* DGBU on ttyS0. (Rx & Tx only) */
++	at91_register_uart(0, 0, 0);
++
++	/* USART0 not connected on the -EK board */
++	/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
++	at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
++
++	/* set serial console to ttyS0 (ie, DBGU) */
++	at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++	at91sam9g45_init_interrupts(NULL);
++}
++
++
++/*
++ * USB HS Host port (common to OHCI & EHCI)
++ */
++static struct at91_usbh_data __initdata ek_usbh_hs_data = {
++	.ports		= 2,
++	.vbus_pin	= {AT91_PIN_PD1, AT91_PIN_PD3},
++};
++
++
++/*
++ * USB HS Device port
++ */
++static struct usba_platform_data __initdata ek_usba_udc_data = {
++	.vbus_pin	= AT91_PIN_PB19,
++};
++
++
++/*
++ * SPI devices.
++ */
++static struct spi_board_info ek_spi_devices[] = {
++	{	/* DataFlash chip */
++		.modalias	= "mtd_dataflash",
++		.chip_select	= 0,
++		.max_speed_hz	= 15 * 1000 * 1000,
++		.bus_num	= 0,
++	},
++};
++
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++	.phy_irq_pin	= AT91_PIN_PD5,
++	.is_rmii	= 1,
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++	{
++		.name	= "Partition 1",
++		.offset	= 0,
++		.size	= SZ_64M,
++	},
++	{
++		.name	= "Partition 2",
++		.offset	= MTDPART_OFS_NXTBLK,
++		.size	= MTDPART_SIZ_FULL,
++	},
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++	*num_partitions = ARRAY_SIZE(ek_nand_partition);
++	return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++	.ale		= 21,
++	.cle		= 22,
++	.rdy_pin	= AT91_PIN_PC8,
++	.enable_pin	= AT91_PIN_PC14,
++	.partition_info	= nand_partitions,
++#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
++	.bus_width_16	= 1,
++#else
++	.bus_width_16	= 0,
++#endif
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++	.ncs_read_setup		= 0,
++	.nrd_setup		= 2,
++	.ncs_write_setup	= 0,
++	.nwe_setup		= 2,
++
++	.ncs_read_pulse		= 4,
++	.nrd_pulse		= 4,
++	.ncs_write_pulse	= 4,
++	.nwe_pulse		= 4,
++
++	.read_cycle		= 7,
++	.write_cycle		= 7,
++
++	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
++	.tdf_cycles		= 3,
++};
++
++static void __init ek_add_device_nand(void)
++{
++	/* setup bus-width (8 or 16) */
++	if (ek_nand_data.bus_width_16)
++		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
++	else
++		ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
++
++	/* configure chip-select 3 (NAND) */
++	sam9_smc_configure(3, &ek_nand_smc_config);
++
++	at91_add_device_nand(&ek_nand_data);
++}
++
++
++/*
++ * LCD Controller
++ */
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static struct fb_videomode at91_tft_vga_modes[] = {
++	{
++		.name           = "LG",
++		.refresh	= 60,
++		.xres		= 480,		.yres		= 272,
++		.pixclock	= KHZ2PICOS(9000),
++
++		.left_margin	= 1,		.right_margin	= 1,
++		.upper_margin	= 40,		.lower_margin	= 1,
++		.hsync_len	= 45,		.vsync_len	= 1,
++
++		.sync		= 0,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++};
++
++static struct fb_monspecs at91fb_default_monspecs = {
++	.manufacturer	= "LG",
++	.monitor        = "LB043WQ1",
++
++	.modedb		= at91_tft_vga_modes,
++	.modedb_len	= ARRAY_SIZE(at91_tft_vga_modes),
++	.hfmin		= 15000,
++	.hfmax		= 17640,
++	.vfmin		= 57,
++	.vfmax		= 67,
++};
++
++#define AT91SAM9G45_DEFAULT_LCDCON2 	(ATMEL_LCDC_MEMOR_LITTLE \
++					| ATMEL_LCDC_DISTYPE_TFT \
++					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
++
++/* Driver datas */
++static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++	.lcdcon_is_backlight		= true,
++	.default_bpp			= 32,
++	.default_dmacon			= ATMEL_LCDC_DMAEN,
++	.default_lcdcon2		= AT91SAM9G45_DEFAULT_LCDCON2,
++	.default_monspecs		= &at91fb_default_monspecs,
++	.guard_time			= 9,
++	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
++};
++
++#else
++static struct atmel_lcdfb_info __initdata ek_lcdc_data;
++#endif
++
++
++/*
++ * GPIO Buttons
++ */
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++static struct gpio_keys_button ek_buttons[] = {
++	{	/* BP1, "leftclic" */
++		.code		= BTN_LEFT,
++		.gpio		= AT91_PIN_PB6,
++		.active_low	= 1,
++		.desc		= "left_click",
++		.wakeup		= 1,
++	},
++	{	/* BP2, "rightclic" */
++		.code		= BTN_RIGHT,
++		.gpio		= AT91_PIN_PB7,
++		.active_low	= 1,
++		.desc		= "right_click",
++		.wakeup		= 1,
++	},
++		/* BP3, "joystick" */
++	{
++		.code		= KEY_LEFT,
++		.gpio		= AT91_PIN_PB14,
++		.active_low	= 1,
++		.desc		= "Joystick Left",
++	},
++	{
++		.code		= KEY_RIGHT,
++		.gpio		= AT91_PIN_PB15,
++		.active_low	= 1,
++		.desc		= "Joystick Right",
++	},
++	{
++		.code		= KEY_UP,
++		.gpio		= AT91_PIN_PB16,
++		.active_low	= 1,
++		.desc		= "Joystick Up",
++	},
++	{
++		.code		= KEY_DOWN,
++		.gpio		= AT91_PIN_PB17,
++		.active_low	= 1,
++		.desc		= "Joystick Down",
++	},
++	{
++		.code		= KEY_ENTER,
++		.gpio		= AT91_PIN_PB18,
++		.active_low	= 1,
++		.desc		= "Joystick Press",
++	},
++};
++
++static struct gpio_keys_platform_data ek_button_data = {
++	.buttons	= ek_buttons,
++	.nbuttons	= ARRAY_SIZE(ek_buttons),
++};
++
++static struct platform_device ek_button_device = {
++	.name		= "gpio-keys",
++	.id		= -1,
++	.num_resources	= 0,
++	.dev		= {
++		.platform_data	= &ek_button_data,
++	}
++};
++
++static void __init ek_add_device_buttons(void)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) {
++		at91_set_GPIO_periph(ek_buttons[i].gpio, 1);
++		at91_set_deglitch(ek_buttons[i].gpio, 1);
++	}
++
++	platform_device_register(&ek_button_device);
++}
++#else
++static void __init ek_add_device_buttons(void) {}
++#endif
++
++
++/*
++ * LEDs ... these could all be PWM-driven, for variable brightness
++ */
++static struct gpio_led ek_leds[] = {
++	{	/* "top" led, red, powerled */
++		.name			= "d8",
++		.gpio			= AT91_PIN_PD30,
++		.default_trigger	= "heartbeat",
++	},
++	{	/* "left" led, green, userled2, pwm3 */
++		.name			= "d6",
++		.gpio			= AT91_PIN_PD0,
++		.active_low		= 1,
++		.default_trigger	= "nand-disk",
++	},
++#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE))
++	{	/* "right" led, green, userled1, pwm1 */
++		.name			= "d7",
++		.gpio			= AT91_PIN_PD31,
++		.active_low		= 1,
++		.default_trigger	= "mmc0",
++	},
++#endif
++};
++
++
++/*
++ * PWM Leds
++ */
++static struct gpio_led ek_pwm_led[] = {
++#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)
++	{	/* "right" led, green, userled1, pwm1 */
++		.name			= "d7",
++		.gpio			= 1,	/* is PWM channel number */
++		.active_low		= 1,
++		.default_trigger	= "none",
++	},
++#endif
++};
++
++
++
++static void __init ek_board_init(void)
++{
++	/* Serial */
++	at91_add_device_serial();
++	/* USB HS Host */
++	at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++	/* USB HS Device */
++	at91_add_device_usba(&ek_usba_udc_data);
++	/* SPI */
++	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++	/* Ethernet */
++	at91_add_device_eth(&ek_macb_data);
++	/* NAND */
++	ek_add_device_nand();
++	/* I2C */
++	at91_add_device_i2c(0, NULL, 0);
++	/* LCD Controller */
++	at91_add_device_lcdc(&ek_lcdc_data);
++	/* Push Buttons */
++	ek_add_device_buttons();
++	/* LEDs */
++	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++	at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
++}
++
++MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
++	/* Maintainer: Atmel */
++	.phys_io	= AT91_BASE_SYS,
++	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++	.boot_params	= AT91_SDRAM_BASE + 0x100,
++	.timer		= &at91sam926x_timer,
++	.map_io		= ek_map_io,
++	.init_irq	= ek_init_irq,
++	.init_machine	= ek_board_init,
++MACHINE_END
+diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
+index af64951..63c89cf 100644
+--- a/arch/arm/mach-at91/generic.h
++++ b/arch/arm/mach-at91/generic.h
+@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
+ extern void __init at91sam9261_initialize(unsigned long main_clock);
+ extern void __init at91sam9263_initialize(unsigned long main_clock);
+ extern void __init at91sam9rl_initialize(unsigned long main_clock);
++extern void __init at91sam9g45_initialize(unsigned long main_clock);
+ extern void __init at91x40_initialize(unsigned long main_clock);
+ extern void __init at91cap9_initialize(unsigned long main_clock);
+ extern void __init at572d940hf_initialize(unsigned long main_clock);
+@@ -24,6 +25,7 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
+ extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
+ extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
+ extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
++extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
+ extern void __init at91x40_init_interrupts(unsigned int priority[]);
+ extern void __init at91cap9_init_interrupts(unsigned int priority[]);
+ extern void __init at572d940hf_init_interrupts(unsigned int priority[]);
+diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
+index bf7548f..2115e6f 100644
+--- a/arch/arm/mach-at91/include/mach/board.h
++++ b/arch/arm/mach-at91/include/mach/board.h
+@@ -80,7 +80,8 @@ struct at91_eth_data {
+ };
+ extern void __init at91_add_device_eth(struct at91_eth_data *data);
+ 
+-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) || defined(CONFIG_ARCH_AT572D940HF)
++#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
++	|| defined(CONFIG_ARCH_AT91SAM9G45) || defined(CONFIG_ARCH_AT572D940HF)
+ #define eth_platform_data	at91_eth_data
+ #endif
+ 
+@@ -90,6 +91,7 @@ struct at91_usbh_data {
+ 	u8		vbus_pin[2];	/* port power-control pin */
+ };
+ extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
++extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
+ 
+  /* NAND / SmartMedia */
+ struct atmel_nand_data {
+@@ -105,7 +107,11 @@ struct atmel_nand_data {
+ extern void __init at91_add_device_nand(struct atmel_nand_data *data);
+ 
+  /* I2C*/
++#if defined(CONFIG_ARCH_AT91SAM9G45)
++extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices);
++#else
+ extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
++#endif
+ 
+  /* SPI */
+ extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index bd6e9f2..f839256 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -219,7 +219,7 @@ config MII
+ 
+ config MACB
+ 	tristate "Atmel MACB support"
+-	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_AT572D940HF
++	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || ARCH_AT572D940HF
+ 	select PHYLIB
+ 	help
+ 	  The Atmel MACB ethernet interface is found on many AT32 and AT91
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 26d6a3a..a9d37ec 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -944,7 +944,7 @@ config FB_S1D13XXX
+ 
+ config FB_ATMEL
+ 	tristate "AT91/AT32 LCD Controller support"
+-	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32)
++	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+-- 
+1.5.6.5
+
+From 48e878c69ff34de6f7a423dfe6a7b3e5f843a631 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:26 +0000
+Subject: [PATCH] ARM: 5622/1: at91: at91sam9g45 headers: DMA peripheral identifiers
+
+It adds DMA peripheral identifiers for hardware handshaking interface. It will
+be used in platform code.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+(cherry picked from commit 4c8abb556b393b3ed73d72481ba27705294f6dc6)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11584 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/include/mach/at91sam9g45.h |   17 +++++++++++++++++
+ 1 files changed, 17 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
+index 2c42cf5..a526869 100644
+--- a/arch/arm/mach-at91/include/mach/at91sam9g45.h
++++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
+@@ -135,4 +135,21 @@
+ 
+ #define CONSISTENT_DMA_SIZE	SZ_4M
+ 
++/*
++ * DMA peripheral identifiers
++ * for hardware handshaking interface
++ */
++#define AT_DMA_ID_MCI0		 0
++#define AT_DMA_ID_SPI0_TX	 1
++#define AT_DMA_ID_SPI0_RX	 2
++#define AT_DMA_ID_SPI1_TX	 3
++#define AT_DMA_ID_SPI1_RX	 4
++#define AT_DMA_ID_SSC0_TX	 5
++#define AT_DMA_ID_SSC0_RX	 6
++#define AT_DMA_ID_SSC1_TX	 7
++#define AT_DMA_ID_SSC1_RX	 8
++#define AT_DMA_ID_AC97_TX	 9
++#define AT_DMA_ID_AC97_RX	10
++#define AT_DMA_ID_MCI1		13
++
+ #endif
+-- 
+1.5.6.5
+
+From 5eb1026a6148d3ea207b3fdf33b2eef8152819f5 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:26 +0000
+Subject: [PATCH] 5567/1: at91: Support for at91sam9g10: clocks management
+
+Add the at91sam9g10 support to the AT91 generic clock file. It takes
+advantage of the management by functionalities of those PLLs and clocks.
+
+Signed-off-by: Hong Xu <hong.xu at atmel.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11585 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/clock.c |    6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
+index b83bfad..7558626 100644
+--- a/arch/arm/mach-at91/clock.c
++++ b/arch/arm/mach-at91/clock.c
+@@ -54,7 +54,7 @@
+ #define cpu_has_800M_plla()	(  cpu_is_at91sam9g20() \
+ 				|| cpu_is_at91sam9g45())
+ 
+-#define cpu_has_300M_plla()	(0)
++#define cpu_has_300M_plla()	(cpu_is_at91sam9g10())
+ 
+ #define cpu_has_pllb()		(!(cpu_is_at91sam9rl() \
+ 				|| cpu_is_at91sam9g45()))
+@@ -644,7 +644,9 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
+ 		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
+ 		udpck.pmc_mask = AT91RM9200_PMC_UDP;
+ 		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
+-	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at572d940hf()) {
++	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
++		   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
++		   cpu_is_at572d940hf() || cpu_is_at91sam9g10()) {
+ 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+ 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
+ 	} else if (cpu_is_at91cap9()) {
+-- 
+1.5.6.5
+
+From 05f67011adcd31598260dce2bc9aed335969bd9c Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:27 +0000
+Subject: [PATCH] 5568/1: at91: Basic support for at91sam9g10: header files
+
+AT91sam9g10 is an ARM 926ej-s SOC. It is an evolution of the at91sam9261 with a
+faster clock speed: 266/133MHz.
+
+Here is the basic header file support for this product.
+
+Signed-off-by: Hong Xu <hong.xu at atmel.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+(cherry picked from commit b784b7c03723891876c9053c589150a4062f9455)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11586 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/include/mach/at91sam9261.h |    3 +++
+ arch/arm/mach-at91/include/mach/cpu.h         |    7 +++++++
+ arch/arm/mach-at91/include/mach/hardware.h    |    2 +-
+ arch/arm/mach-at91/include/mach/timex.h       |    5 +++++
+ 4 files changed, 16 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
+index 3a348ca..87de8be 100644
+--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
++++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
+@@ -95,6 +95,9 @@
+ #define AT91SAM9261_SRAM_BASE	0x00300000	/* Internal SRAM base address */
+ #define AT91SAM9261_SRAM_SIZE	0x00028000	/* Internal SRAM size (160Kb) */
+ 
++#define AT91SAM9G10_SRAM_BASE	AT91SAM9261_SRAM_BASE	/* Internal SRAM base address */
++#define AT91SAM9G10_SRAM_SIZE	0x00004000	/* Internal SRAM size (16Kb) */
++
+ #define AT91SAM9261_ROM_BASE	0x00400000	/* Internal ROM base address */
+ #define AT91SAM9261_ROM_SIZE	SZ_32K		/* Internal ROM size (32Kb) */
+ 
+diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
+index 64af079..6d8c1b9 100644
+--- a/arch/arm/mach-at91/include/mach/cpu.h
++++ b/arch/arm/mach-at91/include/mach/cpu.h
+@@ -21,6 +21,7 @@
+ #define ARCH_ID_AT91SAM9260	0x019803a0
+ #define ARCH_ID_AT91SAM9261	0x019703a0
+ #define ARCH_ID_AT91SAM9263	0x019607a0
++#define ARCH_ID_AT91SAM9G10	0x819903a0
+ #define ARCH_ID_AT91SAM9G20	0x019905a0
+ #define ARCH_ID_AT91SAM9RL64	0x019b03a0
+ #define ARCH_ID_AT91SAM9G45	0x819b05a0
+@@ -99,6 +100,12 @@ static inline unsigned long at91cap9_rev_identify(void)
+ #define cpu_is_at91sam9261()	(0)
+ #endif
+ 
++#ifdef CONFIG_ARCH_AT91SAM9G10
++#define cpu_is_at91sam9g10()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G10)
++#else
++#define cpu_is_at91sam9g10()	(0)
++#endif
++
+ #ifdef CONFIG_ARCH_AT91SAM9263
+ #define cpu_is_at91sam9263()	(at91_cpu_identify() == ARCH_ID_AT91SAM9263)
+ #else
+diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
+index a747d37..3d64a75 100644
+--- a/arch/arm/mach-at91/include/mach/hardware.h
++++ b/arch/arm/mach-at91/include/mach/hardware.h
+@@ -20,7 +20,7 @@
+ #include <mach/at91rm9200.h>
+ #elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
+ #include <mach/at91sam9260.h>
+-#elif defined(CONFIG_ARCH_AT91SAM9261)
++#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)
+ #include <mach/at91sam9261.h>
+ #elif defined(CONFIG_ARCH_AT91SAM9263)
+ #include <mach/at91sam9263.h>
+diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
+index 5abdf73..a83bcc6 100644
+--- a/arch/arm/mach-at91/include/mach/timex.h
++++ b/arch/arm/mach-at91/include/mach/timex.h
+@@ -42,6 +42,11 @@
+ #define AT91SAM9_MASTER_CLOCK	99300000
+ #define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
+ 
++#elif defined(CONFIG_ARCH_AT91SAM9G10)
++
++#define AT91SAM9_MASTER_CLOCK	133000000
++#define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
++
+ #elif defined(CONFIG_ARCH_AT91SAM9263)
+ 
+ #if defined(CONFIG_MACH_USB_A9263)
+-- 
+1.5.6.5
+
+From 2510f55eae021e236cbe3f213de234d154f45849 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:28 +0000
+Subject: [PATCH] 5570/1: at91: Support for at91sam9g10: core chip & board support
+
+Here are the modification to at91sam9261 files dedicated to the support of
+at91sam9g10. This direction has been adopted to minimize code duplication.
+
+All at91sam9261 drivers are enabled in _devices and board- files. Modificaton
+to peripherals that support at91sam9g10 will be added in future patches.
+
+Signed-off-by: Hong Xu <hong.xu at atmel.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11587 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/Kconfig           |   25 +++++++++++++++++++++++--
+ arch/arm/mach-at91/Makefile          |    2 ++
+ arch/arm/mach-at91/at91sam9261.c     |   22 +++++++++++++++++++++-
+ arch/arm/mach-at91/board-sam9261ek.c |   14 ++++++++++++++
+ arch/arm/mach-at91/pm.c              |    3 ++-
+ 5 files changed, 62 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index 6ea88b4..e844fde 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -23,6 +23,12 @@ config ARCH_AT91SAM9261
+ 	select GENERIC_TIME
+ 	select GENERIC_CLOCKEVENTS
+ 
++config ARCH_AT91SAM9G10
++	bool "AT91SAM9G10"
++	select CPU_ARM926T
++	select GENERIC_TIME
++	select GENERIC_CLOCKEVENTS
++
+ config ARCH_AT91SAM9263
+ 	bool "AT91SAM9263"
+ 	select CPU_ARM926T
+@@ -274,6 +280,21 @@ endif
+ 
+ # ----------------------------------------------------------
+ 
++if ARCH_AT91SAM9G10
++
++comment "AT91SAM9G10 Board Type"
++
++config MACH_AT91SAM9G10EK
++	bool "Atmel AT91SAM9G10-EK Evaluation Kit"
++	depends on ARCH_AT91SAM9G10
++	help
++	  Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
++	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
++
++endif
++
++# ----------------------------------------------------------
++
+ if ARCH_AT91SAM9263
+ 
+ comment "AT91SAM9263 Board Type"
+@@ -431,13 +452,13 @@ comment "AT91 Board Options"
+ 
+ config MTD_AT91_DATAFLASH_CARD
+ 	bool "Enable DataFlash Card support"
+-	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_AT572D940HFEB || MACH_TOTEMNOVA || MACH_NEOCORE926)
++	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_AT572D940HFEB || MACH_TOTEMNOVA || MACH_NEOCORE926)
+ 	help
+ 	  Enable support for the DataFlash card.
+ 
+ config MTD_NAND_ATMEL_BUSWIDTH_16
+ 	bool "Enable 16-bit data bus interface to NAND flash"
+-	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK || MACH_AT572D940HFEB)
++	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK || MACH_AT572D940HFEB)
+ 	help
+ 	  On AT91SAM926x boards both types of NAND flash can be present
+ 	  (8 and 16 bit data bus width).
+diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
+index cf31340..56c6381 100644
+--- a/arch/arm/mach-at91/Makefile
++++ b/arch/arm/mach-at91/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_AT91_PMC_UNIT)	+= clock.o
+ obj-$(CONFIG_ARCH_AT91RM9200)	+= at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
+ obj-$(CONFIG_ARCH_AT91SAM9260)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
++obj-$(CONFIG_ARCH_AT91SAM9G10)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
+@@ -50,6 +51,7 @@ obj-$(CONFIG_MACH_AFEB9260)	+= board-afeb-9260v1.o
+ 
+ # AT91SAM9261 board-specific support
+ obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
++obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o
+ 
+ # AT91SAM9263 board-specific support
+ obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
+diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
+index 3acd7d7..4ecf379 100644
+--- a/arch/arm/mach-at91/at91sam9261.c
++++ b/arch/arm/mach-at91/at91sam9261.c
+@@ -16,6 +16,7 @@
+ #include <asm/irq.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
++#include <mach/cpu.h>
+ #include <mach/at91sam9261.h>
+ #include <mach/at91_pmc.h>
+ #include <mach/at91_rstc.h>
+@@ -30,7 +31,11 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
+ 		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+ 		.length		= SZ_16K,
+ 		.type		= MT_DEVICE,
+-	}, {
++	},
++};
++
++static struct map_desc at91sam9261_sram_desc[] __initdata = {
++	{
+ 		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
+ 		.pfn		= __phys_to_pfn(AT91SAM9261_SRAM_BASE),
+ 		.length		= AT91SAM9261_SRAM_SIZE,
+@@ -38,6 +43,15 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
+ 	},
+ };
+ 
++static struct map_desc at91sam9g10_sram_desc[] __initdata = {
++	{
++		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,
++		.pfn		= __phys_to_pfn(AT91SAM9G10_SRAM_BASE),
++		.length		= AT91SAM9G10_SRAM_SIZE,
++		.type		= MT_DEVICE,
++	},
++};
++
+ /* --------------------------------------------------------------------
+  *  Clocks
+  * -------------------------------------------------------------------- */
+@@ -263,6 +277,12 @@ void __init at91sam9261_initialize(unsigned long main_clock)
+ 	/* Map peripherals */
+ 	iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
+ 
++	if (cpu_is_at91sam9g10())
++		iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
++	else
++		iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
++
++
+ 	at91_arch_reset = at91sam9261_reset;
+ 	pm_power_off = at91sam9261_poweroff;
+ 	at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
+diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
+index 9d82c22..8bcd631 100644
+--- a/arch/arm/mach-at91/board-sam9261ek.c
++++ b/arch/arm/mach-at91/board-sam9261ek.c
+@@ -288,7 +288,11 @@ static void __init ek_add_device_ts(void) {}
+  */
+ static struct at73c213_board_info at73c213_data = {
+ 	.ssc_id		= 1,
++#if defined(CONFIG_MACH_AT91SAM9261EK)
+ 	.shortname	= "AT91SAM9261-EK external DAC",
++#else
++	.shortname	= "AT91SAM9G10-EK external DAC",
++#endif
+ };
+ 
+ #if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+@@ -415,6 +419,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ 	.default_monspecs		= &at91fb_default_stn_monspecs,
+ 	.atmel_lcdfb_power_control	= at91_lcdc_stn_power_control,
+ 	.guard_time			= 1,
++#if defined(CONFIG_MACH_AT91SAM9G10EK)
++	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
++#endif
+ };
+ 
+ #else
+@@ -468,6 +475,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ 	.default_monspecs		= &at91fb_default_tft_monspecs,
+ 	.atmel_lcdfb_power_control	= at91_lcdc_tft_power_control,
+ 	.guard_time			= 1,
++#if defined(CONFIG_MACH_AT91SAM9G10EK)
++	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
++#endif
+ };
+ #endif
+ 
+@@ -604,7 +614,11 @@ static void __init ek_board_init(void)
+ 				| AT91_SHDW_RTTWKEN);
+ }
+ 
++#if defined(CONFIG_MACH_AT91SAM9261EK)
+ MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
++#else
++MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
++#endif
+ 	/* Maintainer: Atmel */
+ 	.phys_io	= AT91_BASE_SYS,
+ 	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
+index 3e2a815..242ba6e 100644
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -202,7 +202,8 @@ static int at91_pm_verify_clocks(void)
+ 			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ 			return 0;
+ 		}
+-	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
++	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
++			|| cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
+ 		if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
+ 			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ 			return 0;
+-- 
+1.5.6.5
+
+From 1d41541e67387248947fe3140cb1890b7d88d562 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:28 +0000
+Subject: [PATCH] 5614/1: at91: atmel_lcdfb: add at91sam9g10 support to atmel LCD driver
+
+Modify atmel LCD driver: atmel_lcdfb for at91sam9g10.  This add a clock
+management equivalent to at91sam9261.
+
+Signed-off-by: Hong Xu <hong.xu at atmel.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Andrew Victor <linux at maxim.org.za>
+Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
+(cherry picked from commit 915190f7d4f08e413e5fde6b0abcd5375aeacdf4)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11588 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/video/Kconfig           |    4 ++--
+ drivers/video/atmel_lcdfb.c     |    6 ++++--
+ drivers/video/backlight/Kconfig |    2 +-
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index a9d37ec..d96fd5b 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -944,7 +944,7 @@ config FB_S1D13XXX
+ 
+ config FB_ATMEL
+ 	tristate "AT91/AT32 LCD Controller support"
+-	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32)
++	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+@@ -960,7 +960,7 @@ config FB_INTSRAM
+ 
+ config FB_ATMEL_STN
+ 	bool "Use a STN display with AT91/AT32 LCD Controller"
+-	depends on FB_ATMEL && MACH_AT91SAM9261EK
++	depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
+ 	default n
+ 	help
+ 	  Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
+diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
+index 9eb1f69..a476a0e 100644
+--- a/drivers/video/atmel_lcdfb.c
++++ b/drivers/video/atmel_lcdfb.c
+@@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
+ {
+ 	unsigned long value;
+ 
+-	if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000()))
++	if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10()
++		|| cpu_is_at32ap7000()))
+ 		return xres;
+ 
+ 	value = xres;
+@@ -821,7 +822,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
+ 	info->fix = atmel_lcdfb_fix;
+ 
+ 	/* Enable LCDC Clocks */
+-	if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) {
++	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()
++	 || cpu_is_at32ap7000()) {
+ 		sinfo->bus_clk = clk_get(dev, "hck1");
+ 		if (IS_ERR(sinfo->bus_clk)) {
+ 			ret = PTR_ERR(sinfo->bus_clk);
+diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
+index ed7ecb4..983451e 100644
+--- a/drivers/video/backlight/Kconfig
++++ b/drivers/video/backlight/Kconfig
+@@ -110,7 +110,7 @@ config BACKLIGHT_CLASS_DEVICE
+ config BACKLIGHT_ATMEL_LCDC
+ 	bool "Atmel LCDC Contrast-as-Backlight control"
+ 	depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL
+-	default y if MACH_SAM9261EK || MACH_SAM9263EK
++	default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK
+ 	help
+ 	  This provides a backlight control internal to the Atmel LCDC
+ 	  driver.  If the LCD "contrast control" on your board is wired
+-- 
+1.5.6.5
+
+From 772debf26a13f0f68efa34a1ce87168bee0337ac Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:29 +0000
+Subject: [PATCH] USB: at91: Add USB EHCI driver for at91sam9g45 series
+
+Add host USB High speed driver for at91sam9g45 series.
+The host driver is an EHCI with its companion OHCI. EHCI is
+handled by the new ehci-atmel.c whereas the OHCI is always
+handled by ohci-at91.c.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: David Brownell <dbrownell at users.sourceforge.net>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11589 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/usb/Kconfig           |    1 +
+ drivers/usb/host/ehci-atmel.c |  230 +++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/ehci-hcd.c   |    5 +
+ 3 files changed, 236 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/usb/host/ehci-atmel.c
+
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index c6c816b..3974c9c 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -57,6 +57,7 @@ config USB_ARCH_HAS_EHCI
+ 	default y if PPC_83xx
+ 	default y if SOC_AU1200
+ 	default y if ARCH_IXP4XX
++	default y if ARCH_AT91SAM9G45
+ 	default PCI
+ 
+ # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
+diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
+new file mode 100644
+index 0000000..87c1b7c
+--- /dev/null
++++ b/drivers/usb/host/ehci-atmel.c
+@@ -0,0 +1,230 @@
++/*
++ * Driver for EHCI UHP on Atmel chips
++ *
++ *  Copyright (C) 2009 Atmel Corporation,
++ *                     Nicolas Ferre <nicolas.ferre at atmel.com>
++ *
++ *  Based on various ehci-*.c drivers
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file COPYING in the main directory of this archive for
++ * more details.
++ */
++
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++
++/* interface and function clocks */
++static struct clk *iclk, *fclk;
++static int clocked;
++
++/*-------------------------------------------------------------------------*/
++
++static void atmel_start_clock(void)
++{
++	clk_enable(iclk);
++	clk_enable(fclk);
++	clocked = 1;
++}
++
++static void atmel_stop_clock(void)
++{
++	clk_disable(fclk);
++	clk_disable(iclk);
++	clocked = 0;
++}
++
++static void atmel_start_ehci(struct platform_device *pdev)
++{
++	dev_dbg(&pdev->dev, "start\n");
++	atmel_start_clock();
++}
++
++static void atmel_stop_ehci(struct platform_device *pdev)
++{
++	dev_dbg(&pdev->dev, "stop\n");
++	atmel_stop_clock();
++}
++
++/*-------------------------------------------------------------------------*/
++
++static int ehci_atmel_setup(struct usb_hcd *hcd)
++{
++	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++	int retval = 0;
++
++	/* registers start at offset 0x0 */
++	ehci->caps = hcd->regs;
++	ehci->regs = hcd->regs +
++		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
++	dbg_hcs_params(ehci, "reset");
++	dbg_hcc_params(ehci, "reset");
++
++	/* cache this readonly data; minimize chip reads */
++	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
++
++	retval = ehci_halt(ehci);
++	if (retval)
++		return retval;
++
++	/* data structure init */
++	retval = ehci_init(hcd);
++	if (retval)
++		return retval;
++
++	ehci->sbrn = 0x20;
++
++	ehci_reset(ehci);
++	ehci_port_power(ehci, 0);
++
++	return retval;
++}
++
++static const struct hc_driver ehci_atmel_hc_driver = {
++	.description		= hcd_name,
++	.product_desc		= "Atmel EHCI UHP HS",
++	.hcd_priv_size		= sizeof(struct ehci_hcd),
++
++	/* generic hardware linkage */
++	.irq			= ehci_irq,
++	.flags			= HCD_MEMORY | HCD_USB2,
++
++	/* basic lifecycle operations */
++	.reset			= ehci_atmel_setup,
++	.start			= ehci_run,
++	.stop			= ehci_stop,
++	.shutdown		= ehci_shutdown,
++
++	/* managing i/o requests and associated device resources */
++	.urb_enqueue		= ehci_urb_enqueue,
++	.urb_dequeue		= ehci_urb_dequeue,
++	.endpoint_disable	= ehci_endpoint_disable,
++
++	/* scheduling support */
++	.get_frame_number	= ehci_get_frame,
++
++	/* root hub support */
++	.hub_status_data	= ehci_hub_status_data,
++	.hub_control		= ehci_hub_control,
++	.bus_suspend		= ehci_bus_suspend,
++	.bus_resume		= ehci_bus_resume,
++	.relinquish_port	= ehci_relinquish_port,
++	.port_handed_over	= ehci_port_handed_over,
++};
++
++static int __init ehci_atmel_drv_probe(struct platform_device *pdev)
++{
++	struct usb_hcd *hcd;
++	const struct hc_driver *driver = &ehci_atmel_hc_driver;
++	struct resource *res;
++	int irq;
++	int retval;
++
++	if (usb_disabled())
++		return -ENODEV;
++
++	pr_debug("Initializing Atmel-SoC USB Host Controller\n");
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq <= 0) {
++		dev_err(&pdev->dev,
++			"Found HC with no IRQ. Check %s setup!\n",
++			dev_name(&pdev->dev));
++		retval = -ENODEV;
++		goto fail_create_hcd;
++	}
++
++	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
++	if (!hcd) {
++		retval = -ENOMEM;
++		goto fail_create_hcd;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev,
++			"Found HC with no register addr. Check %s setup!\n",
++			dev_name(&pdev->dev));
++		retval = -ENODEV;
++		goto fail_request_resource;
++	}
++	hcd->rsrc_start = res->start;
++	hcd->rsrc_len = res->end - res->start + 1;
++
++	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
++				driver->description)) {
++		dev_dbg(&pdev->dev, "controller already in use\n");
++		retval = -EBUSY;
++		goto fail_request_resource;
++	}
++
++	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
++	if (hcd->regs == NULL) {
++		dev_dbg(&pdev->dev, "error mapping memory\n");
++		retval = -EFAULT;
++		goto fail_ioremap;
++	}
++
++	iclk = clk_get(&pdev->dev, "ehci_clk");
++	if (IS_ERR(iclk)) {
++		dev_err(&pdev->dev, "Error getting interface clock\n");
++		retval = -ENOENT;
++		goto fail_get_iclk;
++	}
++	fclk = clk_get(&pdev->dev, "uhpck");
++	if (IS_ERR(fclk)) {
++		dev_err(&pdev->dev, "Error getting function clock\n");
++		retval = -ENOENT;
++		goto fail_get_fclk;
++	}
++
++	atmel_start_ehci(pdev);
++
++	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
++	if (retval)
++		goto fail_add_hcd;
++
++	return retval;
++
++fail_add_hcd:
++	atmel_stop_ehci(pdev);
++	clk_put(fclk);
++fail_get_fclk:
++	clk_put(iclk);
++fail_get_iclk:
++	iounmap(hcd->regs);
++fail_ioremap:
++	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++fail_request_resource:
++	usb_put_hcd(hcd);
++fail_create_hcd:
++	dev_err(&pdev->dev, "init %s fail, %d\n",
++		dev_name(&pdev->dev), retval);
++
++	return retval;
++}
++
++static int __exit ehci_atmel_drv_remove(struct platform_device *pdev)
++{
++	struct usb_hcd *hcd = platform_get_drvdata(pdev);
++
++	ehci_shutdown(hcd);
++	usb_remove_hcd(hcd);
++	iounmap(hcd->regs);
++	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++	usb_put_hcd(hcd);
++
++	atmel_stop_ehci(pdev);
++	clk_put(fclk);
++	clk_put(iclk);
++	fclk = iclk = NULL;
++
++	return 0;
++}
++
++static struct platform_driver ehci_atmel_driver = {
++	.probe		= ehci_atmel_drv_probe,
++	.remove		= __exit_p(ehci_atmel_drv_remove),
++	.shutdown	= usb_hcd_platform_shutdown,
++	.driver.name	= "atmel-ehci",
++};
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index c637207..df2ddee 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -1072,6 +1072,11 @@ MODULE_LICENSE ("GPL");
+ #define	PLATFORM_DRIVER		ixp4xx_ehci_driver
+ #endif
+ 
++#ifdef CONFIG_ARCH_AT91
++#include "ehci-atmel.c"
++#define	PLATFORM_DRIVER		ehci_atmel_driver
++#endif
++
+ #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
+     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
+ #error "missing bus glue for ehci-hcd"
+-- 
+1.5.6.5
+
+From 3cf2f721729dac671daee96ca5936306c5927b4e Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:30 +0000
+Subject: [PATCH] USB: at91: Add USB gadget driver selection for at91sam9g45 series
+
+Add gadget USB drivers for at91sam9g45 series. Those SOC include
+high speed USB interfaces.
+The gadget driver is the already available atmel_usba_udc.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: David Brownell <dbrownell at users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+(cherry picked from commit 1c4e0601643c49cd24920f8860920f990feb2b54)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11590 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/usb/gadget/Kconfig |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 080bb1e..9beea52 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -124,7 +124,7 @@ choice
+ 
+ config USB_GADGET_AT91
+ 	boolean "Atmel AT91 USB Device Port"
+-	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
++	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45
+ 	select USB_GADGET_SELECTED
+ 	help
+ 	   Many Atmel AT91 processors (such as the AT91RM2000) have a
+@@ -143,7 +143,7 @@ config USB_AT91
+ config USB_GADGET_ATMEL_USBA
+ 	boolean "Atmel USBA"
+ 	select USB_GADGET_DUALSPEED
+-	depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL
++	depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+ 	help
+ 	  USBA is the integrated high-speed USB Device controller on
+ 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
+-- 
+1.5.6.5
+
+From 50a9f81974a6044756a4990eea45a7622c74f9ae Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:31 +0000
+Subject: [PATCH] USB: at91: modify OHCI driver to allow shared interrupts
+
+At91sam9g45 series has a set of high speed USB interfaces.
+The host driver is an EHCI with its companion OHCI. OHCI is
+always handled by ohci-at91.c.
+This wrapper is just modified to allow IRQ sharing
+between two controllers.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: David Brownell <dbrownell at users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+(cherry picked from commit f1c0a47a57ebbb59f22261c88e17953a34007f36)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11591 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/usb/host/ohci-at91.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
+index b6fee5a..df96772 100644
+--- a/drivers/usb/host/ohci-at91.c
++++ b/drivers/usb/host/ohci-at91.c
+@@ -148,7 +148,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
+ 	at91_start_hc(pdev);
+ 	ohci_hcd_init(hcd_to_ohci(hcd));
+ 
+-	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
++	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
+ 	if (retval == 0)
+ 		return retval;
+ 
+-- 
+1.5.6.5
+
+From e7035127767c5f996f8f69d021b7436d9fb2dd56 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:31 +0000
+Subject: [PATCH] at91/USB: at91sam9g45 series USB host integration
+
+This is the at91 specific part of USB host integration. The EHCI high speed
+controller has a companion OHCI controller to manage USB full and low speed.
+They are sharing the same IRQ line and vbus pin.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11592 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9g45_devices.c |   56 ++++++++++++++++++++++++++++++
+ arch/arm/mach-at91/board-sam9m10g45ek.c  |    1 +
+ arch/arm/mach-at91/include/mach/board.h  |    1 +
+ 3 files changed, 58 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index d746e86..c2ecbb6 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -83,6 +83,62 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  USB Host HS (EHCI)
++ *  Needs an OHCI host for low and full speed management
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
++static u64 ehci_dmamask = DMA_BIT_MASK(32);
++static struct at91_usbh_data usbh_ehci_data;
++
++static struct resource usbh_ehci_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_EHCI_BASE,
++		.end	= AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_UHPHS,
++		.end	= AT91SAM9G45_ID_UHPHS,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91_usbh_ehci_device = {
++	.name		= "atmel-ehci",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &ehci_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &usbh_ehci_data,
++	},
++	.resource	= usbh_ehci_resources,
++	.num_resources	= ARRAY_SIZE(usbh_ehci_resources),
++};
++
++void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
++{
++	int i;
++
++	if (!data)
++		return;
++
++	/* Enable VBus control for UHP ports */
++	for (i = 0; i < data->ports; i++) {
++		if (data->vbus_pin[i])
++			at91_set_gpio_output(data->vbus_pin[i], 0);
++	}
++
++	usbh_ehci_data = *data;
++	at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk");
++	platform_device_register(&at91_usbh_ehci_device);
++}
++#else
++void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+  *  USB HS Device (Gadget)
+  * -------------------------------------------------------------------- */
+ 
+diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
+index b8558ea..d7251b7 100644
+--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
++++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
+@@ -358,6 +358,7 @@ static void __init ek_board_init(void)
+ 	at91_add_device_serial();
+ 	/* USB HS Host */
+ 	at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++	at91_add_device_usbh_ehci(&ek_usbh_hs_data);
+ 	/* USB HS Device */
+ 	at91_add_device_usba(&ek_usba_udc_data);
+ 	/* SPI */
+diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
+index 2115e6f..ce31746 100644
+--- a/arch/arm/mach-at91/include/mach/board.h
++++ b/arch/arm/mach-at91/include/mach/board.h
+@@ -92,6 +92,7 @@ struct at91_usbh_data {
+ };
+ extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
+ extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
++extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
+ 
+  /* NAND / SmartMedia */
+ struct atmel_nand_data {
+-- 
+1.5.6.5
+
+From 0c057d0c0b3ea72e5b4e75e31b3ac689e99418f6 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:32 +0000
+Subject: [PATCH] at91/USB: USB drivers modifications for at91sam9g10
+
+Modify both host and gadget USB drivers for at91sam9g10.
+This add a clock management equivalent to at91sam9261 on usb drivers.
+It also add the way of handling gadget pull-ups (like the at91sam9261).
+
+Signed-off-by: Hong Xu <hong.xu at atmel.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11593 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/usb/gadget/at91_udc.c |    6 +++---
+ drivers/usb/host/ohci-at91.c  |   10 +++++-----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
+index da05291..fc13ad5 100644
+--- a/drivers/usb/gadget/at91_udc.c
++++ b/drivers/usb/gadget/at91_udc.c
+@@ -892,7 +892,7 @@ static void pullup(struct at91_udc *udc, int is_on)
+ 
+ 			txvc |= AT91_UDP_TXVC_PUON;
+ 			at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+-		} else if (cpu_is_at91sam9261()) {
++		} else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
+ 			u32	usbpucr;
+ 
+ 			usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+@@ -910,7 +910,7 @@ static void pullup(struct at91_udc *udc, int is_on)
+ 
+ 			txvc &= ~AT91_UDP_TXVC_PUON;
+ 			at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+-		} else if (cpu_is_at91sam9261()) {
++		} else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
+ 			u32	usbpucr;
+ 
+ 			usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+@@ -1692,7 +1692,7 @@ static int __init at91udc_probe(struct platform_device *pdev)
+ 		udc->ep[3].maxpacket = 64;
+ 		udc->ep[4].maxpacket = 512;
+ 		udc->ep[5].maxpacket = 512;
+-	} else if (cpu_is_at91sam9261()) {
++	} else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
+ 		udc->ep[3].maxpacket = 64;
+ 	} else if (cpu_is_at91sam9263()) {
+ 		udc->ep[0].maxpacket = 64;
+diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
+index df96772..e033a47 100644
+--- a/drivers/usb/host/ohci-at91.c
++++ b/drivers/usb/host/ohci-at91.c
+@@ -35,7 +35,7 @@ extern int usb_disabled(void);
+ 
+ static void at91_start_clock(void)
+ {
+-	if (cpu_is_at91sam9261())
++	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
+ 		clk_enable(hclk);
+ 	clk_enable(iclk);
+ 	clk_enable(fclk);
+@@ -46,7 +46,7 @@ static void at91_stop_clock(void)
+ {
+ 	clk_disable(fclk);
+ 	clk_disable(iclk);
+-	if (cpu_is_at91sam9261())
++	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
+ 		clk_disable(hclk);
+ 	clocked = 0;
+ }
+@@ -142,7 +142,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
+ 
+ 	iclk = clk_get(&pdev->dev, "ohci_clk");
+ 	fclk = clk_get(&pdev->dev, "uhpck");
+-	if (cpu_is_at91sam9261())
++	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
+ 		hclk = clk_get(&pdev->dev, "hck0");
+ 
+ 	at91_start_hc(pdev);
+@@ -155,7 +155,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
+ 	/* Error handling */
+ 	at91_stop_hc(pdev);
+ 
+-	if (cpu_is_at91sam9261())
++	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
+ 		clk_put(hclk);
+ 	clk_put(fclk);
+ 	clk_put(iclk);
+@@ -192,7 +192,7 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+ 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ 	usb_put_hcd(hcd);
+ 
+-	if (cpu_is_at91sam9261())
++	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
+ 		clk_put(hclk);
+ 	clk_put(fclk);
+ 	clk_put(iclk);
+-- 
+1.5.6.5
+
+From c9d06e72b78ca59549eb500078cb8f2de62dab8f Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:33 +0000
+Subject: [PATCH] dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller
+
+This AHB DMA Controller (aka HDMA or DMAC on AT91 systems) is availlable on
+at91sam9rl chip. It will be used on other products in the future.
+
+This first release covers only the memory-to-memory tranfer type. This is the
+only tranfer type supported by this chip.  On other products, it will be used
+also for peripheral DMA transfer (slave API support to come).
+
+I used dmatest client without problem in different configurations to test it.
+
+Full documentation for this controller can be found in the SAM9RL datasheet:
+http://www.atmel.com/dyn/products/product_card.asp?part_id=4243
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Maciej Sosnowski <maciej.sosnowski at intel.com>
+Signed-off-by: Dan Williams <dan.j.williams at intel.com>
+(cherry picked from commit dc78baa2b90b289590911b40b6800f77d0dc935a)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11594 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/include/mach/at_hdmac.h |   26 +
+ drivers/dma/Kconfig                        |    8 +
+ drivers/dma/Makefile                       |    1 +
+ drivers/dma/at_hdmac.c                     | 1009 ++++++++++++++++++++++++++++
+ drivers/dma/at_hdmac_regs.h                |  386 +++++++++++
+ 5 files changed, 1430 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-at91/include/mach/at_hdmac.h
+ create mode 100644 drivers/dma/at_hdmac.c
+ create mode 100644 drivers/dma/at_hdmac_regs.h
+
+diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h
+new file mode 100644
+index 0000000..21a5554
+--- /dev/null
++++ b/arch/arm/mach-at91/include/mach/at_hdmac.h
+@@ -0,0 +1,26 @@
++/*
++ * Header file for the Atmel AHB DMA Controller driver
++ *
++ * Copyright (C) 2008 Atmel Corporation
++ *
++ * 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 AT_HDMAC_H
++#define AT_HDMAC_H
++
++#include <linux/dmaengine.h>
++
++/**
++ * struct at_dma_platform_data - Controller configuration parameters
++ * @nr_channels: Number of channels supported by hardware (max 8)
++ * @cap_mask: dma_capability flags supported by the platform
++ */
++struct at_dma_platform_data {
++	unsigned int	nr_channels;
++	dma_cap_mask_t  cap_mask;
++};
++
++#endif /* AT_HDMAC_H */
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+index 3b3c01b..57ca445 100644
+--- a/drivers/dma/Kconfig
++++ b/drivers/dma/Kconfig
+@@ -46,6 +46,14 @@ config DW_DMAC
+ 	  Support the Synopsys DesignWare AHB DMA controller.  This
+ 	  can be integrated in chips such as the Atmel AT32ap7000.
+ 
++config AT_HDMAC
++	tristate "Atmel AHB DMA support"
++	depends on ARCH_AT91SAM9RL
++	select DMA_ENGINE
++	help
++	  Support the Atmel AHB DMA controller.  This can be integrated in
++	  chips such as the Atmel AT91SAM9RL.
++
+ config FSL_DMA
+ 	tristate "Freescale Elo and Elo Plus DMA support"
+ 	depends on FSL_SOC
+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
+index 2e5dc96..d7bc5fd 100644
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -7,4 +7,5 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
+ obj-$(CONFIG_FSL_DMA) += fsldma.o
+ obj-$(CONFIG_MV_XOR) += mv_xor.o
+ obj-$(CONFIG_DW_DMAC) += dw_dmac.o
++obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
+ obj-$(CONFIG_MX3_IPU) += ipu/
+diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
+new file mode 100644
+index 0000000..64dbf0c
+--- /dev/null
++++ b/drivers/dma/at_hdmac.c
+@@ -0,0 +1,1009 @@
++/*
++ * Driver for the Atmel AHB DMA Controller (aka HDMA or DMAC on AT91 systems)
++ *
++ * Copyright (C) 2008 Atmel Corporation
++ *
++ * 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.
++ *
++ *
++ * This supports the Atmel AHB DMA Controller,
++ *
++ * The driver has currently been tested with the Atmel AT91SAM9RL
++ * and AT91SAM9G45 series.
++ */
++
++#include <linux/clk.h>
++#include <linux/dmaengine.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include "at_hdmac_regs.h"
++
++/*
++ * Glossary
++ * --------
++ *
++ * at_hdmac		: Name of the ATmel AHB DMA Controller
++ * at_dma_ / atdma	: ATmel DMA controller entity related
++ * atc_	/ atchan	: ATmel DMA Channel entity related
++ */
++
++#define	ATC_DEFAULT_CFG		(ATC_FIFOCFG_HALFFIFO)
++#define	ATC_DEFAULT_CTRLA	(0)
++#define	ATC_DEFAULT_CTRLB	(ATC_SIF(0)	\
++				|ATC_DIF(1))
++
++/*
++ * Initial number of descriptors to allocate for each channel. This could
++ * be increased during dma usage.
++ */
++static unsigned int init_nr_desc_per_channel = 64;
++module_param(init_nr_desc_per_channel, uint, 0644);
++MODULE_PARM_DESC(init_nr_desc_per_channel,
++		 "initial descriptors per channel (default: 64)");
++
++
++/* prototypes */
++static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx);
++
++
++/*----------------------------------------------------------------------*/
++
++static struct at_desc *atc_first_active(struct at_dma_chan *atchan)
++{
++	return list_first_entry(&atchan->active_list,
++				struct at_desc, desc_node);
++}
++
++static struct at_desc *atc_first_queued(struct at_dma_chan *atchan)
++{
++	return list_first_entry(&atchan->queue,
++				struct at_desc, desc_node);
++}
++
++/**
++ * atc_alloc_descriptor - allocate and return an initilized descriptor
++ * @chan: the channel to allocate descriptors for
++ * @gfp_flags: GFP allocation flags
++ *
++ * Note: The ack-bit is positioned in the descriptor flag at creation time
++ *       to make initial allocation more convenient. This bit will be cleared
++ *       and control will be given to client at usage time (during
++ *       preparation functions).
++ */
++static struct at_desc *atc_alloc_descriptor(struct dma_chan *chan,
++					    gfp_t gfp_flags)
++{
++	struct at_desc	*desc = NULL;
++	struct at_dma	*atdma = to_at_dma(chan->device);
++	dma_addr_t phys;
++
++	desc = dma_pool_alloc(atdma->dma_desc_pool, gfp_flags, &phys);
++	if (desc) {
++		memset(desc, 0, sizeof(struct at_desc));
++		dma_async_tx_descriptor_init(&desc->txd, chan);
++		/* txd.flags will be overwritten in prep functions */
++		desc->txd.flags = DMA_CTRL_ACK;
++		desc->txd.tx_submit = atc_tx_submit;
++		desc->txd.phys = phys;
++	}
++
++	return desc;
++}
++
++/**
++ * atc_desc_get - get a unsused descriptor from free_list
++ * @atchan: channel we want a new descriptor for
++ */
++static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
++{
++	struct at_desc *desc, *_desc;
++	struct at_desc *ret = NULL;
++	unsigned int i = 0;
++	LIST_HEAD(tmp_list);
++
++	spin_lock_bh(&atchan->lock);
++	list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
++		i++;
++		if (async_tx_test_ack(&desc->txd)) {
++			list_del(&desc->desc_node);
++			ret = desc;
++			break;
++		}
++		dev_dbg(chan2dev(&atchan->chan_common),
++				"desc %p not ACKed\n", desc);
++	}
++	spin_unlock_bh(&atchan->lock);
++	dev_vdbg(chan2dev(&atchan->chan_common),
++		"scanned %u descriptors on freelist\n", i);
++
++	/* no more descriptor available in initial pool: create one more */
++	if (!ret) {
++		ret = atc_alloc_descriptor(&atchan->chan_common, GFP_ATOMIC);
++		if (ret) {
++			spin_lock_bh(&atchan->lock);
++			atchan->descs_allocated++;
++			spin_unlock_bh(&atchan->lock);
++		} else {
++			dev_err(chan2dev(&atchan->chan_common),
++					"not enough descriptors available\n");
++		}
++	}
++
++	return ret;
++}
++
++/**
++ * atc_desc_put - move a descriptor, including any children, to the free list
++ * @atchan: channel we work on
++ * @desc: descriptor, at the head of a chain, to move to free list
++ */
++static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
++{
++	if (desc) {
++		struct at_desc *child;
++
++		spin_lock_bh(&atchan->lock);
++		list_for_each_entry(child, &desc->txd.tx_list, desc_node)
++			dev_vdbg(chan2dev(&atchan->chan_common),
++					"moving child desc %p to freelist\n",
++					child);
++		list_splice_init(&desc->txd.tx_list, &atchan->free_list);
++		dev_vdbg(chan2dev(&atchan->chan_common),
++			 "moving desc %p to freelist\n", desc);
++		list_add(&desc->desc_node, &atchan->free_list);
++		spin_unlock_bh(&atchan->lock);
++	}
++}
++
++/**
++ * atc_assign_cookie - compute and assign new cookie
++ * @atchan: channel we work on
++ * @desc: descriptor to asign cookie for
++ *
++ * Called with atchan->lock held and bh disabled
++ */
++static dma_cookie_t
++atc_assign_cookie(struct at_dma_chan *atchan, struct at_desc *desc)
++{
++	dma_cookie_t cookie = atchan->chan_common.cookie;
++
++	if (++cookie < 0)
++		cookie = 1;
++
++	atchan->chan_common.cookie = cookie;
++	desc->txd.cookie = cookie;
++
++	return cookie;
++}
++
++/**
++ * atc_dostart - starts the DMA engine for real
++ * @atchan: the channel we want to start
++ * @first: first descriptor in the list we want to begin with
++ *
++ * Called with atchan->lock held and bh disabled
++ */
++static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
++{
++	struct at_dma	*atdma = to_at_dma(atchan->chan_common.device);
++
++	/* ASSERT:  channel is idle */
++	if (atc_chan_is_enabled(atchan)) {
++		dev_err(chan2dev(&atchan->chan_common),
++			"BUG: Attempted to start non-idle channel\n");
++		dev_err(chan2dev(&atchan->chan_common),
++			"  channel: s0x%x d0x%x ctrl0x%x:0x%x l0x%x\n",
++			channel_readl(atchan, SADDR),
++			channel_readl(atchan, DADDR),
++			channel_readl(atchan, CTRLA),
++			channel_readl(atchan, CTRLB),
++			channel_readl(atchan, DSCR));
++
++		/* The tasklet will hopefully advance the queue... */
++		return;
++	}
++
++	vdbg_dump_regs(atchan);
++
++	/* clear any pending interrupt */
++	while (dma_readl(atdma, EBCISR))
++		cpu_relax();
++
++	channel_writel(atchan, SADDR, 0);
++	channel_writel(atchan, DADDR, 0);
++	channel_writel(atchan, CTRLA, 0);
++	channel_writel(atchan, CTRLB, 0);
++	channel_writel(atchan, DSCR, first->txd.phys);
++	dma_writel(atdma, CHER, atchan->mask);
++
++	vdbg_dump_regs(atchan);
++}
++
++/**
++ * atc_chain_complete - finish work for one transaction chain
++ * @atchan: channel we work on
++ * @desc: descriptor at the head of the chain we want do complete
++ *
++ * Called with atchan->lock held and bh disabled */
++static void
++atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
++{
++	dma_async_tx_callback		callback;
++	void				*param;
++	struct dma_async_tx_descriptor	*txd = &desc->txd;
++
++	dev_vdbg(chan2dev(&atchan->chan_common),
++		"descriptor %u complete\n", txd->cookie);
++
++	atchan->completed_cookie = txd->cookie;
++	callback = txd->callback;
++	param = txd->callback_param;
++
++	/* move children to free_list */
++	list_splice_init(&txd->tx_list, &atchan->free_list);
++	/* move myself to free_list */
++	list_move(&desc->desc_node, &atchan->free_list);
++
++	/* unmap dma addresses */
++	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
++		if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
++			dma_unmap_single(chan2parent(&atchan->chan_common),
++					desc->lli.daddr,
++					desc->len, DMA_FROM_DEVICE);
++		else
++			dma_unmap_page(chan2parent(&atchan->chan_common),
++					desc->lli.daddr,
++					desc->len, DMA_FROM_DEVICE);
++	}
++	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
++		if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
++			dma_unmap_single(chan2parent(&atchan->chan_common),
++					desc->lli.saddr,
++					desc->len, DMA_TO_DEVICE);
++		else
++			dma_unmap_page(chan2parent(&atchan->chan_common),
++					desc->lli.saddr,
++					desc->len, DMA_TO_DEVICE);
++	}
++
++	/*
++	 * The API requires that no submissions are done from a
++	 * callback, so we don't need to drop the lock here
++	 */
++	if (callback)
++		callback(param);
++
++	dma_run_dependencies(txd);
++}
++
++/**
++ * atc_complete_all - finish work for all transactions
++ * @atchan: channel to complete transactions for
++ *
++ * Eventually submit queued descriptors if any
++ *
++ * Assume channel is idle while calling this function
++ * Called with atchan->lock held and bh disabled
++ */
++static void atc_complete_all(struct at_dma_chan *atchan)
++{
++	struct at_desc *desc, *_desc;
++	LIST_HEAD(list);
++
++	dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
++
++	BUG_ON(atc_chan_is_enabled(atchan));
++
++	/*
++	 * Submit queued descriptors ASAP, i.e. before we go through
++	 * the completed ones.
++	 */
++	if (!list_empty(&atchan->queue))
++		atc_dostart(atchan, atc_first_queued(atchan));
++	/* empty active_list now it is completed */
++	list_splice_init(&atchan->active_list, &list);
++	/* empty queue list by moving descriptors (if any) to active_list */
++	list_splice_init(&atchan->queue, &atchan->active_list);
++
++	list_for_each_entry_safe(desc, _desc, &list, desc_node)
++		atc_chain_complete(atchan, desc);
++}
++
++/**
++ * atc_cleanup_descriptors - cleanup up finished descriptors in active_list
++ * @atchan: channel to be cleaned up
++ *
++ * Called with atchan->lock held and bh disabled
++ */
++static void atc_cleanup_descriptors(struct at_dma_chan *atchan)
++{
++	struct at_desc	*desc, *_desc;
++	struct at_desc	*child;
++
++	dev_vdbg(chan2dev(&atchan->chan_common), "cleanup descriptors\n");
++
++	list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) {
++		if (!(desc->lli.ctrla & ATC_DONE))
++			/* This one is currently in progress */
++			return;
++
++		list_for_each_entry(child, &desc->txd.tx_list, desc_node)
++			if (!(child->lli.ctrla & ATC_DONE))
++				/* Currently in progress */
++				return;
++
++		/*
++		 * No descriptors so far seem to be in progress, i.e.
++		 * this chain must be done.
++		 */
++		atc_chain_complete(atchan, desc);
++	}
++}
++
++/**
++ * atc_advance_work - at the end of a transaction, move forward
++ * @atchan: channel where the transaction ended
++ *
++ * Called with atchan->lock held and bh disabled
++ */
++static void atc_advance_work(struct at_dma_chan *atchan)
++{
++	dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
++
++	if (list_empty(&atchan->active_list) ||
++	    list_is_singular(&atchan->active_list)) {
++		atc_complete_all(atchan);
++	} else {
++		atc_chain_complete(atchan, atc_first_active(atchan));
++		/* advance work */
++		atc_dostart(atchan, atc_first_active(atchan));
++	}
++}
++
++
++/**
++ * atc_handle_error - handle errors reported by DMA controller
++ * @atchan: channel where error occurs
++ *
++ * Called with atchan->lock held and bh disabled
++ */
++static void atc_handle_error(struct at_dma_chan *atchan)
++{
++	struct at_desc *bad_desc;
++	struct at_desc *child;
++
++	/*
++	 * The descriptor currently at the head of the active list is
++	 * broked. Since we don't have any way to report errors, we'll
++	 * just have to scream loudly and try to carry on.
++	 */
++	bad_desc = atc_first_active(atchan);
++	list_del_init(&bad_desc->desc_node);
++
++	/* As we are stopped, take advantage to push queued descriptors
++	 * in active_list */
++	list_splice_init(&atchan->queue, atchan->active_list.prev);
++
++	/* Try to restart the controller */
++	if (!list_empty(&atchan->active_list))
++		atc_dostart(atchan, atc_first_active(atchan));
++
++	/*
++	 * KERN_CRITICAL may seem harsh, but since this only happens
++	 * when someone submits a bad physical address in a
++	 * descriptor, we should consider ourselves lucky that the
++	 * controller flagged an error instead of scribbling over
++	 * random memory locations.
++	 */
++	dev_crit(chan2dev(&atchan->chan_common),
++			"Bad descriptor submitted for DMA!\n");
++	dev_crit(chan2dev(&atchan->chan_common),
++			"  cookie: %d\n", bad_desc->txd.cookie);
++	atc_dump_lli(atchan, &bad_desc->lli);
++	list_for_each_entry(child, &bad_desc->txd.tx_list, desc_node)
++		atc_dump_lli(atchan, &child->lli);
++
++	/* Pretend the descriptor completed successfully */
++	atc_chain_complete(atchan, bad_desc);
++}
++
++
++/*--  IRQ & Tasklet  ---------------------------------------------------*/
++
++static void atc_tasklet(unsigned long data)
++{
++	struct at_dma_chan *atchan = (struct at_dma_chan *)data;
++
++	/* Channel cannot be enabled here */
++	if (atc_chan_is_enabled(atchan)) {
++		dev_err(chan2dev(&atchan->chan_common),
++			"BUG: channel enabled in tasklet\n");
++		return;
++	}
++
++	spin_lock(&atchan->lock);
++	if (test_and_clear_bit(0, &atchan->error_status))
++		atc_handle_error(atchan);
++	else
++		atc_advance_work(atchan);
++
++	spin_unlock(&atchan->lock);
++}
++
++static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
++{
++	struct at_dma		*atdma = (struct at_dma *)dev_id;
++	struct at_dma_chan	*atchan;
++	int			i;
++	u32			status, pending, imr;
++	int			ret = IRQ_NONE;
++
++	do {
++		imr = dma_readl(atdma, EBCIMR);
++		status = dma_readl(atdma, EBCISR);
++		pending = status & imr;
++
++		if (!pending)
++			break;
++
++		dev_vdbg(atdma->dma_common.dev,
++			"interrupt: status = 0x%08x, 0x%08x, 0x%08x\n",
++			 status, imr, pending);
++
++		for (i = 0; i < atdma->dma_common.chancnt; i++) {
++			atchan = &atdma->chan[i];
++			if (pending & (AT_DMA_CBTC(i) | AT_DMA_ERR(i))) {
++				if (pending & AT_DMA_ERR(i)) {
++					/* Disable channel on AHB error */
++					dma_writel(atdma, CHDR, atchan->mask);
++					/* Give information to tasklet */
++					set_bit(0, &atchan->error_status);
++				}
++				tasklet_schedule(&atchan->tasklet);
++				ret = IRQ_HANDLED;
++			}
++		}
++
++	} while (pending);
++
++	return ret;
++}
++
++
++/*--  DMA Engine API  --------------------------------------------------*/
++
++/**
++ * atc_tx_submit - set the prepared descriptor(s) to be executed by the engine
++ * @desc: descriptor at the head of the transaction chain
++ *
++ * Queue chain if DMA engine is working already
++ *
++ * Cookie increment and adding to active_list or queue must be atomic
++ */
++static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
++{
++	struct at_desc		*desc = txd_to_at_desc(tx);
++	struct at_dma_chan	*atchan = to_at_dma_chan(tx->chan);
++	dma_cookie_t		cookie;
++
++	spin_lock_bh(&atchan->lock);
++	cookie = atc_assign_cookie(atchan, desc);
++
++	if (list_empty(&atchan->active_list)) {
++		dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
++				desc->txd.cookie);
++		atc_dostart(atchan, desc);
++		list_add_tail(&desc->desc_node, &atchan->active_list);
++	} else {
++		dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
++				desc->txd.cookie);
++		list_add_tail(&desc->desc_node, &atchan->queue);
++	}
++
++	spin_unlock_bh(&atchan->lock);
++
++	return cookie;
++}
++
++/**
++ * atc_prep_dma_memcpy - prepare a memcpy operation
++ * @chan: the channel to prepare operation on
++ * @dest: operation virtual destination address
++ * @src: operation virtual source address
++ * @len: operation length
++ * @flags: tx descriptor status flags
++ */
++static struct dma_async_tx_descriptor *
++atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
++		size_t len, unsigned long flags)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	struct at_desc		*desc = NULL;
++	struct at_desc		*first = NULL;
++	struct at_desc		*prev = NULL;
++	size_t			xfer_count;
++	size_t			offset;
++	unsigned int		src_width;
++	unsigned int		dst_width;
++	u32			ctrla;
++	u32			ctrlb;
++
++	dev_vdbg(chan2dev(chan), "prep_dma_memcpy: d0x%x s0x%x l0x%zx f0x%lx\n",
++			dest, src, len, flags);
++
++	if (unlikely(!len)) {
++		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
++		return NULL;
++	}
++
++	ctrla =   ATC_DEFAULT_CTRLA;
++	ctrlb =   ATC_DEFAULT_CTRLB
++		| ATC_SRC_ADDR_MODE_INCR
++		| ATC_DST_ADDR_MODE_INCR
++		| ATC_FC_MEM2MEM;
++
++	/*
++	 * We can be a lot more clever here, but this should take care
++	 * of the most common optimization.
++	 */
++	if (!((src | dest  | len) & 3)) {
++		ctrla |= ATC_SRC_WIDTH_WORD | ATC_DST_WIDTH_WORD;
++		src_width = dst_width = 2;
++	} else if (!((src | dest | len) & 1)) {
++		ctrla |= ATC_SRC_WIDTH_HALFWORD | ATC_DST_WIDTH_HALFWORD;
++		src_width = dst_width = 1;
++	} else {
++		ctrla |= ATC_SRC_WIDTH_BYTE | ATC_DST_WIDTH_BYTE;
++		src_width = dst_width = 0;
++	}
++
++	for (offset = 0; offset < len; offset += xfer_count << src_width) {
++		xfer_count = min_t(size_t, (len - offset) >> src_width,
++				ATC_BTSIZE_MAX);
++
++		desc = atc_desc_get(atchan);
++		if (!desc)
++			goto err_desc_get;
++
++		desc->lli.saddr = src + offset;
++		desc->lli.daddr = dest + offset;
++		desc->lli.ctrla = ctrla | xfer_count;
++		desc->lli.ctrlb = ctrlb;
++
++		desc->txd.cookie = 0;
++		async_tx_ack(&desc->txd);
++
++		if (!first) {
++			first = desc;
++		} else {
++			/* inform the HW lli about chaining */
++			prev->lli.dscr = desc->txd.phys;
++			/* insert the link descriptor to the LD ring */
++			list_add_tail(&desc->desc_node,
++					&first->txd.tx_list);
++		}
++		prev = desc;
++	}
++
++	/* First descriptor of the chain embedds additional information */
++	first->txd.cookie = -EBUSY;
++	first->len = len;
++
++	/* set end-of-link to the last link descriptor of list*/
++	set_desc_eol(desc);
++
++	desc->txd.flags = flags; /* client is in control of this ack */
++
++	return &first->txd;
++
++err_desc_get:
++	atc_desc_put(atchan, first);
++	return NULL;
++}
++
++/**
++ * atc_is_tx_complete - poll for transaction completion
++ * @chan: DMA channel
++ * @cookie: transaction identifier to check status of
++ * @done: if not %NULL, updated with last completed transaction
++ * @used: if not %NULL, updated with last used transaction
++ *
++ * If @done and @used are passed in, upon return they reflect the driver
++ * internal state and can be used with dma_async_is_complete() to check
++ * the status of multiple cookies without re-checking hardware state.
++ */
++static enum dma_status
++atc_is_tx_complete(struct dma_chan *chan,
++		dma_cookie_t cookie,
++		dma_cookie_t *done, dma_cookie_t *used)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	dma_cookie_t		last_used;
++	dma_cookie_t		last_complete;
++	enum dma_status		ret;
++
++	dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n",
++			cookie, done ? *done : 0, used ? *used : 0);
++
++	spin_lock_bh(atchan->lock);
++
++	last_complete = atchan->completed_cookie;
++	last_used = chan->cookie;
++
++	ret = dma_async_is_complete(cookie, last_complete, last_used);
++	if (ret != DMA_SUCCESS) {
++		atc_cleanup_descriptors(atchan);
++
++		last_complete = atchan->completed_cookie;
++		last_used = chan->cookie;
++
++		ret = dma_async_is_complete(cookie, last_complete, last_used);
++	}
++
++	spin_unlock_bh(atchan->lock);
++
++	if (done)
++		*done = last_complete;
++	if (used)
++		*used = last_used;
++
++	return ret;
++}
++
++/**
++ * atc_issue_pending - try to finish work
++ * @chan: target DMA channel
++ */
++static void atc_issue_pending(struct dma_chan *chan)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++
++	dev_vdbg(chan2dev(chan), "issue_pending\n");
++
++	if (!atc_chan_is_enabled(atchan)) {
++		spin_lock_bh(&atchan->lock);
++		atc_advance_work(atchan);
++		spin_unlock_bh(&atchan->lock);
++	}
++}
++
++/**
++ * atc_alloc_chan_resources - allocate resources for DMA channel
++ * @chan: allocate descriptor resources for this channel
++ * @client: current client requesting the channel be ready for requests
++ *
++ * return - the number of allocated descriptors
++ */
++static int atc_alloc_chan_resources(struct dma_chan *chan)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	struct at_dma		*atdma = to_at_dma(chan->device);
++	struct at_desc		*desc;
++	int			i;
++	LIST_HEAD(tmp_list);
++
++	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
++
++	/* ASSERT:  channel is idle */
++	if (atc_chan_is_enabled(atchan)) {
++		dev_dbg(chan2dev(chan), "DMA channel not idle ?\n");
++		return -EIO;
++	}
++
++	/* have we already been set up? */
++	if (!list_empty(&atchan->free_list))
++		return atchan->descs_allocated;
++
++	/* Allocate initial pool of descriptors */
++	for (i = 0; i < init_nr_desc_per_channel; i++) {
++		desc = atc_alloc_descriptor(chan, GFP_KERNEL);
++		if (!desc) {
++			dev_err(atdma->dma_common.dev,
++				"Only %d initial descriptors\n", i);
++			break;
++		}
++		list_add_tail(&desc->desc_node, &tmp_list);
++	}
++
++	spin_lock_bh(&atchan->lock);
++	atchan->descs_allocated = i;
++	list_splice(&tmp_list, &atchan->free_list);
++	atchan->completed_cookie = chan->cookie = 1;
++	spin_unlock_bh(&atchan->lock);
++
++	/* channel parameters */
++	channel_writel(atchan, CFG, ATC_DEFAULT_CFG);
++
++	dev_dbg(chan2dev(chan),
++		"alloc_chan_resources: allocated %d descriptors\n",
++		atchan->descs_allocated);
++
++	return atchan->descs_allocated;
++}
++
++/**
++ * atc_free_chan_resources - free all channel resources
++ * @chan: DMA channel
++ */
++static void atc_free_chan_resources(struct dma_chan *chan)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	struct at_dma		*atdma = to_at_dma(chan->device);
++	struct at_desc		*desc, *_desc;
++	LIST_HEAD(list);
++
++	dev_dbg(chan2dev(chan), "free_chan_resources: (descs allocated=%u)\n",
++		atchan->descs_allocated);
++
++	/* ASSERT:  channel is idle */
++	BUG_ON(!list_empty(&atchan->active_list));
++	BUG_ON(!list_empty(&atchan->queue));
++	BUG_ON(atc_chan_is_enabled(atchan));
++
++	list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
++		dev_vdbg(chan2dev(chan), "  freeing descriptor %p\n", desc);
++		list_del(&desc->desc_node);
++		/* free link descriptor */
++		dma_pool_free(atdma->dma_desc_pool, desc, desc->txd.phys);
++	}
++	list_splice_init(&atchan->free_list, &list);
++	atchan->descs_allocated = 0;
++
++	dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
++}
++
++
++/*--  Module Management  -----------------------------------------------*/
++
++/**
++ * at_dma_off - disable DMA controller
++ * @atdma: the Atmel HDAMC device
++ */
++static void at_dma_off(struct at_dma *atdma)
++{
++	dma_writel(atdma, EN, 0);
++
++	/* disable all interrupts */
++	dma_writel(atdma, EBCIDR, -1L);
++
++	/* confirm that all channels are disabled */
++	while (dma_readl(atdma, CHSR) & atdma->all_chan_mask)
++		cpu_relax();
++}
++
++static int __init at_dma_probe(struct platform_device *pdev)
++{
++	struct at_dma_platform_data *pdata;
++	struct resource		*io;
++	struct at_dma		*atdma;
++	size_t			size;
++	int			irq;
++	int			err;
++	int			i;
++
++	/* get DMA Controller parameters from platform */
++	pdata = pdev->dev.platform_data;
++	if (!pdata || pdata->nr_channels > AT_DMA_MAX_NR_CHANNELS)
++		return -EINVAL;
++
++	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!io)
++		return -EINVAL;
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0)
++		return irq;
++
++	size = sizeof(struct at_dma);
++	size += pdata->nr_channels * sizeof(struct at_dma_chan);
++	atdma = kzalloc(size, GFP_KERNEL);
++	if (!atdma)
++		return -ENOMEM;
++
++	/* discover transaction capabilites from the platform data */
++	atdma->dma_common.cap_mask = pdata->cap_mask;
++	atdma->all_chan_mask = (1 << pdata->nr_channels) - 1;
++
++	size = io->end - io->start + 1;
++	if (!request_mem_region(io->start, size, pdev->dev.driver->name)) {
++		err = -EBUSY;
++		goto err_kfree;
++	}
++
++	atdma->regs = ioremap(io->start, size);
++	if (!atdma->regs) {
++		err = -ENOMEM;
++		goto err_release_r;
++	}
++
++	atdma->clk = clk_get(&pdev->dev, "dma_clk");
++	if (IS_ERR(atdma->clk)) {
++		err = PTR_ERR(atdma->clk);
++		goto err_clk;
++	}
++	clk_enable(atdma->clk);
++
++	/* force dma off, just in case */
++	at_dma_off(atdma);
++
++	err = request_irq(irq, at_dma_interrupt, 0, "at_hdmac", atdma);
++	if (err)
++		goto err_irq;
++
++	platform_set_drvdata(pdev, atdma);
++
++	/* create a pool of consistent memory blocks for hardware descriptors */
++	atdma->dma_desc_pool = dma_pool_create("at_hdmac_desc_pool",
++			&pdev->dev, sizeof(struct at_desc),
++			4 /* word alignment */, 0);
++	if (!atdma->dma_desc_pool) {
++		dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
++		err = -ENOMEM;
++		goto err_pool_create;
++	}
++
++	/* clear any pending interrupt */
++	while (dma_readl(atdma, EBCISR))
++		cpu_relax();
++
++	/* initialize channels related values */
++	INIT_LIST_HEAD(&atdma->dma_common.channels);
++	for (i = 0; i < pdata->nr_channels; i++, atdma->dma_common.chancnt++) {
++		struct at_dma_chan	*atchan = &atdma->chan[i];
++
++		atchan->chan_common.device = &atdma->dma_common;
++		atchan->chan_common.cookie = atchan->completed_cookie = 1;
++		atchan->chan_common.chan_id = i;
++		list_add_tail(&atchan->chan_common.device_node,
++				&atdma->dma_common.channels);
++
++		atchan->ch_regs = atdma->regs + ch_regs(i);
++		spin_lock_init(&atchan->lock);
++		atchan->mask = 1 << i;
++
++		INIT_LIST_HEAD(&atchan->active_list);
++		INIT_LIST_HEAD(&atchan->queue);
++		INIT_LIST_HEAD(&atchan->free_list);
++
++		tasklet_init(&atchan->tasklet, atc_tasklet,
++				(unsigned long)atchan);
++		atc_enable_irq(atchan);
++	}
++
++	/* set base routines */
++	atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources;
++	atdma->dma_common.device_free_chan_resources = atc_free_chan_resources;
++	atdma->dma_common.device_is_tx_complete = atc_is_tx_complete;
++	atdma->dma_common.device_issue_pending = atc_issue_pending;
++	atdma->dma_common.dev = &pdev->dev;
++
++	/* set prep routines based on capability */
++	if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
++		atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
++
++	dma_writel(atdma, EN, AT_DMA_ENABLE);
++
++	dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
++	  dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
++	  dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)  ? "slave " : "",
++	  atdma->dma_common.chancnt);
++
++	dma_async_device_register(&atdma->dma_common);
++
++	return 0;
++
++err_pool_create:
++	platform_set_drvdata(pdev, NULL);
++	free_irq(platform_get_irq(pdev, 0), atdma);
++err_irq:
++	clk_disable(atdma->clk);
++	clk_put(atdma->clk);
++err_clk:
++	iounmap(atdma->regs);
++	atdma->regs = NULL;
++err_release_r:
++	release_mem_region(io->start, size);
++err_kfree:
++	kfree(atdma);
++	return err;
++}
++
++static int __exit at_dma_remove(struct platform_device *pdev)
++{
++	struct at_dma		*atdma = platform_get_drvdata(pdev);
++	struct dma_chan		*chan, *_chan;
++	struct resource		*io;
++
++	at_dma_off(atdma);
++	dma_async_device_unregister(&atdma->dma_common);
++
++	dma_pool_destroy(atdma->dma_desc_pool);
++	platform_set_drvdata(pdev, NULL);
++	free_irq(platform_get_irq(pdev, 0), atdma);
++
++	list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
++			device_node) {
++		struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++
++		/* Disable interrupts */
++		atc_disable_irq(atchan);
++		tasklet_disable(&atchan->tasklet);
++
++		tasklet_kill(&atchan->tasklet);
++		list_del(&chan->device_node);
++	}
++
++	clk_disable(atdma->clk);
++	clk_put(atdma->clk);
++
++	iounmap(atdma->regs);
++	atdma->regs = NULL;
++
++	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	release_mem_region(io->start, io->end - io->start + 1);
++
++	kfree(atdma);
++
++	return 0;
++}
++
++static void at_dma_shutdown(struct platform_device *pdev)
++{
++	struct at_dma	*atdma = platform_get_drvdata(pdev);
++
++	at_dma_off(platform_get_drvdata(pdev));
++	clk_disable(atdma->clk);
++}
++
++static int at_dma_suspend_late(struct platform_device *pdev, pm_message_t mesg)
++{
++	struct at_dma	*atdma = platform_get_drvdata(pdev);
++
++	at_dma_off(platform_get_drvdata(pdev));
++	clk_disable(atdma->clk);
++	return 0;
++}
++
++static int at_dma_resume_early(struct platform_device *pdev)
++{
++	struct at_dma	*atdma = platform_get_drvdata(pdev);
++
++	clk_enable(atdma->clk);
++	dma_writel(atdma, EN, AT_DMA_ENABLE);
++	return 0;
++
++}
++
++static struct platform_driver at_dma_driver = {
++	.remove		= __exit_p(at_dma_remove),
++	.shutdown	= at_dma_shutdown,
++	.suspend_late	= at_dma_suspend_late,
++	.resume_early	= at_dma_resume_early,
++	.driver = {
++		.name	= "at_hdmac",
++	},
++};
++
++static int __init at_dma_init(void)
++{
++	return platform_driver_probe(&at_dma_driver, at_dma_probe);
++}
++module_init(at_dma_init);
++
++static void __exit at_dma_exit(void)
++{
++	platform_driver_unregister(&at_dma_driver);
++}
++module_exit(at_dma_exit);
++
++MODULE_DESCRIPTION("Atmel AHB DMA Controller driver");
++MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre at atmel.com>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:at_hdmac");
+diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
+new file mode 100644
+index 0000000..ad2d4f4
+--- /dev/null
++++ b/drivers/dma/at_hdmac_regs.h
+@@ -0,0 +1,386 @@
++/*
++ * Header file for the Atmel AHB DMA Controller driver
++ *
++ * Copyright (C) 2008 Atmel Corporation
++ *
++ * 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 AT_HDMAC_REGS_H
++#define	AT_HDMAC_REGS_H
++
++#include <mach/at_hdmac.h>
++
++#define	AT_DMA_MAX_NR_CHANNELS	8
++
++
++#define	AT_DMA_GCFG	0x00	/* Global Configuration Register */
++#define		AT_DMA_IF_BIGEND(i)	(0x1 << (i))	/* AHB-Lite Interface i in Big-endian mode */
++#define		AT_DMA_ARB_CFG	(0x1 << 4)	/* Arbiter mode. */
++#define			AT_DMA_ARB_CFG_FIXED		(0x0 << 4)
++#define			AT_DMA_ARB_CFG_ROUND_ROBIN	(0x1 << 4)
++
++#define	AT_DMA_EN	0x04	/* Controller Enable Register */
++#define		AT_DMA_ENABLE	(0x1 << 0)
++
++#define	AT_DMA_SREQ	0x08	/* Software Single Request Register */
++#define		AT_DMA_SSREQ(x)	(0x1 << ((x) << 1))		/* Request a source single transfer on channel x */
++#define		AT_DMA_DSREQ(x)	(0x1 << (1 + ((x) << 1)))	/* Request a destination single transfer on channel x */
++
++#define	AT_DMA_CREQ	0x0C	/* Software Chunk Transfer Request Register */
++#define		AT_DMA_SCREQ(x)	(0x1 << ((x) << 1))		/* Request a source chunk transfer on channel x */
++#define		AT_DMA_DCREQ(x)	(0x1 << (1 + ((x) << 1)))	/* Request a destination chunk transfer on channel x */
++
++#define	AT_DMA_LAST	0x10	/* Software Last Transfer Flag Register */
++#define		AT_DMA_SLAST(x)	(0x1 << ((x) << 1))		/* This src rq is last tx of buffer on channel x */
++#define		AT_DMA_DLAST(x)	(0x1 << (1 + ((x) << 1)))	/* This dst rq is last tx of buffer on channel x */
++
++#define	AT_DMA_SYNC	0x14	/* Request Synchronization Register */
++#define		AT_DMA_SYR(h)	(0x1 << (h))			/* Synchronize handshake line h */
++
++/* Error, Chained Buffer transfer completed and Buffer transfer completed Interrupt registers */
++#define	AT_DMA_EBCIER	0x18	/* Enable register */
++#define	AT_DMA_EBCIDR	0x1C	/* Disable register */
++#define	AT_DMA_EBCIMR	0x20	/* Mask Register */
++#define	AT_DMA_EBCISR	0x24	/* Status Register */
++#define		AT_DMA_CBTC_OFFSET	8
++#define		AT_DMA_ERR_OFFSET	16
++#define		AT_DMA_BTC(x)	(0x1 << (x))
++#define		AT_DMA_CBTC(x)	(0x1 << (AT_DMA_CBTC_OFFSET + (x)))
++#define		AT_DMA_ERR(x)	(0x1 << (AT_DMA_ERR_OFFSET + (x)))
++
++#define	AT_DMA_CHER	0x28	/* Channel Handler Enable Register */
++#define		AT_DMA_ENA(x)	(0x1 << (x))
++#define		AT_DMA_SUSP(x)	(0x1 << ( 8 + (x)))
++#define		AT_DMA_KEEP(x)	(0x1 << (24 + (x)))
++
++#define	AT_DMA_CHDR	0x2C	/* Channel Handler Disable Register */
++#define		AT_DMA_DIS(x)	(0x1 << (x))
++#define		AT_DMA_RES(x)	(0x1 << ( 8 + (x)))
++
++#define	AT_DMA_CHSR	0x30	/* Channel Handler Status Register */
++#define		AT_DMA_EMPT(x)	(0x1 << (16 + (x)))
++#define		AT_DMA_STAL(x)	(0x1 << (24 + (x)))
++
++
++#define	AT_DMA_CH_REGS_BASE	0x3C	/* Channel registers base address */
++#define	ch_regs(x)	(AT_DMA_CH_REGS_BASE + (x) * 0x28) /* Channel x base addr */
++
++/* Hardware register offset for each channel */
++#define	ATC_SADDR_OFFSET	0x00	/* Source Address Register */
++#define	ATC_DADDR_OFFSET	0x04	/* Destination Address Register */
++#define	ATC_DSCR_OFFSET		0x08	/* Descriptor Address Register */
++#define	ATC_CTRLA_OFFSET	0x0C	/* Control A Register */
++#define	ATC_CTRLB_OFFSET	0x10	/* Control B Register */
++#define	ATC_CFG_OFFSET		0x14	/* Configuration Register */
++#define	ATC_SPIP_OFFSET		0x18	/* Src PIP Configuration Register */
++#define	ATC_DPIP_OFFSET		0x1C	/* Dst PIP Configuration Register */
++
++
++/* Bitfield definitions */
++
++/* Bitfields in DSCR */
++#define	ATC_DSCR_IF(i)		(0x3 & (i))	/* Dsc feched via AHB-Lite Interface i */
++
++/* Bitfields in CTRLA */
++#define	ATC_BTSIZE_MAX		0xFFFFUL	/* Maximum Buffer Transfer Size */
++#define	ATC_BTSIZE(x)		(ATC_BTSIZE_MAX & (x)) /* Buffer Transfer Size */
++#define	ATC_SCSIZE_MASK		(0x7 << 16)	/* Source Chunk Transfer Size */
++#define		ATC_SCSIZE_1		(0x0 << 16)
++#define		ATC_SCSIZE_4		(0x1 << 16)
++#define		ATC_SCSIZE_8		(0x2 << 16)
++#define		ATC_SCSIZE_16		(0x3 << 16)
++#define		ATC_SCSIZE_32		(0x4 << 16)
++#define		ATC_SCSIZE_64		(0x5 << 16)
++#define		ATC_SCSIZE_128		(0x6 << 16)
++#define		ATC_SCSIZE_256		(0x7 << 16)
++#define	ATC_DCSIZE_MASK		(0x7 << 20)	/* Destination Chunk Transfer Size */
++#define		ATC_DCSIZE_1		(0x0 << 20)
++#define		ATC_DCSIZE_4		(0x1 << 20)
++#define		ATC_DCSIZE_8		(0x2 << 20)
++#define		ATC_DCSIZE_16		(0x3 << 20)
++#define		ATC_DCSIZE_32		(0x4 << 20)
++#define		ATC_DCSIZE_64		(0x5 << 20)
++#define		ATC_DCSIZE_128		(0x6 << 20)
++#define		ATC_DCSIZE_256		(0x7 << 20)
++#define	ATC_SRC_WIDTH_MASK	(0x3 << 24)	/* Source Single Transfer Size */
++#define		ATC_SRC_WIDTH_BYTE	(0x0 << 24)
++#define		ATC_SRC_WIDTH_HALFWORD	(0x1 << 24)
++#define		ATC_SRC_WIDTH_WORD	(0x2 << 24)
++#define	ATC_DST_WIDTH_MASK	(0x3 << 28)	/* Destination Single Transfer Size */
++#define		ATC_DST_WIDTH_BYTE	(0x0 << 28)
++#define		ATC_DST_WIDTH_HALFWORD	(0x1 << 28)
++#define		ATC_DST_WIDTH_WORD	(0x2 << 28)
++#define	ATC_DONE		(0x1 << 31)	/* Tx Done (only written back in descriptor) */
++
++/* Bitfields in CTRLB */
++#define	ATC_SIF(i)		(0x3 & (i))	/* Src tx done via AHB-Lite Interface i */
++#define	ATC_DIF(i)		((0x3 & (i)) <<  4)	/* Dst tx done via AHB-Lite Interface i */
++#define	ATC_SRC_PIP		(0x1 <<  8)	/* Source Picture-in-Picture enabled */
++#define	ATC_DST_PIP		(0x1 << 12)	/* Destination Picture-in-Picture enabled */
++#define	ATC_SRC_DSCR_DIS	(0x1 << 16)	/* Src Descriptor fetch disable */
++#define	ATC_DST_DSCR_DIS	(0x1 << 20)	/* Dst Descriptor fetch disable */
++#define	ATC_FC_MASK		(0x7 << 21)	/* Choose Flow Controller */
++#define		ATC_FC_MEM2MEM		(0x0 << 21)	/* Mem-to-Mem (DMA) */
++#define		ATC_FC_MEM2PER		(0x1 << 21)	/* Mem-to-Periph (DMA) */
++#define		ATC_FC_PER2MEM		(0x2 << 21)	/* Periph-to-Mem (DMA) */
++#define		ATC_FC_PER2PER		(0x3 << 21)	/* Periph-to-Periph (DMA) */
++#define		ATC_FC_PER2MEM_PER	(0x4 << 21)	/* Periph-to-Mem (Peripheral) */
++#define		ATC_FC_MEM2PER_PER	(0x5 << 21)	/* Mem-to-Periph (Peripheral) */
++#define		ATC_FC_PER2PER_PER	(0x6 << 21)	/* Periph-to-Periph (Src Peripheral) */
++#define	ATC_SRC_ADDR_MODE_MASK	(0x3 << 24)
++#define		ATC_SRC_ADDR_MODE_INCR	(0x0 << 24)	/* Incrementing Mode */
++#define		ATC_SRC_ADDR_MODE_DECR	(0x1 << 24)	/* Decrementing Mode */
++#define		ATC_SRC_ADDR_MODE_FIXED	(0x2 << 24)	/* Fixed Mode */
++#define	ATC_DST_ADDR_MODE_MASK	(0x3 << 28)
++#define		ATC_DST_ADDR_MODE_INCR	(0x0 << 28)	/* Incrementing Mode */
++#define		ATC_DST_ADDR_MODE_DECR	(0x1 << 28)	/* Decrementing Mode */
++#define		ATC_DST_ADDR_MODE_FIXED	(0x2 << 28)	/* Fixed Mode */
++#define	ATC_IEN			(0x1 << 30)	/* BTC interrupt enable (active low) */
++#define	ATC_AUTO		(0x1 << 31)	/* Auto multiple buffer tx enable */
++
++/* Bitfields in CFG */
++#define	ATC_SRC_PER(h)		(0xFU & (h))	/* Channel src rq associated with periph handshaking ifc h */
++#define	ATC_DST_PER(h)		((0xFU & (h)) <<  4)	/* Channel dst rq associated with periph handshaking ifc h */
++#define	ATC_SRC_REP		(0x1 <<  8)	/* Source Replay Mod */
++#define	ATC_SRC_H2SEL		(0x1 <<  9)	/* Source Handshaking Mod */
++#define		ATC_SRC_H2SEL_SW	(0x0 <<  9)
++#define		ATC_SRC_H2SEL_HW	(0x1 <<  9)
++#define	ATC_DST_REP		(0x1 << 12)	/* Destination Replay Mod */
++#define	ATC_DST_H2SEL		(0x1 << 13)	/* Destination Handshaking Mod */
++#define		ATC_DST_H2SEL_SW	(0x0 << 13)
++#define		ATC_DST_H2SEL_HW	(0x1 << 13)
++#define	ATC_SOD			(0x1 << 16)	/* Stop On Done */
++#define	ATC_LOCK_IF		(0x1 << 20)	/* Interface Lock */
++#define	ATC_LOCK_B		(0x1 << 21)	/* AHB Bus Lock */
++#define	ATC_LOCK_IF_L		(0x1 << 22)	/* Master Interface Arbiter Lock */
++#define		ATC_LOCK_IF_L_CHUNK	(0x0 << 22)
++#define		ATC_LOCK_IF_L_BUFFER	(0x1 << 22)
++#define	ATC_AHB_PROT_MASK	(0x7 << 24)	/* AHB Protection */
++#define	ATC_FIFOCFG_MASK	(0x3 << 28)	/* FIFO Request Configuration */
++#define		ATC_FIFOCFG_LARGESTBURST	(0x0 << 28)
++#define		ATC_FIFOCFG_HALFFIFO		(0x1 << 28)
++#define		ATC_FIFOCFG_ENOUGHSPACE		(0x2 << 28)
++
++/* Bitfields in SPIP */
++#define	ATC_SPIP_HOLE(x)	(0xFFFFU & (x))
++#define	ATC_SPIP_BOUNDARY(x)	((0x3FF & (x)) << 16)
++
++/* Bitfields in DPIP */
++#define	ATC_DPIP_HOLE(x)	(0xFFFFU & (x))
++#define	ATC_DPIP_BOUNDARY(x)	((0x3FF & (x)) << 16)
++
++
++/*--  descriptors  -----------------------------------------------------*/
++
++/* LLI == Linked List Item; aka DMA buffer descriptor */
++struct at_lli {
++	/* values that are not changed by hardware */
++	dma_addr_t	saddr;
++	dma_addr_t	daddr;
++	/* value that may get written back: */
++	u32		ctrla;
++	/* more values that are not changed by hardware */
++	u32		ctrlb;
++	dma_addr_t	dscr;	/* chain to next lli */
++};
++
++/**
++ * struct at_desc - software descriptor
++ * @at_lli: hardware lli structure
++ * @txd: support for the async_tx api
++ * @desc_node: node on the channed descriptors list
++ * @len: total transaction bytecount
++ */
++struct at_desc {
++	/* FIRST values the hardware uses */
++	struct at_lli			lli;
++
++	/* THEN values for driver housekeeping */
++	struct dma_async_tx_descriptor	txd;
++	struct list_head		desc_node;
++	size_t				len;
++};
++
++static inline struct at_desc *
++txd_to_at_desc(struct dma_async_tx_descriptor *txd)
++{
++	return container_of(txd, struct at_desc, txd);
++}
++
++
++/*--  Channels  --------------------------------------------------------*/
++
++/**
++ * struct at_dma_chan - internal representation of an Atmel HDMAC channel
++ * @chan_common: common dmaengine channel object members
++ * @device: parent device
++ * @ch_regs: memory mapped register base
++ * @mask: channel index in a mask
++ * @error_status: transmit error status information from irq handler
++ *                to tasklet (use atomic operations)
++ * @tasklet: bottom half to finish transaction work
++ * @lock: serializes enqueue/dequeue operations to descriptors lists
++ * @completed_cookie: identifier for the most recently completed operation
++ * @active_list: list of descriptors dmaengine is being running on
++ * @queue: list of descriptors ready to be submitted to engine
++ * @free_list: list of descriptors usable by the channel
++ * @descs_allocated: records the actual size of the descriptor pool
++ */
++struct at_dma_chan {
++	struct dma_chan		chan_common;
++	struct at_dma		*device;
++	void __iomem		*ch_regs;
++	u8			mask;
++	unsigned long		error_status;
++	struct tasklet_struct	tasklet;
++
++	spinlock_t		lock;
++
++	/* these other elements are all protected by lock */
++	dma_cookie_t		completed_cookie;
++	struct list_head	active_list;
++	struct list_head	queue;
++	struct list_head	free_list;
++	unsigned int		descs_allocated;
++};
++
++#define	channel_readl(atchan, name) \
++	__raw_readl((atchan)->ch_regs + ATC_##name##_OFFSET)
++
++#define	channel_writel(atchan, name, val) \
++	__raw_writel((val), (atchan)->ch_regs + ATC_##name##_OFFSET)
++
++static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
++{
++	return container_of(dchan, struct at_dma_chan, chan_common);
++}
++
++
++/*--  Controller  ------------------------------------------------------*/
++
++/**
++ * struct at_dma - internal representation of an Atmel HDMA Controller
++ * @chan_common: common dmaengine dma_device object members
++ * @ch_regs: memory mapped register base
++ * @clk: dma controller clock
++ * @all_chan_mask: all channels availlable in a mask
++ * @dma_desc_pool: base of DMA descriptor region (DMA address)
++ * @chan: channels table to store at_dma_chan structures
++ */
++struct at_dma {
++	struct dma_device	dma_common;
++	void __iomem		*regs;
++	struct clk		*clk;
++
++	u8			all_chan_mask;
++
++	struct dma_pool		*dma_desc_pool;
++	/* AT THE END channels table */
++	struct at_dma_chan	chan[0];
++};
++
++#define	dma_readl(atdma, name) \
++	__raw_readl((atdma)->regs + AT_DMA_##name)
++#define	dma_writel(atdma, name, val) \
++	__raw_writel((val), (atdma)->regs + AT_DMA_##name)
++
++static inline struct at_dma *to_at_dma(struct dma_device *ddev)
++{
++	return container_of(ddev, struct at_dma, dma_common);
++}
++
++
++/*--  Helper functions  ------------------------------------------------*/
++
++static struct device *chan2dev(struct dma_chan *chan)
++{
++	return &chan->dev->device;
++}
++static struct device *chan2parent(struct dma_chan *chan)
++{
++	return chan->dev->device.parent;
++}
++
++#if defined(VERBOSE_DEBUG)
++static void vdbg_dump_regs(struct at_dma_chan *atchan)
++{
++	struct at_dma	*atdma = to_at_dma(atchan->chan_common.device);
++
++	dev_err(chan2dev(&atchan->chan_common),
++		"  channel %d : imr = 0x%x, chsr = 0x%x\n",
++		atchan->chan_common.chan_id,
++		dma_readl(atdma, EBCIMR),
++		dma_readl(atdma, CHSR));
++
++	dev_err(chan2dev(&atchan->chan_common),
++		"  channel: s0x%x d0x%x ctrl0x%x:0x%x l0x%x\n",
++		channel_readl(atchan, SADDR),
++		channel_readl(atchan, DADDR),
++		channel_readl(atchan, CTRLA),
++		channel_readl(atchan, CTRLB),
++		channel_readl(atchan, DSCR));
++}
++#else
++static void vdbg_dump_regs(struct at_dma_chan *atchan) {}
++#endif
++
++static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli)
++{
++	dev_printk(KERN_CRIT, chan2dev(&atchan->chan_common),
++			"  desc: s0x%x d0x%x ctrl0x%x:0x%x l0x%x\n",
++			lli->saddr, lli->daddr,
++			lli->ctrla, lli->ctrlb, lli->dscr);
++}
++
++
++static void atc_setup_irq(struct at_dma_chan *atchan, int on)
++{
++	struct at_dma	*atdma = to_at_dma(atchan->chan_common.device);
++	u32		ebci;
++
++	/* enable interrupts on buffer chain completion & error */
++	ebci =    AT_DMA_CBTC(atchan->chan_common.chan_id)
++		| AT_DMA_ERR(atchan->chan_common.chan_id);
++	if (on)
++		dma_writel(atdma, EBCIER, ebci);
++	else
++		dma_writel(atdma, EBCIDR, ebci);
++}
++
++static inline void atc_enable_irq(struct at_dma_chan *atchan)
++{
++	atc_setup_irq(atchan, 1);
++}
++
++static inline void atc_disable_irq(struct at_dma_chan *atchan)
++{
++	atc_setup_irq(atchan, 0);
++}
++
++
++/**
++ * atc_chan_is_enabled - test if given channel is enabled
++ * @atchan: channel we want to test status
++ */
++static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
++{
++	struct at_dma	*atdma = to_at_dma(atchan->chan_common.device);
++
++	return !!(dma_readl(atdma, CHSR) & atchan->mask);
++}
++
++
++/**
++ * set_desc_eol - set end-of-link to descriptor so it will end transfer
++ * @desc: descriptor, signle or at the end of a chain, to end chain on
++ */
++static void set_desc_eol(struct at_desc *desc)
++{
++	desc->lli.ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS;
++	desc->lli.dscr = 0;
++}
++
++#endif /* AT_HDMAC_REGS_H */
+-- 
+1.5.6.5
+
+From a7dfd8a17561051309889b25a55fbb9967ca71c5 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:33 +0000
+Subject: [PATCH] dmaengine: at_hdmac: add DMA slave transfers
+
+This patch for at_hdmac adds the slave transfers capability to the Atmel DMA
+controller available on some AT91 SOCs. This allow peripheral to memory and
+memory to peripheral transfers with hardware handshaking.
+
+Slave structure for controller specific information is passed through channel
+private data. This at_dma_slave structure is defined in at_hdmac.h header file
+and relative hardware definition are moved to this file from at_hdmac_regs.h.
+Doing this we allow the channel configuration from platform definition code.
+
+This work is intensively based on dw_dmac and several slave implementations.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Signed-off-by: Dan Williams <dan.j.williams at intel.com>
+(cherry picked from commit 808347f6a31792079e345ec865e9cfcb6e8ae6b2)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11595 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/include/mach/at_hdmac.h |   76 ++++++++++
+ drivers/dma/at_hdmac.c                     |  208 +++++++++++++++++++++++++++-
+ drivers/dma/at_hdmac_regs.h                |   49 +------
+ 3 files changed, 290 insertions(+), 43 deletions(-)
+
+diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h
+index 21a5554..187cb58 100644
+--- a/arch/arm/mach-at91/include/mach/at_hdmac.h
++++ b/arch/arm/mach-at91/include/mach/at_hdmac.h
+@@ -23,4 +23,80 @@ struct at_dma_platform_data {
+ 	dma_cap_mask_t  cap_mask;
+ };
+ 
++/**
++ * enum at_dma_slave_width - DMA slave register access width.
++ * @AT_DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
++ * @AT_DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
++ * @AT_DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
++ */
++enum at_dma_slave_width {
++	AT_DMA_SLAVE_WIDTH_8BIT = 0,
++	AT_DMA_SLAVE_WIDTH_16BIT,
++	AT_DMA_SLAVE_WIDTH_32BIT,
++};
++
++/**
++ * struct at_dma_slave - Controller-specific information about a slave
++ * @dma_dev: required DMA master device
++ * @tx_reg: physical address of data register used for
++ *	memory-to-peripheral transfers
++ * @rx_reg: physical address of data register used for
++ *	peripheral-to-memory transfers
++ * @reg_width: peripheral register width
++ * @cfg: Platform-specific initializer for the CFG register
++ * @ctrla: Platform-specific initializer for the CTRLA register
++ */
++struct at_dma_slave {
++	struct device		*dma_dev;
++	dma_addr_t		tx_reg;
++	dma_addr_t		rx_reg;
++	enum at_dma_slave_width	reg_width;
++	u32			cfg;
++	u32			ctrla;
++};
++
++
++/* Platform-configurable bits in CFG */
++#define	ATC_SRC_PER(h)		(0xFU & (h))	/* Channel src rq associated with periph handshaking ifc h */
++#define	ATC_DST_PER(h)		((0xFU & (h)) <<  4)	/* Channel dst rq associated with periph handshaking ifc h */
++#define	ATC_SRC_REP		(0x1 <<  8)	/* Source Replay Mod */
++#define	ATC_SRC_H2SEL		(0x1 <<  9)	/* Source Handshaking Mod */
++#define		ATC_SRC_H2SEL_SW	(0x0 <<  9)
++#define		ATC_SRC_H2SEL_HW	(0x1 <<  9)
++#define	ATC_DST_REP		(0x1 << 12)	/* Destination Replay Mod */
++#define	ATC_DST_H2SEL		(0x1 << 13)	/* Destination Handshaking Mod */
++#define		ATC_DST_H2SEL_SW	(0x0 << 13)
++#define		ATC_DST_H2SEL_HW	(0x1 << 13)
++#define	ATC_SOD			(0x1 << 16)	/* Stop On Done */
++#define	ATC_LOCK_IF		(0x1 << 20)	/* Interface Lock */
++#define	ATC_LOCK_B		(0x1 << 21)	/* AHB Bus Lock */
++#define	ATC_LOCK_IF_L		(0x1 << 22)	/* Master Interface Arbiter Lock */
++#define		ATC_LOCK_IF_L_CHUNK	(0x0 << 22)
++#define		ATC_LOCK_IF_L_BUFFER	(0x1 << 22)
++#define	ATC_AHB_PROT_MASK	(0x7 << 24)	/* AHB Protection */
++#define	ATC_FIFOCFG_MASK	(0x3 << 28)	/* FIFO Request Configuration */
++#define		ATC_FIFOCFG_LARGESTBURST	(0x0 << 28)
++#define		ATC_FIFOCFG_HALFFIFO		(0x1 << 28)
++#define		ATC_FIFOCFG_ENOUGHSPACE		(0x2 << 28)
++
++/* Platform-configurable bits in CTRLA */
++#define	ATC_SCSIZE_MASK		(0x7 << 16)	/* Source Chunk Transfer Size */
++#define		ATC_SCSIZE_1		(0x0 << 16)
++#define		ATC_SCSIZE_4		(0x1 << 16)
++#define		ATC_SCSIZE_8		(0x2 << 16)
++#define		ATC_SCSIZE_16		(0x3 << 16)
++#define		ATC_SCSIZE_32		(0x4 << 16)
++#define		ATC_SCSIZE_64		(0x5 << 16)
++#define		ATC_SCSIZE_128		(0x6 << 16)
++#define		ATC_SCSIZE_256		(0x7 << 16)
++#define	ATC_DCSIZE_MASK		(0x7 << 20)	/* Destination Chunk Transfer Size */
++#define		ATC_DCSIZE_1		(0x0 << 20)
++#define		ATC_DCSIZE_4		(0x1 << 20)
++#define		ATC_DCSIZE_8		(0x2 << 20)
++#define		ATC_DCSIZE_16		(0x3 << 20)
++#define		ATC_DCSIZE_32		(0x4 << 20)
++#define		ATC_DCSIZE_64		(0x5 << 20)
++#define		ATC_DCSIZE_128		(0x6 << 20)
++#define		ATC_DCSIZE_256		(0x7 << 20)
++
+ #endif /* AT_HDMAC_H */
+diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
+index 64dbf0c..9a1e5fb 100644
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -608,6 +608,187 @@ err_desc_get:
+ 	return NULL;
+ }
+ 
++
++/**
++ * atc_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
++ * @chan: DMA channel
++ * @sgl: scatterlist to transfer to/from
++ * @sg_len: number of entries in @scatterlist
++ * @direction: DMA direction
++ * @flags: tx descriptor status flags
++ */
++static struct dma_async_tx_descriptor *
++atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
++		unsigned int sg_len, enum dma_data_direction direction,
++		unsigned long flags)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	struct at_dma_slave	*atslave = chan->private;
++	struct at_desc		*first = NULL;
++	struct at_desc		*prev = NULL;
++	u32			ctrla;
++	u32			ctrlb;
++	dma_addr_t		reg;
++	unsigned int		reg_width;
++	unsigned int		mem_width;
++	unsigned int		i;
++	struct scatterlist	*sg;
++	size_t			total_len = 0;
++
++	dev_vdbg(chan2dev(chan), "prep_slave_sg: %s f0x%lx\n",
++			direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE",
++			flags);
++
++	if (unlikely(!atslave || !sg_len)) {
++		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
++		return NULL;
++	}
++
++	reg_width = atslave->reg_width;
++
++	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);
++
++	ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
++	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;
++
++	switch (direction) {
++	case DMA_TO_DEVICE:
++		ctrla |=  ATC_DST_WIDTH(reg_width);
++		ctrlb |=  ATC_DST_ADDR_MODE_FIXED
++			| ATC_SRC_ADDR_MODE_INCR
++			| ATC_FC_MEM2PER;
++		reg = atslave->tx_reg;
++		for_each_sg(sgl, sg, sg_len, i) {
++			struct at_desc	*desc;
++			u32		len;
++			u32		mem;
++
++			desc = atc_desc_get(atchan);
++			if (!desc)
++				goto err_desc_get;
++
++			mem = sg_phys(sg);
++			len = sg_dma_len(sg);
++			mem_width = 2;
++			if (unlikely(mem & 3 || len & 3))
++				mem_width = 0;
++
++			desc->lli.saddr = mem;
++			desc->lli.daddr = reg;
++			desc->lli.ctrla = ctrla
++					| ATC_SRC_WIDTH(mem_width)
++					| len >> mem_width;
++			desc->lli.ctrlb = ctrlb;
++
++			if (!first) {
++				first = desc;
++			} else {
++				/* inform the HW lli about chaining */
++				prev->lli.dscr = desc->txd.phys;
++				/* insert the link descriptor to the LD ring */
++				list_add_tail(&desc->desc_node,
++						&first->txd.tx_list);
++			}
++			prev = desc;
++			total_len += len;
++		}
++		break;
++	case DMA_FROM_DEVICE:
++		ctrla |=  ATC_SRC_WIDTH(reg_width);
++		ctrlb |=  ATC_DST_ADDR_MODE_INCR
++			| ATC_SRC_ADDR_MODE_FIXED
++			| ATC_FC_PER2MEM;
++
++		reg = atslave->rx_reg;
++		for_each_sg(sgl, sg, sg_len, i) {
++			struct at_desc	*desc;
++			u32		len;
++			u32		mem;
++
++			desc = atc_desc_get(atchan);
++			if (!desc)
++				goto err_desc_get;
++
++			mem = sg_phys(sg);
++			len = sg_dma_len(sg);
++			mem_width = 2;
++			if (unlikely(mem & 3 || len & 3))
++				mem_width = 0;
++
++			desc->lli.saddr = reg;
++			desc->lli.daddr = mem;
++			desc->lli.ctrla = ctrla
++					| ATC_DST_WIDTH(mem_width)
++					| len >> mem_width;
++			desc->lli.ctrlb = ctrlb;
++
++			if (!first) {
++				first = desc;
++			} else {
++				/* inform the HW lli about chaining */
++				prev->lli.dscr = desc->txd.phys;
++				/* insert the link descriptor to the LD ring */
++				list_add_tail(&desc->desc_node,
++						&first->txd.tx_list);
++			}
++			prev = desc;
++			total_len += len;
++		}
++		break;
++	default:
++		return NULL;
++	}
++
++	/* set end-of-link to the last link descriptor of list*/
++	set_desc_eol(prev);
++
++	/* First descriptor of the chain embedds additional information */
++	first->txd.cookie = -EBUSY;
++	first->len = total_len;
++
++	/* last link descriptor of list is responsible of flags */
++	prev->txd.flags = flags; /* client is in control of this ack */
++
++	return &first->txd;
++
++err_desc_get:
++	dev_err(chan2dev(chan), "not enough descriptors available\n");
++	atc_desc_put(atchan, first);
++	return NULL;
++}
++
++static void atc_terminate_all(struct dma_chan *chan)
++{
++	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	struct at_dma		*atdma = to_at_dma(chan->device);
++	struct at_desc		*desc, *_desc;
++	LIST_HEAD(list);
++
++	/*
++	 * This is only called when something went wrong elsewhere, so
++	 * we don't really care about the data. Just disable the
++	 * channel. We still have to poll the channel enable bit due
++	 * to AHB/HSB limitations.
++	 */
++	spin_lock_bh(&atchan->lock);
++
++	dma_writel(atdma, CHDR, atchan->mask);
++
++	/* confirm that this channel is disabled */
++	while (dma_readl(atdma, CHSR) & atchan->mask)
++		cpu_relax();
++
++	/* active_list entries will end up before queued entries */
++	list_splice_init(&atchan->queue, &list);
++	list_splice_init(&atchan->active_list, &list);
++
++	spin_unlock_bh(&atchan->lock);
++
++	/* Flush all pending and queued descriptors */
++	list_for_each_entry_safe(desc, _desc, &list, desc_node)
++		atc_chain_complete(atchan, desc);
++}
++
+ /**
+  * atc_is_tx_complete - poll for transaction completion
+  * @chan: DMA channel
+@@ -686,7 +867,9 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
+ 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
+ 	struct at_dma		*atdma = to_at_dma(chan->device);
+ 	struct at_desc		*desc;
++	struct at_dma_slave	*atslave;
+ 	int			i;
++	u32			cfg;
+ 	LIST_HEAD(tmp_list);
+ 
+ 	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
+@@ -697,7 +880,23 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
+ 		return -EIO;
+ 	}
+ 
+-	/* have we already been set up? */
++	cfg = ATC_DEFAULT_CFG;
++
++	atslave = chan->private;
++	if (atslave) {
++		/*
++		 * We need controller-specific data to set up slave
++		 * transfers.
++		 */
++		BUG_ON(!atslave->dma_dev || atslave->dma_dev != atdma->dma_common.dev);
++
++		/* if cfg configuration specified take it instad of default */
++		if (atslave->cfg)
++			cfg = atslave->cfg;
++	}
++
++	/* have we already been set up?
++	 * reconfigure channel but no need to reallocate descriptors */
+ 	if (!list_empty(&atchan->free_list))
+ 		return atchan->descs_allocated;
+ 
+@@ -719,7 +918,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
+ 	spin_unlock_bh(&atchan->lock);
+ 
+ 	/* channel parameters */
+-	channel_writel(atchan, CFG, ATC_DEFAULT_CFG);
++	channel_writel(atchan, CFG, cfg);
+ 
+ 	dev_dbg(chan2dev(chan),
+ 		"alloc_chan_resources: allocated %d descriptors\n",
+@@ -888,6 +1087,11 @@ static int __init at_dma_probe(struct platform_device *pdev)
+ 	if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
+ 		atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
+ 
++	if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
++		atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
++		atdma->dma_common.device_terminate_all = atc_terminate_all;
++	}
++
+ 	dma_writel(atdma, EN, AT_DMA_ENABLE);
+ 
+ 	dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
+diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
+index ad2d4f4..4c972af 100644
+--- a/drivers/dma/at_hdmac_regs.h
++++ b/drivers/dma/at_hdmac_regs.h
+@@ -87,29 +87,14 @@
+ /* Bitfields in CTRLA */
+ #define	ATC_BTSIZE_MAX		0xFFFFUL	/* Maximum Buffer Transfer Size */
+ #define	ATC_BTSIZE(x)		(ATC_BTSIZE_MAX & (x)) /* Buffer Transfer Size */
+-#define	ATC_SCSIZE_MASK		(0x7 << 16)	/* Source Chunk Transfer Size */
+-#define		ATC_SCSIZE_1		(0x0 << 16)
+-#define		ATC_SCSIZE_4		(0x1 << 16)
+-#define		ATC_SCSIZE_8		(0x2 << 16)
+-#define		ATC_SCSIZE_16		(0x3 << 16)
+-#define		ATC_SCSIZE_32		(0x4 << 16)
+-#define		ATC_SCSIZE_64		(0x5 << 16)
+-#define		ATC_SCSIZE_128		(0x6 << 16)
+-#define		ATC_SCSIZE_256		(0x7 << 16)
+-#define	ATC_DCSIZE_MASK		(0x7 << 20)	/* Destination Chunk Transfer Size */
+-#define		ATC_DCSIZE_1		(0x0 << 20)
+-#define		ATC_DCSIZE_4		(0x1 << 20)
+-#define		ATC_DCSIZE_8		(0x2 << 20)
+-#define		ATC_DCSIZE_16		(0x3 << 20)
+-#define		ATC_DCSIZE_32		(0x4 << 20)
+-#define		ATC_DCSIZE_64		(0x5 << 20)
+-#define		ATC_DCSIZE_128		(0x6 << 20)
+-#define		ATC_DCSIZE_256		(0x7 << 20)
++/* Chunck Tranfer size definitions are in at_hdmac.h */
+ #define	ATC_SRC_WIDTH_MASK	(0x3 << 24)	/* Source Single Transfer Size */
++#define		ATC_SRC_WIDTH(x)	((x) << 24)
+ #define		ATC_SRC_WIDTH_BYTE	(0x0 << 24)
+ #define		ATC_SRC_WIDTH_HALFWORD	(0x1 << 24)
+ #define		ATC_SRC_WIDTH_WORD	(0x2 << 24)
+ #define	ATC_DST_WIDTH_MASK	(0x3 << 28)	/* Destination Single Transfer Size */
++#define		ATC_DST_WIDTH(x)	((x) << 28)
+ #define		ATC_DST_WIDTH_BYTE	(0x0 << 28)
+ #define		ATC_DST_WIDTH_HALFWORD	(0x1 << 28)
+ #define		ATC_DST_WIDTH_WORD	(0x2 << 28)
+@@ -129,7 +114,8 @@
+ #define		ATC_FC_PER2PER		(0x3 << 21)	/* Periph-to-Periph (DMA) */
+ #define		ATC_FC_PER2MEM_PER	(0x4 << 21)	/* Periph-to-Mem (Peripheral) */
+ #define		ATC_FC_MEM2PER_PER	(0x5 << 21)	/* Mem-to-Periph (Peripheral) */
+-#define		ATC_FC_PER2PER_PER	(0x6 << 21)	/* Periph-to-Periph (Src Peripheral) */
++#define		ATC_FC_PER2PER_SRCPER	(0x6 << 21)	/* Periph-to-Periph (Src Peripheral) */
++#define		ATC_FC_PER2PER_DSTPER	(0x7 << 21)	/* Periph-to-Periph (Dst Peripheral) */
+ #define	ATC_SRC_ADDR_MODE_MASK	(0x3 << 24)
+ #define		ATC_SRC_ADDR_MODE_INCR	(0x0 << 24)	/* Incrementing Mode */
+ #define		ATC_SRC_ADDR_MODE_DECR	(0x1 << 24)	/* Decrementing Mode */
+@@ -142,27 +128,7 @@
+ #define	ATC_AUTO		(0x1 << 31)	/* Auto multiple buffer tx enable */
+ 
+ /* Bitfields in CFG */
+-#define	ATC_SRC_PER(h)		(0xFU & (h))	/* Channel src rq associated with periph handshaking ifc h */
+-#define	ATC_DST_PER(h)		((0xFU & (h)) <<  4)	/* Channel dst rq associated with periph handshaking ifc h */
+-#define	ATC_SRC_REP		(0x1 <<  8)	/* Source Replay Mod */
+-#define	ATC_SRC_H2SEL		(0x1 <<  9)	/* Source Handshaking Mod */
+-#define		ATC_SRC_H2SEL_SW	(0x0 <<  9)
+-#define		ATC_SRC_H2SEL_HW	(0x1 <<  9)
+-#define	ATC_DST_REP		(0x1 << 12)	/* Destination Replay Mod */
+-#define	ATC_DST_H2SEL		(0x1 << 13)	/* Destination Handshaking Mod */
+-#define		ATC_DST_H2SEL_SW	(0x0 << 13)
+-#define		ATC_DST_H2SEL_HW	(0x1 << 13)
+-#define	ATC_SOD			(0x1 << 16)	/* Stop On Done */
+-#define	ATC_LOCK_IF		(0x1 << 20)	/* Interface Lock */
+-#define	ATC_LOCK_B		(0x1 << 21)	/* AHB Bus Lock */
+-#define	ATC_LOCK_IF_L		(0x1 << 22)	/* Master Interface Arbiter Lock */
+-#define		ATC_LOCK_IF_L_CHUNK	(0x0 << 22)
+-#define		ATC_LOCK_IF_L_BUFFER	(0x1 << 22)
+-#define	ATC_AHB_PROT_MASK	(0x7 << 24)	/* AHB Protection */
+-#define	ATC_FIFOCFG_MASK	(0x3 << 28)	/* FIFO Request Configuration */
+-#define		ATC_FIFOCFG_LARGESTBURST	(0x0 << 28)
+-#define		ATC_FIFOCFG_HALFFIFO		(0x1 << 28)
+-#define		ATC_FIFOCFG_ENOUGHSPACE		(0x2 << 28)
++/* are in at_hdmac.h */
+ 
+ /* Bitfields in SPIP */
+ #define	ATC_SPIP_HOLE(x)	(0xFFFFU & (x))
+@@ -316,11 +282,12 @@ static void vdbg_dump_regs(struct at_dma_chan *atchan)
+ 		dma_readl(atdma, CHSR));
+ 
+ 	dev_err(chan2dev(&atchan->chan_common),
+-		"  channel: s0x%x d0x%x ctrl0x%x:0x%x l0x%x\n",
++		"  channel: s0x%x d0x%x ctrl0x%x:0x%x cfg0x%x l0x%x\n",
+ 		channel_readl(atchan, SADDR),
+ 		channel_readl(atchan, DADDR),
+ 		channel_readl(atchan, CTRLA),
+ 		channel_readl(atchan, CTRLB),
++		channel_readl(atchan, CFG),
+ 		channel_readl(atchan, DSCR));
+ }
+ #else
+-- 
+1.5.6.5
+
+From ef10a05b2428efd6aec57542e5d3e6495866b8d2 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:34 +0000
+Subject: [PATCH] at91/dmaengine: integration of at_hdmac driver in at91sam9rl
+
+This is the integration of DMA engine driver into at91sam9rl device file. The
+associated driver is at_hdmac.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+(cherry picked from commit 3ea448c18c48fc0442a5ad15eb14163e09fe0d51)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11596 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9rl_devices.c |   47 +++++++++++++++++++++++++++++++
+ 1 files changed, 47 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
+index 7281865..1c2dced 100644
+--- a/arch/arm/mach-at91/at91sam9rl_devices.c
++++ b/arch/arm/mach-at91/at91sam9rl_devices.c
+@@ -21,11 +21,57 @@
+ #include <mach/at91sam9rl.h>
+ #include <mach/at91sam9rl_matrix.h>
+ #include <mach/at91sam9_smc.h>
++#include <mach/at_hdmac.h>
+ 
+ #include "generic.h"
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  HDMAC - AHB DMA Controller
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
++static u64 hdmac_dmamask = DMA_BIT_MASK(32);
++
++static struct at_dma_platform_data atdma_pdata = {
++	.nr_channels	= 2,
++};
++
++static struct resource hdmac_resources[] = {
++	[0] = {
++		.start	= AT91_BASE_SYS + AT91_DMA,
++		.end	= AT91_BASE_SYS + AT91_DMA + SZ_512 - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[2] = {
++		.start	= AT91SAM9RL_ID_DMA,
++		.end	= AT91SAM9RL_ID_DMA,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at_hdmac_device = {
++	.name		= "at_hdmac",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &hdmac_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &atdma_pdata,
++	},
++	.resource	= hdmac_resources,
++	.num_resources	= ARRAY_SIZE(hdmac_resources),
++};
++
++void __init at91_add_device_hdmac(void)
++{
++	dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
++	platform_device_register(&at_hdmac_device);
++}
++#else
++void __init at91_add_device_hdmac(void) {}
++#endif
++
++/* --------------------------------------------------------------------
+  *  USB HS Device (Gadget)
+  * -------------------------------------------------------------------- */
+ 
+@@ -1103,6 +1149,7 @@ void __init at91_add_device_serial(void) {}
+  */
+ static int __init at91_add_standard_devices(void)
+ {
++	at91_add_device_hdmac();
+ 	at91_add_device_rtc();
+ 	at91_add_device_rtt();
+ 	at91_add_device_watchdog();
+-- 
+1.5.6.5
+
+From c34e84cdb67a66cb005e6beebcf984474534f1f3 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:35 +0000
+Subject: [PATCH] at91/dmaengine: integration of at_hdmac driver in at91sam9g45 series
+
+This is the integration of DMA engine driver into at91sam9g45 series
+device file.
+The associated driver is at_hdmac.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+(cherry picked from commit 9a935d5621975fab80c9fc616b42eb696d37c0ab)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11597 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9g45_devices.c |   49 ++++++++++++++++++++++++++++++
+ drivers/dma/Kconfig                      |    2 +-
+ 2 files changed, 50 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index c2ecbb6..5be8cf2 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -24,11 +24,59 @@
+ #include <mach/at91sam9g45.h>
+ #include <mach/at91sam9g45_matrix.h>
+ #include <mach/at91sam9_smc.h>
++#include <mach/at_hdmac.h>
+ 
+ #include "generic.h"
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  HDMAC - AHB DMA Controller
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
++static u64 hdmac_dmamask = DMA_BIT_MASK(32);
++
++static struct at_dma_platform_data atdma_pdata = {
++	.nr_channels	= 8,
++};
++
++static struct resource hdmac_resources[] = {
++	[0] = {
++		.start	= AT91_BASE_SYS + AT91_DMA,
++		.end	= AT91_BASE_SYS + AT91_DMA + SZ_512 - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[2] = {
++		.start	= AT91SAM9G45_ID_DMA,
++		.end	= AT91SAM9G45_ID_DMA,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at_hdmac_device = {
++	.name		= "at_hdmac",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &hdmac_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &atdma_pdata,
++	},
++	.resource	= hdmac_resources,
++	.num_resources	= ARRAY_SIZE(hdmac_resources),
++};
++
++void __init at91_add_device_hdmac(void)
++{
++	dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
++	dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
++	platform_device_register(&at_hdmac_device);
++}
++#else
++void __init at91_add_device_hdmac(void) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+  *  USB Host (OHCI)
+  * -------------------------------------------------------------------- */
+ 
+@@ -1276,6 +1324,7 @@ void __init at91_add_device_serial(void) {}
+  */
+ static int __init at91_add_standard_devices(void)
+ {
++	at91_add_device_hdmac();
+ 	at91_add_device_rtc();
+ 	at91_add_device_rtt();
+ 	at91_add_device_watchdog();
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+index 57ca445..f38eb33 100644
+--- a/drivers/dma/Kconfig
++++ b/drivers/dma/Kconfig
+@@ -48,7 +48,7 @@ config DW_DMAC
+ 
+ config AT_HDMAC
+ 	tristate "Atmel AHB DMA support"
+-	depends on ARCH_AT91SAM9RL
++	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+ 	select DMA_ENGINE
+ 	help
+ 	  Support the Atmel AHB DMA controller.  This can be integrated in
+-- 
+1.5.6.5
+
+From aba15723eef58933ea2f5550dab008fdc2e1dcdb Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:36 +0000
+Subject: [PATCH] atmel-mci: Integrate AT91 specific definition in header file
+
+The MCI IP is shared among AVR32 and AT91 SOCs.
+AT91 has specific bit definitions in the user interface of MCI SD/MMC IP.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Haavard Skinnemoen <haavard.skinnemoen at atmel.com>
+Signed-off-by: Pierre Ossman <pierre at ossman.eu>
+(cherry picked from commit 199118959e9b31cd6cd6492a323669966061033c)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11598 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/atmel-mci-regs.h |   11 +++++++++++
+ 1 files changed, 11 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
+index b58364e..adfb885 100644
+--- a/drivers/mmc/host/atmel-mci-regs.h
++++ b/drivers/mmc/host/atmel-mci-regs.h
+@@ -7,6 +7,11 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
++
++/*
++ * Superset of MCI IP registers integrated in Atmel AVR32 and AT91 Processors
++ */
++
+ #ifndef __DRIVERS_MMC_ATMEL_MCI_H__
+ #define __DRIVERS_MMC_ATMEL_MCI_H__
+ 
+@@ -14,11 +19,17 @@
+ #define MCI_CR			0x0000	/* Control */
+ # define MCI_CR_MCIEN		(  1 <<  0)	/* MCI Enable */
+ # define MCI_CR_MCIDIS		(  1 <<  1)	/* MCI Disable */
++# define MCI_CR_PWSEN		(  1 <<  2)	/* Power Save Enable */
++# define MCI_CR_PWSDIS		(  1 <<  3)	/* Power Save Disable */
+ # define MCI_CR_SWRST		(  1 <<  7)	/* Software Reset */
+ #define MCI_MR			0x0004	/* Mode */
+ # define MCI_MR_CLKDIV(x)	((x) <<  0)	/* Clock Divider */
++# define MCI_MR_PWSDIV(x)	((x) <<  8)	/* Power Saving Divider */
+ # define MCI_MR_RDPROOF		(  1 << 11)	/* Read Proof */
+ # define MCI_MR_WRPROOF		(  1 << 12)	/* Write Proof */
++# define MCI_MR_PDCFBYTE	(  1 << 13)	/* Force Byte Transfer */
++# define MCI_MR_PDCPADV		(  1 << 14)	/* Padding Value */
++# define MCI_MR_PDCMODE		(  1 << 15)	/* PDC-oriented Mode */
+ #define MCI_DTOR		0x0008	/* Data Timeout */
+ # define MCI_DTOCYC(x)		((x) <<  0)	/* Data Timeout Cycles */
+ # define MCI_DTOMUL(x)		((x) <<  4)	/* Data Timeout Multiplier */
+-- 
+1.5.6.5
+
+From 928e3bf527127ed267aa5c4dd620bbd87a993bc7 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:36 +0000
+Subject: [PATCH] atmel-mci: add MCI2 register definitions
+
+New revision of Atmel MCI interface adds new features. This is a update of
+register definition in header file. This new MCI IP is called MCI2.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Acked-by: Haavard Skinnemoen <haavard.skinnemoen at atmel.com>
+Signed-off-by: Pierre Ossman <pierre at ossman.eu>
+(cherry picked from commit 7f72134c32eb64c77d1fb35123ba8bf815bf797c)
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11599 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/atmel-mci-regs.h |   22 ++++++++++++++++++++++
+ 1 files changed, 22 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
+index adfb885..fc8a0fe 100644
+--- a/drivers/mmc/host/atmel-mci-regs.h
++++ b/drivers/mmc/host/atmel-mci-regs.h
+@@ -10,6 +10,7 @@
+ 
+ /*
+  * Superset of MCI IP registers integrated in Atmel AVR32 and AT91 Processors
++ * Registers and bitfields marked with [2] are only available in MCI2
+  */
+ 
+ #ifndef __DRIVERS_MMC_ATMEL_MCI_H__
+@@ -39,6 +40,7 @@
+ # define MCI_SDCSEL_MASK	(  3 <<  0)
+ # define MCI_SDCBUS_1BIT	(  0 <<  6)	/* 1-bit data bus */
+ # define MCI_SDCBUS_4BIT	(  2 <<  6)	/* 4-bit data bus */
++# define MCI_SDCBUS_8BIT	(  3 <<  6)	/* 8-bit data bus[2] */
+ # define MCI_SDCBUS_MASK	(  3 <<  6)
+ #define MCI_ARGR		0x0010	/* Command Argument */
+ #define MCI_CMDR		0x0014	/* Command */
+@@ -67,6 +69,9 @@
+ #define MCI_BLKR		0x0018	/* Block */
+ # define MCI_BCNT(x)		((x) <<  0)	/* Data Block Count */
+ # define MCI_BLKLEN(x)		((x) << 16)	/* Data Block Length */
++#define MCI_CSTOR		0x001c	/* Completion Signal Timeout[2] */
++# define MCI_CSTOCYC(x)		((x) <<  0)	/* CST cycles */
++# define MCI_CSTOMUL(x)		((x) <<  4)	/* CST multiplier */
+ #define MCI_RSPR		0x0020	/* Response 0 */
+ #define MCI_RSPR1		0x0024	/* Response 1 */
+ #define MCI_RSPR2		0x0028	/* Response 2 */
+@@ -94,7 +99,24 @@
+ # define MCI_DTOE		(  1 <<  22)	/* Data Time-Out Error */
+ # define MCI_OVRE		(  1 <<  30)	/* RX Overrun Error */
+ # define MCI_UNRE		(  1 <<  31)	/* TX Underrun Error */
++#define MCI_DMA			0x0050	/* DMA Configuration[2] */
++# define MCI_DMA_OFFSET(x)	((x) <<  0)	/* DMA Write Buffer Offset */
++# define MCI_DMA_CHKSIZE(x)	((x) <<  4)	/* DMA Channel Read and Write Chunk Size */
++# define MCI_DMAEN		(  1 <<  8)	/* DMA Hardware Handshaking Enable */
++#define MCI_CFG			0x0054	/* Configuration[2] */
++# define MCI_CFG_FIFOMODE_1DATA	(  1 <<  0)	/* MCI Internal FIFO control mode */
++# define MCI_CFG_FERRCTRL_COR	(  1 <<  4)	/* Flow Error flag reset control mode */
++# define MCI_CFG_HSMODE		(  1 <<  8)	/* High Speed Mode */
++# define MCI_CFG_LSYNC		(  1 << 12)	/* Synchronize on the last block */
++#define MCI_WPMR		0x00e4	/* Write Protection Mode[2] */
++# define MCI_WP_EN		(  1 <<  0)	/* WP Enable */
++# define MCI_WP_KEY		(0x4d4349 << 8)	/* WP Key */
++#define MCI_WPSR		0x00e8	/* Write Protection Status[2] */
++# define MCI_GET_WP_VS(x)	((x) & 0x0f)
++# define MCI_GET_WP_VSRC(x)	(((x) >> 8) & 0xffff)
++#define MCI_FIFO_APERTURE	0x0200	/* FIFO Aperture[2] */
+ 
++/* This is not including the FIFO Aperture on MCI2 */
+ #define MCI_REGS_SIZE		0x100
+ 
+ /* Register access macros */
+-- 
+1.5.6.5
+
+From 2e55d7a62af67e62b21157079325a522bb721d15 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:37 +0000
+Subject: [PATCH] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91)
+
+Unification of the atmel-mci driver to support the AT91 processors MCI
+interface.  The atmel-mci driver currently supports the AVR32 and this patch
+adds AT91 support.
+Add read/write proof selection switch dependent on chip availability of this
+feature.
+
+To use this new driver on a at91 the platform driver for your board needs to
+updated.
+
+Signed-off-by: Rob Emanuele <rob at emanuele.us>
+[nicolas.ferre at atmel.com indent, Kconfig comment and one printk modification]
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11600 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/Kconfig     |   16 ++++++++++++----
+ drivers/mmc/host/atmel-mci.c |   33 ++++++++++++++++++++++++++++++---
+ 2 files changed, 42 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index b4cf691..e779049 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -124,6 +124,12 @@ config MMC_AU1X
+ 
+ 	  If unsure, say N.
+ 
++choice
++	prompt "Atmel SD/MMC Driver"
++	default MMC_ATMELMCI if AVR32
++	help
++	  Choose which driver to use for the Atmel MCI Silicon
++
+ config MMC_AT91
+ 	tristate "AT91 SD/MMC Card Interface support"
+ 	depends on ARCH_AT91
+@@ -134,17 +140,19 @@ config MMC_AT91
+ 
+ config MMC_ATMELMCI
+ 	tristate "Atmel Multimedia Card Interface support"
+-	depends on AVR32
++	depends on AVR32 || ARCH_AT91
+ 	help
+ 	  This selects the Atmel Multimedia Card Interface driver. If
+-	  you have an AT32 (AVR32) platform with a Multimedia Card
+-	  slot, say Y or M here.
++	  you have an AT32 (AVR32) or AT91 platform with a Multimedia
++	  Card slot, say Y or M here.
+ 
+ 	  If unsure, say N.
+ 
++endchoice
++
+ config MMC_ATMELMCI_DMA
+ 	bool "Atmel MCI DMA support (EXPERIMENTAL)"
+-	depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL
++	depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL
+ 	help
+ 	  Say Y here to have the Atmel MCI driver use a DMA engine to
+ 	  do data transfers and thus increase the throughput and
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index cf6a100..2b4d855 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -30,6 +30,7 @@
+ #include <asm/io.h>
+ #include <asm/unaligned.h>
+ 
++#include <mach/cpu.h>
+ #include <mach/board.h>
+ 
+ #include "atmel-mci-regs.h"
+@@ -208,6 +209,18 @@ struct atmel_mci_slot {
+ 	set_bit(event, &host->pending_events)
+ 
+ /*
++ * Enable or disable features/registers based on
++ * whether the processor supports them
++ */
++static bool mci_has_rwproof(void)
++{
++	if (cpu_is_at91sam9261() || cpu_is_at91rm9200())
++		return false;
++	else
++		return true;
++}
++
++/*
+  * The debugfs stuff below is mostly optimized away when
+  * CONFIG_DEBUG_FS is not set.
+  */
+@@ -274,8 +287,13 @@ static void atmci_show_status_reg(struct seq_file *s,
+ 		[3]	= "BLKE",
+ 		[4]	= "DTIP",
+ 		[5]	= "NOTBUSY",
++		[6]	= "ENDRX",
++		[7]	= "ENDTX",
+ 		[8]	= "SDIOIRQA",
+ 		[9]	= "SDIOIRQB",
++		[12]	= "SDIOWAIT",
++		[14]	= "RXBUFF",
++		[15]	= "TXBUFE",
+ 		[16]	= "RINDE",
+ 		[17]	= "RDIRE",
+ 		[18]	= "RCRCE",
+@@ -283,6 +301,11 @@ static void atmci_show_status_reg(struct seq_file *s,
+ 		[20]	= "RTOE",
+ 		[21]	= "DCRCE",
+ 		[22]	= "DTOE",
++		[23]	= "CSTOE",
++		[24]	= "BLKOVRE",
++		[25]	= "DMADONE",
++		[26]	= "FIFOEMPTY",
++		[27]	= "XFRDONE",
+ 		[30]	= "OVRE",
+ 		[31]	= "UNRE",
+ 	};
+@@ -847,13 +870,15 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 			clkdiv = 255;
+ 		}
+ 
++		host->mode_reg = MCI_MR_CLKDIV(clkdiv);
++
+ 		/*
+ 		 * WRPROOF and RDPROOF prevent overruns/underruns by
+ 		 * stopping the clock when the FIFO is full/empty.
+ 		 * This state is not expected to last for long.
+ 		 */
+-		host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF
+-					| MCI_MR_RDPROOF;
++		if (mci_has_rwproof())
++			host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF);
+ 
+ 		if (list_empty(&host->queue))
+ 			mci_writel(host, MR, host->mode_reg);
+@@ -1642,8 +1667,10 @@ static int __init atmci_probe(struct platform_device *pdev)
+ 			nr_slots++;
+ 	}
+ 
+-	if (!nr_slots)
++	if (!nr_slots) {
++		dev_err(&pdev->dev, "init failed: no slot defined\n");
+ 		goto err_init_slot;
++	}
+ 
+ 	dev_info(&pdev->dev,
+ 			"Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
+-- 
+1.5.6.5
+
+From 2fa101b6a6ab6055229520901fc36c94a6b1ae54 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:38 +0000
+Subject: [PATCH] AT91: atmel-mci: Platform configuration to the the atmel-mci driver
+
+Created a modified version of the at91sam9g20 evaluation kit platform
+(board-sam9g20ek-2slot-mmc.c) and device support to make use of the updated
+atmel-mci driver.
+As the use of two slots modify GPIO pin allocation, we create another board
+file.
+
+Signed-off-by: Rob Emanuele <rob at emanuele.us>
+[nicolas.ferre at atmel.com: printk, slot_count modification in at91sam9260_devices.c file]
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11601 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/Kconfig                     |    7 +
+ arch/arm/mach-at91/Makefile                    |    1 +
+ arch/arm/mach-at91/at91sam9260_devices.c       |   96 ++++++++
+ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c |  277 ++++++++++++++++++++++++
+ arch/arm/mach-at91/include/mach/board.h        |    5 +
+ 5 files changed, 386 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index e844fde..98eed85 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -361,6 +361,13 @@ config MACH_AT91SAM9G20EK
+ 	help
+ 	  Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
+ 
++config MACH_AT91SAM9G20EK_2MMC
++	bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots"
++	depends on ARCH_AT91SAM9G20
++	help
++	  Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
++	  Rev A or B modified for 2 MMC Slots.
++
+ config MACH_USB_A9G20
+ 	bool "CALAO USB-A9G20"
+ 	depends on ARCH_AT91SAM9G20
+diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
+index 56c6381..761098e 100644
+--- a/arch/arm/mach-at91/Makefile
++++ b/arch/arm/mach-at91/Makefile
+@@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK)	+= board-sam9rlek.o
+ 
+ # AT91SAM9G20 board-specific support
+ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
++obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o
+ obj-$(CONFIG_MACH_USB_A9G20)	 += board-usb-a9g20.o
+ obj-$(CONFIG_MACH_QIL_A9G20)	 += board-qil-a9g20.o
+ obj-$(CONFIG_MACH_SBC35_A9G20)	 += board-sbc35-a9g20.o
+diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
+index 30222d4..06239ec 100644
+--- a/arch/arm/mach-at91/at91sam9260_devices.c
++++ b/arch/arm/mach-at91/at91sam9260_devices.c
+@@ -424,6 +424,102 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+ #endif
+ 
++/* --------------------------------------------------------------------
++ *  MMC / SD Slot for Atmel MCI Driver
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
++static u64 mmc_dmamask = DMA_BIT_MASK(32);
++static struct mci_platform_data mmc_data;
++
++static struct resource mmc_resources[] = {
++	[0] = {
++		.start	= AT91SAM9260_BASE_MCI,
++		.end	= AT91SAM9260_BASE_MCI + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9260_ID_MCI,
++		.end	= AT91SAM9260_ID_MCI,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9260_mmc_device = {
++	.name		= "atmel_mci",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &mmc_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &mmc_data,
++	},
++	.resource	= mmc_resources,
++	.num_resources	= ARRAY_SIZE(mmc_resources),
++};
++
++void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
++{
++	unsigned int i;
++	unsigned int slot_count = 0;
++
++	if (!data)
++		return;
++
++	for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
++		if (data->slot[i].bus_width) {
++			/* input/irq */
++			if (data->slot[i].detect_pin) {
++				at91_set_gpio_input(data->slot[i].detect_pin, 1);
++				at91_set_deglitch(data->slot[i].detect_pin, 1);
++			}
++			if (data->slot[i].wp_pin)
++				at91_set_gpio_input(data->slot[i].wp_pin, 1);
++
++			switch(i) {
++			case 0:
++				/* CMD */
++				at91_set_A_periph(AT91_PIN_PA7, 1);
++				/* DAT0, maybe DAT1..DAT3 */
++				at91_set_A_periph(AT91_PIN_PA6, 1);
++				if (data->slot[i].bus_width == 4) {
++					at91_set_A_periph(AT91_PIN_PA9, 1);
++					at91_set_A_periph(AT91_PIN_PA10, 1);
++					at91_set_A_periph(AT91_PIN_PA11, 1);
++				}
++				slot_count++;
++				break;
++			case 1:
++				/* CMD */
++				at91_set_B_periph(AT91_PIN_PA1, 1);
++				/* DAT0, maybe DAT1..DAT3 */
++				at91_set_B_periph(AT91_PIN_PA0, 1);
++				if (data->slot[i].bus_width == 4) {
++					at91_set_B_periph(AT91_PIN_PA5, 1);
++					at91_set_B_periph(AT91_PIN_PA4, 1);
++					at91_set_B_periph(AT91_PIN_PA3, 1);
++				}
++				slot_count++;
++				break;
++			default:
++				printk(KERN_ERR
++					"AT91: SD/MMC slot %d not available\n", i);
++				break;
++			}
++		}
++	}
++
++	if (slot_count) {
++		/* CLK */
++		at91_set_A_periph(AT91_PIN_PA8, 0);
++
++		mmc_data = *data;
++		platform_device_register(&at91sam9260_mmc_device);
++	}
++}
++#else
++void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
++#endif
++
+ 
+ /* --------------------------------------------------------------------
+  *  NAND / SmartMedia
+diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+new file mode 100644
+index 0000000..a28e53f
+--- /dev/null
++++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+@@ -0,0 +1,277 @@
++/*
++ *  Copyright (C) 2005 SAN People
++ *  Copyright (C) 2008 Atmel
++ *  Copyright (C) 2009 Rob Emanuele
++ *
++ * 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.
++ *
++ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/at73c213.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++
++static void __init ek_map_io(void)
++{
++	/* Initialize processor: 18.432 MHz crystal */
++	at91sam9260_initialize(18432000);
++
++	/* DGBU on ttyS0. (Rx & Tx only) */
++	at91_register_uart(0, 0, 0);
++
++	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
++	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
++			   | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
++			   | ATMEL_UART_RI);
++
++	/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
++	at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
++
++	/* set serial console to ttyS0 (ie, DBGU) */
++	at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++	at91sam9260_init_interrupts(NULL);
++}
++
++
++/*
++ * USB Host port
++ */
++static struct at91_usbh_data __initdata ek_usbh_data = {
++	.ports		= 2,
++};
++
++/*
++ * USB Device port
++ */
++static struct at91_udc_data __initdata ek_udc_data = {
++	.vbus_pin	= AT91_PIN_PC5,
++	.pullup_pin	= 0,		/* pull-up driven by UDC */
++};
++
++
++/*
++ * SPI devices.
++ */
++static struct spi_board_info ek_spi_devices[] = {
++#if !defined(CONFIG_MMC_ATMELMCI)
++	{	/* DataFlash chip */
++		.modalias	= "mtd_dataflash",
++		.chip_select	= 1,
++		.max_speed_hz	= 15 * 1000 * 1000,
++		.bus_num	= 0,
++	},
++#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
++	{	/* DataFlash card */
++		.modalias	= "mtd_dataflash",
++		.chip_select	= 0,
++		.max_speed_hz	= 15 * 1000 * 1000,
++		.bus_num	= 0,
++	},
++#endif
++#endif
++};
++
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++	.phy_irq_pin	= AT91_PIN_PC12,
++	.is_rmii	= 1,
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++	{
++		.name   = "Bootstrap",
++		.offset = 0,
++		.size   = 4 * SZ_1M,
++	},
++	{
++		.name	= "Partition 1",
++		.offset	= MTDPART_OFS_NXTBLK,
++		.size	= 60 * SZ_1M,
++	},
++	{
++		.name	= "Partition 2",
++		.offset	= MTDPART_OFS_NXTBLK,
++		.size	= MTDPART_SIZ_FULL,
++	},
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++	*num_partitions = ARRAY_SIZE(ek_nand_partition);
++	return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++	.ale		= 21,
++	.cle		= 22,
++	.rdy_pin	= AT91_PIN_PC13,
++	.enable_pin	= AT91_PIN_PC14,
++	.partition_info	= nand_partitions,
++#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
++	.bus_width_16	= 1,
++#else
++	.bus_width_16	= 0,
++#endif
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++	.ncs_read_setup		= 0,
++	.nrd_setup		= 2,
++	.ncs_write_setup	= 0,
++	.nwe_setup		= 2,
++
++	.ncs_read_pulse		= 4,
++	.nrd_pulse		= 4,
++	.ncs_write_pulse	= 4,
++	.nwe_pulse		= 4,
++
++	.read_cycle		= 7,
++	.write_cycle		= 7,
++
++	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
++	.tdf_cycles		= 3,
++};
++
++static void __init ek_add_device_nand(void)
++{
++	/* setup bus-width (8 or 16) */
++	if (ek_nand_data.bus_width_16)
++		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
++	else
++		ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
++
++	/* configure chip-select 3 (NAND) */
++	sam9_smc_configure(3, &ek_nand_smc_config);
++
++	at91_add_device_nand(&ek_nand_data);
++}
++
++
++/*
++ * MCI (SD/MMC)
++ * det_pin and wp_pin are not connected
++ */
++#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
++static struct mci_platform_data __initdata ek_mmc_data = {
++	.slot[0] = {
++		.bus_width	= 4,
++		.detect_pin	= -ENODEV,
++		.wp_pin		= -ENODEV,
++	},
++	.slot[1] = {
++		.bus_width	= 4,
++		.detect_pin	= -ENODEV,
++		.wp_pin		= -ENODEV,
++	},
++
++};
++#else
++static struct amci_platform_data __initdata ek_mmc_data = {
++};
++#endif
++
++/*
++ * LEDs
++ */
++static struct gpio_led ek_leds[] = {
++	{	/* "bottom" led, green, userled1 to be defined */
++		.name			= "ds5",
++		.gpio			= AT91_PIN_PB12,
++		.active_low		= 1,
++		.default_trigger	= "none",
++	},
++	{	/* "power" led, yellow */
++		.name			= "ds1",
++		.gpio			= AT91_PIN_PB13,
++		.default_trigger	= "heartbeat",
++	}
++};
++
++static struct i2c_board_info __initdata ek_i2c_devices[] = {
++	{
++		I2C_BOARD_INFO("24c512", 0x50),
++	},
++};
++
++
++static void __init ek_board_init(void)
++{
++	/* Serial */
++	at91_add_device_serial();
++	/* USB Host */
++	at91_add_device_usbh(&ek_usbh_data);
++	/* USB Device */
++	at91_add_device_udc(&ek_udc_data);
++	/* SPI */
++	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++	/* NAND */
++	ek_add_device_nand();
++	/* Ethernet */
++	at91_add_device_eth(&ek_macb_data);
++	/* MMC */
++	at91_add_device_mci(0, &ek_mmc_data);
++	/* I2C */
++	at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
++	/* LEDs */
++	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++	/* PCK0 provides MCLK to the WM8731 */
++	at91_set_B_periph(AT91_PIN_PC1, 0);
++	/* SSC (for WM8731) */
++	at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
++}
++
++MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
++	/* Maintainer: Rob Emanuele */
++	.phys_io	= AT91_BASE_SYS,
++	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++	.boot_params	= AT91_SDRAM_BASE + 0x100,
++	.timer		= &at91sam926x_timer,
++	.map_io		= ek_map_io,
++	.init_irq	= ek_init_irq,
++	.init_machine	= ek_board_init,
++MACHINE_END
+diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
+index ce31746..9daecc6 100644
+--- a/arch/arm/mach-at91/include/mach/board.h
++++ b/arch/arm/mach-at91/include/mach/board.h
+@@ -37,6 +37,7 @@
+ #include <linux/leds.h>
+ #include <linux/spi/spi.h>
+ #include <linux/usb/atmel_usba_udc.h>
++#include <linux/atmel-mci.h>
+ 
+  /* USB Device */
+ struct at91_udc_data {
+@@ -63,6 +64,7 @@ struct at91_cf_data {
+ extern void __init at91_add_device_cf(struct at91_cf_data *data);
+ 
+  /* MMC / SD */
++  /* at91_mci platform config */
+ struct at91_mmc_data {
+ 	u8		det_pin;	/* card detect IRQ */
+ 	unsigned	slot_b:1;	/* uses Slot B */
+@@ -72,6 +74,9 @@ struct at91_mmc_data {
+ };
+ extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
+ 
++  /* atmel-mci platform config */
++extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data);
++
+  /* Ethernet (EMAC & MACB) */
+ struct at91_eth_data {
+ 	u32		phy_mask;
+-- 
+1.5.6.5
+
+From e64886ba2203542004e250272148e3a621165d10 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:39 +0000
+Subject: [PATCH] atmel-mci: change use of dma slave interface
+
+Allow the use of another DMA controller driver in atmel-mci sd/mmc driver. This
+adds a generic dma_slave pointer to the mci platform structure where we can
+store DMA controller information. In atmel-mci we use information provided by
+this structure to initialize the driver (with new helper functions that are
+architecture dependant).
+This also adds at32/avr32 chip modifications to cope with this new access
+method.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11602 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/avr32/mach-at32ap/at32ap700x.c |    6 ++-
+ drivers/mmc/host/atmel-mci.c        |   82 ++++++++++++++++++++++++++---------
+ include/linux/atmel-mci.h           |    3 +-
+ 3 files changed, 68 insertions(+), 23 deletions(-)
+
+diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
+index eb9d4dc..d1fe145 100644
+--- a/arch/avr32/mach-at32ap/at32ap700x.c
++++ b/arch/avr32/mach-at32ap/at32ap700x.c
+@@ -1320,7 +1320,7 @@ struct platform_device *__init
+ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
+ {
+ 	struct platform_device		*pdev;
+-	struct dw_dma_slave		*dws = &data->dma_slave;
++	struct dw_dma_slave		*dws;
+ 	u32				pioa_mask;
+ 	u32				piob_mask;
+ 
+@@ -1339,6 +1339,8 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
+ 				ARRAY_SIZE(atmel_mci0_resource)))
+ 		goto fail;
+ 
++	dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
++
+ 	dws->dma_dev = &dw_dmac0_device.dev;
+ 	dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
+ 	dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
+@@ -1346,6 +1348,8 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
+ 	dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
+ 				| DWC_CFGL_HS_SRC_POL);
+ 
++	data->dma_slave = dws;
++
+ 	if (platform_device_add_data(pdev, data,
+ 				sizeof(struct mci_platform_data)))
+ 		goto fail;
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index 2b4d855..2bcd08f 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -1569,16 +1569,71 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot,
+ }
+ 
+ #ifdef CONFIG_MMC_ATMELMCI_DMA
+-static bool filter(struct dma_chan *chan, void *slave)
++static struct device *find_slave_dev(void *slave)
++{
++	if (!slave)
++		return NULL;
++
++	if (cpu_is_at32ap7000())
++		return ((struct dw_dma_slave *)slave)->dma_dev;
++	else
++		return ((struct at_dma_slave *)slave)->dma_dev;
++}
++
++static void setup_dma_addr(struct mci_platform_data *pdata,
++			dma_addr_t tx_addr, dma_addr_t rx_addr)
+ {
+-	struct dw_dma_slave *dws = slave;
++	if (!pdata)
++		return;
++
++	if (cpu_is_at32ap7000()) {
++		struct dw_dma_slave *dws = pdata->dma_slave;
++
++		dws->tx_reg = tx_addr;
++		dws->rx_reg = rx_addr;
++	} else {
++		struct at_dma_slave *ats = pdata->dma_slave;
+ 
+-	if (dws->dma_dev == chan->device->dev) {
+-		chan->private = dws;
++		ats->tx_reg = tx_addr;
++		ats->rx_reg = rx_addr;
++	}
++}
++
++static bool filter(struct dma_chan *chan, void *slave)
++{
++	if (find_slave_dev(slave) == chan->device->dev) {
++		chan->private = slave;
+ 		return true;
+-	} else
++	} else {
+ 		return false;
++	}
++}
++
++static void atmci_configure_dma(struct atmel_mci *host)
++{
++	struct mci_platform_data	*pdata;
++
++	if (host == NULL)
++		return;
++
++	pdata = host->pdev->dev.platform_data;
++
++	if (pdata && find_slave_dev(pdata->dma_slave)) {
++		dma_cap_mask_t mask;
++
++		setup_dma_addr(pdata, host->mapbase + MCI_TDR,
++				      host->mapbase + MCI_RDR);
++
++		/* Try to grab a DMA channel */
++		dma_cap_zero(mask);
++		dma_cap_set(DMA_SLAVE, mask);
++		host->dma.chan = dma_request_channel(mask, filter, pdata->dma_slave);
++	}
++	if (!host->dma.chan)
++		dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
+ }
++#else
++static void atmci_configure_dma(struct atmel_mci *host) {}
+ #endif
+ 
+ static int __init atmci_probe(struct platform_device *pdev)
+@@ -1632,22 +1687,7 @@ static int __init atmci_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto err_request_irq;
+ 
+-#ifdef CONFIG_MMC_ATMELMCI_DMA
+-	if (pdata->dma_slave.dma_dev) {
+-		struct dw_dma_slave *dws = &pdata->dma_slave;
+-		dma_cap_mask_t mask;
+-
+-		dws->tx_reg = regs->start + MCI_TDR;
+-		dws->rx_reg = regs->start + MCI_RDR;
+-
+-		/* Try to grab a DMA channel */
+-		dma_cap_zero(mask);
+-		dma_cap_set(DMA_SLAVE, mask);
+-		host->dma.chan = dma_request_channel(mask, filter, dws);
+-	}
+-	if (!host->dma.chan)
+-		dev_notice(&pdev->dev, "DMA not available, using PIO\n");
+-#endif /* CONFIG_MMC_ATMELMCI_DMA */
++	atmci_configure_dma(host);
+ 
+ 	platform_set_drvdata(pdev, host);
+ 
+diff --git a/include/linux/atmel-mci.h b/include/linux/atmel-mci.h
+index 2f1f957..2ba3179 100644
+--- a/include/linux/atmel-mci.h
++++ b/include/linux/atmel-mci.h
+@@ -4,6 +4,7 @@
+ #define ATMEL_MCI_MAX_NR_SLOTS	2
+ 
+ #include <linux/dw_dmac.h>
++#include <mach/at_hdmac.h>
+ 
+ /**
+  * struct mci_slot_pdata - board-specific per-slot configuration
+@@ -32,7 +33,7 @@ struct mci_slot_pdata {
+  * @slot: Per-slot configuration data.
+  */
+ struct mci_platform_data {
+-	struct dw_dma_slave	dma_slave;
++	void			*dma_slave;
+ 	struct mci_slot_pdata	slot[ATMEL_MCI_MAX_NR_SLOTS];
+ };
+ 
+-- 
+1.5.6.5
+
+From 075ea8051a80ce26a6e5146d62b8a81d9ba0c875 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:39 +0000
+Subject: [PATCH] mmc: atmel-mci: New MCI2 module support in atmel-mci driver
+
+This new revision of the IP adds some improvements to the MCI already present
+in several Atmel SOC.
+Some new registers are added and a particular way of handling DMA interaction
+lead to a new sequence in function call which is backward compatible: On MCI2,
+we must set the DMAEN bit to enable the DMA handshaking interface. This must
+happen before the data transfer command is sent.
+
+A new function is able to differentiate MCI2 code and is based on knowledge of
+processor id (cpu_is_xxx()).
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11603 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/atmel-mci.c |   85 +++++++++++++++++++++++++++++++++++++-----
+ 1 files changed, 75 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index 2bcd08f..c79422e 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -92,6 +92,7 @@ struct atmel_mci_dma {
+  * @need_clock_update: Update the clock rate before the next request.
+  * @need_reset: Reset controller before next request.
+  * @mode_reg: Value of the MR register.
++ * @cfg_reg: Value of the CFG register.
+  * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
+  *	rate and timeout calculations.
+  * @mapbase: Physical address of the MMIO registers.
+@@ -155,6 +156,7 @@ struct atmel_mci {
+ 	bool			need_clock_update;
+ 	bool			need_reset;
+ 	u32			mode_reg;
++	u32			cfg_reg;
+ 	unsigned long		bus_hz;
+ 	unsigned long		mapbase;
+ 	struct clk		*mck;
+@@ -221,6 +223,19 @@ static bool mci_has_rwproof(void)
+ }
+ 
+ /*
++ * The new MCI2 module isn't 100% compatible with the old MCI module,
++ * and it has a few nice features which we want to use...
++ */
++static inline bool atmci_is_mci2(void)
++{
++	if (cpu_is_at91sam9g45())
++		return true;
++
++	return false;
++}
++
++
++/*
+  * The debugfs stuff below is mostly optimized away when
+  * CONFIG_DEBUG_FS is not set.
+  */
+@@ -355,12 +370,33 @@ static int atmci_regs_show(struct seq_file *s, void *v)
+ 			buf[MCI_BLKR / 4],
+ 			buf[MCI_BLKR / 4] & 0xffff,
+ 			(buf[MCI_BLKR / 4] >> 16) & 0xffff);
++	if (atmci_is_mci2())
++		seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]);
+ 
+ 	/* Don't read RSPR and RDR; it will consume the data there */
+ 
+ 	atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
+ 	atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
+ 
++	if (atmci_is_mci2()) {
++		u32 val;
++
++		val = buf[MCI_DMA / 4];
++		seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n",
++				val, val & 3,
++				((val >> 4) & 3) ?
++					1 << (((val >> 4) & 3) + 1) : 1,
++				val & MCI_DMAEN ? " DMAEN" : "");
++
++		val = buf[MCI_CFG / 4];
++		seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n",
++				val,
++				val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
++				val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
++				val & MCI_CFG_HSMODE ? " HSMODE" : "",
++				val & MCI_CFG_LSYNC ? " LSYNC" : "");
++	}
++
+ 	kfree(buf);
+ 
+ 	return 0;
+@@ -555,6 +591,10 @@ static void atmci_dma_complete(void *arg)
+ 
+ 	dev_vdbg(&host->pdev->dev, "DMA complete\n");
+ 
++	if (atmci_is_mci2())
++		/* Disable DMA hardware handshaking on MCI */
++		mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN);
++
+ 	atmci_dma_cleanup(host);
+ 
+ 	/*
+@@ -590,7 +630,7 @@ static void atmci_dma_complete(void *arg)
+ }
+ 
+ static int
+-atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
++atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
+ {
+ 	struct dma_chan			*chan;
+ 	struct dma_async_tx_descriptor	*desc;
+@@ -621,6 +661,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
+ 	if (!chan)
+ 		return -ENODEV;
+ 
++	if (atmci_is_mci2())
++		mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN);
++
+ 	if (data->flags & MMC_DATA_READ)
+ 		direction = DMA_FROM_DEVICE;
+ 	else
+@@ -635,21 +678,30 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
+ 	host->dma.data_desc = desc;
+ 	desc->callback = atmci_dma_complete;
+ 	desc->callback_param = host;
+-	desc->tx_submit(desc);
+-
+-	/* Go! */
+-	chan->device->device_issue_pending(chan);
+ 
+ 	return 0;
+ }
+ 
++static void atmci_submit_data(struct atmel_mci *host)
++{
++	struct dma_chan			*chan = host->data_chan;
++	struct dma_async_tx_descriptor	*desc = host->dma.data_desc;
++
++	if (chan) {
++		desc->tx_submit(desc);
++		chan->device->device_issue_pending(chan);
++	}
++}
++
+ #else /* CONFIG_MMC_ATMELMCI_DMA */
+ 
+-static int atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
++static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
+ {
+ 	return -ENOSYS;
+ }
+ 
++static void atmci_submit_data(struct atmel_mci *host) {}
++
+ static void atmci_stop_dma(struct atmel_mci *host)
+ {
+ 	/* Data transfer was stopped by the interrupt handler */
+@@ -663,7 +715,7 @@ static void atmci_stop_dma(struct atmel_mci *host)
+  * Returns a mask of interrupt flags to be enabled after the whole
+  * request has been prepared.
+  */
+-static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
++static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
+ {
+ 	u32 iflags;
+ 
+@@ -674,7 +726,7 @@ static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
+ 	host->data = data;
+ 
+ 	iflags = ATMCI_DATA_ERROR_FLAGS;
+-	if (atmci_submit_data_dma(host, data)) {
++	if (atmci_prepare_data_dma(host, data)) {
+ 		host->data_chan = NULL;
+ 
+ 		/*
+@@ -720,6 +772,8 @@ static void atmci_start_request(struct atmel_mci *host,
+ 		mci_writel(host, CR, MCI_CR_SWRST);
+ 		mci_writel(host, CR, MCI_CR_MCIEN);
+ 		mci_writel(host, MR, host->mode_reg);
++		if (atmci_is_mci2())
++			mci_writel(host, CFG, host->cfg_reg);
+ 		host->need_reset = false;
+ 	}
+ 	mci_writel(host, SDCR, slot->sdc_reg);
+@@ -735,6 +789,7 @@ static void atmci_start_request(struct atmel_mci *host,
+ 		while (!(mci_readl(host, SR) & MCI_CMDRDY))
+ 			cpu_relax();
+ 	}
++	iflags = 0;
+ 	data = mrq->data;
+ 	if (data) {
+ 		atmci_set_timeout(host, slot, data);
+@@ -744,15 +799,17 @@ static void atmci_start_request(struct atmel_mci *host,
+ 				| MCI_BLKLEN(data->blksz));
+ 		dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n",
+ 			MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
++
++		iflags |= atmci_prepare_data(host, data);
+ 	}
+ 
+-	iflags = MCI_CMDRDY;
++	iflags |= MCI_CMDRDY;
+ 	cmd = mrq->cmd;
+ 	cmdflags = atmci_prepare_command(slot->mmc, cmd);
+ 	atmci_start_command(host, cmd, cmdflags);
+ 
+ 	if (data)
+-		iflags |= atmci_submit_data(host, data);
++		atmci_submit_data(host);
+ 
+ 	if (mrq->stop) {
+ 		host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
+@@ -848,6 +905,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 			clk_enable(host->mck);
+ 			mci_writel(host, CR, MCI_CR_SWRST);
+ 			mci_writel(host, CR, MCI_CR_MCIEN);
++			if (atmci_is_mci2())
++				mci_writel(host, CFG, host->cfg_reg);
+ 		}
+ 
+ 		/*
+@@ -1084,6 +1143,8 @@ static void atmci_detect_change(unsigned long data)
+ 				mci_writel(host, CR, MCI_CR_SWRST);
+ 				mci_writel(host, CR, MCI_CR_MCIEN);
+ 				mci_writel(host, MR, host->mode_reg);
++				if (atmci_is_mci2())
++					mci_writel(host, CFG, host->cfg_reg);
+ 
+ 				host->data = NULL;
+ 				host->cmd = NULL;
+@@ -1631,6 +1692,10 @@ static void atmci_configure_dma(struct atmel_mci *host)
+ 	}
+ 	if (!host->dma.chan)
+ 		dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
++	else
++		dev_info(&host->pdev->dev,
++					"Using %s for DMA transfers\n",
++					dma_chan_name(host->dma.chan));
+ }
+ #else
+ static void atmci_configure_dma(struct atmel_mci *host) {}
+-- 
+1.5.6.5
+
+From a91a3c03e7b112cfc317f278ed53628a3ea72ad4 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:40 +0000
+Subject: [PATCH] at91/atmel-mci: inclusion of sd/mmc driver in at91sam9g45 chip and board
+
+This adds the support of atmel-mci sd/mmc driver in at91sam9g45 devices and
+board files. This also configures the DMA controller slave interface for
+at_hdmac dmaengine driver.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11604 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9g45_devices.c |  159 ++++++++++++++++++++++++++++++
+ arch/arm/mach-at91/board-sam9m10g45ek.c  |   24 +++++
+ drivers/mmc/host/Kconfig                 |    2 +-
+ 3 files changed, 184 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index 5be8cf2..3664e46 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -15,6 +15,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/platform_device.h>
+ #include <linux/i2c-gpio.h>
++#include <linux/atmel-mci.h>
+ 
+ #include <linux/fb.h>
+ #include <video/atmel_lcdc.h>
+@@ -350,6 +351,164 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  MMC / SD
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
++static u64 mmc_dmamask = DMA_BIT_MASK(32);
++static struct mci_platform_data mmc0_data, mmc1_data;
++
++static struct resource mmc0_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_MCI0,
++		.end	= AT91SAM9G45_BASE_MCI0 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_MCI0,
++		.end	= AT91SAM9G45_ID_MCI0,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_mmc0_device = {
++	.name		= "atmel_mci",
++	.id		= 0,
++	.dev		= {
++				.dma_mask		= &mmc_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &mmc0_data,
++	},
++	.resource	= mmc0_resources,
++	.num_resources	= ARRAY_SIZE(mmc0_resources),
++};
++
++static struct resource mmc1_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_MCI1,
++		.end	= AT91SAM9G45_BASE_MCI1 + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_MCI1,
++		.end	= AT91SAM9G45_ID_MCI1,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_mmc1_device = {
++	.name		= "atmel_mci",
++	.id		= 1,
++	.dev		= {
++				.dma_mask		= &mmc_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &mmc1_data,
++	},
++	.resource	= mmc1_resources,
++	.num_resources	= ARRAY_SIZE(mmc1_resources),
++};
++
++/* Consider only one slot : slot 0 */
++void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
++{
++	struct at_dma_slave	*atslave;
++
++	if (!data)
++		return;
++
++	/* Must have at least one usable slot */
++	if (!data->slot[0].bus_width)
++		return;
++
++#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
++	atslave = kzalloc(sizeof(struct at_dma_slave), GFP_KERNEL);
++
++	/* DMA slave channel configuration */
++	atslave->dma_dev = &at_hdmac_device.dev;
++	atslave->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
++	atslave->cfg = ATC_FIFOCFG_HALFFIFO
++			| ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
++	atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
++	if (mmc_id == 0)	/* MCI0 */
++		atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
++			      | ATC_DST_PER(AT_DMA_ID_MCI0);
++
++	else			/* MCI1 */
++		atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1)
++			      | ATC_DST_PER(AT_DMA_ID_MCI1);
++
++	data->dma_slave = atslave;
++#endif
++
++
++	/* input/irq */
++	if (data->slot[0].detect_pin) {
++		at91_set_gpio_input(data->slot[0].detect_pin, 1);
++		at91_set_deglitch(data->slot[0].detect_pin, 1);
++	}
++	if (data->slot[0].wp_pin)
++		at91_set_gpio_input(data->slot[0].wp_pin, 1);
++
++	if (mmc_id == 0) {		/* MCI0 */
++
++		/* CLK */
++		at91_set_A_periph(AT91_PIN_PA0, 0);
++
++		/* CMD */
++		at91_set_A_periph(AT91_PIN_PA1, 1);
++
++		/* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
++		at91_set_A_periph(AT91_PIN_PA2, 1);
++		if (data->slot[0].bus_width == 4) {
++			at91_set_A_periph(AT91_PIN_PA3, 1);
++			at91_set_A_periph(AT91_PIN_PA4, 1);
++			at91_set_A_periph(AT91_PIN_PA5, 1);
++			if (data->slot[0].bus_width == 8) {
++				at91_set_A_periph(AT91_PIN_PA6, 1);
++				at91_set_A_periph(AT91_PIN_PA7, 1);
++				at91_set_A_periph(AT91_PIN_PA8, 1);
++				at91_set_A_periph(AT91_PIN_PA9, 1);
++			}
++		}
++
++		mmc0_data = *data;
++		at91_clock_associate("mci0_clk", &at91sam9g45_mmc0_device.dev, "mci_clk");
++		platform_device_register(&at91sam9g45_mmc0_device);
++
++	} else {			/* MCI1 */
++
++		/* CLK */
++		at91_set_A_periph(AT91_PIN_PA31, 0);
++
++		/* CMD */
++		at91_set_A_periph(AT91_PIN_PA22, 1);
++
++		/* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
++		at91_set_A_periph(AT91_PIN_PA23, 1);
++		if (data->slot[0].bus_width == 4) {
++			at91_set_A_periph(AT91_PIN_PA24, 1);
++			at91_set_A_periph(AT91_PIN_PA25, 1);
++			at91_set_A_periph(AT91_PIN_PA26, 1);
++			if (data->slot[0].bus_width == 8) {
++				at91_set_A_periph(AT91_PIN_PA27, 1);
++				at91_set_A_periph(AT91_PIN_PA28, 1);
++				at91_set_A_periph(AT91_PIN_PA29, 1);
++				at91_set_A_periph(AT91_PIN_PA30, 1);
++			}
++		}
++
++		mmc1_data = *data;
++		at91_clock_associate("mci1_clk", &at91sam9g45_mmc1_device.dev, "mci_clk");
++		platform_device_register(&at91sam9g45_mmc1_device);
++
++	}
++}
++#else
++void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+  *  NAND / SmartMedia
+  * -------------------------------------------------------------------- */
+ 
+diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
+index d7251b7..a7306ac 100644
+--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
++++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
+@@ -24,6 +24,7 @@
+ #include <linux/input.h>
+ #include <linux/leds.h>
+ #include <linux/clk.h>
++#include <linux/atmel-mci.h>
+ 
+ #include <mach/hardware.h>
+ #include <video/atmel_lcdc.h>
+@@ -99,6 +100,26 @@ static struct spi_board_info ek_spi_devices[] = {
+ 
+ 
+ /*
++ * MCI (SD/MMC)
++ */
++static struct mci_platform_data __initdata mci0_data = {
++	.slot[0] = {
++		.bus_width	= 4,
++		.detect_pin	= AT91_PIN_PD10,
++		.wp_pin		= -1,
++	},
++};
++
++static struct mci_platform_data __initdata mci1_data = {
++	.slot[0] = {
++		.bus_width	= 4,
++		.detect_pin	= AT91_PIN_PD11,
++		.wp_pin		= AT91_PIN_PD29,
++	},
++};
++
++
++/*
+  * MACB Ethernet device
+  */
+ static struct at91_eth_data __initdata ek_macb_data = {
+@@ -363,6 +384,9 @@ static void __init ek_board_init(void)
+ 	at91_add_device_usba(&ek_usba_udc_data);
+ 	/* SPI */
+ 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++	/* MMC */
++	at91_add_device_mci(0, &mci0_data);
++	at91_add_device_mci(1, &mci1_data);
+ 	/* Ethernet */
+ 	at91_add_device_eth(&ek_macb_data);
+ 	/* NAND */
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index e779049..7dde378 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -152,7 +152,7 @@ endchoice
+ 
+ config MMC_ATMELMCI_DMA
+ 	bool "Atmel MCI DMA support (EXPERIMENTAL)"
+-	depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL
++	depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE && EXPERIMENTAL
+ 	help
+ 	  Say Y here to have the Atmel MCI driver use a DMA engine to
+ 	  do data transfers and thus increase the throughput and
+-- 
+1.5.6.5
+
+From 5b2961fd6fd907b71ef0c59e5aa063c446a223c9 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:41 +0000
+Subject: [PATCH] MCI2: High speed mode support
+
+WIP For testing on revD boards
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11605 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/atmel-mci.c |   53 +++++++++++++++++++++++++++++++++++++++--
+ 1 files changed, 50 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index c79422e..8b73fe0 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -7,6 +7,10 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
++
++/* High speed mode setting on host & SD card */
++/*#define AT91_HSMODE	1*/
++
+ #include <linux/blkdev.h>
+ #include <linux/clk.h>
+ #include <linux/debugfs.h>
+@@ -929,6 +933,29 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 			clkdiv = 255;
+ 		}
+ 
++#if defined(AT91_HSMODE)
++		/* Not needed for normal operation previous calculation
++		 * takes 50MHz into account */
++#if 0
++		/* fake clkdiv for tests @ 16,6MHz || 12,5MHz */
++		if (ios->clock >= 25000000) {
++			clkdiv = 3;
++		}
++#endif
++#if 0
++		/* fake clkdiv for tests @ 33MHz || 25MHz */
++		if (ios->clock >= 25000000) {
++			clkdiv = 1;
++		}
++#endif
++#if 0
++		/* fake clkdiv for tests @ 66MHz || 50MHz */
++		if (ios->clock >= 25000000) {
++			clkdiv = 0;
++		}
++#endif
++#endif
++
+ 		host->mode_reg = MCI_MR_CLKDIV(clkdiv);
+ 
+ 		/*
+@@ -939,10 +966,23 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 		if (mci_has_rwproof())
+ 			host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF);
+ 
+-		if (list_empty(&host->queue))
++#if defined(AT91_HSMODE)
++		if (atmci_is_mci2()) {
++			/* setup High Speed mode in relation with card capacity */
++			if (ios->timing == MMC_TIMING_SD_HS)
++				host->cfg_reg |= MCI_CFG_HSMODE;
++			else
++				host->cfg_reg &= ~MCI_CFG_HSMODE;
++		}
++#endif
++
++		if (list_empty(&host->queue)) {
+ 			mci_writel(host, MR, host->mode_reg);
+-		else
++			if (atmci_is_mci2())
++				mci_writel(host, CFG, host->cfg_reg);
++		} else {
+ 			host->need_clock_update = true;
++		}
+ 
+ 		spin_unlock_bh(&host->lock);
+ 	} else {
+@@ -1038,8 +1078,11 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq)
+ 	 * necessary if set_ios() is called when a different slot is
+ 	 * busy transfering data.
+ 	 */
+-	if (host->need_clock_update)
++	if (host->need_clock_update) {
+ 		mci_writel(host, MR, host->mode_reg);
++		if (atmci_is_mci2())
++			mci_writel(host, CFG, host->cfg_reg);
++	}
+ 
+ 	host->cur_slot->mrq = NULL;
+ 	host->mrq = NULL;
+@@ -1548,6 +1591,10 @@ static int __init atmci_init_slot(struct atmel_mci *host,
+ 	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
+ 	mmc->f_max = host->bus_hz / 2;
+ 	mmc->ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34;
++#if defined(AT91_HSMODE)
++	if (atmci_is_mci2())
++		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
++#endif
+ 	if (slot_data->bus_width >= 4)
+ 		mmc->caps |= MMC_CAP_4_BIT_DATA;
+ 
+-- 
+1.5.6.5
+
+From 1a740790f1284b8077f0c6ece7b98d5047f2f2b4 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:41 +0000
+Subject: [PATCH] at91_mci: Enable MMC_CAP_SDIO_IRQ only when it actually works.
+
+According to the datasheets AT91SAM9261 does not support
+SDIO interrupts, and AT91SAM9260/9263 have an erratum
+requiring 4bit mode while using slot B for the interrupt
+to work.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11606 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/at91_mci.c |    9 ++++++++-
+ 1 files changed, 8 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
+index 9b333b9..d881d27 100644
+--- a/drivers/mmc/host/at91_mci.c
++++ b/drivers/mmc/host/at91_mci.c
+@@ -1007,7 +1007,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
+ 	mmc->f_min = 375000;
+ 	mmc->f_max = 25000000;
+ 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+-	mmc->caps = MMC_CAP_SDIO_IRQ;
++	mmc->caps = 0;
+ 
+ 	mmc->max_blk_size = 4095;
+ 	mmc->max_blk_count = mmc->max_req_size;
+@@ -1025,6 +1025,13 @@ static int __init at91_mci_probe(struct platform_device *pdev)
+ 				" - using 1 wire\n");
+ 	}
+ 
++	/* Add SDIO capability when available */
++	if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
++		/* AT91SAM9260/9263 erratum */
++		if (host->board->wire4 || !host->board->slot_b)
++			mmc->caps |= MMC_CAP_SDIO_IRQ;
++	}
++
+ 	/*
+ 	 * Reserve GPIOs ... board init code makes sure these pins are set
+ 	 * up as GPIOs with the right direction (input, except for vcc)
+-- 
+1.5.6.5
+
+From 240d32132c4a26e269121254562f3478f80bc5e0 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:42 +0000
+Subject: [PATCH] at91_mci: Do a reset after each request.
+
+My AT91SAM9260 board + Marvell 8686 SDIO WLAN adater are not happy without
+applying the MCI reset trick.
+
+Signed-off-by: Ville Syrjala <syrjala at sci.fi>
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11607 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/at91_mci.c |    5 ++---
+ 1 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
+index d881d27..0297d53 100644
+--- a/drivers/mmc/host/at91_mci.c
++++ b/drivers/mmc/host/at91_mci.c
+@@ -678,11 +678,10 @@ static void at91_mci_process_next(struct at91mci_host *host)
+ 		at91_mci_send_command(host, host->request->stop);
+ 	} else {
+ 		del_timer(&host->timer);
+-		/* the at91rm9200 mci controller hangs after some transfers,
++		/* the mci controller hangs after some transfers,
+ 		 * and the workaround is to reset it after each transfer.
+ 		 */
+-		if (cpu_is_at91rm9200())
+-			at91_reset_host(host);
++		at91_reset_host(host);
+ 		mmc_request_done(host->mmc, host->request);
+ 	}
+ }
+-- 
+1.5.6.5
+
+From 404cbeabd85633dae335a21027ffbe1d547aded3 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:43 +0000
+Subject: [PATCH] at91_mci: introduce per-mci-revision conditional code
+
+We used to manage features and differences on a per-cpu basis. As several cpus
+share the same mci revision, this patch aggregates cpus that have the same IP
+revision in one defined constant.
+We use the at91mci_is_mci1rev2xx() funtion name not to mess with newer Atmel
+sd/mmc IP called "MCI2". _rev2 naming could have been confusing...
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11608 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/mmc/host/at91_mci.c |   27 +++++++++++++++++++--------
+ 1 files changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
+index 0297d53..66f78cb 100644
+--- a/drivers/mmc/host/at91_mci.c
++++ b/drivers/mmc/host/at91_mci.c
+@@ -79,6 +79,17 @@
+ 
+ #define DRIVER_NAME "at91_mci"
+ 
++static inline int at91mci_is_mci1rev2xx(void)
++{
++	return (   cpu_is_at91sam9260()
++		|| cpu_is_at91sam9263()
++		|| cpu_is_at91cap9()
++		|| cpu_is_at91sam9rl()
++		|| cpu_is_at91sam9g10()
++		|| cpu_is_at91sam9g20()
++		);
++}
++
+ #define FL_SENT_COMMAND	(1 << 0)
+ #define FL_SENT_STOP	(1 << 1)
+ 
+@@ -201,8 +212,8 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
+ 	size = data->blksz * data->blocks;
+ 	len = data->sg_len;
+ 
+-	/* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */
+-	if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20())
++	/* at91mci MCI1 rev2xx Data Write Operation and number of bytes erratum */
++	if (at91mci_is_mci1rev2xx())
+ 		if (host->total_length == 12)
+ 			memset(dmabuf, 0, 12);
+ 
+@@ -462,7 +473,7 @@ static void at91_mci_enable(struct at91mci_host *host)
+ 	at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
+ 	mr = AT91_MCI_PDCMODE | 0x34a;
+ 
+-	if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20())
++	if (at91mci_is_mci1rev2xx())
+ 		mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
+ 
+ 	at91_mci_write(host, AT91_MCI_MR, mr);
+@@ -615,10 +626,10 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
+ 				 */
+ 				host->total_length = block_length * blocks;
+ 				/*
+-				 * AT91SAM926[0/3] Data Write Operation and
++				 * at91mci MCI1 rev2xx Data Write Operation and
+ 				 * number of bytes erratum
+ 				 */
+-				if (cpu_is_at91sam9260 () || cpu_is_at91sam9263() || cpu_is_at91sam9g20())
++				if (at91mci_is_mci1rev2xx())
+ 					if (host->total_length < 12)
+ 						host->total_length = 12;
+ 
+@@ -1017,7 +1028,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
+ 	host->bus_mode = 0;
+ 	host->board = pdev->dev.platform_data;
+ 	if (host->board->wire4) {
+-		if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20())
++		if (at91mci_is_mci1rev2xx())
+ 			mmc->caps |= MMC_CAP_4_BIT_DATA;
+ 		else
+ 			dev_warn(&pdev->dev, "4 wire bus mode not supported"
+@@ -1025,8 +1036,8 @@ static int __init at91_mci_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	/* Add SDIO capability when available */
+-	if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
+-		/* AT91SAM9260/9263 erratum */
++	if (at91mci_is_mci1rev2xx()) {
++		/* at91mci MCI1 rev2xx sdio interrupt erratum */
+ 		if (host->board->wire4 || !host->board->slot_b)
+ 			mmc->caps |= MMC_CAP_SDIO_IRQ;
+ 	}
+-- 
+1.5.6.5
+
+From 25ba423d34a49fad9d53b9fb4cb4dbf196defe9a Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:43 +0000
+Subject: [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client
+
+Dan Williams wrote:
+... DMA-slave clients request specific channels and know the hardware
+details at a low level, so it should not be too high an expectation to
+push dma mapping responsibility to the client.
+
+Also this patch includes DMA_COMPL_{SRC,DEST}_UNMAP_SINGLE support for
+dw_dmac driver.
+
+Signed-off-by: Atsushi Nemoto <anemo at mba.ocn.ne.jp>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11609 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/dma/at_hdmac.c       |   43 +++++++++++++++++++++--------------------
+ drivers/dma/dw_dmac.c        |   31 ++++++++++++++++++-----------
+ drivers/mmc/host/atmel-mci.c |   10 ++++++++-
+ 3 files changed, 50 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
+index 9a1e5fb..3d10525 100644
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -252,25 +252,28 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
+ 	list_move(&desc->desc_node, &atchan->free_list);
+ 
+ 	/* unmap dma addresses */
+-	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+-		if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+-			dma_unmap_single(chan2parent(&atchan->chan_common),
+-					desc->lli.daddr,
+-					desc->len, DMA_FROM_DEVICE);
+-		else
+-			dma_unmap_page(chan2parent(&atchan->chan_common),
+-					desc->lli.daddr,
+-					desc->len, DMA_FROM_DEVICE);
+-	}
+-	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+-		if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+-			dma_unmap_single(chan2parent(&atchan->chan_common),
+-					desc->lli.saddr,
+-					desc->len, DMA_TO_DEVICE);
+-		else
+-			dma_unmap_page(chan2parent(&atchan->chan_common),
+-					desc->lli.saddr,
+-					desc->len, DMA_TO_DEVICE);
++	if (!atchan->chan_common.private) {
++		struct device *parent = chan2parent(&atchan->chan_common);
++		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
++			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
++				dma_unmap_single(parent,
++						desc->lli.daddr,
++						desc->len, DMA_FROM_DEVICE);
++			else
++				dma_unmap_page(parent,
++						desc->lli.daddr,
++						desc->len, DMA_FROM_DEVICE);
++		}
++		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
++			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
++				dma_unmap_single(parent,
++						desc->lli.saddr,
++						desc->len, DMA_TO_DEVICE);
++			else
++				dma_unmap_page(parent,
++						desc->lli.saddr,
++						desc->len, DMA_TO_DEVICE);
++		}
+ 	}
+ 
+ 	/*
+@@ -646,8 +649,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+ 
+ 	reg_width = atslave->reg_width;
+ 
+-	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);
+-
+ 	ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
+ 	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;
+ 
+diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
+index 98c9a84..a5a5050 100644
+--- a/drivers/dma/dw_dmac.c
++++ b/drivers/dma/dw_dmac.c
+@@ -212,16 +212,25 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc)
+ 	list_splice_init(&txd->tx_list, &dwc->free_list);
+ 	list_move(&desc->desc_node, &dwc->free_list);
+ 
+-	/*
+-	 * We use dma_unmap_page() regardless of how the buffers were
+-	 * mapped before they were submitted...
+-	 */
+-	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP))
+-		dma_unmap_page(chan2parent(&dwc->chan), desc->lli.dar,
+-			       desc->len, DMA_FROM_DEVICE);
+-	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP))
+-		dma_unmap_page(chan2parent(&dwc->chan), desc->lli.sar,
+-			       desc->len, DMA_TO_DEVICE);
++	if (!dwc->chan.private) {
++		struct device *parent = chan2parent(&dwc->chan);
++		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
++			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
++				dma_unmap_single(parent, desc->lli.dar,
++						desc->len, DMA_FROM_DEVICE);
++			else
++				dma_unmap_page(parent, desc->lli.dar,
++						desc->len, DMA_FROM_DEVICE);
++		}
++		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
++			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
++				dma_unmap_single(parent, desc->lli.sar,
++						desc->len, DMA_TO_DEVICE);
++			else
++				dma_unmap_page(parent, desc->lli.sar,
++						desc->len, DMA_TO_DEVICE);
++		}
++	}
+ 
+ 	/*
+ 	 * The API requires that no submissions are done from a
+@@ -658,8 +667,6 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+ 	reg_width = dws->reg_width;
+ 	prev = first = NULL;
+ 
+-	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);
+-
+ 	switch (direction) {
+ 	case DMA_TO_DEVICE:
+ 		ctllo = (DWC_DEFAULT_CTLLO
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index 8b73fe0..cdb4a78 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -641,6 +641,7 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
+ 	struct scatterlist		*sg;
+ 	unsigned int			i;
+ 	enum dma_data_direction		direction;
++	unsigned int			sglen;
+ 
+ 	/*
+ 	 * We don't do DMA on "complex" transfers, i.e. with
+@@ -673,17 +674,24 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
+ 	else
+ 		direction = DMA_TO_DEVICE;
+ 
++	sglen = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, direction);
++	if (sglen != data->sg_len)
++		goto unmap_exit;
++
+ 	desc = chan->device->device_prep_slave_sg(chan,
+ 			data->sg, data->sg_len, direction,
+ 			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ 	if (!desc)
+-		return -ENOMEM;
++		goto unmap_exit;
+ 
+ 	host->dma.data_desc = desc;
+ 	desc->callback = atmci_dma_complete;
+ 	desc->callback_param = host;
+ 
+ 	return 0;
++unmap_exit:
++	dma_unmap_sg(&host->pdev->dev, data->sg, sglen, direction);
++	return -ENOMEM;
+ }
+ 
+ static void atmci_submit_data(struct atmel_mci *host)
+-- 
+1.5.6.5
+
+From 34964cf9501f171fa1894db90e882c14441cc98e Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:44 +0000
+Subject: [PATCH] AC97 atmel: add support for AT91 (common with AVR32)
+
+This patch add AC97 support for ATMEL AT91 boards, using the AVR32 code.
+It is based on Takashi git tree (sound-2.6/for-next).
+
+Signed-off-by: Sedji Gaouaou <sedji.gaouaou at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11610 50fbe906-d41e-0410-8a96-31537896a350
+---
+ sound/atmel/Kconfig |    2 +-
+ sound/atmel/ac97c.c |  354 +++++++++++++++++++++++++++++++++++++--------------
+ 2 files changed, 262 insertions(+), 94 deletions(-)
+
+diff --git a/sound/atmel/Kconfig b/sound/atmel/Kconfig
+index 6c228a9..94de43a 100644
+--- a/sound/atmel/Kconfig
++++ b/sound/atmel/Kconfig
+@@ -12,7 +12,7 @@ config SND_ATMEL_AC97C
+ 	tristate "Atmel AC97 Controller (AC97C) driver"
+ 	select SND_PCM
+ 	select SND_AC97_CODEC
+-	depends on DW_DMAC && AVR32
++	depends on (DW_DMAC && AVR32) || ARCH_AT91
+ 	help
+ 	  ALSA sound driver for the Atmel AC97 controller.
+ 
+diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
+index 0c0f877..54d1365 100644
+--- a/sound/atmel/ac97c.c
++++ b/sound/atmel/ac97c.c
+@@ -13,6 +13,7 @@
+ #include <linux/device.h>
+ #include <linux/dmaengine.h>
+ #include <linux/dma-mapping.h>
++#include <linux/atmel_pdc.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+@@ -31,6 +32,10 @@
+ 
+ #include <linux/dw_dmac.h>
+ 
++#include <mach/cpu.h>
++#include <mach/hardware.h>
++#include <mach/gpio.h>
++
+ #include "ac97c.h"
+ 
+ enum {
+@@ -63,6 +68,7 @@ struct atmel_ac97c {
+ 	u64				cur_format;
+ 	unsigned int			cur_rate;
+ 	unsigned long			flags;
++	int				period;
+ 	/* Serialize access to opened variable */
+ 	spinlock_t			lock;
+ 	void __iomem			*regs;
+@@ -241,10 +247,13 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
+ 					params_buffer_bytes(hw_params));
+ 	if (retval < 0)
+ 		return retval;
+-	/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
+-	if (retval == 1)
+-		if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
+-			dw_dma_cyclic_free(chip->dma.tx_chan);
++
++	if (cpu_is_at32ap7000()) {
++		/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
++		if (retval == 1)
++			if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
++				dw_dma_cyclic_free(chip->dma.tx_chan);
++	}
+ 
+ 	/* Set restrictions to params. */
+ 	mutex_lock(&opened_mutex);
+@@ -263,12 +272,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
+ 
+ 	retval = snd_pcm_lib_malloc_pages(substream,
+ 					params_buffer_bytes(hw_params));
+-	if (retval < 0)
+-		return retval;
+-	/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
+-	if (retval == 1)
+-		if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
+-			dw_dma_cyclic_free(chip->dma.rx_chan);
++	if (cpu_is_at32ap7000()) {
++		if (retval < 0)
++			return retval;
++		/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
++		if (retval == 1)
++			if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
++				dw_dma_cyclic_free(chip->dma.rx_chan);
++	}
+ 
+ 	/* Set restrictions to params. */
+ 	mutex_lock(&opened_mutex);
+@@ -282,16 +293,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
+ static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream)
+ {
+ 	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
+-	if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
+-		dw_dma_cyclic_free(chip->dma.tx_chan);
++	if (cpu_is_at32ap7000()) {
++		if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
++			dw_dma_cyclic_free(chip->dma.tx_chan);
++	}
+ 	return snd_pcm_lib_free_pages(substream);
+ }
+ 
+ static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream)
+ {
+ 	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
+-	if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
+-		dw_dma_cyclic_free(chip->dma.rx_chan);
++	if (cpu_is_at32ap7000()) {
++		if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
++			dw_dma_cyclic_free(chip->dma.rx_chan);
++	}
+ 	return snd_pcm_lib_free_pages(substream);
+ }
+ 
+@@ -299,9 +314,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
+ {
+ 	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
++	int block_size = frames_to_bytes(runtime, runtime->period_size);
+ 	unsigned long word = ac97c_readl(chip, OCA);
+ 	int retval;
+ 
++	chip->period = 0;
+ 	word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+ 
+ 	/* assign channels to AC97C channel A */
+@@ -324,7 +341,8 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
+ 
+ 	switch (runtime->format) {
+ 	case SNDRV_PCM_FORMAT_S16_LE:
+-		word |= AC97C_CMR_CEM_LITTLE;
++		if (cpu_is_at32ap7000())
++			word |= AC97C_CMR_CEM_LITTLE;
+ 		break;
+ 	case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
+ 		word &= ~(AC97C_CMR_CEM_LITTLE);
+@@ -363,9 +381,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
+ 		dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
+ 				runtime->rate);
+ 
+-	if (!test_bit(DMA_TX_READY, &chip->flags))
+-		retval = atmel_ac97c_prepare_dma(chip, substream,
+-				DMA_TO_DEVICE);
++	if (cpu_is_at32ap7000()) {
++		if (!test_bit(DMA_TX_READY, &chip->flags))
++			retval = atmel_ac97c_prepare_dma(chip, substream,
++					DMA_TO_DEVICE);
++	} else {
++		/* Initialize and start the PDC */
++		writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR);
++		writel(block_size / 2, chip->regs + ATMEL_PDC_TCR);
++		writel(runtime->dma_addr + block_size,
++				chip->regs + ATMEL_PDC_TNPR);
++		writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
++	}
+ 
+ 	return retval;
+ }
+@@ -374,9 +401,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
+ {
+ 	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
++	int block_size = frames_to_bytes(runtime, runtime->period_size);
+ 	unsigned long word = ac97c_readl(chip, ICA);
+ 	int retval;
+ 
++	chip->period = 0;
+ 	word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+ 
+ 	/* assign channels to AC97C channel A */
+@@ -415,11 +444,15 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
+ 	word |= AC97C_CSR_OVRUN;
+ 
+ 	ac97c_writel(chip, CAMR, word);
+-
+ 	/* Enable channel A event interrupt */
+ 	word = ac97c_readl(chip, IMR);
+ 	word |= AC97C_SR_CAEVT;
+-	ac97c_writel(chip, IER, word);
++	ac97c_writel(chip, IER, /*word*/AC97C_SR_CAEVT);
++
++	/* Enable channel A event interrupt */
++	/*word = ac97c_readl(chip, IMR);
++	word |= AC97C_SR_CAEVT;
++	ac97c_writel(chip, IER, word);*/
+ 
+ 	/* set variable rate if needed */
+ 	if (runtime->rate != 48000) {
+@@ -438,9 +471,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
+ 		dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
+ 				runtime->rate);
+ 
+-	if (!test_bit(DMA_RX_READY, &chip->flags))
+-		retval = atmel_ac97c_prepare_dma(chip, substream,
+-				DMA_FROM_DEVICE);
++	if (cpu_is_at32ap7000()) {
++		if (!test_bit(DMA_RX_READY, &chip->flags))
++			retval = atmel_ac97c_prepare_dma(chip, substream,
++					DMA_FROM_DEVICE);
++	} else {
++		/* Initialize and start the PDC */
++		writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR);
++		writel(block_size / 2, chip->regs + ATMEL_PDC_RCR);
++		writel(runtime->dma_addr + block_size,
++				chip->regs + ATMEL_PDC_RNPR);
++		writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
++	}
+ 
+ 	return retval;
+ }
+@@ -449,7 +491,7 @@ static int
+ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+ {
+ 	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
+-	unsigned long camr;
++	unsigned long camr, ptcr = 0;
+ 	int retval = 0;
+ 
+ 	camr = ac97c_readl(chip, CAMR);
+@@ -458,15 +500,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+ 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_START:
+-		retval = dw_dma_cyclic_start(chip->dma.tx_chan);
+-		if (retval)
+-			goto out;
+-		camr |= AC97C_CMR_CENA;
++		if (cpu_is_at32ap7000()) {
++			retval = dw_dma_cyclic_start(chip->dma.tx_chan);
++			if (retval)
++				goto out;
++		} else {
++			ptcr = ATMEL_PDC_TXTEN;
++		}
++		camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX;
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_STOP:
+-		dw_dma_cyclic_stop(chip->dma.tx_chan);
++		if (cpu_is_at32ap7000())
++			dw_dma_cyclic_stop(chip->dma.tx_chan);
++		else
++			ptcr = ATMEL_PDC_TXTDIS;
+ 		if (chip->opened <= 1)
+ 			camr &= ~AC97C_CMR_CENA;
+ 		break;
+@@ -476,6 +525,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+ 	}
+ 
+ 	ac97c_writel(chip, CAMR, camr);
++	if (!cpu_is_at32ap7000())
++		writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
+ out:
+ 	return retval;
+ }
+@@ -484,7 +535,7 @@ static int
+ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+ {
+ 	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
+-	unsigned long camr;
++	unsigned long camr, ptcr = 0;
+ 	int retval = 0;
+ 
+ 	camr = ac97c_readl(chip, CAMR);
+@@ -493,15 +544,22 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+ 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_START:
+-		retval = dw_dma_cyclic_start(chip->dma.rx_chan);
+-		if (retval)
+-			goto out;
++		if (cpu_is_at32ap7000()) {
++			retval = dw_dma_cyclic_start(chip->dma.rx_chan);
++			if (retval)
++				goto out;
++		} else {
++			ptcr = ATMEL_PDC_RXTEN;
++		}
+ 		camr |= AC97C_CMR_CENA;
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
+ 	case SNDRV_PCM_TRIGGER_STOP:
+-		dw_dma_cyclic_stop(chip->dma.rx_chan);
++		if (cpu_is_at32ap7000())
++			dw_dma_cyclic_stop(chip->dma.rx_chan);
++		else
++			ptcr = ATMEL_PDC_RXTDIS;
+ 		if (chip->opened <= 1)
+ 			camr &= ~AC97C_CMR_CENA;
+ 		break;
+@@ -511,6 +569,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+ 	}
+ 
+ 	ac97c_writel(chip, CAMR, camr);
++	if (!cpu_is_at32ap7000())
++		writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
+ out:
+ 	return retval;
+ }
+@@ -523,7 +583,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
+ 	snd_pcm_uframes_t	frames;
+ 	unsigned long		bytes;
+ 
+-	bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
++	if (cpu_is_at32ap7000())
++		bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
++	else
++		bytes = readl(chip->regs + ATMEL_PDC_TPR);
+ 	bytes -= runtime->dma_addr;
+ 
+ 	frames = bytes_to_frames(runtime, bytes);
+@@ -540,7 +603,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
+ 	snd_pcm_uframes_t	frames;
+ 	unsigned long		bytes;
+ 
+-	bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
++	if (cpu_is_at32ap7000())
++		bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
++	else
++		bytes = readl(chip->regs + ATMEL_PDC_RPR);
+ 	bytes -= runtime->dma_addr;
+ 
+ 	frames = bytes_to_frames(runtime, bytes);
+@@ -578,20 +644,67 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
+ 	u32			sr     = ac97c_readl(chip, SR);
+ 	u32			casr   = ac97c_readl(chip, CASR);
+ 	u32			cosr   = ac97c_readl(chip, COSR);
++	u32			camr   = ac97c_readl(chip, CAMR);
+ 
+ 	if (sr & AC97C_SR_CAEVT) {
+-		dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
++		struct snd_pcm_runtime *runtime;
++		int offset, next_period, block_size;
++		dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
+ 				casr & AC97C_CSR_OVRUN   ? " OVRUN"   : "",
+ 				casr & AC97C_CSR_RXRDY   ? " RXRDY"   : "",
+ 				casr & AC97C_CSR_UNRUN   ? " UNRUN"   : "",
+ 				casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
+ 				casr & AC97C_CSR_TXRDY   ? " TXRDY"   : "",
+ 				!casr                    ? " NONE"    : "");
++		if (!cpu_is_at32ap7000()) {
++			if ((casr & camr) & AC97C_CSR_ENDTX) {
++				runtime = chip->playback_substream->runtime;
++				block_size = frames_to_bytes(runtime,
++						runtime->period_size);
++				chip->period++;
++
++				if (chip->period == runtime->periods)
++					chip->period = 0;
++				next_period = chip->period + 1;
++				if (next_period == runtime->periods)
++					next_period = 0;
++
++				offset = block_size * next_period;
++
++				writel(runtime->dma_addr + offset,
++						chip->regs + ATMEL_PDC_TNPR);
++				writel(block_size / 2,
++						chip->regs + ATMEL_PDC_TNCR);
++
++				snd_pcm_period_elapsed(
++						chip->playback_substream);
++			}
++			if ((casr & camr) & AC97C_CSR_ENDRX) {
++				runtime = chip->capture_substream->runtime;
++				block_size = frames_to_bytes(runtime,
++						runtime->period_size);
++				chip->period++;
++
++				if (chip->period == runtime->periods)
++					chip->period = 0;
++				next_period = chip->period + 1;
++				if (next_period == runtime->periods)
++					next_period = 0;
++
++				offset = block_size * next_period;
++
++				writel(runtime->dma_addr + offset,
++						chip->regs + ATMEL_PDC_RNPR);
++				writel(block_size / 2,
++						chip->regs + ATMEL_PDC_RNCR);
++				snd_pcm_period_elapsed(chip->capture_substream);
++			}
++		}
+ 		retval = IRQ_HANDLED;
+ 	}
+ 
+ 	if (sr & AC97C_SR_COEVT) {
+-		dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
++		dev_dbg(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
+ 				cosr & AC97C_CSR_OVRUN   ? " OVRUN"   : "",
+ 				cosr & AC97C_CSR_RXRDY   ? " RXRDY"   : "",
+ 				cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
+@@ -608,15 +721,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
+ 	return retval;
+ }
+ 
++static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = {
++	/* Playback */
++	{
++		.exclusive = 1,
++		.r = { {
++			.slots = ((1 << AC97_SLOT_PCM_LEFT)
++				  | (1 << AC97_SLOT_PCM_RIGHT)),
++		} },
++	},
++	/* PCM in */
++	{
++		.stream = 1,
++		.exclusive = 1,
++		.r = { {
++			.slots = ((1 << AC97_SLOT_PCM_LEFT)
++					| (1 << AC97_SLOT_PCM_RIGHT)),
++		} }
++	},
++	/* Mic in */
++	{
++		.stream = 1,
++		.exclusive = 1,
++		.r = { {
++			.slots = (1<<AC97_SLOT_MIC),
++		} }
++	},
++};
++
+ static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
+ {
+ 	struct snd_pcm		*pcm;
+ 	struct snd_pcm_hardware	hw = atmel_ac97c_hw;
+-	int			capture, playback, retval;
++	int			capture, playback, retval, err;
+ 
+ 	capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
+ 	playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
+ 
++	if (!cpu_is_at32ap7000()) {
++		err = snd_ac97_pcm_assign(chip->ac97_bus,
++				ARRAY_SIZE(at91_ac97_pcm_defs),
++				at91_ac97_pcm_defs);
++		if (err)
++			return err;
++	}
+ 	retval = snd_pcm_new(chip->card, chip->card->shortname,
+ 			chip->pdev->id, playback, capture, &pcm);
+ 	if (retval)
+@@ -775,7 +923,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
+ 		return -ENXIO;
+ 	}
+ 
+-	pclk = clk_get(&pdev->dev, "pclk");
++	if (cpu_is_at32ap7000()) {
++		pclk = clk_get(&pdev->dev, "pclk");
++	} else {
++		pclk = clk_get(&pdev->dev, "ac97_clk");
++	}
++
+ 	if (IS_ERR(pclk)) {
+ 		dev_dbg(&pdev->dev, "no peripheral clock\n");
+ 		return PTR_ERR(pclk);
+@@ -844,43 +997,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
+ 		goto err_ac97_bus;
+ 	}
+ 
+-	if (pdata->rx_dws.dma_dev) {
+-		struct dw_dma_slave *dws = &pdata->rx_dws;
+-		dma_cap_mask_t mask;
++	if (cpu_is_at32ap7000()) {
++		if (pdata->rx_dws.dma_dev) {
++			struct dw_dma_slave *dws = &pdata->rx_dws;
++			dma_cap_mask_t mask;
+ 
+-		dws->rx_reg = regs->start + AC97C_CARHR + 2;
++			dws->rx_reg = regs->start + AC97C_CARHR + 2;
+ 
+-		dma_cap_zero(mask);
+-		dma_cap_set(DMA_SLAVE, mask);
++			dma_cap_zero(mask);
++			dma_cap_set(DMA_SLAVE, mask);
+ 
+-		chip->dma.rx_chan = dma_request_channel(mask, filter, dws);
++			chip->dma.rx_chan = dma_request_channel(mask, filter,
++					dws);
+ 
+-		dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
++			dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
+ 				dev_name(&chip->dma.rx_chan->dev->device));
+-		set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
+-	}
++			set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
++		}
+ 
+-	if (pdata->tx_dws.dma_dev) {
+-		struct dw_dma_slave *dws = &pdata->tx_dws;
+-		dma_cap_mask_t mask;
++		if (pdata->tx_dws.dma_dev) {
++			struct dw_dma_slave *dws = &pdata->tx_dws;
++			dma_cap_mask_t mask;
+ 
+-		dws->tx_reg = regs->start + AC97C_CATHR + 2;
++			dws->tx_reg = regs->start + AC97C_CATHR + 2;
+ 
+-		dma_cap_zero(mask);
+-		dma_cap_set(DMA_SLAVE, mask);
++			dma_cap_zero(mask);
++			dma_cap_set(DMA_SLAVE, mask);
+ 
+-		chip->dma.tx_chan = dma_request_channel(mask, filter, dws);
++			chip->dma.tx_chan = dma_request_channel(mask, filter,
++					dws);
+ 
+-		dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
++			dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
+ 				dev_name(&chip->dma.tx_chan->dev->device));
+-		set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
+-	}
++			set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
++		}
+ 
+-	if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
+-			!test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
+-		dev_dbg(&pdev->dev, "DMA not available\n");
+-		retval = -ENODEV;
+-		goto err_dma;
++		if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
++				!test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
++			dev_dbg(&pdev->dev, "DMA not available\n");
++			retval = -ENODEV;
++			goto err_dma;
++		}
++	} else {
++		/* Just pretend that we have DMA channel(for at91 i is actually
++		 * the PDC */
++		set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
++		set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
+ 	}
+ 
+ 	retval = atmel_ac97c_pcm_new(chip);
+@@ -897,20 +1059,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, card);
+ 
+-	dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n",
+-			chip->regs);
++	dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n",
++			chip->regs, irq);
+ 
+ 	return 0;
+ 
+ err_dma:
+-	if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
+-		dma_release_channel(chip->dma.rx_chan);
+-	if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
+-		dma_release_channel(chip->dma.tx_chan);
+-	clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
+-	clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
+-	chip->dma.rx_chan = NULL;
+-	chip->dma.tx_chan = NULL;
++	if (cpu_is_at32ap7000()) {
++		if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
++			dma_release_channel(chip->dma.rx_chan);
++		if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
++			dma_release_channel(chip->dma.tx_chan);
++		clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
++		clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
++		chip->dma.rx_chan = NULL;
++		chip->dma.tx_chan = NULL;
++	}
+ err_ac97_bus:
+ 	snd_card_set_dev(card, NULL);
+ 
+@@ -934,12 +1098,13 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
+ 	struct snd_card *card = platform_get_drvdata(pdev);
+ 	struct atmel_ac97c *chip = card->private_data;
+ 
+-	if (test_bit(DMA_RX_READY, &chip->flags))
+-		dw_dma_cyclic_stop(chip->dma.rx_chan);
+-	if (test_bit(DMA_TX_READY, &chip->flags))
+-		dw_dma_cyclic_stop(chip->dma.tx_chan);
++	if (cpu_is_at32ap7000()) {
++		if (test_bit(DMA_RX_READY, &chip->flags))
++			dw_dma_cyclic_stop(chip->dma.rx_chan);
++		if (test_bit(DMA_TX_READY, &chip->flags))
++			dw_dma_cyclic_stop(chip->dma.tx_chan);
++	}
+ 	clk_disable(chip->pclk);
+-
+ 	return 0;
+ }
+ 
+@@ -949,11 +1114,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
+ 	struct atmel_ac97c *chip = card->private_data;
+ 
+ 	clk_enable(chip->pclk);
+-	if (test_bit(DMA_RX_READY, &chip->flags))
+-		dw_dma_cyclic_start(chip->dma.rx_chan);
+-	if (test_bit(DMA_TX_READY, &chip->flags))
+-		dw_dma_cyclic_start(chip->dma.tx_chan);
+-
++	if (cpu_is_at32ap7000()) {
++		if (test_bit(DMA_RX_READY, &chip->flags))
++			dw_dma_cyclic_start(chip->dma.rx_chan);
++		if (test_bit(DMA_TX_READY, &chip->flags))
++			dw_dma_cyclic_start(chip->dma.tx_chan);
++	}
+ 	return 0;
+ }
+ #else
+@@ -978,14 +1144,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
+ 	iounmap(chip->regs);
+ 	free_irq(chip->irq, chip);
+ 
+-	if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
+-		dma_release_channel(chip->dma.rx_chan);
+-	if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
+-		dma_release_channel(chip->dma.tx_chan);
+-	clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
+-	clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
+-	chip->dma.rx_chan = NULL;
+-	chip->dma.tx_chan = NULL;
++	if (cpu_is_at32ap7000()) {
++		if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
++			dma_release_channel(chip->dma.rx_chan);
++		if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
++			dma_release_channel(chip->dma.tx_chan);
++		clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
++		clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
++		chip->dma.rx_chan = NULL;
++		chip->dma.tx_chan = NULL;
++	}
+ 
+ 	snd_card_set_dev(card, NULL);
+ 	snd_card_free(card);
+-- 
+1.5.6.5
+
+From b59b29bf4086ed863c3853261b24c03adf5f0302 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:45 +0000
+Subject: [PATCH] AT91: modify the support of AC97 on the at91sam9263 ek board
+
+This patch modifies the support of AC97 on the at91sam9263 ek board,
+so it would share the code with AVR32.
+Plus it removes a typo in at91sam9263_devices.c.
+
+Signed-off-by: Sedji Gaouaou <sedji.gaouaou at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11611 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9263_devices.c |   12 ++++++------
+ arch/arm/mach-at91/board-sam9263ek.c     |    2 +-
+ arch/arm/mach-at91/include/mach/board.h  |    6 ++----
+ 3 files changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
+index e1de2d0..55719a9 100644
+--- a/arch/arm/mach-at91/at91sam9263_devices.c
++++ b/arch/arm/mach-at91/at91sam9263_devices.c
+@@ -707,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+  *  AC97
+  * -------------------------------------------------------------------- */
+ 
+-#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
++#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
+ static u64 ac97_dmamask = DMA_BIT_MASK(32);
+-static struct atmel_ac97_data ac97_data;
++static struct ac97c_platform_data ac97_data;
+ 
+ static struct resource ac97_resources[] = {
+ 	[0] = {
+@@ -725,8 +725,8 @@ static struct resource ac97_resources[] = {
+ };
+ 
+ static struct platform_device at91sam9263_ac97_device = {
+-	.name		= "ac97c",
+-	.id		= 1,
++	.name		= "atmel_ac97c",
++	.id		= 0,
+ 	.dev		= {
+ 				.dma_mask		= &ac97_dmamask,
+ 				.coherent_dma_mask	= DMA_BIT_MASK(32),
+@@ -736,7 +736,7 @@ static struct platform_device at91sam9263_ac97_device = {
+ 	.num_resources	= ARRAY_SIZE(ac97_resources),
+ };
+ 
+-void __init at91_add_device_ac97(struct atmel_ac97_data *data)
++void __init at91_add_device_ac97(struct ac97c_platform_data *data)
+ {
+ 	if (!data)
+ 		return;
+@@ -754,7 +754,7 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data)
+ 	platform_device_register(&at91sam9263_ac97_device);
+ }
+ #else
+-void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
++void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
+ #endif
+ 
+ 
+diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
+index 258b1aa..4cb1b1c 100644
+--- a/arch/arm/mach-at91/board-sam9263ek.c
++++ b/arch/arm/mach-at91/board-sam9263ek.c
+@@ -366,7 +366,7 @@ static void __init ek_add_device_buttons(void) {}
+ /*
+  * AC97
+  */
+-static struct atmel_ac97_data ek_ac97_data = {
++static struct ac97c_platform_data ek_ac97_data = {
+ 	.reset_pin	= AT91_PIN_PA13,
+ };
+ 
+diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
+index 9daecc6..d1f1c38 100644
+--- a/arch/arm/mach-at91/include/mach/board.h
++++ b/arch/arm/mach-at91/include/mach/board.h
+@@ -38,6 +38,7 @@
+ #include <linux/spi/spi.h>
+ #include <linux/usb/atmel_usba_udc.h>
+ #include <linux/atmel-mci.h>
++#include <sound/atmel-ac97c.h>
+ 
+  /* USB Device */
+ struct at91_udc_data {
+@@ -180,10 +181,7 @@ struct atmel_lcdfb_info;
+ extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
+ 
+  /* AC97 */
+-struct atmel_ac97_data {
+-	u8		reset_pin;	/* reset */
+-};
+-extern void __init at91_add_device_ac97(struct atmel_ac97_data *data);
++extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
+ 
+  /* ISI */
+ extern void __init at91_add_device_isi(void);
+-- 
+1.5.6.5
+
+From 683912a0731ddbd6364f3b6ca359be753f7d820a Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:46 +0000
+Subject: [PATCH] AT91: correct AC97 reset line in at91sam9263ek board
+
+Board code was wrongly setting up the reset pin for AC97 on at91sam9263ek.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11612 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9263ek.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
+index 4cb1b1c..dd3f093 100644
+--- a/arch/arm/mach-at91/board-sam9263ek.c
++++ b/arch/arm/mach-at91/board-sam9263ek.c
+@@ -365,9 +365,9 @@ static void __init ek_add_device_buttons(void) {}
+ 
+ /*
+  * AC97
++ * reset_pin is not connected: NRST
+  */
+ static struct ac97c_platform_data ek_ac97_data = {
+-	.reset_pin	= AT91_PIN_PA13,
+ };
+ 
+ 
+-- 
+1.5.6.5
+
+From 31ff757e184b9678e0d00258705092939e5c5099 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:46 +0000
+Subject: [PATCH] at91: add AC97 support to at91sam9rl and at91sam9rlek board
+
+Add the support of AC97 on the at91sam9rl chip and -ek board.
+It will share the code with AVR32 ac97c alsa driver "atmel_ac97c".
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11613 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9rl_devices.c |   55 +++++++++++++++++++++++++++++++
+ arch/arm/mach-at91/board-sam9rlek.c     |   10 ++++++
+ 2 files changed, 65 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
+index 1c2dced..d345f54 100644
+--- a/arch/arm/mach-at91/at91sam9rl_devices.c
++++ b/arch/arm/mach-at91/at91sam9rl_devices.c
+@@ -444,6 +444,61 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  AC97
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
++static u64 ac97_dmamask = DMA_BIT_MASK(32);
++static struct ac97c_platform_data ac97_data;
++
++static struct resource ac97_resources[] = {
++	[0] = {
++		.start	= AT91SAM9RL_BASE_AC97C,
++		.end	= AT91SAM9RL_BASE_AC97C + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9RL_ID_AC97C,
++		.end	= AT91SAM9RL_ID_AC97C,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9rl_ac97_device = {
++	.name		= "atmel_ac97c",
++	.id		= 0,
++	.dev		= {
++				.dma_mask		= &ac97_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &ac97_data,
++	},
++	.resource	= ac97_resources,
++	.num_resources	= ARRAY_SIZE(ac97_resources),
++};
++
++void __init at91_add_device_ac97(struct ac97c_platform_data *data)
++{
++	if (!data)
++		return;
++
++	at91_set_A_periph(AT91_PIN_PD1, 0);	/* AC97FS */
++	at91_set_A_periph(AT91_PIN_PD2, 0);	/* AC97CK */
++	at91_set_A_periph(AT91_PIN_PD3, 0);	/* AC97TX */
++	at91_set_A_periph(AT91_PIN_PD4, 0);	/* AC97RX */
++
++	/* reset */
++	if (data->reset_pin)
++		at91_set_gpio_output(data->reset_pin, 0);
++
++	ac97_data = *data;
++	platform_device_register(&at91sam9rl_ac97_device);
++}
++#else
++void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+  *  LCD Controller
+  * -------------------------------------------------------------------- */
+ 
+diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
+index 450a7be..26cde27 100644
+--- a/arch/arm/mach-at91/board-sam9rlek.c
++++ b/arch/arm/mach-at91/board-sam9rlek.c
+@@ -211,6 +211,14 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+ 
+ 
+ /*
++ * AC97
++ * reset_pin is not connected: NRST
++ */
++static struct ac97c_platform_data ek_ac97_data = {
++};
++
++
++/*
+  * LEDs
+  */
+ static struct gpio_led ek_leds[] = {
+@@ -299,6 +307,8 @@ static void __init ek_board_init(void)
+ 	at91_add_device_mmc(0, &ek_mmc_data);
+ 	/* LCD Controller */
+ 	at91_add_device_lcdc(&ek_lcdc_data);
++	/* AC97 */
++	at91_add_device_ac97(&ek_ac97_data);
+ 	/* Touch Screen Controller */
+ 	at91_add_device_tsadcc();
+ 	/* LEDs */
+-- 
+1.5.6.5
+
+From 2bebd29ea56bf9c32481b5739ef8200a57d599f6 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:47 +0000
+Subject: [PATCH] at91: add AC97 support to at91sam9g45 series and at91sam9m10g45ek board
+
+Add the support of AC97 on the at91sam9g45 chip series and -ek board.
+It will share the code with AVR32 ac97c alsa driver "atmel_ac97c".
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11614 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9g45_devices.c |   55 ++++++++++++++++++++++++++++++
+ arch/arm/mach-at91/board-sam9m10g45ek.c  |   10 +++++
+ 2 files changed, 65 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index 3664e46..425ea97 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -813,6 +813,61 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  AC97
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
++static u64 ac97_dmamask = DMA_BIT_MASK(32);
++static struct ac97c_platform_data ac97_data;
++
++static struct resource ac97_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_AC97C,
++		.end	= AT91SAM9G45_BASE_AC97C + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_AC97C,
++		.end	= AT91SAM9G45_ID_AC97C,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device at91sam9g45_ac97_device = {
++	.name		= "atmel_ac97c",
++	.id		= 0,
++	.dev		= {
++				.dma_mask		= &ac97_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &ac97_data,
++	},
++	.resource	= ac97_resources,
++	.num_resources	= ARRAY_SIZE(ac97_resources),
++};
++
++void __init at91_add_device_ac97(struct ac97c_platform_data *data)
++{
++	if (!data)
++		return;
++
++	at91_set_A_periph(AT91_PIN_PD8, 0);	/* AC97FS */
++	at91_set_A_periph(AT91_PIN_PD9, 0);	/* AC97CK */
++	at91_set_A_periph(AT91_PIN_PD7, 0);	/* AC97TX */
++	at91_set_A_periph(AT91_PIN_PD6, 0);	/* AC97RX */
++
++	/* reset */
++	if (data->reset_pin)
++		at91_set_gpio_output(data->reset_pin, 0);
++
++	ac97_data = *data;
++	platform_device_register(&at91sam9g45_ac97_device);
++}
++#else
++void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+  *  LCD Controller
+  * -------------------------------------------------------------------- */
+ 
+diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
+index a7306ac..2ffeb77 100644
+--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
++++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
+@@ -332,6 +332,14 @@ static void __init ek_add_device_buttons(void) {}
+ 
+ 
+ /*
++ * AC97
++ * reset_pin is not connected: NRST
++ */
++static struct ac97c_platform_data ek_ac97_data = {
++};
++
++
++/*
+  * LEDs ... these could all be PWM-driven, for variable brightness
+  */
+ static struct gpio_led ek_leds[] = {
+@@ -397,6 +405,8 @@ static void __init ek_board_init(void)
+ 	at91_add_device_lcdc(&ek_lcdc_data);
+ 	/* Push Buttons */
+ 	ek_add_device_buttons();
++	/* AC97 */
++	at91_add_device_ac97(&ek_ac97_data);
+ 	/* LEDs */
+ 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ 	at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+-- 
+1.5.6.5
+
+From 2007f9e7c5debef2df870664a7e892f18a35f8ba Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:48 +0000
+Subject: [PATCH] input: atmel_tsadcc: touchscreen rework setting capabilities
+
+Tiny patch for setting capabilities using input API function.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11615 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/input/touchscreen/atmel_tsadcc.c |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
+index 055969e..36a4f5f 100644
+--- a/drivers/input/touchscreen/atmel_tsadcc.c
++++ b/drivers/input/touchscreen/atmel_tsadcc.c
+@@ -242,12 +242,12 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+ 	input_dev->phys = ts_dev->phys;
+ 	input_dev->dev.parent = &pdev->dev;
+ 
+-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+-	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+-
++	__set_bit(EV_ABS, input_dev->evbit);
+ 	input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
+ 	input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
+ 
++	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
++
+ 	/* clk_enable() always returns 0, no need to check it */
+ 	clk_enable(ts_dev->clk);
+ 
+-- 
+1.5.6.5
+
+From f5ea267e707088ef5c4722c7a71443de7e0c82e4 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:49 +0000
+Subject: [PATCH] input: atmel_tsadcc touchscreen use platform parameters
+
+Add a number of plafrom dependent parameters to atmel_tsadcc.
+The touchscreeen driver can now take into account the slight differences that
+exist between IPs included in diferent products.  This will also allow to adapt
+its behaivior to the caracteristics of the resistive panel used.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11616 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/input/touchscreen/atmel_tsadcc.c |   41 +++++++++++++++++++++++++----
+ 1 files changed, 35 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
+index 36a4f5f..3c24783 100644
+--- a/drivers/input/touchscreen/atmel_tsadcc.c
++++ b/drivers/input/touchscreen/atmel_tsadcc.c
+@@ -22,6 +22,8 @@
+ #include <linux/clk.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
++#include <mach/board.h>
++#include <mach/cpu.h>
+ 
+ /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
+ 
+@@ -36,7 +38,9 @@
+ #define	  ATMEL_TSADCC_LOWRES	(1    <<  4)	/* Resolution selection */
+ #define	  ATMEL_TSADCC_SLEEP	(1    <<  5)	/* Sleep mode */
+ #define	  ATMEL_TSADCC_PENDET	(1    <<  6)	/* Pen Detect selection */
++#define	  ATMEL_TSADCC_PRES	(1    <<  7)	/* Pressure Measurement Selection */
+ #define	  ATMEL_TSADCC_PRESCAL	(0x3f <<  8)	/* Prescalar Rate Selection */
++#define	  ATMEL_TSADCC_EPRESCAL	(0xff <<  8)	/* Prescalar Rate Selection (Extended) */
+ #define	  ATMEL_TSADCC_STARTUP	(0x7f << 16)	/* Start Up time */
+ #define	  ATMEL_TSADCC_SHTIM	(0xf  << 24)	/* Sample & Hold time */
+ #define	  ATMEL_TSADCC_PENDBC	(0xf  << 28)	/* Pen Detect debouncing time */
+@@ -84,7 +88,13 @@
+ #define ATMEL_TSADCC_CDR4	0x40	/* Channel Data 4 */
+ #define ATMEL_TSADCC_CDR5	0x44	/* Channel Data 5 */
+ 
+-#define ADC_CLOCK	1000000
++#define ATMEL_TSADCC_XPOS	0x50
++#define ATMEL_TSADCC_Z1DAT	0x54
++#define ATMEL_TSADCC_Z2DAT	0x58
++
++#define PRESCALER_VAL(x)	((x) >> 8)
++
++#define ADC_DEFAULT_CLOCK	100000
+ 
+ struct atmel_tsadcc {
+ 	struct input_dev	*input;
+@@ -172,6 +182,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+ 	struct atmel_tsadcc	*ts_dev;
+ 	struct input_dev	*input_dev;
+ 	struct resource		*res;
++	struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
+ 	int		err = 0;
+ 	unsigned int	prsc;
+ 	unsigned int	reg;
+@@ -254,19 +265,37 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+ 	prsc = clk_get_rate(ts_dev->clk);
+ 	dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
+ 
+-	prsc = prsc / ADC_CLOCK / 2 - 1;
++	if (!pdata)
++		goto err_fail;
++
++	if (!pdata->adc_clock)
++		pdata->adc_clock = ADC_DEFAULT_CLOCK;
++
++	prsc = (prsc / (2 * pdata->adc_clock)) - 1;
++
++	/* saturate if this value is too high */
++	if (cpu_is_at91sam9rl()) {
++		if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL))
++			prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL);
++	} else {
++		if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL))
++			prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL);
++	}
++
++	dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
+ 
+ 	reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE		|
+ 		((0x00 << 5) & ATMEL_TSADCC_SLEEP)	|	/* Normal Mode */
+ 		((0x01 << 6) & ATMEL_TSADCC_PENDET)	|	/* Enable Pen Detect */
+-		((prsc << 8) & ATMEL_TSADCC_PRESCAL)	|	/* PRESCAL */
+-		((0x13 << 16) & ATMEL_TSADCC_STARTUP)	|	/* STARTUP */
+-		((0x0F << 28) & ATMEL_TSADCC_PENDBC);		/* PENDBC */
++		(prsc << 8)				|
++		((0x26 << 16) & ATMEL_TSADCC_STARTUP)	|
++		((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
+ 
+ 	atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
+ 	atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
+ 	atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
+-	atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM);
++	atmel_tsadcc_write(ATMEL_TSADCC_TSR,
++		(pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM);
+ 
+ 	atmel_tsadcc_read(ATMEL_TSADCC_SR);
+ 	atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
+-- 
+1.5.6.5
+
+From a0c6bc387109418b5113ac3d9b4d9c4fae47dcd7 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:49 +0000
+Subject: [PATCH] at91/input: platform parameters for atmel_tsadcc in at91sam9rlek
+
+Setup platform parameters in at91sam9rl-ek board to be passed to atmel_tsadcc
+touchscreen.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11617 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9rl_devices.c |   10 ++++++++--
+ arch/arm/mach-at91/board-sam9rlek.c     |   12 +++++++++++-
+ arch/arm/mach-at91/include/mach/board.h |    7 ++++++-
+ 3 files changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
+index d345f54..53aaa94 100644
+--- a/arch/arm/mach-at91/at91sam9rl_devices.c
++++ b/arch/arm/mach-at91/at91sam9rl_devices.c
+@@ -622,6 +622,7 @@ static void __init at91_add_device_tc(void) { }
+ 
+ #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
+ static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
++static struct at91_tsadcc_data tsadcc_data;
+ 
+ static struct resource tsadcc_resources[] = {
+ 	[0] = {
+@@ -642,22 +643,27 @@ static struct platform_device at91sam9rl_tsadcc_device = {
+ 	.dev		= {
+ 				.dma_mask		= &tsadcc_dmamask,
+ 				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &tsadcc_data,
+ 	},
+ 	.resource	= tsadcc_resources,
+ 	.num_resources	= ARRAY_SIZE(tsadcc_resources),
+ };
+ 
+-void __init at91_add_device_tsadcc(void)
++void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
+ {
++	if (!data)
++		return;
++
+ 	at91_set_A_periph(AT91_PIN_PA17, 0);	/* AD0_XR */
+ 	at91_set_A_periph(AT91_PIN_PA18, 0);	/* AD1_XL */
+ 	at91_set_A_periph(AT91_PIN_PA19, 0);	/* AD2_YT */
+ 	at91_set_A_periph(AT91_PIN_PA20, 0);	/* AD3_TB */
+ 
++	tsadcc_data = *data;
+ 	platform_device_register(&at91sam9rl_tsadcc_device);
+ }
+ #else
+-void __init at91_add_device_tsadcc(void) {}
++void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
+ #endif
+ 
+ 
+diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
+index 26cde27..23e6546 100644
+--- a/arch/arm/mach-at91/board-sam9rlek.c
++++ b/arch/arm/mach-at91/board-sam9rlek.c
+@@ -243,6 +243,16 @@ static struct gpio_led ek_leds[] = {
+ 
+ 
+ /*
++ * Touchscreen
++ */
++static struct at91_tsadcc_data ek_tsadcc_data = {
++	.adc_clock		= 1000000,
++	.pendet_debounce	= 0x0f,
++	.ts_sample_hold_time	= 0x03,
++};
++
++
++/*
+  * GPIO Buttons
+  */
+ #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+@@ -310,7 +320,7 @@ static void __init ek_board_init(void)
+ 	/* AC97 */
+ 	at91_add_device_ac97(&ek_ac97_data);
+ 	/* Touch Screen Controller */
+-	at91_add_device_tsadcc();
++	at91_add_device_tsadcc(&ek_tsadcc_data);
+ 	/* LEDs */
+ 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ 	/* Push Buttons */
+diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
+index d1f1c38..b553970 100644
+--- a/arch/arm/mach-at91/include/mach/board.h
++++ b/arch/arm/mach-at91/include/mach/board.h
+@@ -187,7 +187,12 @@ extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
+ extern void __init at91_add_device_isi(void);
+ 
+  /* Touchscreen Controller */
+-extern void __init at91_add_device_tsadcc(void);
++struct at91_tsadcc_data {
++	unsigned int    adc_clock;
++	u8		pendet_debounce;
++	u8		ts_sample_hold_time;
++};
++extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data);
+ 
+  /* LEDs */
+ extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
+-- 
+1.5.6.5
+
+From b2e0d6d0193307c3735d0f34a9940bdfa036341c Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:50 +0000
+Subject: [PATCH] at91/input: touchscreen support for at91sam9g45ekes
+
+New at91sam9g45ekes board provides a LCD with resistive touchscreen. This is the
+support of this feature by atmel_tsadcc driver.
+This also sets up platform parameters to be passed to the driver.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11618 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/at91sam9g45_devices.c |   51 ++++++++++++++++++++++++++++++
+ arch/arm/mach-at91/board-sam9m10g45ek.c  |   12 +++++++
+ drivers/input/touchscreen/Kconfig        |    2 +-
+ 3 files changed, 64 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index 425ea97..3d9c66e 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -1025,6 +1025,57 @@ static void __init at91_add_device_rtc(void) {}
+ 
+ 
+ /* --------------------------------------------------------------------
++ *  Touchscreen
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
++static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
++static struct at91_tsadcc_data tsadcc_data;
++
++static struct resource tsadcc_resources[] = {
++	[0] = {
++		.start	= AT91SAM9G45_BASE_TSC,
++		.end	= AT91SAM9G45_BASE_TSC + SZ_16K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AT91SAM9G45_ID_TSC,
++		.end	= AT91SAM9G45_ID_TSC,
++		.flags	= IORESOURCE_IRQ,
++	}
++};
++
++static struct platform_device at91sam9g45_tsadcc_device = {
++	.name		= "atmel_tsadcc",
++	.id		= -1,
++	.dev		= {
++				.dma_mask		= &tsadcc_dmamask,
++				.coherent_dma_mask	= DMA_BIT_MASK(32),
++				.platform_data		= &tsadcc_data,
++	},
++	.resource	= tsadcc_resources,
++	.num_resources	= ARRAY_SIZE(tsadcc_resources),
++};
++
++void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
++{
++	if (!data)
++		return;
++
++	at91_set_gpio_input(AT91_PIN_PD20, 0);	/* AD0_XR */
++	at91_set_gpio_input(AT91_PIN_PD21, 0);	/* AD1_XL */
++	at91_set_gpio_input(AT91_PIN_PD22, 0);	/* AD2_YT */
++	at91_set_gpio_input(AT91_PIN_PD23, 0);	/* AD3_TB */
++
++	tsadcc_data = *data;
++	platform_device_register(&at91sam9g45_tsadcc_device);
++}
++#else
++void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+  *  RTT
+  * -------------------------------------------------------------------- */
+ 
+diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
+index 2ffeb77..2d3326d 100644
+--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
++++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
+@@ -250,6 +250,16 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+ 
+ 
+ /*
++ * Touchscreen
++ */
++static struct at91_tsadcc_data ek_tsadcc_data = {
++	.adc_clock		= 300000,
++	.pendet_debounce	= 0x0d,
++	.ts_sample_hold_time	= 0x0a,
++};
++
++
++/*
+  * GPIO Buttons
+  */
+ #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+@@ -403,6 +413,8 @@ static void __init ek_board_init(void)
+ 	at91_add_device_i2c(0, NULL, 0);
+ 	/* LCD Controller */
+ 	at91_add_device_lcdc(&ek_lcdc_data);
++	/* Touch Screen */
++	at91_add_device_tsadcc(&ek_tsadcc_data);
+ 	/* Push Buttons */
+ 	ek_add_device_buttons();
+ 	/* AC97 */
+diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
+index 5855305..545af53 100644
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -277,7 +277,7 @@ config TOUCHSCREEN_TOUCHWIN
+ 
+ config TOUCHSCREEN_ATMEL_TSADCC
+ 	tristate "Atmel Touchscreen Interface"
+-	depends on ARCH_AT91SAM9RL
++	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+ 	default y
+ 	help
+ 	  Say Y here if you have a 4-wire touchscreen connected to the
+-- 
+1.5.6.5
+
+From 4c9c2be310b2b196b9f693834f6f9be62fa2ec0f Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:51 +0000
+Subject: [PATCH] at91: extend power management to at91sam9g45 chip
+
+Add at91sam9g45 defines to select proper RAM chip for power management
+handling.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11619 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/pm.c           |    6 ++++--
+ arch/arm/mach-at91/pm_slowclock.S |   11 +++++++----
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
+index 242ba6e..2ec022d 100644
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -40,9 +40,11 @@
+ #define sdram_selfrefresh_enable()	at91_sys_write(AT91_SDRAMC_SRR, 1)
+ #define sdram_selfrefresh_disable()	do {} while (0)
+ 
+-#elif defined(CONFIG_ARCH_AT91CAP9)
++#elif defined(CONFIG_ARCH_AT91CAP9) || defined(CONFIG_ARCH_AT91SAM9G45)
+ #include <mach/at91cap9_ddrsdr.h>
+-
++#if defined(CONFIG_ARCH_AT91SAM9G45)
++#define AT91_DDRSDRC	AT91_DDRSDRC1
++#endif
+ static u32 saved_lpr;
+ 
+ static inline void sdram_selfrefresh_enable(void)
+diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
+index 987fab3..b29807a 100644
+--- a/arch/arm/mach-at91/pm_slowclock.S
++++ b/arch/arm/mach-at91/pm_slowclock.S
+@@ -18,7 +18,7 @@
+ 
+ #ifdef CONFIG_ARCH_AT91RM9200
+ #include <mach/at91rm9200_mc.h>
+-#elif defined(CONFIG_ARCH_AT91CAP9)
++#elif defined(CONFIG_ARCH_AT91CAP9) || defined(CONFIG_ARCH_AT91SAM9G45)
+ #include <mach/at91cap9_ddrsdr.h>
+ #else
+ #include <mach/at91sam9_sdramc.h>
+@@ -34,6 +34,9 @@
+ #warning Assuming EB1 SDRAM controller is *NOT* used
+ #endif
+ 
++#ifdef CONFIG_ARCH_AT91SAM9G45
++#define AT91_DDRSDRC	AT91_DDRSDRC1
++#endif
+ /*
+  * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
+  * clock during suspend by adjusting its prescalar and divisor.
+@@ -127,7 +130,7 @@ ENTRY(at91_slow_clock)
+ 	/* Put SDRAM in self-refresh mode */
+ 	mov	r3, #1
+ 	str	r3, [r2, #AT91_SDRAMC_SRR]
+-#elif defined(CONFIG_ARCH_AT91CAP9)
++#elif defined(CONFIG_ARCH_AT91CAP9) || defined(CONFIG_ARCH_AT91SAM9G45)
+ 	/* Enable SDRAM self-refresh mode */
+ 	ldr	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+ 	str	r3, .saved_sam9_lpr
+@@ -239,7 +242,7 @@ ENTRY(at91_slow_clock)
+ 
+ #ifdef CONFIG_ARCH_AT91RM9200
+ 	/* Do nothing - self-refresh is automatically disabled. */
+-#elif defined(CONFIG_ARCH_AT91CAP9)
++#elif defined(CONFIG_ARCH_AT91CAP9) || defined(CONFIG_ARCH_AT91SAM9G45)
+ 	/* Restore LPR on AT91CAP9 */
+ 	ldr	r3, .saved_sam9_lpr
+ 	str	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+@@ -271,7 +274,7 @@ ENTRY(at91_slow_clock)
+ #ifdef CONFIG_ARCH_AT91RM9200
+ .at91_va_base_sdramc:
+ 	.word AT91_VA_BASE_SYS
+-#elif defined(CONFIG_ARCH_AT91CAP9)
++#elif defined(CONFIG_ARCH_AT91CAP9) || defined(CONFIG_ARCH_AT91SAM9G45)
+ .at91_va_base_sdramc:
+ 	.word AT91_VA_BASE_SYS + AT91_DDRSDRC
+ #else
+-- 
+1.5.6.5
+
+From 3be60088d7a631833649ce7f829db794ef46ec99 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:52 +0000
+Subject: [PATCH] at91: at91sam9g45 family: identify several chip versions
+
+cpu_is_xxx() macros are identifying generic at91sam9g45 chip. This patch adds
+the capacity to differentiate Engineering Samples and final lots through the
+inclusion of  at91_cpu_fully_identify() and the related chip IDs with chip
+version field preserved.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11620 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/include/mach/cpu.h     |    9 +++++++++
+ arch/avr32/mach-at32ap/include/mach/cpu.h |    1 +
+ 2 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
+index 6d8c1b9..5a06501 100644
+--- a/arch/arm/mach-at91/include/mach/cpu.h
++++ b/arch/arm/mach-at91/include/mach/cpu.h
+@@ -25,6 +25,8 @@
+ #define ARCH_ID_AT91SAM9G20	0x019905a0
+ #define ARCH_ID_AT91SAM9RL64	0x019b03a0
+ #define ARCH_ID_AT91SAM9G45	0x819b05a0
++#define ARCH_ID_AT91SAM9G45MRL	0x819b05a2	/* aka 9G45-ES2 & non ES lots */
++#define ARCH_ID_AT91SAM9G45ES	0x819b05a1	/* 9G45-ES (Engineering Sample) */
+ #define ARCH_ID_AT91CAP9	0x039A03A0
+ 
+ #define ARCH_ID_AT91SAM9XE128	0x329973a0
+@@ -43,6 +45,11 @@ static inline unsigned long at91_cpu_identify(void)
+ 	return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
+ }
+ 
++static inline unsigned long at91_cpu_fully_identify(void)
++{
++	return at91_sys_read(AT91_DBGU_CIDR);
++}
++
+ #define ARCH_EXID_AT91SAM9M11	0x00000001
+ #define ARCH_EXID_AT91SAM9M10	0x00000002
+ #define ARCH_EXID_AT91SAM9G45	0x00000004
+@@ -120,8 +127,10 @@ static inline unsigned long at91cap9_rev_identify(void)
+ 
+ #ifdef CONFIG_ARCH_AT91SAM9G45
+ #define cpu_is_at91sam9g45()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
++#define cpu_is_at91sam9g45es()	(at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
+ #else
+ #define cpu_is_at91sam9g45()	(0)
++#define cpu_is_at91sam9g45es()	(0)
+ #endif
+ 
+ #ifdef CONFIG_ARCH_AT91CAP9
+diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h
+index c253e9b..9c96a13 100644
+--- a/arch/avr32/mach-at32ap/include/mach/cpu.h
++++ b/arch/avr32/mach-at32ap/include/mach/cpu.h
+@@ -33,5 +33,6 @@
+ #define cpu_is_at91cap9()	(0)
+ #define cpu_is_at91sam9g10()	(0)
+ #define cpu_is_at91sam9g45()	(0)
++#define cpu_is_at91sam9g45es()	(0)
+ 
+ #endif /* __ASM_ARCH_CPU_H */
+-- 
+1.5.6.5
+
+From 6a16736be8cb4670127c8f7b2cf1eb7ddeee4a9f Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:52 +0000
+Subject: [PATCH] atmel_lcdfb: New alternate pixel clock formula
+
+at91sam9g45 non ES lots have an alternate pixel clock
+calculation formula. Introduce this one with condition
+on the cpu_is_xxxxx() macros.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11621 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/video/atmel_lcdfb.c |   11 ++++++++---
+ 1 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
+index a476a0e..935fb45 100644
+--- a/drivers/video/atmel_lcdfb.c
++++ b/drivers/video/atmel_lcdfb.c
+@@ -481,6 +481,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
+ 	unsigned long value;
+ 	unsigned long clk_value_khz;
+ 	unsigned long bits_per_line;
++	unsigned long pix_factor = 2;
+ 
+ 	might_sleep();
+ 
+@@ -513,20 +514,24 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
+ 	/* Now, the LCDC core... */
+ 
+ 	/* Set pixel clock */
++	if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es())
++		pix_factor = 1;
++
+ 	clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
+ 
+ 	value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
+ 
+-	if (value < 2) {
++	if (value < pix_factor) {
+ 		dev_notice(info->device, "Bypassing pixel clock divider\n");
+ 		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
+ 	} else {
+-		value = (value / 2) - 1;
++		value = (value / pix_factor) - 1;
+ 		dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n",
+ 				value);
+ 		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1,
+ 				value << ATMEL_LCDC_CLKVAL_OFFSET);
+-		info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
++		info->var.pixclock =
++			KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1)));
+ 		dev_dbg(info->device, "  updated pixclk:     %lu KHz\n",
+ 					PICOS2KHZ(info->var.pixclock));
+ 	}
+-- 
+1.5.6.5
+
+From 3ea7bf96510d12cdddbeccae8117c824d8596ee5 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:53 +0000
+Subject: [PATCH] mach-types: add 2MMC slot 9g20 board
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11622 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/tools/mach-types |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
+index fec6467..165288a 100644
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -2245,3 +2245,4 @@ str9			MACH_STR9		STR9			2257
+ omap3_wl_ff		MACH_OMAP3_WL_FF	OMAP3_WL_FF		2258
+ simcom			MACH_SIMCOM		SIMCOM			2259
+ mcwebio			MACH_MCWEBIO		MCWEBIO			2260
++at91sam9g20ek_2mmc	MACH_AT91SAM9G20EK_2MMC	AT91SAM9G20EK_2MMC	2288
+-- 
+1.5.6.5
+
+From 6fed8ebb469a36d55eb795e6e56173b2a32cdf9b Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:54 +0000
+Subject: [PATCH] at91: at91sam9g20ek add card detect signal to sd/mmc
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11623 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9g20ek.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
+index 88c724d..2062d7f 100644
+--- a/arch/arm/mach-at91/board-sam9g20ek.c
++++ b/arch/arm/mach-at91/board-sam9g20ek.c
+@@ -195,11 +195,12 @@ static void __init ek_add_device_nand(void)
+ 
+ /*
+  * MCI (SD/MMC)
+- * det_pin, wp_pin and vcc_pin are not connected
++ * wp_pin and vcc_pin are not connected
+  */
+ static struct at91_mmc_data __initdata ek_mmc_data = {
+ 	.slot_b		= 1,
+ 	.wire4		= 1,
++	.det_pin	= AT91_PIN_PC9,
+ };
+ 
+ 
+-- 
+1.5.6.5
+
+From c755add0475ea203a3194f7daa1ecf3ace44cba4 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:54 +0000
+Subject: [PATCH] at91: at91sam9g20ek modify dual slot evaluation kit
+
+at91sam9g20ek rev. C and onwards embed two SD/MMC slots. This patch modify the
+previous dual slot board definition to match the official rev. C board. It also
+allows the use of at91_mci SD/MMC driver in addition to the atmel-mci one.
+
+Some pins have been re-affected from leds or Ethernet phy IRQ to the SD/MMC
+slot A. This lead to a modification of those definitions.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11624 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/Kconfig                     |   10 ++++++----
+ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c |   23 +++++++++++++++--------
+ 2 files changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index 98eed85..359b0bc 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -359,14 +359,16 @@ config MACH_AT91SAM9G20EK
+ 	bool "Atmel AT91SAM9G20-EK Evaluation Kit"
+ 	depends on ARCH_AT91SAM9G20
+ 	help
+-	  Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
++	  Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
++	  that embeds only one SD/MMC slot.
+ 
+ config MACH_AT91SAM9G20EK_2MMC
+-	bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots"
++	bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
+ 	depends on ARCH_AT91SAM9G20
+ 	help
+ 	  Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
+-	  Rev A or B modified for 2 MMC Slots.
++	  with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
++	  onwards.
+ 
+ config MACH_USB_A9G20
+ 	bool "CALAO USB-A9G20"
+@@ -465,7 +467,7 @@ config MTD_AT91_DATAFLASH_CARD
+ 
+ config MTD_NAND_ATMEL_BUSWIDTH_16
+ 	bool "Enable 16-bit data bus interface to NAND flash"
+-	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK || MACH_AT572D940HFEB)
++	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G20EK_2MMC || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK || MACH_AT572D940HFEB)
+ 	help
+ 	  On AT91SAM926x boards both types of NAND flash can be present
+ 	  (8 and 16 bit data bus width).
+diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+index a28e53f..a4102d7 100644
+--- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
++++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+@@ -90,7 +90,7 @@ static struct at91_udc_data __initdata ek_udc_data = {
+  * SPI devices.
+  */
+ static struct spi_board_info ek_spi_devices[] = {
+-#if !defined(CONFIG_MMC_ATMELMCI)
++#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
+ 	{	/* DataFlash chip */
+ 		.modalias	= "mtd_dataflash",
+ 		.chip_select	= 1,
+@@ -113,7 +113,7 @@ static struct spi_board_info ek_spi_devices[] = {
+  * MACB Ethernet device
+  */
+ static struct at91_eth_data __initdata ek_macb_data = {
+-	.phy_irq_pin	= AT91_PIN_PC12,
++	.phy_irq_pin	= AT91_PIN_PB0,
+ 	.is_rmii	= 1,
+ };
+ 
+@@ -194,24 +194,27 @@ static void __init ek_add_device_nand(void)
+ 
+ /*
+  * MCI (SD/MMC)
+- * det_pin and wp_pin are not connected
++ * wp_pin is not connected
+  */
+ #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ static struct mci_platform_data __initdata ek_mmc_data = {
+ 	.slot[0] = {
+ 		.bus_width	= 4,
+-		.detect_pin	= -ENODEV,
++		.detect_pin	= AT91_PIN_PC2,
+ 		.wp_pin		= -ENODEV,
+ 	},
+ 	.slot[1] = {
+ 		.bus_width	= 4,
+-		.detect_pin	= -ENODEV,
++		.detect_pin	= AT91_PIN_PC9,
+ 		.wp_pin		= -ENODEV,
+ 	},
+ 
+ };
+ #else
+-static struct amci_platform_data __initdata ek_mmc_data = {
++static struct at91_mmc_data __initdata ek_mmc_data = {
++	.slot_b		= 1,	/* Only one slot so use slot B */
++	.wire4		= 1,
++	.det_pin	= AT91_PIN_PC9,
+ };
+ #endif
+ 
+@@ -221,13 +224,13 @@ static struct amci_platform_data __initdata ek_mmc_data = {
+ static struct gpio_led ek_leds[] = {
+ 	{	/* "bottom" led, green, userled1 to be defined */
+ 		.name			= "ds5",
+-		.gpio			= AT91_PIN_PB12,
++		.gpio			= AT91_PIN_PB8,
+ 		.active_low		= 1,
+ 		.default_trigger	= "none",
+ 	},
+ 	{	/* "power" led, yellow */
+ 		.name			= "ds1",
+-		.gpio			= AT91_PIN_PB13,
++		.gpio			= AT91_PIN_PB9,
+ 		.default_trigger	= "heartbeat",
+ 	}
+ };
+@@ -254,7 +257,11 @@ static void __init ek_board_init(void)
+ 	/* Ethernet */
+ 	at91_add_device_eth(&ek_macb_data);
+ 	/* MMC */
++#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ 	at91_add_device_mci(0, &ek_mmc_data);
++#else
++	at91_add_device_mmc(0, &ek_mmc_data);
++#endif
+ 	/* I2C */
+ 	at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+ 	/* LEDs */
+-- 
+1.5.6.5
+
+From fd5059821a6479c24dbe0b783ed3e73648bc1342 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:55 +0000
+Subject: [PATCH] at91: add gpio buttons to at91sam9g20-ek-2mmc
+
+This adds gpio buttons on the at91sam9g20ek dual SD/MMC slot
+boards.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11625 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c |   53 ++++++++++++++++++++++++
+ 1 files changed, 53 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+index a4102d7..bb48f31 100644
+--- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
++++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+@@ -38,6 +38,8 @@
+ 
+ #include <mach/board.h>
+ #include <mach/gpio.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
+ #include <mach/at91sam9_smc.h>
+ 
+ #include "sam9_smc.h"
+@@ -235,6 +237,55 @@ static struct gpio_led ek_leds[] = {
+ 	}
+ };
+ 
++/*
++ * GPIO Buttons
++ */
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++static struct gpio_keys_button ek_buttons[] = {
++	{
++		.gpio		= AT91_PIN_PA30,
++		.code		= BTN_3,
++		.desc		= "Button 3",
++		.active_low	= 1,
++		.wakeup		= 1,
++	},
++	{
++		.gpio		= AT91_PIN_PA31,
++		.code		= BTN_4,
++		.desc		= "Button 4",
++		.active_low	= 1,
++		.wakeup		= 1,
++	}
++};
++
++static struct gpio_keys_platform_data ek_button_data = {
++	.buttons	= ek_buttons,
++	.nbuttons	= ARRAY_SIZE(ek_buttons),
++};
++
++static struct platform_device ek_button_device = {
++	.name		= "gpio-keys",
++	.id		= -1,
++	.num_resources	= 0,
++	.dev		= {
++		.platform_data	= &ek_button_data,
++	}
++};
++
++static void __init ek_add_device_buttons(void)
++{
++	at91_set_gpio_input(AT91_PIN_PA30, 1);	/* btn3 */
++	at91_set_deglitch(AT91_PIN_PA30, 1);
++	at91_set_gpio_input(AT91_PIN_PA31, 1);	/* btn4 */
++	at91_set_deglitch(AT91_PIN_PA31, 1);
++
++	platform_device_register(&ek_button_device);
++}
++#else
++static void __init ek_add_device_buttons(void) {}
++#endif
++
++
+ static struct i2c_board_info __initdata ek_i2c_devices[] = {
+ 	{
+ 		I2C_BOARD_INFO("24c512", 0x50),
+@@ -266,6 +317,8 @@ static void __init ek_board_init(void)
+ 	at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+ 	/* LEDs */
+ 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++	/* Push Buttons */
++	ek_add_device_buttons();
+ 	/* PCK0 provides MCLK to the WM8731 */
+ 	at91_set_B_periph(AT91_PIN_PC1, 0);
+ 	/* SSC (for WM8731) */
+-- 
+1.5.6.5
+
+From 08b723fcf714ba726816bf095043c5cf677aad3b Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:56 +0000
+Subject: [PATCH] Bug workaround for channel in ac97
+
+This is only a workaround for channel handling in ac97 for AT91
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11626 50fbe906-d41e-0410-8a96-31537896a350
+---
+ sound/atmel/ac97c.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
+index 54d1365..20e5378 100644
+--- a/sound/atmel/ac97c.c
++++ b/sound/atmel/ac97c.c
+@@ -156,7 +156,7 @@ static struct snd_pcm_hardware atmel_ac97c_hw = {
+ 	.rates			= (SNDRV_PCM_RATE_CONTINUOUS),
+ 	.rate_min		= 4000,
+ 	.rate_max		= 48000,
+-	.channels_min		= 1,
++	.channels_min		= 2,
+ 	.channels_max		= 2,
+ 	.buffer_bytes_max	= 2 * 2 * 64 * 2048,
+ 	.period_bytes_min	= 4096,
+-- 
+1.5.6.5
+
+From 06a5d038a80c215bcb312582e1a8c01280f69aa5 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:57 +0000
+Subject: [PATCH] input: atmel_tsadcc: report fake pressure measure
+
+For compatibility to former tslib, we introduce a fake pressure report to input
+layer.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11627 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/input/touchscreen/atmel_tsadcc.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
+index 3c24783..27ac912 100644
+--- a/drivers/input/touchscreen/atmel_tsadcc.c
++++ b/drivers/input/touchscreen/atmel_tsadcc.c
+@@ -134,6 +134,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
+ 
+ 		input_report_key(input_dev, BTN_TOUCH, 0);
+ 		ts_dev->bufferedmeasure = 0;
++		input_report_abs(input_dev, ABS_PRESSURE, 0);
+ 		input_sync(input_dev);
+ 
+ 	} else if (status & ATMEL_TSADCC_PENCNT) {
+@@ -158,6 +159,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
+ 			input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
+ 			input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
+ 			input_report_key(input_dev, BTN_TOUCH, 1);
++			input_report_abs(input_dev, ABS_PRESSURE, 7500);
+ 			input_sync(input_dev);
+ 		} else
+ 			ts_dev->bufferedmeasure = 1;
+@@ -256,6 +258,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+ 	__set_bit(EV_ABS, input_dev->evbit);
+ 	input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
+ 	input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15000, 0, 0);
+ 
+ 	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+ 
+-- 
+1.5.6.5
+
+From b89093f368ba4a45a83d771aa97e1d91bd71fb47 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:57 +0000
+Subject: [PATCH] at91: No more SD/MMC Write-Protect pin connected on at91sam9263ek
+
+A change in board design rev.B and onwards make the Write-Protect pin disappear
+from schematics. Keeping pin assignment in SD/MMC interface definition results
+in mounting the card in read-only mode.
+We choose to remove this definition, even for rev.A as it will not disturb
+people as much as always mounting an SD card read-only.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11628 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/mach-at91/board-sam9263ek.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
+index dd3f093..7cbec96 100644
+--- a/arch/arm/mach-at91/board-sam9263ek.c
++++ b/arch/arm/mach-at91/board-sam9263ek.c
+@@ -155,7 +155,7 @@ static struct spi_board_info ek_spi_devices[] = {
+ static struct at91_mmc_data __initdata ek_mmc_data = {
+ 	.wire4		= 1,
+ 	.det_pin	= AT91_PIN_PE18,
+-	.wp_pin		= AT91_PIN_PE19,
++//	.wp_pin		= ... not connected
+ //	.vcc_pin	= ... not connected
+ };
+ 
+-- 
+1.5.6.5
+
+From 61d994a3953e0c2f0c7d4c794206107e14b6a294 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:58 +0000
+Subject: [PATCH] net: macb: modify SRAM location of descriptor buffers for 9xe chips
+
+At91sam9xe chips have internal FLASH instead of SRAM at first address. We can't
+locate macb descriptor buffers in this location. Instead put them in the
+alternative location.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11629 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/net/macb.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index 8bfe99a..d637702 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -740,7 +740,8 @@ static int macb_alloc_consistent(struct macb *bp)
+ 
+ #if defined(CONFIG_ARCH_AT91) && defined(CONFIG_MACB_TX_SRAM)
+ #if  defined(CONFIG_ARCH_AT91SAM9260)
+-	if (request_mem_region(AT91SAM9260_SRAM0_BASE, TX_DMA_SIZE, "macb")) {
++	if (!cpu_is_at91sam9xe()
++	&& request_mem_region(AT91SAM9260_SRAM0_BASE, TX_DMA_SIZE, "macb")) {
+ 		bp->tx_ring_dma = AT91SAM9260_SRAM0_BASE;
+ 	} else {
+ 		if (request_mem_region(AT91SAM9260_SRAM1_BASE, TX_DMA_SIZE, "macb")) {
+-- 
+1.5.6.5
+
+From 16c8418f5509ac2073eb9870f348d8a00ddfe8ce Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:59 +0000
+Subject: [PATCH] at91: add pwm support in Kconfig for at91sam9g45
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11630 50fbe906-d41e-0410-8a96-31537896a350
+---
+ drivers/misc/Kconfig |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 6d1ac18..8f6bee4 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -15,7 +15,7 @@ if MISC_DEVICES
+ 
+ config ATMEL_PWM
+ 	tristate "Atmel AT32/AT91 PWM support"
+-	depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
++	depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_AT91SAM9G45
+ 	help
+ 	  This option enables device driver support for the PWM channels
+ 	  on certain Atmel processors.  Pulse Width Modulation is used for
+-- 
+1.5.6.5
+
+From 27bbcb928deeb9afd2e84971a14b5b37b68ccee8 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:31:59 +0000
+Subject: [PATCH] at91: update at91sam9263ek defconfig file
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11631 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/configs/at91sam9263ek_defconfig |  817 ++++++++++++++++++++++--------
+ 1 files changed, 614 insertions(+), 203 deletions(-)
+
+diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig
+index 21599f3..cd12c96 100644
+--- a/arch/arm/configs/at91sam9263ek_defconfig
++++ b/arch/arm/configs/at91sam9263ek_defconfig
+@@ -1,17 +1,18 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc7
+-# Tue Jan  8 22:12:20 2008
++# Linux kernel version: 2.6.30
++# Wed Sep 30 18:40:20 2009
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+ CONFIG_GENERIC_GPIO=y
+-# CONFIG_GENERIC_TIME is not set
+-# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_MMU=y
+ # CONFIG_NO_IOPORT is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ CONFIG_HARDIRQS_SW_RESEND=y
+@@ -21,7 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+ CONFIG_VECTORS_BASE=0xffff0000
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+@@ -39,57 +40,82 @@ CONFIG_SYSVIPC_SYSCTL=y
+ # CONFIG_POSIX_MQUEUE is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
+ # CONFIG_CGROUPS is not set
+-CONFIG_FAIR_GROUP_SCHED=y
+-CONFIG_FAIR_USER_SCHED=y
+-# CONFIG_FAIR_CGROUP_SCHED is not set
+ CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
+ # CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
+ # CONFIG_EMBEDDED is not set
+ CONFIG_UID16=y
+ CONFIG_SYSCTL_SYSCALL=y
+ CONFIG_KALLSYMS=y
+-# CONFIG_KALLSYMS_ALL is not set
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
+ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+-CONFIG_ANON_INODES=y
+ CONFIG_EPOLL=y
+ CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
+ CONFIG_EVENTFD=y
+ CONFIG_SHMEM=y
++CONFIG_AIO=y
+ CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+ CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+ CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+ # CONFIG_MODVERSIONS is not set
+ # CONFIG_MODULE_SRCVERSION_ALL is not set
+-CONFIG_KMOD=y
+ CONFIG_BLOCK=y
+ # CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+ # CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
+ 
+ #
+ # IO Schedulers
+@@ -103,6 +129,7 @@ CONFIG_DEFAULT_AS=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
+ 
+ #
+ # System Type
+@@ -112,11 +139,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ # CONFIG_ARCH_REALVIEW is not set
+ # CONFIG_ARCH_VERSATILE is not set
+ CONFIG_ARCH_AT91=y
+-# CONFIG_ARCH_CLPS7500 is not set
+ # CONFIG_ARCH_CLPS711X is not set
+-# CONFIG_ARCH_CO285 is not set
+ # CONFIG_ARCH_EBSA110 is not set
+ # CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
+ # CONFIG_ARCH_FOOTBRIDGE is not set
+ # CONFIG_ARCH_NETX is not set
+ # CONFIG_ARCH_H720X is not set
+@@ -128,26 +154,26 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_IXP2000 is not set
+ # CONFIG_ARCH_IXP4XX is not set
+ # CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
+ # CONFIG_ARCH_KS8695 is not set
+ # CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
+ # CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
+ # CONFIG_ARCH_PNX4008 is not set
+ # CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
+ # CONFIG_ARCH_RPC is not set
+ # CONFIG_ARCH_SA1100 is not set
+ # CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
+ # CONFIG_ARCH_SHARK is not set
+ # CONFIG_ARCH_LH7A40X is not set
+ # CONFIG_ARCH_DAVINCI is not set
+ # CONFIG_ARCH_OMAP is not set
+-
+-#
+-# Boot options
+-#
+-
+-#
+-# Power management
+-#
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
+ 
+ #
+ # Atmel AT91 System-on-Chip
+@@ -155,15 +181,24 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_AT91RM9200 is not set
+ # CONFIG_ARCH_AT91SAM9260 is not set
+ # CONFIG_ARCH_AT91SAM9261 is not set
++# CONFIG_ARCH_AT91SAM9G10 is not set
+ CONFIG_ARCH_AT91SAM9263=y
+ # CONFIG_ARCH_AT91SAM9RL is not set
++# CONFIG_ARCH_AT91SAM9G20 is not set
++# CONFIG_ARCH_AT91SAM9G45 is not set
++# CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
+ # CONFIG_ARCH_AT91X40 is not set
+ CONFIG_AT91_PMC_UNIT=y
++# CONFIG_MACH_NEOCORE926 is not set
+ 
+ #
+ # AT91SAM9263 Board Type
+ #
+ CONFIG_MACH_AT91SAM9263EK=y
++# CONFIG_MACH_USB_A9263 is not set
++# CONFIG_MACH_CSB737 is not set
++# CONFIG_MACH_TOTEMNOVA is not set
+ 
+ #
+ # AT91 Board Options
+@@ -174,9 +209,16 @@ CONFIG_MTD_AT91_DATAFLASH_CARD=y
+ #
+ # AT91 Feature Selections
+ #
+-# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+-# CONFIG_ATMEL_TCLIB is not set
++CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
++# CONFIG_AT91_SLOW_CLOCK is not set
+ CONFIG_AT91_TIMER_HZ=100
++CONFIG_AT91_EARLY_DBGU=y
++# CONFIG_AT91_EARLY_USART0 is not set
++# CONFIG_AT91_EARLY_USART1 is not set
++# CONFIG_AT91_EARLY_USART2 is not set
++# CONFIG_AT91_EARLY_USART3 is not set
++# CONFIG_AT91_EARLY_USART4 is not set
++# CONFIG_AT91_EARLY_USART5 is not set
+ 
+ #
+ # Processor Type
+@@ -185,6 +227,7 @@ CONFIG_CPU_32=y
+ CONFIG_CPU_ARM926T=y
+ CONFIG_CPU_32v5=y
+ CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
+ CONFIG_CPU_CACHE_VIVT=y
+ CONFIG_CPU_COPY_V4WB=y
+ CONFIG_CPU_TLB_V4WBI=y
+@@ -194,7 +237,7 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Processor Features
+ #
+-# CONFIG_ARM_THUMB is not set
++CONFIG_ARM_THUMB=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+@@ -211,25 +254,37 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Kernel Features
+ #
+-# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
+ # CONFIG_PREEMPT is not set
+ CONFIG_HZ=100
+-# CONFIG_AEABI is not set
+-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
+ CONFIG_SELECT_MEMORY_MODEL=y
+ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
+-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4096
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-CONFIG_BOUNCE=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_VIRT_TO_BUS=y
+-# CONFIG_LEDS is not set
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_LEDS=y
++CONFIG_LEDS_CPU=y
+ CONFIG_ALIGNMENT_TRAP=y
+ 
+ #
+@@ -242,6 +297,11 @@ CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev
+ # CONFIG_KEXEC is not set
+ 
+ #
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
+ # Floating point emulation
+ #
+ 
+@@ -257,19 +317,21 @@ CONFIG_FPE_NWFPE=y
+ # Userspace binary formats
+ #
+ CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
+ # CONFIG_BINFMT_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+-# CONFIG_ARTHUR is not set
+ 
+ #
+ # Power management options
+ #
+-# CONFIG_PM is not set
+-CONFIG_SUSPEND_UP_POSSIBLE=y
+-
+-#
+-# Networking
+-#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ CONFIG_NET=y
+ 
+ #
+@@ -280,7 +342,7 @@ CONFIG_PACKET=y
+ CONFIG_UNIX=y
+ # CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
++CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_FIB_HASH=y
+ CONFIG_IP_PNP=y
+@@ -289,6 +351,7 @@ CONFIG_IP_PNP_BOOTP=y
+ CONFIG_IP_PNP_RARP=y
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+@@ -306,8 +369,6 @@ CONFIG_TCP_CONG_CUBIC=y
+ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TCP_MD5SIG is not set
+ # CONFIG_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+ # CONFIG_NETWORK_SECMARK is not set
+ # CONFIG_NETFILTER is not set
+ # CONFIG_IP_DCCP is not set
+@@ -315,6 +376,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_LLC2 is not set
+@@ -324,24 +386,40 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_LAPB is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
+ # CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
+ 
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+ # CONFIG_AF_RXRPC is not set
+-
+-#
+-# Wireless
+-#
+-# CONFIG_CFG80211 is not set
+-# CONFIG_WIRELESS_EXT is not set
+-# CONFIG_MAC80211 is not set
+-# CONFIG_IEEE80211 is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
+ # CONFIG_RFKILL is not set
+ # CONFIG_NET_9P is not set
+ 
+@@ -355,18 +433,20 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
+-# CONFIG_DEBUG_DRIVER is not set
+-# CONFIG_DEBUG_DEVRES is not set
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_SYS_HYPERVISOR is not set
+ # CONFIG_CONNECTOR is not set
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+ # CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ CONFIG_MTD_CMDLINE_PARTS=y
+ # CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
+ 
+ #
+ # User Modules And Translation Layers
+@@ -410,6 +490,8 @@ CONFIG_MTD_CFI_I2=y
+ # Self-contained MTD device drivers
+ #
+ CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
+ # CONFIG_MTD_M25P80 is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+@@ -426,15 +508,24 @@ CONFIG_MTD_NAND=y
+ # CONFIG_MTD_NAND_VERIFY_WRITE is not set
+ # CONFIG_MTD_NAND_ECC_SMC is not set
+ # CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
+ CONFIG_MTD_NAND_IDS=y
+ # CONFIG_MTD_NAND_DISKONCHIP is not set
+ CONFIG_MTD_NAND_ATMEL=y
++CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
++# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
++# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+ # CONFIG_MTD_NAND_NANDSIM is not set
+ # CONFIG_MTD_NAND_PLATFORM is not set
+ # CONFIG_MTD_ALAUDA is not set
+ # CONFIG_MTD_ONENAND is not set
+ 
+ #
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
+ # UBI - Unsorted block images
+ #
+ # CONFIG_MTD_UBI is not set
+@@ -448,12 +539,28 @@ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=8192
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_BLK_DEV_XIP is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+ CONFIG_MISC_DEVICES=y
++CONFIG_ATMEL_PWM=y
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
+ # CONFIG_EEPROM_93CX6 is not set
+-CONFIG_ATMEL_SSC=y
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
+ 
+ #
+ # SCSI device support
+@@ -494,11 +601,15 @@ CONFIG_SCSI_WAIT_SCAN=m
+ # CONFIG_SCSI_SRP_ATTRS is not set
+ CONFIG_SCSI_LOWLEVEL=y
+ # CONFIG_ISCSI_TCP is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
+ # CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
+ CONFIG_NETDEVICES=y
+-# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_COMPAT_NET_DEV_OPS is not set
+ # CONFIG_DUMMY is not set
+ # CONFIG_BONDING is not set
+ # CONFIG_MACVLAN is not set
+@@ -511,7 +622,7 @@ CONFIG_PHYLIB=y
+ # MII PHY device drivers
+ #
+ # CONFIG_MARVELL_PHY is not set
+-# CONFIG_DAVICOM_PHY is not set
++CONFIG_DAVICOM_PHY=y
+ # CONFIG_QSEMI_PHY is not set
+ # CONFIG_LXT_PHY is not set
+ # CONFIG_CICADA_PHY is not set
+@@ -519,27 +630,72 @@ CONFIG_PHYLIB=y
+ # CONFIG_SMSC_PHY is not set
+ # CONFIG_BROADCOM_PHY is not set
+ # CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
+ # CONFIG_FIXED_PHY is not set
+ # CONFIG_MDIO_BITBANG is not set
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+ CONFIG_MACB=y
++CONFIG_MACB_TX_SRAM=y
+ # CONFIG_AX88796 is not set
+ # CONFIG_SMC91X is not set
+ # CONFIG_DM9000 is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
+ # CONFIG_IBM_NEW_EMAC_ZMII is not set
+ # CONFIG_IBM_NEW_EMAC_RGMII is not set
+ # CONFIG_IBM_NEW_EMAC_TAH is not set
+ # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+ # CONFIG_B44 is not set
+-CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
+ 
+ #
+ # Wireless LAN
+ #
+ # CONFIG_WLAN_PRE80211 is not set
+-# CONFIG_WLAN_80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_USB=m
++CONFIG_LIBERTAS_SDIO=m
++CONFIG_LIBERTAS_SPI=m
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++CONFIG_USB_ZD1201=m
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++CONFIG_RTL8187=m
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_AR9170_USB=m
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++CONFIG_RT2X00=m
++CONFIG_RT2500USB=m
++CONFIG_RT73USB=m
++CONFIG_RT2X00_LIB_USB=m
++CONFIG_RT2X00_LIB=m
++CONFIG_RT2X00_LIB_FIRMWARE=y
++CONFIG_RT2X00_LIB_CRYPTO=y
++CONFIG_RT2X00_LIB_RFKILL=y
++CONFIG_RT2X00_LIB_LEDS=y
++# CONFIG_RT2X00_DEBUG is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
+ 
+ #
+ # USB Network Adapters
+@@ -552,7 +708,6 @@ CONFIG_NETDEV_10000=y
+ # CONFIG_WAN is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+-# CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+@@ -563,15 +718,15 @@ CONFIG_NETDEV_10000=y
+ #
+ CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
+-# CONFIG_INPUT_POLLDEV is not set
++CONFIG_INPUT_POLLDEV=m
+ 
+ #
+ # Userland interfaces
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+ # CONFIG_INPUT_JOYDEV is not set
+ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+@@ -592,16 +747,24 @@ CONFIG_KEYBOARD_GPIO=y
+ # CONFIG_INPUT_TABLET is not set
+ CONFIG_INPUT_TOUCHSCREEN=y
+ CONFIG_TOUCHSCREEN_ADS7846=y
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
+ # CONFIG_TOUCHSCREEN_FUJITSU is not set
+ # CONFIG_TOUCHSCREEN_GUNZE is not set
+ # CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+ # CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
+ # CONFIG_TOUCHSCREEN_MK712 is not set
+ # CONFIG_TOUCHSCREEN_PENMOUNT is not set
+ # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+ # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+-# CONFIG_TOUCHSCREEN_UCB1400 is not set
++# CONFIG_TOUCHSCREEN_WM97XX is not set
+ # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
+@@ -614,9 +777,11 @@ CONFIG_TOUCHSCREEN_ADS7846=y
+ # Character devices
+ #
+ CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
+ CONFIG_HW_CONSOLE=y
+ # CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -629,63 +794,65 @@ CONFIG_HW_CONSOLE=y
+ #
+ CONFIG_SERIAL_ATMEL=y
+ CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
+ # CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+ CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
++CONFIG_LEGACY_PTY_COUNT=16
+ # CONFIG_IPMI_HANDLER is not set
+ CONFIG_HW_RANDOM=y
+-# CONFIG_NVRAM is not set
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
+ CONFIG_I2C=y
+ CONFIG_I2C_BOARDINFO=y
+-CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C_CHARDEV is not set
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_ALGOBIT=y
+ 
+ #
+-# I2C Algorithms
++# I2C Hardware Bus support
+ #
+-CONFIG_I2C_ALGOBIT=y
+-# CONFIG_I2C_ALGOPCF is not set
+-# CONFIG_I2C_ALGOPCA is not set
+ 
+ #
+-# I2C Hardware Bus support
++# I2C system bus drivers (mostly embedded / system-on-chip)
+ #
+ CONFIG_I2C_GPIO=y
+ # CONFIG_I2C_OCORES is not set
+-# CONFIG_I2C_PARPORT_LIGHT is not set
+ # CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
+ # CONFIG_I2C_TAOS_EVM is not set
+-# CONFIG_I2C_STUB is not set
+ # CONFIG_I2C_TINY_USB is not set
+-# CONFIG_I2C_PCA is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
+ 
+ #
+ # Miscellaneous I2C Chip support
+ #
+-# CONFIG_SENSORS_DS1337 is not set
+-# CONFIG_SENSORS_DS1374 is not set
+ # CONFIG_DS1682 is not set
+-# CONFIG_EEPROM_LEGACY is not set
+ # CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
+ # CONFIG_SENSORS_PCA9539 is not set
+-# CONFIG_SENSORS_PCF8591 is not set
+ # CONFIG_SENSORS_MAX6875 is not set
+ # CONFIG_SENSORS_TSL2550 is not set
+ # CONFIG_I2C_DEBUG_CORE is not set
+ # CONFIG_I2C_DEBUG_ALGO is not set
+ # CONFIG_I2C_DEBUG_BUS is not set
+ # CONFIG_I2C_DEBUG_CHIP is not set
+-
+-#
+-# SPI support
+-#
+ CONFIG_SPI=y
+-# CONFIG_SPI_DEBUG is not set
+ CONFIG_SPI_MASTER=y
+ 
+ #
+@@ -693,46 +860,84 @@ CONFIG_SPI_MASTER=y
+ #
+ CONFIG_SPI_ATMEL=y
+ # CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
+ 
+ #
+ # SPI Protocol Masters
+ #
+-# CONFIG_EEPROM_AT25 is not set
+ # CONFIG_SPI_SPIDEV is not set
+ # CONFIG_SPI_TLE62X0 is not set
+-# CONFIG_W1 is not set
+-# CONFIG_POWER_SUPPLY is not set
+-# CONFIG_HWMON is not set
+-CONFIG_WATCHDOG=y
+-CONFIG_WATCHDOG_NOWAYOUT=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
+ 
+ #
+-# Watchdog Device Drivers
++# Memory mapped GPIO expanders:
+ #
+-# CONFIG_SOFT_WATCHDOG is not set
+-CONFIG_AT91SAM9X_WATCHDOG=y
+ 
+ #
+-# USB-based Watchdog Cards
++# I2C GPIO expanders:
+ #
+-# CONFIG_USBPCWATCHDOG is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
+ 
+ #
+-# Sonics Silicon Backplane
++# PCI GPIO expanders:
+ #
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
+ CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
+ # CONFIG_SSB is not set
+ 
+ #
+ # Multifunction device drivers
+ #
++# CONFIG_MFD_CORE is not set
+ # CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_UCB1400_CORE is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
+ 
+ #
+ # Multimedia devices
+ #
++
++#
++# Multimedia core support
++#
+ # CONFIG_VIDEO_DEV is not set
+ # CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
+ # CONFIG_DAB is not set
+ 
+ #
+@@ -743,6 +948,7 @@ CONFIG_SSB_POSSIBLE=y
+ CONFIG_FB=y
+ # CONFIG_FIRMWARE_EDID is not set
+ # CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+ CONFIG_FB_CFB_FILLRECT=y
+ CONFIG_FB_CFB_COPYAREA=y
+ CONFIG_FB_CFB_IMAGEBLIT=y
+@@ -750,8 +956,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
+ # CONFIG_FB_SYS_FILLRECT is not set
+ # CONFIG_FB_SYS_COPYAREA is not set
+ # CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
+ # CONFIG_FB_SYS_FOPS is not set
+-CONFIG_FB_DEFERRED_IO=y
+ # CONFIG_FB_SVGALIB is not set
+ # CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_BACKLIGHT is not set
+@@ -765,7 +971,15 @@ CONFIG_FB_DEFERRED_IO=y
+ # CONFIG_FB_S1D13XXX is not set
+ CONFIG_FB_ATMEL=y
+ # CONFIG_FB_VIRTUAL is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_ATMEL_LCDC=y
++# CONFIG_BACKLIGHT_ATMEL_PWM is not set
++# CONFIG_BACKLIGHT_GENERIC is not set
+ 
+ #
+ # Display device support
+@@ -779,11 +993,41 @@ CONFIG_FB_ATMEL=y
+ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_FRAMEBUFFER_CONSOLE is not set
+ # CONFIG_LOGO is not set
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_SEQUENCER_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_VMASTER=y
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++
++#
++# Atmel devices (AVR32 and AT91)
++#
++CONFIG_SND_ATMEL_AC97C=y
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+ # CONFIG_HID_DEBUG is not set
+@@ -793,57 +1037,68 @@ CONFIG_HID=y
+ # USB Input Devices
+ #
+ # CONFIG_USB_HID is not set
++# CONFIG_HID_PID is not set
+ 
+ #
+-# USB HID Boot Protocol drivers
++# Special HID drivers
+ #
+-# CONFIG_USB_KBD is not set
+-# CONFIG_USB_MOUSE is not set
+ CONFIG_USB_SUPPORT=y
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_USB_ARCH_HAS_EHCI is not set
+ CONFIG_USB=y
+ # CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+ 
+ #
+ # Miscellaneous USB options
+ #
+ CONFIG_USB_DEVICEFS=y
+-CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DEVICE_CLASS is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
+ # CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
+ 
+ #
+ # USB Host Controller Drivers
+ #
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+ # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ # CONFIG_USB_SL811_HCD is not set
+ # CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+ #
+ 
+ #
+-# may also be needed; see USB_STORAGE Help for more information
++# also be needed; see USB_STORAGE Help for more info
+ #
+ CONFIG_USB_STORAGE=y
+ # CONFIG_USB_STORAGE_DEBUG is not set
+ # CONFIG_USB_STORAGE_DATAFAB is not set
+ # CONFIG_USB_STORAGE_FREECOM is not set
+ # CONFIG_USB_STORAGE_ISD200 is not set
+-# CONFIG_USB_STORAGE_DPCM is not set
+ # CONFIG_USB_STORAGE_USBAT is not set
+ # CONFIG_USB_STORAGE_SDDR09 is not set
+ # CONFIG_USB_STORAGE_SDDR55 is not set
+@@ -851,6 +1106,7 @@ CONFIG_USB_STORAGE=y
+ # CONFIG_USB_STORAGE_ALAUDA is not set
+ # CONFIG_USB_STORAGE_ONETOUCH is not set
+ # CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+ # CONFIG_USB_LIBUSUAL is not set
+ 
+ #
+@@ -858,15 +1114,10 @@ CONFIG_USB_STORAGE=y
+ #
+ # CONFIG_USB_MDC800 is not set
+ # CONFIG_USB_MICROTEK is not set
+-CONFIG_USB_MON=y
+ 
+ #
+ # USB port drivers
+ #
+-
+-#
+-# USB Serial Converter support
+-#
+ # CONFIG_USB_SERIAL is not set
+ 
+ #
+@@ -875,7 +1126,7 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_ADUTUX is not set
+-# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_SEVSEG is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+ # CONFIG_USB_LCD is not set
+@@ -883,7 +1134,6 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_LED is not set
+ # CONFIG_USB_CYPRESS_CY7C63 is not set
+ # CONFIG_USB_CYTHERM is not set
+-# CONFIG_USB_PHIDGET is not set
+ # CONFIG_USB_IDMOUSE is not set
+ # CONFIG_USB_FTDI_ELAN is not set
+ # CONFIG_USB_APPLEDISPLAY is not set
+@@ -891,56 +1141,95 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_TRANCEVIBRATOR is not set
+ # CONFIG_USB_IOWARRIOR is not set
+ # CONFIG_USB_TEST is not set
+-
+-#
+-# USB DSL modem support
+-#
+-
+-#
+-# USB Gadget Support
+-#
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
+ CONFIG_USB_GADGET=y
+-# CONFIG_USB_GADGET_DEBUG is not set
+ # CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
+ CONFIG_USB_GADGET_SELECTED=y
+-# CONFIG_USB_GADGET_AMD5536UDC is not set
++CONFIG_USB_GADGET_AT91=y
++CONFIG_USB_AT91=y
+ # CONFIG_USB_GADGET_ATMEL_USBA is not set
+ # CONFIG_USB_GADGET_FSL_USB2 is not set
+-# CONFIG_USB_GADGET_NET2280 is not set
+-# CONFIG_USB_GADGET_PXA2XX is not set
+-# CONFIG_USB_GADGET_M66592 is not set
+-# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_LH7A40X is not set
+ # CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
+ # CONFIG_USB_GADGET_S3C2410 is not set
+-CONFIG_USB_GADGET_AT91=y
+-CONFIG_USB_AT91=y
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_DUMMY_HCD is not set
+ # CONFIG_USB_GADGET_DUALSPEED is not set
+-CONFIG_USB_ZERO=m
+-# CONFIG_USB_ETH is not set
+-CONFIG_USB_GADGETFS=m
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
+ CONFIG_USB_FILE_STORAGE=m
+ # CONFIG_USB_FILE_STORAGE_TEST is not set
+ CONFIG_USB_G_SERIAL=m
+ # CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ # CONFIG_MMC_UNSAFE_RESUME is not set
+ 
+ #
+-# MMC/SD Card Drivers
++# MMC/SD/SDIO Card Drivers
+ #
+ CONFIG_MMC_BLOCK=y
+ CONFIG_MMC_BLOCK_BOUNCE=y
+-# CONFIG_SDIO_UART is not set
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
+ 
+ #
+-# MMC/SD Host Controller Drivers
++# MMC/SD/SDIO Host Controller Drivers
+ #
+-CONFIG_MMC_AT91=m
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AT91=y
++# CONFIG_MMC_ATMELMCI is not set
+ # CONFIG_MMC_SPI is not set
+-# CONFIG_NEW_LEDS is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_LEDS_ATMEL_PWM=y
++# CONFIG_LEDS_PCA9532 is not set
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_LP5521 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_BD2802 is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
+ CONFIG_RTC_LIB=y
+ CONFIG_RTC_CLASS=y
+ CONFIG_RTC_HCTOSYS=y
+@@ -969,28 +1258,47 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_PCF8563 is not set
+ # CONFIG_RTC_DRV_PCF8583 is not set
+ # CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
+ 
+ #
+ # SPI RTC drivers
+ #
+-# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
+ # CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
+ 
+ #
+ # Platform RTC drivers
+ #
+ # CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
+ # CONFIG_RTC_DRV_DS1553 is not set
+-# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
+ # CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
+ # CONFIG_RTC_DRV_V3020 is not set
+ 
+ #
+ # on-CPU RTC drivers
+ #
+ CONFIG_RTC_DRV_AT91SAM9=y
++CONFIG_RTC_DRV_AT91SAM9_RTT=0
++CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
+ 
+ #
+ # File systems
+@@ -999,24 +1307,28 @@ CONFIG_EXT2_FS=y
+ # CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_EXT2_FS_XIP is not set
+ # CONFIG_EXT3_FS is not set
+-# CONFIG_EXT4DEV_FS is not set
++# CONFIG_EXT4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
+ # CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+ 
+ #
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
+ # CD-ROM/DVD Filesystems
+ #
+ # CONFIG_ISO9660_FS is not set
+@@ -1026,7 +1338,7 @@ CONFIG_DNOTIFY=y
+ # DOS/FAT/NT Filesystems
+ #
+ CONFIG_FAT_FS=y
+-# CONFIG_MSDOS_FS is not set
++CONFIG_MSDOS_FS=y
+ CONFIG_VFAT_FS=y
+ CONFIG_FAT_DEFAULT_CODEPAGE=437
+ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+@@ -1037,15 +1349,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ #
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
+ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_TMPFS_POSIX_ACL is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ # CONFIG_CONFIGFS_FS is not set
+-
+-#
+-# Miscellaneous filesystems
+-#
++CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+@@ -1057,30 +1367,37 @@ CONFIG_JFFS2_FS=y
+ CONFIG_JFFS2_FS_DEBUG=0
+ CONFIG_JFFS2_FS_WRITEBUFFER=y
+ # CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+-# CONFIG_JFFS2_SUMMARY is not set
++CONFIG_JFFS2_SUMMARY=y
+ # CONFIG_JFFS2_FS_XATTR is not set
+ # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+ CONFIG_JFFS2_ZLIB=y
+ # CONFIG_JFFS2_LZO is not set
+ CONFIG_JFFS2_RTIME=y
+ # CONFIG_JFFS2_RUBIN is not set
+-CONFIG_CRAMFS=y
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
+ CONFIG_NFS_FS=y
+-# CONFIG_NFS_V3 is not set
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
+ # CONFIG_NFS_V4 is not set
+-# CONFIG_NFS_DIRECTIO is not set
+-# CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
+ CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
+ CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+-# CONFIG_SUNRPC_BIND34 is not set
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+ # CONFIG_SMB_FS is not set
+@@ -1130,14 +1447,11 @@ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_ISO8859_9 is not set
+ # CONFIG_NLS_ISO8859_13 is not set
+ # CONFIG_NLS_ISO8859_14 is not set
+-# CONFIG_NLS_ISO8859_15 is not set
++CONFIG_NLS_ISO8859_15=y
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+-# CONFIG_NLS_UTF8 is not set
++CONFIG_NLS_UTF8=y
+ # CONFIG_DLM is not set
+-CONFIG_INSTRUMENTATION=y
+-# CONFIG_PROFILING is not set
+-# CONFIG_MARKERS is not set
+ 
+ #
+ # Kernel hacking
+@@ -1145,64 +1459,161 @@ CONFIG_INSTRUMENTATION=y
+ # CONFIG_PRINTK_TIME is not set
+ CONFIG_ENABLE_WARN_DEPRECATED=y
+ CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ # CONFIG_DEBUG_FS is not set
+ # CONFIG_HEADERS_CHECK is not set
+-CONFIG_DEBUG_KERNEL=y
+-# CONFIG_DEBUG_SHIRQ is not set
+-CONFIG_DETECT_SOFTLOCKUP=y
+-CONFIG_SCHED_DEBUG=y
+-# CONFIG_SCHEDSTATS is not set
+-# CONFIG_TIMER_STATS is not set
+-# CONFIG_DEBUG_SLAB is not set
+-# CONFIG_DEBUG_RT_MUTEXES is not set
+-# CONFIG_RT_MUTEX_TESTER is not set
+-# CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_MUTEXES is not set
+-# CONFIG_DEBUG_LOCK_ALLOC is not set
+-# CONFIG_PROVE_LOCKING is not set
+-# CONFIG_LOCK_STAT is not set
+-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+-# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_KERNEL is not set
+ CONFIG_DEBUG_BUGVERBOSE=y
+-# CONFIG_DEBUG_INFO is not set
+-# CONFIG_DEBUG_VM is not set
+-# CONFIG_DEBUG_LIST is not set
+-# CONFIG_DEBUG_SG is not set
+-CONFIG_FRAME_POINTER=y
+-CONFIG_FORCED_INLINING=y
+-# CONFIG_BOOT_PRINTK_DELAY is not set
+-# CONFIG_RCU_TORTURE_TEST is not set
+-# CONFIG_FAULT_INJECTION is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
+ # CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
+ CONFIG_DEBUG_USER=y
+-# CONFIG_DEBUG_ERRORS is not set
+-CONFIG_DEBUG_LL=y
+-# CONFIG_DEBUG_ICEDCC is not set
+ 
+ #
+ # Security options
+ #
+ # CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
+ # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
+ 
+ #
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
+ # CONFIG_CRC_CCITT is not set
+ # CONFIG_CRC16 is not set
+-# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
+ CONFIG_CRC32=y
+ # CONFIG_CRC7 is not set
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=y
+-CONFIG_PLIST=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
+ CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+-- 
+1.5.6.5
+
+From 82101045ff7a52ccec63eb5de43f8ea7755cb023 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:32:00 +0000
+Subject: [PATCH] at91: add at91sam9g45ekes defconfig file
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11632 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/configs/at91sam9g45ekes_defconfig | 1617 ++++++++++++++++++++++++++++
+ 1 files changed, 1617 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/configs/at91sam9g45ekes_defconfig
+
+diff --git a/arch/arm/configs/at91sam9g45ekes_defconfig b/arch/arm/configs/at91sam9g45ekes_defconfig
+new file mode 100644
+index 0000000..ff35e15
+--- /dev/null
++++ b/arch/arm/configs/at91sam9g45ekes_defconfig
+@@ -0,0 +1,1617 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.30
++# Mon Oct 12 17:39:21 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_FREEZER is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++CONFIG_ARCH_AT91=y
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
++
++#
++# Atmel AT91 System-on-Chip
++#
++# CONFIG_ARCH_AT91RM9200 is not set
++# CONFIG_ARCH_AT91SAM9260 is not set
++# CONFIG_ARCH_AT91SAM9261 is not set
++# CONFIG_ARCH_AT91SAM9G10 is not set
++# CONFIG_ARCH_AT91SAM9263 is not set
++# CONFIG_ARCH_AT91SAM9RL is not set
++# CONFIG_ARCH_AT91SAM9G20 is not set
++CONFIG_ARCH_AT91SAM9G45=y
++# CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
++# CONFIG_ARCH_AT91X40 is not set
++CONFIG_AT91_PMC_UNIT=y
++
++#
++# AT91SAM9G45 Board Type
++#
++CONFIG_MACH_AT91SAM9G45EKES=y
++
++#
++# AT91 Board Options
++#
++# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
++
++#
++# AT91 Feature Selections
++#
++CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
++CONFIG_AT91_TIMER_HZ=100
++CONFIG_AT91_EARLY_DBGU=y
++# CONFIG_AT91_EARLY_USART0 is not set
++# CONFIG_AT91_EARLY_USART1 is not set
++# CONFIG_AT91_EARLY_USART2 is not set
++# CONFIG_AT91_EARLY_USART3 is not set
++# CONFIG_AT91_EARLY_USART4 is not set
++# CONFIG_AT91_EARLY_USART5 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_LEDS=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x71100000,25165824 root=/dev/ram0 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++CONFIG_MTD_NAND_ATMEL=y
++CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
++# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
++# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_ATMEL_PWM is not set
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++CONFIG_COMPAT_NET_DEV_OPS=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++CONFIG_DAVICOM_PHY=y
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_MACB=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_USB=m
++CONFIG_LIBERTAS_SDIO=m
++CONFIG_LIBERTAS_SPI=m
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++CONFIG_USB_ZD1201=m
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++CONFIG_RTL8187=m
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_AR9170_USB=m
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++CONFIG_RT2X00=m
++CONFIG_RT2500USB=m
++CONFIG_RT73USB=m
++CONFIG_RT2X00_LIB_USB=m
++CONFIG_RT2X00_LIB=m
++CONFIG_RT2X00_LIB_FIRMWARE=y
++CONFIG_RT2X00_LIB_CRYPTO=y
++CONFIG_RT2X00_LIB_RFKILL=y
++CONFIG_RT2X00_LIB_LEDS=y
++# CONFIG_RT2X00_DEBUG is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++CONFIG_INPUT_POLLDEV=m
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=272
++CONFIG_INPUT_JOYDEV=y
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
++# CONFIG_TOUCHSCREEN_WM97XX is not set
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_ATMEL=y
++CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
++# CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=16
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_ALGOBIT=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_GPIO=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_ATMEL=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_UCB1400_CORE is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D15605 is not set
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_ATMEL=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_ATMEL_LCDC=y
++# CONFIG_BACKLIGHT_GENERIC is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE is not set
++# CONFIG_LOGO is not set
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_SEQUENCER_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_VMASTER=y
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++
++#
++# Atmel devices (AVR32 and AT91)
++#
++CONFIG_SND_ATMEL_AC97C=y
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++# CONFIG_USB_HID is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++CONFIG_USB_GADGET_ATMEL_USBA=y
++CONFIG_USB_ATMEL_USBA=y
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FILE_STORAGE is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_AT91 is not set
++CONFIG_MMC_ATMELMCI=y
++CONFIG_MMC_ATMELMCI_DMA=y
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++# CONFIG_LEDS_PCA9532 is not set
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_LP5521 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_BD2802 is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AT91SAM9=y
++CONFIG_RTC_DRV_AT91SAM9_RTT=0
++CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++CONFIG_DMADEVICES=y
++
++#
++# DMA Devices
++#
++CONFIG_AT_HDMAC=y
++CONFIG_DMA_ENGINE=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++CONFIG_DMATEST=m
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+-- 
+1.5.6.5
+
+From d059b77515d96520ea59b0bdfabfcdb807d09d1d Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:32:01 +0000
+Subject: [PATCH] at91: update at91sam9g20ek defconfig file
+
+Update at91sam9g20ek and add the 2 SD/MMC slots board defconfig
+named at91sam9g20ek_2mmc.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11633 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/configs/at91sam9g20ek_2mmc_defconfig | 1561 +++++++++++++++++++++++++
+ arch/arm/configs/at91sam9g20ek_defconfig      |  740 +++++++++---
+ 2 files changed, 2128 insertions(+), 173 deletions(-)
+ create mode 100644 arch/arm/configs/at91sam9g20ek_2mmc_defconfig
+
+diff --git a/arch/arm/configs/at91sam9g20ek_2mmc_defconfig b/arch/arm/configs/at91sam9g20ek_2mmc_defconfig
+new file mode 100644
+index 0000000..9873099
+--- /dev/null
++++ b/arch/arm/configs/at91sam9g20ek_2mmc_defconfig
+@@ -0,0 +1,1561 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.30
++# Mon Oct 12 18:24:05 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++CONFIG_ARCH_AT91=y
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
++
++#
++# Atmel AT91 System-on-Chip
++#
++# CONFIG_ARCH_AT91RM9200 is not set
++# CONFIG_ARCH_AT91SAM9260 is not set
++# CONFIG_ARCH_AT91SAM9261 is not set
++# CONFIG_ARCH_AT91SAM9G10 is not set
++# CONFIG_ARCH_AT91SAM9263 is not set
++# CONFIG_ARCH_AT91SAM9RL is not set
++CONFIG_ARCH_AT91SAM9G20=y
++# CONFIG_ARCH_AT91SAM9G45 is not set
++# CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
++# CONFIG_ARCH_AT91X40 is not set
++CONFIG_AT91_PMC_UNIT=y
++
++#
++# AT91SAM9G20 Board Type
++#
++# CONFIG_MACH_AT91SAM9G20EK is not set
++CONFIG_MACH_AT91SAM9G20EK_2MMC=y
++# CONFIG_MACH_USB_A9G20 is not set
++# CONFIG_MACH_QIL_A9G20 is not set
++# CONFIG_MACH_SBC35_A9G20 is not set
++
++#
++# AT91 Board Options
++#
++# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
++
++#
++# AT91 Feature Selections
++#
++CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
++# CONFIG_AT91_SLOW_CLOCK is not set
++CONFIG_AT91_TIMER_HZ=100
++CONFIG_AT91_EARLY_DBGU=y
++# CONFIG_AT91_EARLY_USART0 is not set
++# CONFIG_AT91_EARLY_USART1 is not set
++# CONFIG_AT91_EARLY_USART2 is not set
++# CONFIG_AT91_EARLY_USART3 is not set
++# CONFIG_AT91_EARLY_USART4 is not set
++# CONFIG_AT91_EARLY_USART5 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_LEDS=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++CONFIG_MTD_NAND_ATMEL=y
++CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
++# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
++# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=8
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
++# CONFIG_ICS932S401 is not set
++CONFIG_ATMEL_SSC=y
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++CONFIG_COMPAT_NET_DEV_OPS=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++CONFIG_DAVICOM_PHY=y
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_MACB=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_USB=m
++CONFIG_LIBERTAS_SDIO=m
++CONFIG_LIBERTAS_SPI=m
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++CONFIG_USB_ZD1201=m
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++CONFIG_RTL8187=m
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_AR9170_USB=m
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++CONFIG_RT2X00=m
++CONFIG_RT2500USB=m
++CONFIG_RT73USB=m
++CONFIG_RT2X00_LIB_USB=m
++CONFIG_RT2X00_LIB=m
++CONFIG_RT2X00_LIB_FIRMWARE=y
++CONFIG_RT2X00_LIB_CRYPTO=y
++CONFIG_RT2X00_LIB_RFKILL=y
++CONFIG_RT2X00_LIB_LEDS=y
++# CONFIG_RT2X00_DEBUG is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++CONFIG_INPUT_POLLDEV=m
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_ATMEL=y
++CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
++# CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=16
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_ALGOBIT=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_GPIO=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_ATMEL=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_JACK=y
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++CONFIG_SND_SEQUENCER_OSS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++
++#
++# Atmel devices (AVR32 and AT91)
++#
++# CONFIG_SND_ATMEL_AC97C is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++# CONFIG_SND_USB_CAIAQ is not set
++CONFIG_SND_SOC=y
++CONFIG_SND_ATMEL_SOC=y
++CONFIG_SND_ATMEL_SOC_SSC=y
++CONFIG_SND_AT91_SOC_SAM9G20_WM8731=y
++CONFIG_SND_SOC_I2C_AND_SPI=y
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_WM8731=y
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++# CONFIG_USB_HID is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++CONFIG_USB_GADGET_AT91=y
++CONFIG_USB_AT91=y
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AT91=y
++# CONFIG_MMC_ATMELMCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++# CONFIG_LEDS_PCA9532 is not set
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_LP5521 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_BD2802 is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_RTC_DRV_AT91SAM9=y
++CONFIG_RTC_DRV_AT91SAM9_RTT=0
++CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig
+index 7e018a0..786aa7e 100644
+--- a/arch/arm/configs/at91sam9g20ek_defconfig
++++ b/arch/arm/configs/at91sam9g20ek_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24
+-# Tue Jun 10 15:51:52 2008
++# Linux kernel version: 2.6.30
++# Mon Oct 12 18:24:05 2009
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+@@ -12,6 +12,7 @@ CONFIG_MMU=y
+ # CONFIG_NO_IOPORT is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ CONFIG_HARDIRQS_SW_RESEND=y
+@@ -21,7 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+ CONFIG_VECTORS_BASE=0xffff0000
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+@@ -39,54 +40,82 @@ CONFIG_SYSVIPC_SYSCTL=y
+ # CONFIG_POSIX_MQUEUE is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
+ # CONFIG_CGROUPS is not set
+-# CONFIG_FAIR_GROUP_SCHED is not set
+ CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
+ # CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
+ # CONFIG_EMBEDDED is not set
+ CONFIG_UID16=y
+ CONFIG_SYSCTL_SYSCALL=y
+ CONFIG_KALLSYMS=y
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
+ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+-CONFIG_ANON_INODES=y
+ CONFIG_EPOLL=y
+ CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
+ CONFIG_EVENTFD=y
+ CONFIG_SHMEM=y
++CONFIG_AIO=y
+ CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+ CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+ CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+ # CONFIG_MODVERSIONS is not set
+ # CONFIG_MODULE_SRCVERSION_ALL is not set
+-CONFIG_KMOD=y
+ CONFIG_BLOCK=y
+ # CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+ # CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
+ 
+ #
+ # IO Schedulers
+@@ -100,6 +129,7 @@ CONFIG_DEFAULT_AS=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
+ 
+ #
+ # System Type
+@@ -109,11 +139,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ # CONFIG_ARCH_REALVIEW is not set
+ # CONFIG_ARCH_VERSATILE is not set
+ CONFIG_ARCH_AT91=y
+-# CONFIG_ARCH_CLPS7500 is not set
+ # CONFIG_ARCH_CLPS711X is not set
+-# CONFIG_ARCH_CO285 is not set
+ # CONFIG_ARCH_EBSA110 is not set
+ # CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
+ # CONFIG_ARCH_FOOTBRIDGE is not set
+ # CONFIG_ARCH_NETX is not set
+ # CONFIG_ARCH_H720X is not set
+@@ -125,26 +154,26 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_IXP2000 is not set
+ # CONFIG_ARCH_IXP4XX is not set
+ # CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
+ # CONFIG_ARCH_KS8695 is not set
+ # CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
+ # CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
+ # CONFIG_ARCH_PNX4008 is not set
+ # CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
+ # CONFIG_ARCH_RPC is not set
+ # CONFIG_ARCH_SA1100 is not set
+ # CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
+ # CONFIG_ARCH_SHARK is not set
+ # CONFIG_ARCH_LH7A40X is not set
+ # CONFIG_ARCH_DAVINCI is not set
+ # CONFIG_ARCH_OMAP is not set
+-
+-#
+-# Boot options
+-#
+-
+-#
+-# Power management
+-#
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
+ 
+ #
+ # Atmel AT91 System-on-Chip
+@@ -152,10 +181,13 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_AT91RM9200 is not set
+ # CONFIG_ARCH_AT91SAM9260 is not set
+ # CONFIG_ARCH_AT91SAM9261 is not set
++# CONFIG_ARCH_AT91SAM9G10 is not set
+ # CONFIG_ARCH_AT91SAM9263 is not set
+ # CONFIG_ARCH_AT91SAM9RL is not set
+ CONFIG_ARCH_AT91SAM9G20=y
++# CONFIG_ARCH_AT91SAM9G45 is not set
+ # CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
+ # CONFIG_ARCH_AT91X40 is not set
+ CONFIG_AT91_PMC_UNIT=y
+ 
+@@ -163,6 +195,10 @@ CONFIG_AT91_PMC_UNIT=y
+ # AT91SAM9G20 Board Type
+ #
+ CONFIG_MACH_AT91SAM9G20EK=y
++# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set
++# CONFIG_MACH_USB_A9G20 is not set
++# CONFIG_MACH_QIL_A9G20 is not set
++# CONFIG_MACH_SBC35_A9G20 is not set
+ 
+ #
+ # AT91 Board Options
+@@ -191,6 +227,7 @@ CONFIG_CPU_32=y
+ CONFIG_CPU_ARM926T=y
+ CONFIG_CPU_32v5=y
+ CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
+ CONFIG_CPU_CACHE_VIVT=y
+ CONFIG_CPU_COPY_V4WB=y
+ CONFIG_CPU_TLB_V4WBI=y
+@@ -200,7 +237,7 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Processor Features
+ #
+-# CONFIG_ARM_THUMB is not set
++CONFIG_ARM_THUMB=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+@@ -217,28 +254,35 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Kernel Features
+ #
+-# CONFIG_TICK_ONESHOT is not set
+ # CONFIG_NO_HZ is not set
+ # CONFIG_HIGH_RES_TIMERS is not set
+ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
+ # CONFIG_PREEMPT is not set
+ CONFIG_HZ=100
+ CONFIG_AEABI=y
+ CONFIG_OABI_COMPAT=y
+-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
+ CONFIG_SELECT_MEMORY_MODEL=y
+ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
+-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4096
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-CONFIG_BOUNCE=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+ CONFIG_LEDS=y
+ CONFIG_LEDS_CPU=y
+ CONFIG_ALIGNMENT_TRAP=y
+@@ -253,6 +297,11 @@ CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev
+ # CONFIG_KEXEC is not set
+ 
+ #
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
+ # Floating point emulation
+ #
+ 
+@@ -268,6 +317,8 @@ CONFIG_FPE_NWFPE=y
+ # Userspace binary formats
+ #
+ CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
+ # CONFIG_BINFMT_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+ 
+@@ -275,16 +326,12 @@ CONFIG_BINFMT_ELF=y
+ # Power management options
+ #
+ CONFIG_PM=y
+-# CONFIG_PM_LEGACY is not set
+ # CONFIG_PM_DEBUG is not set
+ CONFIG_PM_SLEEP=y
+-CONFIG_SUSPEND_UP_POSSIBLE=y
+ CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
+ # CONFIG_APM_EMULATION is not set
+-
+-#
+-# Networking
+-#
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ CONFIG_NET=y
+ 
+ #
+@@ -295,15 +342,16 @@ CONFIG_PACKET=y
+ CONFIG_UNIX=y
+ # CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
++CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_FIB_HASH=y
+ CONFIG_IP_PNP=y
+ # CONFIG_IP_PNP_DHCP is not set
+ CONFIG_IP_PNP_BOOTP=y
+-# CONFIG_IP_PNP_RARP is not set
++CONFIG_IP_PNP_RARP=y
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+@@ -315,15 +363,12 @@ CONFIG_IP_PNP_BOOTP=y
+ # CONFIG_INET_XFRM_MODE_TUNNEL is not set
+ # CONFIG_INET_XFRM_MODE_BEET is not set
+ # CONFIG_INET_LRO is not set
+-CONFIG_INET_DIAG=y
+-CONFIG_INET_TCP_DIAG=y
++# CONFIG_INET_DIAG is not set
+ # CONFIG_TCP_CONG_ADVANCED is not set
+ CONFIG_TCP_CONG_CUBIC=y
+ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TCP_MD5SIG is not set
+ # CONFIG_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+ # CONFIG_NETWORK_SECMARK is not set
+ # CONFIG_NETFILTER is not set
+ # CONFIG_IP_DCCP is not set
+@@ -331,6 +376,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_LLC2 is not set
+@@ -340,24 +386,40 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_LAPB is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
+ # CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
+ 
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+ # CONFIG_AF_RXRPC is not set
+-
+-#
+-# Wireless
+-#
+-# CONFIG_CFG80211 is not set
+-# CONFIG_WIRELESS_EXT is not set
+-# CONFIG_MAC80211 is not set
+-# CONFIG_IEEE80211 is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
+ # CONFIG_RFKILL is not set
+ # CONFIG_NET_9P is not set
+ 
+@@ -371,16 +433,20 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_SYS_HYPERVISOR is not set
+ # CONFIG_CONNECTOR is not set
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-CONFIG_MTD_CONCAT=y
++# CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ CONFIG_MTD_CMDLINE_PARTS=y
+ # CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
+ 
+ #
+ # User Modules And Translation Layers
+@@ -424,6 +490,8 @@ CONFIG_MTD_CFI_I2=y
+ # Self-contained MTD device drivers
+ #
+ CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
+ # CONFIG_MTD_M25P80 is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+@@ -440,6 +508,7 @@ CONFIG_MTD_NAND=y
+ # CONFIG_MTD_NAND_VERIFY_WRITE is not set
+ # CONFIG_MTD_NAND_ECC_SMC is not set
+ # CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
+ CONFIG_MTD_NAND_IDS=y
+ # CONFIG_MTD_NAND_DISKONCHIP is not set
+ CONFIG_MTD_NAND_ATMEL=y
+@@ -452,6 +521,11 @@ CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+ # CONFIG_MTD_ONENAND is not set
+ 
+ #
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
+ # UBI - Unsorted block images
+ #
+ # CONFIG_MTD_UBI is not set
+@@ -463,15 +537,30 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_UB is not set
+ CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_COUNT=8
+ CONFIG_BLK_DEV_RAM_SIZE=8192
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_BLK_DEV_XIP is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+ CONFIG_MISC_DEVICES=y
+-CONFIG_ATMEL_PWM=y
+-# CONFIG_EEPROM_93CX6 is not set
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
++# CONFIG_ICS932S401 is not set
+ CONFIG_ATMEL_SSC=y
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
+ 
+ #
+ # SCSI device support
+@@ -511,10 +600,12 @@ CONFIG_SCSI_WAIT_SCAN=m
+ # CONFIG_SCSI_SAS_LIBSAS is not set
+ # CONFIG_SCSI_SRP_ATTRS is not set
+ # CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
+ CONFIG_NETDEVICES=y
+-# CONFIG_NETDEVICES_MULTIQUEUE is not set
++CONFIG_COMPAT_NET_DEV_OPS=y
+ # CONFIG_DUMMY is not set
+ # CONFIG_BONDING is not set
+ # CONFIG_MACVLAN is not set
+@@ -527,7 +618,7 @@ CONFIG_PHYLIB=y
+ # MII PHY device drivers
+ #
+ # CONFIG_MARVELL_PHY is not set
+-# CONFIG_DAVICOM_PHY is not set
++CONFIG_DAVICOM_PHY=y
+ # CONFIG_QSEMI_PHY is not set
+ # CONFIG_LXT_PHY is not set
+ # CONFIG_CICADA_PHY is not set
+@@ -535,6 +626,10 @@ CONFIG_PHYLIB=y
+ # CONFIG_SMSC_PHY is not set
+ # CONFIG_BROADCOM_PHY is not set
+ # CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
+ # CONFIG_FIXED_PHY is not set
+ # CONFIG_MDIO_BITBANG is not set
+ CONFIG_NET_ETHERNET=y
+@@ -543,10 +638,18 @@ CONFIG_MACB=y
+ # CONFIG_AX88796 is not set
+ # CONFIG_SMC91X is not set
+ # CONFIG_DM9000 is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
+ # CONFIG_IBM_NEW_EMAC_ZMII is not set
+ # CONFIG_IBM_NEW_EMAC_RGMII is not set
+ # CONFIG_IBM_NEW_EMAC_TAH is not set
+ # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+ # CONFIG_B44 is not set
+ # CONFIG_NETDEV_1000 is not set
+ # CONFIG_NETDEV_10000 is not set
+@@ -555,7 +658,39 @@ CONFIG_MACB=y
+ # Wireless LAN
+ #
+ # CONFIG_WLAN_PRE80211 is not set
+-# CONFIG_WLAN_80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_USB=m
++CONFIG_LIBERTAS_SDIO=m
++CONFIG_LIBERTAS_SPI=m
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++CONFIG_USB_ZD1201=m
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++CONFIG_RTL8187=m
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_AR9170_USB=m
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++CONFIG_RT2X00=m
++CONFIG_RT2500USB=m
++CONFIG_RT73USB=m
++CONFIG_RT2X00_LIB_USB=m
++CONFIG_RT2X00_LIB=m
++CONFIG_RT2X00_LIB_FIRMWARE=y
++CONFIG_RT2X00_LIB_CRYPTO=y
++CONFIG_RT2X00_LIB_RFKILL=y
++CONFIG_RT2X00_LIB_LEDS=y
++# CONFIG_RT2X00_DEBUG is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
+ 
+ #
+ # USB Network Adapters
+@@ -568,7 +703,6 @@ CONFIG_MACB=y
+ # CONFIG_WAN is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+-# CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+@@ -579,15 +713,15 @@ CONFIG_MACB=y
+ #
+ CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
+-# CONFIG_INPUT_POLLDEV is not set
++CONFIG_INPUT_POLLDEV=m
+ 
+ #
+ # Userland interfaces
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+ # CONFIG_INPUT_JOYDEV is not set
+ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+@@ -612,18 +746,18 @@ CONFIG_KEYBOARD_GPIO=y
+ #
+ # Hardware I/O ports
+ #
+-CONFIG_SERIO=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO is not set
+ # CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+ #
+ CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
+ CONFIG_HW_CONSOLE=y
+ # CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -636,23 +770,64 @@ CONFIG_HW_CONSOLE=y
+ #
+ CONFIG_SERIAL_ATMEL=y
+ CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
+ # CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=16
+ # CONFIG_IPMI_HANDLER is not set
+ CONFIG_HW_RANDOM=y
+-# CONFIG_NVRAM is not set
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
+-# CONFIG_I2C is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_ALGOBIT=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++CONFIG_I2C_GPIO=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
+ 
+ #
+-# SPI support
++# Miscellaneous I2C Chip support
+ #
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
+ CONFIG_SPI=y
+ CONFIG_SPI_MASTER=y
+ 
+@@ -661,34 +836,83 @@ CONFIG_SPI_MASTER=y
+ #
+ CONFIG_SPI_ATMEL=y
+ # CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
+ 
+ #
+ # SPI Protocol Masters
+ #
+-# CONFIG_EEPROM_AT25 is not set
+ CONFIG_SPI_SPIDEV=y
+ # CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
+ # CONFIG_W1 is not set
+ # CONFIG_POWER_SUPPLY is not set
+ # CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
+ # CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
+ 
+ #
+ # Sonics Silicon Backplane
+ #
+-CONFIG_SSB_POSSIBLE=y
+ # CONFIG_SSB is not set
+ 
+ #
+ # Multifunction device drivers
+ #
++# CONFIG_MFD_CORE is not set
+ # CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
+ 
+ #
+ # Multimedia devices
+ #
++
++#
++# Multimedia core support
++#
+ # CONFIG_VIDEO_DEV is not set
+ # CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
+ # CONFIG_DAB is not set
+ 
+ #
+@@ -709,18 +933,14 @@ CONFIG_SSB_POSSIBLE=y
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-
+-#
+-# Sound
+-#
+ CONFIG_SOUND=y
+-
+-#
+-# Advanced Linux Sound Architecture
+-#
++CONFIG_SOUND_OSS_CORE=y
+ CONFIG_SND=y
+ CONFIG_SND_TIMER=y
+ CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_JACK=y
+ CONFIG_SND_SEQUENCER=y
+ # CONFIG_SND_SEQ_DUMMY is not set
+ CONFIG_SND_OSSEMUL=y
+@@ -729,49 +949,28 @@ CONFIG_SND_PCM_OSS=y
+ CONFIG_SND_PCM_OSS_PLUGINS=y
+ CONFIG_SND_SEQUENCER_OSS=y
+ # CONFIG_SND_DYNAMIC_MINORS is not set
+-CONFIG_SND_SUPPORT_OLD_API=y
++# CONFIG_SND_SUPPORT_OLD_API is not set
+ # CONFIG_SND_VERBOSE_PROCFS is not set
+ # CONFIG_SND_VERBOSE_PRINTK is not set
+ # CONFIG_SND_DEBUG is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
+ 
+ #
+-# Generic devices
++# Atmel devices (AVR32 and AT91)
+ #
+-# CONFIG_SND_DUMMY is not set
+-# CONFIG_SND_VIRMIDI is not set
+-# CONFIG_SND_MTPAV is not set
+-# CONFIG_SND_SERIAL_U16550 is not set
+-# CONFIG_SND_MPU401 is not set
+-
+-#
+-# ALSA ARM devices
+-#
+-# CONFIG_SND_AT91_AC97 is not set
+-
+-#
+-# SPI devices
+-#
+-CONFIG_SND_AT73C213=y
+-CONFIG_SND_AT73C213_TARGET_BITRATE=48000
+-
+-#
+-# USB devices
+-#
+-# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_ATMEL_AC97C is not set
++# CONFIG_SND_SPI is not set
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
+ # CONFIG_SND_USB_CAIAQ is not set
+-
+-#
+-# System on Chip audio support
+-#
+-# CONFIG_SND_SOC is not set
+-
+-#
+-# SoC Audio support for SuperH
+-#
+-
+-#
+-# Open Sound System
+-#
++CONFIG_SND_SOC=y
++CONFIG_SND_ATMEL_SOC=y
++CONFIG_SND_ATMEL_SOC_SSC=y
++CONFIG_SND_AT91_SOC_SAM9G20_WM8731=y
++CONFIG_SND_SOC_I2C_AND_SPI=y
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_WM8731=y
+ # CONFIG_SOUND_PRIME is not set
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+@@ -781,16 +980,19 @@ CONFIG_HID=y
+ #
+ # USB Input Devices
+ #
+-CONFIG_USB_HID=y
+-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+-# CONFIG_HID_FF is not set
+-# CONFIG_USB_HIDDEV is not set
++# CONFIG_USB_HID is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
+ CONFIG_USB_SUPPORT=y
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_USB_ARCH_HAS_EHCI is not set
+ CONFIG_USB=y
+ # CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+ 
+ #
+ # Miscellaneous USB options
+@@ -799,45 +1001,56 @@ CONFIG_USB_DEVICEFS=y
+ # CONFIG_USB_DEVICE_CLASS is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
+ # CONFIG_USB_SUSPEND is not set
+-# CONFIG_USB_PERSIST is not set
+ # CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
+ 
+ #
+ # USB Host Controller Drivers
+ #
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+ # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ # CONFIG_USB_SL811_HCD is not set
+ # CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+ #
+ 
+ #
+-# may also be needed; see USB_STORAGE Help for more information
++# also be needed; see USB_STORAGE Help for more info
+ #
+ CONFIG_USB_STORAGE=y
+ # CONFIG_USB_STORAGE_DEBUG is not set
+ # CONFIG_USB_STORAGE_DATAFAB is not set
+ # CONFIG_USB_STORAGE_FREECOM is not set
+ # CONFIG_USB_STORAGE_ISD200 is not set
+-# CONFIG_USB_STORAGE_DPCM is not set
+ # CONFIG_USB_STORAGE_USBAT is not set
+ # CONFIG_USB_STORAGE_SDDR09 is not set
+ # CONFIG_USB_STORAGE_SDDR55 is not set
+ # CONFIG_USB_STORAGE_JUMPSHOT is not set
+ # CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
+ # CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+ # CONFIG_USB_LIBUSUAL is not set
+ 
+ #
+@@ -845,15 +1058,10 @@ CONFIG_USB_STORAGE=y
+ #
+ # CONFIG_USB_MDC800 is not set
+ # CONFIG_USB_MICROTEK is not set
+-CONFIG_USB_MON=y
+ 
+ #
+ # USB port drivers
+ #
+-
+-#
+-# USB Serial Converter support
+-#
+ # CONFIG_USB_SERIAL is not set
+ 
+ #
+@@ -862,7 +1070,7 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_ADUTUX is not set
+-# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_SEVSEG is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+ # CONFIG_USB_LCD is not set
+@@ -870,7 +1078,6 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_LED is not set
+ # CONFIG_USB_CYPRESS_CY7C63 is not set
+ # CONFIG_USB_CYTHERM is not set
+-# CONFIG_USB_PHIDGET is not set
+ # CONFIG_USB_IDMOUSE is not set
+ # CONFIG_USB_FTDI_ELAN is not set
+ # CONFIG_USB_APPLEDISPLAY is not set
+@@ -878,62 +1085,80 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_TRANCEVIBRATOR is not set
+ # CONFIG_USB_IOWARRIOR is not set
+ # CONFIG_USB_TEST is not set
+-
+-#
+-# USB DSL modem support
+-#
+-
+-#
+-# USB Gadget Support
+-#
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
+ CONFIG_USB_GADGET=y
+ # CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
+ CONFIG_USB_GADGET_SELECTED=y
+-# CONFIG_USB_GADGET_AMD5536UDC is not set
++CONFIG_USB_GADGET_AT91=y
++CONFIG_USB_AT91=y
+ # CONFIG_USB_GADGET_ATMEL_USBA is not set
+ # CONFIG_USB_GADGET_FSL_USB2 is not set
+-# CONFIG_USB_GADGET_NET2280 is not set
+-# CONFIG_USB_GADGET_PXA2XX is not set
+-# CONFIG_USB_GADGET_M66592 is not set
+-# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_LH7A40X is not set
+ # CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
+ # CONFIG_USB_GADGET_S3C2410 is not set
+-CONFIG_USB_GADGET_AT91=y
+-CONFIG_USB_AT91=y
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_DUMMY_HCD is not set
+ # CONFIG_USB_GADGET_DUALSPEED is not set
+ CONFIG_USB_ZERO=m
+-# CONFIG_USB_ETH is not set
+-CONFIG_USB_GADGETFS=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
+ CONFIG_USB_FILE_STORAGE=m
+ # CONFIG_USB_FILE_STORAGE_TEST is not set
+ CONFIG_USB_G_SERIAL=m
+ # CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ # CONFIG_MMC_UNSAFE_RESUME is not set
+ 
+ #
+-# MMC/SD Card Drivers
++# MMC/SD/SDIO Card Drivers
+ #
+ CONFIG_MMC_BLOCK=y
+ CONFIG_MMC_BLOCK_BOUNCE=y
+-# CONFIG_SDIO_UART is not set
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
+ 
+ #
+-# MMC/SD Host Controller Drivers
++# MMC/SD/SDIO Host Controller Drivers
+ #
++# CONFIG_MMC_SDHCI is not set
+ CONFIG_MMC_AT91=y
++# CONFIG_MMC_ATMELMCI is not set
+ # CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
+ CONFIG_NEW_LEDS=y
+ CONFIG_LEDS_CLASS=y
+ 
+ #
+ # LED drivers
+ #
+-CONFIG_LEDS_ATMEL_PWM=y
++# CONFIG_LEDS_PCA9532 is not set
+ CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_LP5521 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_BD2802 is not set
+ 
+ #
+ # LED Triggers
+@@ -941,6 +1166,13 @@ CONFIG_LEDS_GPIO=y
+ CONFIG_LEDS_TRIGGERS=y
+ CONFIG_LEDS_TRIGGER_TIMER=y
+ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
+ CONFIG_RTC_LIB=y
+ CONFIG_RTC_CLASS=y
+ CONFIG_RTC_HCTOSYS=y
+@@ -957,20 +1189,46 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_TEST is not set
+ 
+ #
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
+ # SPI RTC drivers
+ #
+-# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
+ # CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
+ 
+ #
+ # Platform RTC drivers
+ #
+ # CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
+ # CONFIG_RTC_DRV_DS1553 is not set
+-# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
+ # CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
+ # CONFIG_RTC_DRV_V3020 is not set
+ 
+ #
+@@ -979,6 +1237,11 @@ CONFIG_RTC_INTF_DEV=y
+ CONFIG_RTC_DRV_AT91SAM9=y
+ CONFIG_RTC_DRV_AT91SAM9_RTT=0
+ CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
+ 
+ #
+ # File systems
+@@ -987,24 +1250,28 @@ CONFIG_EXT2_FS=y
+ # CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_EXT2_FS_XIP is not set
+ # CONFIG_EXT3_FS is not set
+-# CONFIG_EXT4DEV_FS is not set
++# CONFIG_EXT4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
+ # CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+ 
+ #
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
+ # CD-ROM/DVD Filesystems
+ #
+ # CONFIG_ISO9660_FS is not set
+@@ -1014,7 +1281,7 @@ CONFIG_DNOTIFY=y
+ # DOS/FAT/NT Filesystems
+ #
+ CONFIG_FAT_FS=y
+-CONFIG_MSDOS_FS=y
++# CONFIG_MSDOS_FS is not set
+ CONFIG_VFAT_FS=y
+ CONFIG_FAT_DEFAULT_CODEPAGE=437
+ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+@@ -1025,15 +1292,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ #
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
+ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_TMPFS_POSIX_ACL is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ # CONFIG_CONFIGFS_FS is not set
+-
+-#
+-# Miscellaneous filesystems
+-#
++CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+@@ -1052,25 +1317,30 @@ CONFIG_JFFS2_ZLIB=y
+ # CONFIG_JFFS2_LZO is not set
+ CONFIG_JFFS2_RTIME=y
+ # CONFIG_JFFS2_RUBIN is not set
+-CONFIG_CRAMFS=y
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3=y
+ # CONFIG_NFS_V3_ACL is not set
+ # CONFIG_NFS_V4 is not set
+-# CONFIG_NFS_DIRECTIO is not set
+-# CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+-# CONFIG_SUNRPC_BIND34 is not set
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+ # CONFIG_SMB_FS is not set
+@@ -1120,12 +1390,11 @@ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_ISO8859_9 is not set
+ # CONFIG_NLS_ISO8859_13 is not set
+ # CONFIG_NLS_ISO8859_14 is not set
+-CONFIG_NLS_ISO8859_15=y
++# CONFIG_NLS_ISO8859_15 is not set
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+-CONFIG_NLS_UTF8=y
++# CONFIG_NLS_UTF8 is not set
+ # CONFIG_DLM is not set
+-# CONFIG_INSTRUMENTATION is not set
+ 
+ #
+ # Kernel hacking
+@@ -1133,14 +1402,37 @@ CONFIG_NLS_UTF8=y
+ # CONFIG_PRINTK_TIME is not set
+ # CONFIG_ENABLE_WARN_DEPRECATED is not set
+ CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ # CONFIG_DEBUG_FS is not set
+ # CONFIG_HEADERS_CHECK is not set
+ # CONFIG_DEBUG_KERNEL is not set
+ CONFIG_DEBUG_BUGVERBOSE=y
+-CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
+ # CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
+ # CONFIG_DEBUG_USER is not set
+ 
+ #
+@@ -1148,21 +1440,123 @@ CONFIG_FRAME_POINTER=y
+ #
+ # CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
+ # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
+ 
+ #
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
+ # CONFIG_CRC_CCITT is not set
+ # CONFIG_CRC16 is not set
+-# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
+ CONFIG_CRC32=y
+ # CONFIG_CRC7 is not set
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=y
+-CONFIG_PLIST=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+-- 
+1.5.6.5
+
+From 0a6dfc26fd7ca6b4f165176767e94667ee2d94b3 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:32:02 +0000
+Subject: [PATCH] at91: update at91sam9261ek defconfig file
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11634 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/configs/at91sam9261ek_defconfig |  871 +++++++++++++++++++++---------
+ 1 files changed, 611 insertions(+), 260 deletions(-)
+
+diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig
+index 1494561..7722aa7 100644
+--- a/arch/arm/configs/at91sam9261ek_defconfig
++++ b/arch/arm/configs/at91sam9261ek_defconfig
+@@ -1,17 +1,18 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc7
+-# Tue Jan  8 22:21:49 2008
++# Linux kernel version: 2.6.30
++# Tue Oct 13 12:05:37 2009
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+ CONFIG_GENERIC_GPIO=y
+-# CONFIG_GENERIC_TIME is not set
+-# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_MMU=y
+ # CONFIG_NO_IOPORT is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ CONFIG_HARDIRQS_SW_RESEND=y
+@@ -21,7 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+ CONFIG_VECTORS_BASE=0xffff0000
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+@@ -39,57 +40,82 @@ CONFIG_SYSVIPC_SYSCTL=y
+ # CONFIG_POSIX_MQUEUE is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
+ # CONFIG_CGROUPS is not set
+-CONFIG_FAIR_GROUP_SCHED=y
+-CONFIG_FAIR_USER_SCHED=y
+-# CONFIG_FAIR_CGROUP_SCHED is not set
+ CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
+ # CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
+ # CONFIG_EMBEDDED is not set
+ CONFIG_UID16=y
+ CONFIG_SYSCTL_SYSCALL=y
+ CONFIG_KALLSYMS=y
+-# CONFIG_KALLSYMS_ALL is not set
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
+ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+-CONFIG_ANON_INODES=y
+ CONFIG_EPOLL=y
+ CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
+ CONFIG_EVENTFD=y
+ CONFIG_SHMEM=y
++CONFIG_AIO=y
+ CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+ CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+ CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+ # CONFIG_MODVERSIONS is not set
+ # CONFIG_MODULE_SRCVERSION_ALL is not set
+-CONFIG_KMOD=y
+ CONFIG_BLOCK=y
+ # CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+ # CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
+ 
+ #
+ # IO Schedulers
+@@ -103,6 +129,7 @@ CONFIG_DEFAULT_AS=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
+ 
+ #
+ # System Type
+@@ -112,11 +139,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ # CONFIG_ARCH_REALVIEW is not set
+ # CONFIG_ARCH_VERSATILE is not set
+ CONFIG_ARCH_AT91=y
+-# CONFIG_ARCH_CLPS7500 is not set
+ # CONFIG_ARCH_CLPS711X is not set
+-# CONFIG_ARCH_CO285 is not set
+ # CONFIG_ARCH_EBSA110 is not set
+ # CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
+ # CONFIG_ARCH_FOOTBRIDGE is not set
+ # CONFIG_ARCH_NETX is not set
+ # CONFIG_ARCH_H720X is not set
+@@ -128,26 +154,26 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_IXP2000 is not set
+ # CONFIG_ARCH_IXP4XX is not set
+ # CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
+ # CONFIG_ARCH_KS8695 is not set
+ # CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
+ # CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
+ # CONFIG_ARCH_PNX4008 is not set
+ # CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
+ # CONFIG_ARCH_RPC is not set
+ # CONFIG_ARCH_SA1100 is not set
+ # CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
+ # CONFIG_ARCH_SHARK is not set
+ # CONFIG_ARCH_LH7A40X is not set
+ # CONFIG_ARCH_DAVINCI is not set
+ # CONFIG_ARCH_OMAP is not set
+-
+-#
+-# Boot options
+-#
+-
+-#
+-# Power management
+-#
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
+ 
+ #
+ # Atmel AT91 System-on-Chip
+@@ -155,8 +181,13 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_AT91RM9200 is not set
+ # CONFIG_ARCH_AT91SAM9260 is not set
+ CONFIG_ARCH_AT91SAM9261=y
++# CONFIG_ARCH_AT91SAM9G10 is not set
+ # CONFIG_ARCH_AT91SAM9263 is not set
+ # CONFIG_ARCH_AT91SAM9RL is not set
++# CONFIG_ARCH_AT91SAM9G20 is not set
++# CONFIG_ARCH_AT91SAM9G45 is not set
++# CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
+ # CONFIG_ARCH_AT91X40 is not set
+ CONFIG_AT91_PMC_UNIT=y
+ 
+@@ -175,8 +206,15 @@ CONFIG_MACH_AT91SAM9261EK=y
+ # AT91 Feature Selections
+ #
+ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+-# CONFIG_ATMEL_TCLIB is not set
++# CONFIG_AT91_SLOW_CLOCK is not set
+ CONFIG_AT91_TIMER_HZ=100
++CONFIG_AT91_EARLY_DBGU=y
++# CONFIG_AT91_EARLY_USART0 is not set
++# CONFIG_AT91_EARLY_USART1 is not set
++# CONFIG_AT91_EARLY_USART2 is not set
++# CONFIG_AT91_EARLY_USART3 is not set
++# CONFIG_AT91_EARLY_USART4 is not set
++# CONFIG_AT91_EARLY_USART5 is not set
+ 
+ #
+ # Processor Type
+@@ -185,6 +223,7 @@ CONFIG_CPU_32=y
+ CONFIG_CPU_ARM926T=y
+ CONFIG_CPU_32v5=y
+ CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
+ CONFIG_CPU_CACHE_VIVT=y
+ CONFIG_CPU_COPY_V4WB=y
+ CONFIG_CPU_TLB_V4WBI=y
+@@ -194,7 +233,7 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Processor Features
+ #
+-# CONFIG_ARM_THUMB is not set
++CONFIG_ARM_THUMB=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+@@ -211,25 +250,37 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Kernel Features
+ #
+-# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
+ # CONFIG_PREEMPT is not set
+ CONFIG_HZ=100
+-# CONFIG_AEABI is not set
+-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
+ CONFIG_SELECT_MEMORY_MODEL=y
+ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
+-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4096
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-CONFIG_BOUNCE=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_VIRT_TO_BUS=y
+-# CONFIG_LEDS is not set
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_LEDS=y
++CONFIG_LEDS_CPU=y
+ CONFIG_ALIGNMENT_TRAP=y
+ 
+ #
+@@ -242,6 +293,11 @@ CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev
+ # CONFIG_KEXEC is not set
+ 
+ #
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
+ # Floating point emulation
+ #
+ 
+@@ -257,19 +313,21 @@ CONFIG_FPE_NWFPE=y
+ # Userspace binary formats
+ #
+ CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
+ # CONFIG_BINFMT_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+-# CONFIG_ARTHUR is not set
+ 
+ #
+ # Power management options
+ #
+-# CONFIG_PM is not set
+-CONFIG_SUSPEND_UP_POSSIBLE=y
+-
+-#
+-# Networking
+-#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ CONFIG_NET=y
+ 
+ #
+@@ -278,21 +336,18 @@ CONFIG_NET=y
+ CONFIG_PACKET=y
+ # CONFIG_PACKET_MMAP is not set
+ CONFIG_UNIX=y
+-CONFIG_XFRM=y
+-# CONFIG_XFRM_USER is not set
+-# CONFIG_XFRM_SUB_POLICY is not set
+-# CONFIG_XFRM_MIGRATE is not set
+ # CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
++CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_FIB_HASH=y
+ CONFIG_IP_PNP=y
+ # CONFIG_IP_PNP_DHCP is not set
+ CONFIG_IP_PNP_BOOTP=y
+-# CONFIG_IP_PNP_RARP is not set
++CONFIG_IP_PNP_RARP=y
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+@@ -300,19 +355,16 @@ CONFIG_IP_PNP_BOOTP=y
+ # CONFIG_INET_IPCOMP is not set
+ # CONFIG_INET_XFRM_TUNNEL is not set
+ # CONFIG_INET_TUNNEL is not set
+-CONFIG_INET_XFRM_MODE_TRANSPORT=y
+-CONFIG_INET_XFRM_MODE_TUNNEL=y
+-CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
+ # CONFIG_INET_LRO is not set
+-CONFIG_INET_DIAG=y
+-CONFIG_INET_TCP_DIAG=y
++# CONFIG_INET_DIAG is not set
+ # CONFIG_TCP_CONG_ADVANCED is not set
+ CONFIG_TCP_CONG_CUBIC=y
+ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TCP_MD5SIG is not set
+ # CONFIG_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+ # CONFIG_NETWORK_SECMARK is not set
+ # CONFIG_NETFILTER is not set
+ # CONFIG_IP_DCCP is not set
+@@ -320,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_LLC2 is not set
+@@ -329,24 +382,40 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_LAPB is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
+ # CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
+ 
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+ # CONFIG_AF_RXRPC is not set
+-
+-#
+-# Wireless
+-#
+-# CONFIG_CFG80211 is not set
+-# CONFIG_WIRELESS_EXT is not set
+-# CONFIG_MAC80211 is not set
+-# CONFIG_IEEE80211 is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
+ # CONFIG_RFKILL is not set
+ # CONFIG_NET_9P is not set
+ 
+@@ -360,23 +429,25 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
+-# CONFIG_DEBUG_DRIVER is not set
+-# CONFIG_DEBUG_DEVRES is not set
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_SYS_HYPERVISOR is not set
+ # CONFIG_CONNECTOR is not set
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+ # CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ CONFIG_MTD_CMDLINE_PARTS=y
+ # CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
+ 
+ #
+ # User Modules And Translation Layers
+ #
+-# CONFIG_MTD_CHAR is not set
++CONFIG_MTD_CHAR=y
+ CONFIG_MTD_BLKDEVS=y
+ CONFIG_MTD_BLOCK=y
+ # CONFIG_FTL is not set
+@@ -414,7 +485,9 @@ CONFIG_MTD_CFI_I2=y
+ #
+ # Self-contained MTD device drivers
+ #
+-# CONFIG_MTD_DATAFLASH is not set
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
+ # CONFIG_MTD_M25P80 is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+@@ -431,33 +504,55 @@ CONFIG_MTD_NAND=y
+ # CONFIG_MTD_NAND_VERIFY_WRITE is not set
+ # CONFIG_MTD_NAND_ECC_SMC is not set
+ # CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
+ CONFIG_MTD_NAND_IDS=y
+ # CONFIG_MTD_NAND_DISKONCHIP is not set
+ CONFIG_MTD_NAND_ATMEL=y
++CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
++# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
++# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+ # CONFIG_MTD_NAND_NANDSIM is not set
+ # CONFIG_MTD_NAND_PLATFORM is not set
+ # CONFIG_MTD_ALAUDA is not set
+ # CONFIG_MTD_ONENAND is not set
+ 
+ #
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
+ # UBI - Unsorted block images
+ #
+ # CONFIG_MTD_UBI is not set
+ # CONFIG_PARPORT is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+-# CONFIG_BLK_DEV_LOOP is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_UB is not set
+ CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_COUNT=8
+ CONFIG_BLK_DEV_RAM_SIZE=8192
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_BLK_DEV_XIP is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+ CONFIG_MISC_DEVICES=y
+-# CONFIG_EEPROM_93CX6 is not set
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+ CONFIG_ATMEL_SSC=y
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT25 is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
+ 
+ #
+ # SCSI device support
+@@ -496,29 +591,58 @@ CONFIG_SCSI_WAIT_SCAN=m
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
+ # CONFIG_SCSI_SAS_LIBSAS is not set
+ # CONFIG_SCSI_SRP_ATTRS is not set
+-CONFIG_SCSI_LOWLEVEL=y
+-# CONFIG_ISCSI_TCP is not set
+-# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
+ CONFIG_NETDEVICES=y
+-# CONFIG_NETDEVICES_MULTIQUEUE is not set
++CONFIG_COMPAT_NET_DEV_OPS=y
+ # CONFIG_DUMMY is not set
+ # CONFIG_BONDING is not set
+ # CONFIG_MACVLAN is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
+ # CONFIG_VETH is not set
+-# CONFIG_PHYLIB is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+ # CONFIG_AX88796 is not set
+ # CONFIG_SMC91X is not set
+ CONFIG_DM9000=y
++CONFIG_DM9000_DEBUGLEVEL=4
++# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
+ # CONFIG_IBM_NEW_EMAC_ZMII is not set
+ # CONFIG_IBM_NEW_EMAC_RGMII is not set
+ # CONFIG_IBM_NEW_EMAC_TAH is not set
+ # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+ # CONFIG_B44 is not set
+ # CONFIG_NETDEV_1000 is not set
+ # CONFIG_NETDEV_10000 is not set
+@@ -527,7 +651,39 @@ CONFIG_DM9000=y
+ # Wireless LAN
+ #
+ # CONFIG_WLAN_PRE80211 is not set
+-# CONFIG_WLAN_80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_USB=m
++CONFIG_LIBERTAS_SDIO=m
++CONFIG_LIBERTAS_SPI=m
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++CONFIG_USB_ZD1201=m
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++CONFIG_RTL8187=m
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_AR9170_USB=m
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++CONFIG_RT2X00=m
++CONFIG_RT2500USB=m
++CONFIG_RT73USB=m
++CONFIG_RT2X00_LIB_USB=m
++CONFIG_RT2X00_LIB=m
++CONFIG_RT2X00_LIB_FIRMWARE=y
++CONFIG_RT2X00_LIB_CRYPTO=y
++CONFIG_RT2X00_LIB_RFKILL=y
++CONFIG_RT2X00_LIB_LEDS=y
++# CONFIG_RT2X00_DEBUG is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
+ 
+ #
+ # USB Network Adapters
+@@ -540,7 +696,6 @@ CONFIG_DM9000=y
+ # CONFIG_WAN is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+-# CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+@@ -551,17 +706,17 @@ CONFIG_DM9000=y
+ #
+ CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
+-# CONFIG_INPUT_POLLDEV is not set
++CONFIG_INPUT_POLLDEV=m
+ 
+ #
+ # Userland interfaces
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+ # CONFIG_INPUT_JOYDEV is not set
+-# CONFIG_INPUT_EVDEV is not set
++CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+@@ -580,33 +735,38 @@ CONFIG_KEYBOARD_GPIO=y
+ # CONFIG_INPUT_TABLET is not set
+ CONFIG_INPUT_TOUCHSCREEN=y
+ CONFIG_TOUCHSCREEN_ADS7846=y
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
+ # CONFIG_TOUCHSCREEN_FUJITSU is not set
+ # CONFIG_TOUCHSCREEN_GUNZE is not set
+ # CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+ # CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
+ # CONFIG_TOUCHSCREEN_MK712 is not set
+ # CONFIG_TOUCHSCREEN_PENMOUNT is not set
+ # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+ # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+-# CONFIG_TOUCHSCREEN_UCB1400 is not set
+ # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
+ # Hardware I/O ports
+ #
+-CONFIG_SERIO=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO is not set
+ # CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+ #
+ CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
+ CONFIG_HW_CONSOLE=y
+ # CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -619,112 +779,99 @@ CONFIG_HW_CONSOLE=y
+ #
+ CONFIG_SERIAL_ATMEL=y
+ CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
+ # CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+ CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
++CONFIG_LEGACY_PTY_COUNT=16
+ # CONFIG_IPMI_HANDLER is not set
+ CONFIG_HW_RANDOM=y
+-# CONFIG_NVRAM is not set
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
+-CONFIG_I2C=y
+-CONFIG_I2C_BOARDINFO=y
+-CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
+ 
+ #
+-# I2C Algorithms
++# SPI Master Controller Drivers
+ #
+-CONFIG_I2C_ALGOBIT=y
+-# CONFIG_I2C_ALGOPCF is not set
+-# CONFIG_I2C_ALGOPCA is not set
++CONFIG_SPI_ATMEL=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
+ 
+ #
+-# I2C Hardware Bus support
++# SPI Protocol Masters
+ #
+-CONFIG_I2C_GPIO=y
+-# CONFIG_I2C_OCORES is not set
+-# CONFIG_I2C_PARPORT_LIGHT is not set
+-# CONFIG_I2C_SIMTEC is not set
+-# CONFIG_I2C_TAOS_EVM is not set
+-# CONFIG_I2C_STUB is not set
+-# CONFIG_I2C_TINY_USB is not set
+-# CONFIG_I2C_PCA is not set
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
+ 
+ #
+-# Miscellaneous I2C Chip support
++# Memory mapped GPIO expanders:
+ #
+-# CONFIG_SENSORS_DS1337 is not set
+-# CONFIG_SENSORS_DS1374 is not set
+-# CONFIG_DS1682 is not set
+-# CONFIG_EEPROM_LEGACY is not set
+-# CONFIG_SENSORS_PCF8574 is not set
+-# CONFIG_SENSORS_PCA9539 is not set
+-# CONFIG_SENSORS_PCF8591 is not set
+-# CONFIG_SENSORS_MAX6875 is not set
+-# CONFIG_SENSORS_TSL2550 is not set
+-# CONFIG_I2C_DEBUG_CORE is not set
+-# CONFIG_I2C_DEBUG_ALGO is not set
+-# CONFIG_I2C_DEBUG_BUS is not set
+-# CONFIG_I2C_DEBUG_CHIP is not set
+ 
+ #
+-# SPI support
++# I2C GPIO expanders:
+ #
+-CONFIG_SPI=y
+-# CONFIG_SPI_DEBUG is not set
+-CONFIG_SPI_MASTER=y
+ 
+ #
+-# SPI Master Controller Drivers
++# PCI GPIO expanders:
+ #
+-CONFIG_SPI_ATMEL=y
+-# CONFIG_SPI_BITBANG is not set
+ 
+ #
+-# SPI Protocol Masters
++# SPI GPIO expanders:
+ #
+-# CONFIG_EEPROM_AT25 is not set
+-# CONFIG_SPI_SPIDEV is not set
+-# CONFIG_SPI_TLE62X0 is not set
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
+ # CONFIG_W1 is not set
+ # CONFIG_POWER_SUPPLY is not set
+ # CONFIG_HWMON is not set
+-CONFIG_WATCHDOG=y
+-CONFIG_WATCHDOG_NOWAYOUT=y
+-
+-#
+-# Watchdog Device Drivers
+-#
+-# CONFIG_SOFT_WATCHDOG is not set
+-CONFIG_AT91SAM9X_WATCHDOG=y
+-
+-#
+-# USB-based Watchdog Cards
+-#
+-# CONFIG_USBPCWATCHDOG is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
+ 
+ #
+ # Sonics Silicon Backplane
+ #
+-CONFIG_SSB_POSSIBLE=y
+ # CONFIG_SSB is not set
+ 
+ #
+ # Multifunction device drivers
+ #
++# CONFIG_MFD_CORE is not set
+ # CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
+ 
+ #
+ # Multimedia devices
+ #
++
++#
++# Multimedia core support
++#
+ # CONFIG_VIDEO_DEV is not set
+ # CONFIG_DVB_CORE is not set
+-CONFIG_DAB=y
+-# CONFIG_USB_DABUSB is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
+ 
+ #
+ # Graphics support
+@@ -734,6 +881,7 @@ CONFIG_DAB=y
+ CONFIG_FB=y
+ # CONFIG_FIRMWARE_EDID is not set
+ # CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+ CONFIG_FB_CFB_FILLRECT=y
+ CONFIG_FB_CFB_COPYAREA=y
+ CONFIG_FB_CFB_IMAGEBLIT=y
+@@ -741,8 +889,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
+ # CONFIG_FB_SYS_FILLRECT is not set
+ # CONFIG_FB_SYS_COPYAREA is not set
+ # CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
+ # CONFIG_FB_SYS_FOPS is not set
+-CONFIG_FB_DEFERRED_IO=y
+ # CONFIG_FB_SVGALIB is not set
+ # CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_BACKLIGHT is not set
+@@ -755,10 +903,17 @@ CONFIG_FB_DEFERRED_IO=y
+ # CONFIG_FB_S1D15605 is not set
+ # CONFIG_FB_S1D13XXX is not set
+ CONFIG_FB_ATMEL=y
+-# CONFIG_FB_INTSRAM is not set
++CONFIG_FB_INTSRAM=y
+ # CONFIG_FB_ATMEL_STN is not set
+ # CONFIG_FB_VIRTUAL is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_ATMEL_LCDC=y
++# CONFIG_BACKLIGHT_GENERIC is not set
+ 
+ #
+ # Display device support
+@@ -772,11 +927,40 @@ CONFIG_FB_ATMEL=y
+ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_FRAMEBUFFER_CONSOLE is not set
+ # CONFIG_LOGO is not set
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_SEQUENCER_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++
++#
++# Atmel devices (AVR32 and AT91)
++#
++# CONFIG_SND_ATMEL_AC97C is not set
++CONFIG_SND_SPI=y
++CONFIG_SND_AT73C213=y
++CONFIG_SND_AT73C213_TARGET_BITRATE=48000
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+ # CONFIG_HID_DEBUG is not set
+@@ -786,63 +970,76 @@ CONFIG_HID=y
+ # USB Input Devices
+ #
+ # CONFIG_USB_HID is not set
++# CONFIG_HID_PID is not set
+ 
+ #
+-# USB HID Boot Protocol drivers
++# Special HID drivers
+ #
+-# CONFIG_USB_KBD is not set
+-# CONFIG_USB_MOUSE is not set
+ CONFIG_USB_SUPPORT=y
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_USB_ARCH_HAS_EHCI is not set
+ CONFIG_USB=y
+ # CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+ 
+ #
+ # Miscellaneous USB options
+ #
+ CONFIG_USB_DEVICEFS=y
+-CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DEVICE_CLASS is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
+ # CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
+ 
+ #
+ # USB Host Controller Drivers
+ #
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+ # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ # CONFIG_USB_SL811_HCD is not set
+ # CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+ #
+ 
+ #
+-# may also be needed; see USB_STORAGE Help for more information
++# also be needed; see USB_STORAGE Help for more info
+ #
+ CONFIG_USB_STORAGE=y
+-CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DEBUG is not set
+ # CONFIG_USB_STORAGE_DATAFAB is not set
+ # CONFIG_USB_STORAGE_FREECOM is not set
+ # CONFIG_USB_STORAGE_ISD200 is not set
+-# CONFIG_USB_STORAGE_DPCM is not set
+ # CONFIG_USB_STORAGE_USBAT is not set
+ # CONFIG_USB_STORAGE_SDDR09 is not set
+ # CONFIG_USB_STORAGE_SDDR55 is not set
+ # CONFIG_USB_STORAGE_JUMPSHOT is not set
+ # CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
+ # CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+ # CONFIG_USB_LIBUSUAL is not set
+ 
+ #
+@@ -850,15 +1047,10 @@ CONFIG_USB_STORAGE_DEBUG=y
+ #
+ # CONFIG_USB_MDC800 is not set
+ # CONFIG_USB_MICROTEK is not set
+-CONFIG_USB_MON=y
+ 
+ #
+ # USB port drivers
+ #
+-
+-#
+-# USB Serial Converter support
+-#
+ # CONFIG_USB_SERIAL is not set
+ 
+ #
+@@ -867,7 +1059,7 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_ADUTUX is not set
+-# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_SEVSEG is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+ # CONFIG_USB_LCD is not set
+@@ -875,7 +1067,6 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_LED is not set
+ # CONFIG_USB_CYPRESS_CY7C63 is not set
+ # CONFIG_USB_CYTHERM is not set
+-# CONFIG_USB_PHIDGET is not set
+ # CONFIG_USB_IDMOUSE is not set
+ # CONFIG_USB_FTDI_ELAN is not set
+ # CONFIG_USB_APPLEDISPLAY is not set
+@@ -883,56 +1074,90 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_TRANCEVIBRATOR is not set
+ # CONFIG_USB_IOWARRIOR is not set
+ # CONFIG_USB_TEST is not set
+-
+-#
+-# USB DSL modem support
+-#
+-
+-#
+-# USB Gadget Support
+-#
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
+ CONFIG_USB_GADGET=y
+-# CONFIG_USB_GADGET_DEBUG is not set
+ # CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
+ CONFIG_USB_GADGET_SELECTED=y
+-# CONFIG_USB_GADGET_AMD5536UDC is not set
++CONFIG_USB_GADGET_AT91=y
++CONFIG_USB_AT91=y
+ # CONFIG_USB_GADGET_ATMEL_USBA is not set
+ # CONFIG_USB_GADGET_FSL_USB2 is not set
+-# CONFIG_USB_GADGET_NET2280 is not set
+-# CONFIG_USB_GADGET_PXA2XX is not set
+-# CONFIG_USB_GADGET_M66592 is not set
+-# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_LH7A40X is not set
+ # CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
+ # CONFIG_USB_GADGET_S3C2410 is not set
+-CONFIG_USB_GADGET_AT91=y
+-CONFIG_USB_AT91=y
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_DUMMY_HCD is not set
+ # CONFIG_USB_GADGET_DUALSPEED is not set
+ CONFIG_USB_ZERO=m
+-# CONFIG_USB_ETH is not set
+-CONFIG_USB_GADGETFS=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
+ CONFIG_USB_FILE_STORAGE=m
+ # CONFIG_USB_FILE_STORAGE_TEST is not set
+ CONFIG_USB_G_SERIAL=m
+ # CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ # CONFIG_MMC_UNSAFE_RESUME is not set
+ 
+ #
+-# MMC/SD Card Drivers
++# MMC/SD/SDIO Card Drivers
+ #
+ CONFIG_MMC_BLOCK=y
+ CONFIG_MMC_BLOCK_BOUNCE=y
+-# CONFIG_SDIO_UART is not set
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
+ 
+ #
+-# MMC/SD Host Controller Drivers
++# MMC/SD/SDIO Host Controller Drivers
+ #
+-CONFIG_MMC_AT91=y
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AT91=m
++# CONFIG_MMC_ATMELMCI is not set
+ # CONFIG_MMC_SPI is not set
+-# CONFIG_NEW_LEDS is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_DAC124S085 is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
+ CONFIG_RTC_LIB=y
+ CONFIG_RTC_CLASS=y
+ CONFIG_RTC_HCTOSYS=y
+@@ -949,40 +1174,42 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_TEST is not set
+ 
+ #
+-# I2C RTC drivers
+-#
+-# CONFIG_RTC_DRV_DS1307 is not set
+-# CONFIG_RTC_DRV_DS1374 is not set
+-# CONFIG_RTC_DRV_DS1672 is not set
+-# CONFIG_RTC_DRV_MAX6900 is not set
+-# CONFIG_RTC_DRV_RS5C372 is not set
+-# CONFIG_RTC_DRV_ISL1208 is not set
+-# CONFIG_RTC_DRV_X1205 is not set
+-# CONFIG_RTC_DRV_PCF8563 is not set
+-# CONFIG_RTC_DRV_PCF8583 is not set
+-# CONFIG_RTC_DRV_M41T80 is not set
+-
+-#
+ # SPI RTC drivers
+ #
+-# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
+ # CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
+ 
+ #
+ # Platform RTC drivers
+ #
+ # CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
+ # CONFIG_RTC_DRV_DS1553 is not set
+-# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
+ # CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
+ # CONFIG_RTC_DRV_V3020 is not set
+ 
+ #
+ # on-CPU RTC drivers
+ #
+ CONFIG_RTC_DRV_AT91SAM9=y
++CONFIG_RTC_DRV_AT91SAM9_RTT=0
++CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
+ 
+ #
+ # File systems
+@@ -991,24 +1218,28 @@ CONFIG_EXT2_FS=y
+ # CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_EXT2_FS_XIP is not set
+ # CONFIG_EXT3_FS is not set
+-# CONFIG_EXT4DEV_FS is not set
++# CONFIG_EXT4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
+ # CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+ 
+ #
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
+ # CD-ROM/DVD Filesystems
+ #
+ # CONFIG_ISO9660_FS is not set
+@@ -1018,7 +1249,7 @@ CONFIG_DNOTIFY=y
+ # DOS/FAT/NT Filesystems
+ #
+ CONFIG_FAT_FS=y
+-# CONFIG_MSDOS_FS is not set
++CONFIG_MSDOS_FS=y
+ CONFIG_VFAT_FS=y
+ CONFIG_FAT_DEFAULT_CODEPAGE=437
+ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+@@ -1029,15 +1260,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ #
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
+ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_TMPFS_POSIX_ACL is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ # CONFIG_CONFIGFS_FS is not set
+-
+-#
+-# Miscellaneous filesystems
+-#
++CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+@@ -1045,16 +1274,43 @@ CONFIG_TMPFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-# CONFIG_JFFS2_FS is not set
+-CONFIG_CRAMFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
+-# CONFIG_NFS_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
+ # CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
+ # CONFIG_SMB_FS is not set
+ # CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
+@@ -1102,14 +1358,11 @@ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_ISO8859_9 is not set
+ # CONFIG_NLS_ISO8859_13 is not set
+ # CONFIG_NLS_ISO8859_14 is not set
+-# CONFIG_NLS_ISO8859_15 is not set
++CONFIG_NLS_ISO8859_15=y
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+-# CONFIG_NLS_UTF8 is not set
++CONFIG_NLS_UTF8=y
+ # CONFIG_DLM is not set
+-CONFIG_INSTRUMENTATION=y
+-# CONFIG_PROFILING is not set
+-# CONFIG_MARKERS is not set
+ 
+ #
+ # Kernel hacking
+@@ -1117,63 +1370,161 @@ CONFIG_INSTRUMENTATION=y
+ # CONFIG_PRINTK_TIME is not set
+ CONFIG_ENABLE_WARN_DEPRECATED=y
+ CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ # CONFIG_DEBUG_FS is not set
+ # CONFIG_HEADERS_CHECK is not set
+-CONFIG_DEBUG_KERNEL=y
+-# CONFIG_DEBUG_SHIRQ is not set
+-CONFIG_DETECT_SOFTLOCKUP=y
+-CONFIG_SCHED_DEBUG=y
+-# CONFIG_SCHEDSTATS is not set
+-# CONFIG_TIMER_STATS is not set
+-# CONFIG_DEBUG_SLAB is not set
+-# CONFIG_DEBUG_RT_MUTEXES is not set
+-# CONFIG_RT_MUTEX_TESTER is not set
+-# CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_MUTEXES is not set
+-# CONFIG_DEBUG_LOCK_ALLOC is not set
+-# CONFIG_PROVE_LOCKING is not set
+-# CONFIG_LOCK_STAT is not set
+-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+-# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_KERNEL is not set
+ CONFIG_DEBUG_BUGVERBOSE=y
+-# CONFIG_DEBUG_INFO is not set
+-# CONFIG_DEBUG_VM is not set
+-# CONFIG_DEBUG_LIST is not set
+-# CONFIG_DEBUG_SG is not set
+-CONFIG_FRAME_POINTER=y
+-CONFIG_FORCED_INLINING=y
+-# CONFIG_BOOT_PRINTK_DELAY is not set
+-# CONFIG_RCU_TORTURE_TEST is not set
+-# CONFIG_FAULT_INJECTION is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
+ # CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
+ CONFIG_DEBUG_USER=y
+-# CONFIG_DEBUG_ERRORS is not set
+-CONFIG_DEBUG_LL=y
+-# CONFIG_DEBUG_ICEDCC is not set
+ 
+ #
+ # Security options
+ #
+ # CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
+ # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
+ 
+ #
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
+ # CONFIG_CRC_CCITT is not set
+ # CONFIG_CRC16 is not set
+-# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
+ CONFIG_CRC32=y
+ # CONFIG_CRC7 is not set
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+-CONFIG_PLIST=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
+ CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+-- 
+1.5.6.5
+
+From 4c9cd23bb81a8144b77a057aafe60e2340231828 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:32:02 +0000
+Subject: [PATCH] at91: update at91sam9260ek defconfig file
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11635 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/configs/at91sam9260ek_defconfig |  913 ++++++++++++++++++++++--------
+ 1 files changed, 682 insertions(+), 231 deletions(-)
+
+diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig
+index 98e2f3d..c87663d 100644
+--- a/arch/arm/configs/at91sam9260ek_defconfig
++++ b/arch/arm/configs/at91sam9260ek_defconfig
+@@ -1,17 +1,18 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc7
+-# Tue Jan  8 22:20:50 2008
++# Linux kernel version: 2.6.30
++# Tue Oct 13 12:38:49 2009
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+ CONFIG_GENERIC_GPIO=y
+-# CONFIG_GENERIC_TIME is not set
+-# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_MMU=y
+ # CONFIG_NO_IOPORT is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ CONFIG_HARDIRQS_SW_RESEND=y
+@@ -21,7 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+ CONFIG_VECTORS_BASE=0xffff0000
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+@@ -39,57 +40,82 @@ CONFIG_SYSVIPC_SYSCTL=y
+ # CONFIG_POSIX_MQUEUE is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
+ # CONFIG_CGROUPS is not set
+-CONFIG_FAIR_GROUP_SCHED=y
+-CONFIG_FAIR_USER_SCHED=y
+-# CONFIG_FAIR_CGROUP_SCHED is not set
+ CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
+ # CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
+ # CONFIG_EMBEDDED is not set
+ CONFIG_UID16=y
+ CONFIG_SYSCTL_SYSCALL=y
+ CONFIG_KALLSYMS=y
+-# CONFIG_KALLSYMS_ALL is not set
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
+ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+-CONFIG_ANON_INODES=y
+ CONFIG_EPOLL=y
+ CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
+ CONFIG_EVENTFD=y
+ CONFIG_SHMEM=y
++CONFIG_AIO=y
+ CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+ CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+ CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+ # CONFIG_MODVERSIONS is not set
+ # CONFIG_MODULE_SRCVERSION_ALL is not set
+-CONFIG_KMOD=y
+ CONFIG_BLOCK=y
+ # CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+ # CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
+ 
+ #
+ # IO Schedulers
+@@ -103,6 +129,7 @@ CONFIG_DEFAULT_AS=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
+ 
+ #
+ # System Type
+@@ -112,11 +139,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ # CONFIG_ARCH_REALVIEW is not set
+ # CONFIG_ARCH_VERSATILE is not set
+ CONFIG_ARCH_AT91=y
+-# CONFIG_ARCH_CLPS7500 is not set
+ # CONFIG_ARCH_CLPS711X is not set
+-# CONFIG_ARCH_CO285 is not set
+ # CONFIG_ARCH_EBSA110 is not set
+ # CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
+ # CONFIG_ARCH_FOOTBRIDGE is not set
+ # CONFIG_ARCH_NETX is not set
+ # CONFIG_ARCH_H720X is not set
+@@ -128,26 +154,26 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_IXP2000 is not set
+ # CONFIG_ARCH_IXP4XX is not set
+ # CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
+ # CONFIG_ARCH_KS8695 is not set
+ # CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
+ # CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
+ # CONFIG_ARCH_PNX4008 is not set
+ # CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
+ # CONFIG_ARCH_RPC is not set
+ # CONFIG_ARCH_SA1100 is not set
+ # CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
+ # CONFIG_ARCH_SHARK is not set
+ # CONFIG_ARCH_LH7A40X is not set
+ # CONFIG_ARCH_DAVINCI is not set
+ # CONFIG_ARCH_OMAP is not set
+-
+-#
+-# Boot options
+-#
+-
+-#
+-# Power management
+-#
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
+ 
+ #
+ # Atmel AT91 System-on-Chip
+@@ -155,8 +181,13 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_AT91RM9200 is not set
+ CONFIG_ARCH_AT91SAM9260=y
+ # CONFIG_ARCH_AT91SAM9261 is not set
++# CONFIG_ARCH_AT91SAM9G10 is not set
+ # CONFIG_ARCH_AT91SAM9263 is not set
+ # CONFIG_ARCH_AT91SAM9RL is not set
++# CONFIG_ARCH_AT91SAM9G20 is not set
++# CONFIG_ARCH_AT91SAM9G45 is not set
++# CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
+ # CONFIG_ARCH_AT91X40 is not set
+ CONFIG_AT91_PMC_UNIT=y
+ 
+@@ -171,6 +202,10 @@ CONFIG_AT91_PMC_UNIT=y
+ CONFIG_MACH_AT91SAM9260EK=y
+ # CONFIG_MACH_CAM60 is not set
+ # CONFIG_MACH_SAM9_L9260 is not set
++# CONFIG_MACH_AFEB9260 is not set
++# CONFIG_MACH_USB_A9260 is not set
++# CONFIG_MACH_QIL_A9260 is not set
++# CONFIG_MACH_SBC35_A9260 is not set
+ 
+ #
+ # AT91 Board Options
+@@ -182,8 +217,15 @@ CONFIG_MACH_AT91SAM9260EK=y
+ # AT91 Feature Selections
+ #
+ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+-# CONFIG_ATMEL_TCLIB is not set
++# CONFIG_AT91_SLOW_CLOCK is not set
+ CONFIG_AT91_TIMER_HZ=100
++CONFIG_AT91_EARLY_DBGU=y
++# CONFIG_AT91_EARLY_USART0 is not set
++# CONFIG_AT91_EARLY_USART1 is not set
++# CONFIG_AT91_EARLY_USART2 is not set
++# CONFIG_AT91_EARLY_USART3 is not set
++# CONFIG_AT91_EARLY_USART4 is not set
++# CONFIG_AT91_EARLY_USART5 is not set
+ 
+ #
+ # Processor Type
+@@ -192,6 +234,7 @@ CONFIG_CPU_32=y
+ CONFIG_CPU_ARM926T=y
+ CONFIG_CPU_32v5=y
+ CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
+ CONFIG_CPU_CACHE_VIVT=y
+ CONFIG_CPU_COPY_V4WB=y
+ CONFIG_CPU_TLB_V4WBI=y
+@@ -201,7 +244,7 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Processor Features
+ #
+-# CONFIG_ARM_THUMB is not set
++CONFIG_ARM_THUMB=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+@@ -218,25 +261,37 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Kernel Features
+ #
+-# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
+ # CONFIG_PREEMPT is not set
+ CONFIG_HZ=100
+-# CONFIG_AEABI is not set
+-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
+ CONFIG_SELECT_MEMORY_MODEL=y
+ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
+-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4096
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-CONFIG_BOUNCE=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_VIRT_TO_BUS=y
+-# CONFIG_LEDS is not set
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_LEDS=y
++CONFIG_LEDS_CPU=y
+ CONFIG_ALIGNMENT_TRAP=y
+ 
+ #
+@@ -249,6 +304,11 @@ CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev
+ # CONFIG_KEXEC is not set
+ 
+ #
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
+ # Floating point emulation
+ #
+ 
+@@ -264,19 +324,21 @@ CONFIG_FPE_NWFPE=y
+ # Userspace binary formats
+ #
+ CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
+ # CONFIG_BINFMT_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+-# CONFIG_ARTHUR is not set
+ 
+ #
+ # Power management options
+ #
+-# CONFIG_PM is not set
+-CONFIG_SUSPEND_UP_POSSIBLE=y
+-
+-#
+-# Networking
+-#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ CONFIG_NET=y
+ 
+ #
+@@ -287,15 +349,16 @@ CONFIG_PACKET=y
+ CONFIG_UNIX=y
+ # CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
++CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_FIB_HASH=y
+ CONFIG_IP_PNP=y
+ # CONFIG_IP_PNP_DHCP is not set
+ CONFIG_IP_PNP_BOOTP=y
+-# CONFIG_IP_PNP_RARP is not set
++CONFIG_IP_PNP_RARP=y
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+@@ -307,15 +370,12 @@ CONFIG_IP_PNP_BOOTP=y
+ # CONFIG_INET_XFRM_MODE_TUNNEL is not set
+ # CONFIG_INET_XFRM_MODE_BEET is not set
+ # CONFIG_INET_LRO is not set
+-CONFIG_INET_DIAG=y
+-CONFIG_INET_TCP_DIAG=y
++# CONFIG_INET_DIAG is not set
+ # CONFIG_TCP_CONG_ADVANCED is not set
+ CONFIG_TCP_CONG_CUBIC=y
+ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TCP_MD5SIG is not set
+ # CONFIG_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+ # CONFIG_NETWORK_SECMARK is not set
+ # CONFIG_NETFILTER is not set
+ # CONFIG_IP_DCCP is not set
+@@ -323,6 +383,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_LLC2 is not set
+@@ -332,24 +393,40 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_LAPB is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
+ # CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
+ 
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+ # CONFIG_AF_RXRPC is not set
+-
+-#
+-# Wireless
+-#
+-# CONFIG_CFG80211 is not set
+-# CONFIG_WIRELESS_EXT is not set
+-# CONFIG_MAC80211 is not set
+-# CONFIG_IEEE80211 is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
+ # CONFIG_RFKILL is not set
+ # CONFIG_NET_9P is not set
+ 
+@@ -363,27 +440,130 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
+-# CONFIG_DEBUG_DRIVER is not set
+-# CONFIG_DEBUG_DEVRES is not set
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_SYS_HYPERVISOR is not set
+ # CONFIG_CONNECTOR is not set
+-# CONFIG_MTD is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++CONFIG_MTD_NAND_ATMEL=y
++CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
++# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
++# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
+ # CONFIG_PARPORT is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+-# CONFIG_BLK_DEV_LOOP is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_UB is not set
+ CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_COUNT=8
+ CONFIG_BLK_DEV_RAM_SIZE=8192
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_BLK_DEV_XIP is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+ CONFIG_MISC_DEVICES=y
+-# CONFIG_EEPROM_93CX6 is not set
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+ CONFIG_ATMEL_SSC=y
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT25 is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
+ 
+ #
+ # SCSI device support
+@@ -422,13 +602,13 @@ CONFIG_SCSI_WAIT_SCAN=m
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
+ # CONFIG_SCSI_SAS_LIBSAS is not set
+ # CONFIG_SCSI_SRP_ATTRS is not set
+-CONFIG_SCSI_LOWLEVEL=y
+-# CONFIG_ISCSI_TCP is not set
+-# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
+ CONFIG_NETDEVICES=y
+-# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_COMPAT_NET_DEV_OPS is not set
+ # CONFIG_DUMMY is not set
+ # CONFIG_BONDING is not set
+ # CONFIG_MACVLAN is not set
+@@ -441,7 +621,7 @@ CONFIG_PHYLIB=y
+ # MII PHY device drivers
+ #
+ # CONFIG_MARVELL_PHY is not set
+-# CONFIG_DAVICOM_PHY is not set
++CONFIG_DAVICOM_PHY=y
+ # CONFIG_QSEMI_PHY is not set
+ # CONFIG_LXT_PHY is not set
+ # CONFIG_CICADA_PHY is not set
+@@ -449,27 +629,72 @@ CONFIG_PHYLIB=y
+ # CONFIG_SMSC_PHY is not set
+ # CONFIG_BROADCOM_PHY is not set
+ # CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
+ # CONFIG_FIXED_PHY is not set
+ # CONFIG_MDIO_BITBANG is not set
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+ CONFIG_MACB=y
++CONFIG_MACB_TX_SRAM=y
+ # CONFIG_AX88796 is not set
+ # CONFIG_SMC91X is not set
+ # CONFIG_DM9000 is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
+ # CONFIG_IBM_NEW_EMAC_ZMII is not set
+ # CONFIG_IBM_NEW_EMAC_RGMII is not set
+ # CONFIG_IBM_NEW_EMAC_TAH is not set
+ # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+ # CONFIG_B44 is not set
+-CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
+ 
+ #
+ # Wireless LAN
+ #
+ # CONFIG_WLAN_PRE80211 is not set
+-# CONFIG_WLAN_80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_USB=m
++CONFIG_LIBERTAS_SDIO=m
++# CONFIG_LIBERTAS_SPI is not set
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_AT76C50X_USB is not set
++CONFIG_USB_ZD1201=m
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++CONFIG_RTL8187=m
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_AR9170_USB=m
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++CONFIG_RT2X00=m
++CONFIG_RT2500USB=m
++CONFIG_RT73USB=m
++CONFIG_RT2X00_LIB_USB=m
++CONFIG_RT2X00_LIB=m
++CONFIG_RT2X00_LIB_FIRMWARE=y
++CONFIG_RT2X00_LIB_CRYPTO=y
++CONFIG_RT2X00_LIB_RFKILL=y
++CONFIG_RT2X00_LIB_LEDS=y
++# CONFIG_RT2X00_DEBUG is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
+ 
+ #
+ # USB Network Adapters
+@@ -482,7 +707,6 @@ CONFIG_NETDEV_10000=y
+ # CONFIG_WAN is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+-# CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+@@ -493,23 +717,30 @@ CONFIG_NETDEV_10000=y
+ #
+ CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
+-# CONFIG_INPUT_POLLDEV is not set
++CONFIG_INPUT_POLLDEV=m
+ 
+ #
+ # Userland interfaces
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+ # CONFIG_INPUT_JOYDEV is not set
+-# CONFIG_INPUT_EVDEV is not set
++CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+ # Input Device Drivers
+ #
+-# CONFIG_INPUT_KEYBOARD is not set
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_KEYBOARD_GPIO=y
+ # CONFIG_INPUT_MOUSE is not set
+ # CONFIG_INPUT_JOYSTICK is not set
+ # CONFIG_INPUT_TABLET is not set
+@@ -519,16 +750,20 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ #
+ # Hardware I/O ports
+ #
+-# CONFIG_SERIO is not set
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_RAW is not set
+ # CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+ #
+ CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
+ CONFIG_HW_CONSOLE=y
+ # CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -541,96 +776,98 @@ CONFIG_HW_CONSOLE=y
+ #
+ CONFIG_SERIAL_ATMEL=y
+ CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
+ # CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+ CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
++CONFIG_LEGACY_PTY_COUNT=16
+ # CONFIG_IPMI_HANDLER is not set
+-# CONFIG_HW_RANDOM is not set
+-# CONFIG_NVRAM is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
+-CONFIG_I2C=y
+-CONFIG_I2C_BOARDINFO=y
+-CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
+ 
+ #
+-# I2C Algorithms
++# SPI Master Controller Drivers
+ #
+-CONFIG_I2C_ALGOBIT=y
+-# CONFIG_I2C_ALGOPCF is not set
+-# CONFIG_I2C_ALGOPCA is not set
++CONFIG_SPI_ATMEL=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
+ 
+ #
+-# I2C Hardware Bus support
++# SPI Protocol Masters
+ #
+-CONFIG_I2C_GPIO=y
+-# CONFIG_I2C_OCORES is not set
+-# CONFIG_I2C_PARPORT_LIGHT is not set
+-# CONFIG_I2C_SIMTEC is not set
+-# CONFIG_I2C_TAOS_EVM is not set
+-# CONFIG_I2C_STUB is not set
+-# CONFIG_I2C_TINY_USB is not set
+-# CONFIG_I2C_PCA is not set
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
+ 
+ #
+-# Miscellaneous I2C Chip support
++# Memory mapped GPIO expanders:
+ #
+-# CONFIG_SENSORS_DS1337 is not set
+-# CONFIG_SENSORS_DS1374 is not set
+-# CONFIG_DS1682 is not set
+-# CONFIG_EEPROM_LEGACY is not set
+-# CONFIG_SENSORS_PCF8574 is not set
+-# CONFIG_SENSORS_PCA9539 is not set
+-# CONFIG_SENSORS_PCF8591 is not set
+-# CONFIG_SENSORS_MAX6875 is not set
+-# CONFIG_SENSORS_TSL2550 is not set
+-# CONFIG_I2C_DEBUG_CORE is not set
+-# CONFIG_I2C_DEBUG_ALGO is not set
+-# CONFIG_I2C_DEBUG_BUS is not set
+-# CONFIG_I2C_DEBUG_CHIP is not set
+ 
+ #
+-# SPI support
++# I2C GPIO expanders:
+ #
+-# CONFIG_SPI is not set
+-# CONFIG_SPI_MASTER is not set
+-# CONFIG_W1 is not set
+-# CONFIG_POWER_SUPPLY is not set
+-# CONFIG_HWMON is not set
+-CONFIG_WATCHDOG=y
+-CONFIG_WATCHDOG_NOWAYOUT=y
+ 
+ #
+-# Watchdog Device Drivers
++# PCI GPIO expanders:
+ #
+-# CONFIG_SOFT_WATCHDOG is not set
+-CONFIG_AT91SAM9X_WATCHDOG=y
+ 
+ #
+-# USB-based Watchdog Cards
++# SPI GPIO expanders:
+ #
+-# CONFIG_USBPCWATCHDOG is not set
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
+ 
+ #
+ # Sonics Silicon Backplane
+ #
+-CONFIG_SSB_POSSIBLE=y
+ # CONFIG_SSB is not set
+ 
+ #
+ # Multifunction device drivers
+ #
++# CONFIG_MFD_CORE is not set
+ # CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
+ 
+ #
+ # Multimedia devices
+ #
++
++#
++# Multimedia core support
++#
+ # CONFIG_VIDEO_DEV is not set
+ # CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
+ # CONFIG_DAB is not set
+ 
+ #
+@@ -651,11 +888,40 @@ CONFIG_SSB_POSSIBLE=y
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_SEQUENCER_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++
++#
++# Atmel devices (AVR32 and AT91)
++#
++# CONFIG_SND_ATMEL_AC97C is not set
++CONFIG_SND_SPI=y
++CONFIG_SND_AT73C213=y
++CONFIG_SND_AT73C213_TARGET_BITRATE=48000
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++# CONFIG_SND_USB_CAIAQ is not set
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+ # CONFIG_HID_DEBUG is not set
+@@ -665,63 +931,76 @@ CONFIG_HID=y
+ # USB Input Devices
+ #
+ # CONFIG_USB_HID is not set
++# CONFIG_HID_PID is not set
+ 
+ #
+-# USB HID Boot Protocol drivers
++# Special HID drivers
+ #
+-# CONFIG_USB_KBD is not set
+-# CONFIG_USB_MOUSE is not set
+ CONFIG_USB_SUPPORT=y
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_USB_ARCH_HAS_EHCI is not set
+ CONFIG_USB=y
+ # CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+ 
+ #
+ # Miscellaneous USB options
+ #
+ CONFIG_USB_DEVICEFS=y
+-CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DEVICE_CLASS is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
+ # CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
+ 
+ #
+ # USB Host Controller Drivers
+ #
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+ # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ # CONFIG_USB_SL811_HCD is not set
+ # CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+ #
+ 
+ #
+-# may also be needed; see USB_STORAGE Help for more information
++# also be needed; see USB_STORAGE Help for more info
+ #
+ CONFIG_USB_STORAGE=y
+-CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DEBUG is not set
+ # CONFIG_USB_STORAGE_DATAFAB is not set
+ # CONFIG_USB_STORAGE_FREECOM is not set
+ # CONFIG_USB_STORAGE_ISD200 is not set
+-# CONFIG_USB_STORAGE_DPCM is not set
+ # CONFIG_USB_STORAGE_USBAT is not set
+ # CONFIG_USB_STORAGE_SDDR09 is not set
+ # CONFIG_USB_STORAGE_SDDR55 is not set
+ # CONFIG_USB_STORAGE_JUMPSHOT is not set
+ # CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
+ # CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+ # CONFIG_USB_LIBUSUAL is not set
+ 
+ #
+@@ -729,15 +1008,10 @@ CONFIG_USB_STORAGE_DEBUG=y
+ #
+ # CONFIG_USB_MDC800 is not set
+ # CONFIG_USB_MICROTEK is not set
+-CONFIG_USB_MON=y
+ 
+ #
+ # USB port drivers
+ #
+-
+-#
+-# USB Serial Converter support
+-#
+ # CONFIG_USB_SERIAL is not set
+ 
+ #
+@@ -746,7 +1020,7 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_ADUTUX is not set
+-# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_SEVSEG is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+ # CONFIG_USB_LCD is not set
+@@ -754,7 +1028,6 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_LED is not set
+ # CONFIG_USB_CYPRESS_CY7C63 is not set
+ # CONFIG_USB_CYTHERM is not set
+-# CONFIG_USB_PHIDGET is not set
+ # CONFIG_USB_IDMOUSE is not set
+ # CONFIG_USB_FTDI_ELAN is not set
+ # CONFIG_USB_APPLEDISPLAY is not set
+@@ -762,41 +1035,90 @@ CONFIG_USB_MON=y
+ # CONFIG_USB_TRANCEVIBRATOR is not set
+ # CONFIG_USB_IOWARRIOR is not set
+ # CONFIG_USB_TEST is not set
+-
+-#
+-# USB DSL modem support
+-#
+-
+-#
+-# USB Gadget Support
+-#
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
+ CONFIG_USB_GADGET=y
+-# CONFIG_USB_GADGET_DEBUG is not set
+ # CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
+ CONFIG_USB_GADGET_SELECTED=y
+-# CONFIG_USB_GADGET_AMD5536UDC is not set
++CONFIG_USB_GADGET_AT91=y
++CONFIG_USB_AT91=y
+ # CONFIG_USB_GADGET_ATMEL_USBA is not set
+ # CONFIG_USB_GADGET_FSL_USB2 is not set
+-# CONFIG_USB_GADGET_NET2280 is not set
+-# CONFIG_USB_GADGET_PXA2XX is not set
+-# CONFIG_USB_GADGET_M66592 is not set
+-# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_LH7A40X is not set
+ # CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
+ # CONFIG_USB_GADGET_S3C2410 is not set
+-CONFIG_USB_GADGET_AT91=y
+-CONFIG_USB_AT91=y
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
+ # CONFIG_USB_GADGET_DUMMY_HCD is not set
+ # CONFIG_USB_GADGET_DUALSPEED is not set
+ CONFIG_USB_ZERO=m
+-# CONFIG_USB_ETH is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
+ CONFIG_USB_GADGETFS=m
+ CONFIG_USB_FILE_STORAGE=m
+ # CONFIG_USB_FILE_STORAGE_TEST is not set
+ CONFIG_USB_G_SERIAL=m
+ # CONFIG_USB_MIDI_GADGET is not set
+-# CONFIG_MMC is not set
+-# CONFIG_NEW_LEDS is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AT91=y
++# CONFIG_MMC_ATMELMCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_DAC124S085 is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
+ CONFIG_RTC_LIB=y
+ CONFIG_RTC_CLASS=y
+ CONFIG_RTC_HCTOSYS=y
+@@ -813,38 +1135,42 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_TEST is not set
+ 
+ #
+-# I2C RTC drivers
+-#
+-# CONFIG_RTC_DRV_DS1307 is not set
+-# CONFIG_RTC_DRV_DS1374 is not set
+-# CONFIG_RTC_DRV_DS1672 is not set
+-# CONFIG_RTC_DRV_MAX6900 is not set
+-# CONFIG_RTC_DRV_RS5C372 is not set
+-# CONFIG_RTC_DRV_ISL1208 is not set
+-# CONFIG_RTC_DRV_X1205 is not set
+-# CONFIG_RTC_DRV_PCF8563 is not set
+-# CONFIG_RTC_DRV_PCF8583 is not set
+-# CONFIG_RTC_DRV_M41T80 is not set
+-
+-#
+ # SPI RTC drivers
+ #
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
+ 
+ #
+ # Platform RTC drivers
+ #
+ # CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
+ # CONFIG_RTC_DRV_DS1553 is not set
+-# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
+ # CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
+ # CONFIG_RTC_DRV_V3020 is not set
+ 
+ #
+ # on-CPU RTC drivers
+ #
+ CONFIG_RTC_DRV_AT91SAM9=y
++CONFIG_RTC_DRV_AT91SAM9_RTT=0
++CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
+ 
+ #
+ # File systems
+@@ -853,24 +1179,28 @@ CONFIG_EXT2_FS=y
+ # CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_EXT2_FS_XIP is not set
+ # CONFIG_EXT3_FS is not set
+-# CONFIG_EXT4DEV_FS is not set
++# CONFIG_EXT4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
+ # CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+ 
+ #
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
+ # CD-ROM/DVD Filesystems
+ #
+ # CONFIG_ISO9660_FS is not set
+@@ -880,7 +1210,7 @@ CONFIG_DNOTIFY=y
+ # DOS/FAT/NT Filesystems
+ #
+ CONFIG_FAT_FS=y
+-# CONFIG_MSDOS_FS is not set
++CONFIG_MSDOS_FS=y
+ CONFIG_VFAT_FS=y
+ CONFIG_FAT_DEFAULT_CODEPAGE=437
+ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+@@ -891,15 +1221,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ #
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
+ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_TMPFS_POSIX_ACL is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ # CONFIG_CONFIGFS_FS is not set
+-
+-#
+-# Miscellaneous filesystems
+-#
++CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+@@ -907,15 +1235,43 @@ CONFIG_TMPFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-CONFIG_CRAMFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
+-# CONFIG_NFS_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
+ # CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
+ # CONFIG_SMB_FS is not set
+ # CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
+@@ -963,14 +1319,11 @@ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_ISO8859_9 is not set
+ # CONFIG_NLS_ISO8859_13 is not set
+ # CONFIG_NLS_ISO8859_14 is not set
+-# CONFIG_NLS_ISO8859_15 is not set
++CONFIG_NLS_ISO8859_15=y
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+-# CONFIG_NLS_UTF8 is not set
++CONFIG_NLS_UTF8=y
+ # CONFIG_DLM is not set
+-CONFIG_INSTRUMENTATION=y
+-# CONFIG_PROFILING is not set
+-# CONFIG_MARKERS is not set
+ 
+ #
+ # Kernel hacking
+@@ -978,63 +1331,161 @@ CONFIG_INSTRUMENTATION=y
+ # CONFIG_PRINTK_TIME is not set
+ CONFIG_ENABLE_WARN_DEPRECATED=y
+ CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ # CONFIG_DEBUG_FS is not set
+ # CONFIG_HEADERS_CHECK is not set
+-CONFIG_DEBUG_KERNEL=y
+-# CONFIG_DEBUG_SHIRQ is not set
+-CONFIG_DETECT_SOFTLOCKUP=y
+-CONFIG_SCHED_DEBUG=y
+-# CONFIG_SCHEDSTATS is not set
+-# CONFIG_TIMER_STATS is not set
+-# CONFIG_DEBUG_SLAB is not set
+-# CONFIG_DEBUG_RT_MUTEXES is not set
+-# CONFIG_RT_MUTEX_TESTER is not set
+-# CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_MUTEXES is not set
+-# CONFIG_DEBUG_LOCK_ALLOC is not set
+-# CONFIG_PROVE_LOCKING is not set
+-# CONFIG_LOCK_STAT is not set
+-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+-# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_KERNEL is not set
+ CONFIG_DEBUG_BUGVERBOSE=y
+-# CONFIG_DEBUG_INFO is not set
+-# CONFIG_DEBUG_VM is not set
+-# CONFIG_DEBUG_LIST is not set
+-# CONFIG_DEBUG_SG is not set
+-CONFIG_FRAME_POINTER=y
+-CONFIG_FORCED_INLINING=y
+-# CONFIG_BOOT_PRINTK_DELAY is not set
+-# CONFIG_RCU_TORTURE_TEST is not set
+-# CONFIG_FAULT_INJECTION is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
+ # CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
+ CONFIG_DEBUG_USER=y
+-# CONFIG_DEBUG_ERRORS is not set
+-CONFIG_DEBUG_LL=y
+-# CONFIG_DEBUG_ICEDCC is not set
+ 
+ #
+ # Security options
+ #
+ # CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
+ # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
+ 
+ #
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
+ # CONFIG_CRC_CCITT is not set
+ # CONFIG_CRC16 is not set
+-# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
+ CONFIG_CRC32=y
+ # CONFIG_CRC7 is not set
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+-CONFIG_PLIST=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
+ CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+-- 
+1.5.6.5
+
+From 01df1515ac885873e2576792368605dc44b53755 Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:32:03 +0000
+Subject: [PATCH] at91: update at91sam9rlek defconfig file
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11636 50fbe906-d41e-0410-8a96-31537896a350
+---
+ arch/arm/configs/at91sam9rlek_defconfig |  834 +++++++++++++++++++++++--------
+ 1 files changed, 631 insertions(+), 203 deletions(-)
+
+diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig
+index e2df81a..3e6fba6 100644
+--- a/arch/arm/configs/at91sam9rlek_defconfig
++++ b/arch/arm/configs/at91sam9rlek_defconfig
+@@ -1,17 +1,18 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc7
+-# Tue Jan  8 22:24:14 2008
++# Linux kernel version: 2.6.30
++# Tue Oct 13 12:57:29 2009
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+ CONFIG_GENERIC_GPIO=y
+-# CONFIG_GENERIC_TIME is not set
+-# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_MMU=y
+ # CONFIG_NO_IOPORT is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ CONFIG_HARDIRQS_SW_RESEND=y
+@@ -21,7 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+ CONFIG_VECTORS_BASE=0xffff0000
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+@@ -39,57 +40,82 @@ CONFIG_SYSVIPC_SYSCTL=y
+ # CONFIG_POSIX_MQUEUE is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
+ # CONFIG_CGROUPS is not set
+-CONFIG_FAIR_GROUP_SCHED=y
+-CONFIG_FAIR_USER_SCHED=y
+-# CONFIG_FAIR_CGROUP_SCHED is not set
+ CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
+ # CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
+ # CONFIG_EMBEDDED is not set
+ CONFIG_UID16=y
+ CONFIG_SYSCTL_SYSCALL=y
+ CONFIG_KALLSYMS=y
+-# CONFIG_KALLSYMS_ALL is not set
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_STRIP_ASM_SYMS=y
+ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+-CONFIG_ANON_INODES=y
+ CONFIG_EPOLL=y
+ CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
+ CONFIG_EVENTFD=y
+ CONFIG_SHMEM=y
++CONFIG_AIO=y
+ CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+ CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+ CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+ # CONFIG_MODVERSIONS is not set
+ # CONFIG_MODULE_SRCVERSION_ALL is not set
+-CONFIG_KMOD=y
+ CONFIG_BLOCK=y
+ # CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+ # CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
+ 
+ #
+ # IO Schedulers
+@@ -103,6 +129,7 @@ CONFIG_DEFAULT_AS=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
+ 
+ #
+ # System Type
+@@ -112,11 +139,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ # CONFIG_ARCH_REALVIEW is not set
+ # CONFIG_ARCH_VERSATILE is not set
+ CONFIG_ARCH_AT91=y
+-# CONFIG_ARCH_CLPS7500 is not set
+ # CONFIG_ARCH_CLPS711X is not set
+-# CONFIG_ARCH_CO285 is not set
+ # CONFIG_ARCH_EBSA110 is not set
+ # CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_GEMINI is not set
+ # CONFIG_ARCH_FOOTBRIDGE is not set
+ # CONFIG_ARCH_NETX is not set
+ # CONFIG_ARCH_H720X is not set
+@@ -128,26 +154,26 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_IXP2000 is not set
+ # CONFIG_ARCH_IXP4XX is not set
+ # CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
+ # CONFIG_ARCH_KS8695 is not set
+ # CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
+ # CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
+ # CONFIG_ARCH_PNX4008 is not set
+ # CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MMP is not set
+ # CONFIG_ARCH_RPC is not set
+ # CONFIG_ARCH_SA1100 is not set
+ # CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
+ # CONFIG_ARCH_SHARK is not set
+ # CONFIG_ARCH_LH7A40X is not set
+ # CONFIG_ARCH_DAVINCI is not set
+ # CONFIG_ARCH_OMAP is not set
+-
+-#
+-# Boot options
+-#
+-
+-#
+-# Power management
+-#
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_W90X900 is not set
+ 
+ #
+ # Atmel AT91 System-on-Chip
+@@ -155,8 +181,13 @@ CONFIG_ARCH_AT91=y
+ # CONFIG_ARCH_AT91RM9200 is not set
+ # CONFIG_ARCH_AT91SAM9260 is not set
+ # CONFIG_ARCH_AT91SAM9261 is not set
++# CONFIG_ARCH_AT91SAM9G10 is not set
+ # CONFIG_ARCH_AT91SAM9263 is not set
+ CONFIG_ARCH_AT91SAM9RL=y
++# CONFIG_ARCH_AT91SAM9G20 is not set
++# CONFIG_ARCH_AT91SAM9G45 is not set
++# CONFIG_ARCH_AT91CAP9 is not set
++# CONFIG_ARCH_AT572D940HF is not set
+ # CONFIG_ARCH_AT91X40 is not set
+ CONFIG_AT91_PMC_UNIT=y
+ 
+@@ -173,8 +204,15 @@ CONFIG_MACH_AT91SAM9RLEK=y
+ # AT91 Feature Selections
+ #
+ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+-# CONFIG_ATMEL_TCLIB is not set
++# CONFIG_AT91_SLOW_CLOCK is not set
+ CONFIG_AT91_TIMER_HZ=100
++CONFIG_AT91_EARLY_DBGU=y
++# CONFIG_AT91_EARLY_USART0 is not set
++# CONFIG_AT91_EARLY_USART1 is not set
++# CONFIG_AT91_EARLY_USART2 is not set
++# CONFIG_AT91_EARLY_USART3 is not set
++# CONFIG_AT91_EARLY_USART4 is not set
++# CONFIG_AT91_EARLY_USART5 is not set
+ 
+ #
+ # Processor Type
+@@ -183,6 +221,7 @@ CONFIG_CPU_32=y
+ CONFIG_CPU_ARM926T=y
+ CONFIG_CPU_32v5=y
+ CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
+ CONFIG_CPU_CACHE_VIVT=y
+ CONFIG_CPU_COPY_V4WB=y
+ CONFIG_CPU_TLB_V4WBI=y
+@@ -192,7 +231,7 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Processor Features
+ #
+-# CONFIG_ARM_THUMB is not set
++CONFIG_ARM_THUMB=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+@@ -209,25 +248,37 @@ CONFIG_CPU_CP15_MMU=y
+ #
+ # Kernel Features
+ #
+-# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
+ # CONFIG_PREEMPT is not set
+ CONFIG_HZ=100
+-# CONFIG_AEABI is not set
+-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
+ CONFIG_SELECT_MEMORY_MODEL=y
+ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
+-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4096
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-CONFIG_BOUNCE=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_VIRT_TO_BUS=y
+-# CONFIG_LEDS is not set
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_LEDS=y
++CONFIG_LEDS_CPU=y
+ CONFIG_ALIGNMENT_TRAP=y
+ 
+ #
+@@ -235,11 +286,16 @@ CONFIG_ALIGNMENT_TRAP=y
+ #
+ CONFIG_ZBOOT_ROM_TEXT=0x0
+ CONFIG_ZBOOT_ROM_BSS=0x0
+-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,17105363 root=/dev/ram0 rw"
++CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+ # CONFIG_XIP_KERNEL is not set
+ # CONFIG_KEXEC is not set
+ 
+ #
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
+ # Floating point emulation
+ #
+ 
+@@ -255,32 +311,62 @@ CONFIG_FPE_NWFPE=y
+ # Userspace binary formats
+ #
+ CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
+ # CONFIG_BINFMT_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+-# CONFIG_ARTHUR is not set
+ 
+ #
+ # Power management options
+ #
+-# CONFIG_PM is not set
+-CONFIG_SUSPEND_UP_POSSIBLE=y
+-
+-#
+-# Networking
+-#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ CONFIG_NET=y
+ 
+ #
+ # Networking options
+ #
+-# CONFIG_PACKET is not set
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
+ CONFIG_UNIX=y
+ # CONFIG_NET_KEY is not set
+-# CONFIG_INET is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
+ # CONFIG_NETWORK_SECMARK is not set
+ # CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_LLC2 is not set
+@@ -288,24 +374,42 @@ CONFIG_UNIX=y
+ # CONFIG_ATALK is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
+ # CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
+ 
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+-
+-#
+-# Wireless
+-#
+-# CONFIG_CFG80211 is not set
+-# CONFIG_WIRELESS_EXT is not set
+-# CONFIG_MAC80211 is not set
+-# CONFIG_IEEE80211 is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=y
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=y
++# CONFIG_LIB80211_DEBUG is not set
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++# CONFIG_MAC80211_LEDS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
+ # CONFIG_RFKILL is not set
+ # CONFIG_NET_9P is not set
+ 
+@@ -319,18 +423,20 @@ CONFIG_UNIX=y
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
+-# CONFIG_DEBUG_DRIVER is not set
+-# CONFIG_DEBUG_DEVRES is not set
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_SYS_HYPERVISOR is not set
+ # CONFIG_CONNECTOR is not set
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-CONFIG_MTD_CONCAT=y
++# CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ CONFIG_MTD_CMDLINE_PARTS=y
+ # CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
+ 
+ #
+ # User Modules And Translation Layers
+@@ -374,6 +480,8 @@ CONFIG_MTD_CFI_I2=y
+ # Self-contained MTD device drivers
+ #
+ CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
+ # CONFIG_MTD_M25P80 is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+@@ -390,14 +498,23 @@ CONFIG_MTD_NAND=y
+ # CONFIG_MTD_NAND_VERIFY_WRITE is not set
+ # CONFIG_MTD_NAND_ECC_SMC is not set
+ # CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
+ CONFIG_MTD_NAND_IDS=y
+ # CONFIG_MTD_NAND_DISKONCHIP is not set
+ CONFIG_MTD_NAND_ATMEL=y
++CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
++# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
++# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+ # CONFIG_MTD_NAND_NANDSIM is not set
+ # CONFIG_MTD_NAND_PLATFORM is not set
+ # CONFIG_MTD_ONENAND is not set
+ 
+ #
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
+ # UBI - Unsorted block images
+ #
+ # CONFIG_MTD_UBI is not set
+@@ -408,14 +525,27 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=4
+-CONFIG_BLK_DEV_RAM_SIZE=24576
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++CONFIG_BLK_DEV_RAM_COUNT=8
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+ CONFIG_MISC_DEVICES=y
++CONFIG_ATMEL_PWM=y
++CONFIG_ATMEL_TCLIB=y
++CONFIG_ATMEL_TCB_CLKSRC=y
++CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT25 is not set
+ # CONFIG_EEPROM_93CX6 is not set
+-CONFIG_ATMEL_SSC=y
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
+ 
+ #
+ # SCSI device support
+@@ -454,11 +584,49 @@ CONFIG_SCSI_WAIT_SCAN=m
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
+ # CONFIG_SCSI_SAS_LIBSAS is not set
+ # CONFIG_SCSI_SRP_ATTRS is not set
+-CONFIG_SCSI_LOWLEVEL=y
+-# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
+-# CONFIG_NETDEVICES is not set
++CONFIG_NETDEVICES=y
++# CONFIG_COMPAT_NET_DEV_OPS is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++CONFIG_LIBERTAS_SDIO=m
++# CONFIG_LIBERTAS_SPI is not set
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_RT2X00 is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+ # CONFIG_ISDN is not set
+ 
+ #
+@@ -473,8 +641,8 @@ CONFIG_INPUT=y
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+ # CONFIG_INPUT_JOYDEV is not set
+ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+@@ -482,23 +650,36 @@ CONFIG_INPUT_EVDEV=y
+ #
+ # Input Device Drivers
+ #
+-# CONFIG_INPUT_KEYBOARD is not set
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_KEYBOARD_GPIO=y
+ # CONFIG_INPUT_MOUSE is not set
+ # CONFIG_INPUT_JOYSTICK is not set
+ # CONFIG_INPUT_TABLET is not set
+ CONFIG_INPUT_TOUCHSCREEN=y
+ # CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
+ # CONFIG_TOUCHSCREEN_FUJITSU is not set
+ # CONFIG_TOUCHSCREEN_GUNZE is not set
+ # CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+ # CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
+ # CONFIG_TOUCHSCREEN_MK712 is not set
+ # CONFIG_TOUCHSCREEN_PENMOUNT is not set
+ # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+ # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+ CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
+-# CONFIG_TOUCHSCREEN_UCB1400 is not set
++# CONFIG_TOUCHSCREEN_WM97XX is not set
+ # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
+@@ -511,9 +692,11 @@ CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
+ # Character devices
+ #
+ CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
+ CONFIG_HW_CONSOLE=y
+ # CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -526,103 +709,99 @@ CONFIG_HW_CONSOLE=y
+ #
+ CONFIG_SERIAL_ATMEL=y
+ CONFIG_SERIAL_ATMEL_CONSOLE=y
++CONFIG_SERIAL_ATMEL_PDC=y
+ # CONFIG_SERIAL_ATMEL_TTYAT is not set
++# CONFIG_SERIAL_MAX3100 is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+ CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
++CONFIG_LEGACY_PTY_COUNT=16
+ # CONFIG_IPMI_HANDLER is not set
+-# CONFIG_HW_RANDOM is not set
+-# CONFIG_NVRAM is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
+-CONFIG_I2C=y
+-CONFIG_I2C_BOARDINFO=y
+-CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
+ 
+ #
+-# I2C Algorithms
++# SPI Master Controller Drivers
+ #
+-CONFIG_I2C_ALGOBIT=y
+-# CONFIG_I2C_ALGOPCF is not set
+-# CONFIG_I2C_ALGOPCA is not set
++CONFIG_SPI_ATMEL=y
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
+ 
+ #
+-# I2C Hardware Bus support
++# SPI Protocol Masters
+ #
+-CONFIG_I2C_GPIO=y
+-# CONFIG_I2C_OCORES is not set
+-# CONFIG_I2C_PARPORT_LIGHT is not set
+-# CONFIG_I2C_SIMTEC is not set
+-# CONFIG_I2C_TAOS_EVM is not set
+-# CONFIG_I2C_STUB is not set
+-# CONFIG_I2C_PCA is not set
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_GPIO_SYSFS is not set
+ 
+ #
+-# Miscellaneous I2C Chip support
++# Memory mapped GPIO expanders:
+ #
+-# CONFIG_SENSORS_DS1337 is not set
+-# CONFIG_SENSORS_DS1374 is not set
+-# CONFIG_DS1682 is not set
+-# CONFIG_EEPROM_LEGACY is not set
+-# CONFIG_SENSORS_PCF8574 is not set
+-# CONFIG_SENSORS_PCA9539 is not set
+-# CONFIG_SENSORS_PCF8591 is not set
+-# CONFIG_SENSORS_MAX6875 is not set
+-# CONFIG_SENSORS_TSL2550 is not set
+-# CONFIG_I2C_DEBUG_CORE is not set
+-# CONFIG_I2C_DEBUG_ALGO is not set
+-# CONFIG_I2C_DEBUG_BUS is not set
+-# CONFIG_I2C_DEBUG_CHIP is not set
+ 
+ #
+-# SPI support
++# I2C GPIO expanders:
+ #
+-CONFIG_SPI=y
+-# CONFIG_SPI_DEBUG is not set
+-CONFIG_SPI_MASTER=y
+ 
+ #
+-# SPI Master Controller Drivers
++# PCI GPIO expanders:
+ #
+-CONFIG_SPI_ATMEL=y
+-# CONFIG_SPI_BITBANG is not set
+ 
+ #
+-# SPI Protocol Masters
++# SPI GPIO expanders:
+ #
+-# CONFIG_EEPROM_AT25 is not set
+-# CONFIG_SPI_SPIDEV is not set
+-# CONFIG_SPI_TLE62X0 is not set
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
+ # CONFIG_W1 is not set
+ # CONFIG_POWER_SUPPLY is not set
+ # CONFIG_HWMON is not set
+-CONFIG_WATCHDOG=y
+-CONFIG_WATCHDOG_NOWAYOUT=y
+-
+-#
+-# Watchdog Device Drivers
+-#
+-# CONFIG_SOFT_WATCHDOG is not set
+-CONFIG_AT91SAM9X_WATCHDOG=y
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
+ 
+ #
+ # Sonics Silicon Backplane
+ #
+-CONFIG_SSB_POSSIBLE=y
+ # CONFIG_SSB is not set
+ 
+ #
+ # Multifunction device drivers
+ #
++# CONFIG_MFD_CORE is not set
+ # CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_UCB1400_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
+ 
+ #
+ # Multimedia devices
+ #
++
++#
++# Multimedia core support
++#
+ # CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
+ # CONFIG_DAB is not set
+ 
+ #
+@@ -633,6 +812,7 @@ CONFIG_SSB_POSSIBLE=y
+ CONFIG_FB=y
+ # CONFIG_FIRMWARE_EDID is not set
+ # CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+ CONFIG_FB_CFB_FILLRECT=y
+ CONFIG_FB_CFB_COPYAREA=y
+ CONFIG_FB_CFB_IMAGEBLIT=y
+@@ -640,8 +820,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
+ # CONFIG_FB_SYS_FILLRECT is not set
+ # CONFIG_FB_SYS_COPYAREA is not set
+ # CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
+ # CONFIG_FB_SYS_FOPS is not set
+-CONFIG_FB_DEFERRED_IO=y
+ # CONFIG_FB_SVGALIB is not set
+ # CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_BACKLIGHT is not set
+@@ -655,7 +835,15 @@ CONFIG_FB_DEFERRED_IO=y
+ # CONFIG_FB_S1D13XXX is not set
+ CONFIG_FB_ATMEL=y
+ # CONFIG_FB_VIRTUAL is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_ATMEL_LCDC=y
++# CONFIG_BACKLIGHT_ATMEL_PWM is not set
++# CONFIG_BACKLIGHT_GENERIC is not set
+ 
+ #
+ # Display device support
+@@ -669,46 +857,139 @@ CONFIG_FB_ATMEL=y
+ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_FRAMEBUFFER_CONSOLE is not set
+ # CONFIG_LOGO is not set
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_SEQUENCER_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_VMASTER=y
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++
++#
++# Atmel devices (AVR32 and AT91)
++#
++CONFIG_SND_ATMEL_AC97C=y
++# CONFIG_SND_SPI is not set
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+ # CONFIG_HID_DEBUG is not set
+ # CONFIG_HIDRAW is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
+ CONFIG_USB_SUPPORT=y
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_USB_ARCH_HAS_EHCI is not set
+ # CONFIG_USB is not set
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+-#
+-
+-#
+-# USB Gadget Support
+-#
+-# CONFIG_USB_GADGET is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++CONFIG_USB_GADGET_ATMEL_USBA=y
++CONFIG_USB_ATMEL_USBA=y
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ # CONFIG_MMC_UNSAFE_RESUME is not set
+ 
+ #
+-# MMC/SD Card Drivers
++# MMC/SD/SDIO Card Drivers
+ #
+ CONFIG_MMC_BLOCK=y
+ CONFIG_MMC_BLOCK_BOUNCE=y
+-# CONFIG_SDIO_UART is not set
++CONFIG_SDIO_UART=m
++# CONFIG_MMC_TEST is not set
+ 
+ #
+-# MMC/SD Host Controller Drivers
++# MMC/SD/SDIO Host Controller Drivers
+ #
++# CONFIG_MMC_SDHCI is not set
+ CONFIG_MMC_AT91=y
++# CONFIG_MMC_ATMELMCI is not set
+ # CONFIG_MMC_SPI is not set
+-# CONFIG_NEW_LEDS is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_LEDS_ATMEL_PWM=y
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_DAC124S085 is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++CONFIG_LEDS_TRIGGER_GPIO=y
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
+ CONFIG_RTC_LIB=y
+ CONFIG_RTC_CLASS=y
+ CONFIG_RTC_HCTOSYS=y
+@@ -725,40 +1006,56 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_TEST is not set
+ 
+ #
+-# I2C RTC drivers
+-#
+-# CONFIG_RTC_DRV_DS1307 is not set
+-# CONFIG_RTC_DRV_DS1374 is not set
+-# CONFIG_RTC_DRV_DS1672 is not set
+-# CONFIG_RTC_DRV_MAX6900 is not set
+-# CONFIG_RTC_DRV_RS5C372 is not set
+-# CONFIG_RTC_DRV_ISL1208 is not set
+-# CONFIG_RTC_DRV_X1205 is not set
+-# CONFIG_RTC_DRV_PCF8563 is not set
+-# CONFIG_RTC_DRV_PCF8583 is not set
+-# CONFIG_RTC_DRV_M41T80 is not set
+-
+-#
+ # SPI RTC drivers
+ #
+-# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
+ # CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
+ 
+ #
+ # Platform RTC drivers
+ #
+ # CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
+ # CONFIG_RTC_DRV_DS1553 is not set
+-# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
+ # CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
+ # CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
+ # CONFIG_RTC_DRV_V3020 is not set
+ 
+ #
+ # on-CPU RTC drivers
+ #
++# CONFIG_RTC_DRV_AT91RM9200 is not set
+ CONFIG_RTC_DRV_AT91SAM9=y
++CONFIG_RTC_DRV_AT91SAM9_RTT=0
++CONFIG_RTC_DRV_AT91SAM9_GPBR=0
++CONFIG_DMADEVICES=y
++
++#
++# DMA Devices
++#
++CONFIG_AT_HDMAC=m
++CONFIG_DMA_ENGINE=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++CONFIG_DMATEST=m
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
+ 
+ #
+ # File systems
+@@ -767,24 +1064,28 @@ CONFIG_EXT2_FS=y
+ # CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_EXT2_FS_XIP is not set
+ # CONFIG_EXT3_FS is not set
+-# CONFIG_EXT4DEV_FS is not set
++# CONFIG_EXT4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
+ # CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+ 
+ #
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
+ # CD-ROM/DVD Filesystems
+ #
+ # CONFIG_ISO9660_FS is not set
+@@ -805,15 +1106,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ #
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
+ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_TMPFS_POSIX_ACL is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ # CONFIG_CONFIGFS_FS is not set
+-
+-#
+-# Miscellaneous filesystems
+-#
++CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+@@ -821,14 +1120,47 @@ CONFIG_TMPFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-# CONFIG_JFFS2_FS is not set
+-CONFIG_CRAMFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
+ 
+ #
+ # Partition Types
+@@ -875,9 +1207,7 @@ CONFIG_NLS_ISO8859_15=y
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+ CONFIG_NLS_UTF8=y
+-CONFIG_INSTRUMENTATION=y
+-# CONFIG_PROFILING is not set
+-# CONFIG_MARKERS is not set
++# CONFIG_DLM is not set
+ 
+ #
+ # Kernel hacking
+@@ -885,63 +1215,161 @@ CONFIG_INSTRUMENTATION=y
+ # CONFIG_PRINTK_TIME is not set
+ CONFIG_ENABLE_WARN_DEPRECATED=y
+ CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ # CONFIG_DEBUG_FS is not set
+ # CONFIG_HEADERS_CHECK is not set
+-CONFIG_DEBUG_KERNEL=y
+-# CONFIG_DEBUG_SHIRQ is not set
+-CONFIG_DETECT_SOFTLOCKUP=y
+-CONFIG_SCHED_DEBUG=y
+-# CONFIG_SCHEDSTATS is not set
+-# CONFIG_TIMER_STATS is not set
+-# CONFIG_DEBUG_SLAB is not set
+-# CONFIG_DEBUG_RT_MUTEXES is not set
+-# CONFIG_RT_MUTEX_TESTER is not set
+-# CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_MUTEXES is not set
+-# CONFIG_DEBUG_LOCK_ALLOC is not set
+-# CONFIG_PROVE_LOCKING is not set
+-# CONFIG_LOCK_STAT is not set
+-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+-# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_KERNEL is not set
+ CONFIG_DEBUG_BUGVERBOSE=y
+-CONFIG_DEBUG_INFO=y
+-# CONFIG_DEBUG_VM is not set
+-# CONFIG_DEBUG_LIST is not set
+-# CONFIG_DEBUG_SG is not set
+-CONFIG_FRAME_POINTER=y
+-CONFIG_FORCED_INLINING=y
+-# CONFIG_BOOT_PRINTK_DELAY is not set
+-# CONFIG_RCU_TORTURE_TEST is not set
+-# CONFIG_FAULT_INJECTION is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_CONTEXT_SWITCH_TRACER is not set
++# CONFIG_EVENT_TRACER is not set
++# CONFIG_BOOT_TRACER is not set
++# CONFIG_TRACE_BRANCH_PROFILING is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
+ # CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_ARM_UNWIND=y
+ CONFIG_DEBUG_USER=y
+-# CONFIG_DEBUG_ERRORS is not set
+-CONFIG_DEBUG_LL=y
+-# CONFIG_DEBUG_ICEDCC is not set
+ 
+ #
+ # Security options
+ #
+ # CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
+ # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
+ 
+ #
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
+ # CONFIG_CRC_CCITT is not set
+ # CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
+ # CONFIG_CRC_ITU_T is not set
+ CONFIG_CRC32=y
+ # CONFIG_CRC7 is not set
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+-CONFIG_PLIST=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
+ CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+-- 
+1.5.6.5
+
+From 1dfe61265cf293a1b21aa903759c000ffeb93f6f Mon Sep 17 00:00:00 2001
+From: nferre <nferre at 50fbe906-d41e-0410-8a96-31537896a350>
+Date: Wed, 14 Oct 2009 13:32:04 +0000
+Subject: [PATCH] sound/soc: update soc support to 2.6.32-rc3 alsa
+
+Just copied the 2.6.32-rc3 sound/soc directory to update
+this part of ALSA to 1.0.21.
+
+Beware: all other parts of alsa stay the same.
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
+
+git-svn-id: svn://rfolxts01.rfo.atmel.com/at91_sandbox/linux-2.6.x/branches/linux-2.6.30-at91@11637 50fbe906-d41e-0410-8a96-31537896a350
+---
+ include/sound/ac97_codec.h       |    9 +
+ include/sound/soc-dai.h          |   82 ++--
+ include/sound/soc-dapm.h         |   51 ++-
+ include/sound/soc.h              |   80 ++-
+ sound/soc/Makefile               |    2 +-
+ sound/soc/atmel/Kconfig          |    8 +
+ sound/soc/atmel/Makefile         |    1 +
+ sound/soc/atmel/atmel_ssc_dai.c  |    2 +-
+ sound/soc/atmel/playpaq_wm8510.c |    4 +-
+ sound/soc/atmel/sam9g20_wm8731.c |  174 +-----
+ sound/soc/codecs/Kconfig         |   76 +++
+ sound/soc/codecs/Makefile        |   42 ++
+ sound/soc/codecs/ac97.c          |    4 +-
+ sound/soc/codecs/ad1980.c        |    4 +-
+ sound/soc/codecs/ak4535.c        |   16 -
+ sound/soc/codecs/cs4270.c        |  126 ++++-
+ sound/soc/codecs/ssm2602.c       |   29 +-
+ sound/soc/codecs/tlv320aic23.c   |   16 +-
+ sound/soc/codecs/tlv320aic3x.c   |  244 ++++----
+ sound/soc/codecs/tlv320aic3x.h   |    2 -
+ sound/soc/codecs/twl4030.c       | 1316 ++++++++++++++++++++++++++++----------
+ sound/soc/codecs/twl4030.h       |   45 ++-
+ sound/soc/codecs/uda134x.c       |    6 +-
+ sound/soc/codecs/uda1380.c       |  313 +++++----
+ sound/soc/codecs/uda1380.h       |    8 -
+ sound/soc/codecs/wm8350.c        |   59 ++-
+ sound/soc/codecs/wm8350.h        |    1 +
+ sound/soc/codecs/wm8400.c        |   37 +-
+ sound/soc/codecs/wm8510.c        |  181 ++----
+ sound/soc/codecs/wm8580.c        |  219 +++----
+ sound/soc/codecs/wm8728.c        |  111 +---
+ sound/soc/codecs/wm8731.c        |  222 +++----
+ sound/soc/codecs/wm8750.c        |  154 ++---
+ sound/soc/codecs/wm8753.c        |   52 ++-
+ sound/soc/codecs/wm8900.c        |  355 +++++------
+ sound/soc/codecs/wm8903.c        |  376 ++++++------
+ sound/soc/codecs/wm8971.c        |  127 ++---
+ sound/soc/codecs/wm8990.c        |  200 +++----
+ sound/soc/codecs/wm9705.c        |    6 +-
+ sound/soc/codecs/wm9712.c        |    8 +-
+ sound/soc/codecs/wm9713.c        |   52 +-
+ sound/soc/soc-cache.c            |  258 ++++++++
+ sound/soc/soc-core.c             |  374 ++++++++---
+ sound/soc/soc-dapm.c             |  920 +++++++++++++++++++++------
+ sound/soc/soc-jack.c             |   24 +-
+ 45 files changed, 4030 insertions(+), 2366 deletions(-)
+ create mode 100644 sound/soc/soc-cache.c
+
+diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
+index 251fc1c..3dae3f7 100644
+--- a/include/sound/ac97_codec.h
++++ b/include/sound/ac97_codec.h
+@@ -32,6 +32,9 @@
+ #include "control.h"
+ #include "info.h"
+ 
++/* maximum number of devices on the AC97 bus */
++#define	AC97_BUS_MAX_DEVICES	4
++
+ /*
+  *  AC'97 codec registers
+  */
+@@ -642,4 +645,10 @@ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
+ /* ad hoc AC97 device driver access */
+ extern struct bus_type ac97_bus_type;
+ 
++/* AC97 platform_data adding function */
++static inline void snd_ac97_dev_add_pdata(struct snd_ac97 *ac97, void *data)
++{
++	ac97->dev.platform_data = data;
++}
++
+ #endif /* __SOUND_AC97_CODEC_H */
+diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
+index 1367647..ca24e7f 100644
+--- a/include/sound/soc-dai.h
++++ b/include/sound/soc-dai.h
+@@ -27,9 +27,10 @@ struct snd_pcm_substream;
+ #define SND_SOC_DAIFMT_I2S		0 /* I2S mode */
+ #define SND_SOC_DAIFMT_RIGHT_J		1 /* Right Justified mode */
+ #define SND_SOC_DAIFMT_LEFT_J		2 /* Left Justified mode */
+-#define SND_SOC_DAIFMT_DSP_A		3 /* L data msb after FRM LRC */
+-#define SND_SOC_DAIFMT_DSP_B		4 /* L data msb during FRM LRC */
++#define SND_SOC_DAIFMT_DSP_A		3 /* L data MSB after FRM LRC */
++#define SND_SOC_DAIFMT_DSP_B		4 /* L data MSB during FRM LRC */
+ #define SND_SOC_DAIFMT_AC97		5 /* AC97 */
++#define SND_SOC_DAIFMT_PDM		6 /* Pulse density modulation */
+ 
+ /* left and right justified also known as MSB and LSB respectively */
+ #define SND_SOC_DAIFMT_MSB		SND_SOC_DAIFMT_LEFT_J
+@@ -38,52 +39,34 @@ struct snd_pcm_substream;
+ /*
+  * DAI Clock gating.
+  *
+- * DAI bit clocks can be be gated (disabled) when not the DAI is not
++ * DAI bit clocks can be be gated (disabled) when the DAI is not
+  * sending or receiving PCM data in a frame. This can be used to save power.
+  */
+ #define SND_SOC_DAIFMT_CONT		(0 << 4) /* continuous clock */
+ #define SND_SOC_DAIFMT_GATED		(1 << 4) /* clock is gated */
+ 
+ /*
+- * DAI Left/Right Clocks.
+- *
+- * Specifies whether the DAI can support different samples for similtanious
+- * playback and capture. This usually requires a seperate physical frame
+- * clock for playback and capture.
+- */
+-#define SND_SOC_DAIFMT_SYNC		(0 << 5) /* Tx FRM = Rx FRM */
+-#define SND_SOC_DAIFMT_ASYNC		(1 << 5) /* Tx FRM ~ Rx FRM */
+-
+-/*
+- * TDM
+- *
+- * Time Division Multiplexing. Allows PCM data to be multplexed with other
+- * data on the DAI.
+- */
+-#define SND_SOC_DAIFMT_TDM		(1 << 6)
+-
+-/*
+  * DAI hardware signal inversions.
+  *
+  * Specifies whether the DAI can also support inverted clocks for the specified
+  * format.
+  */
+ #define SND_SOC_DAIFMT_NB_NF		(0 << 8) /* normal bit clock + frame */
+-#define SND_SOC_DAIFMT_NB_IF		(1 << 8) /* normal bclk + inv frm */
+-#define SND_SOC_DAIFMT_IB_NF		(2 << 8) /* invert bclk + nor frm */
+-#define SND_SOC_DAIFMT_IB_IF		(3 << 8) /* invert bclk + frm */
++#define SND_SOC_DAIFMT_NB_IF		(1 << 8) /* normal BCLK + inv FRM */
++#define SND_SOC_DAIFMT_IB_NF		(2 << 8) /* invert BCLK + nor FRM */
++#define SND_SOC_DAIFMT_IB_IF		(3 << 8) /* invert BCLK + FRM */
+ 
+ /*
+  * DAI hardware clock masters.
+  *
+  * This is wrt the codec, the inverse is true for the interface
+- * i.e. if the codec is clk and frm master then the interface is
++ * i.e. if the codec is clk and FRM master then the interface is
+  * clk and frame slave.
+  */
+-#define SND_SOC_DAIFMT_CBM_CFM		(0 << 12) /* codec clk & frm master */
+-#define SND_SOC_DAIFMT_CBS_CFM		(1 << 12) /* codec clk slave & frm master */
++#define SND_SOC_DAIFMT_CBM_CFM		(0 << 12) /* codec clk & FRM master */
++#define SND_SOC_DAIFMT_CBS_CFM		(1 << 12) /* codec clk slave & FRM master */
+ #define SND_SOC_DAIFMT_CBM_CFS		(2 << 12) /* codec clk master & frame slave */
+-#define SND_SOC_DAIFMT_CBS_CFS		(3 << 12) /* codec clk & frm slave */
++#define SND_SOC_DAIFMT_CBS_CFS		(3 << 12) /* codec clk & FRM slave */
+ 
+ #define SND_SOC_DAIFMT_FORMAT_MASK	0x000f
+ #define SND_SOC_DAIFMT_CLOCK_MASK	0x00f0
+@@ -96,6 +79,16 @@ struct snd_pcm_substream;
+ #define SND_SOC_CLOCK_IN		0
+ #define SND_SOC_CLOCK_OUT		1
+ 
++#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S8 |\
++			       SNDRV_PCM_FMTBIT_S16_LE |\
++			       SNDRV_PCM_FMTBIT_S16_BE |\
++			       SNDRV_PCM_FMTBIT_S20_3LE |\
++			       SNDRV_PCM_FMTBIT_S20_3BE |\
++			       SNDRV_PCM_FMTBIT_S24_3LE |\
++			       SNDRV_PCM_FMTBIT_S24_3BE |\
++                               SNDRV_PCM_FMTBIT_S32_LE |\
++                               SNDRV_PCM_FMTBIT_S32_BE)
++
+ struct snd_soc_dai_ops;
+ struct snd_soc_dai;
+ struct snd_ac97_bus_ops;
+@@ -114,13 +107,17 @@ int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
+ 	int div_id, int div);
+ 
+ int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
+-	int pll_id, unsigned int freq_in, unsigned int freq_out);
++	int pll_id, int source, unsigned int freq_in, unsigned int freq_out);
+ 
+ /* Digital Audio interface formatting */
+ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
+ 
+ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
+-	unsigned int mask, int slots);
++	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width);
++
++int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
++	unsigned int tx_num, unsigned int *tx_slot,
++	unsigned int rx_num, unsigned int *rx_slot);
+ 
+ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
+ 
+@@ -130,12 +127,12 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
+ /*
+  * Digital Audio Interface.
+  *
+- * Describes the Digital Audio Interface in terms of it's ALSA, DAI and AC97
+- * operations an capabilities. Codec and platfom drivers will register a this
++ * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
++ * operations and capabilities. Codec and platform drivers will register this
+  * structure for every DAI they have.
+  *
+  * This structure covers the clocking, formating and ALSA operations for each
+- * interface a
++ * interface.
+  */
+ struct snd_soc_dai_ops {
+ 	/*
+@@ -144,8 +141,8 @@ struct snd_soc_dai_ops {
+ 	 */
+ 	int (*set_sysclk)(struct snd_soc_dai *dai,
+ 		int clk_id, unsigned int freq, int dir);
+-	int (*set_pll)(struct snd_soc_dai *dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out);
++	int (*set_pll)(struct snd_soc_dai *dai, int pll_id, int source,
++		unsigned int freq_in, unsigned int freq_out);
+ 	int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
+ 
+ 	/*
+@@ -154,7 +151,11 @@ struct snd_soc_dai_ops {
+ 	 */
+ 	int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
+ 	int (*set_tdm_slot)(struct snd_soc_dai *dai,
+-		unsigned int mask, int slots);
++		unsigned int tx_mask, unsigned int rx_mask,
++		int slots, int slot_width);
++	int (*set_channel_map)(struct snd_soc_dai *dai,
++		unsigned int tx_num, unsigned int *tx_slot,
++		unsigned int rx_num, unsigned int *rx_slot);
+ 	int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
+ 
+ 	/*
+@@ -193,6 +194,7 @@ struct snd_soc_dai {
+ 	int ac97_control;
+ 
+ 	struct device *dev;
++	void *ac97_pdata;	/* platform_data for the ac97 codec */
+ 
+ 	/* DAI callbacks */
+ 	int (*probe)(struct platform_device *pdev,
+@@ -208,6 +210,7 @@ struct snd_soc_dai {
+ 	/* DAI capabilities */
+ 	struct snd_soc_pcm_stream capture;
+ 	struct snd_soc_pcm_stream playback;
++	unsigned int symmetric_rates:1;
+ 
+ 	/* DAI runtime info */
+ 	struct snd_pcm_runtime *runtime;
+@@ -219,11 +222,8 @@ struct snd_soc_dai {
+ 	/* DAI private data */
+ 	void *private_data;
+ 
+-	/* parent codec/platform */
+-	union {
+-		struct snd_soc_codec *codec;
+-		struct snd_soc_platform *platform;
+-	};
++	/* parent platform */
++	struct snd_soc_platform *platform;
+ 
+ 	struct list_head list;
+ };
+diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
+index a7def6a..c5c95e1 100644
+--- a/include/sound/soc-dapm.h
++++ b/include/sound/soc-dapm.h
+@@ -137,19 +137,39 @@
+ 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
+ 
+ /* stream domain */
++#define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
++{	.id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
++	.reg = wreg, .shift = wshift, .invert = winvert }
++#define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
++{	.id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
++	.reg = wreg, .shift = wshift, .invert = winvert }
+ #define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
+ {	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
+ 	.shift = wshift, .invert = winvert}
++#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
++			   wevent, wflags)				\
++{	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
++	.shift = wshift, .invert = winvert, \
++	.event = wevent, .event_flags = wflags}
+ #define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
+ {	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
+ 	.shift = wshift, .invert = winvert}
++#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
++			   wevent, wflags)				\
++{	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
++	.shift = wshift, .invert = winvert, \
++	.event = wevent, .event_flags = wflags}
+ 
+-/* generic register modifier widget */
++/* generic widgets */
+ #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
+ {	.id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
+ 	.reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
+ 	.on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
+ 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
++#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
++{	.id = snd_soc_dapm_supply, .name = wname, .reg = wreg,	\
++	.shift = wshift, .invert = winvert, .event = wevent, \
++	.event_flags = wflags}
+ 
+ /* dapm kcontrol types */
+ #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
+@@ -186,6 +206,12 @@
+  	.get = snd_soc_dapm_get_enum_double, \
+  	.put = snd_soc_dapm_put_enum_double, \
+   	.private_value = (unsigned long)&xenum }
++#define SOC_DAPM_ENUM_VIRT(xname, xenum)		    \
++{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
++	.info = snd_soc_info_enum_double, \
++	.get = snd_soc_dapm_get_enum_virt, \
++	.put = snd_soc_dapm_put_enum_virt, \
++	.private_value = (unsigned long)&xenum }
+ #define SOC_DAPM_VALUE_ENUM(xname, xenum) \
+ {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ 	.info = snd_soc_info_enum_double, \
+@@ -240,6 +266,10 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
+ 	struct snd_ctl_elem_value *ucontrol);
+ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
+ 	struct snd_ctl_elem_value *ucontrol);
++int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol);
++int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol);
+ int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
+ 	struct snd_ctl_elem_value *ucontrol);
+ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
+@@ -265,11 +295,11 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
+ /* dapm events */
+ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
+ 	int event);
+-int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
+-	enum snd_soc_bias_level level);
++void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);
+ 
+ /* dapm sys fs - used by the core */
+ int snd_soc_dapm_sys_add(struct device *dev);
++void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
+ 
+ /* dapm audio pin control and status */
+ int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
+@@ -298,6 +328,9 @@ enum snd_soc_dapm_type {
+ 	snd_soc_dapm_vmid,			/* codec bias/vmid - to minimise pops */
+ 	snd_soc_dapm_pre,			/* machine specific pre widget - exec first */
+ 	snd_soc_dapm_post,			/* machine specific post widget - exec last */
++	snd_soc_dapm_supply,		/* power/clock supply */
++	snd_soc_dapm_aif_in,		/* audio interface input */
++	snd_soc_dapm_aif_out,		/* audio interface output */
+ };
+ 
+ /*
+@@ -310,6 +343,10 @@ struct snd_soc_dapm_route {
+ 	const char *sink;
+ 	const char *control;
+ 	const char *source;
++
++	/* Note: currently only supported for links where source is a supply */
++	int (*connected)(struct snd_soc_dapm_widget *source,
++			 struct snd_soc_dapm_widget *sink);
+ };
+ 
+ /* dapm audio path between two widgets */
+@@ -326,6 +363,9 @@ struct snd_soc_dapm_path {
+ 	u32 connect:1;	/* source and sink widgets are connected */
+ 	u32 walked:1;	/* path has been walked */
+ 
++	int (*connected)(struct snd_soc_dapm_widget *source,
++			 struct snd_soc_dapm_widget *sink);
++
+ 	struct list_head list_source;
+ 	struct list_head list_sink;
+ 	struct list_head list;
+@@ -357,6 +397,8 @@ struct snd_soc_dapm_widget {
+ 	unsigned char suspend:1;		/* was active before suspend */
+ 	unsigned char pmdown:1;			/* waiting for timeout */
+ 
++	int (*power_check)(struct snd_soc_dapm_widget *w);
++
+ 	/* external events */
+ 	unsigned short event_flags;		/* flags to specify event types */
+ 	int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int);
+@@ -368,6 +410,9 @@ struct snd_soc_dapm_widget {
+ 	/* widget input and outputs */
+ 	struct list_head sources;
+ 	struct list_head sinks;
++
++	/* used during DAPM updates */
++	struct list_head power_list;
+ };
+ 
+ #endif
+diff --git a/include/sound/soc.h b/include/sound/soc.h
+index a40bc6f..0b1f917 100644
+--- a/include/sound/soc.h
++++ b/include/sound/soc.h
+@@ -118,6 +118,14 @@
+ 	.info = snd_soc_info_volsw, \
+ 	.get = xhandler_get, .put = xhandler_put, \
+ 	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
++#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\
++	 xhandler_get, xhandler_put) \
++{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
++	.info = snd_soc_info_volsw, \
++	.get = xhandler_get, .put = xhandler_put, \
++	.private_value = (unsigned long)&(struct soc_mixer_control) \
++		{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
++		 .max = xmax, .invert = xinvert} }
+ #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
+ 	 xhandler_get, xhandler_put, tlv_array) \
+ {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+@@ -127,6 +135,28 @@
+ 	.info = snd_soc_info_volsw, \
+ 	.get = xhandler_get, .put = xhandler_put, \
+ 	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
++#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
++	 xhandler_get, xhandler_put, tlv_array) \
++{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
++	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
++		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
++	.tlv.p = (tlv_array), \
++	.info = snd_soc_info_volsw, \
++	.get = xhandler_get, .put = xhandler_put, \
++	.private_value = (unsigned long)&(struct soc_mixer_control) \
++		{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
++		.max = xmax, .invert = xinvert} }
++#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
++	 xhandler_get, xhandler_put, tlv_array) \
++{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
++	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
++		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
++	.tlv.p = (tlv_array), \
++	.info = snd_soc_info_volsw_2r, \
++	.get = xhandler_get, .put = xhandler_put, \
++	.private_value = (unsigned long)&(struct soc_mixer_control) \
++		{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
++		.max = xmax, .invert = xinvert} }
+ #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
+ {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ 	.info = snd_soc_info_bool_ext, \
+@@ -175,14 +205,28 @@ struct snd_soc_jack_gpio;
+ #endif
+ 
+ typedef int (*hw_write_t)(void *,const char* ,int);
+-typedef int (*hw_read_t)(void *,char* ,int);
+ 
+ extern struct snd_ac97_bus_ops soc_ac97_ops;
+ 
++enum snd_soc_control_type {
++	SND_SOC_CUSTOM,
++	SND_SOC_I2C,
++	SND_SOC_SPI,
++};
++
+ int snd_soc_register_platform(struct snd_soc_platform *platform);
+ void snd_soc_unregister_platform(struct snd_soc_platform *platform);
+ int snd_soc_register_codec(struct snd_soc_codec *codec);
+ void snd_soc_unregister_codec(struct snd_soc_codec *codec);
++int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
++int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
++			       int addr_bits, int data_bits,
++			       enum snd_soc_control_type control);
++
++#ifdef CONFIG_PM
++int snd_soc_suspend_device(struct device *dev);
++int snd_soc_resume_device(struct device *dev);
++#endif
+ 
+ /* pcm <-> DAI connect */
+ void snd_soc_free_pcms(struct snd_soc_device *socdev);
+@@ -206,15 +250,11 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
+ 			struct snd_soc_jack_gpio *gpios);
+ #endif
+ 
+-/* codec IO */
+-#define snd_soc_read(codec, reg) codec->read(codec, reg)
+-#define snd_soc_write(codec, reg, value) codec->write(codec, reg, value)
+-
+ /* codec register bit access */
+ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
+-				unsigned short mask, unsigned short value);
++				unsigned int mask, unsigned int value);
+ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
+-				unsigned short mask, unsigned short value);
++				unsigned int mask, unsigned int value);
+ 
+ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+ 	struct snd_ac97_bus_ops *ops, int num);
+@@ -331,6 +371,7 @@ struct snd_soc_codec {
+ 	struct module *owner;
+ 	struct mutex mutex;
+ 	struct device *dev;
++	struct snd_soc_device *socdev;
+ 
+ 	struct list_head list;
+ 
+@@ -351,8 +392,10 @@ struct snd_soc_codec {
+ 	int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
+ 	int (*display_register)(struct snd_soc_codec *, char *,
+ 				size_t, unsigned int);
++	int (*volatile_register)(unsigned int);
++	int (*readable_register)(unsigned int);
+ 	hw_write_t hw_write;
+-	hw_read_t hw_read;
++	unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
+ 	void *reg_cache;
+ 	short reg_cache_size;
+ 	short reg_cache_step;
+@@ -370,8 +413,10 @@ struct snd_soc_codec {
+ 	unsigned int num_dai;
+ 
+ #ifdef CONFIG_DEBUG_FS
++	struct dentry *debugfs_codec_root;
+ 	struct dentry *debugfs_reg;
+ 	struct dentry *debugfs_pop_time;
++	struct dentry *debugfs_dapm;
+ #endif
+ };
+ 
+@@ -417,6 +462,12 @@ struct snd_soc_dai_link  {
+ 	/* codec/machine specific init - e.g. add machine controls */
+ 	int (*init)(struct snd_soc_codec *codec);
+ 
++	/* Symmetry requirements */
++	unsigned int symmetric_rates:1;
++
++	/* Symmetry data - only valid if symmetry is being enforced */
++	unsigned int rate;
++
+ 	/* DAI pcm */
+ 	struct snd_pcm *pcm;
+ };
+@@ -490,6 +541,19 @@ struct soc_enum {
+ 	void *dapm;
+ };
+ 
++/* codec IO */
++static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
++					unsigned int reg)
++{
++	return codec->read(codec, reg);
++}
++
++static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
++					 unsigned int reg, unsigned int val)
++{
++	return codec->write(codec, reg, val);
++}
++
+ #include <sound/soc-dai.h>
+ 
+ #endif
+diff --git a/sound/soc/Makefile b/sound/soc/Makefile
+index 0237879..b7aeb44 100644
+--- a/sound/soc/Makefile
++++ b/sound/soc/Makefile
+@@ -1,4 +1,4 @@
+-snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o
++snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o
+ 
+ obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
+ obj-$(CONFIG_SND_SOC)	+= codecs/
+diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
+index a608d70..e720d5e 100644
+--- a/sound/soc/atmel/Kconfig
++++ b/sound/soc/atmel/Kconfig
+@@ -41,3 +41,11 @@ config SND_AT32_SOC_PLAYPAQ_SLAVE
+           and FRAME signals on the PlayPaq.  Unless you want to play
+           with the AT32 as the SSC master, you probably want to say N here,
+           as this will give you better sound quality.
++
++config SND_AT91_SOC_AFEB9260
++	tristate "SoC Audio support for AFEB9260 board"
++	depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
++	select SND_ATMEL_SOC_SSC
++	select SND_SOC_TLV320AIC23
++	help
++	  Say Y here to support sound on AFEB9260 board.
+diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
+index f54a7cc..e7ea56b 100644
+--- a/sound/soc/atmel/Makefile
++++ b/sound/soc/atmel/Makefile
+@@ -13,3 +13,4 @@ snd-soc-playpaq-objs := playpaq_wm8510.o
+ 
+ obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
+ obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
++obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
+diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
+index e588e63..7e78e02 100644
+--- a/sound/soc/atmel/atmel_ssc_dai.c
++++ b/sound/soc/atmel/atmel_ssc_dai.c
+@@ -427,7 +427,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
+ 			| SSC_BF(RCMR_STTDLY, START_DELAY)
+ 			| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
+ 			| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
+-			| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
++			| SSC_BF(RCMR_CKO, SSC_CKO_CONTINUOUS)
+ 			| SSC_BF(RCMR_CKS, SSC_CKS_DIV);
+ 
+ 		rfmr =	  SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
+index 7065753..9df4c68 100644
+--- a/sound/soc/atmel/playpaq_wm8510.c
++++ b/sound/soc/atmel/playpaq_wm8510.c
+@@ -117,7 +117,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
+ 	 * Find actual rate, compare to requested rate
+ 	 */
+ 	actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1));
+-	pr_debug("playpaq_wm8510: Request rate = %d, actual rate = %d\n",
++	pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n",
+ 		 rate, actual_rate);
+ 
+ 
+@@ -268,7 +268,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
+ #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
+ 
+ 
+-	ret = snd_soc_dai_set_pll(codec_dai, 0,
++	ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
+ 					 clk_get_rate(CODEC_CLK), pll_out);
+ 	if (ret < 0) {
+ 		pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
+diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
+index 173a239..948d7ed 100644
+--- a/sound/soc/atmel/sam9g20_wm8731.c
++++ b/sound/soc/atmel/sam9g20_wm8731.c
+@@ -56,133 +56,32 @@
+ 
+ #define MCLK_RATE 12000000
+ 
++/*
++ * As shipped the board does not have inputs.  However, it is relatively
++ * straightforward to modify the board to hook them up so support is left
++ * in the driver.
++ */
++#undef ENABLE_MIC_INPUT
++#define ENABLE_MIC_INPUT 1
+ static struct clk *mclk;
+ 
+-static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
+-{
+-	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+-	int ret;
+-
+-	ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
+-		MCLK_RATE, SND_SOC_CLOCK_IN);
+-	if (ret < 0) {
+-		clk_disable(mclk);
+-		return ret;
+-	}
+-
+-	return 0;
+-}
+-
+-static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
+-{
+-	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+-
+-	dev_dbg(rtd->socdev->dev, "shutdown");
+-}
+-
+ static int at91sam9g20ek_hw_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 *codec_dai = rtd->dai->codec_dai;
+ 	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+-	struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
+-	struct ssc_device *ssc = ssc_p->ssc;
+ 	int ret;
+ 
+-	unsigned int rate;
+-	int cmr_div, period;
+-
+-	if (ssc == NULL) {
+-		printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
+-		return -EINVAL;
+-	}
+-
+ 	/* set codec DAI configuration */
+ 	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
++		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ 	if (ret < 0)
+ 		return ret;
+ 
+ 	/* set cpu DAI configuration */
+ 	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+-	if (ret < 0)
+-		return ret;
+-
+-	/*
+-	 * The SSC clock dividers depend on the sample rate.  The CMR.DIV
+-	 * field divides the system master clock MCK to drive the SSC TK
+-	 * signal which provides the codec BCLK.  The TCMR.PERIOD and
+-	 * RCMR.PERIOD fields further divide the BCLK signal to drive
+-	 * the SSC TF and RF signals which provide the codec DACLRC and
+-	 * ADCLRC clocks.
+-	 *
+-	 * The dividers were determined through trial and error, where a
+-	 * CMR.DIV value is chosen such that the resulting BCLK value is
+-	 * divisible, or almost divisible, by (2 * sample rate), and then
+-	 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
+-	 */
+-	rate = params_rate(params);
+-
+-	switch (rate) {
+-	case 8000:
+-		cmr_div = 55;	/* BCLK = 133MHz/(2*55) = 1.209MHz */
+-		period = 74;	/* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
+-		break;
+-	case 11025:
+-		cmr_div = 67;	/* BCLK = 133MHz/(2*60) = 1.108MHz */
+-		period = 45;	/* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
+-		break;
+-	case 16000:
+-		cmr_div = 63;	/* BCLK = 133MHz/(2*63) = 1.055MHz */
+-		period = 32;	/* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
+-		break;
+-	case 22050:
+-		cmr_div = 52;	/* BCLK = 133MHz/(2*52) = 1.278MHz */
+-		period = 28;	/* LRC = BCLK/(2*(28+1)) = 22049Hz */
+-		break;
+-	case 32000:
+-		cmr_div = 66;	/* BCLK = 133MHz/(2*66) = 1.007MHz */
+-		period = 15;	/* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
+-		break;
+-	case 44100:
+-		cmr_div = 29;	/* BCLK = 133MHz/(2*29) = 2.293MHz */
+-		period = 25;	/* LRC = BCLK/(2*(25+1)) = 44098Hz */
+-		break;
+-	case 48000:
+-		cmr_div = 33;	/* BCLK = 133MHz/(2*33) = 2.015MHz */
+-		period = 20;	/* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
+-		break;
+-	case 88200:
+-		cmr_div = 29;	/* BCLK = 133MHz/(2*29) = 2.293MHz */
+-		period = 12;	/* LRC = BCLK/(2*(12+1)) = 88196Hz */
+-		break;
+-	case 96000:
+-		cmr_div = 23;	/* BCLK = 133MHz/(2*23) = 2.891MHz */
+-		period = 14;	/* LRC = BCLK/(2*(14+1)) = 96376Hz */
+-		break;
+-	default:
+-		printk(KERN_WARNING "unsupported rate %d"
+-				" on at91sam9g20ek board\n", rate);
+-		return -EINVAL;
+-	}
+-
+-	/* set the MCK divider for BCLK */
+-	ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
+-	if (ret < 0)
+-		return ret;
+-
+-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+-		/* set the BCLK divider for DACLRC */
+-		ret = snd_soc_dai_set_clkdiv(cpu_dai,
+-						ATMEL_SSC_TCMR_PERIOD, period);
+-	} else {
+-		/* set the BCLK divider for ADCLRC */
+-		ret = snd_soc_dai_set_clkdiv(cpu_dai,
+-						ATMEL_SSC_RCMR_PERIOD, period);
+-	}
++		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ 	if (ret < 0)
+ 		return ret;
+ 
+@@ -190,9 +89,7 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
+ }
+ 
+ static struct snd_soc_ops at91sam9g20ek_ops = {
+-	.startup = at91sam9g20ek_startup,
+ 	.hw_params = at91sam9g20ek_hw_params,
+-	.shutdown = at91sam9g20ek_shutdown,
+ };
+ 
+ static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
+@@ -241,10 +138,20 @@ static const struct snd_soc_dapm_route intercon[] = {
+  */
+ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
+ {
++	struct snd_soc_dai *codec_dai = &codec->dai[0];
++	int ret;
++
+ 	printk(KERN_DEBUG
+ 			"at91sam9g20ek_wm8731 "
+ 			": at91sam9g20ek_wm8731_init() called\n");
+ 
++	ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
++		MCLK_RATE, SND_SOC_CLOCK_IN);
++	if (ret < 0) {
++		printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
++		return ret;
++	}
++
+ 	/* Add specific widgets */
+ 	snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
+ 				  ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
+@@ -255,8 +162,13 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
+ 	snd_soc_dapm_nc_pin(codec, "RLINEIN");
+ 	snd_soc_dapm_nc_pin(codec, "LLINEIN");
+ 
+-	/* always connected */
++#ifdef ENABLE_MIC_INPUT
+ 	snd_soc_dapm_enable_pin(codec, "Int Mic");
++#else
++	snd_soc_dapm_nc_pin(codec, "Int Mic");
++#endif
++
++	/* always connected */
+ 	snd_soc_dapm_enable_pin(codec, "Ext Spk");
+ 
+ 	snd_soc_dapm_sync(codec);
+@@ -281,38 +193,6 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
+ 	.set_bias_level = at91sam9g20ek_set_bias_level,
+ };
+ 
+-/*
+- * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
+- * New drivers should register the wm8731 I2C device in the machine
+- * setup code (under arch/arm for ARM systems).
+- */
+-static int wm8731_i2c_register(void)
+-{
+-	struct i2c_board_info info;
+-	struct i2c_adapter *adapter;
+-	struct i2c_client *client;
+-
+-	memset(&info, 0, sizeof(struct i2c_board_info));
+-	info.addr = 0x1b;
+-	strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
+-
+-	adapter = i2c_get_adapter(0);
+-	if (!adapter) {
+-		printk(KERN_ERR "can't get i2c adapter 0\n");
+-		return -ENODEV;
+-	}
+-
+-	client = i2c_new_device(adapter, &info);
+-	i2c_put_adapter(adapter);
+-	if (!client) {
+-		printk(KERN_ERR "can't add i2c device at 0x%x\n",
+-			(unsigned int)info.addr);
+-		return -ENODEV;
+-	}
+-
+-	return 0;
+-}
+-
+ static struct snd_soc_device at91sam9g20ek_snd_devdata = {
+ 	.card = &snd_soc_at91sam9g20ek,
+ 	.codec_dev = &soc_codec_dev_wm8731,
+@@ -367,10 +247,6 @@ static int __init at91sam9g20ek_init(void)
+ 	}
+ 	ssc_p->ssc = ssc;
+ 
+-	ret = wm8731_i2c_register();
+-	if (ret != 0)
+-		goto err_ssc;
+-
+ 	at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
+ 	if (!at91sam9g20ek_snd_device) {
+ 		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index b6c7f7a..3c46f34 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -12,13 +12,20 @@ config SND_SOC_ALL_CODECS
+ 	tristate "Build all ASoC CODEC drivers"
+ 	select SND_SOC_L3
+ 	select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
++	select SND_SOC_AD1836 if SPI_MASTER
++	select SND_SOC_AD1938 if SPI_MASTER
+ 	select SND_SOC_AD1980 if SND_SOC_AC97_BUS
+ 	select SND_SOC_AD73311 if I2C
+ 	select SND_SOC_AK4104 if SPI_MASTER
+ 	select SND_SOC_AK4535 if I2C
++	select SND_SOC_AK4642 if I2C
++	select SND_SOC_AK4671 if I2C
+ 	select SND_SOC_CS4270 if I2C
++	select SND_SOC_MAX9877 if I2C
+ 	select SND_SOC_PCM3008
++	select SND_SOC_SPDIF
+ 	select SND_SOC_SSM2602 if I2C
++	select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
+ 	select SND_SOC_TLV320AIC23 if I2C
+ 	select SND_SOC_TLV320AIC26 if SPI_MASTER
+ 	select SND_SOC_TLV320AIC3X if I2C
+@@ -28,15 +35,25 @@ config SND_SOC_ALL_CODECS
+ 	select SND_SOC_WM8350 if MFD_WM8350
+ 	select SND_SOC_WM8400 if MFD_WM8400
+ 	select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
++	select SND_SOC_WM8523 if I2C
+ 	select SND_SOC_WM8580 if I2C
++	select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
++	select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_WM8900 if I2C
+ 	select SND_SOC_WM8903 if I2C
++	select SND_SOC_WM8940 if I2C
++	select SND_SOC_WM8960 if I2C
++	select SND_SOC_WM8961 if I2C
+ 	select SND_SOC_WM8971 if I2C
++	select SND_SOC_WM8974 if I2C
++	select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
+ 	select SND_SOC_WM8990 if I2C
++	select SND_SOC_WM8993 if I2C
++	select SND_SOC_WM9081 if I2C
+ 	select SND_SOC_WM9705 if SND_SOC_AC97_BUS
+ 	select SND_SOC_WM9712 if SND_SOC_AC97_BUS
+ 	select SND_SOC_WM9713 if SND_SOC_AC97_BUS
+@@ -51,11 +68,21 @@ config SND_SOC_ALL_CODECS
+ 
+           If unsure select "N".
+ 
++config SND_SOC_WM_HUBS
++	tristate
++	default y if SND_SOC_WM8993=y
++	default m if SND_SOC_WM8993=m
+ 
+ config SND_SOC_AC97_CODEC
+ 	tristate
+ 	select SND_AC97_CODEC
+ 
++config SND_SOC_AD1836
++	tristate
++
++config SND_SOC_AD1938
++	tristate
++
+ config SND_SOC_AD1980
+ 	tristate
+ 
+@@ -68,6 +95,12 @@ config SND_SOC_AK4104
+ config SND_SOC_AK4535
+ 	tristate
+ 
++config SND_SOC_AK4642
++	tristate
++
++config SND_SOC_AK4671
++	tristate
++
+ # Cirrus Logic CS4270 Codec
+ config SND_SOC_CS4270
+ 	tristate
+@@ -80,15 +113,24 @@ config SND_SOC_CS4270_VD33_ERRATA
+ 	bool
+ 	depends on SND_SOC_CS4270
+ 
++config SND_SOC_CX20442
++	tristate
++
+ config SND_SOC_L3
+        tristate
+ 
+ config SND_SOC_PCM3008
+        tristate
+ 
++config SND_SOC_SPDIF
++	tristate
++
+ config SND_SOC_SSM2602
+ 	tristate
+ 
++config SND_SOC_STAC9766
++	tristate
++
+ config SND_SOC_TLV320AIC23
+ 	tristate
+ 
+@@ -117,9 +159,15 @@ config SND_SOC_WM8400
+ config SND_SOC_WM8510
+ 	tristate
+ 
++config SND_SOC_WM8523
++	tristate
++
+ config SND_SOC_WM8580
+ 	tristate
+ 
++config SND_SOC_WM8711
++	tristate
++
+ config SND_SOC_WM8728
+ 	tristate
+ 
+@@ -132,18 +180,42 @@ config SND_SOC_WM8750
+ config SND_SOC_WM8753
+ 	tristate
+ 
++config SND_SOC_WM8776
++	tristate
++
+ config SND_SOC_WM8900
+ 	tristate
+ 
+ config SND_SOC_WM8903
+ 	tristate
+ 
++config SND_SOC_WM8940
++        tristate
++
++config SND_SOC_WM8960
++	tristate
++
++config SND_SOC_WM8961
++	tristate
++
+ config SND_SOC_WM8971
+ 	tristate
+ 
++config SND_SOC_WM8974
++	tristate
++
++config SND_SOC_WM8988
++	tristate
++
+ config SND_SOC_WM8990
+ 	tristate
+ 
++config SND_SOC_WM8993
++	tristate
++
++config SND_SOC_WM9081
++	tristate
++
+ config SND_SOC_WM9705
+ 	tristate
+ 
+@@ -152,3 +224,7 @@ config SND_SOC_WM9712
+ 
+ config SND_SOC_WM9713
+ 	tristate
++
++# Amp
++config SND_SOC_MAX9877
++	tristate
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index f265380..fc1c458 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -1,12 +1,19 @@
+ snd-soc-ac97-objs := ac97.o
++snd-soc-ad1836-objs := ad1836.o
++snd-soc-ad1938-objs := ad1938.o
+ snd-soc-ad1980-objs := ad1980.o
+ snd-soc-ad73311-objs := ad73311.o
+ snd-soc-ak4104-objs := ak4104.o
+ snd-soc-ak4535-objs := ak4535.o
++snd-soc-ak4642-objs := ak4642.o
++snd-soc-ak4671-objs := ak4671.o
+ snd-soc-cs4270-objs := cs4270.o
++snd-soc-cx20442-objs := cx20442.o
+ snd-soc-l3-objs := l3.o
+ snd-soc-pcm3008-objs := pcm3008.o
++snd-soc-spdif-objs := spdif_transciever.o
+ snd-soc-ssm2602-objs := ssm2602.o
++snd-soc-stac9766-objs := stac9766.o
+ snd-soc-tlv320aic23-objs := tlv320aic23.o
+ snd-soc-tlv320aic26-objs := tlv320aic26.o
+ snd-soc-tlv320aic3x-objs := tlv320aic3x.o
+@@ -16,28 +23,49 @@ snd-soc-uda1380-objs := uda1380.o
+ snd-soc-wm8350-objs := wm8350.o
+ snd-soc-wm8400-objs := wm8400.o
+ snd-soc-wm8510-objs := wm8510.o
++snd-soc-wm8523-objs := wm8523.o
+ snd-soc-wm8580-objs := wm8580.o
++snd-soc-wm8711-objs := wm8711.o
+ snd-soc-wm8728-objs := wm8728.o
+ snd-soc-wm8731-objs := wm8731.o
+ snd-soc-wm8750-objs := wm8750.o
+ snd-soc-wm8753-objs := wm8753.o
++snd-soc-wm8776-objs := wm8776.o
+ snd-soc-wm8900-objs := wm8900.o
+ snd-soc-wm8903-objs := wm8903.o
++snd-soc-wm8940-objs := wm8940.o
++snd-soc-wm8960-objs := wm8960.o
++snd-soc-wm8961-objs := wm8961.o
+ snd-soc-wm8971-objs := wm8971.o
++snd-soc-wm8974-objs := wm8974.o
++snd-soc-wm8988-objs := wm8988.o
+ snd-soc-wm8990-objs := wm8990.o
++snd-soc-wm8993-objs := wm8993.o
++snd-soc-wm9081-objs := wm9081.o
+ snd-soc-wm9705-objs := wm9705.o
+ snd-soc-wm9712-objs := wm9712.o
+ snd-soc-wm9713-objs := wm9713.o
++snd-soc-wm-hubs-objs := wm_hubs.o
++
++# Amp
++snd-soc-max9877-objs := max9877.o
+ 
+ obj-$(CONFIG_SND_SOC_AC97_CODEC)	+= snd-soc-ac97.o
++obj-$(CONFIG_SND_SOC_AD1836)	+= snd-soc-ad1836.o
++obj-$(CONFIG_SND_SOC_AD1938)	+= snd-soc-ad1938.o
+ obj-$(CONFIG_SND_SOC_AD1980)	+= snd-soc-ad1980.o
+ obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
+ obj-$(CONFIG_SND_SOC_AK4104)	+= snd-soc-ak4104.o
+ obj-$(CONFIG_SND_SOC_AK4535)	+= snd-soc-ak4535.o
++obj-$(CONFIG_SND_SOC_AK4642)	+= snd-soc-ak4642.o
++obj-$(CONFIG_SND_SOC_AK4671)	+= snd-soc-ak4671.o
+ obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o
++obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
+ obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o
+ obj-$(CONFIG_SND_SOC_PCM3008)	+= snd-soc-pcm3008.o
++obj-$(CONFIG_SND_SOC_SPDIF)	+= snd-soc-spdif.o
+ obj-$(CONFIG_SND_SOC_SSM2602)	+= snd-soc-ssm2602.o
++obj-$(CONFIG_SND_SOC_STAC9766)	+= snd-soc-stac9766.o
+ obj-$(CONFIG_SND_SOC_TLV320AIC23)	+= snd-soc-tlv320aic23.o
+ obj-$(CONFIG_SND_SOC_TLV320AIC26)	+= snd-soc-tlv320aic26.o
+ obj-$(CONFIG_SND_SOC_TLV320AIC3X)	+= snd-soc-tlv320aic3x.o
+@@ -47,15 +75,29 @@ obj-$(CONFIG_SND_SOC_UDA1380)	+= snd-soc-uda1380.o
+ obj-$(CONFIG_SND_SOC_WM8350)	+= snd-soc-wm8350.o
+ obj-$(CONFIG_SND_SOC_WM8400)	+= snd-soc-wm8400.o
+ obj-$(CONFIG_SND_SOC_WM8510)	+= snd-soc-wm8510.o
++obj-$(CONFIG_SND_SOC_WM8523)	+= snd-soc-wm8523.o
+ obj-$(CONFIG_SND_SOC_WM8580)	+= snd-soc-wm8580.o
++obj-$(CONFIG_SND_SOC_WM8711)	+= snd-soc-wm8711.o
+ obj-$(CONFIG_SND_SOC_WM8728)	+= snd-soc-wm8728.o
+ obj-$(CONFIG_SND_SOC_WM8731)	+= snd-soc-wm8731.o
+ obj-$(CONFIG_SND_SOC_WM8750)	+= snd-soc-wm8750.o
+ obj-$(CONFIG_SND_SOC_WM8753)	+= snd-soc-wm8753.o
++obj-$(CONFIG_SND_SOC_WM8776)	+= snd-soc-wm8776.o
+ obj-$(CONFIG_SND_SOC_WM8900)	+= snd-soc-wm8900.o
+ obj-$(CONFIG_SND_SOC_WM8903)	+= snd-soc-wm8903.o
+ obj-$(CONFIG_SND_SOC_WM8971)	+= snd-soc-wm8971.o
++obj-$(CONFIG_SND_SOC_WM8974)	+= snd-soc-wm8974.o
++obj-$(CONFIG_SND_SOC_WM8940)	+= snd-soc-wm8940.o
++obj-$(CONFIG_SND_SOC_WM8960)	+= snd-soc-wm8960.o
++obj-$(CONFIG_SND_SOC_WM8961)	+= snd-soc-wm8961.o
++obj-$(CONFIG_SND_SOC_WM8988)	+= snd-soc-wm8988.o
+ obj-$(CONFIG_SND_SOC_WM8990)	+= snd-soc-wm8990.o
++obj-$(CONFIG_SND_SOC_WM8993)	+= snd-soc-wm8993.o
++obj-$(CONFIG_SND_SOC_WM9081)	+= snd-soc-wm9081.o
+ obj-$(CONFIG_SND_SOC_WM9705)	+= snd-soc-wm9705.o
+ obj-$(CONFIG_SND_SOC_WM9712)	+= snd-soc-wm9712.o
+ obj-$(CONFIG_SND_SOC_WM9713)	+= snd-soc-wm9713.o
++obj-$(CONFIG_SND_SOC_WM_HUBS)	+= snd-soc-wm-hubs.o
++
++# Amp
++obj-$(CONFIG_SND_SOC_MAX9877)	+= snd-soc-max9877.o
+diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
+index b0d4af1..932299b 100644
+--- a/sound/soc/codecs/ac97.c
++++ b/sound/soc/codecs/ac97.c
+@@ -53,13 +53,13 @@ struct snd_soc_dai ac97_dai = {
+ 		.channels_min = 1,
+ 		.channels_max = 2,
+ 		.rates = STD_AC97_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.capture = {
+ 		.stream_name = "AC97 Capture",
+ 		.channels_min = 1,
+ 		.channels_max = 2,
+ 		.rates = STD_AC97_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.ops = &ac97_dai_ops,
+ };
+ EXPORT_SYMBOL_GPL(ac97_dai);
+diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
+index ddb3b08..d7440a9 100644
+--- a/sound/soc/codecs/ad1980.c
++++ b/sound/soc/codecs/ad1980.c
+@@ -137,13 +137,13 @@ struct snd_soc_dai ad1980_dai = {
+ 		.channels_min = 2,
+ 		.channels_max = 6,
+ 		.rates = SNDRV_PCM_RATE_48000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
++		.formats = SND_SOC_STD_AC97_FMTS, },
+ 	.capture = {
+ 		.stream_name = "Capture",
+ 		.channels_min = 2,
+ 		.channels_max = 2,
+ 		.rates = SNDRV_PCM_RATE_48000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
++		.formats = SND_SOC_STD_AC97_FMTS, },
+ };
+ EXPORT_SYMBOL_GPL(ad1980_dai);
+ 
+diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
+index dd33802..0abec0d 100644
+--- a/sound/soc/codecs/ak4535.c
++++ b/sound/soc/codecs/ak4535.c
+@@ -59,21 +59,6 @@ static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
+ 	return cache[reg];
+ }
+ 
+-static inline unsigned int ak4535_read(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u8 data;
+-	data = reg;
+-
+-	if (codec->hw_write(codec->control_data, &data, 1) != 1)
+-		return -EIO;
+-
+-	if (codec->hw_read(codec->control_data, &data, 1) != 1)
+-		return -EIO;
+-
+-	return data;
+-};
+-
+ /*
+  * write ak4535 register cache
+  */
+@@ -635,7 +620,6 @@ static int ak4535_probe(struct platform_device *pdev)
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ 	if (setup->i2c_address) {
+ 		codec->hw_write = (hw_write_t)i2c_master_send;
+-		codec->hw_read = (hw_read_t)i2c_master_recv;
+ 		ret = ak4535_add_i2c_device(pdev, setup);
+ 	}
+ #endif
+diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
+index 7fa09a3..ca1e24a 100644
+--- a/sound/soc/codecs/cs4270.c
++++ b/sound/soc/codecs/cs4270.c
+@@ -18,7 +18,7 @@
+  * - The machine driver's 'startup' function must call
+  *   cs4270_set_dai_sysclk() with the value of MCLK.
+  * - Only I2S and left-justified modes are supported
+- * - Power management is not supported
++ * - Power management is supported
+  */
+ 
+ #include <linux/module.h>
+@@ -27,6 +27,7 @@
+ #include <sound/soc.h>
+ #include <sound/initval.h>
+ #include <linux/i2c.h>
++#include <linux/delay.h>
+ 
+ #include "cs4270.h"
+ 
+@@ -56,6 +57,7 @@
+ #define CS4270_FIRSTREG	0x01
+ #define CS4270_LASTREG	0x08
+ #define CS4270_NUMREGS	(CS4270_LASTREG - CS4270_FIRSTREG + 1)
++#define CS4270_I2C_INCR	0x80
+ 
+ /* Bit masks for the CS4270 registers */
+ #define CS4270_CHIPID_ID	0xF0
+@@ -64,6 +66,8 @@
+ #define CS4270_PWRCTL_PDN_ADC	0x20
+ #define CS4270_PWRCTL_PDN_DAC	0x02
+ #define CS4270_PWRCTL_PDN	0x01
++#define CS4270_PWRCTL_PDN_ALL	\
++	(CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
+ #define CS4270_MODE_SPEED_MASK	0x30
+ #define CS4270_MODE_1X		0x00
+ #define CS4270_MODE_2X		0x10
+@@ -109,6 +113,7 @@ struct cs4270_private {
+ 	unsigned int mclk; /* Input frequency of the MCLK pin */
+ 	unsigned int mode; /* The mode (I2S or left-justified) */
+ 	unsigned int slave_mode;
++	unsigned int manual_mute;
+ };
+ 
+ /**
+@@ -295,7 +300,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec)
+ 	s32 length;
+ 
+ 	length = i2c_smbus_read_i2c_block_data(i2c_client,
+-		CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache);
++		CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
+ 
+ 	if (length != CS4270_NUMREGS) {
+ 		dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
+@@ -453,7 +458,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
+ }
+ 
+ /**
+- * cs4270_mute - enable/disable the CS4270 external mute
++ * cs4270_dai_mute - enable/disable the CS4270 external mute
+  * @dai: the SOC DAI
+  * @mute: 0 = disable mute, 1 = enable mute
+  *
+@@ -462,21 +467,52 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
+  * board does not have the MUTEA or MUTEB pins connected to such circuitry,
+  * then this function will do nothing.
+  */
+-static int cs4270_mute(struct snd_soc_dai *dai, int mute)
++static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
+ {
+ 	struct snd_soc_codec *codec = dai->codec;
++	struct cs4270_private *cs4270 = codec->private_data;
+ 	int reg6;
+ 
+ 	reg6 = snd_soc_read(codec, CS4270_MUTE);
+ 
+ 	if (mute)
+ 		reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
+-	else
++	else {
+ 		reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
++		reg6 |= cs4270->manual_mute;
++	}
+ 
+ 	return snd_soc_write(codec, CS4270_MUTE, reg6);
+ }
+ 
++/**
++ * cs4270_soc_put_mute - put callback for the 'Master Playback switch'
++ * 			 alsa control.
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * This function basically passes the arguments on to the generic
++ * snd_soc_put_volsw() function and saves the mute information in
++ * our private data structure. This is because we want to prevent
++ * cs4270_dai_mute() neglecting the user's decision to manually
++ * mute the codec's output.
++ *
++ * Returns 0 for success.
++ */
++static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
++				struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct cs4270_private *cs4270 = codec->private_data;
++	int left = !ucontrol->value.integer.value[0];
++	int right = !ucontrol->value.integer.value[1];
++
++	cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
++			      (right ? CS4270_MUTE_DAC_B : 0);
++
++	return snd_soc_put_volsw(kcontrol, ucontrol);
++}
++
+ /* A list of non-DAPM controls that the CS4270 supports */
+ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
+ 	SOC_DOUBLE_R("Master Playback Volume",
+@@ -486,7 +522,9 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
+ 	SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
+ 	SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
+ 	SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
+-	SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0)
++	SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
++	SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
++		snd_soc_get_volsw, cs4270_soc_put_mute),
+ };
+ 
+ /*
+@@ -506,7 +544,7 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
+ 	.hw_params	= cs4270_hw_params,
+ 	.set_sysclk	= cs4270_set_dai_sysclk,
+ 	.set_fmt	= cs4270_set_dai_fmt,
+-	.digital_mute	= cs4270_mute,
++	.digital_mute	= cs4270_dai_mute,
+ };
+ 
+ struct snd_soc_dai cs4270_dai = {
+@@ -753,6 +791,74 @@ static struct i2c_device_id cs4270_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, cs4270_id);
+ 
++#ifdef CONFIG_PM
++
++/* This suspend/resume implementation can handle both - a simple standby
++ * where the codec remains powered, and a full suspend, where the voltage
++ * domain the codec is connected to is teared down and/or any other hardware
++ * reset condition is asserted.
++ *
++ * The codec's own power saving features are enabled in the suspend callback,
++ * and all registers are written back to the hardware when resuming.
++ */
++
++static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
++{
++	struct cs4270_private *cs4270 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = &cs4270->codec;
++
++	return snd_soc_suspend_device(codec->dev);
++}
++
++static int cs4270_i2c_resume(struct i2c_client *client)
++{
++	struct cs4270_private *cs4270 = i2c_get_clientdata(client);
++	struct snd_soc_codec *codec = &cs4270->codec;
++
++	return snd_soc_resume_device(codec->dev);
++}
++
++static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
++{
++	struct snd_soc_codec *codec = cs4270_codec;
++	int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
++
++	return snd_soc_write(codec, CS4270_PWRCTL, reg);
++}
++
++static int cs4270_soc_resume(struct platform_device *pdev)
++{
++	struct snd_soc_codec *codec = cs4270_codec;
++	struct i2c_client *i2c_client = codec->control_data;
++	int reg;
++
++	/* In case the device was put to hard reset during sleep, we need to
++	 * wait 500ns here before any I2C communication. */
++	ndelay(500);
++
++	/* first restore the entire register cache ... */
++	for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
++		u8 val = snd_soc_read(codec, reg);
++
++		if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
++			dev_err(codec->dev, "i2c write failed\n");
++			return -EIO;
++		}
++	}
++
++	/* ... then disable the power-down bits */
++	reg = snd_soc_read(codec, CS4270_PWRCTL);
++	reg &= ~CS4270_PWRCTL_PDN_ALL;
++
++	return snd_soc_write(codec, CS4270_PWRCTL, reg);
++}
++#else
++#define cs4270_i2c_suspend	NULL
++#define cs4270_i2c_resume	NULL
++#define cs4270_soc_suspend	NULL
++#define cs4270_soc_resume	NULL
++#endif /* CONFIG_PM */
++
+ /*
+  * cs4270_i2c_driver - I2C device identification
+  *
+@@ -767,6 +873,8 @@ static struct i2c_driver cs4270_i2c_driver = {
+ 	.id_table = cs4270_id,
+ 	.probe = cs4270_i2c_probe,
+ 	.remove = cs4270_i2c_remove,
++	.suspend = cs4270_i2c_suspend,
++	.resume = cs4270_i2c_resume,
+ };
+ 
+ /*
+@@ -777,7 +885,9 @@ static struct i2c_driver cs4270_i2c_driver = {
+  */
+ struct snd_soc_codec_device soc_codec_device_cs4270 = {
+ 	.probe = 	cs4270_probe,
+-	.remove = 	cs4270_remove
++	.remove = 	cs4270_remove,
++	.suspend =	cs4270_soc_suspend,
++	.resume =	cs4270_soc_resume,
+ };
+ EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
+ 
+diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
+index 87f606c..c550750 100644
+--- a/sound/soc/codecs/ssm2602.c
++++ b/sound/soc/codecs/ssm2602.c
+@@ -336,15 +336,17 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
+ 			master_runtime->sample_bits,
+ 			master_runtime->rate);
+ 
+-		snd_pcm_hw_constraint_minmax(substream->runtime,
+-					     SNDRV_PCM_HW_PARAM_RATE,
+-					     master_runtime->rate,
+-					     master_runtime->rate);
+-
+-		snd_pcm_hw_constraint_minmax(substream->runtime,
+-					     SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+-					     master_runtime->sample_bits,
+-					     master_runtime->sample_bits);
++		if (master_runtime->rate != 0)
++			snd_pcm_hw_constraint_minmax(substream->runtime,
++						     SNDRV_PCM_HW_PARAM_RATE,
++						     master_runtime->rate,
++						     master_runtime->rate);
++
++		if (master_runtime->sample_bits != 0)
++			snd_pcm_hw_constraint_minmax(substream->runtime,
++						     SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
++						     master_runtime->sample_bits,
++						     master_runtime->sample_bits);
+ 
+ 		ssm2602->slave_substream = substream;
+ 	} else
+@@ -372,6 +374,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	struct ssm2602_priv *ssm2602 = codec->private_data;
++
+ 	/* deactivate */
+ 	if (!codec->active)
+ 		ssm2602_write(codec, SSM2602_ACTIVE, 0);
+@@ -497,11 +500,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
+ 	return 0;
+ }
+ 
+-#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+-		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+-		SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+-		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+-		SNDRV_PCM_RATE_96000)
++#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\
++		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
++		SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+ 
+ #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ 		SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
+index c3f4afb..0b8dcb5 100644
+--- a/sound/soc/codecs/tlv320aic23.c
++++ b/sound/soc/codecs/tlv320aic23.c
+@@ -86,7 +86,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
+ 	 */
+ 
+ 	if ((reg < 0 || reg > 9) && (reg != 15)) {
+-		printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
++		printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
+ 		return -1;
+ 	}
+ 
+@@ -98,7 +98,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
+ 	if (codec->hw_write(codec->control_data, data, 2) == 2)
+ 		return 0;
+ 
+-	printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
++	printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
+ 	       value, reg);
+ 
+ 	return -EIO;
+@@ -273,14 +273,14 @@ static const unsigned short sr_valid_mask[] = {
+  * Every divisor is a factor of 11*12
+  */
+ #define SR_MULT (11*12)
+-#define A(x) (x) ? (SR_MULT/x) : 0
++#define A(x) (SR_MULT/x)
+ static const unsigned char sr_adc_mult_table[] = {
+-	A(2), A(2), A(12), A(12),  A(0), A(0), A(3), A(1),
+-	A(2), A(2), A(11), A(11),  A(0), A(0), A(0), A(1)
++	A(2), A(2), A(12), A(12),  0, 0, A(3), A(1),
++	A(2), A(2), A(11), A(11),  0, 0, 0, A(1)
+ };
+ static const unsigned char sr_dac_mult_table[] = {
+-	A(2), A(12), A(2), A(12),  A(0), A(0), A(3), A(1),
+-	A(2), A(11), A(2), A(11),  A(0), A(0), A(0), A(1)
++	A(2), A(12), A(2), A(12),  0, 0, A(3), A(1),
++	A(2), A(11), A(2), A(11),  0, 0, 0, A(1)
+ };
+ 
+ static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
+@@ -523,6 +523,8 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	case SND_SOC_DAIFMT_I2S:
+ 		iface_reg |= TLV320AIC23_FOR_I2S;
+ 		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		iface_reg |= TLV320AIC23_LRP_ON;
+ 	case SND_SOC_DAIFMT_DSP_B:
+ 		iface_reg |= TLV320AIC23_FOR_DSP;
+ 		break;
+diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
+index ab099f4..3395cf9 100644
+--- a/sound/soc/codecs/tlv320aic3x.c
++++ b/sound/soc/codecs/tlv320aic3x.c
+@@ -53,6 +53,7 @@
+ 
+ /* codec private data */
+ struct aic3x_priv {
++	struct snd_soc_codec codec;
+ 	unsigned int sysclk;
+ 	int master;
+ };
+@@ -145,8 +146,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
+ 		      u8 *value)
+ {
+ 	*value = reg & 0xff;
+-	if (codec->hw_read(codec->control_data, value, 1) != 1)
+-		return -EIO;
++
++	value[0] = i2c_smbus_read_byte_data(codec->control_data, value[0]);
+ 
+ 	aic3x_write_reg_cache(codec, reg, *value);
+ 	return 0;
+@@ -767,6 +768,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
+ 	int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
+ 	u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
+ 	u16 pll_d = 1;
++	u8 reg;
+ 
+ 	/* select data word length */
+ 	data =
+@@ -801,8 +803,16 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
+ 		pll_q &= 0xf;
+ 		aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
+ 		aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
+-	} else
++		/* disable PLL if it is bypassed */
++		reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
++		aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE);
++
++	} else {
+ 		aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
++		/* enable PLL when it is used */
++		reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
++		aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
++	}
+ 
+ 	/* Route Left DAC to left channel input and
+ 	 * right DAC to right channel input */
+@@ -1147,11 +1157,13 @@ static int aic3x_resume(struct platform_device *pdev)
+  * initialise the AIC3X driver
+  * register the mixer and dsp interfaces with the kernel
+  */
+-static int aic3x_init(struct snd_soc_device *socdev)
++static int aic3x_init(struct snd_soc_codec *codec)
+ {
+-	struct snd_soc_codec *codec = socdev->card->codec;
+-	struct aic3x_setup_data *setup = socdev->codec_data;
+-	int reg, ret = 0;
++	int reg;
++
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
+ 
+ 	codec->name = "tlv320aic3x";
+ 	codec->owner = THIS_MODULE;
+@@ -1168,13 +1180,6 @@ static int aic3x_init(struct snd_soc_device *socdev)
+ 	aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
+ 	aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
+ 
+-	/* register pcms */
+-	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+-	if (ret < 0) {
+-		printk(KERN_ERR "aic3x: failed to create pcms\n");
+-		goto pcm_err;
+-	}
+-
+ 	/* DAC default volume and mute */
+ 	aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
+ 	aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
+@@ -1241,30 +1246,51 @@ static int aic3x_init(struct snd_soc_device *socdev)
+ 	/* off, with power on */
+ 	aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ 
+-	/* setup GPIO functions */
+-	aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4);
+-	aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
++	return 0;
++}
++
++static struct snd_soc_codec *aic3x_codec;
+ 
+-	snd_soc_add_controls(codec, aic3x_snd_controls,
+-				ARRAY_SIZE(aic3x_snd_controls));
+-	aic3x_add_widgets(codec);
+-	ret = snd_soc_init_card(socdev);
++static int aic3x_register(struct snd_soc_codec *codec)
++{
++	int ret;
++
++	ret = aic3x_init(codec);
+ 	if (ret < 0) {
+-		printk(KERN_ERR "aic3x: failed to register card\n");
+-		goto card_err;
++		dev_err(codec->dev, "Failed to initialise device\n");
++		return ret;
+ 	}
+ 
+-	return ret;
++	aic3x_codec = codec;
+ 
+-card_err:
+-	snd_soc_free_pcms(socdev);
+-	snd_soc_dapm_free(socdev);
+-pcm_err:
+-	kfree(codec->reg_cache);
+-	return ret;
++	ret = snd_soc_register_codec(codec);
++	if (ret) {
++		dev_err(codec->dev, "Failed to register codec\n");
++		return ret;
++	}
++
++	ret = snd_soc_register_dai(&aic3x_dai);
++	if (ret) {
++		dev_err(codec->dev, "Failed to register dai\n");
++		snd_soc_unregister_codec(codec);
++		return ret;
++	}
++
++	return 0;
+ }
+ 
+-static struct snd_soc_device *aic3x_socdev;
++static int aic3x_unregister(struct aic3x_priv *aic3x)
++{
++	aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF);
++
++	snd_soc_unregister_dai(&aic3x_dai);
++	snd_soc_unregister_codec(&aic3x->codec);
++
++	kfree(aic3x);
++	aic3x_codec = NULL;
++
++	return 0;
++}
+ 
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ /*
+@@ -1279,28 +1305,36 @@ static struct snd_soc_device *aic3x_socdev;
+ static int aic3x_i2c_probe(struct i2c_client *i2c,
+ 			   const struct i2c_device_id *id)
+ {
+-	struct snd_soc_device *socdev = aic3x_socdev;
+-	struct snd_soc_codec *codec = socdev->card->codec;
+-	int ret;
++	struct snd_soc_codec *codec;
++	struct aic3x_priv *aic3x;
++
++	aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
++	if (aic3x == NULL) {
++		dev_err(&i2c->dev, "failed to create private data\n");
++		return -ENOMEM;
++	}
+ 
+-	i2c_set_clientdata(i2c, codec);
++	codec = &aic3x->codec;
++	codec->dev = &i2c->dev;
++	codec->private_data = aic3x;
+ 	codec->control_data = i2c;
++	codec->hw_write = (hw_write_t) i2c_master_send;
+ 
+-	ret = aic3x_init(socdev);
+-	if (ret < 0)
+-		printk(KERN_ERR "aic3x: failed to initialise AIC3X\n");
+-	return ret;
++	i2c_set_clientdata(i2c, aic3x);
++
++	return aic3x_register(codec);
+ }
+ 
+ static int aic3x_i2c_remove(struct i2c_client *client)
+ {
+-	struct snd_soc_codec *codec = i2c_get_clientdata(client);
+-	kfree(codec->reg_cache);
+-	return 0;
++	struct aic3x_priv *aic3x = i2c_get_clientdata(client);
++
++	return aic3x_unregister(aic3x);
+ }
+ 
+ static const struct i2c_device_id aic3x_i2c_id[] = {
+ 	{ "tlv320aic3x", 0 },
++	{ "tlv320aic33", 0 },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
+@@ -1311,56 +1345,28 @@ static struct i2c_driver aic3x_i2c_driver = {
+ 		.name = "aic3x I2C Codec",
+ 		.owner = THIS_MODULE,
+ 	},
+-	.probe = aic3x_i2c_probe,
++	.probe	= aic3x_i2c_probe,
+ 	.remove = aic3x_i2c_remove,
+ 	.id_table = aic3x_i2c_id,
+ };
+ 
+-static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
+-{
+-	value[0] = i2c_smbus_read_byte_data(client, value[0]);
+-	return (len == 1);
+-}
+-
+-static int aic3x_add_i2c_device(struct platform_device *pdev,
+-				 const struct aic3x_setup_data *setup)
++static inline void aic3x_i2c_init(void)
+ {
+-	struct i2c_board_info info;
+-	struct i2c_adapter *adapter;
+-	struct i2c_client *client;
+ 	int ret;
+ 
+ 	ret = i2c_add_driver(&aic3x_i2c_driver);
+-	if (ret != 0) {
+-		dev_err(&pdev->dev, "can't add i2c driver\n");
+-		return ret;
+-	}
+-
+-	memset(&info, 0, sizeof(struct i2c_board_info));
+-	info.addr = setup->i2c_address;
+-	strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
+-
+-	adapter = i2c_get_adapter(setup->i2c_bus);
+-	if (!adapter) {
+-		dev_err(&pdev->dev, "can't get i2c adapter %d\n",
+-			setup->i2c_bus);
+-		goto err_driver;
+-	}
+-
+-	client = i2c_new_device(adapter, &info);
+-	i2c_put_adapter(adapter);
+-	if (!client) {
+-		dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
+-			(unsigned int)info.addr);
+-		goto err_driver;
+-	}
+-
+-	return 0;
++	if (ret)
++		printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
++		       __func__, ret);
++}
+ 
+-err_driver:
++static inline void aic3x_i2c_exit(void)
++{
+ 	i2c_del_driver(&aic3x_i2c_driver);
+-	return -ENODEV;
+ }
++#else
++static inline void aic3x_i2c_init(void) { }
++static inline void aic3x_i2c_exit(void) { }
+ #endif
+ 
+ static int aic3x_probe(struct platform_device *pdev)
+@@ -1368,43 +1374,51 @@ static int aic3x_probe(struct platform_device *pdev)
+ 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ 	struct aic3x_setup_data *setup;
+ 	struct snd_soc_codec *codec;
+-	struct aic3x_priv *aic3x;
+ 	int ret = 0;
+ 
+-	printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION);
++	codec = aic3x_codec;
++	if (!codec) {
++		dev_err(&pdev->dev, "Codec not registered\n");
++		return -ENODEV;
++	}
+ 
++	socdev->card->codec = codec;
+ 	setup = socdev->codec_data;
+-	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+-	if (codec == NULL)
+-		return -ENOMEM;
+ 
+-	aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
+-	if (aic3x == NULL) {
+-		kfree(codec);
+-		return -ENOMEM;
++	if (setup) {
++		/* setup GPIO functions */
++		aic3x_write(codec, AIC3X_GPIO1_REG,
++			    (setup->gpio_func[0] & 0xf) << 4);
++		aic3x_write(codec, AIC3X_GPIO2_REG,
++			    (setup->gpio_func[1] & 0xf) << 4);
+ 	}
+ 
+-	codec->private_data = aic3x;
+-	socdev->card->codec = codec;
+-	mutex_init(&codec->mutex);
+-	INIT_LIST_HEAD(&codec->dapm_widgets);
+-	INIT_LIST_HEAD(&codec->dapm_paths);
+-
+-	aic3x_socdev = socdev;
+-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+-	if (setup->i2c_address) {
+-		codec->hw_write = (hw_write_t) i2c_master_send;
+-		codec->hw_read = (hw_read_t) aic3x_i2c_read;
+-		ret = aic3x_add_i2c_device(pdev, setup);
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if (ret < 0) {
++		printk(KERN_ERR "aic3x: failed to create pcms\n");
++		goto pcm_err;
+ 	}
+-#else
+-	/* Add other interfaces here */
+-#endif
+ 
+-	if (ret != 0) {
+-		kfree(codec->private_data);
+-		kfree(codec);
++	snd_soc_add_controls(codec, aic3x_snd_controls,
++			     ARRAY_SIZE(aic3x_snd_controls));
++
++	aic3x_add_widgets(codec);
++
++	ret = snd_soc_init_card(socdev);
++	if (ret < 0) {
++		printk(KERN_ERR "aic3x: failed to register card\n");
++		goto card_err;
+ 	}
++
++	return ret;
++
++card_err:
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++
++pcm_err:
++	kfree(codec->reg_cache);
+ 	return ret;
+ }
+ 
+@@ -1419,12 +1433,8 @@ static int aic3x_remove(struct platform_device *pdev)
+ 
+ 	snd_soc_free_pcms(socdev);
+ 	snd_soc_dapm_free(socdev);
+-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+-	i2c_unregister_device(codec->control_data);
+-	i2c_del_driver(&aic3x_i2c_driver);
+-#endif
+-	kfree(codec->private_data);
+-	kfree(codec);
++
++	kfree(codec->reg_cache);
+ 
+ 	return 0;
+ }
+@@ -1439,13 +1449,15 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
+ 
+ static int __init aic3x_modinit(void)
+ {
+-	return snd_soc_register_dai(&aic3x_dai);
++	aic3x_i2c_init();
++
++	return 0;
+ }
+ module_init(aic3x_modinit);
+ 
+ static void __exit aic3x_exit(void)
+ {
+-	snd_soc_unregister_dai(&aic3x_dai);
++	aic3x_i2c_exit();
+ }
+ module_exit(aic3x_exit);
+ 
+diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
+index ac827e5..9af1c88 100644
+--- a/sound/soc/codecs/tlv320aic3x.h
++++ b/sound/soc/codecs/tlv320aic3x.h
+@@ -282,8 +282,6 @@ int aic3x_headset_detected(struct snd_soc_codec *codec);
+ int aic3x_button_pressed(struct snd_soc_codec *codec);
+ 
+ struct aic3x_setup_data {
+-	int i2c_bus;
+-	unsigned short i2c_address;
+ 	unsigned int gpio_func[2];
+ };
+ 
+diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
+index df7c8c2..4df7c6c 100644
+--- a/sound/soc/codecs/twl4030.c
++++ b/sound/soc/codecs/twl4030.c
+@@ -115,6 +115,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
+ 	0x00, /* REG_VIBRA_PWM_SET	(0x47)	*/
+ 	0x00, /* REG_ANAMIC_GAIN	(0x48)	*/
+ 	0x00, /* REG_MISC_SET_2		(0x49)	*/
++	0x00, /* REG_SW_SHADOW		(0x4A)	- Shadow, non HW register */
+ };
+ 
+ /* codec private data */
+@@ -125,6 +126,17 @@ struct twl4030_priv {
+ 
+ 	struct snd_pcm_substream *master_substream;
+ 	struct snd_pcm_substream *slave_substream;
++
++	unsigned int configured;
++	unsigned int rate;
++	unsigned int sample_bits;
++	unsigned int channels;
++
++	unsigned int sysclk;
++
++	/* Headset output state handling */
++	unsigned int hsl_enabled;
++	unsigned int hsr_enabled;
+ };
+ 
+ /*
+@@ -161,7 +173,11 @@ static int twl4030_write(struct snd_soc_codec *codec,
+ 			unsigned int reg, unsigned int value)
+ {
+ 	twl4030_write_reg_cache(codec, reg, value);
+-	return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
++	if (likely(reg < TWL4030_REG_SW_SHADOW))
++		return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value,
++					    reg);
++	else
++		return 0;
+ }
+ 
+ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
+@@ -188,6 +204,7 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
+ 
+ static void twl4030_init_chip(struct snd_soc_codec *codec)
+ {
++	u8 *cache = codec->reg_cache;
+ 	int i;
+ 
+ 	/* clear CODECPDZ prior to setting register defaults */
+@@ -195,7 +212,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
+ 
+ 	/* set all audio section registers to reasonable defaults */
+ 	for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
+-		twl4030_write(codec, i,	twl4030_reg[i]);
++		twl4030_write(codec, i,	cache[i]);
+ 
+ }
+ 
+@@ -208,55 +225,11 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
+ 		return;
+ 
+ 	if (mute) {
+-		/* Bypass the reg_cache and mute the volumes
+-		 * Headset mute is done in it's own event handler
+-		 * Things to mute:  Earpiece, PreDrivL/R, CarkitL/R
+-		 */
+-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL);
+-		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+-					reg_val & (~TWL4030_EAR_GAIN),
+-					TWL4030_REG_EAR_CTL);
+-
+-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL);
+-		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+-					reg_val & (~TWL4030_PREDL_GAIN),
+-					TWL4030_REG_PREDL_CTL);
+-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL);
+-		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+-					reg_val & (~TWL4030_PREDR_GAIN),
+-					TWL4030_REG_PREDL_CTL);
+-
+-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL);
+-		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+-					reg_val & (~TWL4030_PRECKL_GAIN),
+-					TWL4030_REG_PRECKL_CTL);
+-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL);
+-		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+-					reg_val & (~TWL4030_PRECKL_GAIN),
+-					TWL4030_REG_PRECKR_CTL);
+-
+ 		/* Disable PLL */
+ 		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
+ 		reg_val &= ~TWL4030_APLL_EN;
+ 		twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
+ 	} else {
+-		/* Restore the volumes
+-		 * Headset mute is done in it's own event handler
+-		 * Things to restore:  Earpiece, PreDrivL/R, CarkitL/R
+-		 */
+-		twl4030_write(codec, TWL4030_REG_EAR_CTL,
+-			twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL));
+-
+-		twl4030_write(codec, TWL4030_REG_PREDL_CTL,
+-			twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL));
+-		twl4030_write(codec, TWL4030_REG_PREDR_CTL,
+-			twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL));
+-
+-		twl4030_write(codec, TWL4030_REG_PRECKL_CTL,
+-			twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL));
+-		twl4030_write(codec, TWL4030_REG_PRECKR_CTL,
+-			twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL));
+-
+ 		/* Enable PLL */
+ 		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
+ 		reg_val |= TWL4030_APLL_EN;
+@@ -316,104 +289,60 @@ static void twl4030_power_down(struct snd_soc_codec *codec)
+ }
+ 
+ /* Earpiece */
+-static const char *twl4030_earpiece_texts[] =
+-		{"Off", "DACL1", "DACL2", "DACR1"};
+-
+-static const unsigned int twl4030_earpiece_values[] =
+-		{0x0, 0x1, 0x2, 0x4};
+-
+-static const struct soc_enum twl4030_earpiece_enum =
+-	SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
+-			ARRAY_SIZE(twl4030_earpiece_texts),
+-			twl4030_earpiece_texts,
+-			twl4030_earpiece_values);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
+-SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum);
++static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
++	SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
++	SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
++};
+ 
+ /* PreDrive Left */
+-static const char *twl4030_predrivel_texts[] =
+-		{"Off", "DACL1", "DACL2", "DACR2"};
+-
+-static const unsigned int twl4030_predrivel_values[] =
+-		{0x0, 0x1, 0x2, 0x4};
+-
+-static const struct soc_enum twl4030_predrivel_enum =
+-	SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
+-			ARRAY_SIZE(twl4030_predrivel_texts),
+-			twl4030_predrivel_texts,
+-			twl4030_predrivel_values);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
+-SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum);
++static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
++	SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
++	SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
++};
+ 
+ /* PreDrive Right */
+-static const char *twl4030_predriver_texts[] =
+-		{"Off", "DACR1", "DACR2", "DACL2"};
+-
+-static const unsigned int twl4030_predriver_values[] =
+-		{0x0, 0x1, 0x2, 0x4};
+-
+-static const struct soc_enum twl4030_predriver_enum =
+-	SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
+-			ARRAY_SIZE(twl4030_predriver_texts),
+-			twl4030_predriver_texts,
+-			twl4030_predriver_values);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
+-SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum);
++static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
++	SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
++	SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
++};
+ 
+ /* Headset Left */
+-static const char *twl4030_hsol_texts[] =
+-		{"Off", "DACL1", "DACL2"};
+-
+-static const struct soc_enum twl4030_hsol_enum =
+-	SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
+-			ARRAY_SIZE(twl4030_hsol_texts),
+-			twl4030_hsol_texts);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
+-SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
++static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
++	SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
++};
+ 
+ /* Headset Right */
+-static const char *twl4030_hsor_texts[] =
+-		{"Off", "DACR1", "DACR2"};
+-
+-static const struct soc_enum twl4030_hsor_enum =
+-	SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
+-			ARRAY_SIZE(twl4030_hsor_texts),
+-			twl4030_hsor_texts);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
+-SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
++static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
++	SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
++	SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
++};
+ 
+ /* Carkit Left */
+-static const char *twl4030_carkitl_texts[] =
+-		{"Off", "DACL1", "DACL2"};
+-
+-static const struct soc_enum twl4030_carkitl_enum =
+-	SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
+-			ARRAY_SIZE(twl4030_carkitl_texts),
+-			twl4030_carkitl_texts);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
+-SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
++static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
++	SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
++};
+ 
+ /* Carkit Right */
+-static const char *twl4030_carkitr_texts[] =
+-		{"Off", "DACR1", "DACR2"};
+-
+-static const struct soc_enum twl4030_carkitr_enum =
+-	SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
+-			ARRAY_SIZE(twl4030_carkitr_texts),
+-			twl4030_carkitr_texts);
+-
+-static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
+-SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
++static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
++	SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
++	SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
++};
+ 
+ /* Handsfree Left */
+ static const char *twl4030_handsfreel_texts[] =
+-		{"Voice", "DACL1", "DACL2", "DACR2"};
++		{"Voice", "AudioL1", "AudioL2", "AudioR2"};
+ 
+ static const struct soc_enum twl4030_handsfreel_enum =
+ 	SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
+@@ -423,9 +352,13 @@ static const struct soc_enum twl4030_handsfreel_enum =
+ static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
+ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
+ 
++/* Handsfree Left virtual mute */
++static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control =
++	SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0);
++
+ /* Handsfree Right */
+ static const char *twl4030_handsfreer_texts[] =
+-		{"Voice", "DACR1", "DACR2", "DACL2"};
++		{"Voice", "AudioR1", "AudioR2", "AudioL2"};
+ 
+ static const struct soc_enum twl4030_handsfreer_enum =
+ 	SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
+@@ -435,37 +368,52 @@ static const struct soc_enum twl4030_handsfreer_enum =
+ static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
+ SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
+ 
+-/* Left analog microphone selection */
+-static const char *twl4030_analoglmic_texts[] =
+-		{"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"};
++/* Handsfree Right virtual mute */
++static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control =
++	SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0);
+ 
+-static const unsigned int twl4030_analoglmic_values[] =
+-		{0x0, 0x1, 0x2, 0x4, 0x8};
++/* Vibra */
++/* Vibra audio path selection */
++static const char *twl4030_vibra_texts[] =
++		{"AudioL1", "AudioR1", "AudioL2", "AudioR2"};
+ 
+-static const struct soc_enum twl4030_analoglmic_enum =
+-	SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
+-			ARRAY_SIZE(twl4030_analoglmic_texts),
+-			twl4030_analoglmic_texts,
+-			twl4030_analoglmic_values);
++static const struct soc_enum twl4030_vibra_enum =
++	SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2,
++			ARRAY_SIZE(twl4030_vibra_texts),
++			twl4030_vibra_texts);
+ 
+-static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control =
+-SOC_DAPM_VALUE_ENUM("Route", twl4030_analoglmic_enum);
++static const struct snd_kcontrol_new twl4030_dapm_vibra_control =
++SOC_DAPM_ENUM("Route", twl4030_vibra_enum);
+ 
+-/* Right analog microphone selection */
+-static const char *twl4030_analogrmic_texts[] =
+-		{"Off", "Sub mic", "AUXR"};
++/* Vibra path selection: local vibrator (PWM) or audio driven */
++static const char *twl4030_vibrapath_texts[] =
++		{"Local vibrator", "Audio"};
+ 
+-static const unsigned int twl4030_analogrmic_values[] =
+-		{0x0, 0x1, 0x4};
++static const struct soc_enum twl4030_vibrapath_enum =
++	SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4,
++			ARRAY_SIZE(twl4030_vibrapath_texts),
++			twl4030_vibrapath_texts);
+ 
+-static const struct soc_enum twl4030_analogrmic_enum =
+-	SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
+-			ARRAY_SIZE(twl4030_analogrmic_texts),
+-			twl4030_analogrmic_texts,
+-			twl4030_analogrmic_values);
++static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control =
++SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
+ 
+-static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control =
+-SOC_DAPM_VALUE_ENUM("Route", twl4030_analogrmic_enum);
++/* Left analog microphone selection */
++static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
++	SOC_DAPM_SINGLE("Main Mic Capture Switch",
++			TWL4030_REG_ANAMICL, 0, 1, 0),
++	SOC_DAPM_SINGLE("Headset Mic Capture Switch",
++			TWL4030_REG_ANAMICL, 1, 1, 0),
++	SOC_DAPM_SINGLE("AUXL Capture Switch",
++			TWL4030_REG_ANAMICL, 2, 1, 0),
++	SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
++			TWL4030_REG_ANAMICL, 3, 1, 0),
++};
++
++/* Right analog microphone selection */
++static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
++	SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
++	SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
++};
+ 
+ /* TX1 L/R Analog/Digital microphone selection */
+ static const char *twl4030_micpathtx1_texts[] =
+@@ -507,6 +455,10 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
+ static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
+ 	SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
+ 
++/* Analog bypass for Voice */
++static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
++	SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
++
+ /* Digital bypass gain, 0 mutes the bypass */
+ static const unsigned int twl4030_dapm_dbypass_tlv[] = {
+ 	TLV_DB_RANGE_HEAD(2),
+@@ -526,6 +478,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
+ 			TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
+ 			twl4030_dapm_dbypass_tlv);
+ 
++/*
++ * Voice Sidetone GAIN volume control:
++ * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB)
++ */
++static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1);
++
++/* Digital bypass voice: sidetone (VUL -> VDL)*/
++static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
++	SOC_DAPM_SINGLE_TLV("Volume",
++			TWL4030_REG_VSTPGA, 0, 0x29, 0,
++			twl4030_dapm_dbypassv_tlv);
++
+ static int micpath_event(struct snd_soc_dapm_widget *w,
+ 	struct snd_kcontrol *kcontrol, int event)
+ {
+@@ -556,63 +520,205 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
+ 	return 0;
+ }
+ 
+-static int handsfree_event(struct snd_soc_dapm_widget *w,
+-		struct snd_kcontrol *kcontrol, int event)
++/*
++ * Output PGA builder:
++ * Handle the muting and unmuting of the given output (turning off the
++ * amplifier associated with the output pin)
++ * On mute bypass the reg_cache and mute the volume
++ * On unmute: restore the register content
++ * Outputs handled in this way:  Earpiece, PreDrivL/R, CarkitL/R
++ */
++#define TWL4030_OUTPUT_PGA(pin_name, reg, mask)				\
++static int pin_name##pga_event(struct snd_soc_dapm_widget *w,		\
++		struct snd_kcontrol *kcontrol, int event)		\
++{									\
++	u8 reg_val;							\
++									\
++	switch (event) {						\
++	case SND_SOC_DAPM_POST_PMU:					\
++		twl4030_write(w->codec, reg,				\
++			twl4030_read_reg_cache(w->codec, reg));		\
++		break;							\
++	case SND_SOC_DAPM_POST_PMD:					\
++		reg_val = twl4030_read_reg_cache(w->codec, reg);	\
++		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,	\
++					reg_val & (~mask),		\
++					reg);				\
++		break;							\
++	}								\
++	return 0;							\
++}
++
++TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
++TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
++TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
++TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
++TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
++
++static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
+ {
+-	struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
+ 	unsigned char hs_ctl;
+ 
+-	hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
++	hs_ctl = twl4030_read_reg_cache(codec, reg);
+ 
+-	if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
++	if (ramp) {
++		/* HF ramp-up */
++		hs_ctl |= TWL4030_HF_CTL_REF_EN;
++		twl4030_write(codec, reg, hs_ctl);
++		udelay(10);
+ 		hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
+-		twl4030_write(w->codec, e->reg, hs_ctl);
++		twl4030_write(codec, reg, hs_ctl);
++		udelay(40);
+ 		hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
+-		twl4030_write(w->codec, e->reg, hs_ctl);
+ 		hs_ctl |= TWL4030_HF_CTL_HB_EN;
+-		twl4030_write(w->codec, e->reg, hs_ctl);
++		twl4030_write(codec, reg, hs_ctl);
+ 	} else {
+-		hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
+-				| TWL4030_HF_CTL_HB_EN);
+-		twl4030_write(w->codec, e->reg, hs_ctl);
++		/* HF ramp-down */
++		hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
++		hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
++		twl4030_write(codec, reg, hs_ctl);
++		hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
++		twl4030_write(codec, reg, hs_ctl);
++		udelay(40);
++		hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
++		twl4030_write(codec, reg, hs_ctl);
+ 	}
++}
+ 
++static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event)
++{
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
++		break;
++	case SND_SOC_DAPM_POST_PMD:
++		handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
++		break;
++	}
+ 	return 0;
+ }
+ 
+-static int headsetl_event(struct snd_soc_dapm_widget *w,
++static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
+ 		struct snd_kcontrol *kcontrol, int event)
+ {
+-	unsigned char hs_gain, hs_pop;
+-
+-	/* Save the current volume */
+-	hs_gain = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_GAIN_SET);
+-	hs_pop = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_POPN_SET);
+-
+ 	switch (event) {
+ 	case SND_SOC_DAPM_POST_PMU:
+-		/* Do the anti-pop/bias ramp enable according to the TRM */
+-		hs_pop |= TWL4030_VMID_EN;
+-		twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+-		/* Is this needed? Can we just use whatever gain here? */
+-		twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET,
+-				(hs_gain & (~0x0f)) | 0x0a);
+-		hs_pop |= TWL4030_RAMP_EN;
+-		twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+-
+-		/* Restore the original volume */
+-		twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
++		handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
+ 		break;
+ 	case SND_SOC_DAPM_POST_PMD:
+-		/* Do the anti-pop/bias ramp disable according to the TRM */
++		handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
++		break;
++	}
++	return 0;
++}
++
++static void headset_ramp(struct snd_soc_codec *codec, int ramp)
++{
++	struct snd_soc_device *socdev = codec->socdev;
++	struct twl4030_setup_data *setup = socdev->codec_data;
++
++	unsigned char hs_gain, hs_pop;
++	struct twl4030_priv *twl4030 = codec->private_data;
++	/* Base values for ramp delay calculation: 2^19 - 2^26 */
++	unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
++				    8388608, 16777216, 33554432, 67108864};
++
++	hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
++	hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
++
++	/* Enable external mute control, this dramatically reduces
++	 * the pop-noise */
++	if (setup && setup->hs_extmute) {
++		if (setup->set_hs_extmute) {
++			setup->set_hs_extmute(1);
++		} else {
++			hs_pop |= TWL4030_EXTMUTE;
++			twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		}
++	}
++
++	if (ramp) {
++		/* Headset ramp-up according to the TRM */
++		hs_pop |= TWL4030_VMID_EN;
++		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
++		hs_pop |= TWL4030_RAMP_EN;
++		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		/* Wait ramp delay time + 1, so the VMID can settle */
++		mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
++			twl4030->sysclk) + 1);
++	} else {
++		/* Headset ramp-down _not_ according to
++		 * the TRM, but in a way that it is working */
+ 		hs_pop &= ~TWL4030_RAMP_EN;
+-		twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		/* Wait ramp delay time + 1, so the VMID can settle */
++		mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
++			twl4030->sysclk) + 1);
+ 		/* Bypass the reg_cache to mute the headset */
+ 		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ 					hs_gain & (~0x0f),
+ 					TWL4030_REG_HS_GAIN_SET);
++
+ 		hs_pop &= ~TWL4030_VMID_EN;
+-		twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++	}
++
++	/* Disable external mute */
++	if (setup && setup->hs_extmute) {
++		if (setup->set_hs_extmute) {
++			setup->set_hs_extmute(0);
++		} else {
++			hs_pop &= ~TWL4030_EXTMUTE;
++			twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++		}
++	}
++}
++
++static int headsetlpga_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event)
++{
++	struct twl4030_priv *twl4030 = w->codec->private_data;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		/* Do the ramp-up only once */
++		if (!twl4030->hsr_enabled)
++			headset_ramp(w->codec, 1);
++
++		twl4030->hsl_enabled = 1;
++		break;
++	case SND_SOC_DAPM_POST_PMD:
++		/* Do the ramp-down only if both headsetL/R is disabled */
++		if (!twl4030->hsr_enabled)
++			headset_ramp(w->codec, 0);
++
++		twl4030->hsl_enabled = 0;
++		break;
++	}
++	return 0;
++}
++
++static int headsetrpga_event(struct snd_soc_dapm_widget *w,
++		struct snd_kcontrol *kcontrol, int event)
++{
++	struct twl4030_priv *twl4030 = w->codec->private_data;
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMU:
++		/* Do the ramp-up only once */
++		if (!twl4030->hsl_enabled)
++			headset_ramp(w->codec, 1);
++
++		twl4030->hsr_enabled = 1;
++		break;
++	case SND_SOC_DAPM_POST_PMD:
++		/* Do the ramp-down only if both headsetL/R is disabled */
++		if (!twl4030->hsl_enabled)
++			headset_ramp(w->codec, 0);
++
++		twl4030->hsr_enabled = 0;
+ 		break;
+ 	}
+ 	return 0;
+@@ -624,11 +730,23 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
+ 	struct soc_mixer_control *m =
+ 		(struct soc_mixer_control *)w->kcontrols->private_value;
+ 	struct twl4030_priv *twl4030 = w->codec->private_data;
+-	unsigned char reg;
++	unsigned char reg, misc;
+ 
+ 	reg = twl4030_read_reg_cache(w->codec, m->reg);
+ 
+-	if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
++	/*
++	 * bypass_state[0:3] - analog HiFi bypass
++	 * bypass_state[4]   - analog voice bypass
++	 * bypass_state[5]   - digital voice bypass
++	 * bypass_state[6:7] - digital HiFi bypass
++	 */
++	if (m->reg == TWL4030_REG_VSTPGA) {
++		/* Voice digital bypass */
++		if (reg)
++			twl4030->bypass_state |= (1 << 5);
++		else
++			twl4030->bypass_state &= ~(1 << 5);
++	} else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
+ 		/* Analog bypass */
+ 		if (reg & (1 << m->shift))
+ 			twl4030->bypass_state |=
+@@ -636,14 +754,28 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
+ 		else
+ 			twl4030->bypass_state &=
+ 				~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
++	} else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
++		/* Analog voice bypass */
++		if (reg & (1 << m->shift))
++			twl4030->bypass_state |= (1 << 4);
++		else
++			twl4030->bypass_state &= ~(1 << 4);
+ 	} else {
+ 		/* Digital bypass */
+ 		if (reg & (0x7 << m->shift))
+-			twl4030->bypass_state |= (1 << (m->shift ? 5 : 4));
++			twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
+ 		else
+-			twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4));
++			twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
+ 	}
+ 
++	/* Enable master analog loopback mode if any analog switch is enabled*/
++	misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
++	if (twl4030->bypass_state & 0x1F)
++		misc |= TWL4030_FMLOOP_EN;
++	else
++		misc &= ~TWL4030_FMLOOP_EN;
++	twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
++
+ 	if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ 		if (twl4030->bypass_state)
+ 			twl4030_codec_mute(w->codec, 0);
+@@ -810,6 +942,48 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
+ 	return err;
+ }
+ 
++/* Codec operation modes */
++static const char *twl4030_op_modes_texts[] = {
++	"Option 2 (voice/audio)", "Option 1 (audio)"
++};
++
++static const struct soc_enum twl4030_op_modes_enum =
++	SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0,
++			ARRAY_SIZE(twl4030_op_modes_texts),
++			twl4030_op_modes_texts);
++
++static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
++	struct snd_ctl_elem_value *ucontrol)
++{
++	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	struct twl4030_priv *twl4030 = codec->private_data;
++	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
++	unsigned short val;
++	unsigned short mask, bitmask;
++
++	if (twl4030->configured) {
++		printk(KERN_ERR "twl4030 operation mode cannot be "
++			"changed on-the-fly\n");
++		return -EBUSY;
++	}
++
++	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
++		;
++	if (ucontrol->value.enumerated.item[0] > e->max - 1)
++		return -EINVAL;
++
++	val = ucontrol->value.enumerated.item[0] << e->shift_l;
++	mask = (bitmask - 1) << e->shift_l;
++	if (e->shift_l != e->shift_r) {
++		if (ucontrol->value.enumerated.item[1] > e->max - 1)
++			return -EINVAL;
++		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
++		mask |= (bitmask - 1) << e->shift_r;
++	}
++
++	return snd_soc_update_bits(codec, e->reg, mask, val);
++}
++
+ /*
+  * FGAIN volume control:
+  * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
+@@ -824,6 +998,12 @@ static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
+ static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
+ 
+ /*
++ * Voice Downlink GAIN volume control:
++ * from -37 to 12 dB in 1 dB steps (mute instead of -37 dB)
++ */
++static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1);
++
++/*
+  * Analog playback gain
+  * -24 dB to 12 dB in 2 dB steps
+  */
+@@ -853,6 +1033,16 @@ static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
+  */
+ static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
+ 
++/* AVADC clock priority */
++static const char *twl4030_avadc_clk_priority_texts[] = {
++	"Voice high priority", "HiFi high priority"
++};
++
++static const struct soc_enum twl4030_avadc_clk_priority_enum =
++	SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
++			ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
++			twl4030_avadc_clk_priority_texts);
++
+ static const char *twl4030_rampdelay_texts[] = {
+ 	"27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
+ 	"437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
+@@ -864,7 +1054,32 @@ static const struct soc_enum twl4030_rampdelay_enum =
+ 			ARRAY_SIZE(twl4030_rampdelay_texts),
+ 			twl4030_rampdelay_texts);
+ 
++/* Vibra H-bridge direction mode */
++static const char *twl4030_vibradirmode_texts[] = {
++	"Vibra H-bridge direction", "Audio data MSB",
++};
++
++static const struct soc_enum twl4030_vibradirmode_enum =
++	SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5,
++			ARRAY_SIZE(twl4030_vibradirmode_texts),
++			twl4030_vibradirmode_texts);
++
++/* Vibra H-bridge direction */
++static const char *twl4030_vibradir_texts[] = {
++	"Positive polarity", "Negative polarity",
++};
++
++static const struct soc_enum twl4030_vibradir_enum =
++	SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1,
++			ARRAY_SIZE(twl4030_vibradir_texts),
++			twl4030_vibradir_texts);
++
+ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
++	/* Codec operation mode control */
++	SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
++		snd_soc_get_enum_double,
++		snd_soc_put_twl4030_opmode_enum_double),
++
+ 	/* Common playback gain controls */
+ 	SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
+ 		TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
+@@ -893,6 +1108,16 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
+ 		TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
+ 		1, 1, 0),
+ 
++	/* Common voice downlink gain controls */
++	SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume",
++		TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv),
++
++	SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume",
++		TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv),
++
++	SOC_SINGLE("DAC Voice Analog Downlink Switch",
++		TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
++
+ 	/* Separate output gain controls */
+ 	SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
+ 		TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
+@@ -919,7 +1144,12 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
+ 	SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
+ 		0, 3, 5, 0, input_gain_tlv),
+ 
++	SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
++
+ 	SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
++
++	SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
++	SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
+ };
+ 
+ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+@@ -947,26 +1177,19 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ 	SND_SOC_DAPM_OUTPUT("CARKITR"),
+ 	SND_SOC_DAPM_OUTPUT("HFL"),
+ 	SND_SOC_DAPM_OUTPUT("HFR"),
++	SND_SOC_DAPM_OUTPUT("VIBRA"),
+ 
+ 	/* DACs */
+-	SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
++	SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
+ 			SND_SOC_NOPM, 0, 0),
+-	SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
++	SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback",
+ 			SND_SOC_NOPM, 0, 0),
+-	SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
++	SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback",
+ 			SND_SOC_NOPM, 0, 0),
+-	SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
++	SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
++			SND_SOC_NOPM, 0, 0),
++	SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
+ 			SND_SOC_NOPM, 0, 0),
+-
+-	/* Analog PGAs */
+-	SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
+-			0, 0, NULL, 0),
+-	SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
+-			0, 0, NULL, 0),
+-	SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL,
+-			0, 0, NULL, 0),
+-	SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
+-			0, 0, NULL, 0),
+ 
+ 	/* Analog bypasses */
+ 	SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
+@@ -981,6 +1204,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ 	SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
+ 			&twl4030_dapm_abypassl2_control,
+ 			bypass_event, SND_SOC_DAPM_POST_REG),
++	SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_abypassv_control,
++			bypass_event, SND_SOC_DAPM_POST_REG),
+ 
+ 	/* Digital bypasses */
+ 	SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
+@@ -989,43 +1215,103 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ 	SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
+ 			&twl4030_dapm_dbypassr_control, bypass_event,
+ 			SND_SOC_DAPM_POST_REG),
++	SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_dbypassv_control, bypass_event,
++			SND_SOC_DAPM_POST_REG),
+ 
+-	SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL,
+-			0, 0, NULL, 0),
+-	SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", TWL4030_REG_AVDAC_CTL,
+-			1, 0, NULL, 0),
+-	SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
+-			2, 0, NULL, 0),
+-	SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
+-			3, 0, NULL, 0),
+-
+-	/* Output MUX controls */
++	/* Digital mixers, power control for the physical DACs */
++	SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
++			TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Digital L1 Playback Mixer",
++			TWL4030_REG_AVDAC_CTL, 1, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Digital R2 Playback Mixer",
++			TWL4030_REG_AVDAC_CTL, 2, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Digital L2 Playback Mixer",
++			TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Digital Voice Playback Mixer",
++			TWL4030_REG_AVDAC_CTL, 4, 0, NULL, 0),
++
++	/* Analog mixers, power control for the physical PGAs */
++	SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer",
++			TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer",
++			TWL4030_REG_ARXL1_APGA_CTL, 0, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer",
++			TWL4030_REG_ARXR2_APGA_CTL, 0, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer",
++			TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
++			TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
++
++	/* Output MIXER controls */
+ 	/* Earpiece */
+-	SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_earpiece_control),
++	SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_earpiece_controls[0],
++			ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
++	SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, earpiecepga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+ 	/* PreDrivL/R */
+-	SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_predrivel_control),
+-	SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_predriver_control),
++	SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_predrivel_controls[0],
++			ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
++	SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, predrivelpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_predriver_controls[0],
++			ARRAY_SIZE(twl4030_dapm_predriver_controls)),
++	SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, predriverpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+ 	/* HeadsetL/R */
+-	SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_hsol_control, headsetl_event,
+-		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+-	SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_hsor_control),
++	SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_hsol_controls[0],
++			ARRAY_SIZE(twl4030_dapm_hsol_controls)),
++	SND_SOC_DAPM_PGA_E("HeadsetL PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, headsetlpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_hsor_controls[0],
++			ARRAY_SIZE(twl4030_dapm_hsor_controls)),
++	SND_SOC_DAPM_PGA_E("HeadsetR PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, headsetrpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+ 	/* CarkitL/R */
+-	SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_carkitl_control),
+-	SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
+-		&twl4030_dapm_carkitr_control),
++	SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_carkitl_controls[0],
++			ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
++	SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, carkitlpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_carkitr_controls[0],
++			ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
++	SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, carkitrpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++
++	/* Output MUX controls */
+ 	/* HandsfreeL/R */
+-	SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
+-		&twl4030_dapm_handsfreel_control, handsfree_event,
+-		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+-	SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
+-		&twl4030_dapm_handsfreer_control, handsfree_event,
+-		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
++		&twl4030_dapm_handsfreel_control),
++	SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_handsfreelmute_control),
++	SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, handsfreelpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++	SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
++		&twl4030_dapm_handsfreer_control),
++	SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
++			&twl4030_dapm_handsfreermute_control),
++	SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
++			0, 0, NULL, 0, handsfreerpga_event,
++			SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++	/* Vibra */
++	SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
++		&twl4030_dapm_vibra_control),
++	SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
++		&twl4030_dapm_vibrapath_control),
+ 
+ 	/* Introducing four virtual ADC, since TWL4030 have four channel for
+ 	   capture */
+@@ -1050,11 +1336,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ 		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
+ 		SND_SOC_DAPM_POST_REG),
+ 
+-	/* Analog input muxes with switch for the capture amplifiers */
+-	SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route",
+-		TWL4030_REG_ANAMICL, 4, 0, &twl4030_dapm_analoglmic_control),
+-	SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route",
+-		TWL4030_REG_ANAMICR, 4, 0, &twl4030_dapm_analogrmic_control),
++	/* Analog input mixers for the capture amplifiers */
++	SND_SOC_DAPM_MIXER("Analog Left",
++		TWL4030_REG_ANAMICL, 4, 0,
++		&twl4030_dapm_analoglmic_controls[0],
++		ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
++	SND_SOC_DAPM_MIXER("Analog Right",
++		TWL4030_REG_ANAMICR, 4, 0,
++		&twl4030_dapm_analogrmic_controls[0],
++		ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
+ 
+ 	SND_SOC_DAPM_PGA("ADC Physical Left",
+ 		TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0),
+@@ -1073,74 +1363,103 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ };
+ 
+ static const struct snd_soc_dapm_route intercon[] = {
+-	{"Analog L1 Playback Mixer", NULL, "DAC Left1"},
+-	{"Analog R1 Playback Mixer", NULL, "DAC Right1"},
+-	{"Analog L2 Playback Mixer", NULL, "DAC Left2"},
+-	{"Analog R2 Playback Mixer", NULL, "DAC Right2"},
+-
+-	{"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"},
+-	{"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"},
+-	{"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"},
+-	{"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"},
++	{"Digital L1 Playback Mixer", NULL, "DAC Left1"},
++	{"Digital R1 Playback Mixer", NULL, "DAC Right1"},
++	{"Digital L2 Playback Mixer", NULL, "DAC Left2"},
++	{"Digital R2 Playback Mixer", NULL, "DAC Right2"},
++	{"Digital Voice Playback Mixer", NULL, "DAC Voice"},
++
++	{"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
++	{"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
++	{"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
++	{"Analog R2 Playback Mixer", NULL, "Digital R2 Playback Mixer"},
++	{"Analog Voice Playback Mixer", NULL, "Digital Voice Playback Mixer"},
+ 
+ 	/* Internal playback routings */
+ 	/* Earpiece */
+-	{"Earpiece Mux", "DACL1", "ARXL1_APGA"},
+-	{"Earpiece Mux", "DACL2", "ARXL2_APGA"},
+-	{"Earpiece Mux", "DACR1", "ARXR1_APGA"},
++	{"Earpiece Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
++	{"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
++	{"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
++	{"Earpiece PGA", NULL, "Earpiece Mixer"},
+ 	/* PreDrivL */
+-	{"PredriveL Mux", "DACL1", "ARXL1_APGA"},
+-	{"PredriveL Mux", "DACL2", "ARXL2_APGA"},
+-	{"PredriveL Mux", "DACR2", "ARXR2_APGA"},
++	{"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
++	{"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
++	{"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
++	{"PredriveL PGA", NULL, "PredriveL Mixer"},
+ 	/* PreDrivR */
+-	{"PredriveR Mux", "DACR1", "ARXR1_APGA"},
+-	{"PredriveR Mux", "DACR2", "ARXR2_APGA"},
+-	{"PredriveR Mux", "DACL2", "ARXL2_APGA"},
++	{"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
++	{"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
++	{"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
++	{"PredriveR PGA", NULL, "PredriveR Mixer"},
+ 	/* HeadsetL */
+-	{"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
+-	{"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
++	{"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
++	{"HeadsetL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
++	{"HeadsetL PGA", NULL, "HeadsetL Mixer"},
+ 	/* HeadsetR */
+-	{"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
+-	{"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
++	{"HeadsetR Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"HeadsetR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
++	{"HeadsetR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
++	{"HeadsetR PGA", NULL, "HeadsetR Mixer"},
+ 	/* CarkitL */
+-	{"CarkitL Mux", "DACL1", "ARXL1_APGA"},
+-	{"CarkitL Mux", "DACL2", "ARXL2_APGA"},
++	{"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
++	{"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
++	{"CarkitL PGA", NULL, "CarkitL Mixer"},
+ 	/* CarkitR */
+-	{"CarkitR Mux", "DACR1", "ARXR1_APGA"},
+-	{"CarkitR Mux", "DACR2", "ARXR2_APGA"},
++	{"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
++	{"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
++	{"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
++	{"CarkitR PGA", NULL, "CarkitR Mixer"},
+ 	/* HandsfreeL */
+-	{"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
+-	{"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
+-	{"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
++	{"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
++	{"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
++	{"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
++	{"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
++	{"HandsfreeL", "Switch", "HandsfreeL Mux"},
++	{"HandsfreeL PGA", NULL, "HandsfreeL"},
+ 	/* HandsfreeR */
+-	{"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
+-	{"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
+-	{"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
++	{"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
++	{"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
++	{"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
++	{"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
++	{"HandsfreeR", "Switch", "HandsfreeR Mux"},
++	{"HandsfreeR PGA", NULL, "HandsfreeR"},
++	/* Vibra */
++	{"Vibra Mux", "AudioL1", "DAC Left1"},
++	{"Vibra Mux", "AudioR1", "DAC Right1"},
++	{"Vibra Mux", "AudioL2", "DAC Left2"},
++	{"Vibra Mux", "AudioR2", "DAC Right2"},
+ 
+ 	/* outputs */
+-	{"OUTL", NULL, "ARXL2_APGA"},
+-	{"OUTR", NULL, "ARXR2_APGA"},
+-	{"EARPIECE", NULL, "Earpiece Mux"},
+-	{"PREDRIVEL", NULL, "PredriveL Mux"},
+-	{"PREDRIVER", NULL, "PredriveR Mux"},
+-	{"HSOL", NULL, "HeadsetL Mux"},
+-	{"HSOR", NULL, "HeadsetR Mux"},
+-	{"CARKITL", NULL, "CarkitL Mux"},
+-	{"CARKITR", NULL, "CarkitR Mux"},
+-	{"HFL", NULL, "HandsfreeL Mux"},
+-	{"HFR", NULL, "HandsfreeR Mux"},
++	{"OUTL", NULL, "Analog L2 Playback Mixer"},
++	{"OUTR", NULL, "Analog R2 Playback Mixer"},
++	{"EARPIECE", NULL, "Earpiece PGA"},
++	{"PREDRIVEL", NULL, "PredriveL PGA"},
++	{"PREDRIVER", NULL, "PredriveR PGA"},
++	{"HSOL", NULL, "HeadsetL PGA"},
++	{"HSOR", NULL, "HeadsetR PGA"},
++	{"CARKITL", NULL, "CarkitL PGA"},
++	{"CARKITR", NULL, "CarkitR PGA"},
++	{"HFL", NULL, "HandsfreeL PGA"},
++	{"HFR", NULL, "HandsfreeR PGA"},
++	{"Vibra Route", "Audio", "Vibra Mux"},
++	{"VIBRA", NULL, "Vibra Route"},
+ 
+ 	/* Capture path */
+-	{"Analog Left Capture Route", "Main mic", "MAINMIC"},
+-	{"Analog Left Capture Route", "Headset mic", "HSMIC"},
+-	{"Analog Left Capture Route", "AUXL", "AUXL"},
+-	{"Analog Left Capture Route", "Carkit mic", "CARKITMIC"},
++	{"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
++	{"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
++	{"Analog Left", "AUXL Capture Switch", "AUXL"},
++	{"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
+ 
+-	{"Analog Right Capture Route", "Sub mic", "SUBMIC"},
+-	{"Analog Right Capture Route", "AUXR", "AUXR"},
++	{"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
++	{"Analog Right", "AUXR Capture Switch", "AUXR"},
+ 
+-	{"ADC Physical Left", NULL, "Analog Left Capture Route"},
+-	{"ADC Physical Right", NULL, "Analog Right Capture Route"},
++	{"ADC Physical Left", NULL, "Analog Left"},
++	{"ADC Physical Right", NULL, "Analog Right"},
+ 
+ 	{"Digimic0 Enable", NULL, "DIGIMIC0"},
+ 	{"Digimic1 Enable", NULL, "DIGIMIC1"},
+@@ -1164,22 +1483,26 @@ static const struct snd_soc_dapm_route intercon[] = {
+ 	{"ADC Virtual Right2", NULL, "TX2 Capture Route"},
+ 
+ 	/* Analog bypass routes */
+-	{"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"},
+-	{"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"},
+-	{"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"},
+-	{"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"},
++	{"Right1 Analog Loopback", "Switch", "Analog Right"},
++	{"Left1 Analog Loopback", "Switch", "Analog Left"},
++	{"Right2 Analog Loopback", "Switch", "Analog Right"},
++	{"Left2 Analog Loopback", "Switch", "Analog Left"},
++	{"Voice Analog Loopback", "Switch", "Analog Left"},
+ 
+ 	{"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
+ 	{"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
+ 	{"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
+ 	{"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
++	{"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
+ 
+ 	/* Digital bypass routes */
+ 	{"Right Digital Loopback", "Volume", "TX1 Capture Route"},
+ 	{"Left Digital Loopback", "Volume", "TX1 Capture Route"},
++	{"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
+ 
+-	{"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"},
+-	{"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"},
++	{"Digital R2 Playback Mixer", NULL, "Right Digital Loopback"},
++	{"Digital L2 Playback Mixer", NULL, "Left Digital Loopback"},
++	{"Digital Voice Playback Mixer", NULL, "Voice Digital Loopback"},
+ 
+ };
+ 
+@@ -1226,6 +1549,58 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
+ 	return 0;
+ }
+ 
++static void twl4030_constraints(struct twl4030_priv *twl4030,
++				struct snd_pcm_substream *mst_substream)
++{
++	struct snd_pcm_substream *slv_substream;
++
++	/* Pick the stream, which need to be constrained */
++	if (mst_substream == twl4030->master_substream)
++		slv_substream = twl4030->slave_substream;
++	else if (mst_substream == twl4030->slave_substream)
++		slv_substream = twl4030->master_substream;
++	else /* This should not happen.. */
++		return;
++
++	/* Set the constraints according to the already configured stream */
++	snd_pcm_hw_constraint_minmax(slv_substream->runtime,
++				SNDRV_PCM_HW_PARAM_RATE,
++				twl4030->rate,
++				twl4030->rate);
++
++	snd_pcm_hw_constraint_minmax(slv_substream->runtime,
++				SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
++				twl4030->sample_bits,
++				twl4030->sample_bits);
++
++	snd_pcm_hw_constraint_minmax(slv_substream->runtime,
++				SNDRV_PCM_HW_PARAM_CHANNELS,
++				twl4030->channels,
++				twl4030->channels);
++}
++
++/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
++ * capture has to be enabled/disabled. */
++static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
++				int enable)
++{
++	u8 reg, mask;
++
++	reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
++
++	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
++		mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
++	else
++		mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
++
++	if (enable)
++		reg |= mask;
++	else
++		reg &= ~mask;
++
++	twl4030_write(codec, TWL4030_REG_OPTION, reg);
++}
++
+ static int twl4030_startup(struct snd_pcm_substream *substream,
+ 			   struct snd_soc_dai *dai)
+ {
+@@ -1234,26 +1609,25 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	struct twl4030_priv *twl4030 = codec->private_data;
+ 
+-	/* If we already have a playback or capture going then constrain
+-	 * this substream to match it.
+-	 */
+ 	if (twl4030->master_substream) {
+-		struct snd_pcm_runtime *master_runtime;
+-		master_runtime = twl4030->master_substream->runtime;
+-
+-		snd_pcm_hw_constraint_minmax(substream->runtime,
+-					     SNDRV_PCM_HW_PARAM_RATE,
+-					     master_runtime->rate,
+-					     master_runtime->rate);
+-
+-		snd_pcm_hw_constraint_minmax(substream->runtime,
+-					     SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+-					     master_runtime->sample_bits,
+-					     master_runtime->sample_bits);
+-
+ 		twl4030->slave_substream = substream;
+-	} else
++		/* The DAI has one configuration for playback and capture, so
++		 * if the DAI has been already configured then constrain this
++		 * substream to match it. */
++		if (twl4030->configured)
++			twl4030_constraints(twl4030, twl4030->master_substream);
++	} else {
++		if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) &
++			TWL4030_OPTION_1)) {
++			/* In option2 4 channel is not supported, set the
++			 * constraint for the first stream for channels, the
++			 * second stream will 'inherit' this cosntraint */
++			snd_pcm_hw_constraint_minmax(substream->runtime,
++						SNDRV_PCM_HW_PARAM_CHANNELS,
++						2, 2);
++		}
+ 		twl4030->master_substream = substream;
++	}
+ 
+ 	return 0;
+ }
+@@ -1270,6 +1644,17 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
+ 		twl4030->master_substream = twl4030->slave_substream;
+ 
+ 	twl4030->slave_substream = NULL;
++
++	/* If all streams are closed, or the remaining stream has not yet
++	 * been configured than set the DAI as not configured. */
++	if (!twl4030->master_substream)
++		twl4030->configured = 0;
++	 else if (!twl4030->master_substream->runtime->channels)
++		twl4030->configured = 0;
++
++	 /* If the closing substream had 4 channel, do the necessary cleanup */
++	if (substream->runtime->channels == 4)
++		twl4030_tdm_enable(codec, substream->stream, 0);
+ }
+ 
+ static int twl4030_hw_params(struct snd_pcm_substream *substream,
+@@ -1282,8 +1667,22 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
+ 	struct twl4030_priv *twl4030 = codec->private_data;
+ 	u8 mode, old_mode, format, old_format;
+ 
+-	if (substream == twl4030->slave_substream)
+-		/* Ignoring hw_params for slave substream */
++	 /* If the substream has 4 channel, do the necessary setup */
++	if (params_channels(params) == 4) {
++		format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
++		mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
++
++		/* Safety check: are we in the correct operating mode and
++		 * the interface is in TDM mode? */
++		if ((mode & TWL4030_OPTION_1) &&
++		    ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
++			twl4030_tdm_enable(codec, substream->stream, 1);
++		else
++			return -EINVAL;
++	}
++
++	if (twl4030->configured)
++		/* Ignoring hw_params for already configured DAI */
+ 		return 0;
+ 
+ 	/* bit rate */
+@@ -1363,6 +1762,21 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
+ 		/* set CODECPDZ afterwards */
+ 		twl4030_codec_enable(codec, 1);
+ 	}
++
++	/* Store the important parameters for the DAI configuration and set
++	 * the DAI as configured */
++	twl4030->configured = 1;
++	twl4030->rate = params_rate(params);
++	twl4030->sample_bits = hw_param_interval(params,
++					SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
++	twl4030->channels = params_channels(params);
++
++	/* If both playback and capture streams are open, and one of them
++	 * is setting the hw parameters right now (since we are here), set
++	 * constraints to the other stream to match the current one. */
++	if (twl4030->slave_substream)
++		twl4030_constraints(twl4030, substream);
++
+ 	return 0;
+ }
+ 
+@@ -1370,17 +1784,21 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ 		int clk_id, unsigned int freq, int dir)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
++	struct twl4030_priv *twl4030 = codec->private_data;
+ 	u8 infreq;
+ 
+ 	switch (freq) {
+ 	case 19200000:
+ 		infreq = TWL4030_APLL_INFREQ_19200KHZ;
++		twl4030->sysclk = 19200;
+ 		break;
+ 	case 26000000:
+ 		infreq = TWL4030_APLL_INFREQ_26000KHZ;
++		twl4030->sysclk = 26000;
+ 		break;
+ 	case 38400000:
+ 		infreq = TWL4030_APLL_INFREQ_38400KHZ;
++		twl4030->sysclk = 38400;
+ 		break;
+ 	default:
+ 		printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
+@@ -1424,6 +1842,9 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	case SND_SOC_DAIFMT_I2S:
+ 		format |= TWL4030_AIF_FORMAT_CODEC;
+ 		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		format |= TWL4030_AIF_FORMAT_TDM;
++		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -1443,6 +1864,206 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	return 0;
+ }
+ 
++static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
++
++	if (tristate)
++		reg |= TWL4030_AIF_TRI_EN;
++	else
++		reg &= ~TWL4030_AIF_TRI_EN;
++
++	return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
++}
++
++/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
++ * (VTXL, VTXR) for uplink has to be enabled/disabled. */
++static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
++				int enable)
++{
++	u8 reg, mask;
++
++	reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
++
++	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
++		mask = TWL4030_ARXL1_VRX_EN;
++	else
++		mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
++
++	if (enable)
++		reg |= mask;
++	else
++		reg &= ~mask;
++
++	twl4030_write(codec, TWL4030_REG_OPTION, reg);
++}
++
++static int twl4030_voice_startup(struct snd_pcm_substream *substream,
++		struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->card->codec;
++	u8 infreq;
++	u8 mode;
++
++	/* If the system master clock is not 26MHz, the voice PCM interface is
++	 * not avilable.
++	 */
++	infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL)
++		& TWL4030_APLL_INFREQ;
++
++	if (infreq != TWL4030_APLL_INFREQ_26000KHZ) {
++		printk(KERN_ERR "TWL4030 voice startup: "
++			"MCLK is not 26MHz, call set_sysclk() on init\n");
++		return -EINVAL;
++	}
++
++	/* If the codec mode is not option2, the voice PCM interface is not
++	 * avilable.
++	 */
++	mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
++		& TWL4030_OPT_MODE;
++
++	if (mode != TWL4030_OPTION_2) {
++		printk(KERN_ERR "TWL4030 voice startup: "
++			"the codec mode is not option2\n");
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
++				struct snd_soc_dai *dai)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->card->codec;
++
++	/* Enable voice digital filters */
++	twl4030_voice_enable(codec, substream->stream, 0);
++}
++
++static int twl4030_voice_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_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->card->codec;
++	u8 old_mode, mode;
++
++	/* Enable voice digital filters */
++	twl4030_voice_enable(codec, substream->stream, 1);
++
++	/* bit rate */
++	old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
++		& ~(TWL4030_CODECPDZ);
++	mode = old_mode;
++
++	switch (params_rate(params)) {
++	case 8000:
++		mode &= ~(TWL4030_SEL_16K);
++		break;
++	case 16000:
++		mode |= TWL4030_SEL_16K;
++		break;
++	default:
++		printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n",
++			params_rate(params));
++		return -EINVAL;
++	}
++
++	if (mode != old_mode) {
++		/* change rate and set CODECPDZ */
++		twl4030_codec_enable(codec, 0);
++		twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
++		twl4030_codec_enable(codec, 1);
++	}
++
++	return 0;
++}
++
++static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 infreq;
++
++	switch (freq) {
++	case 26000000:
++		infreq = TWL4030_APLL_INFREQ_26000KHZ;
++		break;
++	default:
++		printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n",
++			freq);
++		return -EINVAL;
++	}
++
++	infreq |= TWL4030_APLL_EN;
++	twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
++
++	return 0;
++}
++
++static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 old_format, format;
++
++	/* get format */
++	old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
++	format = old_format;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		format &= ~(TWL4030_VIF_SLAVE_EN);
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		format |= TWL4030_VIF_SLAVE_EN;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_IB_NF:
++		format &= ~(TWL4030_VIF_FORMAT);
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		format |= TWL4030_VIF_FORMAT;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	if (format != old_format) {
++		/* change format and set CODECPDZ */
++		twl4030_codec_enable(codec, 0);
++		twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
++		twl4030_codec_enable(codec, 1);
++	}
++
++	return 0;
++}
++
++static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
++
++	if (tristate)
++		reg |= TWL4030_VIF_TRI_EN;
++	else
++		reg &= ~TWL4030_VIF_TRI_EN;
++
++	return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
++}
++
+ #define TWL4030_RATES	 (SNDRV_PCM_RATE_8000_48000)
+ #define TWL4030_FORMATS	 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
+ 
+@@ -1452,23 +2073,51 @@ static struct snd_soc_dai_ops twl4030_dai_ops = {
+ 	.hw_params	= twl4030_hw_params,
+ 	.set_sysclk	= twl4030_set_dai_sysclk,
+ 	.set_fmt	= twl4030_set_dai_fmt,
++	.set_tristate	= twl4030_set_tristate,
++};
++
++static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
++	.startup	= twl4030_voice_startup,
++	.shutdown	= twl4030_voice_shutdown,
++	.hw_params	= twl4030_voice_hw_params,
++	.set_sysclk	= twl4030_voice_set_dai_sysclk,
++	.set_fmt	= twl4030_voice_set_dai_fmt,
++	.set_tristate	= twl4030_voice_set_tristate,
+ };
+ 
+-struct snd_soc_dai twl4030_dai = {
++struct snd_soc_dai twl4030_dai[] = {
++{
+ 	.name = "twl4030",
+ 	.playback = {
+-		.stream_name = "Playback",
++		.stream_name = "HiFi Playback",
+ 		.channels_min = 2,
+-		.channels_max = 2,
++		.channels_max = 4,
+ 		.rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
+ 		.formats = TWL4030_FORMATS,},
+ 	.capture = {
+ 		.stream_name = "Capture",
+ 		.channels_min = 2,
+-		.channels_max = 2,
++		.channels_max = 4,
+ 		.rates = TWL4030_RATES,
+ 		.formats = TWL4030_FORMATS,},
+ 	.ops = &twl4030_dai_ops,
++},
++{
++	.name = "twl4030 Voice",
++	.playback = {
++		.stream_name = "Voice Playback",
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.ops = &twl4030_dai_voice_ops,
++},
+ };
+ EXPORT_SYMBOL_GPL(twl4030_dai);
+ 
+@@ -1500,6 +2149,8 @@ static int twl4030_resume(struct platform_device *pdev)
+ static int twl4030_init(struct snd_soc_device *socdev)
+ {
+ 	struct snd_soc_codec *codec = socdev->card->codec;
++	struct twl4030_setup_data *setup = socdev->codec_data;
++	struct twl4030_priv *twl4030 = codec->private_data;
+ 	int ret = 0;
+ 
+ 	printk(KERN_INFO "TWL4030 Audio Codec init \n");
+@@ -1509,14 +2160,31 @@ static int twl4030_init(struct snd_soc_device *socdev)
+ 	codec->read = twl4030_read_reg_cache;
+ 	codec->write = twl4030_write;
+ 	codec->set_bias_level = twl4030_set_bias_level;
+-	codec->dai = &twl4030_dai;
+-	codec->num_dai = 1;
++	codec->dai = twl4030_dai;
++	codec->num_dai = ARRAY_SIZE(twl4030_dai),
+ 	codec->reg_cache_size = sizeof(twl4030_reg);
+ 	codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
+ 					GFP_KERNEL);
+ 	if (codec->reg_cache == NULL)
+ 		return -ENOMEM;
+ 
++	/* Configuration for headset ramp delay from setup data */
++	if (setup) {
++		unsigned char hs_pop;
++
++		if (setup->sysclk)
++			twl4030->sysclk = setup->sysclk;
++		else
++			twl4030->sysclk = 26000;
++
++		hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
++		hs_pop &= ~TWL4030_RAMP_DELAY;
++		hs_pop |= (setup->ramp_delay_value << 2);
++		twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
++	} else {
++		twl4030->sysclk = 26000;
++	}
++
+ 	/* register pcms */
+ 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ 	if (ret < 0) {
+@@ -1604,13 +2272,13 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
+ 
+ static int __init twl4030_modinit(void)
+ {
+-	return snd_soc_register_dai(&twl4030_dai);
++	return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
+ }
+ module_init(twl4030_modinit);
+ 
+ static void __exit twl4030_exit(void)
+ {
+-	snd_soc_unregister_dai(&twl4030_dai);
++	snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
+ }
+ module_exit(twl4030_exit);
+ 
+diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
+index cb63765..2b4bfa2 100644
+--- a/sound/soc/codecs/twl4030.h
++++ b/sound/soc/codecs/twl4030.h
+@@ -92,8 +92,9 @@
+ #define TWL4030_REG_VIBRA_PWM_SET	0x47
+ #define TWL4030_REG_ANAMIC_GAIN		0x48
+ #define TWL4030_REG_MISC_SET_2		0x49
++#define TWL4030_REG_SW_SHADOW		0x4A
+ 
+-#define TWL4030_CACHEREGNUM	(TWL4030_REG_MISC_SET_2 + 1)
++#define TWL4030_CACHEREGNUM	(TWL4030_REG_SW_SHADOW + 1)
+ 
+ /* Bitfield Definitions */
+ 
+@@ -110,9 +111,22 @@
+ #define TWL4030_APLL_RATE_44100		0x90
+ #define TWL4030_APLL_RATE_48000		0xA0
+ #define TWL4030_APLL_RATE_96000		0xE0
+-#define TWL4030_SEL_16K			0x04
++#define TWL4030_SEL_16K			0x08
+ #define TWL4030_CODECPDZ		0x02
+ #define TWL4030_OPT_MODE		0x01
++#define TWL4030_OPTION_1		(1 << 0)
++#define TWL4030_OPTION_2		(0 << 0)
++
++/* TWL4030_OPTION (0x02) Fields */
++
++#define TWL4030_ATXL1_EN		(1 << 0)
++#define TWL4030_ATXR1_EN		(1 << 1)
++#define TWL4030_ATXL2_VTXL_EN		(1 << 2)
++#define TWL4030_ATXR2_VTXR_EN		(1 << 3)
++#define TWL4030_ARXL1_VRX_EN		(1 << 4)
++#define TWL4030_ARXR1_EN		(1 << 5)
++#define TWL4030_ARXL2_EN		(1 << 6)
++#define TWL4030_ARXR2_EN		(1 << 7)
+ 
+ /* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
+ 
+@@ -171,6 +185,17 @@
+ #define TWL4030_CLK256FS_EN		0x02
+ #define TWL4030_AIF_EN			0x01
+ 
++/* VOICE_IF (0x0F) Fields */
++
++#define TWL4030_VIF_SLAVE_EN		0x80
++#define TWL4030_VIF_DIN_EN		0x40
++#define TWL4030_VIF_DOUT_EN		0x20
++#define TWL4030_VIF_SWAP		0x10
++#define TWL4030_VIF_FORMAT		0x08
++#define TWL4030_VIF_TRI_EN		0x04
++#define TWL4030_VIF_SUB_EN		0x02
++#define TWL4030_VIF_EN			0x01
++
+ /* EAR_CTL (0x21) */
+ #define TWL4030_EAR_GAIN		0x30
+ 
+@@ -236,7 +261,21 @@
+ #define TWL4030_SMOOTH_ANAVOL_EN	0x02
+ #define TWL4030_DIGMIC_LR_SWAP_EN	0x01
+ 
+-extern struct snd_soc_dai twl4030_dai;
++/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
++#define TWL4030_HFL_EN			0x01
++#define TWL4030_HFR_EN			0x02
++
++#define TWL4030_DAI_HIFI		0
++#define TWL4030_DAI_VOICE		1
++
++extern struct snd_soc_dai twl4030_dai[2];
+ extern struct snd_soc_codec_device soc_codec_dev_twl4030;
+ 
++struct twl4030_setup_data {
++	unsigned int ramp_delay_value;
++	unsigned int sysclk;
++	unsigned int hs_extmute:1;
++	void (*set_hs_extmute)(int mute);
++};
++
+ #endif	/* End of __TWL4030_AUDIO_H__ */
+diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
+index ddefb8f..c33b92e 100644
+--- a/sound/soc/codecs/uda134x.c
++++ b/sound/soc/codecs/uda134x.c
+@@ -101,7 +101,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
+ 	pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
+ 
+ 	if (reg >= UDA134X_REGS_NUM) {
+-		printk(KERN_ERR "%s unkown register: reg: %d",
++		printk(KERN_ERR "%s unkown register: reg: %u",
+ 		       __func__, reg);
+ 		return -EINVAL;
+ 	}
+@@ -163,7 +163,7 @@ static int uda134x_mute(struct snd_soc_dai *dai, int mute)
+ 	else
+ 		mute_reg &= ~(1<<2);
+ 
+-	uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
++	uda134x_write(codec, UDA134X_DATA010, mute_reg);
+ 
+ 	return 0;
+ }
+@@ -296,7 +296,7 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	struct uda134x_priv *uda134x = codec->private_data;
+ 
+-	pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
++	pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
+ 		 clk_id, freq, dir);
+ 
+ 	/* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
+diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
+index 5b21594..92ec034 100644
+--- a/sound/soc/codecs/uda1380.c
++++ b/sound/soc/codecs/uda1380.c
+@@ -5,9 +5,7 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+- * Copyright (c) 2007 Philipp Zabel <philipp.zabel at gmail.com>
+- * Improved support for DAPM and audio routing/mixing capabilities,
+- * added TLV support.
++ * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel at gmail.com>
+  *
+  * Modified by Richard Purdie <richard at openedhand.com> to fit into SoC
+  * codec model.
+@@ -19,26 +17,32 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/types.h>
+-#include <linux/string.h>
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+-#include <linux/ioctl.h>
++#include <linux/gpio.h>
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/workqueue.h>
+ #include <sound/core.h>
+ #include <sound/control.h>
+ #include <sound/initval.h>
+-#include <sound/info.h>
+ #include <sound/soc.h>
+ #include <sound/soc-dapm.h>
+ #include <sound/tlv.h>
++#include <sound/uda1380.h>
+ 
+ #include "uda1380.h"
+ 
+-static struct work_struct uda1380_work;
+ static struct snd_soc_codec *uda1380_codec;
+ 
++/* codec private data */
++struct uda1380_priv {
++	struct snd_soc_codec codec;
++	u16 reg_cache[UDA1380_CACHEREGNUM];
++	unsigned int dac_clk;
++	struct work_struct work;
++};
++
+ /*
+  * uda1380 register cache
+  */
+@@ -473,6 +477,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
++	struct uda1380_priv *uda1380 = codec->private_data;
+ 	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
+ 
+ 	switch (cmd) {
+@@ -480,13 +485,13 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
+ 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
+ 					mixer & ~R14_SILENCE);
+-		schedule_work(&uda1380_work);
++		schedule_work(&uda1380->work);
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_STOP:
+ 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
+ 					mixer | R14_SILENCE);
+-		schedule_work(&uda1380_work);
++		schedule_work(&uda1380->work);
+ 		break;
+ 	}
+ 	return 0;
+@@ -670,44 +675,33 @@ static int uda1380_resume(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-/*
+- * initialise the UDA1380 driver
+- * register mixer and dsp interfaces with the kernel
+- */
+-static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
++static int uda1380_probe(struct platform_device *pdev)
+ {
+-	struct snd_soc_codec *codec = socdev->card->codec;
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec;
++	struct uda1380_platform_data *pdata;
+ 	int ret = 0;
+ 
+-	codec->name = "UDA1380";
+-	codec->owner = THIS_MODULE;
+-	codec->read = uda1380_read_reg_cache;
+-	codec->write = uda1380_write;
+-	codec->set_bias_level = uda1380_set_bias_level;
+-	codec->dai = uda1380_dai;
+-	codec->num_dai = ARRAY_SIZE(uda1380_dai);
+-	codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg),
+-				   GFP_KERNEL);
+-	if (codec->reg_cache == NULL)
+-		return -ENOMEM;
+-	codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
+-	codec->reg_cache_step = 1;
+-	uda1380_reset(codec);
++	if (uda1380_codec == NULL) {
++		dev_err(&pdev->dev, "Codec device not registered\n");
++		return -ENODEV;
++	}
+ 
+-	uda1380_codec = codec;
+-	INIT_WORK(&uda1380_work, uda1380_flush_work);
++	socdev->card->codec = uda1380_codec;
++	codec = uda1380_codec;
++	pdata = codec->dev->platform_data;
+ 
+ 	/* register pcms */
+ 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ 	if (ret < 0) {
+-		pr_err("uda1380: failed to create pcms\n");
++		dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+ 		goto pcm_err;
+ 	}
+ 
+ 	/* power on device */
+ 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ 	/* set clock input */
+-	switch (dac_clk) {
++	switch (pdata->dac_clk) {
+ 	case UDA1380_DAC_CLK_SYSCLK:
+ 		uda1380_write(codec, UDA1380_CLK, 0);
+ 		break;
+@@ -716,13 +710,12 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
+ 		break;
+ 	}
+ 
+-	/* uda1380 init */
+ 	snd_soc_add_controls(codec, uda1380_snd_controls,
+ 				ARRAY_SIZE(uda1380_snd_controls));
+ 	uda1380_add_widgets(codec);
+ 	ret = snd_soc_init_card(socdev);
+ 	if (ret < 0) {
+-		pr_err("uda1380: failed to register card\n");
++		dev_err(codec->dev, "failed to register card: %d\n", ret);
+ 		goto card_err;
+ 	}
+ 
+@@ -732,165 +725,201 @@ card_err:
+ 	snd_soc_free_pcms(socdev);
+ 	snd_soc_dapm_free(socdev);
+ pcm_err:
+-	kfree(codec->reg_cache);
+ 	return ret;
+ }
+ 
+-static struct snd_soc_device *uda1380_socdev;
+-
+-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+-
+-static int uda1380_i2c_probe(struct i2c_client *i2c,
+-			     const struct i2c_device_id *id)
++/* power down chip */
++static int uda1380_remove(struct platform_device *pdev)
+ {
+-	struct snd_soc_device *socdev = uda1380_socdev;
+-	struct uda1380_setup_data *setup = socdev->codec_data;
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+-	int ret;
+-
+-	i2c_set_clientdata(i2c, codec);
+-	codec->control_data = i2c;
+ 
+-	ret = uda1380_init(socdev, setup->dac_clk);
+-	if (ret < 0)
+-		pr_err("uda1380: failed to initialise UDA1380\n");
++	if (codec->control_data)
++		uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ 
+-	return ret;
+-}
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
+ 
+-static int uda1380_i2c_remove(struct i2c_client *client)
+-{
+-	struct snd_soc_codec *codec = i2c_get_clientdata(client);
+-	kfree(codec->reg_cache);
+ 	return 0;
+ }
+ 
+-static const struct i2c_device_id uda1380_i2c_id[] = {
+-	{ "uda1380", 0 },
+-	{ }
+-};
+-MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
+-
+-static struct i2c_driver uda1380_i2c_driver = {
+-	.driver = {
+-		.name =  "UDA1380 I2C Codec",
+-		.owner = THIS_MODULE,
+-	},
+-	.probe =    uda1380_i2c_probe,
+-	.remove =   uda1380_i2c_remove,
+-	.id_table = uda1380_i2c_id,
++struct snd_soc_codec_device soc_codec_dev_uda1380 = {
++	.probe = 	uda1380_probe,
++	.remove = 	uda1380_remove,
++	.suspend = 	uda1380_suspend,
++	.resume =	uda1380_resume,
+ };
++EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
+ 
+-static int uda1380_add_i2c_device(struct platform_device *pdev,
+-				  const struct uda1380_setup_data *setup)
++static int uda1380_register(struct uda1380_priv *uda1380)
+ {
+-	struct i2c_board_info info;
+-	struct i2c_adapter *adapter;
+-	struct i2c_client *client;
+-	int ret;
++	int ret, i;
++	struct snd_soc_codec *codec = &uda1380->codec;
++	struct uda1380_platform_data *pdata = codec->dev->platform_data;
+ 
+-	ret = i2c_add_driver(&uda1380_i2c_driver);
+-	if (ret != 0) {
+-		dev_err(&pdev->dev, "can't add i2c driver\n");
+-		return ret;
++	if (uda1380_codec) {
++		dev_err(codec->dev, "Another UDA1380 is registered\n");
++		return -EINVAL;
++	}
++
++	if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
++		return -EINVAL;
++
++	ret = gpio_request(pdata->gpio_power, "uda1380 power");
++	if (ret)
++		goto err_out;
++	ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
++	if (ret)
++		goto err_gpio;
++
++	gpio_direction_output(pdata->gpio_power, 1);
++
++	/* we may need to have the clock running here - pH5 */
++	gpio_direction_output(pdata->gpio_reset, 1);
++	udelay(5);
++	gpio_set_value(pdata->gpio_reset, 0);
++
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++
++	codec->private_data = uda1380;
++	codec->name = "UDA1380";
++	codec->owner = THIS_MODULE;
++	codec->read = uda1380_read_reg_cache;
++	codec->write = uda1380_write;
++	codec->bias_level = SND_SOC_BIAS_OFF;
++	codec->set_bias_level = uda1380_set_bias_level;
++	codec->dai = uda1380_dai;
++	codec->num_dai = ARRAY_SIZE(uda1380_dai);
++	codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
++	codec->reg_cache = &uda1380->reg_cache;
++	codec->reg_cache_step = 1;
++
++	memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
++
++	ret = uda1380_reset(codec);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to issue reset\n");
++		goto err_reset;
+ 	}
+ 
+-	memset(&info, 0, sizeof(struct i2c_board_info));
+-	info.addr = setup->i2c_address;
+-	strlcpy(info.type, "uda1380", I2C_NAME_SIZE);
++	INIT_WORK(&uda1380->work, uda1380_flush_work);
++
++	for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++)
++		uda1380_dai[i].dev = codec->dev;
+ 
+-	adapter = i2c_get_adapter(setup->i2c_bus);
+-	if (!adapter) {
+-		dev_err(&pdev->dev, "can't get i2c adapter %d\n",
+-			setup->i2c_bus);
+-		goto err_driver;
++	uda1380_codec = codec;
++
++	ret = snd_soc_register_codec(codec);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
++		goto err_reset;
+ 	}
+ 
+-	client = i2c_new_device(adapter, &info);
+-	i2c_put_adapter(adapter);
+-	if (!client) {
+-		dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
+-			(unsigned int)info.addr);
+-		goto err_driver;
++	ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
++		goto err_dai;
+ 	}
+ 
+ 	return 0;
+ 
+-err_driver:
+-	i2c_del_driver(&uda1380_i2c_driver);
+-	return -ENODEV;
++err_dai:
++	snd_soc_unregister_codec(codec);
++err_reset:
++	gpio_set_value(pdata->gpio_power, 0);
++	gpio_free(pdata->gpio_reset);
++err_gpio:
++	gpio_free(pdata->gpio_power);
++err_out:
++	return ret;
+ }
+-#endif
+ 
+-static int uda1380_probe(struct platform_device *pdev)
++static void uda1380_unregister(struct uda1380_priv *uda1380)
+ {
+-	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+-	struct uda1380_setup_data *setup;
++	struct snd_soc_codec *codec = &uda1380->codec;
++	struct uda1380_platform_data *pdata = codec->dev->platform_data;
++
++	snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
++	snd_soc_unregister_codec(&uda1380->codec);
++
++	gpio_set_value(pdata->gpio_power, 0);
++	gpio_free(pdata->gpio_reset);
++	gpio_free(pdata->gpio_power);
++
++	kfree(uda1380);
++	uda1380_codec = NULL;
++}
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
++				      const struct i2c_device_id *id)
++{
++	struct uda1380_priv *uda1380;
+ 	struct snd_soc_codec *codec;
+ 	int ret;
+ 
+-	setup = socdev->codec_data;
+-	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+-	if (codec == NULL)
++	uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
++	if (uda1380 == NULL)
+ 		return -ENOMEM;
+ 
+-	socdev->card->codec = codec;
+-	mutex_init(&codec->mutex);
+-	INIT_LIST_HEAD(&codec->dapm_widgets);
+-	INIT_LIST_HEAD(&codec->dapm_paths);
++	codec = &uda1380->codec;
++	codec->hw_write = (hw_write_t)i2c_master_send;
+ 
+-	uda1380_socdev = socdev;
+-	ret = -ENODEV;
++	i2c_set_clientdata(i2c, uda1380);
++	codec->control_data = i2c;
+ 
+-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+-	if (setup->i2c_address) {
+-		codec->hw_write = (hw_write_t)i2c_master_send;
+-		ret = uda1380_add_i2c_device(pdev, setup);
+-	}
+-#endif
++	codec->dev = &i2c->dev;
+ 
++	ret = uda1380_register(uda1380);
+ 	if (ret != 0)
+-		kfree(codec);
++		kfree(uda1380);
++
+ 	return ret;
+ }
+ 
+-/* power down chip */
+-static int uda1380_remove(struct platform_device *pdev)
++static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
+ {
+-	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+-	struct snd_soc_codec *codec = socdev->card->codec;
+-
+-	if (codec->control_data)
+-		uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
+-
+-	snd_soc_free_pcms(socdev);
+-	snd_soc_dapm_free(socdev);
+-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+-	i2c_unregister_device(codec->control_data);
+-	i2c_del_driver(&uda1380_i2c_driver);
+-#endif
+-	kfree(codec);
+-
++	struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c);
++	uda1380_unregister(uda1380);
+ 	return 0;
+ }
+ 
+-struct snd_soc_codec_device soc_codec_dev_uda1380 = {
+-	.probe = 	uda1380_probe,
+-	.remove = 	uda1380_remove,
+-	.suspend = 	uda1380_suspend,
+-	.resume =	uda1380_resume,
++static const struct i2c_device_id uda1380_i2c_id[] = {
++	{ "uda1380", 0 },
++	{ }
+ };
+-EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
++MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
++
++static struct i2c_driver uda1380_i2c_driver = {
++	.driver = {
++		.name =  "UDA1380 I2C Codec",
++		.owner = THIS_MODULE,
++	},
++	.probe =    uda1380_i2c_probe,
++	.remove =   __devexit_p(uda1380_i2c_remove),
++	.id_table = uda1380_i2c_id,
++};
++#endif
+ 
+ static int __init uda1380_modinit(void)
+ {
+-	return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
++	int ret;
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	ret = i2c_add_driver(&uda1380_i2c_driver);
++	if (ret != 0)
++		pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
++#endif
++	return 0;
+ }
+ module_init(uda1380_modinit);
+ 
+ static void __exit uda1380_exit(void)
+ {
+-	snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++	i2c_del_driver(&uda1380_i2c_driver);
++#endif
+ }
+ module_exit(uda1380_exit);
+ 
+diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
+index c55c17a..9cefa8a 100644
+--- a/sound/soc/codecs/uda1380.h
++++ b/sound/soc/codecs/uda1380.h
+@@ -72,14 +72,6 @@
+ #define R22_SKIP_DCFIL	0x0002
+ #define R23_AGC_EN	0x0001
+ 
+-struct uda1380_setup_data {
+-	int            i2c_bus;
+-	unsigned short i2c_address;
+-	int            dac_clk;
+-#define UDA1380_DAC_CLK_SYSCLK 0
+-#define UDA1380_DAC_CLK_WSPLL  1
+-};
+-
+ #define UDA1380_DAI_DUPLEX	0 /* playback and capture on single DAI */
+ #define UDA1380_DAI_PLAYBACK	1 /* playback DAI */
+ #define UDA1380_DAI_CAPTURE	2 /* capture DAI */
+diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
+index 0275321..72abc5a 100644
+--- a/sound/soc/codecs/wm8350.c
++++ b/sound/soc/codecs/wm8350.c
+@@ -63,6 +63,8 @@ struct wm8350_data {
+ 	struct wm8350_jack_data hpl;
+ 	struct wm8350_jack_data hpr;
+ 	struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
++	int fll_freq_out;
++	int fll_freq_in;
+ };
+ 
+ static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
+@@ -406,7 +408,6 @@ static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
+ static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
+ static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
+ static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
+-static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
+ static const char *wm8350_adcfilter[] = { "None", "High Pass" };
+ static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
+ static const char *wm8350_lr[] = { "Left", "Right" };
+@@ -416,7 +417,6 @@ static const struct soc_enum wm8350_enum[] = {
+ 	SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
+ 	SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
+ 	SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
+-	SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
+ 	SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
+ 	SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
+ 	SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
+@@ -444,10 +444,9 @@ static const struct snd_kcontrol_new wm8350_snd_controls[] = {
+ 				0, 255, 0, dac_pcm_tlv),
+ 	SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
+ 	SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
+-	SOC_ENUM("Playback PCM Filter", wm8350_enum[4]),
+-	SOC_ENUM("Capture PCM Filter", wm8350_enum[5]),
+-	SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]),
+-	SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
++	SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
++	SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
++	SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
+ 	SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
+ 				WM8350_ADC_DIGITAL_VOLUME_L,
+ 				WM8350_ADC_DIGITAL_VOLUME_R,
+@@ -580,7 +579,7 @@ static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
+ 	SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
+ 			    WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
+ 	SOC_DAPM_SINGLE("PGA Capture Switch",
+-			WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
++			WM8350_LEFT_INPUT_VOLUME, 14, 1, 1),
+ };
+ 
+ /* Right Input Mixer */
+@@ -590,7 +589,7 @@ static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
+ 	SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
+ 			    WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
+ 	SOC_DAPM_SINGLE("PGA Capture Switch",
+-			WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
++			WM8350_RIGHT_INPUT_VOLUME, 14, 1, 1),
+ };
+ 
+ /* Left Mic Mixer */
+@@ -613,7 +612,7 @@ SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
+ 
+ /* Out4 Capture Mux */
+ static const struct snd_kcontrol_new wm8350_out4_capture_controls =
+-SOC_DAPM_ENUM("Route", wm8350_enum[8]);
++SOC_DAPM_ENUM("Route", wm8350_enum[7]);
+ 
+ static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
+ 
+@@ -993,6 +992,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
+ 				struct snd_soc_dai *codec_dai)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
++	struct wm8350 *wm8350 = codec->control_data;
+ 	u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
+ 	    ~WM8350_AIF_WL_MASK;
+ 
+@@ -1012,6 +1012,19 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	}
+ 
+ 	wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
++
++	/* The sloping stopband filter is recommended for use with
++	 * lower sample rates to improve performance.
++	 */
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		if (params_rate(params) < 24000)
++			wm8350_set_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
++					WM8350_DAC_SB_FILT);
++		else
++			wm8350_clear_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
++					  WM8350_DAC_SB_FILT);
++	}
++
+ 	return 0;
+ }
+ 
+@@ -1088,15 +1101,19 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
+ }
+ 
+ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
+-			  int pll_id, unsigned int freq_in,
++			  int pll_id, int source, unsigned int freq_in,
+ 			  unsigned int freq_out)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	struct wm8350 *wm8350 = codec->control_data;
++	struct wm8350_data *priv = codec->private_data;
+ 	struct _fll_div fll_div;
+ 	int ret = 0;
+ 	u16 fll_1, fll_4;
+ 
++	if (freq_in == priv->fll_freq_in && freq_out == priv->fll_freq_out)
++		return 0;
++
+ 	/* power down FLL - we need to do this for reconfiguration */
+ 	wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
+ 			  WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
+@@ -1108,7 +1125,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
+ 	if (ret < 0)
+ 		return ret;
+ 	dev_dbg(wm8350->dev,
+-		"FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d",
++		"FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d",
+ 		freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
+ 		fll_div.ratio);
+ 
+@@ -1131,6 +1148,9 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
+ 	wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
+ 	wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
+ 
++	priv->fll_freq_out = freq_out;
++	priv->fll_freq_in = freq_in;
++
+ 	return 0;
+ }
+ 
+@@ -1660,6 +1680,21 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
++{
++	return snd_soc_suspend_device(&pdev->dev);
++}
++
++static int wm8350_codec_resume(struct platform_device *pdev)
++{
++	return snd_soc_resume_device(&pdev->dev);
++}
++#else
++#define wm8350_codec_suspend NULL
++#define wm8350_codec_resume NULL
++#endif
++
+ static struct platform_driver wm8350_codec_driver = {
+ 	.driver = {
+ 		   .name = "wm8350-codec",
+@@ -1667,6 +1702,8 @@ static struct platform_driver wm8350_codec_driver = {
+ 		   },
+ 	.probe = wm8350_codec_probe,
+ 	.remove = __devexit_p(wm8350_codec_remove),
++	.suspend = wm8350_codec_suspend,
++	.resume = wm8350_codec_resume,
+ };
+ 
+ static __init int wm8350_init(void)
+diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
+index d11bd92..d088eb4 100644
+--- a/sound/soc/codecs/wm8350.h
++++ b/sound/soc/codecs/wm8350.h
+@@ -13,6 +13,7 @@
+ #define _WM8350_H
+ 
+ #include <sound/soc.h>
++#include <linux/mfd/wm8350/audio.h>
+ 
+ extern struct snd_soc_dai wm8350_dai;
+ extern struct snd_soc_codec_device soc_codec_dev_wm8350;
+diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
+index 510efa6..9cb8e50 100644
+--- a/sound/soc/codecs/wm8400.c
++++ b/sound/soc/codecs/wm8400.c
+@@ -954,7 +954,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
+ 		factors->outdiv *= 2;
+ 		if (factors->outdiv > 32) {
+ 			dev_err(wm8400->wm8400->dev,
+-				"Unsupported FLL output frequency %dHz\n",
++				"Unsupported FLL output frequency %uHz\n",
+ 				Fout);
+ 			return -EINVAL;
+ 		}
+@@ -1003,7 +1003,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
+ 	factors->k = K / 10;
+ 
+ 	dev_dbg(wm8400->wm8400->dev,
+-		"FLL: Fref=%d Fout=%d N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
++		"FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
+ 		Fref, Fout,
+ 		factors->n, factors->k, factors->fratio, factors->outdiv);
+ 
+@@ -1011,7 +1011,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
+ }
+ 
+ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+-			      unsigned int freq_in, unsigned int freq_out)
++			      int source, unsigned int freq_in,
++			      unsigned int freq_out)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	struct wm8400_priv *wm8400 = codec->private_data;
+@@ -1022,10 +1023,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ 	if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
+ 		return 0;
+ 
+-	if (freq_out != 0) {
++	if (freq_out) {
+ 		ret = fll_factors(wm8400, &factors, freq_in, freq_out);
+ 		if (ret != 0)
+ 			return ret;
++	} else {
++		/* Bodge GCC 4.4.0 uninitialised variable warning - it
++		 * doesn't seem capable of working out that we exit if
++		 * freq_out is 0 before any of the uses. */
++		memset(&factors, 0, sizeof(factors));
+ 	}
+ 
+ 	wm8400->fll_out = freq_out;
+@@ -1040,7 +1046,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ 	reg &= ~WM8400_FLL_OSC_ENA;
+ 	wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
+ 
+-	if (freq_out == 0)
++	if (!freq_out)
+ 		return 0;
+ 
+ 	reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
+@@ -1473,8 +1479,8 @@ static int wm8400_codec_probe(struct platform_device *dev)
+ 
+ 	codec = &priv->codec;
+ 	codec->private_data = priv;
+-	codec->control_data = dev->dev.driver_data;
+-	priv->wm8400 = dev->dev.driver_data;
++	codec->control_data = dev_get_drvdata(&dev->dev);
++	priv->wm8400 = dev_get_drvdata(&dev->dev);
+ 
+ 	ret = regulator_bulk_get(priv->wm8400->dev,
+ 				 ARRAY_SIZE(power), &power[0]);
+@@ -1553,6 +1559,21 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&pdev->dev);
++}
++
++static int wm8400_pdev_resume(struct platform_device *pdev)
++{
++	return snd_soc_resume_device(&pdev->dev);
++}
++#else
++#define wm8400_pdev_suspend NULL
++#define wm8400_pdev_resume NULL
++#endif
++
+ static struct platform_driver wm8400_codec_driver = {
+ 	.driver = {
+ 		.name = "wm8400-codec",
+@@ -1560,6 +1581,8 @@ static struct platform_driver wm8400_codec_driver = {
+ 	},
+ 	.probe = wm8400_codec_probe,
+ 	.remove	= __exit_p(wm8400_codec_remove),
++	.suspend = wm8400_pdev_suspend,
++	.resume = wm8400_pdev_resume,
+ };
+ 
+ static int __init wm8400_codec_init(void)
+diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
+index 6a4cea0..5702435 100644
+--- a/sound/soc/codecs/wm8510.c
++++ b/sound/soc/codecs/wm8510.c
+@@ -58,55 +58,7 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
+ #define WM8510_POWER1_BIASEN  0x08
+ #define WM8510_POWER1_BUFIOEN 0x10
+ 
+-/*
+- * read wm8510 register cache
+- */
+-static inline unsigned int wm8510_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg == WM8510_RESET)
+-		return 0;
+-	if (reg >= WM8510_CACHEREGNUM)
+-		return -1;
+-	return cache[reg];
+-}
+-
+-/*
+- * write wm8510 register cache
+- */
+-static inline void wm8510_write_reg_cache(struct snd_soc_codec *codec,
+-	u16 reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg >= WM8510_CACHEREGNUM)
+-		return;
+-	cache[reg] = value;
+-}
+-
+-/*
+- * write to the WM8510 register space
+- */
+-static int wm8510_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[2];
+-
+-	/* data is
+-	 *   D15..D9 WM8510 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+-	data[1] = value & 0x00ff;
+-
+-	wm8510_write_reg_cache(codec, reg, value);
+-	if (codec->hw_write(codec->control_data, data, 2) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-#define wm8510_reset(c)	wm8510_write(c, WM8510_RESET, 0)
++#define wm8510_reset(c)	snd_soc_write(c, WM8510_RESET, 0)
+ 
+ static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
+ static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
+@@ -298,7 +250,7 @@ static void pll_factors(unsigned int target, unsigned int source)
+ 
+ 	if ((Ndiv < 6) || (Ndiv > 12))
+ 		printk(KERN_WARNING
+-			"WM8510 N value %d outwith recommended range!d\n",
++			"WM8510 N value %u outwith recommended range!d\n",
+ 			Ndiv);
+ 
+ 	pll_div.n = Ndiv;
+@@ -319,35 +271,35 @@ static void pll_factors(unsigned int target, unsigned int source)
+ 	pll_div.k = K;
+ }
+ 
+-static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out)
++static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	u16 reg;
+ 
+ 	if (freq_in == 0 || freq_out == 0) {
+ 		/* Clock CODEC directly from MCLK */
+-		reg = wm8510_read_reg_cache(codec, WM8510_CLOCK);
+-		wm8510_write(codec, WM8510_CLOCK, reg & 0x0ff);
++		reg = snd_soc_read(codec, WM8510_CLOCK);
++		snd_soc_write(codec, WM8510_CLOCK, reg & 0x0ff);
+ 
+ 		/* Turn off PLL */
+-		reg = wm8510_read_reg_cache(codec, WM8510_POWER1);
+-		wm8510_write(codec, WM8510_POWER1, reg & 0x1df);
++		reg = snd_soc_read(codec, WM8510_POWER1);
++		snd_soc_write(codec, WM8510_POWER1, reg & 0x1df);
+ 		return 0;
+ 	}
+ 
+ 	pll_factors(freq_out*4, freq_in);
+ 
+-	wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
+-	wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18);
+-	wm8510_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
+-	wm8510_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
+-	reg = wm8510_read_reg_cache(codec, WM8510_POWER1);
+-	wm8510_write(codec, WM8510_POWER1, reg | 0x020);
++	snd_soc_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
++	snd_soc_write(codec, WM8510_PLLK1, pll_div.k >> 18);
++	snd_soc_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
++	snd_soc_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
++	reg = snd_soc_read(codec, WM8510_POWER1);
++	snd_soc_write(codec, WM8510_POWER1, reg | 0x020);
+ 
+ 	/* Run CODEC from PLL instead of MCLK */
+-	reg = wm8510_read_reg_cache(codec, WM8510_CLOCK);
+-	wm8510_write(codec, WM8510_CLOCK, reg | 0x100);
++	reg = snd_soc_read(codec, WM8510_CLOCK);
++	snd_soc_write(codec, WM8510_CLOCK, reg | 0x100);
+ 
+ 	return 0;
+ }
+@@ -363,24 +315,24 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 
+ 	switch (div_id) {
+ 	case WM8510_OPCLKDIV:
+-		reg = wm8510_read_reg_cache(codec, WM8510_GPIO) & 0x1cf;
+-		wm8510_write(codec, WM8510_GPIO, reg | div);
++		reg = snd_soc_read(codec, WM8510_GPIO) & 0x1cf;
++		snd_soc_write(codec, WM8510_GPIO, reg | div);
+ 		break;
+ 	case WM8510_MCLKDIV:
+-		reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x11f;
+-		wm8510_write(codec, WM8510_CLOCK, reg | div);
++		reg = snd_soc_read(codec, WM8510_CLOCK) & 0x11f;
++		snd_soc_write(codec, WM8510_CLOCK, reg | div);
+ 		break;
+ 	case WM8510_ADCCLK:
+-		reg = wm8510_read_reg_cache(codec, WM8510_ADC) & 0x1f7;
+-		wm8510_write(codec, WM8510_ADC, reg | div);
++		reg = snd_soc_read(codec, WM8510_ADC) & 0x1f7;
++		snd_soc_write(codec, WM8510_ADC, reg | div);
+ 		break;
+ 	case WM8510_DACCLK:
+-		reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0x1f7;
+-		wm8510_write(codec, WM8510_DAC, reg | div);
++		reg = snd_soc_read(codec, WM8510_DAC) & 0x1f7;
++		snd_soc_write(codec, WM8510_DAC, reg | div);
+ 		break;
+ 	case WM8510_BCLKDIV:
+-		reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1e3;
+-		wm8510_write(codec, WM8510_CLOCK, reg | div);
++		reg = snd_soc_read(codec, WM8510_CLOCK) & 0x1e3;
++		snd_soc_write(codec, WM8510_CLOCK, reg | div);
+ 		break;
+ 	default:
+ 		return -EINVAL;
+@@ -394,7 +346,7 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	u16 iface = 0;
+-	u16 clk = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1fe;
++	u16 clk = snd_soc_read(codec, WM8510_CLOCK) & 0x1fe;
+ 
+ 	/* set master/slave audio interface */
+ 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+@@ -441,8 +393,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8510_write(codec, WM8510_IFACE, iface);
+-	wm8510_write(codec, WM8510_CLOCK, clk);
++	snd_soc_write(codec, WM8510_IFACE, iface);
++	snd_soc_write(codec, WM8510_CLOCK, clk);
+ 	return 0;
+ }
+ 
+@@ -453,8 +405,8 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+-	u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f;
+-	u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1;
++	u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
++	u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
+ 
+ 	/* bit size */
+ 	switch (params_format(params)) {
+@@ -493,20 +445,20 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
+ 		break;
+ 	}
+ 
+-	wm8510_write(codec, WM8510_IFACE, iface);
+-	wm8510_write(codec, WM8510_ADD, adn);
++	snd_soc_write(codec, WM8510_IFACE, iface);
++	snd_soc_write(codec, WM8510_ADD, adn);
+ 	return 0;
+ }
+ 
+ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
+ {
+ 	struct snd_soc_codec *codec = dai->codec;
+-	u16 mute_reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0xffbf;
++	u16 mute_reg = snd_soc_read(codec, WM8510_DAC) & 0xffbf;
+ 
+ 	if (mute)
+-		wm8510_write(codec, WM8510_DAC, mute_reg | 0x40);
++		snd_soc_write(codec, WM8510_DAC, mute_reg | 0x40);
+ 	else
+-		wm8510_write(codec, WM8510_DAC, mute_reg);
++		snd_soc_write(codec, WM8510_DAC, mute_reg);
+ 	return 0;
+ }
+ 
+@@ -514,13 +466,13 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
+ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
+ 	enum snd_soc_bias_level level)
+ {
+-	u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
++	u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
+ 
+ 	switch (level) {
+ 	case SND_SOC_BIAS_ON:
+ 	case SND_SOC_BIAS_PREPARE:
+ 		power1 |= 0x1;  /* VMID 50k */
+-		wm8510_write(codec, WM8510_POWER1, power1);
++		snd_soc_write(codec, WM8510_POWER1, power1);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_STANDBY:
+@@ -528,18 +480,18 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
+ 
+ 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ 			/* Initial cap charge at VMID 5k */
+-			wm8510_write(codec, WM8510_POWER1, power1 | 0x3);
++			snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
+ 			mdelay(100);
+ 		}
+ 
+ 		power1 |= 0x2;  /* VMID 500k */
+-		wm8510_write(codec, WM8510_POWER1, power1);
++		snd_soc_write(codec, WM8510_POWER1, power1);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_OFF:
+-		wm8510_write(codec, WM8510_POWER1, 0);
+-		wm8510_write(codec, WM8510_POWER2, 0);
+-		wm8510_write(codec, WM8510_POWER3, 0);
++		snd_soc_write(codec, WM8510_POWER1, 0);
++		snd_soc_write(codec, WM8510_POWER2, 0);
++		snd_soc_write(codec, WM8510_POWER3, 0);
+ 		break;
+ 	}
+ 
+@@ -577,6 +529,7 @@ struct snd_soc_dai wm8510_dai = {
+ 		.rates = WM8510_RATES,
+ 		.formats = WM8510_FORMATS,},
+ 	.ops = &wm8510_dai_ops,
++	.symmetric_rates = 1,
+ };
+ EXPORT_SYMBOL_GPL(wm8510_dai);
+ 
+@@ -612,15 +565,14 @@ static int wm8510_resume(struct platform_device *pdev)
+  * initialise the WM8510 driver
+  * register the mixer and dsp interfaces with the kernel
+  */
+-static int wm8510_init(struct snd_soc_device *socdev)
++static int wm8510_init(struct snd_soc_device *socdev,
++		       enum snd_soc_control_type control)
+ {
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	int ret = 0;
+ 
+ 	codec->name = "WM8510";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8510_read_reg_cache;
+-	codec->write = wm8510_write;
+ 	codec->set_bias_level = wm8510_set_bias_level;
+ 	codec->dai = &wm8510_dai;
+ 	codec->num_dai = 1;
+@@ -630,13 +582,20 @@ static int wm8510_init(struct snd_soc_device *socdev)
+ 	if (codec->reg_cache == NULL)
+ 		return -ENOMEM;
+ 
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n",
++		       ret);
++		goto err;
++	}
++
+ 	wm8510_reset(codec);
+ 
+ 	/* register pcms */
+ 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ 	if (ret < 0) {
+ 		printk(KERN_ERR "wm8510: failed to create pcms\n");
+-		goto pcm_err;
++		goto err;
+ 	}
+ 
+ 	/* power on device */
+@@ -655,7 +614,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
+ card_err:
+ 	snd_soc_free_pcms(socdev);
+ 	snd_soc_dapm_free(socdev);
+-pcm_err:
++err:
+ 	kfree(codec->reg_cache);
+ 	return ret;
+ }
+@@ -678,7 +637,7 @@ static int wm8510_i2c_probe(struct i2c_client *i2c,
+ 	i2c_set_clientdata(i2c, codec);
+ 	codec->control_data = i2c;
+ 
+-	ret = wm8510_init(socdev);
++	ret = wm8510_init(socdev, SND_SOC_I2C);
+ 	if (ret < 0)
+ 		pr_err("failed to initialise WM8510\n");
+ 
+@@ -758,7 +717,7 @@ static int __devinit wm8510_spi_probe(struct spi_device *spi)
+ 
+ 	codec->control_data = spi;
+ 
+-	ret = wm8510_init(socdev);
++	ret = wm8510_init(socdev, SND_SOC_SPI);
+ 	if (ret < 0)
+ 		dev_err(&spi->dev, "failed to initialise WM8510\n");
+ 
+@@ -779,30 +738,6 @@ static struct spi_driver wm8510_spi_driver = {
+ 	.probe		= wm8510_spi_probe,
+ 	.remove		= __devexit_p(wm8510_spi_remove),
+ };
+-
+-static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
+-{
+-	struct spi_transfer t;
+-	struct spi_message m;
+-	u8 msg[2];
+-
+-	if (len <= 0)
+-		return 0;
+-
+-	msg[0] = data[0];
+-	msg[1] = data[1];
+-
+-	spi_message_init(&m);
+-	memset(&t, 0, (sizeof t));
+-
+-	t.tx_buf = &msg[0];
+-	t.len = len;
+-
+-	spi_message_add_tail(&t, &m);
+-	spi_sync(spi, &m);
+-
+-	return len;
+-}
+ #endif /* CONFIG_SPI_MASTER */
+ 
+ static int wm8510_probe(struct platform_device *pdev)
+@@ -827,13 +762,11 @@ static int wm8510_probe(struct platform_device *pdev)
+ 	wm8510_socdev = socdev;
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ 	if (setup->i2c_address) {
+-		codec->hw_write = (hw_write_t)i2c_master_send;
+ 		ret = wm8510_add_i2c_device(pdev, setup);
+ 	}
+ #endif
+ #if defined(CONFIG_SPI_MASTER)
+ 	if (setup->spi) {
+-		codec->hw_write = (hw_write_t)wm8510_spi_write;
+ 		ret = spi_register_driver(&wm8510_spi_driver);
+ 		if (ret != 0)
+ 			printk(KERN_ERR "can't add spi driver");
+diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
+index 9f6be3d..3be5c0b 100644
+--- a/sound/soc/codecs/wm8580.c
++++ b/sound/soc/codecs/wm8580.c
+@@ -24,6 +24,8 @@
+ #include <linux/pm.h>
+ #include <linux/i2c.h>
+ #include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++
+ #include <sound/core.h>
+ #include <sound/pcm.h>
+ #include <sound/pcm_params.h>
+@@ -187,82 +189,22 @@ struct pll_state {
+ 	unsigned int out;
+ };
+ 
++#define WM8580_NUM_SUPPLIES 3
++static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
++	"AVDD",
++	"DVDD",
++	"PVDD",
++};
++
+ /* codec private data */
+ struct wm8580_priv {
+ 	struct snd_soc_codec codec;
++	struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
+ 	u16 reg_cache[WM8580_MAX_REGISTER + 1];
+ 	struct pll_state a;
+ 	struct pll_state b;
+ };
+ 
+-
+-/*
+- * read wm8580 register cache
+- */
+-static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
+-	return cache[reg];
+-}
+-
+-/*
+- * write wm8580 register cache
+- */
+-static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-
+-	cache[reg] = value;
+-}
+-
+-/*
+- * write to the WM8580 register space
+- */
+-static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[2];
+-
+-	BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
+-
+-	/* Registers are 9 bits wide */
+-	value &= 0x1ff;
+-
+-	switch (reg) {
+-	case WM8580_RESET:
+-		/* Uncached */
+-		break;
+-	default:
+-		if (value == wm8580_read_reg_cache(codec, reg))
+-			return 0;
+-	}
+-
+-	/* data is
+-	 *   D15..D9 WM8580 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+-	data[1] = value & 0x00ff;
+-
+-	wm8580_write_reg_cache(codec, reg, value);
+-	if (codec->hw_write(codec->control_data, data, 2) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
+-				       unsigned int reg)
+-{
+-	switch (reg) {
+-	default:
+-		return wm8580_read_reg_cache(codec, reg);
+-	}
+-}
+-
+ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+ 
+ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
+@@ -271,25 +213,22 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
+ 	struct soc_mixer_control *mc =
+ 		(struct soc_mixer_control *)kcontrol->private_value;
+ 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++	u16 *reg_cache = codec->reg_cache;
+ 	unsigned int reg = mc->reg;
+ 	unsigned int reg2 = mc->rreg;
+ 	int ret;
+-	u16 val;
+ 
+ 	/* Clear the register cache so we write without VU set */
+-	wm8580_write_reg_cache(codec, reg, 0);
+-	wm8580_write_reg_cache(codec, reg2, 0);
++	reg_cache[reg] = 0;
++	reg_cache[reg2] = 0;
+ 
+ 	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ 	if (ret < 0)
+ 		return ret;
+ 
+ 	/* Now write again with the volume update bit set */
+-	val = wm8580_read_reg_cache(codec, reg);
+-	wm8580_write(codec, reg, val | 0x0100);
+-
+-	val = wm8580_read_reg_cache(codec, reg2);
+-	wm8580_write(codec, reg2, val | 0x0100);
++	snd_soc_update_bits(codec, reg, 0x100, 0x100);
++	snd_soc_update_bits(codec, reg2, 0x100, 0x100);
+ 
+ 	return 0;
+ }
+@@ -415,7 +354,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 	unsigned int K, Ndiv, Nmod;
+ 	int i;
+ 
+-	pr_debug("wm8580: PLL %dHz->%dHz\n", source, target);
++	pr_debug("wm8580: PLL %uHz->%uHz\n", source, target);
+ 
+ 	/* Scale the output frequency up; the PLL should run in the
+ 	 * region of 90-100MHz.
+@@ -447,7 +386,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 
+ 	if ((Ndiv < 5) || (Ndiv > 13)) {
+ 		printk(KERN_ERR
+-			"WM8580 N=%d outside supported range\n", Ndiv);
++			"WM8580 N=%u outside supported range\n", Ndiv);
+ 		return -EINVAL;
+ 	}
+ 
+@@ -468,8 +407,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 	return 0;
+ }
+ 
+-static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out)
++static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
+ {
+ 	int offset;
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+@@ -512,27 +451,27 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
+ 	/* Always disable the PLL - it is not safe to leave it running
+ 	 * while reprogramming it.
+ 	 */
+-	reg = wm8580_read(codec, WM8580_PWRDN2);
+-	wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask);
++	reg = snd_soc_read(codec, WM8580_PWRDN2);
++	snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask);
+ 
+ 	if (!freq_in || !freq_out)
+ 		return 0;
+ 
+-	wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
+-	wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff);
+-	wm8580_write(codec, WM8580_PLLA3 + offset,
++	snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
++	snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
++	snd_soc_write(codec, WM8580_PLLA3 + offset,
+ 		     (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
+ 
+-	reg = wm8580_read(codec, WM8580_PLLA4 + offset);
+-	reg &= ~0x3f;
++	reg = snd_soc_read(codec, WM8580_PLLA4 + offset);
++	reg &= ~0x1b;
+ 	reg |= pll_div.prescale | pll_div.postscale << 1 |
+ 		pll_div.freqmode << 3;
+ 
+-	wm8580_write(codec, WM8580_PLLA4 + offset, reg);
++	snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
+ 
+ 	/* All done, turn it on */
+-	reg = wm8580_read(codec, WM8580_PWRDN2);
+-	wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
++	reg = snd_soc_read(codec, WM8580_PWRDN2);
++	snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
+ 
+ 	return 0;
+ }
+@@ -547,7 +486,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+-	u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
++	u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id);
+ 
+ 	paifb &= ~WM8580_AIF_LENGTH_MASK;
+ 	/* bit size */
+@@ -567,7 +506,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb);
++	snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb);
+ 	return 0;
+ }
+ 
+@@ -579,8 +518,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	unsigned int aifb;
+ 	int can_invert_lrclk;
+ 
+-	aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id);
+-	aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id);
++	aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id);
++	aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id);
+ 
+ 	aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
+ 
+@@ -646,8 +585,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
+-	wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
++	snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
++	snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
+ 
+ 	return 0;
+ }
+@@ -660,7 +599,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 
+ 	switch (div_id) {
+ 	case WM8580_MCLK:
+-		reg = wm8580_read(codec, WM8580_PLLB4);
++		reg = snd_soc_read(codec, WM8580_PLLB4);
+ 		reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
+ 
+ 		switch (div) {
+@@ -682,11 +621,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 		default:
+ 			return -EINVAL;
+ 		}
+-		wm8580_write(codec, WM8580_PLLB4, reg);
++		snd_soc_write(codec, WM8580_PLLB4, reg);
+ 		break;
+ 
+ 	case WM8580_DAC_CLKSEL:
+-		reg = wm8580_read(codec, WM8580_CLKSEL);
++		reg = snd_soc_read(codec, WM8580_CLKSEL);
+ 		reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
+ 
+ 		switch (div) {
+@@ -704,11 +643,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 		default:
+ 			return -EINVAL;
+ 		}
+-		wm8580_write(codec, WM8580_CLKSEL, reg);
++		snd_soc_write(codec, WM8580_CLKSEL, reg);
+ 		break;
+ 
+ 	case WM8580_CLKOUTSRC:
+-		reg = wm8580_read(codec, WM8580_PLLB4);
++		reg = snd_soc_read(codec, WM8580_PLLB4);
+ 		reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
+ 
+ 		switch (div) {
+@@ -730,7 +669,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 		default:
+ 			return -EINVAL;
+ 		}
+-		wm8580_write(codec, WM8580_PLLB4, reg);
++		snd_soc_write(codec, WM8580_PLLB4, reg);
+ 		break;
+ 
+ 	default:
+@@ -745,14 +684,14 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	unsigned int reg;
+ 
+-	reg = wm8580_read(codec, WM8580_DAC_CONTROL5);
++	reg = snd_soc_read(codec, WM8580_DAC_CONTROL5);
+ 
+ 	if (mute)
+ 		reg |= WM8580_DAC_CONTROL5_MUTEALL;
+ 	else
+ 		reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
+ 
+-	wm8580_write(codec, WM8580_DAC_CONTROL5, reg);
++	snd_soc_write(codec, WM8580_DAC_CONTROL5, reg);
+ 
+ 	return 0;
+ }
+@@ -769,20 +708,20 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
+ 	case SND_SOC_BIAS_STANDBY:
+ 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ 			/* Power up and get individual control of the DACs */
+-			reg = wm8580_read(codec, WM8580_PWRDN1);
++			reg = snd_soc_read(codec, WM8580_PWRDN1);
+ 			reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
+-			wm8580_write(codec, WM8580_PWRDN1, reg);
++			snd_soc_write(codec, WM8580_PWRDN1, reg);
+ 
+ 			/* Make VMID high impedence */
+-			reg = wm8580_read(codec,  WM8580_ADC_CONTROL1);
++			reg = snd_soc_read(codec,  WM8580_ADC_CONTROL1);
+ 			reg &= ~0x100;
+-			wm8580_write(codec, WM8580_ADC_CONTROL1, reg);
++			snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
+ 		}
+ 		break;
+ 
+ 	case SND_SOC_BIAS_OFF:
+-		reg = wm8580_read(codec, WM8580_PWRDN1);
+-		wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
++		reg = snd_soc_read(codec, WM8580_PWRDN1);
++		snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
+ 		break;
+ 	}
+ 	codec->bias_level = level;
+@@ -893,7 +832,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
+ };
+ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
+ 
+-static int wm8580_register(struct wm8580_priv *wm8580)
++static int wm8580_register(struct wm8580_priv *wm8580,
++			   enum snd_soc_control_type control)
+ {
+ 	int ret, i;
+ 	struct snd_soc_codec *codec = &wm8580->codec;
+@@ -911,8 +851,6 @@ static int wm8580_register(struct wm8580_priv *wm8580)
+ 	codec->private_data = wm8580;
+ 	codec->name = "WM8580";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8580_read_reg_cache;
+-	codec->write = wm8580_write;
+ 	codec->bias_level = SND_SOC_BIAS_OFF;
+ 	codec->set_bias_level = wm8580_set_bias_level;
+ 	codec->dai = wm8580_dai;
+@@ -922,11 +860,34 @@ static int wm8580_register(struct wm8580_priv *wm8580)
+ 
+ 	memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
+ 
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		goto err;
++	}
++
++	for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
++		wm8580->supplies[i].supply = wm8580_supply_names[i];
++
++	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies),
++				 wm8580->supplies);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
++		goto err;
++	}
++
++	ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
++				    wm8580->supplies);
++	if (ret != 0) {
++		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
++		goto err_regulator_get;
++	}
++
+ 	/* Get the codec into a known state */
+-	ret = wm8580_write(codec, WM8580_RESET, 0);
++	ret = snd_soc_write(codec, WM8580_RESET, 0);
+ 	if (ret != 0) {
+ 		dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
+-		goto err;
++		goto err_regulator_enable;
+ 	}
+ 
+ 	for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
+@@ -939,7 +900,7 @@ static int wm8580_register(struct wm8580_priv *wm8580)
+ 	ret = snd_soc_register_codec(codec);
+ 	if (ret != 0) {
+ 		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+-		goto err;
++		goto err_regulator_enable;
+ 	}
+ 
+ 	ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
+@@ -952,6 +913,10 @@ static int wm8580_register(struct wm8580_priv *wm8580)
+ 
+ err_codec:
+ 	snd_soc_unregister_codec(codec);
++err_regulator_enable:
++	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
++err_regulator_get:
++	regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
+ err:
+ 	kfree(wm8580);
+ 	return ret;
+@@ -962,6 +927,8 @@ static void wm8580_unregister(struct wm8580_priv *wm8580)
+ 	wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
+ 	snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
+ 	snd_soc_unregister_codec(&wm8580->codec);
++	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
++	regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
+ 	kfree(wm8580);
+ 	wm8580_codec = NULL;
+ }
+@@ -978,14 +945,13 @@ static int wm8580_i2c_probe(struct i2c_client *i2c,
+ 		return -ENOMEM;
+ 
+ 	codec = &wm8580->codec;
+-	codec->hw_write = (hw_write_t)i2c_master_send;
+ 
+ 	i2c_set_clientdata(i2c, wm8580);
+ 	codec->control_data = i2c;
+ 
+ 	codec->dev = &i2c->dev;
+ 
+-	return wm8580_register(wm8580);
++	return wm8580_register(wm8580, SND_SOC_I2C);
+ }
+ 
+ static int wm8580_i2c_remove(struct i2c_client *client)
+@@ -995,6 +961,21 @@ static int wm8580_i2c_remove(struct i2c_client *client)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&client->dev);
++}
++
++static int wm8580_i2c_resume(struct i2c_client *client)
++{
++	return snd_soc_resume_device(&client->dev);
++}
++#else
++#define wm8580_i2c_suspend NULL
++#define wm8580_i2c_resume NULL
++#endif
++
+ static const struct i2c_device_id wm8580_i2c_id[] = {
+ 	{ "wm8580", 0 },
+ 	{ }
+@@ -1008,6 +989,8 @@ static struct i2c_driver wm8580_i2c_driver = {
+ 	},
+ 	.probe =    wm8580_i2c_probe,
+ 	.remove =   wm8580_i2c_remove,
++	.suspend =  wm8580_i2c_suspend,
++	.resume =   wm8580_i2c_resume,
+ 	.id_table = wm8580_i2c_id,
+ };
+ #endif
+diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
+index e7ff212..16e969a 100644
+--- a/sound/soc/codecs/wm8728.c
++++ b/sound/soc/codecs/wm8728.c
+@@ -43,45 +43,6 @@ static const u16 wm8728_reg_defaults[] = {
+ 	0x100,
+ };
+ 
+-static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
+-	return cache[reg];
+-}
+-
+-static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
+-	u16 reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-	BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
+-	cache[reg] = value;
+-}
+-
+-/*
+- * write to the WM8728 register space
+- */
+-static int wm8728_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[2];
+-
+-	/* data is
+-	 *   D15..D9 WM8728 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+-	data[1] = value & 0x00ff;
+-
+-	wm8728_write_reg_cache(codec, reg, value);
+-
+-	if (codec->hw_write(codec->control_data, data, 2) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+ static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
+ 
+ static const struct snd_kcontrol_new wm8728_snd_controls[] = {
+@@ -121,12 +82,12 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
+ static int wm8728_mute(struct snd_soc_dai *dai, int mute)
+ {
+ 	struct snd_soc_codec *codec = dai->codec;
+-	u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
++	u16 mute_reg = snd_soc_read(codec, WM8728_DACCTL);
+ 
+ 	if (mute)
+-		wm8728_write(codec, WM8728_DACCTL, mute_reg | 1);
++		snd_soc_write(codec, WM8728_DACCTL, mute_reg | 1);
+ 	else
+-		wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1);
++		snd_soc_write(codec, WM8728_DACCTL, mute_reg & ~1);
+ 
+ 	return 0;
+ }
+@@ -138,7 +99,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+-	u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL);
++	u16 dac = snd_soc_read(codec, WM8728_DACCTL);
+ 
+ 	dac &= ~0x18;
+ 
+@@ -155,7 +116,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8728_write(codec, WM8728_DACCTL, dac);
++	snd_soc_write(codec, WM8728_DACCTL, dac);
+ 
+ 	return 0;
+ }
+@@ -164,7 +125,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		unsigned int fmt)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+-	u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL);
++	u16 iface = snd_soc_read(codec, WM8728_IFCTL);
+ 
+ 	/* Currently only I2S is supported by the driver, though the
+ 	 * hardware is more flexible.
+@@ -204,7 +165,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8728_write(codec, WM8728_IFCTL, iface);
++	snd_soc_write(codec, WM8728_IFCTL, iface);
+ 	return 0;
+ }
+ 
+@@ -220,19 +181,19 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
+ 	case SND_SOC_BIAS_STANDBY:
+ 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ 			/* Power everything up... */
+-			reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
+-			wm8728_write(codec, WM8728_DACCTL, reg & ~0x4);
++			reg = snd_soc_read(codec, WM8728_DACCTL);
++			snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
+ 
+ 			/* ..then sync in the register cache. */
+ 			for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
+-				wm8728_write(codec, i,
+-					     wm8728_read_reg_cache(codec, i));
++				snd_soc_write(codec, i,
++					     snd_soc_read(codec, i));
+ 		}
+ 		break;
+ 
+ 	case SND_SOC_BIAS_OFF:
+-		reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
+-		wm8728_write(codec, WM8728_DACCTL, reg | 0x4);
++		reg = snd_soc_read(codec, WM8728_DACCTL);
++		snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
+ 		break;
+ 	}
+ 	codec->bias_level = level;
+@@ -287,15 +248,14 @@ static int wm8728_resume(struct platform_device *pdev)
+  * initialise the WM8728 driver
+  * register the mixer and dsp interfaces with the kernel
+  */
+-static int wm8728_init(struct snd_soc_device *socdev)
++static int wm8728_init(struct snd_soc_device *socdev,
++		       enum snd_soc_control_type control)
+ {
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	int ret = 0;
+ 
+ 	codec->name = "WM8728";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8728_read_reg_cache;
+-	codec->write = wm8728_write;
+ 	codec->set_bias_level = wm8728_set_bias_level;
+ 	codec->dai = &wm8728_dai;
+ 	codec->num_dai = 1;
+@@ -307,11 +267,18 @@ static int wm8728_init(struct snd_soc_device *socdev)
+ 	if (codec->reg_cache == NULL)
+ 		return -ENOMEM;
+ 
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
++		       ret);
++		goto err;
++	}
++
+ 	/* register pcms */
+ 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ 	if (ret < 0) {
+ 		printk(KERN_ERR "wm8728: failed to create pcms\n");
+-		goto pcm_err;
++		goto err;
+ 	}
+ 
+ 	/* power on device */
+@@ -331,7 +298,7 @@ static int wm8728_init(struct snd_soc_device *socdev)
+ card_err:
+ 	snd_soc_free_pcms(socdev);
+ 	snd_soc_dapm_free(socdev);
+-pcm_err:
++err:
+ 	kfree(codec->reg_cache);
+ 	return ret;
+ }
+@@ -357,7 +324,7 @@ static int wm8728_i2c_probe(struct i2c_client *i2c,
+ 	i2c_set_clientdata(i2c, codec);
+ 	codec->control_data = i2c;
+ 
+-	ret = wm8728_init(socdev);
++	ret = wm8728_init(socdev, SND_SOC_I2C);
+ 	if (ret < 0)
+ 		pr_err("failed to initialise WM8728\n");
+ 
+@@ -437,7 +404,7 @@ static int __devinit wm8728_spi_probe(struct spi_device *spi)
+ 
+ 	codec->control_data = spi;
+ 
+-	ret = wm8728_init(socdev);
++	ret = wm8728_init(socdev, SND_SOC_SPI);
+ 	if (ret < 0)
+ 		dev_err(&spi->dev, "failed to initialise WM8728\n");
+ 
+@@ -458,30 +425,6 @@ static struct spi_driver wm8728_spi_driver = {
+ 	.probe		= wm8728_spi_probe,
+ 	.remove		= __devexit_p(wm8728_spi_remove),
+ };
+-
+-static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
+-{
+-	struct spi_transfer t;
+-	struct spi_message m;
+-	u8 msg[2];
+-
+-	if (len <= 0)
+-		return 0;
+-
+-	msg[0] = data[0];
+-	msg[1] = data[1];
+-
+-	spi_message_init(&m);
+-	memset(&t, 0, (sizeof t));
+-
+-	t.tx_buf = &msg[0];
+-	t.len = len;
+-
+-	spi_message_add_tail(&t, &m);
+-	spi_sync(spi, &m);
+-
+-	return len;
+-}
+ #endif /* CONFIG_SPI_MASTER */
+ 
+ static int wm8728_probe(struct platform_device *pdev)
+@@ -506,13 +449,11 @@ static int wm8728_probe(struct platform_device *pdev)
+ 
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ 	if (setup->i2c_address) {
+-		codec->hw_write = (hw_write_t)i2c_master_send;
+ 		ret = wm8728_add_i2c_device(pdev, setup);
+ 	}
+ #endif
+ #if defined(CONFIG_SPI_MASTER)
+ 	if (setup->spi) {
+-		codec->hw_write = (hw_write_t)wm8728_spi_write;
+ 		ret = spi_register_driver(&wm8728_spi_driver);
+ 		if (ret != 0)
+ 			printk(KERN_ERR "can't add spi driver");
+diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
+index e043e3f..d3fd4f2 100644
+--- a/sound/soc/codecs/wm8731.c
++++ b/sound/soc/codecs/wm8731.c
+@@ -26,6 +26,7 @@
+ #include <sound/soc.h>
+ #include <sound/soc-dapm.h>
+ #include <sound/initval.h>
++#include <sound/tlv.h>
+ 
+ #include "wm8731.h"
+ 
+@@ -39,9 +40,6 @@ struct wm8731_priv {
+ 	unsigned int sysclk;
+ };
+ 
+-#ifdef CONFIG_SPI_MASTER
+-static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
+-#endif
+ 
+ /*
+  * wm8731 register cache
+@@ -50,60 +48,12 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
+  * There is no point in caching the reset register
+  */
+ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
+-    0x0097, 0x0097, 0x0079, 0x0079,
+-    0x000a, 0x0008, 0x009f, 0x000a,
+-    0x0000, 0x0000
++	0x0097, 0x0097, 0x0079, 0x0079,
++	0x000a, 0x0008, 0x009f, 0x000a,
++	0x0000, 0x0000
+ };
+ 
+-/*
+- * read wm8731 register cache
+- */
+-static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg == WM8731_RESET)
+-		return 0;
+-	if (reg >= WM8731_CACHEREGNUM)
+-		return -1;
+-	return cache[reg];
+-}
+-
+-/*
+- * write wm8731 register cache
+- */
+-static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec,
+-	u16 reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg >= WM8731_CACHEREGNUM)
+-		return;
+-	cache[reg] = value;
+-}
+-
+-/*
+- * write to the WM8731 register space
+- */
+-static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[2];
+-
+-	/* data is
+-	 *   D15..D9 WM8731 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+-	data[1] = value & 0x00ff;
+-
+-	wm8731_write_reg_cache(codec, reg, value);
+-	if (codec->hw_write(codec->control_data, data, 2) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-#define wm8731_reset(c)	wm8731_write(c, WM8731_RESET, 0)
++#define wm8731_reset(c)	snd_soc_write(c, WM8731_RESET, 0)
+ 
+ static const char *wm8731_input_select[] = {"Line In", "Mic"};
+ static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
+@@ -113,20 +63,26 @@ static const struct soc_enum wm8731_enum[] = {
+ 	SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph),
+ };
+ 
++static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
++static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
++static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
++
+ static const struct snd_kcontrol_new wm8731_snd_controls[] = {
+ 
+-SOC_DOUBLE_R("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
+-	0, 127, 0),
++SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
++		 0, 127, 0, out_tlv),
+ SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V,
+ 	7, 1, 0),
+ 
+-SOC_DOUBLE_R("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0),
++SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
++		 in_tlv),
+ SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
+ 
+ SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0),
+-SOC_SINGLE("Capture Mic Switch", WM8731_APANA, 1, 1, 1),
++SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
+ 
+-SOC_SINGLE("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1),
++SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
++	       sidetone_tlv),
+ 
+ SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
+ SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
+@@ -260,12 +216,12 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	struct wm8731_priv *wm8731 = codec->private_data;
+-	u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3;
++	u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
+ 	int i = get_coeff(wm8731->sysclk, params_rate(params));
+ 	u16 srate = (coeff_div[i].sr << 2) |
+ 		(coeff_div[i].bosr << 1) | coeff_div[i].usb;
+ 
+-	wm8731_write(codec, WM8731_SRATE, srate);
++	snd_soc_write(codec, WM8731_SRATE, srate);
+ 
+ 	/* bit size */
+ 	switch (params_format(params)) {
+@@ -279,7 +235,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
+ 		break;
+ 	}
+ 
+-	wm8731_write(codec, WM8731_IFACE, iface);
++	snd_soc_write(codec, WM8731_IFACE, iface);
+ 	return 0;
+ }
+ 
+@@ -291,7 +247,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 
+ 	/* set active */
+-	wm8731_write(codec, WM8731_ACTIVE, 0x0001);
++	snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
+ 
+ 	return 0;
+ }
+@@ -306,19 +262,19 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream,
+ 	/* deactivate */
+ 	if (!codec->active) {
+ 		udelay(50);
+-		wm8731_write(codec, WM8731_ACTIVE, 0x0);
++		snd_soc_write(codec, WM8731_ACTIVE, 0x0);
+ 	}
+ }
+ 
+ static int wm8731_mute(struct snd_soc_dai *dai, int mute)
+ {
+ 	struct snd_soc_codec *codec = dai->codec;
+-	u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7;
++	u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
+ 
+ 	if (mute)
+-		wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8);
++		snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
+ 	else
+-		wm8731_write(codec, WM8731_APDIGI, mute_reg);
++		snd_soc_write(codec, WM8731_APDIGI, mute_reg);
+ 	return 0;
+ }
+ 
+@@ -396,7 +352,7 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	}
+ 
+ 	/* set iface */
+-	wm8731_write(codec, WM8731_IFACE, iface);
++	snd_soc_write(codec, WM8731_IFACE, iface);
+ 	return 0;
+ }
+ 
+@@ -412,12 +368,12 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
+ 		break;
+ 	case SND_SOC_BIAS_STANDBY:
+ 		/* Clear PWROFF, gate CLKOUT, everything else as-is */
+-		reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f;
+-		wm8731_write(codec, WM8731_PWR, reg | 0x0040);
++		reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
++		snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
+ 		break;
+ 	case SND_SOC_BIAS_OFF:
+-		wm8731_write(codec, WM8731_ACTIVE, 0x0);
+-		wm8731_write(codec, WM8731_PWR, 0xffff);
++		snd_soc_write(codec, WM8731_ACTIVE, 0x0);
++		snd_soc_write(codec, WM8731_PWR, 0xffff);
+ 		break;
+ 	}
+ 	codec->bias_level = level;
+@@ -457,15 +413,17 @@ struct snd_soc_dai wm8731_dai = {
+ 		.rates = WM8731_RATES,
+ 		.formats = WM8731_FORMATS,},
+ 	.ops = &wm8731_dai_ops,
++	.symmetric_rates = 1,
+ };
+ EXPORT_SYMBOL_GPL(wm8731_dai);
+ 
++#ifdef CONFIG_PM
+ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+ 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 
+-	wm8731_write(codec, WM8731_ACTIVE, 0x0);
++	snd_soc_write(codec, WM8731_ACTIVE, 0x0);
+ 	wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ 	return 0;
+ }
+@@ -488,6 +446,10 @@ static int wm8731_resume(struct platform_device *pdev)
+ 	wm8731_set_bias_level(codec, codec->suspend_bias_level);
+ 	return 0;
+ }
++#else
++#define wm8731_suspend NULL
++#define wm8731_resume NULL
++#endif
+ 
+ static int wm8731_probe(struct platform_device *pdev)
+ {
+@@ -547,15 +509,16 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
+ };
+ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
+ 
+-static int wm8731_register(struct wm8731_priv *wm8731)
++static int wm8731_register(struct wm8731_priv *wm8731,
++			   enum snd_soc_control_type control)
+ {
+ 	int ret;
+ 	struct snd_soc_codec *codec = &wm8731->codec;
+-	u16 reg;
+ 
+ 	if (wm8731_codec) {
+ 		dev_err(codec->dev, "Another WM8731 is registered\n");
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto err;
+ 	}
+ 
+ 	mutex_init(&codec->mutex);
+@@ -565,8 +528,6 @@ static int wm8731_register(struct wm8731_priv *wm8731)
+ 	codec->private_data = wm8731;
+ 	codec->name = "WM8731";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8731_read_reg_cache;
+-	codec->write = wm8731_write;
+ 	codec->bias_level = SND_SOC_BIAS_OFF;
+ 	codec->set_bias_level = wm8731_set_bias_level;
+ 	codec->dai = &wm8731_dai;
+@@ -576,10 +537,16 @@ static int wm8731_register(struct wm8731_priv *wm8731)
+ 
+ 	memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
+ 
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
++	if (ret < 0) {
++		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++		goto err;
++	}
++
+ 	ret = wm8731_reset(codec);
+ 	if (ret < 0) {
+-		dev_err(codec->dev, "Failed to issue reset\n");
+-		return ret;
++		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
++		goto err;
+ 	}
+ 
+ 	wm8731_dai.dev = codec->dev;
+@@ -587,35 +554,36 @@ static int wm8731_register(struct wm8731_priv *wm8731)
+ 	wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ 
+ 	/* Latch the update bits */
+-	reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
+-	wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100);
+-	reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V);
+-	wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100);
+-	reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
+-	wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
+-	reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
+-	wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
++	snd_soc_update_bits(codec, WM8731_LOUT1V, 0x100, 0);
++	snd_soc_update_bits(codec, WM8731_ROUT1V, 0x100, 0);
++	snd_soc_update_bits(codec, WM8731_LINVOL, 0x100, 0);
++	snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
+ 
+ 	/* Disable bypass path by default */
+-	reg = wm8731_read_reg_cache(codec, WM8731_APANA);
+-	wm8731_write(codec, WM8731_APANA, reg & ~0x4);
++	snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
+ 
+ 	wm8731_codec = codec;
+ 
+ 	ret = snd_soc_register_codec(codec);
+ 	if (ret != 0) {
+ 		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+-		return ret;
++		goto err;
+ 	}
+ 
+ 	ret = snd_soc_register_dai(&wm8731_dai);
+ 	if (ret != 0) {
+ 		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+ 		snd_soc_unregister_codec(codec);
+-		return ret;
++		goto err_codec;
+ 	}
+ 
+ 	return 0;
++
++err_codec:
++	snd_soc_unregister_codec(codec);
++err:
++	kfree(wm8731);
++	return ret;
+ }
+ 
+ static void wm8731_unregister(struct wm8731_priv *wm8731)
+@@ -628,30 +596,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
+ }
+ 
+ #if defined(CONFIG_SPI_MASTER)
+-static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
+-{
+-	struct spi_transfer t;
+-	struct spi_message m;
+-	u8 msg[2];
+-
+-	if (len <= 0)
+-		return 0;
+-
+-	msg[0] = data[0];
+-	msg[1] = data[1];
+-
+-	spi_message_init(&m);
+-	memset(&t, 0, (sizeof t));
+-
+-	t.tx_buf = &msg[0];
+-	t.len = len;
+-
+-	spi_message_add_tail(&t, &m);
+-	spi_sync(spi, &m);
+-
+-	return len;
+-}
+-
+ static int __devinit wm8731_spi_probe(struct spi_device *spi)
+ {
+ 	struct snd_soc_codec *codec;
+@@ -663,23 +607,37 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
+ 
+ 	codec = &wm8731->codec;
+ 	codec->control_data = spi;
+-	codec->hw_write = (hw_write_t)wm8731_spi_write;
+ 	codec->dev = &spi->dev;
+ 
+-	spi->dev.driver_data = wm8731;
++	dev_set_drvdata(&spi->dev, wm8731);
+ 
+-	return wm8731_register(wm8731);
++	return wm8731_register(wm8731, SND_SOC_SPI);
+ }
+ 
+ static int __devexit wm8731_spi_remove(struct spi_device *spi)
+ {
+-	struct wm8731_priv *wm8731 = spi->dev.driver_data;
++	struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev);
+ 
+ 	wm8731_unregister(wm8731);
+ 
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&spi->dev);
++}
++
++static int wm8731_spi_resume(struct spi_device *spi)
++{
++	return snd_soc_resume_device(&spi->dev);
++}
++#else
++#define wm8731_spi_suspend NULL
++#define wm8731_spi_resume NULL
++#endif
++
+ static struct spi_driver wm8731_spi_driver = {
+ 	.driver = {
+ 		.name	= "wm8731",
+@@ -687,6 +645,8 @@ static struct spi_driver wm8731_spi_driver = {
+ 		.owner	= THIS_MODULE,
+ 	},
+ 	.probe		= wm8731_spi_probe,
++	.suspend	= wm8731_spi_suspend,
++	.resume		= wm8731_spi_resume,
+ 	.remove		= __devexit_p(wm8731_spi_remove),
+ };
+ #endif /* CONFIG_SPI_MASTER */
+@@ -703,14 +663,13 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
+ 		return -ENOMEM;
+ 
+ 	codec = &wm8731->codec;
+-	codec->hw_write = (hw_write_t)i2c_master_send;
+ 
+ 	i2c_set_clientdata(i2c, wm8731);
+ 	codec->control_data = i2c;
+ 
+ 	codec->dev = &i2c->dev;
+ 
+-	return wm8731_register(wm8731);
++	return wm8731_register(wm8731, SND_SOC_I2C);
+ }
+ 
+ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
+@@ -720,6 +679,21 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&i2c->dev);
++}
++
++static int wm8731_i2c_resume(struct i2c_client *i2c)
++{
++	return snd_soc_resume_device(&i2c->dev);
++}
++#else
++#define wm8731_i2c_suspend NULL
++#define wm8731_i2c_resume NULL
++#endif
++
+ static const struct i2c_device_id wm8731_i2c_id[] = {
+ 	{ "wm8731", 0 },
+ 	{ }
+@@ -733,6 +707,8 @@ static struct i2c_driver wm8731_i2c_driver = {
+ 	},
+ 	.probe =    wm8731_i2c_probe,
+ 	.remove =   __devexit_p(wm8731_i2c_remove),
++	.suspend =  wm8731_i2c_suspend,
++	.resume =   wm8731_i2c_resume,
+ 	.id_table = wm8731_i2c_id,
+ };
+ #endif
+diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
+index b64509b..4ba1e7e 100644
+--- a/sound/soc/codecs/wm8750.c
++++ b/sound/soc/codecs/wm8750.c
+@@ -55,50 +55,7 @@ static const u16 wm8750_reg[] = {
+ 	0x0079, 0x0079, 0x0079,          /* 40 */
+ };
+ 
+-/*
+- * read wm8750 register cache
+- */
+-static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg > WM8750_CACHE_REGNUM)
+-		return -1;
+-	return cache[reg];
+-}
+-
+-/*
+- * write wm8750 register cache
+- */
+-static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg > WM8750_CACHE_REGNUM)
+-		return;
+-	cache[reg] = value;
+-}
+-
+-static int wm8750_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[2];
+-
+-	/* data is
+-	 *   D15..D9 WM8753 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+-	data[1] = value & 0x00ff;
+-
+-	wm8750_write_reg_cache(codec, reg, value);
+-	if (codec->hw_write(codec->control_data, data, 2) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-#define wm8750_reset(c)	wm8750_write(c, WM8750_RESET, 0)
++#define wm8750_reset(c)	snd_soc_write(c, WM8750_RESET, 0)
+ 
+ /*
+  * WM8750 Controls
+@@ -594,7 +551,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8750_write(codec, WM8750_IFACE, iface);
++	snd_soc_write(codec, WM8750_IFACE, iface);
+ 	return 0;
+ }
+ 
+@@ -606,8 +563,8 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	struct wm8750_priv *wm8750 = codec->private_data;
+-	u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3;
+-	u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0;
++	u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
++	u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
+ 	int coeff = get_coeff(wm8750->sysclk, params_rate(params));
+ 
+ 	/* bit size */
+@@ -626,9 +583,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	}
+ 
+ 	/* set iface & srate */
+-	wm8750_write(codec, WM8750_IFACE, iface);
++	snd_soc_write(codec, WM8750_IFACE, iface);
+ 	if (coeff >= 0)
+-		wm8750_write(codec, WM8750_SRATE, srate |
++		snd_soc_write(codec, WM8750_SRATE, srate |
+ 			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
+ 
+ 	return 0;
+@@ -637,35 +594,35 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
+ static int wm8750_mute(struct snd_soc_dai *dai, int mute)
+ {
+ 	struct snd_soc_codec *codec = dai->codec;
+-	u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7;
++	u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
+ 
+ 	if (mute)
+-		wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
++		snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
+ 	else
+-		wm8750_write(codec, WM8750_ADCDAC, mute_reg);
++		snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
+ 	return 0;
+ }
+ 
+ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
+ 				 enum snd_soc_bias_level level)
+ {
+-	u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e;
++	u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
+ 
+ 	switch (level) {
+ 	case SND_SOC_BIAS_ON:
+ 		/* set vmid to 50k and unmute dac */
+-		wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
++		snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
+ 		break;
+ 	case SND_SOC_BIAS_PREPARE:
+ 		/* set vmid to 5k for quick power up */
+-		wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
++		snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
+ 		break;
+ 	case SND_SOC_BIAS_STANDBY:
+ 		/* mute dac and set vmid to 500k, enable VREF */
+-		wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
++		snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
+ 		break;
+ 	case SND_SOC_BIAS_OFF:
+-		wm8750_write(codec, WM8750_PWR1, 0x0001);
++		snd_soc_write(codec, WM8750_PWR1, 0x0001);
+ 		break;
+ 	}
+ 	codec->bias_level = level;
+@@ -754,15 +711,14 @@ static int wm8750_resume(struct platform_device *pdev)
+  * initialise the WM8750 driver
+  * register the mixer and dsp interfaces with the kernel
+  */
+-static int wm8750_init(struct snd_soc_device *socdev)
++static int wm8750_init(struct snd_soc_device *socdev,
++		       enum snd_soc_control_type control)
+ {
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	int reg, ret = 0;
+ 
+ 	codec->name = "WM8750";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8750_read_reg_cache;
+-	codec->write = wm8750_write;
+ 	codec->set_bias_level = wm8750_set_bias_level;
+ 	codec->dai = &wm8750_dai;
+ 	codec->num_dai = 1;
+@@ -771,13 +727,23 @@ static int wm8750_init(struct snd_soc_device *socdev)
+ 	if (codec->reg_cache == NULL)
+ 		return -ENOMEM;
+ 
+-	wm8750_reset(codec);
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
++		goto err;
++	}
++
++	ret = wm8750_reset(codec);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
++		goto err;
++	}
+ 
+ 	/* register pcms */
+ 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ 	if (ret < 0) {
+ 		printk(KERN_ERR "wm8750: failed to create pcms\n");
+-		goto pcm_err;
++		goto err;
+ 	}
+ 
+ 	/* charge output caps */
+@@ -786,22 +752,22 @@ static int wm8750_init(struct snd_soc_device *socdev)
+ 	schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
+ 
+ 	/* set the update bits */
+-	reg = wm8750_read_reg_cache(codec, WM8750_LDAC);
+-	wm8750_write(codec, WM8750_LDAC, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_RDAC);
+-	wm8750_write(codec, WM8750_RDAC, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V);
+-	wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V);
+-	wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V);
+-	wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V);
+-	wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_LINVOL);
+-	wm8750_write(codec, WM8750_LINVOL, reg | 0x0100);
+-	reg = wm8750_read_reg_cache(codec, WM8750_RINVOL);
+-	wm8750_write(codec, WM8750_RINVOL, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_LDAC);
++	snd_soc_write(codec, WM8750_LDAC, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_RDAC);
++	snd_soc_write(codec, WM8750_RDAC, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_LOUT1V);
++	snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_ROUT1V);
++	snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_LOUT2V);
++	snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_ROUT2V);
++	snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_LINVOL);
++	snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8750_RINVOL);
++	snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
+ 
+ 	snd_soc_add_controls(codec, wm8750_snd_controls,
+ 				ARRAY_SIZE(wm8750_snd_controls));
+@@ -816,7 +782,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
+ card_err:
+ 	snd_soc_free_pcms(socdev);
+ 	snd_soc_dapm_free(socdev);
+-pcm_err:
++err:
+ 	kfree(codec->reg_cache);
+ 	return ret;
+ }
+@@ -844,7 +810,7 @@ static int wm8750_i2c_probe(struct i2c_client *i2c,
+ 	i2c_set_clientdata(i2c, codec);
+ 	codec->control_data = i2c;
+ 
+-	ret = wm8750_init(socdev);
++	ret = wm8750_init(socdev, SND_SOC_I2C);
+ 	if (ret < 0)
+ 		pr_err("failed to initialise WM8750\n");
+ 
+@@ -924,7 +890,7 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi)
+ 
+ 	codec->control_data = spi;
+ 
+-	ret = wm8750_init(socdev);
++	ret = wm8750_init(socdev, SND_SOC_SPI);
+ 	if (ret < 0)
+ 		dev_err(&spi->dev, "failed to initialise WM8750\n");
+ 
+@@ -945,30 +911,6 @@ static struct spi_driver wm8750_spi_driver = {
+ 	.probe		= wm8750_spi_probe,
+ 	.remove		= __devexit_p(wm8750_spi_remove),
+ };
+-
+-static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
+-{
+-	struct spi_transfer t;
+-	struct spi_message m;
+-	u8 msg[2];
+-
+-	if (len <= 0)
+-		return 0;
+-
+-	msg[0] = data[0];
+-	msg[1] = data[1];
+-
+-	spi_message_init(&m);
+-	memset(&t, 0, (sizeof t));
+-
+-	t.tx_buf = &msg[0];
+-	t.len = len;
+-
+-	spi_message_add_tail(&t, &m);
+-	spi_sync(spi, &m);
+-
+-	return len;
+-}
+ #endif
+ 
+ static int wm8750_probe(struct platform_device *pdev)
+@@ -1002,13 +944,11 @@ static int wm8750_probe(struct platform_device *pdev)
+ 
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ 	if (setup->i2c_address) {
+-		codec->hw_write = (hw_write_t)i2c_master_send;
+ 		ret = wm8750_add_i2c_device(pdev, setup);
+ 	}
+ #endif
+ #if defined(CONFIG_SPI_MASTER)
+ 	if (setup->spi) {
+-		codec->hw_write = (hw_write_t)wm8750_spi_write;
+ 		ret = spi_register_driver(&wm8750_spi_driver);
+ 		if (ret != 0)
+ 			printk(KERN_ERR "can't add spi driver");
+diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
+index a6e8f3f..9b27efb 100644
+--- a/sound/soc/codecs/wm8753.c
++++ b/sound/soc/codecs/wm8753.c
+@@ -79,7 +79,7 @@ static const u16 wm8753_reg[] = {
+ 	0x0097, 0x0097, 0x0000, 0x0004,
+ 	0x0000, 0x0083, 0x0024, 0x01ba,
+ 	0x0000, 0x0083, 0x0024, 0x01ba,
+-	0x0000, 0x0000
++	0x0000, 0x0000, 0x0000
+ };
+ 
+ /* codec private data */
+@@ -595,6 +595,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
+ 
+ 	/* Mono Capture mixer-mux */
+ 	{"Capture Right Mixer", "Stereo", "Capture Right Mux"},
++	{"Capture Left Mixer", "Stereo", "Capture Left Mux"},
+ 	{"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
+ 	{"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
+ 	{"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
+@@ -703,7 +704,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 
+ 	if ((Ndiv < 6) || (Ndiv > 12))
+ 		printk(KERN_WARNING
+-			"wm8753: unsupported N = %d\n", Ndiv);
++			"wm8753: unsupported N = %u\n", Ndiv);
+ 
+ 	pll_div->n = Ndiv;
+ 	Nmod = target % source;
+@@ -723,8 +724,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 	pll_div->k = K;
+ }
+ 
+-static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out)
++static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
+ {
+ 	u16 reg, enable;
+ 	int offset;
+@@ -1660,11 +1661,11 @@ static int wm8753_register(struct wm8753_priv *wm8753)
+ 	codec->set_bias_level = wm8753_set_bias_level;
+ 	codec->dai = wm8753_dai;
+ 	codec->num_dai = 2;
+-	codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache);
++	codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
+ 	codec->reg_cache = &wm8753->reg_cache;
+ 	codec->private_data = wm8753;
+ 
+-	memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache));
++	memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
+ 	INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
+ 
+ 	ret = wm8753_reset(codec);
+@@ -1766,6 +1767,21 @@ static int wm8753_i2c_remove(struct i2c_client *client)
+         return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&client->dev);
++}
++
++static int wm8753_i2c_resume(struct i2c_client *client)
++{
++	return snd_soc_resume_device(&client->dev);
++}
++#else
++#define wm8753_i2c_suspend NULL
++#define wm8753_i2c_resume NULL
++#endif
++
+ static const struct i2c_device_id wm8753_i2c_id[] = {
+ 	{ "wm8753", 0 },
+ 	{ }
+@@ -1779,6 +1795,8 @@ static struct i2c_driver wm8753_i2c_driver = {
+ 	},
+ 	.probe =    wm8753_i2c_probe,
+ 	.remove =   wm8753_i2c_remove,
++	.suspend =  wm8753_i2c_suspend,
++	.resume =   wm8753_i2c_resume,
+ 	.id_table = wm8753_i2c_id,
+ };
+ #endif
+@@ -1822,18 +1840,34 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
+ 	codec->hw_write = (hw_write_t)wm8753_spi_write;
+ 	codec->dev = &spi->dev;
+ 
+-	spi->dev.driver_data = wm8753;
++	dev_set_drvdata(&spi->dev, wm8753);
+ 
+ 	return wm8753_register(wm8753);
+ }
+ 
+ static int __devexit wm8753_spi_remove(struct spi_device *spi)
+ {
+-	struct wm8753_priv *wm8753 = spi->dev.driver_data;
++	struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev);
+ 	wm8753_unregister(wm8753);
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&spi->dev);
++}
++
++static int wm8753_spi_resume(struct spi_device *spi)
++{
++	return snd_soc_resume_device(&spi->dev);
++}
++
++#else
++#define wm8753_spi_suspend NULL
++#define wm8753_spi_resume NULL
++#endif
++
+ static struct spi_driver wm8753_spi_driver = {
+ 	.driver = {
+ 		.name	= "wm8753",
+@@ -1842,6 +1876,8 @@ static struct spi_driver wm8753_spi_driver = {
+ 	},
+ 	.probe		= wm8753_spi_probe,
+ 	.remove		= __devexit_p(wm8753_spi_remove),
++	.suspend	= wm8753_spi_suspend,
++	.resume		= wm8753_spi_resume,
+ };
+ #endif
+ 
+diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
+index 46c5ea1..882604e 100644
+--- a/sound/soc/codecs/wm8900.c
++++ b/sound/soc/codecs/wm8900.c
+@@ -116,6 +116,7 @@
+ #define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
+ 
+ #define WM8900_REG_DACCTRL_MUTE          0x004
++#define WM8900_REG_DACCTRL_DAC_SB_FILT   0x100
+ #define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
+ 
+ #define WM8900_REG_AUDIO3_ADCLRC_DIR    0x0800
+@@ -182,111 +183,20 @@ static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
+ 	/* Remaining registers all zero */
+ };
+ 
+-/*
+- * read wm8900 register cache
+- */
+-static inline unsigned int wm8900_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-
+-	BUG_ON(reg >= WM8900_MAXREG);
+-
+-	if (reg == WM8900_REG_ID)
+-		return 0;
+-
+-	return cache[reg];
+-}
+-
+-/*
+- * write wm8900 register cache
+- */
+-static inline void wm8900_write_reg_cache(struct snd_soc_codec *codec,
+-	u16 reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-
+-	BUG_ON(reg >= WM8900_MAXREG);
+-
+-	cache[reg] = value;
+-}
+-
+-/*
+- * write to the WM8900 register space
+- */
+-static int wm8900_write(struct snd_soc_codec *codec, unsigned int reg,
+-			unsigned int value)
+-{
+-	u8 data[3];
+-
+-	if (value == wm8900_read_reg_cache(codec, reg))
+-		return 0;
+-
+-	/* data is
+-	 *   D15..D9 WM8900 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = reg;
+-	data[1] = value >> 8;
+-	data[2] = value & 0x00ff;
+-
+-	wm8900_write_reg_cache(codec, reg, value);
+-	if (codec->hw_write(codec->control_data, data, 3) == 3)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-/*
+- * Read from the wm8900.
+- */
+-static unsigned int wm8900_chip_read(struct snd_soc_codec *codec, u8 reg)
+-{
+-	struct i2c_msg xfer[2];
+-	u16 data;
+-	int ret;
+-	struct i2c_client *client = codec->control_data;
+-
+-	BUG_ON(reg != WM8900_REG_ID && reg != WM8900_REG_POWER1);
+-
+-	/* Write register */
+-	xfer[0].addr = client->addr;
+-	xfer[0].flags = 0;
+-	xfer[0].len = 1;
+-	xfer[0].buf = &reg;
+-
+-	/* Read data */
+-	xfer[1].addr = client->addr;
+-	xfer[1].flags = I2C_M_RD;
+-	xfer[1].len = 2;
+-	xfer[1].buf = (u8 *)&data;
+-
+-	ret = i2c_transfer(client->adapter, xfer, 2);
+-	if (ret != 2) {
+-		printk(KERN_CRIT "i2c_transfer returned %d\n", ret);
+-		return 0;
+-	}
+-
+-	return (data >> 8) | ((data & 0xff) << 8);
+-}
+-
+-/*
+- * Read from the WM8900 register space.  Most registers can't be read
+- * and are therefore supplied from cache.
+- */
+-static unsigned int wm8900_read(struct snd_soc_codec *codec, unsigned int reg)
++static int wm8900_volatile_register(unsigned int reg)
+ {
+ 	switch (reg) {
+ 	case WM8900_REG_ID:
+-		return wm8900_chip_read(codec, reg);
++	case WM8900_REG_POWER1:
++		return 1;
+ 	default:
+-		return wm8900_read_reg_cache(codec, reg);
++		return 0;
+ 	}
+ }
+ 
+ static void wm8900_reset(struct snd_soc_codec *codec)
+ {
+-	wm8900_write(codec, WM8900_REG_RESET, 0);
++	snd_soc_write(codec, WM8900_REG_RESET, 0);
+ 
+ 	memcpy(codec->reg_cache, wm8900_reg_defaults,
+ 	       sizeof(codec->reg_cache));
+@@ -296,14 +206,14 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
+ 			   struct snd_kcontrol *kcontrol, int event)
+ {
+ 	struct snd_soc_codec *codec = w->codec;
+-	u16 hpctl1 = wm8900_read(codec, WM8900_REG_HPCTL1);
++	u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
+ 
+ 	switch (event) {
+ 	case SND_SOC_DAPM_PRE_PMU:
+ 		/* Clamp headphone outputs */
+ 		hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
+ 			WM8900_REG_HPCTL1_HP_CLAMP_OP;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 		break;
+ 
+ 	case SND_SOC_DAPM_POST_PMU:
+@@ -312,41 +222,41 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
+ 		hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
+ 			WM8900_REG_HPCTL1_HP_SHORT2 |
+ 			WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 
+ 		msleep(400);
+ 
+ 		/* Enable the output stage */
+ 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
+ 		hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 
+ 		/* Remove the shorts */
+ 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 		break;
+ 
+ 	case SND_SOC_DAPM_PRE_PMD:
+ 		/* Short the output */
+ 		hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 
+ 		/* Disable the output stage */
+ 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 
+ 		/* Clamp the outputs and power down input */
+ 		hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
+ 			WM8900_REG_HPCTL1_HP_CLAMP_OP;
+ 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
+-		wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+ 		break;
+ 
+ 	case SND_SOC_DAPM_POST_PMD:
+ 		/* Disable everything */
+-		wm8900_write(codec, WM8900_REG_HPCTL1, 0);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
+ 		break;
+ 
+ 	default:
+@@ -439,7 +349,6 @@ SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
+ SOC_ENUM("DAC Mute Rate", dac_mute_rate),
+ SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
+ SOC_ENUM("DAC Deemphasis", dac_deemphasis),
+-SOC_SINGLE("DAC Sloping Stopband Filter Switch", WM8900_REG_DACCTRL, 8, 1, 0),
+ SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
+ 	   12, 1, 0),
+ 
+@@ -723,7 +632,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	u16 reg;
+ 
+-	reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60;
++	reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
+ 
+ 	switch (params_format(params)) {
+ 	case SNDRV_PCM_FORMAT_S16_LE:
+@@ -741,7 +650,18 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8900_write(codec, WM8900_REG_AUDIO1, reg);
++	snd_soc_write(codec, WM8900_REG_AUDIO1, reg);
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
++
++		if (params_rate(params) <= 24000)
++			reg |= WM8900_REG_DACCTRL_DAC_SB_FILT;
++		else
++			reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT;
++
++		snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
++	}
+ 
+ 	return 0;
+ }
+@@ -778,11 +698,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
+ 	}
+ 
+ 	if (target > 100000000)
+-		printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d"
+-		       " Fout=%d\n", target, Fref, Fout);
++		printk(KERN_WARNING "wm8900: FLL rate %u out of range, Fref=%u"
++		       " Fout=%u\n", target, Fref, Fout);
+ 	if (div > 32) {
+ 		printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
+-		       "Fref=%d, Fout=%d, target=%d\n",
++		       "Fref=%u, Fout=%u, target=%u\n",
+ 		       div, Fref, Fout, target);
+ 		return -EINVAL;
+ 	}
+@@ -834,18 +754,18 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
+ 		return 0;
+ 
+ 	/* The digital side should be disabled during any change. */
+-	reg = wm8900_read(codec, WM8900_REG_POWER1);
+-	wm8900_write(codec, WM8900_REG_POWER1,
++	reg = snd_soc_read(codec, WM8900_REG_POWER1);
++	snd_soc_write(codec, WM8900_REG_POWER1,
+ 		     reg & (~WM8900_REG_POWER1_FLL_ENA));
+ 
+ 	/* Disable the FLL? */
+ 	if (!freq_in || !freq_out) {
+-		reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
+-		wm8900_write(codec, WM8900_REG_CLOCKING1,
++		reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
++		snd_soc_write(codec, WM8900_REG_CLOCKING1,
+ 			     reg & (~WM8900_REG_CLOCKING1_MCLK_SRC));
+ 
+-		reg = wm8900_read(codec, WM8900_REG_FLLCTL1);
+-		wm8900_write(codec, WM8900_REG_FLLCTL1,
++		reg = snd_soc_read(codec, WM8900_REG_FLLCTL1);
++		snd_soc_write(codec, WM8900_REG_FLLCTL1,
+ 			     reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
+ 
+ 		wm8900->fll_in = freq_in;
+@@ -862,40 +782,40 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
+ 
+ 	/* The osclilator *MUST* be enabled before we enable the
+ 	 * digital circuit. */
+-	wm8900_write(codec, WM8900_REG_FLLCTL1,
++	snd_soc_write(codec, WM8900_REG_FLLCTL1,
+ 		     fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
+ 
+-	wm8900_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
+-	wm8900_write(codec, WM8900_REG_FLLCTL5,
++	snd_soc_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
++	snd_soc_write(codec, WM8900_REG_FLLCTL5,
+ 		     (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
+ 
+ 	if (fll_div.k) {
+-		wm8900_write(codec, WM8900_REG_FLLCTL2,
++		snd_soc_write(codec, WM8900_REG_FLLCTL2,
+ 			     (fll_div.k >> 8) | 0x100);
+-		wm8900_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
++		snd_soc_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
+ 	} else
+-		wm8900_write(codec, WM8900_REG_FLLCTL2, 0);
++		snd_soc_write(codec, WM8900_REG_FLLCTL2, 0);
+ 
+ 	if (fll_div.fll_slow_lock_ref)
+-		wm8900_write(codec, WM8900_REG_FLLCTL6,
++		snd_soc_write(codec, WM8900_REG_FLLCTL6,
+ 			     WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
+ 	else
+-		wm8900_write(codec, WM8900_REG_FLLCTL6, 0);
++		snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
+ 
+-	reg = wm8900_read(codec, WM8900_REG_POWER1);
+-	wm8900_write(codec, WM8900_REG_POWER1,
++	reg = snd_soc_read(codec, WM8900_REG_POWER1);
++	snd_soc_write(codec, WM8900_REG_POWER1,
+ 		     reg | WM8900_REG_POWER1_FLL_ENA);
+ 
+ reenable:
+-	reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
+-	wm8900_write(codec, WM8900_REG_CLOCKING1,
++	reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
++	snd_soc_write(codec, WM8900_REG_CLOCKING1,
+ 		     reg | WM8900_REG_CLOCKING1_MCLK_SRC);
+ 
+ 	return 0;
+ }
+ 
+-static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out)
++static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
+ {
+ 	return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
+ }
+@@ -908,38 +828,38 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 
+ 	switch (div_id) {
+ 	case WM8900_BCLK_DIV:
+-		reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
+-		wm8900_write(codec, WM8900_REG_CLOCKING1,
++		reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
++		snd_soc_write(codec, WM8900_REG_CLOCKING1,
+ 			     div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
+ 		break;
+ 	case WM8900_OPCLK_DIV:
+-		reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
+-		wm8900_write(codec, WM8900_REG_CLOCKING1,
++		reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
++		snd_soc_write(codec, WM8900_REG_CLOCKING1,
+ 			     div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
+ 		break;
+ 	case WM8900_DAC_LRCLK:
+-		reg = wm8900_read(codec, WM8900_REG_AUDIO4);
+-		wm8900_write(codec, WM8900_REG_AUDIO4,
++		reg = snd_soc_read(codec, WM8900_REG_AUDIO4);
++		snd_soc_write(codec, WM8900_REG_AUDIO4,
+ 			     div | (reg & WM8900_LRC_MASK));
+ 		break;
+ 	case WM8900_ADC_LRCLK:
+-		reg = wm8900_read(codec, WM8900_REG_AUDIO3);
+-		wm8900_write(codec, WM8900_REG_AUDIO3,
++		reg = snd_soc_read(codec, WM8900_REG_AUDIO3);
++		snd_soc_write(codec, WM8900_REG_AUDIO3,
+ 			     div | (reg & WM8900_LRC_MASK));
+ 		break;
+ 	case WM8900_DAC_CLKDIV:
+-		reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
+-		wm8900_write(codec, WM8900_REG_CLOCKING2,
++		reg = snd_soc_read(codec, WM8900_REG_CLOCKING2);
++		snd_soc_write(codec, WM8900_REG_CLOCKING2,
+ 			     div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
+ 		break;
+ 	case WM8900_ADC_CLKDIV:
+-		reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
+-		wm8900_write(codec, WM8900_REG_CLOCKING2,
++		reg = snd_soc_read(codec, WM8900_REG_CLOCKING2);
++		snd_soc_write(codec, WM8900_REG_CLOCKING2,
+ 			     div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
+ 		break;
+ 	case WM8900_LRCLK_MODE:
+-		reg = wm8900_read(codec, WM8900_REG_DACCTRL);
+-		wm8900_write(codec, WM8900_REG_DACCTRL,
++		reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
++		snd_soc_write(codec, WM8900_REG_DACCTRL,
+ 			     div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
+ 		break;
+ 	default:
+@@ -956,10 +876,10 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	unsigned int clocking1, aif1, aif3, aif4;
+ 
+-	clocking1 = wm8900_read(codec, WM8900_REG_CLOCKING1);
+-	aif1 = wm8900_read(codec, WM8900_REG_AUDIO1);
+-	aif3 = wm8900_read(codec, WM8900_REG_AUDIO3);
+-	aif4 = wm8900_read(codec, WM8900_REG_AUDIO4);
++	clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1);
++	aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1);
++	aif3 = snd_soc_read(codec, WM8900_REG_AUDIO3);
++	aif4 = snd_soc_read(codec, WM8900_REG_AUDIO4);
+ 
+ 	/* set master/slave audio interface */
+ 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+@@ -1055,10 +975,10 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8900_write(codec, WM8900_REG_CLOCKING1, clocking1);
+-	wm8900_write(codec, WM8900_REG_AUDIO1, aif1);
+-	wm8900_write(codec, WM8900_REG_AUDIO3, aif3);
+-	wm8900_write(codec, WM8900_REG_AUDIO4, aif4);
++	snd_soc_write(codec, WM8900_REG_CLOCKING1, clocking1);
++	snd_soc_write(codec, WM8900_REG_AUDIO1, aif1);
++	snd_soc_write(codec, WM8900_REG_AUDIO3, aif3);
++	snd_soc_write(codec, WM8900_REG_AUDIO4, aif4);
+ 
+ 	return 0;
+ }
+@@ -1068,14 +988,14 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	u16 reg;
+ 
+-	reg = wm8900_read(codec, WM8900_REG_DACCTRL);
++	reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
+ 
+ 	if (mute)
+ 		reg |= WM8900_REG_DACCTRL_MUTE;
+ 	else
+ 		reg &= ~WM8900_REG_DACCTRL_MUTE;
+ 
+-	wm8900_write(codec, WM8900_REG_DACCTRL, reg);
++	snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
+ 
+ 	return 0;
+ }
+@@ -1124,11 +1044,11 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
+ 	switch (level) {
+ 	case SND_SOC_BIAS_ON:
+ 		/* Enable thermal shutdown */
+-		reg = wm8900_read(codec, WM8900_REG_GPIO);
+-		wm8900_write(codec, WM8900_REG_GPIO,
++		reg = snd_soc_read(codec, WM8900_REG_GPIO);
++		snd_soc_write(codec, WM8900_REG_GPIO,
+ 			     reg | WM8900_REG_GPIO_TEMP_ENA);
+-		reg = wm8900_read(codec, WM8900_REG_ADDCTL);
+-		wm8900_write(codec, WM8900_REG_ADDCTL,
++		reg = snd_soc_read(codec, WM8900_REG_ADDCTL);
++		snd_soc_write(codec, WM8900_REG_ADDCTL,
+ 			     reg | WM8900_REG_ADDCTL_TEMP_SD);
+ 		break;
+ 
+@@ -1139,69 +1059,69 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
+ 		/* Charge capacitors if initial power up */
+ 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ 			/* STARTUP_BIAS_ENA on */
+-			wm8900_write(codec, WM8900_REG_POWER1,
++			snd_soc_write(codec, WM8900_REG_POWER1,
+ 				     WM8900_REG_POWER1_STARTUP_BIAS_ENA);
+ 
+ 			/* Startup bias mode */
+-			wm8900_write(codec, WM8900_REG_ADDCTL,
++			snd_soc_write(codec, WM8900_REG_ADDCTL,
+ 				     WM8900_REG_ADDCTL_BIAS_SRC |
+ 				     WM8900_REG_ADDCTL_VMID_SOFTST);
+ 
+ 			/* VMID 2x50k */
+-			wm8900_write(codec, WM8900_REG_POWER1,
++			snd_soc_write(codec, WM8900_REG_POWER1,
+ 				     WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
+ 
+ 			/* Allow capacitors to charge */
+ 			schedule_timeout_interruptible(msecs_to_jiffies(400));
+ 
+ 			/* Enable bias */
+-			wm8900_write(codec, WM8900_REG_POWER1,
++			snd_soc_write(codec, WM8900_REG_POWER1,
+ 				     WM8900_REG_POWER1_STARTUP_BIAS_ENA |
+ 				     WM8900_REG_POWER1_BIAS_ENA | 0x1);
+ 
+-			wm8900_write(codec, WM8900_REG_ADDCTL, 0);
++			snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
+ 
+-			wm8900_write(codec, WM8900_REG_POWER1,
++			snd_soc_write(codec, WM8900_REG_POWER1,
+ 				     WM8900_REG_POWER1_BIAS_ENA | 0x1);
+ 		}
+ 
+-		reg = wm8900_read(codec, WM8900_REG_POWER1);
+-		wm8900_write(codec, WM8900_REG_POWER1,
++		reg = snd_soc_read(codec, WM8900_REG_POWER1);
++		snd_soc_write(codec, WM8900_REG_POWER1,
+ 			     (reg & WM8900_REG_POWER1_FLL_ENA) |
+ 			     WM8900_REG_POWER1_BIAS_ENA | 0x1);
+-		wm8900_write(codec, WM8900_REG_POWER2,
++		snd_soc_write(codec, WM8900_REG_POWER2,
+ 			     WM8900_REG_POWER2_SYSCLK_ENA);
+-		wm8900_write(codec, WM8900_REG_POWER3, 0);
++		snd_soc_write(codec, WM8900_REG_POWER3, 0);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_OFF:
+ 		/* Startup bias enable */
+-		reg = wm8900_read(codec, WM8900_REG_POWER1);
+-		wm8900_write(codec, WM8900_REG_POWER1,
++		reg = snd_soc_read(codec, WM8900_REG_POWER1);
++		snd_soc_write(codec, WM8900_REG_POWER1,
+ 			     reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
+-		wm8900_write(codec, WM8900_REG_ADDCTL,
++		snd_soc_write(codec, WM8900_REG_ADDCTL,
+ 			     WM8900_REG_ADDCTL_BIAS_SRC |
+ 			     WM8900_REG_ADDCTL_VMID_SOFTST);
+ 
+ 		/* Discharge caps */
+-		wm8900_write(codec, WM8900_REG_POWER1,
++		snd_soc_write(codec, WM8900_REG_POWER1,
+ 			     WM8900_REG_POWER1_STARTUP_BIAS_ENA);
+ 		schedule_timeout_interruptible(msecs_to_jiffies(500));
+ 
+ 		/* Remove clamp */
+-		wm8900_write(codec, WM8900_REG_HPCTL1, 0);
++		snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
+ 
+ 		/* Power down */
+-		wm8900_write(codec, WM8900_REG_ADDCTL, 0);
+-		wm8900_write(codec, WM8900_REG_POWER1, 0);
+-		wm8900_write(codec, WM8900_REG_POWER2, 0);
+-		wm8900_write(codec, WM8900_REG_POWER3, 0);
++		snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
++		snd_soc_write(codec, WM8900_REG_POWER1, 0);
++		snd_soc_write(codec, WM8900_REG_POWER2, 0);
++		snd_soc_write(codec, WM8900_REG_POWER3, 0);
+ 
+ 		/* Need to let things settle before stopping the clock
+ 		 * to ensure that restart works, see "Stopping the
+ 		 * master clock" in the datasheet. */
+ 		schedule_timeout_interruptible(msecs_to_jiffies(1));
+-		wm8900_write(codec, WM8900_REG_POWER2,
++		snd_soc_write(codec, WM8900_REG_POWER2,
+ 			     WM8900_REG_POWER2_SYSCLK_ENA);
+ 		break;
+ 	}
+@@ -1264,7 +1184,7 @@ static int wm8900_resume(struct platform_device *pdev)
+ 
+ 	if (cache) {
+ 		for (i = 0; i < WM8900_MAXREG; i++)
+-			wm8900_write(codec, i, cache[i]);
++			snd_soc_write(codec, i, cache[i]);
+ 		kfree(cache);
+ 	} else
+ 		dev_err(&pdev->dev, "Unable to allocate register cache\n");
+@@ -1297,16 +1217,20 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
+ 
+ 	codec->name = "WM8900";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8900_read;
+-	codec->write = wm8900_write;
+ 	codec->dai = &wm8900_dai;
+ 	codec->num_dai = 1;
+-	codec->hw_write = (hw_write_t)i2c_master_send;
+ 	codec->control_data = i2c;
+ 	codec->set_bias_level = wm8900_set_bias_level;
++	codec->volatile_register = wm8900_volatile_register;
+ 	codec->dev = &i2c->dev;
+ 
+-	reg = wm8900_read(codec, WM8900_REG_ID);
++	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
++	if (ret != 0) {
++		dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
++		goto err;
++	}
++
++	reg = snd_soc_read(codec, WM8900_REG_ID);
+ 	if (reg != 0x8900) {
+ 		dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
+ 		ret = -ENODEV;
+@@ -1314,7 +1238,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
+ 	}
+ 
+ 	/* Read back from the chip */
+-	reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
++	reg = snd_soc_read(codec, WM8900_REG_POWER1);
+ 	reg = (reg >> 12) & 0xf;
+ 	dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
+ 
+@@ -1324,29 +1248,29 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
+ 	wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ 
+ 	/* Latch the volume update bits */
+-	wm8900_write(codec, WM8900_REG_LINVOL,
+-		     wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
+-	wm8900_write(codec, WM8900_REG_RINVOL,
+-		     wm8900_read(codec, WM8900_REG_RINVOL) | 0x100);
+-	wm8900_write(codec, WM8900_REG_LOUT1CTL,
+-		     wm8900_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
+-	wm8900_write(codec, WM8900_REG_ROUT1CTL,
+-		     wm8900_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
+-	wm8900_write(codec, WM8900_REG_LOUT2CTL,
+-		     wm8900_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
+-	wm8900_write(codec, WM8900_REG_ROUT2CTL,
+-		     wm8900_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
+-	wm8900_write(codec, WM8900_REG_LDAC_DV,
+-		     wm8900_read(codec, WM8900_REG_LDAC_DV) | 0x100);
+-	wm8900_write(codec, WM8900_REG_RDAC_DV,
+-		     wm8900_read(codec, WM8900_REG_RDAC_DV) | 0x100);
+-	wm8900_write(codec, WM8900_REG_LADC_DV,
+-		     wm8900_read(codec, WM8900_REG_LADC_DV) | 0x100);
+-	wm8900_write(codec, WM8900_REG_RADC_DV,
+-		     wm8900_read(codec, WM8900_REG_RADC_DV) | 0x100);
++	snd_soc_write(codec, WM8900_REG_LINVOL,
++		      snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100);
++	snd_soc_write(codec, WM8900_REG_RINVOL,
++		      snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100);
++	snd_soc_write(codec, WM8900_REG_LOUT1CTL,
++		      snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
++	snd_soc_write(codec, WM8900_REG_ROUT1CTL,
++		      snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
++	snd_soc_write(codec, WM8900_REG_LOUT2CTL,
++		      snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
++	snd_soc_write(codec, WM8900_REG_ROUT2CTL,
++		      snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
++	snd_soc_write(codec, WM8900_REG_LDAC_DV,
++		      snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100);
++	snd_soc_write(codec, WM8900_REG_RDAC_DV,
++		      snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100);
++	snd_soc_write(codec, WM8900_REG_LADC_DV,
++		      snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100);
++	snd_soc_write(codec, WM8900_REG_RADC_DV,
++		      snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100);
+ 
+ 	/* Set the DAC and mixer output bias */
+-	wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
++	snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
+ 
+ 	wm8900_dai.dev = &i2c->dev;
+ 
+@@ -1388,6 +1312,21 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&client->dev);
++}
++
++static int wm8900_i2c_resume(struct i2c_client *client)
++{
++	return snd_soc_resume_device(&client->dev);
++}
++#else
++#define wm8900_i2c_suspend NULL
++#define wm8900_i2c_resume NULL
++#endif
++
+ static const struct i2c_device_id wm8900_i2c_id[] = {
+ 	{ "wm8900", 0 },
+ 	{ }
+@@ -1401,6 +1340,8 @@ static struct i2c_driver wm8900_i2c_driver = {
+ 	},
+ 	.probe = wm8900_i2c_probe,
+ 	.remove = __devexit_p(wm8900_i2c_remove),
++	.suspend = wm8900_i2c_suspend,
++	.resume = wm8900_i2c_resume,
+ 	.id_table = wm8900_i2c_id,
+ };
+ 
+diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
+index 8cf571f..fe1307b 100644
+--- a/sound/soc/codecs/wm8903.c
++++ b/sound/soc/codecs/wm8903.c
+@@ -217,7 +217,6 @@ struct wm8903_priv {
+ 	int sysclk;
+ 
+ 	/* Reference counts */
+-	int charge_pump_users;
+ 	int class_w_users;
+ 	int playback_active;
+ 	int capture_active;
+@@ -226,94 +225,18 @@ struct wm8903_priv {
+ 	struct snd_pcm_substream *slave_substream;
+ };
+ 
+-
+-static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
+-						 unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-
+-	BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
+-
+-	return cache[reg];
+-}
+-
+-static unsigned int wm8903_hw_read(struct snd_soc_codec *codec, u8 reg)
+-{
+-	struct i2c_msg xfer[2];
+-	u16 data;
+-	int ret;
+-	struct i2c_client *client = codec->control_data;
+-
+-	/* Write register */
+-	xfer[0].addr = client->addr;
+-	xfer[0].flags = 0;
+-	xfer[0].len = 1;
+-	xfer[0].buf = &reg;
+-
+-	/* Read data */
+-	xfer[1].addr = client->addr;
+-	xfer[1].flags = I2C_M_RD;
+-	xfer[1].len = 2;
+-	xfer[1].buf = (u8 *)&data;
+-
+-	ret = i2c_transfer(client->adapter, xfer, 2);
+-	if (ret != 2) {
+-		pr_err("i2c_transfer returned %d\n", ret);
+-		return 0;
+-	}
+-
+-	return (data >> 8) | ((data & 0xff) << 8);
+-}
+-
+-static unsigned int wm8903_read(struct snd_soc_codec *codec,
+-				unsigned int reg)
++static int wm8903_volatile_register(unsigned int reg)
+ {
+ 	switch (reg) {
+ 	case WM8903_SW_RESET_AND_ID:
+ 	case WM8903_REVISION_NUMBER:
+ 	case WM8903_INTERRUPT_STATUS_1:
+ 	case WM8903_WRITE_SEQUENCER_4:
+-		return wm8903_hw_read(codec, reg);
+-
+-	default:
+-		return wm8903_read_reg_cache(codec, reg);
+-	}
+-}
+-
+-static void wm8903_write_reg_cache(struct snd_soc_codec *codec,
+-				   u16 reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-
+-	BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
+-
+-	switch (reg) {
+-	case WM8903_SW_RESET_AND_ID:
+-	case WM8903_REVISION_NUMBER:
+-		break;
++		return 1;
+ 
+ 	default:
+-		cache[reg] = value;
+-		break;
+-	}
+-}
+-
+-static int wm8903_write(struct snd_soc_codec *codec, unsigned int reg,
+-			unsigned int value)
+-{
+-	u8 data[3];
+-
+-	wm8903_write_reg_cache(codec, reg, value);
+-
+-	/* Data format is 1 byte of address followed by 2 bytes of data */
+-	data[0] = reg;
+-	data[1] = (value >> 8) & 0xff;
+-	data[2] = value & 0xff;
+-
+-	if (codec->hw_write(codec->control_data, data, 3) == 2)
+ 		return 0;
+-	else
+-		return -EIO;
++	}
+ }
+ 
+ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
+@@ -324,13 +247,13 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
+ 	BUG_ON(start > 48);
+ 
+ 	/* Enable the sequencer */
+-	reg[0] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_0);
++	reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
+ 	reg[0] |= WM8903_WSEQ_ENA;
+-	wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
++	snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
+ 
+ 	dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
+ 
+-	wm8903_write(codec, WM8903_WRITE_SEQUENCER_3,
++	snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
+ 		     start | WM8903_WSEQ_START);
+ 
+ 	/* Wait for it to complete.  If we have the interrupt wired up then
+@@ -340,13 +263,13 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
+ 	do {
+ 		msleep(10);
+ 
+-		reg[4] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_4);
++		reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
+ 	} while (reg[4] & WM8903_WSEQ_BUSY);
+ 
+ 	dev_dbg(&i2c->dev, "Sequence complete\n");
+ 
+ 	/* Disable the sequencer again */
+-	wm8903_write(codec, WM8903_WRITE_SEQUENCER_0,
++	snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
+ 		     reg[0] & ~WM8903_WSEQ_ENA);
+ 
+ 	return 0;
+@@ -358,12 +281,12 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
+ 
+ 	/* There really ought to be something better we can do here :/ */
+ 	for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
+-		cache[i] = wm8903_hw_read(codec, i);
++		cache[i] = codec->hw_read(codec, i);
+ }
+ 
+ static void wm8903_reset(struct snd_soc_codec *codec)
+ {
+-	wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
++	snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
+ 	memcpy(codec->reg_cache, wm8903_reg_defaults,
+ 	       sizeof(wm8903_reg_defaults));
+ }
+@@ -373,6 +296,15 @@ static void wm8903_reset(struct snd_soc_codec *codec)
+ #define WM8903_OUTPUT_INT   0x2
+ #define WM8903_OUTPUT_IN    0x1
+ 
++static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
++			   struct snd_kcontrol *kcontrol, int event)
++{
++	WARN_ON(event != SND_SOC_DAPM_POST_PMU);
++	mdelay(4);
++
++	return 0;
++}
++
+ /*
+  * Event for headphone and line out amplifier power changes.  Special
+  * power up/down sequences are required in order to maximise pop/click
+@@ -382,19 +314,20 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
+ 			       struct snd_kcontrol *kcontrol, int event)
+ {
+ 	struct snd_soc_codec *codec = w->codec;
+-	struct wm8903_priv *wm8903 = codec->private_data;
+-	struct i2c_client *i2c = codec->control_data;
+ 	u16 val;
+ 	u16 reg;
++	u16 dcs_reg;
++	u16 dcs_bit;
+ 	int shift;
+-	u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0);
+ 
+ 	switch (w->reg) {
+ 	case WM8903_POWER_MANAGEMENT_2:
+ 		reg = WM8903_ANALOGUE_HP_0;
++		dcs_bit = 0 + w->shift;
+ 		break;
+ 	case WM8903_POWER_MANAGEMENT_3:
+ 		reg = WM8903_ANALOGUE_LINEOUT_0;
++		dcs_bit = 2 + w->shift;
+ 		break;
+ 	default:
+ 		BUG();
+@@ -414,67 +347,52 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
+ 	}
+ 
+ 	if (event & SND_SOC_DAPM_PRE_PMU) {
+-		val = wm8903_read(codec, reg);
++		val = snd_soc_read(codec, reg);
+ 
+ 		/* Short the output */
+ 		val &= ~(WM8903_OUTPUT_SHORT << shift);
+-		wm8903_write(codec, reg, val);
+-
+-		wm8903->charge_pump_users++;
+-
+-		dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
+-			wm8903->charge_pump_users);
+-
+-		if (wm8903->charge_pump_users == 1) {
+-			dev_dbg(&i2c->dev, "Enabling charge pump\n");
+-			wm8903_write(codec, WM8903_CHARGE_PUMP_0,
+-				     cp_reg | WM8903_CP_ENA);
+-			mdelay(4);
+-		}
++		snd_soc_write(codec, reg, val);
+ 	}
+ 
+ 	if (event & SND_SOC_DAPM_POST_PMU) {
+-		val = wm8903_read(codec, reg);
++		val = snd_soc_read(codec, reg);
+ 
+ 		val |= (WM8903_OUTPUT_IN << shift);
+-		wm8903_write(codec, reg, val);
++		snd_soc_write(codec, reg, val);
+ 
+ 		val |= (WM8903_OUTPUT_INT << shift);
+-		wm8903_write(codec, reg, val);
++		snd_soc_write(codec, reg, val);
+ 
+ 		/* Turn on the output ENA_OUTP */
+ 		val |= (WM8903_OUTPUT_OUT << shift);
+-		wm8903_write(codec, reg, val);
++		snd_soc_write(codec, reg, val);
++
++		/* Enable the DC servo */
++		dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0);
++		dcs_reg |= dcs_bit;
++		snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
+ 
+ 		/* Remove the short */
+ 		val |= (WM8903_OUTPUT_SHORT << shift);
+-		wm8903_write(codec, reg, val);
++		snd_soc_write(codec, reg, val);
+ 	}
+ 
+ 	if (event & SND_SOC_DAPM_PRE_PMD) {
+-		val = wm8903_read(codec, reg);
++		val = snd_soc_read(codec, reg);
+ 
+ 		/* Short the output */
+ 		val &= ~(WM8903_OUTPUT_SHORT << shift);
+-		wm8903_write(codec, reg, val);
++		snd_soc_write(codec, reg, val);
++
++		/* Disable the DC servo */
++		dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0);
++		dcs_reg &= ~dcs_bit;
++		snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
+ 
+ 		/* Then disable the intermediate and output stages */
+ 		val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
+ 			  WM8903_OUTPUT_IN) << shift);
+-		wm8903_write(codec, reg, val);
+-	}
+-
+-	if (event & SND_SOC_DAPM_POST_PMD) {
+-		wm8903->charge_pump_users--;
+-
+-		dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
+-			wm8903->charge_pump_users);
+-
+-		if (wm8903->charge_pump_users == 0) {
+-			dev_dbg(&i2c->dev, "Disabling charge pump\n");
+-			wm8903_write(codec, WM8903_CHARGE_PUMP_0,
+-				     cp_reg & ~WM8903_CP_ENA);
+-		}
++		snd_soc_write(codec, reg, val);
+ 	}
+ 
+ 	return 0;
+@@ -498,13 +416,13 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
+ 	u16 reg;
+ 	int ret;
+ 
+-	reg = wm8903_read(codec, WM8903_CLASS_W_0);
++	reg = snd_soc_read(codec, WM8903_CLASS_W_0);
+ 
+ 	/* Turn it off if we're about to enable bypass */
+ 	if (ucontrol->value.integer.value[0]) {
+ 		if (wm8903->class_w_users == 0) {
+ 			dev_dbg(&i2c->dev, "Disabling Class W\n");
+-			wm8903_write(codec, WM8903_CLASS_W_0, reg &
++			snd_soc_write(codec, WM8903_CLASS_W_0, reg &
+ 				     ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
+ 		}
+ 		wm8903->class_w_users++;
+@@ -517,7 +435,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
+ 	if (!ucontrol->value.integer.value[0]) {
+ 		if (wm8903->class_w_users == 1) {
+ 			dev_dbg(&i2c->dev, "Enabling Class W\n");
+-			wm8903_write(codec, WM8903_CLASS_W_0, reg |
++			snd_soc_write(codec, WM8903_CLASS_W_0, reg |
+ 				     WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
+ 		}
+ 		wm8903->class_w_users--;
+@@ -539,6 +457,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
+ /* ALSA can only do steps of .01dB */
+ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
+ 
++static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0);
+ static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
+ 
+ static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
+@@ -657,6 +576,16 @@ static const struct soc_enum rinput_inv_enum =
+ 	SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
+ 
+ 
++static const char *sidetone_text[] = {
++	"None", "Left", "Right"
++};
++
++static const struct soc_enum lsidetone_enum =
++	SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text);
++
++static const struct soc_enum rsidetone_enum =
++	SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
++
+ static const struct snd_kcontrol_new wm8903_snd_controls[] = {
+ 
+ /* Input PGAs - No TLV since the scale depends on PGA mode */
+@@ -700,6 +629,9 @@ SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
+ SOC_ENUM("ADC Companding Mode", adc_companding),
+ SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
+ 
++SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
++	       12, 0, digital_sidetone_tlv),
++
+ /* DAC */
+ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
+ 		 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
+@@ -707,8 +639,6 @@ SOC_ENUM("DAC Soft Mute Rate", soft_mute),
+ SOC_ENUM("DAC Mute Mode", mute_mode),
+ SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
+ SOC_ENUM("DAC De-emphasis", dac_deemphasis),
+-SOC_SINGLE("DAC Sloping Stopband Filter Switch",
+-	   WM8903_DAC_DIGITAL_1, 11, 1, 0),
+ SOC_ENUM("DAC Companding Mode", dac_companding),
+ SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
+ 
+@@ -762,6 +692,12 @@ static const struct snd_kcontrol_new rinput_mux =
+ static const struct snd_kcontrol_new rinput_inv_mux =
+ 	SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
+ 
++static const struct snd_kcontrol_new lsidetone_mux =
++	SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum);
++
++static const struct snd_kcontrol_new rsidetone_mux =
++	SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
++
+ static const struct snd_kcontrol_new left_output_mixer[] = {
+ SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
+ SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
+@@ -828,6 +764,9 @@ SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
+ SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0),
+ SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0),
+ 
++SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
++SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
++
+ SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0),
+ SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0),
+ 
+@@ -844,26 +783,29 @@ SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
+ SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
+ 		   1, 0, NULL, 0, wm8903_output_event,
+ 		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+-		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
++		   SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
+ 		   0, 0, NULL, 0, wm8903_output_event,
+ 		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+-		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
++		   SND_SOC_DAPM_PRE_PMD),
+ 
+ SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0,
+ 		   NULL, 0, wm8903_output_event,
+ 		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+-		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
++		   SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0,
+ 		   NULL, 0, wm8903_output_event,
+ 		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+-		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
++		   SND_SOC_DAPM_PRE_PMD),
+ 
+ SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
+ 		 NULL, 0),
+ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
+ 		 NULL, 0),
+ 
++SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
++		    wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
++SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
+ };
+ 
+ static const struct snd_soc_dapm_route intercon[] = {
+@@ -909,7 +851,19 @@ static const struct snd_soc_dapm_route intercon[] = {
+ 	{ "Right Input PGA", NULL, "Right Input Mode Mux" },
+ 
+ 	{ "ADCL", NULL, "Left Input PGA" },
++	{ "ADCL", NULL, "CLK_DSP" },
+ 	{ "ADCR", NULL, "Right Input PGA" },
++	{ "ADCR", NULL, "CLK_DSP" },
++
++	{ "DACL Sidetone", "Left", "ADCL" },
++	{ "DACL Sidetone", "Right", "ADCR" },
++	{ "DACR Sidetone", "Left", "ADCL" },
++	{ "DACR Sidetone", "Right", "ADCR" },
++
++	{ "DACL", NULL, "DACL Sidetone" },
++	{ "DACL", NULL, "CLK_DSP" },
++	{ "DACR", NULL, "DACR Sidetone" },
++	{ "DACR", NULL, "CLK_DSP" },
+ 
+ 	{ "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
+ 	{ "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
+@@ -951,6 +905,11 @@ static const struct snd_soc_dapm_route intercon[] = {
+ 
+ 	{ "ROP", NULL, "Right Speaker PGA" },
+ 	{ "RON", NULL, "Right Speaker PGA" },
++
++	{ "Left Headphone Output PGA", NULL, "Charge Pump" },
++	{ "Right Headphone Output PGA", NULL, "Charge Pump" },
++	{ "Left Line Output PGA", NULL, "Charge Pump" },
++	{ "Right Line Output PGA", NULL, "Charge Pump" },
+ };
+ 
+ static int wm8903_add_widgets(struct snd_soc_codec *codec)
+@@ -974,50 +933,55 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
+ 	switch (level) {
+ 	case SND_SOC_BIAS_ON:
+ 	case SND_SOC_BIAS_PREPARE:
+-		reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
++		reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
+ 		reg &= ~(WM8903_VMID_RES_MASK);
+ 		reg |= WM8903_VMID_RES_50K;
+-		wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
++		snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_STANDBY:
+ 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+-			wm8903_write(codec, WM8903_CLOCK_RATES_2,
++			snd_soc_write(codec, WM8903_CLOCK_RATES_2,
+ 				     WM8903_CLK_SYS_ENA);
+ 
++			/* Change DC servo dither level in startup sequence */
++			snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11);
++			snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257);
++			snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2);
++
+ 			wm8903_run_sequence(codec, 0);
+ 			wm8903_sync_reg_cache(codec, codec->reg_cache);
+ 
+ 			/* Enable low impedence charge pump output */
+-			reg = wm8903_read(codec,
++			reg = snd_soc_read(codec,
+ 					  WM8903_CONTROL_INTERFACE_TEST_1);
+-			wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
++			snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
+ 				     reg | WM8903_TEST_KEY);
+-			reg2 = wm8903_read(codec, WM8903_CHARGE_PUMP_TEST_1);
+-			wm8903_write(codec, WM8903_CHARGE_PUMP_TEST_1,
++			reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1);
++			snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1,
+ 				     reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
+-			wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
++			snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
+ 				     reg);
+ 
+ 			/* By default no bypass paths are enabled so
+ 			 * enable Class W support.
+ 			 */
+ 			dev_dbg(&i2c->dev, "Enabling Class W\n");
+-			wm8903_write(codec, WM8903_CLASS_W_0, reg |
++			snd_soc_write(codec, WM8903_CLASS_W_0, reg |
+ 				     WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
+ 		}
+ 
+-		reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
++		reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
+ 		reg &= ~(WM8903_VMID_RES_MASK);
+ 		reg |= WM8903_VMID_RES_250K;
+-		wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
++		snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_OFF:
+ 		wm8903_run_sequence(codec, 32);
+-		reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
++		reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2);
+ 		reg &= ~WM8903_CLK_SYS_ENA;
+-		wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
++		snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg);
+ 		break;
+ 	}
+ 
+@@ -1041,7 +1005,7 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 			      unsigned int fmt)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+-	u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
++	u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
+ 
+ 	aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
+ 		  WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
+@@ -1119,7 +1083,7 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
++	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
+ 
+ 	return 0;
+ }
+@@ -1129,14 +1093,14 @@ static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	u16 reg;
+ 
+-	reg = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
++	reg = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
+ 
+ 	if (mute)
+ 		reg |= WM8903_DAC_MUTE;
+ 	else
+ 		reg &= ~WM8903_DAC_MUTE;
+ 
+-	wm8903_write(codec, WM8903_DAC_DIGITAL_1, reg);
++	snd_soc_write(codec, WM8903_DAC_DIGITAL_1, reg);
+ 
+ 	return 0;
+ }
+@@ -1215,22 +1179,18 @@ static struct {
+ 	int div;
+ } bclk_divs[] = {
+ 	{  10,  0 },
+-	{  15,  1 },
+ 	{  20,  2 },
+ 	{  30,  3 },
+ 	{  40,  4 },
+ 	{  50,  5 },
+-	{  55,  6 },
+ 	{  60,  7 },
+ 	{  80,  8 },
+ 	{ 100,  9 },
+-	{ 110, 10 },
+ 	{ 120, 11 },
+ 	{ 160, 12 },
+ 	{ 200, 13 },
+ 	{ 220, 14 },
+ 	{ 240, 15 },
+-	{ 250, 16 },
+ 	{ 300, 17 },
+ 	{ 320, 18 },
+ 	{ 440, 19 },
+@@ -1277,14 +1237,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
+ 	if (wm8903->master_substream) {
+ 		master_runtime = wm8903->master_substream->runtime;
+ 
+-		dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
+-			master_runtime->sample_bits,
+-			master_runtime->rate);
+-
+-		snd_pcm_hw_constraint_minmax(substream->runtime,
+-					     SNDRV_PCM_HW_PARAM_RATE,
+-					     master_runtime->rate,
+-					     master_runtime->rate);
++		dev_dbg(&i2c->dev, "Constraining to %d bits\n",
++			master_runtime->sample_bits);
+ 
+ 		snd_pcm_hw_constraint_minmax(substream->runtime,
+ 					     SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+@@ -1336,17 +1290,24 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
+ 	int cur_val;
+ 	int clk_sys;
+ 
+-	u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
+-	u16 aif2 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_2);
+-	u16 aif3 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_3);
+-	u16 clock0 = wm8903_read(codec, WM8903_CLOCK_RATES_0);
+-	u16 clock1 = wm8903_read(codec, WM8903_CLOCK_RATES_1);
++	u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
++	u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2);
++	u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3);
++	u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0);
++	u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
++	u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
+ 
+ 	if (substream == wm8903->slave_substream) {
+ 		dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
+ 		return 0;
+ 	}
+ 
++	/* Enable sloping stopband filter for low sample rates */
++	if (fs <= 24000)
++		dac_digital1 |= WM8903_DAC_SB_FILT;
++	else
++		dac_digital1 &= ~WM8903_DAC_SB_FILT;
++
+ 	/* Configure sample rate logic for DSP - choose nearest rate */
+ 	dsp_config = 0;
+ 	best_val = abs(sample_rates[dsp_config].rate - fs);
+@@ -1466,11 +1427,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
+ 	aif2 |= bclk_divs[bclk_div].div;
+ 	aif3 |= bclk / fs;
+ 
+-	wm8903_write(codec, WM8903_CLOCK_RATES_0, clock0);
+-	wm8903_write(codec, WM8903_CLOCK_RATES_1, clock1);
+-	wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
+-	wm8903_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
+-	wm8903_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
++	snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
++	snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
++	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
++	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
++	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
++	snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1);
+ 
+ 	return 0;
+ }
+@@ -1523,6 +1485,7 @@ struct snd_soc_dai wm8903_dai = {
+ 		 .formats = WM8903_FORMATS,
+ 	 },
+ 	.ops = &wm8903_dai_ops,
++	.symmetric_rates = 1,
+ };
+ EXPORT_SYMBOL_GPL(wm8903_dai);
+ 
+@@ -1554,7 +1517,7 @@ static int wm8903_resume(struct platform_device *pdev)
+ 	if (tmp_cache) {
+ 		for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
+ 			if (tmp_cache[i] != reg_cache[i])
+-				wm8903_write(codec, i, tmp_cache[i]);
++				snd_soc_write(codec, i, tmp_cache[i]);
+ 	} else {
+ 		dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
+ 	}
+@@ -1585,9 +1548,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
+ 	codec->dev = &i2c->dev;
+ 	codec->name = "WM8903";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8903_read;
+-	codec->write = wm8903_write;
+-	codec->hw_write = (hw_write_t)i2c_master_send;
+ 	codec->bias_level = SND_SOC_BIAS_OFF;
+ 	codec->set_bias_level = wm8903_set_bias_level;
+ 	codec->dai = &wm8903_dai;
+@@ -1595,18 +1555,25 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
+ 	codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
+ 	codec->reg_cache = &wm8903->reg_cache[0];
+ 	codec->private_data = wm8903;
++	codec->volatile_register = wm8903_volatile_register;
+ 
+ 	i2c_set_clientdata(i2c, codec);
+ 	codec->control_data = i2c;
+ 
+-	val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
++	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
++	if (ret != 0) {
++		dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
++		goto err;
++	}
++
++	val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
+ 	if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
+ 		dev_err(&i2c->dev,
+ 			"Device with ID register %x is not a WM8903\n", val);
+ 		return -ENODEV;
+ 	}
+ 
+-	val = wm8903_read(codec, WM8903_REVISION_NUMBER);
++	val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
+ 	dev_info(&i2c->dev, "WM8903 revision %d\n",
+ 		 val & WM8903_CHIP_REV_MASK);
+ 
+@@ -1616,35 +1583,35 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
+ 	wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ 
+ 	/* Latch volume update bits */
+-	val = wm8903_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
++	val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
+ 	val |= WM8903_ADCVU;
+-	wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
+-	wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
++	snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
++	snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
+ 
+-	val = wm8903_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
++	val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
+ 	val |= WM8903_DACVU;
+-	wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
+-	wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
++	snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
++	snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
+ 
+-	val = wm8903_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
++	val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
+ 	val |= WM8903_HPOUTVU;
+-	wm8903_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
+-	wm8903_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
++	snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
++	snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
+ 
+-	val = wm8903_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
++	val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
+ 	val |= WM8903_LINEOUTVU;
+-	wm8903_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
+-	wm8903_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
++	snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
++	snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
+ 
+-	val = wm8903_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
++	val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
+ 	val |= WM8903_SPKVU;
+-	wm8903_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
+-	wm8903_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
++	snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
++	snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
+ 
+ 	/* Enable DAC soft mute by default */
+-	val = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
++	val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
+ 	val |= WM8903_DAC_MUTEMODE;
+-	wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
++	snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val);
+ 
+ 	wm8903_dai.dev = &i2c->dev;
+ 	wm8903_codec = codec;
+@@ -1688,6 +1655,21 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
++{
++	return snd_soc_suspend_device(&client->dev);
++}
++
++static int wm8903_i2c_resume(struct i2c_client *client)
++{
++	return snd_soc_resume_device(&client->dev);
++}
++#else
++#define wm8903_i2c_suspend NULL
++#define wm8903_i2c_resume NULL
++#endif
++
+ /* i2c codec control layer */
+ static const struct i2c_device_id wm8903_i2c_id[] = {
+        { "wm8903", 0 },
+@@ -1702,6 +1684,8 @@ static struct i2c_driver wm8903_i2c_driver = {
+ 	},
+ 	.probe    = wm8903_i2c_probe,
+ 	.remove   = __devexit_p(wm8903_i2c_remove),
++	.suspend  = wm8903_i2c_suspend,
++	.resume   = wm8903_i2c_resume,
+ 	.id_table = wm8903_i2c_id,
+ };
+ 
+diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
+index 032dca2..d66efb0 100644
+--- a/sound/soc/codecs/wm8971.c
++++ b/sound/soc/codecs/wm8971.c
+@@ -59,44 +59,7 @@ static const u16 wm8971_reg[] = {
+ 	0x0079, 0x0079, 0x0079,          /* 40 */
+ };
+ 
+-static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg < WM8971_REG_COUNT)
+-		return cache[reg];
+-
+-	return -1;
+-}
+-
+-static inline void wm8971_write_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-	if (reg < WM8971_REG_COUNT)
+-		cache[reg] = value;
+-}
+-
+-static int wm8971_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[2];
+-
+-	/* data is
+-	 *   D15..D9 WM8753 register offset
+-	 *   D8...D0 register data
+-	 */
+-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+-	data[1] = value & 0x00ff;
+-
+-	wm8971_write_reg_cache (codec, reg, value);
+-	if (codec->hw_write(codec->control_data, data, 2) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-#define wm8971_reset(c)	wm8971_write(c, WM8971_RESET, 0)
++#define wm8971_reset(c)	snd_soc_write(c, WM8971_RESET, 0)
+ 
+ /* WM8971 Controls */
+ static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
+@@ -521,7 +484,7 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8971_write(codec, WM8971_IFACE, iface);
++	snd_soc_write(codec, WM8971_IFACE, iface);
+ 	return 0;
+ }
+ 
+@@ -533,8 +496,8 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	struct wm8971_priv *wm8971 = codec->private_data;
+-	u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3;
+-	u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0;
++	u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
++	u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
+ 	int coeff = get_coeff(wm8971->sysclk, params_rate(params));
+ 
+ 	/* bit size */
+@@ -553,9 +516,9 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	}
+ 
+ 	/* set iface & srate */
+-	wm8971_write(codec, WM8971_IFACE, iface);
++	snd_soc_write(codec, WM8971_IFACE, iface);
+ 	if (coeff >= 0)
+-		wm8971_write(codec, WM8971_SRATE, srate |
++		snd_soc_write(codec, WM8971_SRATE, srate |
+ 			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
+ 
+ 	return 0;
+@@ -564,33 +527,33 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
+ static int wm8971_mute(struct snd_soc_dai *dai, int mute)
+ {
+ 	struct snd_soc_codec *codec = dai->codec;
+-	u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7;
++	u16 mute_reg = snd_soc_read(codec, WM8971_ADCDAC) & 0xfff7;
+ 
+ 	if (mute)
+-		wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
++		snd_soc_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
+ 	else
+-		wm8971_write(codec, WM8971_ADCDAC, mute_reg);
++		snd_soc_write(codec, WM8971_ADCDAC, mute_reg);
+ 	return 0;
+ }
+ 
+ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
+ 	enum snd_soc_bias_level level)
+ {
+-	u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
++	u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
+ 
+ 	switch (level) {
+ 	case SND_SOC_BIAS_ON:
+ 		/* set vmid to 50k and unmute dac */
+-		wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
++		snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
+ 		break;
+ 	case SND_SOC_BIAS_PREPARE:
+ 		break;
+ 	case SND_SOC_BIAS_STANDBY:
+ 		/* mute dac and set vmid to 500k, enable VREF */
+-		wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
++		snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
+ 		break;
+ 	case SND_SOC_BIAS_OFF:
+-		wm8971_write(codec, WM8971_PWR1, 0x0001);
++		snd_soc_write(codec, WM8971_PWR1, 0x0001);
+ 		break;
+ 	}
+ 	codec->bias_level = level;
+@@ -667,8 +630,8 @@ static int wm8971_resume(struct platform_device *pdev)
+ 
+ 	/* charge wm8971 caps */
+ 	if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
+-		reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
+-		wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
++		reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
++		snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
+ 		codec->bias_level = SND_SOC_BIAS_ON;
+ 		queue_delayed_work(wm8971_workq, &codec->delayed_work,
+ 			msecs_to_jiffies(1000));
+@@ -677,15 +640,14 @@ static int wm8971_resume(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static int wm8971_init(struct snd_soc_device *socdev)
++static int wm8971_init(struct snd_soc_device *socdev,
++		       enum snd_soc_control_type control)
+ {
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+ 	int reg, ret = 0;
+ 
+ 	codec->name = "WM8971";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8971_read_reg_cache;
+-	codec->write = wm8971_write;
+ 	codec->set_bias_level = wm8971_set_bias_level;
+ 	codec->dai = &wm8971_dai;
+ 	codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
+@@ -695,42 +657,48 @@ static int wm8971_init(struct snd_soc_device *socdev)
+ 	if (codec->reg_cache == NULL)
+ 		return -ENOMEM;
+ 
++	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
++		goto err;
++	}
++
+ 	wm8971_reset(codec);
+ 
+ 	/* register pcms */
+ 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ 	if (ret < 0) {
+ 		printk(KERN_ERR "wm8971: failed to create pcms\n");
+-		goto pcm_err;
++		goto err;
+ 	}
+ 
+ 	/* charge output caps - set vmid to 5k for quick power up */
+-	reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
+-	wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
++	reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
++	snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
+ 	codec->bias_level = SND_SOC_BIAS_STANDBY;
+ 	queue_delayed_work(wm8971_workq, &codec->delayed_work,
+ 		msecs_to_jiffies(1000));
+ 
+ 	/* set the update bits */
+-	reg = wm8971_read_reg_cache(codec, WM8971_LDAC);
+-	wm8971_write(codec, WM8971_LDAC, reg | 0x0100);
+-	reg = wm8971_read_reg_cache(codec, WM8971_RDAC);
+-	wm8971_write(codec, WM8971_RDAC, reg | 0x0100);
+-
+-	reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V);
+-	wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100);
+-	reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V);
+-	wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100);
+-
+-	reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V);
+-	wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100);
+-	reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V);
+-	wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100);
+-
+-	reg = wm8971_read_reg_cache(codec, WM8971_LINVOL);
+-	wm8971_write(codec, WM8971_LINVOL, reg | 0x0100);
+-	reg = wm8971_read_reg_cache(codec, WM8971_RINVOL);
+-	wm8971_write(codec, WM8971_RINVOL, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8971_LDAC);
++	snd_soc_write(codec, WM8971_LDAC, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8971_RDAC);
++	snd_soc_write(codec, WM8971_RDAC, reg | 0x0100);
++
++	reg = snd_soc_read(codec, WM8971_LOUT1V);
++	snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8971_ROUT1V);
++	snd_soc_write(codec, WM8971_ROUT1V, reg | 0x0100);
++
++	reg = snd_soc_read(codec, WM8971_LOUT2V);
++	snd_soc_write(codec, WM8971_LOUT2V, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8971_ROUT2V);
++	snd_soc_write(codec, WM8971_ROUT2V, reg | 0x0100);
++
++	reg = snd_soc_read(codec, WM8971_LINVOL);
++	snd_soc_write(codec, WM8971_LINVOL, reg | 0x0100);
++	reg = snd_soc_read(codec, WM8971_RINVOL);
++	snd_soc_write(codec, WM8971_RINVOL, reg | 0x0100);
+ 
+ 	snd_soc_add_controls(codec, wm8971_snd_controls,
+ 				ARRAY_SIZE(wm8971_snd_controls));
+@@ -745,7 +713,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
+ card_err:
+ 	snd_soc_free_pcms(socdev);
+ 	snd_soc_dapm_free(socdev);
+-pcm_err:
++err:
+ 	kfree(codec->reg_cache);
+ 	return ret;
+ }
+@@ -767,7 +735,7 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
+ 
+ 	codec->control_data = i2c;
+ 
+-	ret = wm8971_init(socdev);
++	ret = wm8971_init(socdev, SND_SOC_I2C);
+ 	if (ret < 0)
+ 		pr_err("failed to initialise WM8971\n");
+ 
+@@ -877,7 +845,6 @@ static int wm8971_probe(struct platform_device *pdev)
+ 
+ #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ 	if (setup->i2c_address) {
+-		codec->hw_write = (hw_write_t)i2c_master_send;
+ 		ret = wm8971_add_i2c_device(pdev, setup);
+ 	}
+ #endif
+diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
+index 40cd274..f657e9a 100644
+--- a/sound/soc/codecs/wm8990.c
++++ b/sound/soc/codecs/wm8990.c
+@@ -108,53 +108,7 @@ static const u16 wm8990_reg[] = {
+ 	0x0000,	    /* R63 - Driver internal */
+ };
+ 
+-/*
+- * read wm8990 register cache
+- */
+-static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg)
+-{
+-	u16 *cache = codec->reg_cache;
+-	BUG_ON(reg >= ARRAY_SIZE(wm8990_reg));
+-	return cache[reg];
+-}
+-
+-/*
+- * write wm8990 register cache
+- */
+-static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
+-	unsigned int reg, unsigned int value)
+-{
+-	u16 *cache = codec->reg_cache;
+-
+-	/* Reset register and reserved registers are uncached */
+-	if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg))
+-		return;
+-
+-	cache[reg] = value;
+-}
+-
+-/*
+- * write to the wm8990 register space
+- */
+-static int wm8990_write(struct snd_soc_codec *codec, unsigned int reg,
+-	unsigned int value)
+-{
+-	u8 data[3];
+-
+-	data[0] = reg & 0xFF;
+-	data[1] = (value >> 8) & 0xFF;
+-	data[2] = value & 0xFF;
+-
+-	wm8990_write_reg_cache(codec, reg, value);
+-
+-	if (codec->hw_write(codec->control_data, data, 3) == 2)
+-		return 0;
+-	else
+-		return -EIO;
+-}
+-
+-#define wm8990_reset(c) wm8990_write(c, WM8990_RESET, 0)
++#define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0)
+ 
+ static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600);
+ 
+@@ -187,8 +141,8 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
+ 		return ret;
+ 
+ 	/* now hit the volume update bits (always bit 8) */
+-	val = wm8990_read_reg_cache(codec, reg);
+-	return wm8990_write(codec, reg, val | 0x0100);
++	val = snd_soc_read(codec, reg);
++	return snd_soc_write(codec, reg, val | 0x0100);
+ }
+ 
+ #define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
+@@ -427,8 +381,8 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
+ {
+ 	u16 reg, fakepower;
+ 
+-	reg = wm8990_read_reg_cache(w->codec, WM8990_POWER_MANAGEMENT_2);
+-	fakepower = wm8990_read_reg_cache(w->codec, WM8990_INTDRIVBITS);
++	reg = snd_soc_read(w->codec, WM8990_POWER_MANAGEMENT_2);
++	fakepower = snd_soc_read(w->codec, WM8990_INTDRIVBITS);
+ 
+ 	if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) |
+ 		(1 << WM8990_AINLMUX_PWR_BIT))) {
+@@ -443,7 +397,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
+ 	} else {
+ 		reg &= ~WM8990_AINL_ENA;
+ 	}
+-	wm8990_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
++	snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
+ 
+ 	return 0;
+ }
+@@ -457,7 +411,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
+ 
+ 	switch (reg_shift) {
+ 	case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
+-		reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER1);
++		reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER1);
+ 		if (reg & WM8990_LDLO) {
+ 			printk(KERN_WARNING
+ 			"Cannot set as Output Mixer 1 LDLO Set\n");
+@@ -465,7 +419,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
+ 		}
+ 		break;
+ 	case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
+-		reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER2);
++		reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER2);
+ 		if (reg & WM8990_RDRO) {
+ 			printk(KERN_WARNING
+ 			"Cannot set as Output Mixer 2 RDRO Set\n");
+@@ -473,7 +427,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
+ 		}
+ 		break;
+ 	case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
+-		reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER);
++		reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
+ 		if (reg & WM8990_LDSPK) {
+ 			printk(KERN_WARNING
+ 			"Cannot set as Speaker Mixer LDSPK Set\n");
+@@ -481,7 +435,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
+ 		}
+ 		break;
+ 	case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
+-		reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER);
++		reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
+ 		if (reg & WM8990_RDSPK) {
+ 			printk(KERN_WARNING
+ 			"Cannot set as Speaker Mixer RDSPK Set\n");
+@@ -998,7 +952,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 
+ 	if ((Ndiv < 6) || (Ndiv > 12))
+ 		printk(KERN_WARNING
+-		"WM8990 N value outwith recommended range! N = %d\n", Ndiv);
++		"WM8990 N value outwith recommended range! N = %u\n", Ndiv);
+ 
+ 	pll_div->n = Ndiv;
+ 	Nmod = target % source;
+@@ -1018,8 +972,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
+ 	pll_div->k = K;
+ }
+ 
+-static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out)
++static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
+ {
+ 	u16 reg;
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+@@ -1029,24 +983,24 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
+ 		pll_factors(&pll_div, freq_out * 4, freq_in);
+ 
+ 		/* Turn on PLL */
+-		reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2);
++		reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
+ 		reg |= WM8990_PLL_ENA;
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
+ 
+ 		/* sysclk comes from PLL */
+-		reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2);
+-		wm8990_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
++		reg = snd_soc_read(codec, WM8990_CLOCKING_2);
++		snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
+ 
+ 		/* set up N , fractional mode and pre-divisor if neccessary */
+-		wm8990_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
++		snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
+ 			(pll_div.div2?WM8990_PRESCALE:0));
+-		wm8990_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
+-		wm8990_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
++		snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
++		snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
+ 	} else {
+ 		/* Turn on PLL */
+-		reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2);
++		reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
+ 		reg &= ~WM8990_PLL_ENA;
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
+ 	}
+ 	return 0;
+ }
+@@ -1073,8 +1027,8 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	u16 audio1, audio3;
+ 
+-	audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1);
+-	audio3 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_3);
++	audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
++	audio3 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_3);
+ 
+ 	/* set master/slave audio interface */
+ 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+@@ -1115,8 +1069,8 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ 		return -EINVAL;
+ 	}
+ 
+-	wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
+-	wm8990_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
++	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
++	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
+ 	return 0;
+ }
+ 
+@@ -1128,24 +1082,24 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ 
+ 	switch (div_id) {
+ 	case WM8990_MCLK_DIV:
+-		reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) &
++		reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
+ 			~WM8990_MCLK_DIV_MASK;
+-		wm8990_write(codec, WM8990_CLOCKING_2, reg | div);
++		snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
+ 		break;
+ 	case WM8990_DACCLK_DIV:
+-		reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) &
++		reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
+ 			~WM8990_DAC_CLKDIV_MASK;
+-		wm8990_write(codec, WM8990_CLOCKING_2, reg | div);
++		snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
+ 		break;
+ 	case WM8990_ADCCLK_DIV:
+-		reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) &
++		reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
+ 			~WM8990_ADC_CLKDIV_MASK;
+-		wm8990_write(codec, WM8990_CLOCKING_2, reg | div);
++		snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
+ 		break;
+ 	case WM8990_BCLK_DIV:
+-		reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_1) &
++		reg = snd_soc_read(codec, WM8990_CLOCKING_1) &
+ 			~WM8990_BCLK_DIV_MASK;
+-		wm8990_write(codec, WM8990_CLOCKING_1, reg | div);
++		snd_soc_write(codec, WM8990_CLOCKING_1, reg | div);
+ 		break;
+ 	default:
+ 		return -EINVAL;
+@@ -1164,7 +1118,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct snd_soc_device *socdev = rtd->socdev;
+ 	struct snd_soc_codec *codec = socdev->card->codec;
+-	u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1);
++	u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
+ 
+ 	audio1 &= ~WM8990_AIF_WL_MASK;
+ 	/* bit size */
+@@ -1182,7 +1136,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
+ 		break;
+ 	}
+ 
+-	wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
++	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
+ 	return 0;
+ }
+ 
+@@ -1191,12 +1145,12 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute)
+ 	struct snd_soc_codec *codec = dai->codec;
+ 	u16 val;
+ 
+-	val  = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
++	val  = snd_soc_read(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
+ 
+ 	if (mute)
+-		wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
++		snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
+ 	else
+-		wm8990_write(codec, WM8990_DAC_CTRL, val);
++		snd_soc_write(codec, WM8990_DAC_CTRL, val);
+ 
+ 	return 0;
+ }
+@@ -1212,21 +1166,21 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
+ 
+ 	case SND_SOC_BIAS_PREPARE:
+ 		/* VMID=2*50k */
+-		val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
++		val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) &
+ 			~WM8990_VMID_MODE_MASK;
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_STANDBY:
+ 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ 			/* Enable all output discharge bits */
+-			wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
++			snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
+ 				WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
+ 				WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
+ 				WM8990_DIS_ROUT);
+ 
+ 			/* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
+-			wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
++			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+ 				     WM8990_BUFDCOPEN | WM8990_POBCTRL |
+ 				     WM8990_VMIDTOG);
+ 
+@@ -1234,83 +1188,83 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
+ 			msleep(msecs_to_jiffies(300));
+ 
+ 			/* Disable VMIDTOG */
+-			wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
++			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+ 				     WM8990_BUFDCOPEN | WM8990_POBCTRL);
+ 
+ 			/* disable all output discharge bits */
+-			wm8990_write(codec, WM8990_ANTIPOP1, 0);
++			snd_soc_write(codec, WM8990_ANTIPOP1, 0);
+ 
+ 			/* Enable outputs */
+-			wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
++			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
+ 
+ 			msleep(msecs_to_jiffies(50));
+ 
+ 			/* Enable VMID at 2x50k */
+-			wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
++			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
+ 
+ 			msleep(msecs_to_jiffies(100));
+ 
+ 			/* Enable VREF */
+-			wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
++			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
+ 
+ 			msleep(msecs_to_jiffies(600));
+ 
+ 			/* Enable BUFIOEN */
+-			wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
++			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+ 				     WM8990_BUFDCOPEN | WM8990_POBCTRL |
+ 				     WM8990_BUFIOEN);
+ 
+ 			/* Disable outputs */
+-			wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
++			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
+ 
+ 			/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
+-			wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
++			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
+ 
+ 			/* Enable workaround for ADC clocking issue. */
+-			wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
+-			wm8990_write(codec, WM8990_EXT_CTL1, 0xa003);
+-			wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0);
++			snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
++			snd_soc_write(codec, WM8990_EXT_CTL1, 0xa003);
++			snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0);
+ 		}
+ 
+ 		/* VMID=2*250k */
+-		val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
++		val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) &
+ 			~WM8990_VMID_MODE_MASK;
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
+ 		break;
+ 
+ 	case SND_SOC_BIAS_OFF:
+ 		/* Enable POBCTRL and SOFT_ST */
+-		wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
++		snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+ 			WM8990_POBCTRL | WM8990_BUFIOEN);
+ 
+ 		/* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
+-		wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
++		snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+ 			WM8990_BUFDCOPEN | WM8990_POBCTRL |
+ 			WM8990_BUFIOEN);
+ 
+ 		/* mute DAC */
+-		val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL);
+-		wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
++		val = snd_soc_read(codec, WM8990_DAC_CTRL);
++		snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
+ 
+ 		/* Enable any disabled outputs */
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
+ 
+ 		/* Disable VMID */
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
+ 
+ 		msleep(msecs_to_jiffies(300));
+ 
+ 		/* Enable all output discharge bits */
+-		wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
++		snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
+ 			WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
+ 			WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
+ 			WM8990_DIS_ROUT);
+ 
+ 		/* Disable VREF */
+-		wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
++		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
+ 
+ 		/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
+-		wm8990_write(codec, WM8990_ANTIPOP2, 0x0);
++		snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
+ 		break;
+ 	}
+ 
+@@ -1411,8 +1365,6 @@ static int wm8990_init(struct snd_soc_device *socdev)
+ 
+ 	codec->name = "WM8990";
+ 	codec->owner = THIS_MODULE;
+-	codec->read = wm8990_read_reg_cache;
+-	codec->write = wm8990_write;
+ 	codec->set_bias_level = wm8990_set_bias_level;
+ 	codec->dai = &wm8990_dai;
+ 	codec->num_dai = 2;
+@@ -1422,6 +1374,12 @@ static int wm8990_init(struct snd_soc_device *socdev)
+ 	if (codec->reg_cache == NULL)
+ 		return -ENOMEM;
+ 
++	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
++		goto pcm_err;
++	}
++
+ 	wm8990_reset(codec);
+ 
+ 	/* register pcms */
+@@ -1435,18 +1393,18 @@ static int wm8990_init(struct snd_soc_device *socdev)
+ 	codec->bias_level = SND_SOC_BIAS_OFF;
+ 	wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ 
+-	reg = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_4);
+-	wm8990_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1);
++	reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4);
++	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1);
+ 
+-	reg = wm8990_read_reg_cache(codec, WM8990_GPIO1_GPIO2) &
++	reg = snd_soc_read(codec, WM8990_GPIO1_GPIO2) &
+ 		~WM8990_GPIO1_SEL_MASK;
+-	wm8990_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
++	snd_soc_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
+ 
+-	reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2);
+-	wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA);
++	reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
++	snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA);
+ 
+-	wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
+-	wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
++	snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
++	snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
+ 
+ 	snd_soc_add_controls(codec, wm8990_snd_controls,
+ 				ARRAY_SIZE(wm8990_snd_controls));
+diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
+index c2d1a7a..e7d2840 100644
+--- a/sound/soc/codecs/wm9705.c
++++ b/sound/soc/codecs/wm9705.c
+@@ -282,14 +282,14 @@ struct snd_soc_dai wm9705_dai[] = {
+ 			.channels_min = 1,
+ 			.channels_max = 2,
+ 			.rates = WM9705_AC97_RATES,
+-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
++			.formats = SND_SOC_STD_AC97_FMTS,
+ 		},
+ 		.capture = {
+ 			.stream_name = "HiFi Capture",
+ 			.channels_min = 1,
+ 			.channels_max = 2,
+ 			.rates = WM9705_AC97_RATES,
+-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
++			.formats = SND_SOC_STD_AC97_FMTS,
+ 		},
+ 		.ops = &wm9705_dai_ops,
+ 	},
+@@ -406,7 +406,7 @@ static int wm9705_soc_probe(struct platform_device *pdev)
+ 	ret = snd_soc_init_card(socdev);
+ 	if (ret < 0) {
+ 		printk(KERN_ERR "wm9705: failed to register card\n");
+-		goto pcm_err;
++		goto reset_err;
+ 	}
+ 
+ 	return 0;
+diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
+index 765cf1e..1fd4e88 100644
+--- a/sound/soc/codecs/wm9712.c
++++ b/sound/soc/codecs/wm9712.c
+@@ -534,13 +534,13 @@ struct snd_soc_dai wm9712_dai[] = {
+ 		.channels_min = 1,
+ 		.channels_max = 2,
+ 		.rates = WM9712_AC97_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.capture = {
+ 		.stream_name = "HiFi Capture",
+ 		.channels_min = 1,
+ 		.channels_max = 2,
+ 		.rates = WM9712_AC97_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.ops = &wm9712_dai_ops_hifi,
+ },
+ {
+@@ -550,7 +550,7 @@ struct snd_soc_dai wm9712_dai[] = {
+ 		.channels_min = 1,
+ 		.channels_max = 1,
+ 		.rates = WM9712_AC97_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.ops = &wm9712_dai_ops_aux,
+ }
+ };
+@@ -585,6 +585,8 @@ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
+ 	}
+ 
+ 	soc_ac97_ops.reset(codec->ac97);
++	if (soc_ac97_ops.warm_reset)
++		soc_ac97_ops.warm_reset(codec->ac97);
+ 	if (ac97_read(codec, 0) != wm9712_reg[0])
+ 		goto err;
+ 	return 0;
+diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
+index 523bad0..ca3d449 100644
+--- a/sound/soc/codecs/wm9713.c
++++ b/sound/soc/codecs/wm9713.c
+@@ -189,6 +189,26 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
+ SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
+ };
+ 
++static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
++				 struct snd_kcontrol *kcontrol, int event)
++{
++	struct snd_soc_codec *codec = w->codec;
++	u16 status, rate;
++
++	BUG_ON(event != SND_SOC_DAPM_PRE_PMD);
++
++	/* Gracefully shut down the voice interface. */
++	status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000;
++	rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
++	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
++	schedule_timeout_interruptible(msecs_to_jiffies(1));
++	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
++	ac97_write(codec, AC97_EXTENDED_MID, status);
++
++	return 0;
++}
++
++
+ /* We have to create a fake left and right HP mixers because
+  * the codec only has a single control that is shared by both channels.
+  * This makes it impossible to determine the audio path using the current
+@@ -400,7 +420,8 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+-SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
++SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1,
++		   wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
+ SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
+@@ -689,7 +710,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source)
+ 	Ndiv = target / source;
+ 	if ((Ndiv < 5) || (Ndiv > 12))
+ 		printk(KERN_WARNING
+-			"WM9713 PLL N value %d out of recommended range!\n",
++			"WM9713 PLL N value %u out of recommended range!\n",
+ 			Ndiv);
+ 
+ 	pll_div->n = Ndiv;
+@@ -779,8 +800,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
+ 	return 0;
+ }
+ 
+-static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai,
+-		int pll_id, unsigned int freq_in, unsigned int freq_out)
++static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
++		int source, unsigned int freq_in, unsigned int freq_out)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
+@@ -936,21 +957,6 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	return 0;
+ }
+ 
+-static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
+-				 struct snd_soc_dai *dai)
+-{
+-	struct snd_soc_codec *codec = dai->codec;
+-	u16 status, rate;
+-
+-	/* Gracefully shut down the voice interface. */
+-	status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
+-	rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
+-	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
+-	schedule_timeout_interruptible(msecs_to_jiffies(1));
+-	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
+-	ac97_write(codec, AC97_EXTENDED_MID, status);
+-}
+-
+ static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
+ 			     struct snd_soc_dai *dai)
+ {
+@@ -1019,7 +1025,6 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
+ 
+ static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
+ 	.hw_params	= wm9713_pcm_hw_params,
+-	.shutdown	= wm9713_voiceshutdown,
+ 	.set_clkdiv	= wm9713_set_dai_clkdiv,
+ 	.set_pll	= wm9713_set_dai_pll,
+ 	.set_fmt	= wm9713_set_dai_fmt,
+@@ -1035,13 +1040,13 @@ struct snd_soc_dai wm9713_dai[] = {
+ 		.channels_min = 1,
+ 		.channels_max = 2,
+ 		.rates = WM9713_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.capture = {
+ 		.stream_name = "HiFi Capture",
+ 		.channels_min = 1,
+ 		.channels_max = 2,
+ 		.rates = WM9713_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.ops = &wm9713_dai_ops_hifi,
+ 	},
+ 	{
+@@ -1051,7 +1056,7 @@ struct snd_soc_dai wm9713_dai[] = {
+ 		.channels_min = 1,
+ 		.channels_max = 1,
+ 		.rates = WM9713_RATES,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++		.formats = SND_SOC_STD_AC97_FMTS,},
+ 	.ops = &wm9713_dai_ops_aux,
+ 	},
+ 	{
+@@ -1069,6 +1074,7 @@ struct snd_soc_dai wm9713_dai[] = {
+ 		.rates = WM9713_PCM_RATES,
+ 		.formats = WM9713_PCM_FORMATS,},
+ 	.ops = &wm9713_dai_ops_voice,
++	.symmetric_rates = 1,
+ 	},
+ };
+ EXPORT_SYMBOL_GPL(wm9713_dai);
+diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
+new file mode 100644
+index 0000000..d2505e8
+--- /dev/null
++++ b/sound/soc/soc-cache.c
+@@ -0,0 +1,258 @@
++/*
++ * soc-cache.c  --  ASoC register cache helpers
++ *
++ * Copyright 2009 Wolfson Microelectronics PLC.
++ *
++ * Author: Mark Brown <broonie at opensource.wolfsonmicro.com>
++ *
++ *  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/i2c.h>
++#include <linux/spi/spi.h>
++#include <sound/soc.h>
++
++static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
++				     unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg >= codec->reg_cache_size)
++		return -1;
++	return cache[reg];
++}
++
++static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
++			     unsigned int value)
++{
++	u16 *cache = codec->reg_cache;
++	u8 data[2];
++	int ret;
++
++	BUG_ON(codec->volatile_register);
++
++	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
++	data[1] = value & 0x00ff;
++
++	if (reg < codec->reg_cache_size)
++		cache[reg] = value;
++	ret = codec->hw_write(codec->control_data, data, 2);
++	if (ret == 2)
++		return 0;
++	if (ret < 0)
++		return ret;
++	else
++		return -EIO;
++}
++
++#if defined(CONFIG_SPI_MASTER)
++static int snd_soc_7_9_spi_write(void *control_data, const char *data,
++				 int len)
++{
++	struct spi_device *spi = control_data;
++	struct spi_transfer t;
++	struct spi_message m;
++	u8 msg[2];
++
++	if (len <= 0)
++		return 0;
++
++	msg[0] = data[0];
++	msg[1] = data[1];
++
++	spi_message_init(&m);
++	memset(&t, 0, (sizeof t));
++
++	t.tx_buf = &msg[0];
++	t.len = len;
++
++	spi_message_add_tail(&t, &m);
++	spi_sync(spi, &m);
++
++	return len;
++}
++#else
++#define snd_soc_7_9_spi_write NULL
++#endif
++
++static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
++			     unsigned int value)
++{
++	u8 *cache = codec->reg_cache;
++	u8 data[2];
++
++	BUG_ON(codec->volatile_register);
++
++	data[0] = reg & 0xff;
++	data[1] = value & 0xff;
++
++	if (reg < codec->reg_cache_size)
++		cache[reg] = value;
++
++	if (codec->hw_write(codec->control_data, data, 2) == 2)
++		return 0;
++	else
++		return -EIO;
++}
++
++static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
++				     unsigned int reg)
++{
++	u8 *cache = codec->reg_cache;
++	if (reg >= codec->reg_cache_size)
++		return -1;
++	return cache[reg];
++}
++
++static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
++			      unsigned int value)
++{
++	u16 *reg_cache = codec->reg_cache;
++	u8 data[3];
++
++	data[0] = reg;
++	data[1] = (value >> 8) & 0xff;
++	data[2] = value & 0xff;
++
++	if (!snd_soc_codec_volatile_register(codec, reg))
++		reg_cache[reg] = value;
++
++	if (codec->hw_write(codec->control_data, data, 3) == 3)
++		return 0;
++	else
++		return -EIO;
++}
++
++static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
++				      unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++
++	if (reg >= codec->reg_cache_size ||
++	    snd_soc_codec_volatile_register(codec, reg))
++		return codec->hw_read(codec, reg);
++	else
++		return cache[reg];
++}
++
++#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
++static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
++					  unsigned int r)
++{
++	struct i2c_msg xfer[2];
++	u8 reg = r;
++	u16 data;
++	int ret;
++	struct i2c_client *client = codec->control_data;
++
++	/* Write register */
++	xfer[0].addr = client->addr;
++	xfer[0].flags = 0;
++	xfer[0].len = 1;
++	xfer[0].buf = &reg;
++
++	/* Read data */
++	xfer[1].addr = client->addr;
++	xfer[1].flags = I2C_M_RD;
++	xfer[1].len = 2;
++	xfer[1].buf = (u8 *)&data;
++
++	ret = i2c_transfer(client->adapter, xfer, 2);
++	if (ret != 2) {
++		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
++		return 0;
++	}
++
++	return (data >> 8) | ((data & 0xff) << 8);
++}
++#else
++#define snd_soc_8_16_read_i2c NULL
++#endif
++
++static struct {
++	int addr_bits;
++	int data_bits;
++	int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
++	int (*spi_write)(void *, const char *, int);
++	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
++	unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
++} io_types[] = {
++	{
++		.addr_bits = 7, .data_bits = 9,
++		.write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
++		.spi_write = snd_soc_7_9_spi_write 
++	},
++	{
++		.addr_bits = 8, .data_bits = 8,
++		.write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
++	},
++	{
++		.addr_bits = 8, .data_bits = 16,
++		.write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
++		.i2c_read = snd_soc_8_16_read_i2c,
++	},
++};
++
++/**
++ * snd_soc_codec_set_cache_io: Set up standard I/O functions.
++ *
++ * @codec: CODEC to configure.
++ * @type: Type of cache.
++ * @addr_bits: Number of bits of register address data.
++ * @data_bits: Number of bits of data per register.
++ * @control: Control bus used.
++ *
++ * Register formats are frequently shared between many I2C and SPI
++ * devices.  In order to promote code reuse the ASoC core provides
++ * some standard implementations of CODEC read and write operations
++ * which can be set up using this function.
++ *
++ * The caller is responsible for allocating and initialising the
++ * actual cache.
++ *
++ * Note that at present this code cannot be used by CODECs with
++ * volatile registers.
++ */
++int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
++			       int addr_bits, int data_bits,
++			       enum snd_soc_control_type control)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(io_types); i++)
++		if (io_types[i].addr_bits == addr_bits &&
++		    io_types[i].data_bits == data_bits)
++			break;
++	if (i == ARRAY_SIZE(io_types)) {
++		printk(KERN_ERR
++		       "No I/O functions for %d bit address %d bit data\n",
++		       addr_bits, data_bits);
++		return -EINVAL;
++	}
++
++	codec->write = io_types[i].write;
++	codec->read = io_types[i].read;
++
++	switch (control) {
++	case SND_SOC_CUSTOM:
++		break;
++
++	case SND_SOC_I2C:
++#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
++		codec->hw_write = (hw_write_t)i2c_master_send;
++#endif
++		if (io_types[i].i2c_read)
++			codec->hw_read = io_types[i].i2c_read;
++		break;
++
++	case SND_SOC_SPI:
++		if (io_types[i].spi_write)
++			codec->hw_write = io_types[i].spi_write;
++		break;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index 1cd149b..1dec9d2 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -28,6 +28,7 @@
+ #include <linux/bitops.h>
+ #include <linux/debugfs.h>
+ #include <linux/platform_device.h>
++#include <sound/ac97_codec.h>
+ #include <sound/core.h>
+ #include <sound/pcm.h>
+ #include <sound/pcm_params.h>
+@@ -113,6 +114,35 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
+ }
+ #endif
+ 
++static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_card *card = socdev->card;
++	struct snd_soc_dai_link *machine = rtd->dai;
++	struct snd_soc_dai *cpu_dai = machine->cpu_dai;
++	struct snd_soc_dai *codec_dai = machine->codec_dai;
++	int ret;
++
++	if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates ||
++	    machine->symmetric_rates) {
++		dev_dbg(card->dev, "Symmetry forces %dHz rate\n", 
++			machine->rate);
++
++		ret = snd_pcm_hw_constraint_minmax(substream->runtime,
++						   SNDRV_PCM_HW_PARAM_RATE,
++						   machine->rate,
++						   machine->rate);
++		if (ret < 0) {
++			dev_err(card->dev,
++				"Unable to apply rate symmetry constraint: %d\n", ret);
++			return ret;
++		}
++	}
++
++	return 0;
++}
++
+ /*
+  * Called by ALSA when a PCM substream is opened, the runtime->hw record is
+  * then initialized and any private data can be allocated. This also calls
+@@ -221,6 +251,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
+ 		goto machine_err;
+ 	}
+ 
++	/* Symmetry only applies if we've already got an active stream. */
++	if (cpu_dai->active || codec_dai->active) {
++		ret = soc_pcm_apply_symmetry(substream);
++		if (ret != 0)
++			goto machine_err;
++	}
++
+ 	pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
+ 	pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
+ 	pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
+@@ -263,7 +300,6 @@ static void close_delayed_work(struct work_struct *work)
+ {
+ 	struct snd_soc_card *card = container_of(work, struct snd_soc_card,
+ 						 delayed_work.work);
+-	struct snd_soc_device *socdev = card->socdev;
+ 	struct snd_soc_codec *codec = card->codec;
+ 	struct snd_soc_dai *codec_dai;
+ 	int i;
+@@ -279,27 +315,10 @@ static void close_delayed_work(struct work_struct *work)
+ 
+ 		/* are we waiting on this codec DAI stream */
+ 		if (codec_dai->pop_wait == 1) {
+-
+-			/* Reduce power if no longer active */
+-			if (codec->active == 0) {
+-				pr_debug("pop wq D1 %s %s\n", codec->name,
+-					 codec_dai->playback.stream_name);
+-				snd_soc_dapm_set_bias_level(socdev,
+-					SND_SOC_BIAS_PREPARE);
+-			}
+-
+ 			codec_dai->pop_wait = 0;
+ 			snd_soc_dapm_stream_event(codec,
+ 				codec_dai->playback.stream_name,
+ 				SND_SOC_DAPM_STREAM_STOP);
+-
+-			/* Fall into standby if no longer active */
+-			if (codec->active == 0) {
+-				pr_debug("pop wq D3 %s %s\n", codec->name,
+-					 codec_dai->playback.stream_name);
+-				snd_soc_dapm_set_bias_level(socdev,
+-					SND_SOC_BIAS_STANDBY);
+-			}
+ 		}
+ 	}
+ 	mutex_unlock(&pcm_mutex);
+@@ -363,10 +382,6 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
+ 		snd_soc_dapm_stream_event(codec,
+ 			codec_dai->capture.stream_name,
+ 			SND_SOC_DAPM_STREAM_STOP);
+-
+-		if (codec->active == 0 && codec_dai->pop_wait == 0)
+-			snd_soc_dapm_set_bias_level(socdev,
+-						SND_SOC_BIAS_STANDBY);
+ 	}
+ 
+ 	mutex_unlock(&pcm_mutex);
+@@ -431,36 +446,16 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
+ 		cancel_delayed_work(&card->delayed_work);
+ 	}
+ 
+-	/* do we need to power up codec */
+-	if (codec->bias_level != SND_SOC_BIAS_ON) {
+-		snd_soc_dapm_set_bias_level(socdev,
+-					    SND_SOC_BIAS_PREPARE);
+-
+-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-			snd_soc_dapm_stream_event(codec,
+-					codec_dai->playback.stream_name,
+-					SND_SOC_DAPM_STREAM_START);
+-		else
+-			snd_soc_dapm_stream_event(codec,
+-					codec_dai->capture.stream_name,
+-					SND_SOC_DAPM_STREAM_START);
+-
+-		snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
+-		snd_soc_dai_digital_mute(codec_dai, 0);
+-
+-	} else {
+-		/* codec already powered - power on widgets */
+-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-			snd_soc_dapm_stream_event(codec,
+-					codec_dai->playback.stream_name,
+-					SND_SOC_DAPM_STREAM_START);
+-		else
+-			snd_soc_dapm_stream_event(codec,
+-					codec_dai->capture.stream_name,
+-					SND_SOC_DAPM_STREAM_START);
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++		snd_soc_dapm_stream_event(codec,
++					  codec_dai->playback.stream_name,
++					  SND_SOC_DAPM_STREAM_START);
++	else
++		snd_soc_dapm_stream_event(codec,
++					  codec_dai->capture.stream_name,
++					  SND_SOC_DAPM_STREAM_START);
+ 
+-		snd_soc_dai_digital_mute(codec_dai, 0);
+-	}
++	snd_soc_dai_digital_mute(codec_dai, 0);
+ 
+ out:
+ 	mutex_unlock(&pcm_mutex);
+@@ -521,6 +516,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
+ 		}
+ 	}
+ 
++	machine->rate = params_rate(params);
++
+ out:
+ 	mutex_unlock(&pcm_mutex);
+ 	return ret;
+@@ -623,8 +620,9 @@ static struct snd_pcm_ops soc_pcm_ops = {
+ 
+ #ifdef CONFIG_PM
+ /* powers down audio subsystem for suspend */
+-static int soc_suspend(struct platform_device *pdev, pm_message_t state)
++static int soc_suspend(struct device *dev)
+ {
++	struct platform_device *pdev = to_platform_device(dev);
+ 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ 	struct snd_soc_card *card = socdev->card;
+ 	struct snd_soc_platform *platform = card->platform;
+@@ -632,6 +630,12 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
+ 	struct snd_soc_codec *codec = card->codec;
+ 	int i;
+ 
++	/* If the initialization of this soc device failed, there is no codec
++	 * associated with it. Just bail out in this case.
++	 */
++	if (!codec)
++		return 0;
++
+ 	/* Due to the resume being scheduled into a workqueue we could
+ 	* suspend before that's finished - wait for it to complete.
+ 	 */
+@@ -654,7 +658,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
+ 		snd_pcm_suspend_all(card->dai_link[i].pcm);
+ 
+ 	if (card->suspend_pre)
+-		card->suspend_pre(pdev, state);
++		card->suspend_pre(pdev, PMSG_SUSPEND);
+ 
+ 	for (i = 0; i < card->num_links; i++) {
+ 		struct snd_soc_dai  *cpu_dai = card->dai_link[i].cpu_dai;
+@@ -680,7 +684,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
+ 	}
+ 
+ 	if (codec_dev->suspend)
+-		codec_dev->suspend(pdev, state);
++		codec_dev->suspend(pdev, PMSG_SUSPEND);
+ 
+ 	for (i = 0; i < card->num_links; i++) {
+ 		struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
+@@ -689,7 +693,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
+ 	}
+ 
+ 	if (card->suspend_post)
+-		card->suspend_post(pdev, state);
++		card->suspend_post(pdev, PMSG_SUSPEND);
+ 
+ 	return 0;
+ }
+@@ -763,8 +767,9 @@ static void soc_resume_deferred(struct work_struct *work)
+ }
+ 
+ /* powers up audio subsystem after a suspend */
+-static int soc_resume(struct platform_device *pdev)
++static int soc_resume(struct device *dev)
+ {
++	struct platform_device *pdev = to_platform_device(dev);
+ 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ 	struct snd_soc_card *card = socdev->card;
+ 	struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
+@@ -786,6 +791,44 @@ static int soc_resume(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++/**
++ * snd_soc_suspend_device: Notify core of device suspend
++ *
++ * @dev: Device being suspended.
++ *
++ * In order to ensure that the entire audio subsystem is suspended in a
++ * coordinated fashion ASoC devices should suspend themselves when
++ * called by ASoC.  When the standard kernel suspend process asks the
++ * device to suspend it should call this function to initiate a suspend
++ * of the entire ASoC card.
++ *
++ * \note Currently this function is stubbed out.
++ */
++int snd_soc_suspend_device(struct device *dev)
++{
++	return 0;
++}
++EXPORT_SYMBOL_GPL(snd_soc_suspend_device);
++
++/**
++ * snd_soc_resume_device: Notify core of device resume
++ *
++ * @dev: Device being resumed.
++ *
++ * In order to ensure that the entire audio subsystem is resumed in a
++ * coordinated fashion ASoC devices should resume themselves when called
++ * by ASoC.  When the standard kernel resume process asks the device
++ * to resume it should call this function.  Once all the components of
++ * the card have notified that they are ready to be resumed the card
++ * will be resumed.
++ *
++ * \note Currently this function is stubbed out.
++ */
++int snd_soc_resume_device(struct device *dev)
++{
++	return 0;
++}
++EXPORT_SYMBOL_GPL(snd_soc_resume_device);
+ #else
+ #define soc_suspend	NULL
+ #define soc_resume	NULL
+@@ -979,16 +1022,39 @@ static int soc_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++static int soc_poweroff(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_card *card = socdev->card;
++
++	if (!card->instantiated)
++		return 0;
++
++	/* Flush out pmdown_time work - we actually do want to run it
++	 * now, we're shutting down so no imminent restart. */
++	run_delayed_work(&card->delayed_work);
++
++	snd_soc_dapm_shutdown(socdev);
++
++	return 0;
++}
++
++static struct dev_pm_ops soc_pm_ops = {
++	.suspend = soc_suspend,
++	.resume = soc_resume,
++	.poweroff = soc_poweroff,
++};
++
+ /* ASoC platform driver */
+ static struct platform_driver soc_driver = {
+ 	.driver		= {
+ 		.name		= "soc-audio",
+ 		.owner		= THIS_MODULE,
++		.pm		= &soc_pm_ops,
+ 	},
+ 	.probe		= soc_probe,
+ 	.remove		= soc_remove,
+-	.suspend	= soc_suspend,
+-	.resume		= soc_resume,
+ };
+ 
+ /* create a new pcm */
+@@ -1060,6 +1126,23 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
+ 	return ret;
+ }
+ 
++/**
++ * snd_soc_codec_volatile_register: Report if a register is volatile.
++ *
++ * @codec: CODEC to query.
++ * @reg: Register to query.
++ *
++ * Boolean function indiciating if a CODEC register is volatile.
++ */
++int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
++{
++	if (codec->volatile_register)
++		return codec->volatile_register(reg);
++	else
++		return 0;
++}
++EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
++
+ /* codec register dump */
+ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
+ {
+@@ -1073,6 +1156,9 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
+ 
+ 	count += sprintf(buf, "%s registers\n", codec->name);
+ 	for (i = 0; i < codec->reg_cache_size; i += step) {
++		if (codec->readable_register && !codec->readable_register(i))
++			continue;
++
+ 		count += sprintf(buf + count, "%2x: ", i);
+ 		if (count >= PAGE_SIZE - 1)
+ 			break;
+@@ -1168,25 +1254,49 @@ static const struct file_operations codec_reg_fops = {
+ 
+ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
+ {
++	char codec_root[128];
++
++	if (codec->dev)
++		snprintf(codec_root, sizeof(codec_root),
++			"%s.%s", codec->name, dev_name(codec->dev));
++	else
++		snprintf(codec_root, sizeof(codec_root),
++			"%s", codec->name);
++
++	codec->debugfs_codec_root = debugfs_create_dir(codec_root,
++						       debugfs_root);
++	if (!codec->debugfs_codec_root) {
++		printk(KERN_WARNING
++		       "ASoC: Failed to create codec debugfs directory\n");
++		return;
++	}
++
+ 	codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
+-						 debugfs_root, codec,
+-						 &codec_reg_fops);
++						 codec->debugfs_codec_root,
++						 codec, &codec_reg_fops);
+ 	if (!codec->debugfs_reg)
+ 		printk(KERN_WARNING
+ 		       "ASoC: Failed to create codec register debugfs file\n");
+ 
+ 	codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
+-						     debugfs_root,
++						     codec->debugfs_codec_root,
+ 						     &codec->pop_time);
+ 	if (!codec->debugfs_pop_time)
+ 		printk(KERN_WARNING
+ 		       "Failed to create pop time debugfs file\n");
++
++	codec->debugfs_dapm = debugfs_create_dir("dapm",
++						 codec->debugfs_codec_root);
++	if (!codec->debugfs_dapm)
++		printk(KERN_WARNING
++		       "Failed to create DAPM debugfs directory\n");
++
++	snd_soc_dapm_debugfs_init(codec);
+ }
+ 
+ static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
+ {
+-	debugfs_remove(codec->debugfs_pop_time);
+-	debugfs_remove(codec->debugfs_reg);
++	debugfs_remove_recursive(codec->debugfs_codec_root);
+ }
+ 
+ #else
+@@ -1262,10 +1372,10 @@ EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
+  * Returns 1 for change else 0.
+  */
+ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
+-				unsigned short mask, unsigned short value)
++				unsigned int mask, unsigned int value)
+ {
+ 	int change;
+-	unsigned short old, new;
++	unsigned int old, new;
+ 
+ 	mutex_lock(&io_mutex);
+ 	old = snd_soc_read(codec, reg);
+@@ -1292,10 +1402,10 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits);
+  * Returns 1 for change else 0.
+  */
+ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
+-				unsigned short mask, unsigned short value)
++				unsigned int mask, unsigned int value)
+ {
+ 	int change;
+-	unsigned short old, new;
++	unsigned int old, new;
+ 
+ 	mutex_lock(&io_mutex);
+ 	old = snd_soc_read(codec, reg);
+@@ -1334,6 +1444,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
+ 		return ret;
+ 	}
+ 
++	codec->socdev = socdev;
+ 	codec->card->dev = socdev->dev;
+ 	codec->card->private_data = codec;
+ 	strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
+@@ -1378,14 +1489,20 @@ int snd_soc_init_card(struct snd_soc_device *socdev)
+ 				continue;
+ 			}
+ 		}
+-		if (card->dai_link[i].codec_dai->ac97_control)
++		if (card->dai_link[i].codec_dai->ac97_control) {
+ 			ac97 = 1;
++			snd_ac97_dev_add_pdata(codec->ac97,
++				card->dai_link[i].cpu_dai->ac97_pdata);
++		}
+ 	}
+ 	snprintf(codec->card->shortname, sizeof(codec->card->shortname),
+ 		 "%s",  card->name);
+ 	snprintf(codec->card->longname, sizeof(codec->card->longname),
+ 		 "%s (%s)", card->name, codec->name);
+ 
++	/* Make sure all DAPM widgets are instantiated */
++	snd_soc_dapm_new_widgets(codec);
++
+ 	ret = snd_card_register(codec->card);
+ 	if (ret < 0) {
+ 		printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
+@@ -1580,7 +1697,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
+ {
+ 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+-	unsigned short val, bitmask;
++	unsigned int val, bitmask;
+ 
+ 	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
+ 		;
+@@ -1609,8 +1726,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
+ {
+ 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+-	unsigned short val;
+-	unsigned short mask, bitmask;
++	unsigned int val;
++	unsigned int mask, bitmask;
+ 
+ 	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
+ 		;
+@@ -1646,7 +1763,7 @@ int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
+ {
+ 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+-	unsigned short reg_val, val, mux;
++	unsigned int reg_val, val, mux;
+ 
+ 	reg_val = snd_soc_read(codec, e->reg);
+ 	val = (reg_val >> e->shift_l) & e->mask;
+@@ -1685,8 +1802,8 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
+ {
+ 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+-	unsigned short val;
+-	unsigned short mask;
++	unsigned int val;
++	unsigned int mask;
+ 
+ 	if (ucontrol->value.enumerated.item[0] > e->max - 1)
+ 		return -EINVAL;
+@@ -1744,7 +1861,7 @@ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
+ {
+ 	int max = kcontrol->private_value;
+ 
+-	if (max == 1)
++	if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ 	else
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+@@ -1774,7 +1891,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
+ 	unsigned int shift = mc->shift;
+ 	unsigned int rshift = mc->rshift;
+ 
+-	if (max == 1)
++	if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ 	else
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+@@ -1846,7 +1963,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
+ 	int max = mc->max;
+ 	unsigned int mask = (1 << fls(max)) - 1;
+ 	unsigned int invert = mc->invert;
+-	unsigned short val, val2, val_mask;
++	unsigned int val, val2, val_mask;
+ 
+ 	val = (ucontrol->value.integer.value[0] & mask);
+ 	if (invert)
+@@ -1881,7 +1998,7 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
+ 		(struct soc_mixer_control *)kcontrol->private_value;
+ 	int max = mc->max;
+ 
+-	if (max == 1)
++	if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ 	else
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+@@ -1912,7 +2029,7 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
+ 	unsigned int reg2 = mc->rreg;
+ 	unsigned int shift = mc->shift;
+ 	int max = mc->max;
+-	unsigned int mask = (1<<fls(max))-1;
++	unsigned int mask = (1 << fls(max)) - 1;
+ 	unsigned int invert = mc->invert;
+ 
+ 	ucontrol->value.integer.value[0] =
+@@ -1952,7 +2069,7 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
+ 	unsigned int mask = (1 << fls(max)) - 1;
+ 	unsigned int invert = mc->invert;
+ 	int err;
+-	unsigned short val, val2, val_mask;
++	unsigned int val, val2, val_mask;
+ 
+ 	val_mask = mask << shift;
+ 	val = (ucontrol->value.integer.value[0] & mask);
+@@ -2044,7 +2161,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
+ 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ 	unsigned int reg = mc->reg;
+ 	int min = mc->min;
+-	unsigned short val;
++	unsigned int val;
+ 
+ 	val = (ucontrol->value.integer.value[0]+min) & 0xff;
+ 	val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
+@@ -2065,7 +2182,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
+ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+ 	unsigned int freq, int dir)
+ {
+-	if (dai->ops->set_sysclk)
++	if (dai->ops && dai->ops->set_sysclk)
+ 		return dai->ops->set_sysclk(dai, clk_id, freq, dir);
+ 	else
+ 		return -EINVAL;
+@@ -2085,7 +2202,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
+ int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
+ 	int div_id, int div)
+ {
+-	if (dai->ops->set_clkdiv)
++	if (dai->ops && dai->ops->set_clkdiv)
+ 		return dai->ops->set_clkdiv(dai, div_id, div);
+ 	else
+ 		return -EINVAL;
+@@ -2096,16 +2213,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
+  * snd_soc_dai_set_pll - configure DAI PLL.
+  * @dai: DAI
+  * @pll_id: DAI specific PLL ID
++ * @source: DAI specific source for the PLL
+  * @freq_in: PLL input clock frequency in Hz
+  * @freq_out: requested PLL output clock frequency in Hz
+  *
+  * Configures and enables PLL to generate output clock based on input clock.
+  */
+-int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
+-	int pll_id, unsigned int freq_in, unsigned int freq_out)
++int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
++	unsigned int freq_in, unsigned int freq_out)
+ {
+-	if (dai->ops->set_pll)
+-		return dai->ops->set_pll(dai, pll_id, freq_in, freq_out);
++	if (dai->ops && dai->ops->set_pll)
++		return dai->ops->set_pll(dai, pll_id, source,
++					 freq_in, freq_out);
+ 	else
+ 		return -EINVAL;
+ }
+@@ -2120,7 +2239,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
+  */
+ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+ {
+-	if (dai->ops->set_fmt)
++	if (dai->ops && dai->ops->set_fmt)
+ 		return dai->ops->set_fmt(dai, fmt);
+ 	else
+ 		return -EINVAL;
+@@ -2130,23 +2249,50 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
+ /**
+  * snd_soc_dai_set_tdm_slot - configure DAI TDM.
+  * @dai: DAI
+- * @mask: DAI specific mask representing used slots.
++ * @tx_mask: bitmask representing active TX slots.
++ * @rx_mask: bitmask representing active RX slots.
+  * @slots: Number of slots in use.
++ * @slot_width: Width in bits for each slot.
+  *
+  * Configures a DAI for TDM operation. Both mask and slots are codec and DAI
+  * specific.
+  */
+ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
+-	unsigned int mask, int slots)
++	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
+ {
+-	if (dai->ops->set_sysclk)
+-		return dai->ops->set_tdm_slot(dai, mask, slots);
++	if (dai->ops && dai->ops->set_tdm_slot)
++		return dai->ops->set_tdm_slot(dai, tx_mask, rx_mask,
++				slots, slot_width);
+ 	else
+ 		return -EINVAL;
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
+ 
+ /**
++ * snd_soc_dai_set_channel_map - configure DAI audio channel map
++ * @dai: DAI
++ * @tx_num: how many TX channels
++ * @tx_slot: pointer to an array which imply the TX slot number channel
++ *           0~num-1 uses
++ * @rx_num: how many RX channels
++ * @rx_slot: pointer to an array which imply the RX slot number channel
++ *           0~num-1 uses
++ *
++ * configure the relationship between channel number and TDM slot number.
++ */
++int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
++	unsigned int tx_num, unsigned int *tx_slot,
++	unsigned int rx_num, unsigned int *rx_slot)
++{
++	if (dai->ops && dai->ops->set_channel_map)
++		return dai->ops->set_channel_map(dai, tx_num, tx_slot,
++			rx_num, rx_slot);
++	else
++		return -EINVAL;
++}
++EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
++
++/**
+  * snd_soc_dai_set_tristate - configure DAI system or master clock.
+  * @dai: DAI
+  * @tristate: tristate enable
+@@ -2155,7 +2301,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
+  */
+ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
+ {
+-	if (dai->ops->set_sysclk)
++	if (dai->ops && dai->ops->set_tristate)
+ 		return dai->ops->set_tristate(dai, tristate);
+ 	else
+ 		return -EINVAL;
+@@ -2171,7 +2317,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
+  */
+ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
+ {
+-	if (dai->ops->digital_mute)
++	if (dai->ops && dai->ops->digital_mute)
+ 		return dai->ops->digital_mute(dai, mute);
+ 	else
+ 		return -EINVAL;
+@@ -2352,6 +2498,39 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform)
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
+ 
++static u64 codec_format_map[] = {
++	SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE,
++	SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE,
++	SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
++	SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE,
++	SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
++	SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE,
++	SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
++	SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
++	SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE,
++	SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE,
++	SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE,
++	SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE,
++	SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE,
++	SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE,
++	SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
++	| SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
++};
++
++/* Fix up the DAI formats for endianness: codecs don't actually see
++ * the endianness of the data but we're using the CPU format
++ * definitions which do need to include endianness so we ensure that
++ * codec DAIs always have both big and little endian variants set.
++ */
++static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(codec_format_map); i++)
++		if (stream->formats & codec_format_map[i])
++			stream->formats |= codec_format_map[i];
++}
++
+ /**
+  * snd_soc_register_codec - Register a codec with the ASoC core
+  *
+@@ -2359,6 +2538,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
+  */
+ int snd_soc_register_codec(struct snd_soc_codec *codec)
+ {
++	int i;
++
+ 	if (!codec->name)
+ 		return -EINVAL;
+ 
+@@ -2368,6 +2549,11 @@ int snd_soc_register_codec(struct snd_soc_codec *codec)
+ 
+ 	INIT_LIST_HEAD(&codec->list);
+ 
++	for (i = 0; i < codec->num_dai; i++) {
++		fixup_codec_formats(&codec->dai[i].playback);
++		fixup_codec_formats(&codec->dai[i].capture);
++	}
++
+ 	mutex_lock(&client_mutex);
+ 	list_add(&codec->list, &codec_list);
+ 	snd_soc_instantiate_cards();
+diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
+index 735903a..d2af872 100644
+--- a/sound/soc/soc-dapm.c
++++ b/sound/soc/soc-dapm.c
+@@ -12,7 +12,7 @@
+  *  Features:
+  *    o Changes power status of internal codec blocks depending on the
+  *      dynamic configuration of codec internal audio paths and active
+- *      DAC's/ADC's.
++ *      DACs/ADCs.
+  *    o Platform power domain - can support external components i.e. amps and
+  *      mic/meadphone insertion events.
+  *    o Automatic Mic Bias support
+@@ -37,6 +37,7 @@
+ #include <linux/bitops.h>
+ #include <linux/platform_device.h>
+ #include <linux/jiffies.h>
++#include <linux/debugfs.h>
+ #include <sound/core.h>
+ #include <sound/pcm.h>
+ #include <sound/pcm_params.h>
+@@ -52,23 +53,43 @@
+ 
+ /* dapm power sequences - make this per codec in the future */
+ static int dapm_up_seq[] = {
+-	snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
+-	snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac,
+-	snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga,
+-	snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post
++	[snd_soc_dapm_pre] = 0,
++	[snd_soc_dapm_supply] = 1,
++	[snd_soc_dapm_micbias] = 2,
++	[snd_soc_dapm_aif_in] = 3,
++	[snd_soc_dapm_aif_out] = 3,
++	[snd_soc_dapm_mic] = 4,
++	[snd_soc_dapm_mux] = 5,
++	[snd_soc_dapm_value_mux] = 5,
++	[snd_soc_dapm_dac] = 6,
++	[snd_soc_dapm_mixer] = 7,
++	[snd_soc_dapm_mixer_named_ctl] = 7,
++	[snd_soc_dapm_pga] = 8,
++	[snd_soc_dapm_adc] = 9,
++	[snd_soc_dapm_hp] = 10,
++	[snd_soc_dapm_spk] = 10,
++	[snd_soc_dapm_post] = 11,
+ };
+ 
+ static int dapm_down_seq[] = {
+-	snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
+-	snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer,
+-	snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias,
+-	snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post
++	[snd_soc_dapm_pre] = 0,
++	[snd_soc_dapm_adc] = 1,
++	[snd_soc_dapm_hp] = 2,
++	[snd_soc_dapm_spk] = 2,
++	[snd_soc_dapm_pga] = 4,
++	[snd_soc_dapm_mixer_named_ctl] = 5,
++	[snd_soc_dapm_mixer] = 5,
++	[snd_soc_dapm_dac] = 6,
++	[snd_soc_dapm_mic] = 7,
++	[snd_soc_dapm_micbias] = 8,
++	[snd_soc_dapm_mux] = 9,
++	[snd_soc_dapm_value_mux] = 9,
++	[snd_soc_dapm_aif_in] = 10,
++	[snd_soc_dapm_aif_out] = 10,
++	[snd_soc_dapm_supply] = 11,
++	[snd_soc_dapm_post] = 12,
+ };
+ 
+-static int dapm_status = 1;
+-module_param(dapm_status, int, 0);
+-MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
+-
+ static void pop_wait(u32 pop_time)
+ {
+ 	if (pop_time)
+@@ -96,6 +117,52 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
+ 	return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
+ }
+ 
++/**
++ * snd_soc_dapm_set_bias_level - set the bias level for the system
++ * @socdev: audio device
++ * @level: level to configure
++ *
++ * Configure the bias (power) levels for the SoC audio device.
++ *
++ * Returns 0 for success else error.
++ */
++static int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
++				       enum snd_soc_bias_level level)
++{
++	struct snd_soc_card *card = socdev->card;
++	struct snd_soc_codec *codec = socdev-