Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] ARM: Thumb-2: Reflect ARM/Thumb-2 configuration in module vermagic
From: Dave Martin @ 2011-02-25 18:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D67EC9F.8010305@ru.mvista.com>

On Fri, Feb 25, 2011 at 5:53 PM, Sergei Shtylyov <sshtylyov@mvista.com> wrote:
> Hello.
>
> Dave Martin wrote:
>
>>>> Loading Thumb-2 modules into an ARM kernel or vice-versa isn't
>>>> guaranteed to work safely, since the kernel is not interworking-
>>>> aware everywhere.
>>>> This patch adds "thumb2" to the module vermagic when
>>>> CONFIG_THUMB2_KERNEL is enabled, to help avoid accidental loading
>>>> of modules into the wrong kernel.
>>>> v2: modified to apply consistently on top of rmk's p2v branch.
>
>>> ?Patch changelog should follow the -- tearline.
>
>>>> Signed-off-by: Dave Martin<dave.martin@linaro.org>
>>>> Acked-by: Nicolas Pitre<nicolas.pitre@linaro.org>
>
> ?> Opinions seem to differ... I have no strong opinion on this myself.
>
> ? At least that's what Documentation/SubmittingPatches suggests:
>
> <<
> One good use for the additional comments after the "---" marker is for
> a diffstat, to show what files have changed, and the number of
> inserted and deleted lines per file. ?A diffstat is especially useful
> on bigger patches. ?Other comments relevant only to the moment or the
> maintainer, not suitable for the permanent changelog, should also go
> here. ?A good example of such comments might be "patch changelogs"
> which describe what has changed between the v1 and v2 version of the
> patch.

Fair enough.  Doesn't sounds like a inflexible rule all the same, but
when the history ceases to be relevant when the patch is merged
upstream (as in my case) is may be better to do as you suggest.  I
agree with Grant that it may sometimes be useful to preserve some of
this information in the final commit for more complex/subtle cases,
though.

I normally tidy up the cruft before sending a patch to Russell's patch
system in any case.

Cheers
---Dave

^ permalink raw reply

* [PATCH v2] ARM: Thumb-2: Reflect ARM/Thumb-2 configuration in module vermagic
From: Sergei Shtylyov @ 2011-02-25 17:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTimm+xqrQSWzPxxV7Kv+0NH2fpkg2HHUz=JNj3pN@mail.gmail.com>

Hello.

Dave Martin wrote:

>>> Loading Thumb-2 modules into an ARM kernel or vice-versa isn't
>>> guaranteed to work safely, since the kernel is not interworking-
>>> aware everywhere.
>>> This patch adds "thumb2" to the module vermagic when
>>> CONFIG_THUMB2_KERNEL is enabled, to help avoid accidental loading
>>> of modules into the wrong kernel.
>>> v2: modified to apply consistently on top of rmk's p2v branch.

>>   Patch changelog should follow the -- tearline.

>>> Signed-off-by: Dave Martin<dave.martin@linaro.org>
>>> Acked-by: Nicolas Pitre<nicolas.pitre@linaro.org>

  > Opinions seem to differ... I have no strong opinion on this myself.

    At least that's what Documentation/SubmittingPatches suggests:

<<
One good use for the additional comments after the "---" marker is for
a diffstat, to show what files have changed, and the number of
inserted and deleted lines per file.  A diffstat is especially useful
on bigger patches.  Other comments relevant only to the moment or the
maintainer, not suitable for the permanent changelog, should also go
here.  A good example of such comments might be "patch changelogs"
which describe what has changed between the v1 and v2 version of the
patch.
 >>

> Cheers
> ---Dave

WBR, Sergei

^ permalink raw reply

* [PATCH] omap4: Fix ULPI PHY init for ES1.0 SDP (Re: 4430SDP boot failure)
From: Tony Lindgren @ 2011-02-25 17:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <08df39a319ecf8f67fb87b4ba3af85dd@mail.gmail.com>

* Santosh Shilimkar <santosh.shilimkar@ti.com> [110224 21:31]:
> >
> > Was this with linux-omap master branch or mainline?
> >
> > The V6 vs V7 issues should be sorted out with Russell's patches that
> > we also have now in linux-omap master branch.
> >
> This was with mainline.
> Then I applied RMK's series and things were OK.

OK good to hear & thanks for checking that.

Tony

^ permalink raw reply

* [PATCH] nmk-gpio: use request_irq instead of chained handler
From: Will Deacon @ 2011-02-25 17:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTin_xxPJnOKxiu-z=Yo2FVkD=_Ow7CoGb2gApUaq@mail.gmail.com>

Hi Linus,

> 2011/2/23 Will Deacon <will.deacon@arm.com>:
> >> On Wed, Feb 23, 2011 at 22:47, Will Deacon <will.deacon@arm.com> wrote:
> >> >> __nmk_gpio_irq_handler doesn't do anything more that what a normal handler
> >> >> does, so it can become one. ?This is also needed for changing the GIC
> >> >> implementation to a different flow handler.
> >> >>
> >> >> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> >> >
> >> > mach-nomadik only seems to use the vic. Why does this GPIO handler
> >> > need updating?
> >>
> >> plat-nomadik/gpio.c is also used by mach-ux500, which uses the GIC.
> >
> > Ah yes, sorry I missed that one. I'm happy to include any patches from you
> > in the GIC fasteoi series if it makes merging easier.
> 
> OK if this one is OK I sure prefer that you take it in your series Will,
> since you have the whole picture of what you want to do with the
> GIC.
> 
> It'll likely collide with the stuff I have stacked up for the 2.6.39 merge
> window though, which will be pull-requested any day now.

Sure. I'll add a patch to my series that makes the minimal change required
and post it next week.

Will

^ permalink raw reply

* [PATCH] nmk-gpio: use request_irq instead of chained handler
From: Linus Walleij @ 2011-02-25 16:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5890487119819559395@unknownmsgid>

2011/2/23 Will Deacon <will.deacon@arm.com>:
>> On Wed, Feb 23, 2011 at 22:47, Will Deacon <will.deacon@arm.com> wrote:
>> >> __nmk_gpio_irq_handler doesn't do anything more that what a normal handler
>> >> does, so it can become one. ?This is also needed for changing the GIC
>> >> implementation to a different flow handler.
>> >>
>> >> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
>> >
>> > mach-nomadik only seems to use the vic. Why does this GPIO handler
>> > need updating?
>>
>> plat-nomadik/gpio.c is also used by mach-ux500, which uses the GIC.
>
> Ah yes, sorry I missed that one. I'm happy to include any patches from you
> in the GIC fasteoi series if it makes merging easier.

OK if this one is OK I sure prefer that you take it in your series Will,
since you have the whole picture of what you want to do with the
GIC.

It'll likely collide with the stuff I have stacked up for the 2.6.39 merge
window though, which will be pull-requested any day now.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v4 6/7] arm/dt: Basic tegra devicetree support
From: Grant Likely @ 2011-02-25 15:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D67AEEE.30000@ru.mvista.com>

On Fri, Feb 25, 2011 at 6:30 AM, Sergei Shtylyov <sshtylyov@mvista.com> wrote:
> On 24-02-2011 0:36, Grant Likely wrote:
>>>> v2: Fixed cut-and-paste error in commit text
>
>>> ? ?Shouldn't this sentence follow the --- tearline?
>
>> Nope! ?It is actually quite useful for the version information to show
>> up in the commit text. ?That way you know *exactly* which version got
>> merged. ?dwmw2 pointed that out to me a few months back.
>
> ? Well, I think that depends on the patch. If you have say 9 revisions with
> significant changes (that's what I actually had) and the revision history
> far exceeds the original patch description, then this will just become too
> ugly I think...

Meh.  commit text is cheap and useful.

g.

^ permalink raw reply

* [PATCH] DA850 EVM: kill useless variable
From: Nori, Sekhar @ 2011-02-25 15:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201102071845.37812.sshtylyov@ru.mvista.com>

Hi Sergei,

On Mon, Feb 07, 2011 at 21:15:37, Sergei Shtylyov wrote:
> Commit 75e2ea643fe43d5aa836475acee5bd97cd9ea4bf (davinci: DA850/OMAP-L138 EVM
> expander setup and UI card detection) introduced a useless variable: it's
> always set to 1 before it's checked in da850_evm_setup_nor_nand()...

Added this patch in queue for 2.6.39. Added a "davinci: " prefix to
the subject line.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH 8/8] OMAP2+: clockevent: late-init GPTIMER clockevent hwmodright before timer init
From: DebBarma, Tarun Kanti @ 2011-02-25 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224154108.GB20560@atomide.com>

> -----Original Message-----
> From: Tony Lindgren [mailto:tony at atomide.com]
> Sent: Thursday, February 24, 2011 9:11 PM
> To: DebBarma, Tarun Kanti
> Cc: Paul Walmsley; Shilimkar, Santosh; linux-omap at vger.kernel.org; linux-
> arm-kernel at lists.infradead.org; Hilman, Kevin; Cousson, Benoit
> Subject: Re: [PATCH 8/8] OMAP2+: clockevent: late-init GPTIMER clockevent
> hwmodright before timer init
> 
> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110224 00:27]:
> > I have tested on OMAP3 and works fine.
> > On OMAP2, I guess there is different issue for which it does not work.
> 
> That's because commit 15490ef8ff8fd22d677cb5d4f6a98e5a79118dba changed
> things to include CONFIG_CPU_32v6K. And this means that omap-for-linus
> won't boot on omap2 currently using omap2plus_defconfig. The master
> branch boots because of the patches in omap-testing.
> 
> To boot test omap-for-linus, you can temporarily merge in the
> omap-testing branch that has the pending patches from Russell to
> make non-6K ARMv6 processors work with CONFIG_CPU_32v6K.
I have re-based the changes on omap-testing branch and tested on
OMAP2420 and OMAP2430.
--
Tarun

^ permalink raw reply

* [PATCH v2 5/6] eukrea_mbimxsd51: add IPU support
From: Eric Bénard @ 2011-02-25 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-5-git-send-email-eric@eukrea.com>

- TFT lcd or DVI output selection
- if a TFT is used, add backight and lcd platform data

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
v2 : don't free gpio when lcd is selected

 arch/arm/mach-mx5/Kconfig                    |    1 +
 arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c |  132 ++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index ded1d2d..c50089b 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -109,6 +109,7 @@ config MACH_EUKREA_MBIMXSD51_BASEBOARD
 	bool
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 	select IMX_HAVE_PLATFORM_IMX_SSI
+	select IMX_HAVE_PLATFORM_IMX_IPUV3
 	help
 	  This adds board specific devices that can be found on Eukrea's
 	  MBIMXSD evaluation board.
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
index 712061c..778adee 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -30,6 +30,11 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
+#include <linux/mfd/imx-ipu-v3.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <video/platform_lcd.h>
+#include <linux/backlight.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -41,6 +46,7 @@
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx51.h>
 #include <mach/audmux.h>
+#include <mach/ipu-v3.h>
 
 #include "devices-imx51.h"
 #include "devices.h"
@@ -72,10 +78,78 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
 	MX51_PAD_AUD3_BB_CK__AUD3_TXC,
 	MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
+	/* LCD */
+	MX51_PAD_DISP1_DAT0__DISP1_DAT0,
+	MX51_PAD_DISP1_DAT1__DISP1_DAT1,
+	MX51_PAD_DISP1_DAT2__DISP1_DAT2,
+	MX51_PAD_DISP1_DAT3__DISP1_DAT3,
+	MX51_PAD_DISP1_DAT4__DISP1_DAT4,
+	MX51_PAD_DISP1_DAT5__DISP1_DAT5,
+	MX51_PAD_DISP1_DAT6__DISP1_DAT6,
+	MX51_PAD_DISP1_DAT7__DISP1_DAT7,
+	MX51_PAD_DISP1_DAT8__DISP1_DAT8,
+	MX51_PAD_DISP1_DAT9__DISP1_DAT9,
+	MX51_PAD_DISP1_DAT10__DISP1_DAT10,
+	MX51_PAD_DISP1_DAT11__DISP1_DAT11,
+	MX51_PAD_DISP1_DAT12__DISP1_DAT12,
+	MX51_PAD_DISP1_DAT13__DISP1_DAT13,
+	MX51_PAD_DISP1_DAT14__DISP1_DAT14,
+	MX51_PAD_DISP1_DAT15__DISP1_DAT15,
+	MX51_PAD_DISP1_DAT16__DISP1_DAT16,
+	MX51_PAD_DISP1_DAT17__DISP1_DAT17,
+	MX51_PAD_DI1_PIN3__DI1_PIN3,
+	MX51_PAD_DI1_PIN2__DI1_PIN2,
+	/* LCD Backlight */
+	MX51_PAD_DI1_D1_CS__GPIO3_4,
+	/* LCD RST */
+	MX51_PAD_CSI1_D9__GPIO3_13,
 };
 
 #define GPIO_LED1	IMX_GPIO_NR(3, 30)
 #define GPIO_SWITCH1	IMX_GPIO_NR(3, 31)
+#define GPIO_LCDRST	IMX_GPIO_NR(3, 13)
+#define GPIO_LCDBL	IMX_GPIO_NR(3, 4)
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power)
+		gpio_direction_output(GPIO_LCDRST, 1);
+	else
+		gpio_direction_output(GPIO_LCDRST, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+	.set_power		= eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.platform_data	= &eukrea_mbimxsd_lcd_power_data,
+};
+
+static void eukrea_mbimxsd_bl_set_intensity(int intensity)
+{
+	if (intensity)
+		gpio_direction_output(GPIO_LCDBL, 1);
+	else
+		gpio_direction_output(GPIO_LCDBL, 0);
+}
+
+static struct generic_bl_info eukrea_mbimxsd_bl_info = {
+	.name			= "eukrea_mbimxsd-bl",
+	.max_intensity		= 0xff,
+	.default_intensity	= 0xff,
+	.set_bl_intensity	= eukrea_mbimxsd_bl_set_intensity,
+};
+
+static struct platform_device eukrea_mbimxsd_bl_dev = {
+	.name			= "generic-bl",
+	.id			= 1,
+	.dev = {
+		.platform_data	= &eukrea_mbimxsd_bl_info,
+	},
+};
 
 static struct gpio_led eukrea_mbimxsd_leds[] = {
 	{
@@ -138,6 +212,50 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
 	},
 };
 
+static struct fb_videomode fb_modedb[] = {
+	{
+		.name		= "CMO-QVGA",
+		.refresh	= 60,
+		.xres		= 320,
+		.yres		= 240,
+		.pixclock	= KHZ2PICOS(6500),
+		.left_margin	= 68,
+		.right_margin	= 20,
+		.upper_margin	= 15,
+		.lower_margin	= 4,
+		.hsync_len	= 30,
+		.vsync_len	= 3,
+		.sync		= FB_SYNC_OE_LOW_ACT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+};
+
+static struct ipuv3_fb_platform_data eukrea_mbimxsd_fb0_data = {
+	.interface_pix_fmt = IPU_PIX_FMT_RGB666,
+	.flags = IMX_IPU_FB_USE_MODEDB,
+	.modes = fb_modedb,
+	.num_modes = ARRAY_SIZE(fb_modedb),
+	.display = 0,
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+	.fb_head0_platform_data = &eukrea_mbimxsd_fb0_data,
+};
+
+static int screen_type;
+
+static int __init eukrea_mbimx51sd_screen_type(char *options)
+{
+	if (!strcmp(options, "dvi"))
+		screen_type = 1;
+	else if (!strcmp(options, "tft"))
+		screen_type = 0;
+
+	return 0;
+}
+__setup("screen_type=", eukrea_mbimx51sd_screen_type);
+
 static const
 struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
 	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
@@ -186,8 +304,22 @@ void __init eukrea_mbimxsd51_baseboard_init(void)
 	gpio_direction_input(GPIO_SWITCH1);
 	gpio_free(GPIO_SWITCH1);
 
+	gpio_request(GPIO_LCDRST, "LCDRST");
+	gpio_direction_output(GPIO_LCDRST, 0);
+	gpio_request(GPIO_LCDBL, "LCDBL");
+	gpio_direction_output(GPIO_LCDBL, 0);
+	if (!screen_type) {
+		platform_device_register(&eukrea_mbimxsd_bl_dev);
+		platform_device_register(&eukrea_mbimxsd_lcd_powerdev);
+	} else {
+		gpio_free(GPIO_LCDRST);
+		gpio_free(GPIO_LCDBL);
+	}
+
 	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
 				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
 
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+	imx51_add_ipuv3(&ipu_data);
 }
-- 
1.7.4

^ permalink raw reply related

* [PATCH v2 3/6] cpuimx51sd: fix tsc2007
From: Eric Bénard @ 2011-02-25 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-3-git-send-email-eric@eukrea.com>

- wrong MUX was set before for IRQ
- get_pendown_state is no more needed

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
v2 : use correct define for pad name (with _)

 arch/arm/mach-mx5/board-cpuimx51sd.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
index 68ecfc0..6ac41d5 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -110,7 +110,7 @@ static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = {
 
 	/* Touchscreen */
 	/* IRQ */
-	_MX51_PAD_CSI1_D8__GPIO3_12 | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+	_MX51_PAD_GPIO_NAND__GPIO_NAND | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
 			PAD_CTL_PKE | PAD_CTL_SRE_FAST |
 			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
 };
@@ -119,15 +119,9 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
-static int ts_get_pendown_state(void)
-{
-	return gpio_get_value(TSC2007_IRQGPIO) ? 0 : 1;
-}
-
 static struct tsc2007_platform_data tsc2007_info = {
 	.model			= 2007,
 	.x_plate_ohms		= 180,
-	.get_pendown_state	= ts_get_pendown_state,
 };
 
 static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = {
-- 
1.7.4

^ permalink raw reply related

* [PATCH 4/4] ARM: Add SSI and aic3204 code to Visstrim_M10 boards.
From: Javier Martin @ 2011-02-25 13:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641370-17461-1-git-send-email-javier.martin@vista-silicon.com>

Visstrim_M10 boards have an TI tlv320aic3204 codec
attached to SSI1.

Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
 arch/arm/mach-imx/Kconfig                   |    1 +
 arch/arm/mach-imx/mach-imx27_visstrim_m10.c |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 197f9e2..4d01d8c 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -168,6 +168,7 @@ config MACH_IMX27_VISSTRIM_M10
 	bool "Vista Silicon i.MX27 Visstrim_m10"
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IMX_SSI
 	help
 	  Include support for Visstrim_m10 platform and its different variants.
 	  This includes specific configurations for the board and its
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 59716fa..b346484 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -69,6 +69,11 @@ static const int visstrim_m10_pins[] __initconst = {
 	PD15_AOUT_FEC_COL,
 	PD16_AIN_FEC_TX_ER,
 	PF23_AIN_FEC_TX_EN,
+	/* SSI1 */
+	PC20_PF_SSI1_FS,
+	PC21_PF_SSI1_RXD,
+	PC22_PF_SSI1_TXD,
+	PC23_PF_SSI1_CLK,
 	/* SDHC1 */
 	PE18_PF_SD1_D0,
 	PE19_PF_SD1_D1,
@@ -207,6 +212,9 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = {
 		I2C_BOARD_INFO("pca9555", 0x20),
 		.platform_data = &visstrim_m10_pca9555_pdata,
 	},
+	{
+		I2C_BOARD_INFO("tlv320aic32x4", 0x18),
+	}
 };
 
 /* USB OTG */
@@ -222,6 +230,11 @@ static struct mxc_usbh_platform_data visstrim_m10_usbotg_pdata = {
 	.flags	= MXC_EHCI_POWER_PINS_ENABLED,
 };
 
+/* SSI */
+static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = {
+	.flags			= IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
 static void __init visstrim_m10_board_init(void)
 {
 	int ret;
@@ -231,6 +244,7 @@ static void __init visstrim_m10_board_init(void)
 	if (ret)
 		pr_err("Failed to setup pins (%d)\n", ret);
 
+	imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata);
 	imx27_add_imx_uart0(&uart_pdata);
 
 	i2c_register_board_info(0, visstrim_m10_i2c_devices,
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 3/4] ASoC: Add machine driver for Visstrim_M10 board.
From: Javier Martin @ 2011-02-25 13:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641370-17461-1-git-send-email-javier.martin@vista-silicon.com>

Visstrim_M10 board uses a tlv320aic3204 codec. This driver
provides support for it.

Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
 sound/soc/imx/Kconfig           |   10 +++
 sound/soc/imx/Makefile          |    2 +
 sound/soc/imx/mx27vis-aic32x4.c |  137 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/imx/mx27vis-aic32x4.c

diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 642270a..15e7c04 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -30,6 +30,16 @@ config SND_MXC_SOC_WM1133_EV1
 	  Enable support for audio on the i.MX31ADS with the WM1133-EV1
 	  PMIC board with WM8835x fitted.
 
+config SND_SOC_MX27VIS_AIC32X4
+	tristate "SoC audio support for Visstrim M10 boards"
+	depends on MACH_IMX27_VISSTRIM_M10
+	select SND_SOC_TVL320AIC32X4
+	select SND_MXC_SOC_SSI
+	select SND_MXC_SOC_MX2
+	help
+	  Say Y if you want to add support for SoC audio on Visstrim SM10
+	  board with TLV320AIC32X4 codec.
+
 config SND_SOC_PHYCORE_AC97
 	tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
 	depends on MACH_PCM043 || MACH_PCA100
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index b67fc02..d6d609b 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -10,8 +10,10 @@ obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
 snd-soc-phycore-ac97-objs := phycore-ac97.o
+snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
+obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
new file mode 100644
index 0000000..21583fe
--- /dev/null
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -0,0 +1,137 @@
+/*
+ * mx27vis-aic32x4.c
+ *
+ * Copyright 2011 Vista Silicon S.L.
+ *
+ * Author: Javier Martin <javier.martin@vista-silicon.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <asm/mach-types.h>
+#include <mach/audmux.h>
+
+#include "../codecs/tlv320aic32x4.h"
+#include "imx-ssi.h"
+
+static int mx27vis_aic32x4_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->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret;
+	u32 dai_format;
+
+	dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
+		SND_SOC_DAIFMT_CBM_CFM;
+
+	/* set codec DAI configuration */
+	snd_soc_dai_set_fmt(codec_dai, dai_format);
+
+	/* set cpu DAI configuration */
+	snd_soc_dai_set_fmt(cpu_dai, dai_format);
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+				     25000000, SND_SOC_CLOCK_OUT);
+	if (ret) {
+		pr_err("%s: failed setting codec sysclk\n", __func__);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
+				SND_SOC_CLOCK_IN);
+	if (ret) {
+		pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
+	.hw_params	= mx27vis_aic32x4_hw_params,
+};
+
+static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
+	.name		= "tlv320aic32x4",
+	.stream_name	= "TLV320AIC32X4",
+	.codec_dai_name	= "tlv320aic32x4-hifi",
+	.platform_name	= "imx-pcm-audio.0",
+	.codec_name	= "tlv320aic32x4-codec.0-0018",
+	.cpu_dai_name	= "imx-ssi.0",
+	.ops		= &mx27vis_aic32x4_snd_ops,
+};
+
+static struct snd_soc_card mx27vis_aic32x4 = {
+	.name		= "visstrim_m10-audio",
+	.dai_link	= &mx27vis_aic32x4_dai,
+	.num_links	= 1,
+};
+
+static struct platform_device *mx27vis_aic32x4_snd_device;
+
+static int __init mx27vis_aic32x4_init(void)
+{
+	int ret;
+
+	mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!mx27vis_aic32x4_snd_device)
+		return -ENOMEM;
+
+	platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4);
+	ret = platform_device_add(mx27vis_aic32x4_snd_device);
+
+	if (ret) {
+		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
+		platform_device_put(mx27vis_aic32x4_snd_device);
+	}
+
+	/* Connect SSI0 as clock slave to SSI1 external pins */
+	mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+			MXC_AUDMUX_V1_PCR_SYN |
+			MXC_AUDMUX_V1_PCR_TFSDIR |
+			MXC_AUDMUX_V1_PCR_TCLKDIR |
+			MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
+			MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
+	);
+	mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
+			MXC_AUDMUX_V1_PCR_SYN |
+			MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+	);
+
+	return ret;
+}
+
+static void __exit mx27vis_aic32x4_exit(void)
+{
+	platform_device_unregister(mx27vis_aic32x4_snd_device);
+}
+
+module_init(mx27vis_aic32x4_init);
+module_exit(mx27vis_aic32x4_exit);
+
+MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
+MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 2/4] ASoC: Fix burstsize and DSP_B format problems in imx-ssi.
From: Javier Martin @ 2011-02-25 13:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641370-17461-1-git-send-email-javier.martin@vista-silicon.com>

When choosing IMX_DMA flag, burtsizes are set to its default
value (0) which leads to driver malfunction. Change them to 4.

DSP_B interface needs additional flag to match DSP_B formats
as described in several codecs as wm8741 and aic3205.

Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
 sound/soc/imx/imx-ssi.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 30894ea..bc92ec6 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -108,7 +108,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		break;
 	case SND_SOC_DAIFMT_DSP_B:
 		/* data on rising edge of bclk, frame high with data */
-		strcr |= SSI_STCR_TFSL;
+		strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
 		/* data on rising edge of bclk, frame high 1clk before data */
@@ -656,6 +656,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
 	ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
 	ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
 
+	ssi->dma_params_tx.burstsize = 4;
+	ssi->dma_params_rx.burstsize = 4;
+
 	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
 	if (res)
 		ssi->dma_params_tx.dma = res->start;
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 1/4] ASoC: Add TI tlv320aic32x4 codec support.
From: Javier Martin @ 2011-02-25 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for tlv320aic3205 and tlv320aic3254 codecs.
It doesn't include miniDSP support for aic3254.

Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
 sound/soc/codecs/Kconfig         |    4 +
 sound/soc/codecs/Makefile        |    2 +
 sound/soc/codecs/tlv320aic32x4.c |  884 ++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/tlv320aic32x4.h |  138 ++++++
 4 files changed, 1028 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/codecs/tlv320aic32x4.c
 create mode 100644 sound/soc/codecs/tlv320aic32x4.h

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3b5690d..497c9a6 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS
 	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_TVL320AIC32X4 if I2C
 	select SND_SOC_TLV320AIC3X if I2C
 	select SND_SOC_TPA6130A2 if I2C
 	select SND_SOC_TLV320DAC33 if I2C
@@ -182,6 +183,9 @@ config SND_SOC_TLV320AIC26
 	tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
 	depends on SPI
 
+config SND_SOC_TVL320AIC32X4
+	tristate
+
 config SND_SOC_TLV320AIC3X
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f67a2d6..5709ca6 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -23,6 +23,7 @@ snd-soc-stac9766-objs := stac9766.o
 snd-soc-tlv320aic23-objs := tlv320aic23.o
 snd-soc-tlv320aic26-objs := tlv320aic26.o
 snd-soc-tlv320aic3x-objs := tlv320aic3x.o
+snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
 snd-soc-tlv320dac33-objs := tlv320dac33.o
 snd-soc-twl4030-objs := twl4030.o
 snd-soc-twl6040-objs := twl6040.o
@@ -98,6 +99,7 @@ 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
+obj-$(CONFIG_SND_SOC_TVL320AIC32X4)     += snd-soc-tlv320aic32x4.o
 obj-$(CONFIG_SND_SOC_TLV320DAC33)	+= snd-soc-tlv320dac33.o
 obj-$(CONFIG_SND_SOC_TWL4030)	+= snd-soc-twl4030.o
 obj-$(CONFIG_SND_SOC_TWL6040)	+= snd-soc-twl6040.o
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
new file mode 100644
index 0000000..5ae7b20
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -0,0 +1,884 @@
+/*
+ * linux/sound/soc/codecs/tlv320aic32x4.c
+ *
+ * Copyright 2011 Vista Silicon S.L.
+ *
+ * Author: Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+
+#include "tlv320aic32x4.h"
+
+#define SOC_DOUBLE_R_AIC32X4(xname, reg_left, reg_right, shift, mask, invert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.info = snd_soc_info_volsw_2r_aic32x4, \
+	.get = snd_soc_get_volsw_2r_aic32x4, \
+	.put = snd_soc_put_volsw_2r_aic32x4, \
+	.private_value = (reg_left) | ((shift) << 8)  | \
+		((mask) << 12) | ((invert) << 20) | ((reg_right) << 24) }
+
+struct aic32x4_rate_divs {
+	u32 mclk;
+	u32 rate;
+	u8 p_val;
+	u8 pll_j;
+	u16 pll_d;
+	u16 dosr;
+	u8 ndac;
+	u8 mdac;
+	u8 aosr;
+	u8 nadc;
+	u8 madc;
+	u8 blck_N;
+};
+
+struct aic32x4_priv {
+	u32 sysclk;
+	s32 master;
+	u8 page_no;
+	void *control_data;
+};
+
+struct aic32x4_configs {
+	u8 reg_offset;
+	u8 reg_val;
+};
+
+#define aic32x4_reset(c) snd_soc_write(c, AIC32X4_RESET, 0x01);
+
+static int snd_soc_info_volsw_2r_aic32x4(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo);
+
+static int snd_soc_get_volsw_2r_aic32x4(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol);
+
+static int snd_soc_put_volsw_2r_aic32x4(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol);
+
+static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
+	SOC_DOUBLE_R_AIC32X4("PCM Playback Volume", AIC32X4_LDACVOL,
+			AIC32X4_RDACVOL, 0, 0xAf, 0),
+	SOC_DOUBLE_R_AIC32X4("HP Driver Gain", AIC32X4_HPLGAIN,
+			AIC32X4_HPRGAIN, 0, 0x23, 0),
+	SOC_DOUBLE_R_AIC32X4("LO Driver Gain", AIC32X4_LOLGAIN,
+			AIC32X4_LORGAIN, 0, 0x23, 0),
+	SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
+			AIC32X4_HPRGAIN, 6, 0x01, 1),
+	SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
+			AIC32X4_LORGAIN, 6, 0x01, 1),
+
+	SOC_DOUBLE_R("ADC Volume Level", AIC32X4_LADCVOL,
+			AIC32X4_RADCVOL, 0, 0x28, 0),
+	SOC_DOUBLE_R("PGA Gain Level", AIC32X4_LMICPGAVOL,
+			AIC32X4_RMICPGAVOL, 0, 0x5f, 0),
+
+	SOC_SINGLE("Auto-mute", AIC32X4_DACMUTE, 4, 7, 0),
+
+	SOC_SINGLE("AGC Left Enable Switch", AIC32X4_LAGC1, 7, 1, 0),
+	SOC_SINGLE("AGC Right Enable Switch", AIC32X4_RAGC1, 7, 1, 0),
+	SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
+			4, 0x07, 0),
+	SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
+			0, 0x03, 0),
+	SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
+			6, 0x03, 0),
+	SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
+			1, 0x1F, 0),
+	SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
+			0, 0x7F, 0),
+	SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
+			3, 0x1F, 0),
+	SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
+			3, 0x1F, 0),
+	SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
+			0, 0x1F, 0),
+	SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
+			0, 0x0F, 0),
+
+	SOC_SINGLE("MIC BIAS", AIC32X4_MICBIAS, 6, 1, 0),
+};
+
+static const struct aic32x4_rate_divs aic32x4_divs[] = {
+	/* 8k rate */
+	{AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
+	{AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
+	{AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
+	/* 11.025k rate */
+	{AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
+	{AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
+	/* 16k rate */
+	{AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
+	{AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
+	{AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
+	/* 22.05k rate */
+	{AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
+	{AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
+	{AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
+	/* 32k rate */
+	{AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
+	{AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
+	/* 44.1k rate */
+	{AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
+	{AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
+	{AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
+	/* 48k rate */
+	{AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
+	{AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
+	{AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}
+};
+
+static const struct aic32x4_configs aic32x4_reg_init[] = {
+	{AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE},
+	{AIC32X4_LDOCTL, AIC32X4_LDOCTLEN},
+	{AIC32X4_CMMODE, AIC32X4_LDOIN_18_36 | AIC32X4_LDOIN2HP},
+	{AIC32X4_CLKMUX, AIC32X4_PLLCLKIN},
+	{AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK},
+	{AIC32X4_DACSETUP,
+	 AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN | AIC32X4_SSTEP2WCLK},
+	{AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K},
+	{AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K},
+	{AIC32X4_LMICPGAVOL, 0x00},
+	{AIC32X4_RMICPGAVOL, 0x00},
+	/* Unmute ADC left and right channels */
+	{AIC32X4_ADCFGA, 0x00},
+	/* MICBIAS = 2.075V(CM=0.75V) generated from LDOIN */
+	{AIC32X4_MICBIAS, 0x68},
+	{AIC32X4_DACSPB, AIC32X4_DACSPBLOCK_MASK & 0x1},
+	{AIC32X4_ADCSPB, AIC32X4_ADCSPBLOCK_MASK & 0x1},
+};
+
+static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
+	SOC_DAPM_SINGLE("L_DAC switch", AIC32X4_HPLROUTE, 3, 1, 0),
+	SOC_DAPM_SINGLE("IN1_L switch", AIC32X4_HPLROUTE, 2, 1, 0),
+};
+
+static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
+	SOC_DAPM_SINGLE("R_DAC switch", AIC32X4_HPRROUTE, 3, 1, 0),
+	SOC_DAPM_SINGLE("IN1_R switch", AIC32X4_HPRROUTE, 2, 1, 0),
+};
+
+static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
+	SOC_DAPM_SINGLE("L_DAC switch", AIC32X4_LOLROUTE, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
+	SOC_DAPM_SINGLE("R_DAC switch", AIC32X4_LORROUTE, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new left_input_mixer_controls[] = {
+	SOC_DAPM_SINGLE("IN1_L P switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
+	SOC_DAPM_SINGLE("IN2_L P switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
+	SOC_DAPM_SINGLE("IN3_L P switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
+};
+
+static const struct snd_kcontrol_new right_input_mixer_controls[] = {
+	SOC_DAPM_SINGLE("IN1_R P switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
+	SOC_DAPM_SINGLE("IN2_R P switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
+	SOC_DAPM_SINGLE("IN3_R P switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
+	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
+	SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
+			   &hpl_output_mixer_controls[0],
+			   ARRAY_SIZE(hpl_output_mixer_controls)),
+	SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
+			   &lol_output_mixer_controls[0],
+			   ARRAY_SIZE(lol_output_mixer_controls)),
+	SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
+
+	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
+	SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
+			   &hpr_output_mixer_controls[0],
+			   ARRAY_SIZE(hpr_output_mixer_controls)),
+	SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
+			   &lor_output_mixer_controls[0],
+			   ARRAY_SIZE(lor_output_mixer_controls)),
+	SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
+			   &left_input_mixer_controls[0],
+			   ARRAY_SIZE(left_input_mixer_controls)),
+	SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
+			   &right_input_mixer_controls[0],
+			   ARRAY_SIZE(right_input_mixer_controls)),
+	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
+	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
+
+	SND_SOC_DAPM_OUTPUT("HPL"),
+	SND_SOC_DAPM_OUTPUT("HPR"),
+	SND_SOC_DAPM_OUTPUT("LOL"),
+	SND_SOC_DAPM_OUTPUT("LOR"),
+	SND_SOC_DAPM_INPUT("IN1_L"),
+	SND_SOC_DAPM_INPUT("IN1_R"),
+	SND_SOC_DAPM_INPUT("IN2_L"),
+	SND_SOC_DAPM_INPUT("IN2_R"),
+	SND_SOC_DAPM_INPUT("IN3_L"),
+	SND_SOC_DAPM_INPUT("IN3_R"),
+};
+
+static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
+	/* Left Output */
+	{"HPL Output Mixer", "L_DAC switch", "Left DAC"},
+	{"HPL Output Mixer", "IN1_L switch", "IN1_L"},
+
+	{"HPL Power", NULL, "HPL Output Mixer"},
+	{"HPL", NULL, "HPL Power"},
+
+	{"LOL Output Mixer", "L_DAC switch", "Left DAC"},
+
+	{"LOL Power", NULL, "LOL Output Mixer"},
+	{"LOL", NULL, "LOL Power"},
+
+	/* Right Output */
+	{"HPR Output Mixer", "R_DAC switch", "Right DAC"},
+	{"HPR Output Mixer", "IN1_R switch", "IN1_R"},
+
+	{"HPR Power", NULL, "HPR Output Mixer"},
+	{"HPR", NULL, "HPR Power"},
+
+	{"LOR Output Mixer", "R_DAC switch", "Right DAC"},
+
+	{"LOR Power", NULL, "LOR Output Mixer"},
+	{"LOR", NULL, "LOR Power"},
+
+	/* Left input */
+	{"Left Input Mixer", "IN1_L P switch", "IN1_L"},
+	{"Left Input Mixer", "IN2_L P switch", "IN2_L"},
+	{"Left Input Mixer", "IN3_L P switch", "IN3_L"},
+
+	{"Left ADC", NULL, "Left Input Mixer"},
+
+	/* Right Input */
+	{"Right Input Mixer", "IN1_R P switch", "IN1_R"},
+	{"Right Input Mixer", "IN2_R P switch", "IN2_R"},
+	{"Right Input Mixer", "IN3_R P switch", "IN3_R"},
+
+	{"Right ADC", NULL, "Right Input Mixer"},
+};
+
+static inline int aic32x4_change_page(struct snd_soc_codec *codec,
+					unsigned int new_page)
+{
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	u8 data[2];
+
+	data[0] = 0x00;
+	data[1] = new_page & 0xff;
+
+	if (codec->hw_write(codec->control_data, data, 2) == 2) {
+		aic32x4->page_no = new_page;
+		return 0;
+	} else {
+		return -EIO;
+	}
+}
+
+static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg,
+				unsigned int val)
+{
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	unsigned int page = reg / 128;
+	unsigned int fixed_reg = reg % 128;
+	u8 data[2];
+	int ret;
+
+	/* A write to AIC32X4_PSEL is really a non-explicit page change */
+	if (reg == AIC32X4_PSEL)
+		return aic32x4_change_page(codec, val);
+
+	if (aic32x4->page_no != page) {
+		ret = aic32x4_change_page(codec, page);
+		if (ret != 0)
+			return ret;
+	}
+
+	data[0] = fixed_reg & 0xff;
+	data[1] = val & 0xff;
+
+	if (codec->hw_write(codec->control_data, data, 2) == 2)
+		return 0;
+	else
+		return -EIO;
+}
+
+static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	unsigned int page = reg / 128;
+	unsigned int fixed_reg = reg % 128;
+	int ret;
+
+	if (aic32x4->page_no != page) {
+		ret = aic32x4_change_page(codec, page);
+		if (ret != 0)
+			return ret;
+	}
+	return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff);
+}
+
+static int snd_soc_info_volsw_2r_aic32x4(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
+{
+	int mask = (kcontrol->private_value >> 12) & 0xff;
+
+	uinfo->type =
+	mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = mask;
+	return 0;
+}
+
+int snd_soc_get_volsw_2r_aic32x4(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int reg = kcontrol->private_value & 0xff;
+	int reg2 = (kcontrol->private_value >> 24) & 0xff;
+	int mask;
+	int shift;
+	unsigned short val, val2;
+
+	if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
+		mask = 0xff;
+		shift = 0;
+	} else if ((!strcmp(kcontrol->id.name, "HP Driver Gain")) ||
+		   (!strcmp(kcontrol->id.name, "LO Driver Gain"))) {
+		mask = 0x3F;
+		shift = 0;
+	} else if (!strcmp(kcontrol->id.name, "PGA Capture Volume")) {
+		mask = 0x7F;
+		shift = 0;
+	} else {
+		printk(KERN_ERR "aic32x4: invalid kcontrol name\n");
+		return -1;
+	}
+
+	val = (snd_soc_read(codec, reg) >> shift) & mask;
+	val2 = (snd_soc_read(codec, reg2) >> shift) & mask;
+
+	if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
+		ucontrol->value.integer.value[0] =
+		    (val <= 48) ? (val + 127) : (val - 129);
+		ucontrol->value.integer.value[1] =
+		    (val2 <= 48) ? (val2 + 127) : (val2 - 129);
+	} else if ((!strcmp(kcontrol->id.name, "HP Driver Gain"))
+		   || (!strcmp(kcontrol->id.name, "LO Driver Gain"))) {
+		ucontrol->value.integer.value[0] =
+		    (val <= 29) ? (val + 6) : (val - 58);
+		ucontrol->value.integer.value[1] =
+		    (val2 <= 29) ? (val2 + 6) : (val2 - 58);
+	} else if (!strcmp(kcontrol->id.name, "PGA Capture Volume")) {
+		ucontrol->value.integer.value[0] =
+		    (val <= 38) ? (val + 25) : (val - 103);
+		ucontrol->value.integer.value[1] =
+		    (val2 <= 38) ? (val2 + 25) : (val2 - 103);
+	}
+	return 0;
+}
+
+int snd_soc_put_volsw_2r_aic32x4(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int reg = kcontrol->private_value & 0xff;
+	int reg2 = (kcontrol->private_value >> 24) & 0xff;
+	int err;
+	unsigned short val, val2, val_mask;
+
+	val = ucontrol->value.integer.value[0];
+	val2 = ucontrol->value.integer.value[1];
+
+	if (!strcmp(kcontrol->id.name, "PCM Playback Volume")) {
+		val = (val >= 127) ? (val - 127) : (val + 129);
+		val2 = (val2 >= 127) ? (val2 - 127) : (val2 + 129);
+		val_mask = 0xff;	/* 8 bits */
+	} else if ((!strcmp(kcontrol->id.name, "HP Driver Gain")) ||
+		   (!strcmp(kcontrol->id.name, "LO Driver Gain"))) {
+		val = (val >= 6) ? (val - 6) : (val + 58);
+		val2 = (val2 >= 6) ? (val2 - 6) : (val2 + 58);
+		val_mask = 0x3F;	/* 6 bits */
+	} else if (!strcmp(kcontrol->id.name, "PGA Capture Volume")) {
+		val = (val >= 25) ? (val - 25) : (val + 103);
+		val2 = (val2 >= 25) ? (val2 - 25) : (val2 + 103);
+		val_mask = 0x7F;	/* 7 bits */
+	} else {
+		printk(KERN_ERR "aic32x4: invalid control name\n");
+		return -1;
+	}
+
+	err = snd_soc_update_bits(codec, reg, val_mask, val);
+	if (err < 0) {
+		printk(KERN_ERR "aic32x4: error while updating bits\n");
+		return err;
+	}
+
+	err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+	return err;
+}
+
+static inline int aic32x4_get_divs(int mclk, int rate)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
+		if ((aic32x4_divs[i].rate == rate)
+		    && (aic32x4_divs[i].mclk == mclk)) {
+			return i;
+		}
+	}
+	printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
+	return -EINVAL;
+}
+
+static int aic32x4_add_widgets(struct snd_soc_codec *codec)
+{
+	snd_soc_dapm_new_controls(codec, aic32x4_dapm_widgets,
+				ARRAY_SIZE(aic32x4_dapm_widgets));
+
+	snd_soc_dapm_add_routes(codec, aic32x4_dapm_routes,
+				ARRAY_SIZE(aic32x4_dapm_routes));
+
+	snd_soc_dapm_new_widgets(codec);
+	return 0;
+}
+
+static int aic32x4_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 aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+
+	switch (freq) {
+	case AIC32X4_FREQ_12000000:
+	case AIC32X4_FREQ_24000000:
+	case AIC32X4_FREQ_25000000:
+		aic32x4->sysclk = freq;
+		return 0;
+	}
+	printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
+	return -EINVAL;
+}
+
+static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	u8 iface_reg_1;
+	u8 iface_reg_2;
+	u8 iface_reg_3;
+
+	iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
+	iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
+	iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
+	iface_reg_2 = 0;
+	iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
+	iface_reg_3 = iface_reg_3 & ~(1 << 3);
+
+	/* set master/slave audio interface */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		aic32x4->master = 1;
+		iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		aic32x4->master = 0;
+		break;
+	default:
+		printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
+		iface_reg_3 |= (1 << 3); /* invert bit clock */
+		iface_reg_2 = 0x01; /* add offset 1 */
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
+		iface_reg_3 |= (1 << 3); /* invert bit clock */
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		iface_reg_1 |=
+			(AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		iface_reg_1 |=
+			(AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
+		break;
+	default:
+		printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
+		return -EINVAL;
+	}
+
+	snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
+	snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
+	snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);
+	return 0;
+}
+
+static int aic32x4_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params,
+			     struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	u8 data;
+	int i;
+
+	i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
+	if (i < 0) {
+		printk(KERN_ERR "aic32x4: sampling rate not supported\n");
+		return i;
+	}
+
+	/* We will fix R value to 1 and will make P & J=K.D as varialble */
+	data = snd_soc_read(codec, AIC32X4_PLLPR);
+	data &= ~(7 << 4);
+	snd_soc_write(codec, AIC32X4_PLLPR,
+		      (data | (aic32x4_divs[i].p_val << 4) | 0x01));
+
+	snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
+
+	snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
+	snd_soc_write(codec, AIC32X4_PLLDLSB,
+		      (aic32x4_divs[i].pll_d & 0xff));
+
+	/* NDAC divider value */
+	data = snd_soc_read(codec, AIC32X4_NDAC);
+	data &= ~(0x7f);
+	snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
+
+	/* MDAC divider value */
+	data = snd_soc_read(codec, AIC32X4_MDAC);
+	data &= ~(0x7f);
+	snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
+
+	/* DOSR MSB & LSB values */
+	snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
+	snd_soc_write(codec, AIC32X4_DOSRLSB,
+		      (aic32x4_divs[i].dosr & 0xff));
+
+	/* NADC divider value */
+	data = snd_soc_read(codec, AIC32X4_NADC);
+	data &= ~(0x7f);
+	snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
+
+	/* MADC divider value */
+	data = snd_soc_read(codec, AIC32X4_MADC);
+	data &= ~(0x7f);
+	snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
+
+	/* AOSR value */
+	snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
+
+	/* BCLK N divider */
+	data = snd_soc_read(codec, AIC32X4_BCLKN);
+	data &= ~(0x7f);
+	snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
+
+	data = snd_soc_read(codec, AIC32X4_IFACE1);
+	data = data & ~(3 << 4);
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
+		break;
+	}
+	snd_soc_write(codec, AIC32X4_IFACE1, data);
+
+	return 0;
+}
+
+static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	u8 dac_reg;
+
+	dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
+	if (mute)
+		snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
+	else
+		snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
+	return 0;
+}
+
+static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
+				  enum snd_soc_bias_level level)
+{
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	u8 value;
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		if (aic32x4->master) {
+			/* Switch on PLL */
+			value = snd_soc_read(codec, AIC32X4_PLLPR);
+			snd_soc_write(codec, AIC32X4_PLLPR,
+				      (value | AIC32X4_PLLEN));
+
+			/* Switch on NDAC Divider */
+			value = snd_soc_read(codec, AIC32X4_NDAC);
+			snd_soc_write(codec, AIC32X4_NDAC,
+				      value | AIC32X4_NDACEN);
+
+			/* Switch on MDAC Divider */
+			value = snd_soc_read(codec, AIC32X4_MDAC);
+			snd_soc_write(codec, AIC32X4_MDAC,
+				      value | AIC32X4_MDACEN);
+
+			/* Switch on NADC Divider */
+			value = snd_soc_read(codec, AIC32X4_NADC);
+			snd_soc_write(codec, AIC32X4_NADC,
+				      value | AIC32X4_MDACEN);
+
+			/* Switch on MADC Divider */
+			value = snd_soc_read(codec, AIC32X4_MADC);
+			snd_soc_write(codec, AIC32X4_MADC,
+				      value | AIC32X4_MDACEN);
+
+			/* Switch on BCLK_N Divider */
+			value = snd_soc_read(codec, AIC32X4_BCLKN);
+			snd_soc_write(codec, AIC32X4_BCLKN,
+				      value | AIC32X4_BCLKEN);
+		}
+		break;
+	case SND_SOC_BIAS_PREPARE:
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		if (aic32x4->master) {
+			/* Switch off PLL */
+			value = snd_soc_read(codec, AIC32X4_PLLPR);
+			snd_soc_write(codec, AIC32X4_PLLPR,
+				      (value & ~AIC32X4_PLLEN));
+
+			/* Switch off NDAC Divider */
+			value = snd_soc_read(codec, AIC32X4_NDAC);
+			snd_soc_write(codec, AIC32X4_NDAC,
+				      value & ~AIC32X4_NDACEN);
+
+			/* Switch off MDAC Divider */
+			value = snd_soc_read(codec, AIC32X4_MDAC);
+			snd_soc_write(codec, AIC32X4_MDAC,
+				      value & ~AIC32X4_MDACEN);
+
+			/* Switch off NADC Divider */
+			value = snd_soc_read(codec, AIC32X4_NADC);
+			snd_soc_write(codec, AIC32X4_NADC,
+				      value & ~AIC32X4_NDACEN);
+
+			/* Switch off MADC Divider */
+			value = snd_soc_read(codec, AIC32X4_MADC);
+			snd_soc_write(codec, AIC32X4_MADC,
+				      value & ~AIC32X4_MDACEN);
+			value = snd_soc_read(codec, AIC32X4_BCLKN);
+
+			/* Switch off BCLK_N Divider */
+			snd_soc_write(codec, AIC32X4_BCLKN,
+				      value & ~AIC32X4_BCLKEN);
+		}
+		break;
+	case SND_SOC_BIAS_OFF:
+		break;
+	}
+	codec->bias_level = level;
+	return 0;
+}
+
+#define AIC32X4_RATES	SNDRV_PCM_RATE_8000_48000
+#define AIC32X4_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
+			 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops aic32x4_ops = {
+	.hw_params = aic32x4_hw_params,
+	.digital_mute = aic32x4_mute,
+	.set_fmt = aic32x4_set_dai_fmt,
+	.set_sysclk = aic32x4_set_dai_sysclk,
+};
+
+static struct snd_soc_dai_driver aic32x4_dai = {
+	.name = "tlv320aic32x4-hifi",
+	.playback = {
+		     .stream_name = "Playback",
+		     .channels_min = 1,
+		     .channels_max = 2,
+		     .rates = AIC32X4_RATES,
+		     .formats = AIC32X4_FORMATS,},
+	.capture = {
+		    .stream_name = "Capture",
+		    .channels_min = 1,
+		    .channels_max = 2,
+		    .rates = AIC32X4_RATES,
+		    .formats = AIC32X4_FORMATS,},
+	.ops = &aic32x4_ops,
+	.symmetric_rates = 1,
+};
+
+static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+	aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	return 0;
+}
+
+static int aic32x4_resume(struct snd_soc_codec *codec)
+{
+	aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	return 0;
+}
+
+static int aic32x4_probe(struct snd_soc_codec *codec)
+{
+	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	int i;
+
+	codec->hw_write = (hw_write_t) i2c_master_send;
+	codec->control_data = aic32x4->control_data;
+
+	aic32x4_reset(codec);
+
+	/* Initial value for some registers */
+	for (i = 0; i < ARRAY_SIZE(aic32x4_reg_init); i++)
+		snd_soc_write(codec, aic32x4_reg_init[i].reg_offset,
+			      aic32x4_reg_init[i].reg_val);
+
+	aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_add_controls(codec, aic32x4_snd_controls,
+			     ARRAY_SIZE(aic32x4_snd_controls));
+	aic32x4_add_widgets(codec);
+
+	return 0;
+}
+
+
+static int aic32x4_remove(struct snd_soc_codec *codec)
+{
+	aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
+	.read = aic32x4_read,
+	.write = aic32x4_write,
+	.probe = aic32x4_probe,
+	.remove = aic32x4_remove,
+	.suspend = aic32x4_suspend,
+	.resume = aic32x4_resume,
+	.set_bias_level = aic32x4_set_bias_level,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
+				      const struct i2c_device_id *id)
+{
+	struct aic32x4_priv *aic32x4;
+	int ret;
+
+	aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL);
+	if (aic32x4 == NULL)
+		return -ENOMEM;
+
+	aic32x4->control_data = i2c;
+	i2c_set_clientdata(i2c, aic32x4);
+
+	ret = snd_soc_register_codec(&i2c->dev,
+			&soc_codec_dev_aic32x4, &aic32x4_dai, 1);
+	if (ret < 0)
+		kfree(aic32x4);
+	return ret;
+}
+
+static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
+{
+	snd_soc_unregister_codec(&client->dev);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static const struct i2c_device_id aic32x4_i2c_id[] = {
+	{ "tlv320aic32x4", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
+
+static struct i2c_driver aic32x4_i2c_driver = {
+	.driver = {
+		.name = "tlv320aic32x4-codec",
+		.owner = THIS_MODULE,
+	},
+	.probe =    aic32x4_i2c_probe,
+	.remove =   __devexit_p(aic32x4_i2c_remove),
+	.id_table = aic32x4_i2c_id,
+};
+#endif
+
+static int __init aic32x4_modinit(void)
+{
+	int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	ret = i2c_add_driver(&aic32x4_i2c_driver);
+	if (ret != 0) {
+		printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
+		       ret);
+	}
+#endif
+	return ret;
+}
+module_init(aic32x4_modinit);
+
+static void __exit aic32x4_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	i2c_del_driver(&aic32x4_i2c_driver);
+#endif
+}
+module_exit(aic32x4_exit);
+
+MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
+MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h
new file mode 100644
index 0000000..48c0a3d
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.h
@@ -0,0 +1,138 @@
+/*
+ * tlv320aic32x4.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef _TLV320AIC32X4_H
+#define _TLV320AIC32X4_H
+
+/* tlv320aic32x4 register space (in decimal to match datasheet) */
+
+#define AIC32X4_PAGE1		128
+
+#define	AIC32X4_PSEL		0
+#define	AIC32X4_RESET		1
+#define	AIC32X4_CLKMUX		4
+#define	AIC32X4_PLLPR		5
+#define	AIC32X4_PLLJ		6
+#define	AIC32X4_PLLDMSB		7
+#define	AIC32X4_PLLDLSB		8
+#define	AIC32X4_NDAC		11
+#define	AIC32X4_MDAC		12
+#define AIC32X4_DOSRMSB		13
+#define AIC32X4_DOSRLSB		14
+#define	AIC32X4_NADC		18
+#define	AIC32X4_MADC		19
+#define AIC32X4_AOSR		20
+#define AIC32X4_CLKMUX2		25
+#define AIC32X4_CLKOUTM		26
+#define AIC32X4_IFACE1		27
+#define AIC32X4_IFACE2		28
+#define AIC32X4_IFACE3		29
+#define AIC32X4_BCLKN		30
+#define AIC32X4_IFACE4		31
+#define AIC32X4_IFACE5		32
+#define AIC32X4_IFACE6		33
+#define AIC32X4_DOUTCTL		53
+#define AIC32X4_DINCTL		54
+#define AIC32X4_DACSPB		60
+#define AIC32X4_ADCSPB		61
+#define AIC32X4_DACSETUP	63
+#define AIC32X4_DACMUTE		64
+#define AIC32X4_LDACVOL		65
+#define AIC32X4_RDACVOL		66
+#define AIC32X4_ADCSETUP	81
+#define	AIC32X4_ADCFGA		82
+#define AIC32X4_LADCVOL		83
+#define AIC32X4_RADCVOL		84
+#define AIC32X4_LAGC1		86
+#define AIC32X4_LAGC2		87
+#define AIC32X4_LAGC3		88
+#define AIC32X4_LAGC4		89
+#define AIC32X4_LAGC5		90
+#define AIC32X4_LAGC6		91
+#define AIC32X4_LAGC7		92
+#define AIC32X4_RAGC1		94
+#define AIC32X4_RAGC2		95
+#define AIC32X4_RAGC3		96
+#define AIC32X4_RAGC4		97
+#define AIC32X4_RAGC5		98
+#define AIC32X4_RAGC6		99
+#define AIC32X4_RAGC7		100
+#define AIC32X4_PWRCFG		(AIC32X4_PAGE1 + 1)
+#define AIC32X4_LDOCTL		(AIC32X4_PAGE1 + 2)
+#define AIC32X4_OUTPWRCTL	(AIC32X4_PAGE1 + 9)
+#define AIC32X4_CMMODE		(AIC32X4_PAGE1 + 10)
+#define AIC32X4_HPLROUTE	(AIC32X4_PAGE1 + 12)
+#define AIC32X4_HPRROUTE	(AIC32X4_PAGE1 + 13)
+#define AIC32X4_LOLROUTE	(AIC32X4_PAGE1 + 14)
+#define AIC32X4_LORROUTE	(AIC32X4_PAGE1 + 15)
+#define	AIC32X4_HPLGAIN		(AIC32X4_PAGE1 + 16)
+#define	AIC32X4_HPRGAIN		(AIC32X4_PAGE1 + 17)
+#define	AIC32X4_LOLGAIN		(AIC32X4_PAGE1 + 18)
+#define	AIC32X4_LORGAIN		(AIC32X4_PAGE1 + 19)
+#define AIC32X4_HEADSTART	(AIC32X4_PAGE1 + 20)
+#define AIC32X4_MICBIAS		(AIC32X4_PAGE1 + 51)
+#define AIC32X4_LMICPGAPIN	(AIC32X4_PAGE1 + 52)
+#define AIC32X4_LMICPGANIN	(AIC32X4_PAGE1 + 54)
+#define AIC32X4_RMICPGAPIN	(AIC32X4_PAGE1 + 55)
+#define AIC32X4_RMICPGANIN	(AIC32X4_PAGE1 + 57)
+#define AIC32X4_FLOATINGINPUT	(AIC32X4_PAGE1 + 58)
+#define AIC32X4_LMICPGAVOL	(AIC32X4_PAGE1 + 59)
+#define AIC32X4_RMICPGAVOL	(AIC32X4_PAGE1 + 60)
+
+#define AIC32X4_FREQ_12000000 12000000
+#define AIC32X4_FREQ_24000000 24000000
+#define AIC32X4_FREQ_25000000 25000000
+
+#define AIC32X4_WORD_LEN_16BITS		0x00
+#define AIC32X4_WORD_LEN_20BITS		0x01
+#define AIC32X4_WORD_LEN_24BITS		0x02
+#define AIC32X4_WORD_LEN_32BITS		0x03
+
+#define AIC32X4_I2S_MODE		0x00
+#define AIC32X4_DSP_MODE		0x01
+#define AIC32X4_RIGHT_JUSTIFIED_MODE	0x02
+#define AIC32X4_LEFT_JUSTIFIED_MODE	0x03
+
+#define AIC32X4_AVDDWEAKDISABLE		0x08
+#define AIC32X4_LDOCTLEN		0x01
+
+#define AIC32X4_LDOIN_18_36		0x01
+#define AIC32X4_LDOIN2HP		0x02
+
+#define AIC32X4_DACSPBLOCK_MASK		0x1f
+#define AIC32X4_ADCSPBLOCK_MASK		0x1f
+
+#define AIC32X4_PLLJ_SHIFT		6
+#define AIC32X4_DOSRMSB_SHIFT		4
+
+#define AIC32X4_PLLCLKIN		0x03
+
+#define AIC32X4_LMICPGANIN_IN2R_10K	0x10
+#define AIC32X4_RMICPGANIN_IN1L_10K	0x10
+
+#define AIC32X4_LMICPGAVOL_NOGAIN	0x80
+#define AIC32X4_RMICPGAVOL_NOGAIN	0x80
+
+#define AIC32X4_BCLKMASTER		0x08
+#define AIC32X4_WCLKMASTER		0x04
+#define AIC32X4_PLLEN			(0x01 << 7)
+#define AIC32X4_NDACEN			(0x01 << 7)
+#define AIC32X4_MDACEN			(0x01 << 7)
+#define AIC32X4_NADCEN			(0x01 << 7)
+#define AIC32X4_MADCEN			(0x01 << 7)
+#define AIC32X4_BCLKEN			(0x01 << 7)
+#define AIC32X4_DACEN			(0x03 << 6)
+#define AIC32X4_LDAC2LCHN		(0x01 << 4)
+#define AIC32X4_RDAC2RCHN		(0x01 << 2)
+
+#define AIC32X4_SSTEP2WCLK		0x01
+#define AIC32X4_MUTEON			0x0C
+#define	AIC32X4_DACMOD2BCLK		0x01
+
+#endif				/* _TLV320AIC32X4_H */
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 6/6] eukrea_mbimxsd51: add SD Card detect
From: Eric Bénard @ 2011-02-25 13:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-1-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
index fe70e76..04927ff 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -103,6 +103,10 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	MX51_PAD_DI1_D1_CS__GPIO3_4,
 	/* LCD RST */
 	MX51_PAD_CSI1_D9__GPIO3_13,
+	/* SD1 CD */
+	_MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+			PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
 };
 
 #define GPIO_LED1	IMX_GPIO_NR(3, 30)
-- 
1.7.4

^ permalink raw reply related

* [PATCH 5/6] eukrea_mbimxsd51: add IPU support
From: Eric Bénard @ 2011-02-25 13:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-1-git-send-email-eric@eukrea.com>

- TFT lcd or DVI output selection
- if a TFT is used, add backight and lcd platform data

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/Kconfig                    |    1 +
 arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c |  131 ++++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index ded1d2d..c50089b 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -109,6 +109,7 @@ config MACH_EUKREA_MBIMXSD51_BASEBOARD
 	bool
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 	select IMX_HAVE_PLATFORM_IMX_SSI
+	select IMX_HAVE_PLATFORM_IMX_IPUV3
 	help
 	  This adds board specific devices that can be found on Eukrea's
 	  MBIMXSD evaluation board.
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
index 712061c..fe70e76 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -30,6 +30,11 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
+#include <linux/mfd/imx-ipu-v3.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <video/platform_lcd.h>
+#include <linux/backlight.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -41,6 +46,7 @@
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx51.h>
 #include <mach/audmux.h>
+#include <mach/ipu-v3.h>
 
 #include "devices-imx51.h"
 #include "devices.h"
@@ -72,10 +78,78 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
 	MX51_PAD_AUD3_BB_CK__AUD3_TXC,
 	MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
+	/* LCD */
+	MX51_PAD_DISP1_DAT0__DISP1_DAT0,
+	MX51_PAD_DISP1_DAT1__DISP1_DAT1,
+	MX51_PAD_DISP1_DAT2__DISP1_DAT2,
+	MX51_PAD_DISP1_DAT3__DISP1_DAT3,
+	MX51_PAD_DISP1_DAT4__DISP1_DAT4,
+	MX51_PAD_DISP1_DAT5__DISP1_DAT5,
+	MX51_PAD_DISP1_DAT6__DISP1_DAT6,
+	MX51_PAD_DISP1_DAT7__DISP1_DAT7,
+	MX51_PAD_DISP1_DAT8__DISP1_DAT8,
+	MX51_PAD_DISP1_DAT9__DISP1_DAT9,
+	MX51_PAD_DISP1_DAT10__DISP1_DAT10,
+	MX51_PAD_DISP1_DAT11__DISP1_DAT11,
+	MX51_PAD_DISP1_DAT12__DISP1_DAT12,
+	MX51_PAD_DISP1_DAT13__DISP1_DAT13,
+	MX51_PAD_DISP1_DAT14__DISP1_DAT14,
+	MX51_PAD_DISP1_DAT15__DISP1_DAT15,
+	MX51_PAD_DISP1_DAT16__DISP1_DAT16,
+	MX51_PAD_DISP1_DAT17__DISP1_DAT17,
+	MX51_PAD_DI1_PIN3__DI1_PIN3,
+	MX51_PAD_DI1_PIN2__DI1_PIN2,
+	/* LCD Backlight */
+	MX51_PAD_DI1_D1_CS__GPIO3_4,
+	/* LCD RST */
+	MX51_PAD_CSI1_D9__GPIO3_13,
 };
 
 #define GPIO_LED1	IMX_GPIO_NR(3, 30)
 #define GPIO_SWITCH1	IMX_GPIO_NR(3, 31)
+#define GPIO_LCDRST	IMX_GPIO_NR(3, 13)
+#define GPIO_LCDBL	IMX_GPIO_NR(3, 4)
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power)
+		gpio_direction_output(GPIO_LCDRST, 1);
+	else
+		gpio_direction_output(GPIO_LCDRST, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+	.set_power		= eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.platform_data	= &eukrea_mbimxsd_lcd_power_data,
+};
+
+static void eukrea_mbimxsd_bl_set_intensity(int intensity)
+{
+	if (intensity)
+		gpio_direction_output(GPIO_LCDBL, 1);
+	else
+		gpio_direction_output(GPIO_LCDBL, 0);
+}
+
+static struct generic_bl_info eukrea_mbimxsd_bl_info = {
+	.name			= "eukrea_mbimxsd-bl",
+	.max_intensity		= 0xff,
+	.default_intensity	= 0xff,
+	.set_bl_intensity	= eukrea_mbimxsd_bl_set_intensity,
+};
+
+static struct platform_device eukrea_mbimxsd_bl_dev = {
+	.name			= "generic-bl",
+	.id			= 1,
+	.dev = {
+		.platform_data	= &eukrea_mbimxsd_bl_info,
+	},
+};
 
 static struct gpio_led eukrea_mbimxsd_leds[] = {
 	{
@@ -138,6 +212,50 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
 	},
 };
 
+static struct fb_videomode fb_modedb[] = {
+	{
+		.name		= "CMO-QVGA",
+		.refresh	= 60,
+		.xres		= 320,
+		.yres		= 240,
+		.pixclock	= KHZ2PICOS(6500),
+		.left_margin	= 68,
+		.right_margin	= 20,
+		.upper_margin	= 15,
+		.lower_margin	= 4,
+		.hsync_len	= 30,
+		.vsync_len	= 3,
+		.sync		= FB_SYNC_OE_LOW_ACT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+};
+
+static struct ipuv3_fb_platform_data eukrea_mbimxsd_fb0_data = {
+	.interface_pix_fmt = IPU_PIX_FMT_RGB666,
+	.flags = IMX_IPU_FB_USE_MODEDB,
+	.modes = fb_modedb,
+	.num_modes = ARRAY_SIZE(fb_modedb),
+	.display = 0,
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+	.fb_head0_platform_data = &eukrea_mbimxsd_fb0_data,
+};
+
+static int screen_type;
+
+static int __init eukrea_mbimx51sd_screen_type(char *options)
+{
+	if (!strcmp(options, "dvi"))
+		screen_type = 1;
+	else if (!strcmp(options, "tft"))
+		screen_type = 0;
+
+	return 0;
+}
+__setup("screen_type=", eukrea_mbimx51sd_screen_type);
+
 static const
 struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
 	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
@@ -186,8 +304,21 @@ void __init eukrea_mbimxsd51_baseboard_init(void)
 	gpio_direction_input(GPIO_SWITCH1);
 	gpio_free(GPIO_SWITCH1);
 
+	gpio_request(GPIO_LCDRST, "LCDRST");
+	gpio_direction_output(GPIO_LCDRST, 0);
+	gpio_free(GPIO_LCDRST);
+	gpio_request(GPIO_LCDBL, "LCDBL");
+	gpio_direction_output(GPIO_LCDBL, 0);
+	gpio_free(GPIO_LCDBL);
+	if (!screen_type) {
+		platform_device_register(&eukrea_mbimxsd_bl_dev);
+		platform_device_register(&eukrea_mbimxsd_lcd_powerdev);
+	}
+
 	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
 				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
 
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+	imx51_add_ipuv3(&ipu_data);
 }
-- 
1.7.4

^ permalink raw reply related

* [PATCH 4/6] cpuimx51sd: mcp2515 supports up to 10MHz SPI clock
From: Eric Bénard @ 2011-02-25 13:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-1-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/board-cpuimx51sd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
index 5b19419..4d4e8e4 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -237,7 +237,7 @@ static struct mcp251x_platform_data mcp251x_info = {
 static struct spi_board_info cpuimx51sd_spi_device[] = {
 	{
 		.modalias        = "mcp2515",
-		.max_speed_hz    = 6500000,
+		.max_speed_hz    = 10000000,
 		.bus_num         = 0,
 		.mode		= SPI_MODE_0,
 		.chip_select     = 0,
-- 
1.7.4

^ permalink raw reply related

* [PATCH 3/6] cpuimx51sd: fix tsc2007
From: Eric Bénard @ 2011-02-25 13:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-1-git-send-email-eric@eukrea.com>

- wrong MUX was set before for IRQ
- get_pendown_state is no more needed

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/board-cpuimx51sd.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
index 68ecfc0..5b19419 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -110,7 +110,7 @@ static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = {
 
 	/* Touchscreen */
 	/* IRQ */
-	_MX51_PAD_CSI1_D8__GPIO3_12 | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+	MX51_PAD_GPIO_NAND__GPIO_NAND | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
 			PAD_CTL_PKE | PAD_CTL_SRE_FAST |
 			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
 };
@@ -119,15 +119,9 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
-static int ts_get_pendown_state(void)
-{
-	return gpio_get_value(TSC2007_IRQGPIO) ? 0 : 1;
-}
-
 static struct tsc2007_platform_data tsc2007_info = {
 	.model			= 2007,
 	.x_plate_ohms		= 180,
-	.get_pendown_state	= ts_get_pendown_state,
 };
 
 static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = {
-- 
1.7.4

^ permalink raw reply related

* [PATCH 2/6] cpuimx51sd: add cpufreq support
From: Eric Bénard @ 2011-02-25 13:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298641111-12957-1-git-send-email-eric@eukrea.com>

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/board-cpuimx51sd.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
index b89afba..68ecfc0 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -42,6 +42,7 @@
 
 #include "devices-imx51.h"
 #include "devices.h"
+#include "cpu_op-mx51.h"
 
 #define USBH1_RST		IMX_GPIO_NR(2, 28)
 #define ETH_RST			IMX_GPIO_NR(2, 31)
@@ -269,6 +270,10 @@ static void __init eukrea_cpuimx51sd_init(void)
 	mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
 					ARRAY_SIZE(eukrea_cpuimx51sd_pads));
 
+#if defined(CONFIG_CPU_FREQ_IMX)
+	get_cpu_op = mx51_get_cpu_op;
+#endif
+
 	imx51_add_imx_uart(0, &uart_pdata);
 	imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info);
 
-- 
1.7.4

^ permalink raw reply related

* [PATCH 1/6] eukrea_mbimxsd: add audio support
From: Eric Bénard @ 2011-02-25 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/Kconfig                    |    1 +
 arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c |   28 ++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 4e4d7af..ded1d2d 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -108,6 +108,7 @@ config MACH_EUKREA_MBIMXSD51_BASEBOARD
 	prompt "Eukrea MBIMXSD development board"
 	bool
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	select IMX_HAVE_PLATFORM_IMX_SSI
 	help
 	  This adds board specific devices that can be found on Eukrea's
 	  MBIMXSD evaluation board.
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
index c372a43..712061c 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -67,6 +67,11 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	MX51_PAD_SD1_DATA1__SD1_DATA1,
 	MX51_PAD_SD1_DATA2__SD1_DATA2,
 	MX51_PAD_SD1_DATA3__SD1_DATA3,
+	/* SSI */
+	MX51_PAD_AUD3_BB_TXD__AUD3_TXD,
+	MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
+	MX51_PAD_AUD3_BB_CK__AUD3_TXC,
+	MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
 };
 
 #define GPIO_LED1	IMX_GPIO_NR(3, 30)
@@ -133,6 +138,11 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
 	},
 };
 
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
+	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
+};
+
 /*
  * system init for baseboard usage. Will be called by cpuimx51sd init.
  *
@@ -145,10 +155,28 @@ void __init eukrea_mbimxsd51_baseboard_init(void)
 			ARRAY_SIZE(eukrea_mbimxsd_pads)))
 		printk(KERN_ERR "error setting mbimxsd pads !\n");
 
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
+	/* SSI unit master I2S codec connected to SSI_AUD3 */
+	mxc_audmux_v2_configure_port(0,
+			MXC_AUDMUX_V2_PTCR_SYN |
+			MXC_AUDMUX_V2_PTCR_TFSDIR |
+			MXC_AUDMUX_V2_PTCR_TFSEL(2) |
+			MXC_AUDMUX_V2_PTCR_TCLKDIR |
+			MXC_AUDMUX_V2_PTCR_TCSEL(2),
+			MXC_AUDMUX_V2_PDCR_RXDSEL(2)
+	);
+	mxc_audmux_v2_configure_port(2,
+			MXC_AUDMUX_V2_PTCR_SYN |
+			MXC_AUDMUX_V2_PTCR_TCSEL(0),
+			MXC_AUDMUX_V2_PDCR_RXDSEL(0)
+	);
+#endif
+
 	imx51_add_imx_uart(1, NULL);
 	imx51_add_imx_uart(2, &uart_pdata);
 
 	imx51_add_sdhci_esdhc_imx(0, NULL);
+	imx51_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
 	gpio_request(GPIO_LED1, "LED1");
 	gpio_direction_output(GPIO_LED1, 1);
-- 
1.7.4

^ permalink raw reply related

* [PATCH v4 6/7] arm/dt: Basic tegra devicetree support
From: Sergei Shtylyov @ 2011-02-25 13:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110223213601.GA5404@angua.secretlab.ca>

Hello.

On 24-02-2011 0:36, Grant Likely wrote:

>>> This patch adds adds very basic support for booting tegra with a
>>> device tree.  It simply allows the existing machine_descs to match
>>> against the tegra compatible values so that the kernel can boot.
>>> Kernel parameters and the initrd pointer is read out of the tree
>>> instead of atags.

>>> This is not complete device tree support.  This change will be
>>> reverted when a new machine_desc is added that can populate the
>>> device registrations directly from data in the tree instead of using
>>> hard coded data.  That change will be made in a future patch.

>>> v2: Fixed cut-and-paste error in commit text

>>     Shouldn't this sentence follow the --- tearline?

> Nope!  It is actually quite useful for the version information to show
> up in the commit text.  That way you know *exactly* which version got
> merged.  dwmw2 pointed that out to me a few months back.

    Well, I think that depends on the patch. If you have say 9 revisions with 
significant changes (that's what I actually had) and the revision history far 
exceeds the original patch description, then this will just become too ugly I 
think...

WBR, Sergei

^ permalink raw reply

* [PATCH 2/4] msm: scm: Fix improper register assignment
From: Will Deacon @ 2011-02-25 13:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298573085-23217-3-git-send-email-sboyd@codeaurora.org>

On Thu, 2011-02-24 at 18:44 +0000, Stephen Boyd wrote:
> Assign the registers used in the inline assembly immediately
> before the inline assembly block. This ensures the compiler
> doesn't optimize away dead register assignments when it
> shouldn't.
> 
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
>  arch/arm/mach-msm/scm.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
> index ba57b5a..5eddf54 100644
> --- a/arch/arm/mach-msm/scm.c
> +++ b/arch/arm/mach-msm/scm.c
> @@ -264,13 +264,16 @@ u32 scm_get_version(void)
>  {
>         int context_id;
>         static u32 version = -1;
> -       register u32 r0 asm("r0") = 0x1 << 8;
> -       register u32 r1 asm("r1") = (u32)&context_id;
> +       register u32 r0 asm("r0");
> +       register u32 r1 asm("r1");
> 
>         if (version != -1)
>                 return version;
> 
>         mutex_lock(&scm_lock);
> +
> +       r0 = 0x1 << 8;
> +       r1 = (u32)&context_id;
>         asm volatile(
>                 __asmeq("%0", "r1")
>                 __asmeq("%1", "r0")


Whoa, have you seen the compiler `optimise' the original assignments
away? Since there is a use in the asm block, the definition shouldn't
be omitted. What toolchain are you using?

Will

^ permalink raw reply

* [PATCH v4 2/2] Defines DA850/AM18xx/OMAPL1-38 SOC resources used by PRUSS UIO driver
From: Sergei Shtylyov @ 2011-02-25 13:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110225130241.GA2791@local>

Hello.

On 25-02-2011 16:02, Hans J. Koch wrote:

>>> This patch defines PRUSS, ECAP clocks, memory and IRQ resources
>>> used by PRUSS UIO driver in DA850/AM18xx/OMAPL1-38 devices. UIO

>>     It's OMAP-L138.

> From the TI wiki: "The PRU subsystem is supported on
> OMAP-L1x8/C674m/AM18xx devices (where m is an even number)."

> http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit_Subsystem

    I meant there's a typo in "OMAPL1-38".

> Thanks,
> Hans

WBR, Sergei

^ permalink raw reply

* [PATCH] davinci: da850/omap-l138: Add Carrier Link OK check in Davinci RX Handler
From: Cyril Chemparathy @ 2011-02-25 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298627788-32339-1-git-send-email-vinay.hegde@ti.com>

On 02/25/2011 04:56 AM, Hegde, Vinay wrote:
> This patch adds an additional check in the Davinci EMAC RX Handler,
> which tests the __LINK_STATE_NOCARRIER flag along with the
> __LINK_STATE_START flag as part EMAC shutting down procedure.
> 
> This avoids
> WARNING: at drivers/net/davinci_emac.c:1040 emac_rx_handler+0xf8/0x120()
> during rtcwake used to suspend the target for a specified duration.
> 
> Signed-off-by: Hegde, Vinay <vinay.hegde@ti.com>
> ---
>  drivers/net/davinci_emac.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
> index 2a628d1..7018bfe 100644
> --- a/drivers/net/davinci_emac.c
> +++ b/drivers/net/davinci_emac.c
> @@ -1008,7 +1008,7 @@ static void emac_rx_handler(void *token, int len, int status)
>  	int			ret;
>  
>  	/* free and bail if we are shutting down */
> -	if (unlikely(!netif_running(ndev))) {
> +	if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) {
>  		dev_kfree_skb_any(skb);
>  		return;
>  	}

Looks ok.

Acked-by: Cyril Chemparathy <cyril@ti.com>

^ permalink raw reply

* [PATCH] ARM: S5P: Add platform helpers for camera GPIO configuration
From: Sylwester Nawrocki @ 2011-02-25 13:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297447665-19492-2-git-send-email-s.nawrocki@samsung.com>


On 02/11/2011 07:07 PM, Sylwester Nawrocki wrote:
> Add functions for the parallel camera GPIO interface
> configuration on S5PV210 and S5PV310 SoCs.
> 

Kukjin, are you OK with general concept of those?
I would probably need to rework the patches after recent
S5PV310 -> EXYNOS4 renaming. And move camera.h 
to arch/arm/plat-samsung/include/plat/?

What's your opinion?

Thanks,
-- 
Sylwester Nawrocki
Samsung Poland R&D Center

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox