diff options
Diffstat (limited to 'meta/packages')
-rw-r--r-- | meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch | 75 | ||||
-rw-r--r-- | meta/packages/linux/linux-rp-2.6.23/zylonite_touch-r0.patch | 1548 | ||||
-rw-r--r-- | meta/packages/linux/linux-rp_2.6.23.bb | 3 |
3 files changed, 1603 insertions, 23 deletions
diff --git a/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch b/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch index 231b3d76c9..cb5a9c5f72 100644 --- a/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch +++ b/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch | |||
@@ -4,8 +4,8 @@ Flash driver forward ported to 2.6.14 | |||
4 | 4 | ||
5 | Index: linux-2.6.23/drivers/mtd/nand/Kconfig | 5 | Index: linux-2.6.23/drivers/mtd/nand/Kconfig |
6 | =================================================================== | 6 | =================================================================== |
7 | --- linux-2.6.23.orig/drivers/mtd/nand/Kconfig 2008-02-12 18:02:36.000000000 +0000 | 7 | --- linux-2.6.23.orig/drivers/mtd/nand/Kconfig 2007-10-09 21:31:38.000000000 +0100 |
8 | +++ linux-2.6.23/drivers/mtd/nand/Kconfig 2008-02-12 18:03:07.000000000 +0000 | 8 | +++ linux-2.6.23/drivers/mtd/nand/Kconfig 2008-02-13 00:59:45.000000000 +0000 |
9 | @@ -223,6 +223,10 @@ | 9 | @@ -223,6 +223,10 @@ |
10 | tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" | 10 | tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" |
11 | depends on ARCH_PXA | 11 | depends on ARCH_PXA |
@@ -19,8 +19,8 @@ Index: linux-2.6.23/drivers/mtd/nand/Kconfig | |||
19 | depends on BASLER_EXCITE | 19 | depends on BASLER_EXCITE |
20 | Index: linux-2.6.23/drivers/mtd/nand/Makefile | 20 | Index: linux-2.6.23/drivers/mtd/nand/Makefile |
21 | =================================================================== | 21 | =================================================================== |
22 | --- linux-2.6.23.orig/drivers/mtd/nand/Makefile 2008-02-12 18:02:36.000000000 +0000 | 22 | --- linux-2.6.23.orig/drivers/mtd/nand/Makefile 2007-10-09 21:31:38.000000000 +0100 |
23 | +++ linux-2.6.23/drivers/mtd/nand/Makefile 2008-02-12 18:03:27.000000000 +0000 | 23 | +++ linux-2.6.23/drivers/mtd/nand/Makefile 2008-02-13 00:59:45.000000000 +0000 |
24 | @@ -19,6 +19,7 @@ | 24 | @@ -19,6 +19,7 @@ |
25 | obj-$(CONFIG_MTD_NAND_H1900) += h1910.o | 25 | obj-$(CONFIG_MTD_NAND_H1900) += h1910.o |
26 | obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o | 26 | obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o |
@@ -32,7 +32,7 @@ Index: linux-2.6.23/drivers/mtd/nand/Makefile | |||
32 | Index: linux-2.6.23/drivers/mtd/nand/mhn_nand.c | 32 | Index: linux-2.6.23/drivers/mtd/nand/mhn_nand.c |
33 | =================================================================== | 33 | =================================================================== |
34 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | 34 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
35 | +++ linux-2.6.23/drivers/mtd/nand/mhn_nand.c 2008-02-12 23:54:00.000000000 +0000 | 35 | +++ linux-2.6.23/drivers/mtd/nand/mhn_nand.c 2008-02-13 00:59:45.000000000 +0000 |
36 | @@ -0,0 +1,3869 @@ | 36 | @@ -0,0 +1,3869 @@ |
37 | +/* | 37 | +/* |
38 | + * drivers/mtd/nand/mhn_nand.c | 38 | + * drivers/mtd/nand/mhn_nand.c |
@@ -3905,8 +3905,8 @@ Index: linux-2.6.23/drivers/mtd/nand/mhn_nand.c | |||
3905 | + | 3905 | + |
3906 | Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c | 3906 | Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c |
3907 | =================================================================== | 3907 | =================================================================== |
3908 | --- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite.c 2008-02-12 21:12:29.000000000 +0000 | 3908 | --- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite.c 2008-02-13 00:59:45.000000000 +0000 |
3909 | +++ linux-2.6.23/arch/arm/mach-pxa/zylonite.c 2008-02-13 00:50:30.000000000 +0000 | 3909 | +++ linux-2.6.23/arch/arm/mach-pxa/zylonite.c 2008-02-13 09:11:02.000000000 +0000 |
3910 | @@ -29,6 +29,8 @@ | 3910 | @@ -29,6 +29,8 @@ |
3911 | #include "generic.h" | 3911 | #include "generic.h" |
3912 | 3912 | ||
@@ -3916,7 +3916,7 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c | |||
3916 | int gpio_eth_irq; | 3916 | int gpio_eth_irq; |
3917 | 3917 | ||
3918 | int lcd_id; | 3918 | int lcd_id; |
3919 | @@ -54,6 +56,11 @@ | 3919 | @@ -54,6 +56,16 @@ |
3920 | .resource = smc91x_resources, | 3920 | .resource = smc91x_resources, |
3921 | }; | 3921 | }; |
3922 | 3922 | ||
@@ -3925,10 +3925,15 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c | |||
3925 | + .id = -1, | 3925 | + .id = -1, |
3926 | +}; | 3926 | +}; |
3927 | + | 3927 | + |
3928 | +static struct platform_device touch_device = { | ||
3929 | + .name = "pxa2xx-touch", | ||
3930 | + .id = -1, | ||
3931 | +}; | ||
3932 | + | ||
3928 | #if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES) | 3933 | #if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES) |
3929 | static void zylonite_backlight_power(int on) | 3934 | static void zylonite_backlight_power(int on) |
3930 | { | 3935 | { |
3931 | @@ -96,7 +103,7 @@ | 3936 | @@ -96,7 +108,7 @@ |
3932 | }; | 3937 | }; |
3933 | 3938 | ||
3934 | static struct pxafb_mode_info sharp_ls037_modes[] = { | 3939 | static struct pxafb_mode_info sharp_ls037_modes[] = { |
@@ -3937,7 +3942,7 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c | |||
3937 | .pixclock = 158000, | 3942 | .pixclock = 158000, |
3938 | .xres = 240, | 3943 | .xres = 240, |
3939 | .yres = 320, | 3944 | .yres = 320, |
3940 | @@ -109,8 +116,8 @@ | 3945 | @@ -109,8 +121,8 @@ |
3941 | .lower_margin = 3, | 3946 | .lower_margin = 3, |
3942 | .sync = 0, | 3947 | .sync = 0, |
3943 | }, | 3948 | }, |
@@ -3948,7 +3953,7 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c | |||
3948 | .xres = 480, | 3953 | .xres = 480, |
3949 | .yres = 640, | 3954 | .yres = 640, |
3950 | .bpp = 16, | 3955 | .bpp = 16, |
3951 | @@ -137,6 +144,11 @@ | 3956 | @@ -137,6 +149,11 @@ |
3952 | /* backlight GPIO: output, default on */ | 3957 | /* backlight GPIO: output, default on */ |
3953 | gpio_direction_output(gpio_backlight, 1); | 3958 | gpio_direction_output(gpio_backlight, 1); |
3954 | 3959 | ||
@@ -3960,20 +3965,35 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c | |||
3960 | if (lcd_id & 0x20) { | 3965 | if (lcd_id & 0x20) { |
3961 | set_pxa_fb_info(&zylonite_sharp_lcd_info); | 3966 | set_pxa_fb_info(&zylonite_sharp_lcd_info); |
3962 | return; | 3967 | return; |
3963 | @@ -169,6 +181,8 @@ | 3968 | @@ -169,6 +186,8 @@ |
3964 | smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq); | 3969 | smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq); |
3965 | smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); | 3970 | smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); |
3966 | platform_device_register(&smc91x_device); | 3971 | platform_device_register(&smc91x_device); |
3967 | + platform_device_register(&nand_device); | 3972 | + platform_device_register(&nand_device); |
3968 | + printk(KERN_ERR "Nand device registered\n"); | 3973 | + platform_device_register(&touch_device); |
3969 | 3974 | ||
3970 | zylonite_init_lcd(); | 3975 | zylonite_init_lcd(); |
3971 | } | 3976 | } |
3972 | Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c | 3977 | Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c |
3973 | =================================================================== | 3978 | =================================================================== |
3974 | --- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-12 20:52:26.000000000 +0000 | 3979 | --- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-13 00:59:45.000000000 +0000 |
3975 | +++ linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-13 00:26:37.000000000 +0000 | 3980 | +++ linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-13 14:01:13.000000000 +0000 |
3976 | @@ -104,6 +104,30 @@ | 3981 | @@ -62,12 +62,12 @@ |
3982 | GPIO110_UART3_RXD, | ||
3983 | |||
3984 | /* AC97 */ | ||
3985 | - GPIO23_AC97_nACRESET, | ||
3986 | + /*GPIO23_AC97_nACRESET, | ||
3987 | GPIO24_AC97_SYSCLK, | ||
3988 | GPIO29_AC97_BITCLK, | ||
3989 | GPIO25_AC97_SDATA_IN_0, | ||
3990 | GPIO27_AC97_SDATA_OUT, | ||
3991 | - GPIO28_AC97_SYNC, | ||
3992 | + GPIO28_AC97_SYNC,*/ | ||
3993 | |||
3994 | /* Keypad */ | ||
3995 | GPIO107_KP_DKIN_0, | ||
3996 | @@ -104,6 +104,41 @@ | ||
3977 | /* Ethernet */ | 3997 | /* Ethernet */ |
3978 | GPIO2_nCS3, | 3998 | GPIO2_nCS3, |
3979 | GPIO99_GPIO, | 3999 | GPIO99_GPIO, |
@@ -4001,10 +4021,21 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c | |||
4001 | + MFP_CFG_X(DF_IO12, AF1, DS08X, PULL_LOW), | 4021 | + MFP_CFG_X(DF_IO12, AF1, DS08X, PULL_LOW), |
4002 | + MFP_CFG_X(DF_IO13, AF1, DS08X, PULL_LOW), | 4022 | + MFP_CFG_X(DF_IO13, AF1, DS08X, PULL_LOW), |
4003 | + MFP_CFG_X(DF_IO14, AF1, DS08X, PULL_LOW), | 4023 | + MFP_CFG_X(DF_IO14, AF1, DS08X, PULL_LOW), |
4024 | + | ||
4025 | + /* AC97 */ | ||
4026 | + MFP_CFG_X(GPIO23, AF1, DS03X, PULL_LOW), | ||
4027 | + MFP_CFG_X(GPIO27, AF1, DS03X, PULL_LOW), | ||
4028 | + MFP_CFG_X(GPIO28, AF1, DS03X, PULL_LOW), | ||
4029 | + MFP_CFG_X(GPIO29, AF1, DS03X, PULL_LOW), | ||
4030 | + MFP_CFG_X(GPIO25, AF1, DS03X, PULL_LOW), | ||
4031 | + | ||
4032 | + MFP_CFG_X(GPIO26, AF0, DS01X, PULL_LOW), /* Interrupt */ | ||
4033 | + MFP_CFG_X(GPIO24, AF0, DS03X, PULL_LOW), /*SYSCLK external */ | ||
4034 | + MFP_CFG_X(GPIO11, AF0, DS01X, PULL_LOW), | ||
4004 | }; | 4035 | }; |
4005 | 4036 | ||
4006 | static mfp_cfg_t pxa310_mfp_cfg[] __initdata = { | 4037 | static mfp_cfg_t pxa310_mfp_cfg[] __initdata = { |
4007 | @@ -163,6 +187,9 @@ | 4038 | @@ -163,6 +198,9 @@ |
4008 | pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]); | 4039 | pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]); |
4009 | } | 4040 | } |
4010 | 4041 | ||
@@ -4014,7 +4045,7 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c | |||
4014 | void __init zylonite_pxa300_init(void) | 4045 | void __init zylonite_pxa300_init(void) |
4015 | { | 4046 | { |
4016 | if (cpu_is_pxa300() || cpu_is_pxa310()) { | 4047 | if (cpu_is_pxa300() || cpu_is_pxa310()) { |
4017 | @@ -174,6 +201,8 @@ | 4048 | @@ -174,6 +212,8 @@ |
4018 | 4049 | ||
4019 | /* GPIO pin assignment */ | 4050 | /* GPIO pin assignment */ |
4020 | gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); | 4051 | gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); |
@@ -4025,8 +4056,8 @@ Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c | |||
4025 | if (cpu_is_pxa300()) { | 4056 | if (cpu_is_pxa300()) { |
4026 | Index: linux-2.6.23/drivers/video/pxafb.c | 4057 | Index: linux-2.6.23/drivers/video/pxafb.c |
4027 | =================================================================== | 4058 | =================================================================== |
4028 | --- linux-2.6.23.orig/drivers/video/pxafb.c 2008-02-13 00:05:42.000000000 +0000 | 4059 | --- linux-2.6.23.orig/drivers/video/pxafb.c 2008-02-13 00:59:45.000000000 +0000 |
4029 | +++ linux-2.6.23/drivers/video/pxafb.c 2008-02-13 00:06:02.000000000 +0000 | 4060 | +++ linux-2.6.23/drivers/video/pxafb.c 2008-02-13 00:59:45.000000000 +0000 |
4030 | @@ -1543,9 +1543,9 @@ | 4061 | @@ -1543,9 +1543,9 @@ |
4031 | if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) | 4062 | if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) |
4032 | dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n", | 4063 | dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n", |
@@ -4042,8 +4073,8 @@ Index: linux-2.6.23/drivers/video/pxafb.c | |||
4042 | (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || | 4073 | (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || |
4043 | Index: linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h | 4074 | Index: linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h |
4044 | =================================================================== | 4075 | =================================================================== |
4045 | --- linux-2.6.23.orig/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:44:38.000000000 +0000 | 4076 | --- linux-2.6.23.orig/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:59:45.000000000 +0000 |
4046 | +++ linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:49:38.000000000 +0000 | 4077 | +++ linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:59:45.000000000 +0000 |
4047 | @@ -175,13 +175,13 @@ | 4078 | @@ -175,13 +175,13 @@ |
4048 | #define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X) | 4079 | #define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X) |
4049 | #define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X) | 4080 | #define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X) |
diff --git a/meta/packages/linux/linux-rp-2.6.23/zylonite_touch-r0.patch b/meta/packages/linux/linux-rp-2.6.23/zylonite_touch-r0.patch new file mode 100644 index 0000000000..1c00696051 --- /dev/null +++ b/meta/packages/linux/linux-rp-2.6.23/zylonite_touch-r0.patch | |||
@@ -0,0 +1,1548 @@ | |||
1 | Index: linux-2.6.23/drivers/input/touchscreen/Kconfig | ||
2 | =================================================================== | ||
3 | --- linux-2.6.23.orig/drivers/input/touchscreen/Kconfig 2008-02-13 01:12:29.000000000 +0000 | ||
4 | +++ linux-2.6.23/drivers/input/touchscreen/Kconfig 2008-02-13 01:13:20.000000000 +0000 | ||
5 | @@ -54,6 +54,12 @@ | ||
6 | To compile this driver as a module, choose M here: the | ||
7 | module will be called corgi_ts. | ||
8 | |||
9 | +config TOUCHSCREEN_ZYLONITE | ||
10 | + tristate "Zylonite touchscreen driver" | ||
11 | + default y | ||
12 | + help | ||
13 | + Say Y here for the Zylonite touchscreen driver | ||
14 | + | ||
15 | config TOUCHSCREEN_FUJITSU | ||
16 | tristate "Fujitsu serial touchscreen" | ||
17 | select SERIO | ||
18 | Index: linux-2.6.23/drivers/input/touchscreen/Makefile | ||
19 | =================================================================== | ||
20 | --- linux-2.6.23.orig/drivers/input/touchscreen/Makefile 2008-02-13 01:12:29.000000000 +0000 | ||
21 | +++ linux-2.6.23/drivers/input/touchscreen/Makefile 2008-02-13 01:13:38.000000000 +0000 | ||
22 | @@ -19,3 +19,4 @@ | ||
23 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | ||
24 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | ||
25 | obj-$(CONFIG_TOUCHSCREEN_TSC2101) += tsc2101_ts.o | ||
26 | +obj-$(CONFIG_TOUCHSCREEN_ZYLONITE) += zylonite-ts.o | ||
27 | Index: linux-2.6.23/drivers/input/touchscreen/zylonite-ts.c | ||
28 | =================================================================== | ||
29 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
30 | +++ linux-2.6.23/drivers/input/touchscreen/zylonite-ts.c 2008-02-13 16:19:15.000000000 +0000 | ||
31 | @@ -0,0 +1,1517 @@ | ||
32 | +/* | ||
33 | + * drivers/input/touchscreen/mhn_audio_touch.c. | ||
34 | + * | ||
35 | + * Author: bridge.wu@marvell.com | ||
36 | + * Created: Nov 17, 2006 | ||
37 | + * Copyright: Marvell Corporation. | ||
38 | + * | ||
39 | + * This program is free software; you can redistribute it and/or modify | ||
40 | + * it under the terms of the GNU General Public License version 2 as | ||
41 | + * published by the Free Software Foundation. | ||
42 | + */ | ||
43 | +#include <linux/init.h> | ||
44 | +#include <linux/module.h> | ||
45 | +#include <linux/kernel.h> | ||
46 | +#include <linux/device.h> | ||
47 | +#include <linux/platform_device.h> | ||
48 | +#include <linux/interrupt.h> | ||
49 | +#include <linux/delay.h> | ||
50 | + | ||
51 | +#include <sound/driver.h> | ||
52 | +#include <sound/core.h> | ||
53 | +#include <sound/pcm.h> | ||
54 | +#include <sound/initval.h> | ||
55 | + | ||
56 | +#include <asm/semaphore.h> | ||
57 | +#include <asm/hardware.h> | ||
58 | +#include <asm/arch/pxa-regs.h> | ||
59 | +#include <asm/arch/gpio.h> | ||
60 | +#include <asm/arch/mfp.h> | ||
61 | +//#include <asm/arch/ipmc.h> | ||
62 | +#include <linux/suspend.h> | ||
63 | +#include <linux/spinlock.h> | ||
64 | + | ||
65 | +//#include <asm/arch/codec/acodec.h> | ||
66 | +//#include <asm/arch/mhn_audio_plat.h> | ||
67 | + | ||
68 | +#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */ | ||
69 | +#define AC97_DIV __REG(0x41340014) | ||
70 | + | ||
71 | +#define ALSA_ZY_CARD_DEBUG | ||
72 | +#undef ALSA_ZY_CARD_DEBUG | ||
73 | + | ||
74 | +#define WM_9713_ID 0x4C13 /* this should be the 7E register value */ | ||
75 | + | ||
76 | +#ifdef ALSA_ZY_CARD_DEBUG | ||
77 | +#define dbg(format, arg...) printk(KERN_DEBUG format, ##arg) | ||
78 | +#else | ||
79 | +#define dbg(format, arg...) | ||
80 | +#endif | ||
81 | + | ||
82 | +#define DEBUG | ||
83 | +#undef DEBUG | ||
84 | +#ifdef DEBUG | ||
85 | +unsigned int start_time; | ||
86 | +unsigned int end_time; | ||
87 | +unsigned int time; | ||
88 | +#define PRINT_TIME() do {\ | ||
89 | + time = ((end_time > start_time))?\ | ||
90 | + (end_time - start_time)*100/325:\ | ||
91 | + (0xffffffff - start_time + end_time)*100/325;\ | ||
92 | + printk("\n%s:%dus\n", __FUNCTION__, time);\ | ||
93 | +} while(0) | ||
94 | +#endif | ||
95 | + | ||
96 | + | ||
97 | + | ||
98 | + | ||
99 | +/* 9713 specific | ||
100 | + * Register Name Index | ||
101 | + */ | ||
102 | +#define RESET 0X00 | ||
103 | +#define SPEAKER_VOLUME 0X02 | ||
104 | +#define HEADPHONE_VOLUME 0X04 | ||
105 | +#define OUT3_OUT4_VOLUME 0X06 | ||
106 | +#define MONOVOL_MONOINPGA_ROUTE 0X08 | ||
107 | +#define LINE_IN_PGA_VOL_ROUTE 0X0A | ||
108 | +#define DAC_PGA_VOL_ROUTE 0X0C | ||
109 | +#define MIC_PGA_VOLUME 0X0E | ||
110 | +#define MIC_ROUTING 0X10 | ||
111 | +#define REC_PGA_VOL 0X12 | ||
112 | +#define REC_ROUTE_MUX_SEL 0X14 | ||
113 | +#define PCBEEP_VOL_ROUTE 0X16 | ||
114 | +#define VXDAC_VOLUME_ROUTE 0X18 | ||
115 | +#define AUX_DAC_VOL_ROUTE 0X1A | ||
116 | +#define OUTPUT_PGA_MUX 0X1C | ||
117 | +#define DAC_3D_CTRL_INV_MUX_SEL 0X1E | ||
118 | +#define DAC_TONE_CTRL 0X20 | ||
119 | +#define MIC_BIAS 0X22 | ||
120 | +#define OUTPUT_VOL_MAPPING_JACK 0X24 | ||
121 | +#define POWERDOWN_CTRL_STAT 0X26 | ||
122 | +#define EXTENDED_AUD_ID 0X28 | ||
123 | +#define EXTENDED_AUD_STAT_CTRL 0X2A | ||
124 | +#define AUDIO_DAC_RATE 0X2C | ||
125 | +#define AUX_DAC_RATE 0X2E | ||
126 | +#define AUDIO_ADC_RATE 0X32 | ||
127 | +#define PCM_CODEC_CTRL 0X36 | ||
128 | +#define SPDIF_CTRL 0X3A | ||
129 | +#define POWER_DOWN_1 0X3C | ||
130 | +#define POWER_DOWN_2 0X3E | ||
131 | +#define GENERAL_PURPOSE_WM_13 0X40 | ||
132 | +#define FAST_POWERUP_CTRL 0X42 | ||
133 | +#define MCLK_PLL_CTRL_1 0X44 | ||
134 | +#define MCLK_PLL_CTRL_2 0X46 | ||
135 | +#define GPIO_PIN_CFG 0X4C | ||
136 | +#define GPIO_PIN_POL_TYPE 0X4E | ||
137 | +#define GPIO_PIN_STICKY 0X50 | ||
138 | +#define GPIO_PIN_WAKEUP 0X52 | ||
139 | +#define GPIO_PIN_STATUS 0X54 | ||
140 | +#define GPIO_PIN_SHARING 0X56 | ||
141 | +#define GPIO_PULL_UP_DOWN_CTRL 0X58 | ||
142 | +#define ADD_FUNC_1 0X5A | ||
143 | +#define ADD_FUNC_2 0X5C | ||
144 | +#define ALC_CTRL 0X60 | ||
145 | +#define ALC_NOISE_GATE_CTRL 0X62 | ||
146 | +#define AUX_DAC_INPUT_CTRL 0X64 | ||
147 | +#define TEST_REG_1 0X68 | ||
148 | +#define TEST_REG_2 0X6A | ||
149 | +#define TEST_REG_3 0X6C | ||
150 | +#define TEST_REG_4 0X6E | ||
151 | +#define DIGITIZER_1_WM13 0x74 | ||
152 | +#define DIGITIZER_2_WM13 0x76 | ||
153 | +#define DIGITIZER_3_WM13 0x78 | ||
154 | +#define DIGITIZER_READ_BACK 0x7a | ||
155 | +#define VENDOR_ID1 0x7c | ||
156 | +#define VENDOR_ID2 0x7e | ||
157 | + | ||
158 | +#define ZY_TOUCH_SAMPLE_X 1 | ||
159 | +#define ZY_TOUCH_SAMPLE_Y 2 | ||
160 | + | ||
161 | +#define ZY_EVENT_TYPE_NONE 0 | ||
162 | +#define ZY_EVENT_TYPE_PDN 1 | ||
163 | + | ||
164 | + | ||
165 | +typedef enum _zy_acodec_error_t { | ||
166 | + ZY_ACODEC_SUCCESS = 0, /* successful completion of a function */ | ||
167 | + ZY_ACODEC_GENERAL_SW_ERR, /* null pointer to registers or other software error */ | ||
168 | + ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT, /* time-out for waiting for respponse */ | ||
169 | + ZY_ACODEC_SAMPLERATE_NOT_SUPPORTED, /* the sample rate is not supported either in controller or codec */ | ||
170 | + ZY_ACODEC_FEATURE_NO_SUPPORTED, /* this codec feature is not supported */ | ||
171 | + ZY_ACODEC_GENERAL_HW_ERR ,/* other hardware error besides time out */ | ||
172 | + ZY_ACODEC_ROUTE_NO_SUPPORTED, /* the codec can not set the route required */ | ||
173 | + ZY_ACODEC_SLEEP /* the codec is sleep */ | ||
174 | +} zy_acodec_error_t; | ||
175 | + | ||
176 | +typedef unsigned int zy_acodec_device_id_t; | ||
177 | + | ||
178 | +typedef enum _codec_state { | ||
179 | + ZY_CODEC_SLEEP = 0, | ||
180 | + ZY_CODEC_WAKEUP = 1 | ||
181 | +} acodec_state_t; | ||
182 | + | ||
183 | +typedef enum { | ||
184 | + ZY_FM = 0, | ||
185 | + ZY_MIC1 = 1, | ||
186 | + ZY_MIC2 = 2, | ||
187 | + ZY_SPEAKER =3, | ||
188 | + ZY_HEADSET =4, | ||
189 | + ZY_HANDSET =5, | ||
190 | +} vol_port_type_t; | ||
191 | + | ||
192 | +typedef struct _context_t { | ||
193 | + int use_count; /* probe/remove and suspend/resume usage count, sync among multiple devices */ | ||
194 | + zy_acodec_device_id_t acodec_id;/* - an ID that uniquely identifies the codec to be used */ | ||
195 | + unsigned long init_number; /* used by driver to track whether it is inited or not */ | ||
196 | + | ||
197 | + void *p_voice_reg; /* pointer to Monahans registers that has PCM interface to codec */ | ||
198 | + void *p_hifi_reg; /* pointer to Monahans registers that has hifi interface to codec */ | ||
199 | + void *p_ctrl_reg; /* pointer to Monahans registers that has control interface to codec */ | ||
200 | + int *p_ost_regs; /* needed for time out */ | ||
201 | + void *p_save_memory; /* pointer to a memory region to save context while suspend */ | ||
202 | + void *p_zy_scenario; /* pointer to the scenario data structure */ | ||
203 | + long u_max_read_write_time_out_ms;/* input the max time to wait in milliseconds before giving up on a read or write operation */ | ||
204 | + long u_max_setup_time_out_ms; /* input the maximum time in milliseconds to wait during initial setup of the ACODEC controller and codec */ | ||
205 | + | ||
206 | + /* member functions these pointers must be set by */ | ||
207 | + zy_acodec_error_t (* g_pfn_codec_specific_init) (struct _context_t *p_device_context); | ||
208 | + zy_acodec_error_t (* g_pfn_codec_specific_dinit) (struct _context_t *p_device_context); | ||
209 | + zy_acodec_error_t (* g_pfn_acodec_read) (struct _context_t *p_dev_context, unsigned short reg_addr, unsigned short *p_reg_value); | ||
210 | + zy_acodec_error_t (* g_pfn_acodec_write) (struct _context_t *p_dev_context, unsigned short reg_addr, unsigned short reg_value); | ||
211 | + | ||
212 | + /* add for route */ | ||
213 | + zy_acodec_error_t (* g_pfn_set_route) (struct _context_t *p_device_context, unsigned short * rout_map ,unsigned short* current_map); | ||
214 | + /* add for sleep the codec */ | ||
215 | + zy_acodec_error_t (* g_pfn_sleep_codec) (struct _context_t *p_device_context); | ||
216 | + /* add for Wake up the codec */ | ||
217 | + zy_acodec_error_t (* g_pfn_wake_codec) (struct _context_t *p_device_context); | ||
218 | + /* add for get codec state */ | ||
219 | + zy_acodec_error_t (* g_pfn_get_state) (struct _context_t *p_device_context, acodec_state_t *p_state); | ||
220 | + /* add for volume */ | ||
221 | + zy_acodec_error_t (* g_pfn_get_vol)(struct _context_t *p_device_context, vol_port_type_t port, unsigned short *gain_in_db); | ||
222 | + zy_acodec_error_t (* g_pfn_set_vol)(struct _context_t *p_device_context, vol_port_type_t port, unsigned short gain_in_db); | ||
223 | + | ||
224 | + void (* g_pfn_get_event)(struct _context_t *p_device_context, unsigned char * event_type); | ||
225 | + void (* g_pfn_event_ack)(struct _context_t *p_device_context, unsigned char event_type); | ||
226 | + zy_acodec_error_t (* g_pfn_enable_touch)(struct _context_t *p_device_context); | ||
227 | + zy_acodec_error_t (* g_pfn_disable_touch)(struct _context_t *p_device_context); | ||
228 | +} zy_acocec_context_t, *p_zy_acocec_context_t; | ||
229 | + | ||
230 | + | ||
231 | + | ||
232 | + | ||
233 | + | ||
234 | +static p_zy_acocec_context_t p_zy_codec_ctxt = NULL; | ||
235 | + | ||
236 | +#include <linux/input.h> | ||
237 | +//#include <asm/arch/codec/wm9713.h> | ||
238 | + | ||
239 | +#define PEN_DOWN 1 | ||
240 | +#define PEN_UP 0 | ||
241 | +#define TS_SAMPLE_INTERVAL 1 | ||
242 | + | ||
243 | +typedef struct { | ||
244 | + struct input_dev *idev; | ||
245 | + struct timer_list *timer; | ||
246 | + int use_count; | ||
247 | +} codec_zy_ts_t; | ||
248 | + | ||
249 | +codec_zy_ts_t codec_zy_ts; | ||
250 | + | ||
251 | +static struct input_dev *codec_zy_ts_input; | ||
252 | + | ||
253 | +#ifdef CONFIG_PM | ||
254 | +static volatile int touch_suspend = 0 ; | ||
255 | +#endif | ||
256 | + | ||
257 | +#define ZY_AC97_CODEC_REGS_NUM 0x40 | ||
258 | + | ||
259 | +typedef struct | ||
260 | +{ // Register symbol // Usage | ||
261 | + volatile unsigned long pocr; // PCM Out Control Register | ||
262 | + volatile unsigned long picr; // PCM In Control Register | ||
263 | + volatile unsigned long mccr; // Mic In Control Register | ||
264 | + volatile unsigned long gcr; // Global Control Register | ||
265 | + volatile unsigned long posr; // PCM Out Status Register | ||
266 | + volatile unsigned long pisr; // PCM In Status Register | ||
267 | + volatile unsigned long mcsr; // Mic In Status Register | ||
268 | + volatile unsigned long gsr; // Global Status Register | ||
269 | + volatile unsigned long car; // CODEC Access Register | ||
270 | + volatile unsigned long pcscr; // PCM Surround Out Control | ||
271 | + volatile unsigned long pcssr; // PCM Surround Out Status | ||
272 | + volatile unsigned long pcsdr; // PCM Surround Out Data | ||
273 | + volatile unsigned long pcclcr; // PCM Center/LFE Out Control | ||
274 | + volatile unsigned long pcclsr; // PCM Center/LFE Out Status | ||
275 | + volatile unsigned long pccldr; // PCM Center/LFE Out Data | ||
276 | + volatile unsigned long reserved1; // | ||
277 | + volatile unsigned long pcdr; // PCM FIFO Data Register | ||
278 | + volatile unsigned long reserved2 [0x7]; // 0x4050-0044 through 0x4050-005C | ||
279 | + volatile unsigned long mcdr; // Mic-in FIFO Data Register | ||
280 | + volatile unsigned long reserved3 [0x27]; // 0x4050-0064 through 0x4050-00FC | ||
281 | + volatile unsigned long mocr; // MODEM Out Control Register | ||
282 | + volatile unsigned long reserved4; | ||
283 | + volatile unsigned long micr; // MODEM In Control Register | ||
284 | + volatile unsigned long reserved5; | ||
285 | + volatile unsigned long mosr; // MODEM Out Status Register | ||
286 | + volatile unsigned long reserved6; | ||
287 | + volatile unsigned long misr; // MODEM In Status Register | ||
288 | + volatile unsigned long reserved7 [0x9]; // 0x4050-011C through 0x4050-013C | ||
289 | + volatile unsigned long modr; // MODEM FIFO Data Register | ||
290 | + volatile unsigned long reserved8 [0x2F]; // 0x4050-0144 through 0x4050-01FC | ||
291 | + // Primary Audio CODEC registers access | ||
292 | + volatile unsigned long codec_regs_primary_aud [ZY_AC97_CODEC_REGS_NUM]; | ||
293 | + // Secondary ID 01 Audio CODEC registers access | ||
294 | + volatile unsigned long codec_regs_secondary_aud [ZY_AC97_CODEC_REGS_NUM]; | ||
295 | + // Primary MODEM CODEC registers access | ||
296 | + volatile unsigned long codec_regs_primary_mdm [ZY_AC97_CODEC_REGS_NUM]; | ||
297 | + // Secondary ID 01 MODEM CODEC registers access | ||
298 | + volatile unsigned long codec_regs_secondary_mdm [ZY_AC97_CODEC_REGS_NUM]; | ||
299 | + // Secondary ID 10 MODEM CODEC registers access | ||
300 | + volatile unsigned long codec_regs_third_mdm [ZY_AC97_CODEC_REGS_NUM]; | ||
301 | + // Secondary ID 11 MODEM CODEC registers access | ||
302 | + volatile unsigned long codec_regs_fouth_mdm [ZY_AC97_CODEC_REGS_NUM]; | ||
303 | + // Secondary ID 10 Audio CODEC registers access | ||
304 | + volatile unsigned long codec_regs_third_aud [ZY_AC97_CODEC_REGS_NUM]; | ||
305 | + // Secondary ID 11 Audio CODEC registers access | ||
306 | + volatile unsigned long codec_regs_fouth_aud [ZY_AC97_CODEC_REGS_NUM]; | ||
307 | +} zy_ac97_acodec_t, *p_zy_ac97acodec_t ; | ||
308 | + | ||
309 | + | ||
310 | +/* Constants for the Global Control Register and Global Status Register */ | ||
311 | + | ||
312 | +// AC97 Global Control Register bit mask constants | ||
313 | + | ||
314 | +#define ZY_AC97_GCR_GIE_MSK (1u << 0 ) | ||
315 | +#define ZY_AC97_GCR_COLD_RESET_MSK (1u << 1 ) | ||
316 | +#define ZY_AC97_GCR_WARM_RESET_MSK (1u << 2 ) | ||
317 | +#define ZY_AC97_GCR_LINK_OFF_MSK (1u << 3 ) | ||
318 | +#define ZY_AC97_GCR_PCRSM_IEN_MSK (1u << 4 ) | ||
319 | +#define ZY_AC97_GCR_SCRSM_IEN_MSK (1u << 5 ) | ||
320 | +#define ZY_AC97_GCR_PCRDY_IEN_MSK (1u << 8 ) | ||
321 | +#define ZY_AC97_GCR_SCRDY_IEN_MSK (1u << 9 ) | ||
322 | +#define ZY_AC97_GCR_SDONE_IE_MSK (1u << 18) | ||
323 | +#define ZY_AC97_GCR_CDONE_IE_MSK (1u << 19) | ||
324 | +#define ZY_AC97_GCR_nDMAEN_MSK (1u << 24) | ||
325 | +#define ZY_AC97_GCR_CLKBPB_MSK (1u << 31) | ||
326 | +#define ZY_AC97_GCR_FRCRST_MSK (1u << 30) | ||
327 | +// Global Status Register bit mask constants | ||
328 | + | ||
329 | +#define ZY_AC97_GSR_GSCI_MSK (1u << 0 ) | ||
330 | +#define ZY_AC97_GSR_MIINT_MSK (1u << 1 ) | ||
331 | +#define ZY_AC97_GSR_MOINT_MSK (1u << 2 ) | ||
332 | +#define ZY_AC97_GSR_ACOFFD_MSK (1u << 3 ) | ||
333 | +#define ZY_AC97_GSR_PIINT_MSK (1u << 5 ) | ||
334 | +#define ZY_AC97_GSR_POINT_MSK (1u << 6 ) | ||
335 | +#define ZY_AC97_GSR_MINT_MSK (1u << 7 ) | ||
336 | +#define ZY_AC97_GSR_PCRDY_MSK (1u << 8 ) | ||
337 | +#define ZY_AC97_GSR_SCRDY_MSK (1u << 9 ) | ||
338 | +#define ZY_AC97_GSR_PCRSM_MSK (1u << 10) | ||
339 | +#define ZY_AC97_GSR_SCRSM_MSK (1u << 11) | ||
340 | +#define ZY_AC97_GSR_SLT12_BITS_MSK (7u << 12) | ||
341 | +#define ZY_AC97_GSR_RCS_ERR_MSK (1u << 15) | ||
342 | +#define ZY_AC97_GSR_SDONE_MSK (1u << 18) | ||
343 | +#define ZY_AC97_GSR_CDONE_MSK (1u << 19) | ||
344 | + | ||
345 | + | ||
346 | +// Bit mask and values for CAIP bit in car register. | ||
347 | +#define ZY_AC97_CAR_CAIP_MSK (0x1<<0) | ||
348 | +#define ZY_AC97_CAR_CAIP_LOCKED (0x1<<0) | ||
349 | +#define ZY_AC97_CAR_CAIP_CLEAR (0<<0) | ||
350 | + | ||
351 | +/* Constants for FIFO status reporting and control */ | ||
352 | + | ||
353 | +// One bit location is used to report FIFO error conditions and clear | ||
354 | +// interrupts on those conditions in the various non-global status registers. | ||
355 | + | ||
356 | +// ZY_AC97_FIFOSTAT_FIFOE is used in: | ||
357 | + // posr | ||
358 | + // pisr | ||
359 | + // mcsr | ||
360 | + // mosr | ||
361 | + // misr | ||
362 | + | ||
363 | +#define ZY_AC97_FIFOSTAT_FIFOE (1u << 4) | ||
364 | +#define ZY_AC97_FIFOSTAT_EOC (1u << 3) | ||
365 | +#define ZY_AC97_FIFOSTAT_FSR (1u << 2) | ||
366 | + | ||
367 | +// A different bit location is used to enable or disable interrupts based on | ||
368 | +// FIFO error conditions in the various non-global control registers. | ||
369 | + | ||
370 | +// ZY_AC97_FIFOCTRL_FEIE is used in: | ||
371 | + // pocr | ||
372 | + // picr | ||
373 | + // mccr | ||
374 | + // mocr | ||
375 | + // micr | ||
376 | + | ||
377 | +#define ZY_AC97_FIFOCTRL_FEIE (1u << 3) | ||
378 | +#define ZY_AC97_FIFOCTRL_FSRIE (1u << 1) | ||
379 | + | ||
380 | +/* | ||
381 | +******************************************************************************* | ||
382 | + AC'97 Codec Registers Location and Bit Definition | ||
383 | +******************************************************************************* | ||
384 | +*/ | ||
385 | + | ||
386 | +/* */ | ||
387 | + | ||
388 | + // Includes symbolic values for certain proprietary register asssignments | ||
389 | + // in AC'97 devices that might be used with ZY_AC97. | ||
390 | + | ||
391 | + // Valid for subset of R 2.1 specification. | ||
392 | + // Leading "e" in comment means it is an "expanded" register definition as | ||
393 | + // found in one or more of the Appendices A-D of the R 2.1 specification. | ||
394 | + // Appendix identifier will immediately follow the "e", such as "eA" | ||
395 | + // R/O indicates read-only | ||
396 | + // Registers not supported by the assumed controller will be commented out. | ||
397 | + | ||
398 | +#define ZY_AC97_CR_RESET_ID 0x00 // RESET CODEC TO DEFAULT, get ID info | ||
399 | +#define ZY_AC97_CR_MASTER_VOLUME 0x02 // LINE OUT VOLUME | ||
400 | +#define ZY_AC97_CR_HEADPHONE_VOLUME 0x04 // | ||
401 | +#define ZY_AC97_CR_MASTER_VOLUME_MONO 0x06 // | ||
402 | +#define ZY_AC97_CR_MASTER_TONE_R_L 0x08 // | ||
403 | +#define ZY_AC97_CR_PC_BEEP_VOLUME 0x0A // | ||
404 | +#define ZY_AC97_CR_PHONE_VOLUME 0x0C // | ||
405 | +#define ZY_AC97_CR_MIC_VOLUME 0x0E // micrOPHONE VOLUME/ AGC | ||
406 | +#define ZY_AC97_CR_LINE_IN_VOLUME 0x10 // LINE IN VOLUME | ||
407 | +#define ZY_AC97_CR_CD_VOLUME 0x12 // | ||
408 | +#define ZY_AC97_CR_VIDEO_VOLUME 0x14 // | ||
409 | +#define ZY_AC97_CR_AUX_VOLUME 0x16 // | ||
410 | +#define ZY_AC97_CR_PCM_OUT_VOLUME 0x18 // | ||
411 | +#define ZY_AC97_CR_RECORD_SELECT 0x1A // SELECT LINE IN OR micrOPHONE | ||
412 | +#define ZY_AC97_CR_RECORD_GAIN 0x1C // | ||
413 | +#define ZY_AC97_CR_RECORD_GAIN_MIC 0x1E // | ||
414 | +#define ZY_AC97_CR_GENERAL_PURPOSE 0x20 // | ||
415 | +#define ZY_AC97_CR_CONTROL_3D 0x22 // | ||
416 | +#define ZY_AC97_CR_POWERDOWN_CTRL_STAT 0x26 // POWER MANAGEMENT | ||
417 | +#define ZY_AC97_CR_E_AUDIO_ID 0x28 // eA Extended audio sprt info, R/O | ||
418 | +#define ZY_AC97_CR_E_AUDIO_CTRL_STAT 0x2A // eA Extended audio stat + control | ||
419 | + | ||
420 | +// | ||
421 | +// Audio Sample Rate Control Registers, 0x2C - 0x34 | ||
422 | +// | ||
423 | + // eA PCM Front DAC rate control | ||
424 | +#define ZY_AC97_CR_E_ASR_PCM_FRNT_DAC_RT 0x2C // (output slots 3, 4, 6) | ||
425 | +#define ZY_AC97_CR_E_ASR_PCM_LR_ADC_RT 0x32 // eA PCM L+R ADC rate control (3+4) | ||
426 | +#define ZY_AC97_CR_E_ASR_MIC_ADC_RT 0x34 // eA PCM Mic ADC rate control (5) | ||
427 | + | ||
428 | + | ||
429 | +#define ZY_AC97_CR_E_MDM_GPIO_PIN_STAT 0x54 | ||
430 | +// | ||
431 | +// 5Ah-7Ah: Vendor Reserved | ||
432 | +// | ||
433 | +// | ||
434 | +// 7Ch-7Eh: Vendor ID registers. Optional but standardized for Plug'n'Play | ||
435 | +// | ||
436 | +#define ZY_AC97_CR_VENDOR_ID1 0x7C | ||
437 | +#define ZY_AC97_CR_VENDOR_ID2 0x7E | ||
438 | + | ||
439 | +#define ZY_AC97_CR_MAX ZY_AC97_CR_VENDOR_ID2 | ||
440 | + | ||
441 | +#define ZY_AC97_CR_END_OF_LIST (ZY_AC97_CR_MAX + 2) | ||
442 | + | ||
443 | + | ||
444 | + | ||
445 | +/* Other Constants */ | ||
446 | + | ||
447 | +// For accessing the Codec mixer registers, each increment of one 32-bit word | ||
448 | +// in processor space increments the addressed mixer register by two. | ||
449 | +// This does not cause any ambiguities because only even mixer register | ||
450 | +// addresses are currently supported (AC '97 spec, R 2.2) | ||
451 | +#define ZY_AC97_CODEC_REGS_PER_WORD 2 | ||
452 | + | ||
453 | +/* Default timeout and holdtime settings */ | ||
454 | + | ||
455 | +// timeout in reading and writing codec registers through AC link | ||
456 | +#define ZY_AC97_RW_TIMEOUT_DEF 200 //unit is us | ||
457 | + | ||
458 | +// timeout in waiting for codec's ready signal during setup process | ||
459 | +#define ZY_AC97_SETUP_TIMEOUT_DEF 500 //unit is us | ||
460 | + | ||
461 | +// timeout in waiting for locking the link successfully | ||
462 | +#define ZY_AC97_LOCK_TIMEOUT_DEF 300 //unit is us | ||
463 | + | ||
464 | +// timeout in shutting down the link | ||
465 | +#define ZY_AC97_LINKOFF_TIMEOUT_DEF 500 //unit is us | ||
466 | + | ||
467 | +// holdtime for keeping nReset signal active(low) in AC link | ||
468 | +#define ZY_AC97_COLD_HOLDTIME 100 //unit is us | ||
469 | + | ||
470 | +/* | ||
471 | +******************************************************************************* | ||
472 | + ZY AC97 data structure used in function interface | ||
473 | +******************************************************************************* | ||
474 | +*/ | ||
475 | + | ||
476 | +typedef struct | ||
477 | +{ | ||
478 | + unsigned long pocr; // PCM Out Control Register | ||
479 | + unsigned long picr; // PCM In Control Register | ||
480 | + unsigned long mccr; // Mic In Control Register | ||
481 | + unsigned long gcr; // Global Control Register | ||
482 | + unsigned long pcscr; // PCM Surround Out Control | ||
483 | + unsigned long pcclcr; // PCM Center/LFE Out Control | ||
484 | + unsigned long mocr; // MODEM Out Control Register | ||
485 | + unsigned long micr; // MODEM In Control Register | ||
486 | +}zy_ac97_save_context_t; | ||
487 | + | ||
488 | + | ||
489 | +#define AC97_SAVE_CONTEXT_SIZE (sizeof(zy_ac97_save_context_t)) | ||
490 | + | ||
491 | +static int zy_ac97_acodec_link_lock(p_zy_ac97acodec_t p_ac97_reg) | ||
492 | +{ | ||
493 | + int status = 1; | ||
494 | + volatile unsigned long car_tmp; | ||
495 | + | ||
496 | + car_tmp = p_ac97_reg->car; | ||
497 | + if (car_tmp & ZY_AC97_CAR_CAIP_MSK) /* "1" in CAIP bit means lock failed. */ | ||
498 | + { | ||
499 | + status = 0; | ||
500 | + } | ||
501 | + return (status); | ||
502 | +} | ||
503 | + | ||
504 | + | ||
505 | +zy_acodec_error_t zy_ac97_acodec_write (zy_acocec_context_t *p_dev_context, unsigned short offset, unsigned short data) | ||
506 | +{ | ||
507 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
508 | + int got_link; | ||
509 | + unsigned long time_remaining; | ||
510 | + volatile unsigned long * p_codec_reg; | ||
511 | + p_zy_ac97acodec_t p_ac97_reg = (p_zy_ac97acodec_t)(p_dev_context->p_ctrl_reg); | ||
512 | + unsigned long max_rw_time_out_us = (p_dev_context->u_max_read_write_time_out_ms) * 1000; | ||
513 | + | ||
514 | + | ||
515 | + if(offset == ZY_AC97_CR_E_MDM_GPIO_PIN_STAT) | ||
516 | + {/* it is a special register and sent out on slot 12 */ | ||
517 | + p_codec_reg = &(p_ac97_reg->codec_regs_primary_mdm[0]); | ||
518 | + p_codec_reg += offset / ZY_AC97_CODEC_REGS_PER_WORD; | ||
519 | + /* The data will be sent out on slot 12. */ | ||
520 | + *p_codec_reg = (unsigned long)data; | ||
521 | + goto done; | ||
522 | + } | ||
523 | + | ||
524 | + /* Point to specified register within area mapped to target codec regs */ | ||
525 | + p_codec_reg = &(p_ac97_reg->codec_regs_primary_aud[0]); | ||
526 | + p_codec_reg += offset / ZY_AC97_CODEC_REGS_PER_WORD; | ||
527 | + | ||
528 | + | ||
529 | + /* Lock the ACLINK */ | ||
530 | + time_remaining = ZY_AC97_LOCK_TIMEOUT_DEF; | ||
531 | + do | ||
532 | + { | ||
533 | + got_link = zy_ac97_acodec_link_lock(p_ac97_reg); | ||
534 | + if (0 == got_link) /* 1 usec is a long time. Skip delay if possible. */ | ||
535 | + { | ||
536 | + udelay(1); | ||
537 | + } | ||
538 | + } /* Wait while time remaining and ACLINK not available */ | ||
539 | + while (time_remaining-- && (0 == got_link)); | ||
540 | + | ||
541 | + if (0 == got_link) /* Didn't get the ACLINK */ | ||
542 | + { | ||
543 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
544 | + printk(KERN_ERR "AC97 Write Link Timeout\n"); | ||
545 | + } | ||
546 | + else /* We got the link. Perform the write operation and don't wait. */ | ||
547 | + { | ||
548 | + /* First, clear old write status indication CDONE by writing a ONE to that bit. */ | ||
549 | + p_ac97_reg->gsr = ZY_AC97_GSR_CDONE_MSK; | ||
550 | + | ||
551 | + *p_codec_reg = (unsigned long)data; /* Now the write! */ | ||
552 | + | ||
553 | + /* Wait until write cycle is complete. There should be a way | ||
554 | + * to do this speculatively at the beginning of the procedure. | ||
555 | + * Need to discover it. Too inefficient to always wait. | ||
556 | + */ | ||
557 | + | ||
558 | + time_remaining = max_rw_time_out_us; | ||
559 | + do | ||
560 | + { | ||
561 | + udelay(1); | ||
562 | + } /* Wait while time remaining and command I/O still incomplete. */ | ||
563 | + while ( (time_remaining--) && !(p_ac97_reg->gsr & ZY_AC97_GSR_CDONE_MSK)); | ||
564 | + if (!(p_ac97_reg->gsr & ZY_AC97_GSR_CDONE_MSK)) | ||
565 | + { | ||
566 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
567 | + p_ac97_reg->car = ZY_AC97_CAR_CAIP_CLEAR; | ||
568 | + } | ||
569 | + } /* Got AC link */ | ||
570 | + | ||
571 | +done: | ||
572 | + return(status); | ||
573 | +} /* Ac97CtrlCodecWrite() */ | ||
574 | + | ||
575 | +#define CKENA __REG(0x4134000C) /* A Clock Enable Register */ | ||
576 | +#define CKENB __REG(0x41340010) | ||
577 | + | ||
578 | +zy_acodec_error_t zy_ac97_acodec_read (zy_acocec_context_t *p_dev_context, unsigned short offset, unsigned short *pdata) | ||
579 | +{ | ||
580 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
581 | + int got_link; | ||
582 | + unsigned long time_remaining; | ||
583 | + volatile unsigned long * p_codec_reg; | ||
584 | + p_zy_ac97acodec_t p_ac97_reg = (p_zy_ac97acodec_t)(p_dev_context->p_ctrl_reg); | ||
585 | + unsigned long max_rw_time_out_us = (p_dev_context->u_max_read_write_time_out_ms) * 1000; | ||
586 | + | ||
587 | + /* Point to specified register within area mapped to target codec regs */ | ||
588 | + p_codec_reg = &(p_ac97_reg->codec_regs_primary_aud[0]); | ||
589 | + p_codec_reg += offset / ZY_AC97_CODEC_REGS_PER_WORD; | ||
590 | + | ||
591 | + /* Lock the ACLINK */ | ||
592 | + time_remaining = ZY_AC97_LOCK_TIMEOUT_DEF; | ||
593 | + do | ||
594 | + { | ||
595 | + got_link = zy_ac97_acodec_link_lock(p_ac97_reg); | ||
596 | + if (0 == got_link) /* 1 usec is a long time. Skip delay if possible. */ | ||
597 | + { | ||
598 | + udelay(1); | ||
599 | + } | ||
600 | + } /* Wait while time remaining and ACLINK not available */ | ||
601 | + while (time_remaining-- && (0 == got_link)); | ||
602 | + | ||
603 | + if (0 == got_link) /* Didn't get the ACLINK */ | ||
604 | + { | ||
605 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
606 | + printk(KERN_ERR "AC97 Read Link Timeout\n"); | ||
607 | + } | ||
608 | + else /* We got the link. Perform the write operation and don't wait. */ | ||
609 | + { | ||
610 | + /* First, clear old read status indications. */ | ||
611 | + p_ac97_reg->gsr = ZY_AC97_GSR_SDONE_MSK | ZY_AC97_GSR_RCS_ERR_MSK; | ||
612 | + | ||
613 | + *pdata = (unsigned short)(*p_codec_reg); /* This is THE DUMMY READ. */ | ||
614 | + | ||
615 | + /* Wait for read I/O with codec to complete before doing real read. */ | ||
616 | + time_remaining = max_rw_time_out_us; | ||
617 | + do | ||
618 | + { | ||
619 | + udelay(1); | ||
620 | + } /* Wait while time remaining and read I/O still incomplete */ | ||
621 | + while( (time_remaining--) && (!(p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK)) ); | ||
622 | + | ||
623 | + if ((p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK) && (!(p_ac97_reg->gsr & ZY_AC97_GSR_RCS_ERR_MSK)) ) | ||
624 | + { | ||
625 | + if (p_ac97_reg->gsr & ZY_AC97_GSR_RCS_ERR_MSK) | ||
626 | + {/* timeout indicated by RCS bit */ | ||
627 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
628 | + } | ||
629 | + /* succeed in reading. clear status bits first. */ | ||
630 | + p_ac97_reg->gsr = ZY_AC97_GSR_SDONE_MSK | ZY_AC97_GSR_RCS_ERR_MSK; | ||
631 | + *pdata = (unsigned short)(*p_codec_reg); /* THE REAL READ. */ | ||
632 | + if (*pdata == 0xffff) | ||
633 | + {/* timeout indicated by returned value */ | ||
634 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
635 | + } | ||
636 | + /* check later: is second waiting really needed? */ | ||
637 | + time_remaining = max_rw_time_out_us; | ||
638 | + do | ||
639 | + { | ||
640 | + udelay(1); | ||
641 | + } /* Wait while time remaining and read I/O still incomplete */ | ||
642 | + while( (time_remaining--) && (!(p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK)) ); | ||
643 | + //printk(KERN_ERR "AC97 Read Result %d\n", (p_ac97_reg->gsr & ZY_AC97_GSR_SDONE_MSK) ); | ||
644 | + } | ||
645 | + else /* failed */ | ||
646 | + { | ||
647 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
648 | + p_ac97_reg->car = ZY_AC97_CAR_CAIP_CLEAR; | ||
649 | + //printk(KERN_ERR "AC97 Read Link Timeout2 %x %x %x\n", CKENA, OSCC, CKENB); | ||
650 | + } /* else (OK to do real read) */ | ||
651 | + | ||
652 | + } /* else (We got the link. Perform the read operations.) */ | ||
653 | + | ||
654 | + return (status); | ||
655 | +} | ||
656 | + | ||
657 | + | ||
658 | + | ||
659 | +zy_acodec_error_t zy_acodec_get_adc_sample(zy_acocec_context_t *p_device_context, unsigned short *p_sample_data, unsigned short adc_type, int *p_pen_down) | ||
660 | +{ | ||
661 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
662 | + unsigned short value; | ||
663 | + unsigned long wait; | ||
664 | + | ||
665 | + if (adc_type == ZY_TOUCH_SAMPLE_X) | ||
666 | + { | ||
667 | + value = 0x202; | ||
668 | + } | ||
669 | + else | ||
670 | + {/* Y sample */ | ||
671 | + value = 0x204; | ||
672 | + } | ||
673 | + | ||
674 | + status = zy_ac97_acodec_write(p_device_context, DIGITIZER_1_WM13, value); | ||
675 | + | ||
676 | + wait = 0; | ||
677 | + do | ||
678 | + { | ||
679 | + status = zy_ac97_acodec_read(p_device_context, DIGITIZER_1_WM13, &value); | ||
680 | + if ( !(value & 0x200 ) ) | ||
681 | + { | ||
682 | + break; | ||
683 | + } | ||
684 | + }while ( 100 > wait++ ); | ||
685 | + | ||
686 | + status = zy_ac97_acodec_read(p_device_context, DIGITIZER_READ_BACK, &value); | ||
687 | + if (value & 0x8000) | ||
688 | + {/* means pen down */ | ||
689 | + *p_pen_down = 1; | ||
690 | + } | ||
691 | + else | ||
692 | + { | ||
693 | + *p_pen_down = 0; | ||
694 | + } | ||
695 | + *p_sample_data = value & 0xfff; | ||
696 | + | ||
697 | + return status; | ||
698 | +} | ||
699 | + | ||
700 | + | ||
701 | + | ||
702 | +/* | ||
703 | + * add a touch event | ||
704 | + */ | ||
705 | +static int codec_zy_ts_evt_add(codec_zy_ts_t* ts, u16 pressure, u16 x, u16 y) | ||
706 | +{ | ||
707 | + /* add event and remove adc src bits */ | ||
708 | + static u16 pre_press = 0; | ||
709 | + | ||
710 | + input_report_abs(ts->idev, ABS_X, x & 0xfff); | ||
711 | + input_report_abs(ts->idev, ABS_Y, y & 0xfff); | ||
712 | + if (pressure == pre_press){ | ||
713 | + pressure--; | ||
714 | + } | ||
715 | + pre_press = pressure; | ||
716 | + input_report_abs(ts->idev, ABS_PRESSURE, pressure & 0xfff); | ||
717 | + input_sync(ts->idev); | ||
718 | +#ifdef CONFIG_IPM | ||
719 | + ipm_event_notify(IPM_EVENT_UI, IPM_EVENT_DEVICE_TSI, NULL, 0); | ||
720 | +#endif | ||
721 | + return 0; | ||
722 | +} | ||
723 | + | ||
724 | +/* | ||
725 | + * add a pen up event | ||
726 | + */ | ||
727 | +static void codec_zy_ts_evt_release(codec_zy_ts_t* ts) | ||
728 | +{ | ||
729 | + input_report_abs(ts->idev, ABS_PRESSURE, 0); | ||
730 | + input_sync(ts->idev); | ||
731 | + | ||
732 | +#ifdef CONFIG_IPM | ||
733 | + ipm_event_notify(IPM_EVENT_UI, IPM_EVENT_DEVICE_TSI, NULL, 0); | ||
734 | +#endif | ||
735 | + p_zy_codec_ctxt->g_pfn_event_ack(p_zy_codec_ctxt,ZY_EVENT_TYPE_PDN); | ||
736 | +} | ||
737 | + | ||
738 | +/* | ||
739 | + * Kill the touchscreen thread and stop | ||
740 | + * the touch digitiser. | ||
741 | + */ | ||
742 | +static void codec_zy_ts_input_close(struct input_dev *idev) | ||
743 | +{ | ||
744 | + codec_zy_ts_t *ts = (codec_zy_ts_t *) &codec_zy_ts; | ||
745 | + | ||
746 | +#ifdef CONFIG_PM | ||
747 | + if(touch_suspend){ | ||
748 | + pr_info("touch is suspended!\n"); | ||
749 | + return -1; | ||
750 | + } | ||
751 | +#endif | ||
752 | + dbg("close ts input!\n"); | ||
753 | + if (--ts->use_count == 0) { | ||
754 | + del_timer(ts->timer); | ||
755 | + if (ts->timer != NULL) | ||
756 | + kfree(ts->timer); | ||
757 | + p_zy_codec_ctxt->g_pfn_disable_touch(p_zy_codec_ctxt); | ||
758 | + } | ||
759 | +} | ||
760 | + | ||
761 | +/* | ||
762 | + * Sample the touchscreen | ||
763 | + */ | ||
764 | +int ac97_poll_touch(codec_zy_ts_t *ts) | ||
765 | +{ | ||
766 | + unsigned short x=0, y=0; | ||
767 | + int if_down= 0; | ||
768 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
769 | + | ||
770 | +#ifdef DEBUG | ||
771 | + start_time = OSCR; | ||
772 | +#endif | ||
773 | + | ||
774 | + /* get x value */ | ||
775 | + status = zy_acodec_get_adc_sample(p_zy_codec_ctxt, &x, ZY_TOUCH_SAMPLE_X, &if_down); | ||
776 | + if (ZY_ACODEC_SUCCESS != status ){ | ||
777 | + return -EIO; | ||
778 | + } | ||
779 | + dbg("x:0x%x\n", x); | ||
780 | + | ||
781 | + /* the pen is up */ | ||
782 | + if (1 != if_down){ | ||
783 | + return PEN_UP; | ||
784 | + } | ||
785 | + | ||
786 | + /* get y vaule */ | ||
787 | + status = zy_acodec_get_adc_sample(p_zy_codec_ctxt, &y, ZY_TOUCH_SAMPLE_Y, &if_down); | ||
788 | + if (ZY_ACODEC_SUCCESS != status ){ | ||
789 | + return -EIO; | ||
790 | + } | ||
791 | + dbg("y:0x%x\n",y); | ||
792 | + | ||
793 | + /* the pen is up */ | ||
794 | + if (1 != if_down){ | ||
795 | + return PEN_UP; | ||
796 | + } | ||
797 | + | ||
798 | + /* the pen is down, can not get the pressure value, | ||
799 | + * so if pen is down, give the max pressure value | ||
800 | + */ | ||
801 | + codec_zy_ts_evt_add(ts,0xfff, x, y); | ||
802 | + | ||
803 | +#ifdef DEBUG | ||
804 | + end_time = OSCR; | ||
805 | + PRINT_TIME(); | ||
806 | +#endif | ||
807 | + | ||
808 | + return PEN_DOWN; | ||
809 | +} | ||
810 | + | ||
811 | +static void touch_timer_handler(unsigned long unused) | ||
812 | +{ | ||
813 | + int event; | ||
814 | + codec_zy_ts_t *ts = &codec_zy_ts; | ||
815 | + | ||
816 | + event = ac97_poll_touch(ts); | ||
817 | + | ||
818 | + if (event == PEN_DOWN) { | ||
819 | + dbg("pen down!\n"); | ||
820 | + ts->timer->expires = jiffies + TS_SAMPLE_INTERVAL; | ||
821 | + add_timer(ts->timer); | ||
822 | + } else if(event == PEN_UP) { | ||
823 | + dbg("pen up!\n"); | ||
824 | + codec_zy_ts_evt_release(ts); | ||
825 | + } else if(event == -EIO) { | ||
826 | + printk(KERN_ERR "Access touch interface error!\n"); | ||
827 | + } | ||
828 | + return; | ||
829 | +} | ||
830 | + | ||
831 | +static zy_acodec_error_t zy_ac97_acodec_cold_reset(zy_acocec_context_t * p_ac97_ctxt) | ||
832 | +{ | ||
833 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
834 | + p_zy_ac97acodec_t p_ac97 = (p_zy_ac97acodec_t)(p_ac97_ctxt->p_ctrl_reg); | ||
835 | + int pri_codec_ready; | ||
836 | + unsigned long time_remaining; | ||
837 | + | ||
838 | + p_ac97->gcr = 0; | ||
839 | + p_ac97->gcr |= ZY_AC97_GCR_CLKBPB_MSK; | ||
840 | + /* Hold reset active for a minimum time */ | ||
841 | + udelay(ZY_AC97_COLD_HOLDTIME); | ||
842 | + p_ac97->gcr &= ~ZY_AC97_GCR_CLKBPB_MSK; | ||
843 | + | ||
844 | + /* Deactivate cold reset condition */ | ||
845 | + p_ac97->gcr |= (ZY_AC97_GCR_COLD_RESET_MSK | ZY_AC97_GCR_WARM_RESET_MSK); | ||
846 | + | ||
847 | + | ||
848 | + pri_codec_ready = 0; | ||
849 | + time_remaining = (p_ac97_ctxt->u_max_setup_time_out_ms) * 10; | ||
850 | + do | ||
851 | + { | ||
852 | + udelay(1); | ||
853 | + if (p_ac97->gsr & ZY_AC97_GSR_PCRDY_MSK) | ||
854 | + pri_codec_ready = 1; | ||
855 | + } | ||
856 | + while (time_remaining-- && (pri_codec_ready == 0)); | ||
857 | + | ||
858 | + /* Timeout status if some of the devices weren't ready. */ | ||
859 | + if (pri_codec_ready == 0) | ||
860 | + { | ||
861 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
862 | + } | ||
863 | + | ||
864 | + return (status); | ||
865 | +} | ||
866 | + | ||
867 | + | ||
868 | +zy_acodec_error_t zy_ac97_acodec_init(zy_acocec_context_t *p_ac97_ctxt) | ||
869 | +{ | ||
870 | + zy_acodec_error_t status ; | ||
871 | + | ||
872 | + status = zy_ac97_acodec_cold_reset(p_ac97_ctxt); | ||
873 | + | ||
874 | + return (status); | ||
875 | +} | ||
876 | + | ||
877 | + | ||
878 | +/* | ||
879 | + * Start the touchscreen thread and | ||
880 | + * the touch digitiser. | ||
881 | + */ | ||
882 | +static int codec_zy_ts_input_open(struct input_dev *idev) | ||
883 | +{ | ||
884 | + codec_zy_ts_t *ts = (codec_zy_ts_t *) &codec_zy_ts; | ||
885 | + | ||
886 | +#ifdef CONFIG_PM | ||
887 | + if(touch_suspend){ | ||
888 | + pr_info("touch is suspended!\n"); | ||
889 | + return -1; | ||
890 | + } | ||
891 | +#endif | ||
892 | + | ||
893 | + if (ts->use_count++ > 0) | ||
894 | + return 0; | ||
895 | + | ||
896 | + dbg("Touch is opened. Use count: %d\n", ts->use_count); | ||
897 | + ts->idev = idev; | ||
898 | + ts->timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); | ||
899 | + if (!ts->timer) { | ||
900 | + printk(KERN_ERR "Alloc memory error for timer!\n"); | ||
901 | + return -ENOMEM; | ||
902 | + } | ||
903 | + | ||
904 | + init_timer(ts->timer); | ||
905 | + ts->timer->function = touch_timer_handler; | ||
906 | + ts->timer->data = 0; | ||
907 | + p_zy_codec_ctxt->g_pfn_enable_touch(p_zy_codec_ctxt); | ||
908 | + | ||
909 | + return 0; | ||
910 | +} | ||
911 | + | ||
912 | +/* | ||
913 | + * initilze the pxa touch screen | ||
914 | + */ | ||
915 | +static int alsa_ts_init( void ) | ||
916 | +{ | ||
917 | + codec_zy_ts_t* ts = &codec_zy_ts; | ||
918 | + | ||
919 | + memset(ts, 0, sizeof(codec_zy_ts_t)); | ||
920 | + | ||
921 | + codec_zy_ts_input = input_allocate_device(); | ||
922 | + if (!codec_zy_ts_input) | ||
923 | + return -ENOMEM; | ||
924 | + | ||
925 | + | ||
926 | + /* tell input system what we events we accept and register */ | ||
927 | + codec_zy_ts_input->name = "codec zy touchscreen"; | ||
928 | + codec_zy_ts_input->open = codec_zy_ts_input_open; | ||
929 | + codec_zy_ts_input->close = codec_zy_ts_input_close; | ||
930 | + __set_bit(EV_ABS, codec_zy_ts_input->evbit); | ||
931 | + __set_bit(ABS_X, codec_zy_ts_input->absbit); | ||
932 | + __set_bit(ABS_Y, codec_zy_ts_input->absbit); | ||
933 | + __set_bit(ABS_PRESSURE, codec_zy_ts_input->absbit); | ||
934 | + input_register_device(codec_zy_ts_input); | ||
935 | + | ||
936 | + return 0; | ||
937 | +} | ||
938 | + | ||
939 | +static irqreturn_t pxa_touch_irq(int irq, void *dev) | ||
940 | +{ | ||
941 | + unsigned char event_type; | ||
942 | + | ||
943 | + //printk(KERN_ERR "%s: enter codec event handler\n", __FUNCTION__); | ||
944 | + | ||
945 | + dbg("%s: enter codec event handler\n", __FUNCTION__); | ||
946 | + p_zy_codec_ctxt->g_pfn_get_event(p_zy_codec_ctxt, &event_type); | ||
947 | + switch (event_type) { | ||
948 | + case ZY_EVENT_TYPE_PDN: | ||
949 | + { | ||
950 | + codec_zy_ts_t *ts = &codec_zy_ts; | ||
951 | + /*if the touch is not open need not acknowledge the event*/ | ||
952 | + if (ts->use_count <= 0) | ||
953 | + break; | ||
954 | + ts->timer->expires = jiffies + TS_SAMPLE_INTERVAL; | ||
955 | + add_timer(ts->timer); | ||
956 | + break; | ||
957 | + } | ||
958 | + default: | ||
959 | + printk("unsupported codec event:0x%x\n", event_type); | ||
960 | + } | ||
961 | + | ||
962 | + return IRQ_HANDLED; | ||
963 | +} | ||
964 | + | ||
965 | + | ||
966 | + | ||
967 | + | ||
968 | + | ||
969 | + | ||
970 | + | ||
971 | + | ||
972 | + | ||
973 | +static mfp_cfg_t extra_cfg[] = { | ||
974 | + MFP_CFG_X(GPIO17, AF3, DS03X, PULL_LOW), | ||
975 | + MFP_CFG_X(GPIO25, AF0, DS01X, PULL_LOW), | ||
976 | +}; | ||
977 | + | ||
978 | +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | ||
979 | + | ||
980 | +extern void dump_mfp(void); | ||
981 | + | ||
982 | +zy_acodec_error_t zy_ac97_acodec_mfp_init(zy_acocec_context_t *p_device_context) | ||
983 | +{ | ||
984 | + unsigned short codec_id; | ||
985 | + | ||
986 | + //mhn_mfp_set_afds(MFP_RSVD_AC97_SDATA_IN_0, MFP_AF0, MFP_DS03X); | ||
987 | + //enable_ac97_pins(); | ||
988 | + zy_ac97_acodec_init(p_device_context); | ||
989 | + if (zy_ac97_acodec_read(p_device_context, 0x0, &codec_id)){ | ||
990 | + | ||
991 | + /* | ||
992 | + * there is a bug on MonahansL/MonhansPL PC card: AC97_SDATA_IN is not connected to CODEC | ||
993 | + * ECO 72: Connect PWM_0(MFP_RSVD_AC97_SDATA_IN_0) to CODEC as AC97_SDATA_IN | ||
994 | + */ | ||
995 | + | ||
996 | + //mhn_mfp_set_afds(MFP_RSVD_AC97_SDATA_IN_0, MFP_RSVD_AC97_SDATA_IN_0_AF, MFP_DS03X); | ||
997 | + //mhn_mfp_set_afds(MFP_AC97_SDATA_IN_0, MFP_AF0, MFP_DS01X); | ||
998 | + | ||
999 | + gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO17), 0); | ||
1000 | + pxa3xx_mfp_config(ARRAY_AND_SIZE(extra_cfg)); | ||
1001 | + gpio_direction_input(mfp_to_gpio(MFP_PIN_GPIO25)); | ||
1002 | + } | ||
1003 | + | ||
1004 | + | ||
1005 | + return ZY_ACODEC_SUCCESS; | ||
1006 | +} | ||
1007 | + | ||
1008 | +#define ZY_AC97_WM9713_GPIO_PIN_PDN ( 0x1 << 13 ) /* Pen down */ | ||
1009 | + | ||
1010 | +/*power enable bit in 3ch and 3eh */ | ||
1011 | +/*3ch */ | ||
1012 | +#define ZY_AC97_9713_PWR_PADCPD ( 0x1 << 15 ) | ||
1013 | +#define ZY_AC97_9713_PWR_VMID ( 0x1 << 14 ) | ||
1014 | +#define ZY_AC97_9713_PWR_TSHUT ( 0x1 << 13 ) | ||
1015 | +#define ZY_AC97_9713_PWR_VXDAC ( 0x1 << 12 ) | ||
1016 | +#define ZY_AC97_9713_PWR_AUXDAC ( 0x1 << 11 ) | ||
1017 | +#define ZY_AC97_9713_PWR_MBIAS ( 0x1 << 10 ) | ||
1018 | +#define ZY_AC97_9713_PWR_PLL ( 0x1 << 9 ) | ||
1019 | +#define ZY_AC97_9713_PWR_DACL ( 0x1 << 7 ) | ||
1020 | +#define ZY_AC97_9713_PWR_DACR ( 0x1 << 6 ) | ||
1021 | +#define ZY_AC97_9713_PWR_ADCL ( 0x1 << 5 ) | ||
1022 | +#define ZY_AC97_9713_PWR_ADCR ( 0x1 << 4 ) | ||
1023 | +#define ZY_AC97_9713_PWR_HPLX ( 0x1 << 3 ) | ||
1024 | +#define ZY_AC97_9713_PWR_HPRX ( 0x1 << 2 ) | ||
1025 | +#define ZY_AC97_9713_PWR_SPKX ( 0x1 << 1 ) | ||
1026 | +#define ZY_AC97_9713_PWR_MX ( 0x1 << 0 ) | ||
1027 | + | ||
1028 | +/*3EH */ | ||
1029 | +#define ZY_AC97_9713_PWR_MCD ( 0x1 << 15 ) | ||
1030 | +#define ZY_AC97_9713_PWR_MICBIAS ( 0x1 << 14 ) | ||
1031 | +#define ZY_AC97_9713_PWR_MONO ( 0x1 << 13 ) | ||
1032 | +#define ZY_AC97_9713_PWR_OUT4 ( 0x1 << 12 ) | ||
1033 | +#define ZY_AC97_9713_PWR_OUT3 ( 0x1 << 11 ) | ||
1034 | +#define ZY_AC97_9713_PWR_HPL ( 0x1 << 10 ) | ||
1035 | +#define ZY_AC97_9713_PWR_HPR ( 0x1 << 9 ) | ||
1036 | +#define ZY_AC97_9713_PWR_SPKL ( 0x1 << 8 ) | ||
1037 | +#define ZY_AC97_9713_PWR_SPKR ( 0x1 << 7 ) | ||
1038 | +#define ZY_AC97_9713_PWR_LL ( 0x1 << 6 ) | ||
1039 | +#define ZY_AC97_9713_PWR_LR ( 0x1 << 5 ) | ||
1040 | +#define ZY_AC97_9713_PWR_MOIN ( 0x1 << 4 ) | ||
1041 | +#define ZY_AC97_9713_PWR_MA ( 0x1 << 3 ) | ||
1042 | +#define ZY_AC97_9713_PWR_MB ( 0x1 << 2 ) | ||
1043 | +#define ZY_AC97_9713_PWR_MPA ( 0x1 << 1 ) | ||
1044 | +#define ZY_AC97_9713_PWR_MPB ( 0x1 << 0 ) | ||
1045 | + | ||
1046 | + | ||
1047 | +void zy_wm9713_get_event(zy_acocec_context_t *p_device_context, unsigned char * event_type) | ||
1048 | +{ | ||
1049 | + unsigned short event_state = 0; | ||
1050 | + zy_ac97_acodec_read(p_device_context, GPIO_PIN_STATUS, &event_state); | ||
1051 | + if(event_state & ZY_AC97_WM9713_GPIO_PIN_PDN){ | ||
1052 | + *event_type = ZY_EVENT_TYPE_PDN; | ||
1053 | + return; | ||
1054 | + } | ||
1055 | + return; | ||
1056 | +} | ||
1057 | + | ||
1058 | +void zy_wm9713_event_ack(zy_acocec_context_t *p_device_context, unsigned char event_type) | ||
1059 | +{ | ||
1060 | + unsigned short event_state = 0; | ||
1061 | + zy_ac97_acodec_read(p_device_context, GPIO_PIN_STATUS, &event_state); | ||
1062 | + if( event_type == ZY_EVENT_TYPE_PDN){ | ||
1063 | + zy_ac97_acodec_write(p_device_context, | ||
1064 | + GPIO_PIN_STATUS, | ||
1065 | + (event_state & (~ZY_AC97_WM9713_GPIO_PIN_PDN))); | ||
1066 | + } | ||
1067 | + | ||
1068 | + zy_ac97_acodec_read(p_device_context, GPIO_PIN_STATUS, &event_state); | ||
1069 | + return; | ||
1070 | +} | ||
1071 | + | ||
1072 | +static void * p_saved_memory = NULL; | ||
1073 | +static void * p_zy_scenario = NULL; | ||
1074 | +static p_zy_acocec_context_t p_zy_ctxt = NULL; | ||
1075 | + | ||
1076 | +#define WM9713_SAVE_REGISTER_NO (64-11) | ||
1077 | +typedef struct { | ||
1078 | + unsigned short wm9713RegisterContext [WM9713_SAVE_REGISTER_NO + 1]; /* Fixed (data misalignment error) */ | ||
1079 | +}ZY_9713_CONTEXT_SAVE_T; | ||
1080 | + | ||
1081 | + | ||
1082 | +/** | ||
1083 | + * alsa_prepare_for_zy - create and initialize the p_zy_acocec_context_t | ||
1084 | + * open the clock of data link | ||
1085 | + * @p_p_zy_ctxt: return the data structure p_zy_acocec_context_t | ||
1086 | + * return: 0 success ; -ENOMEM | ||
1087 | + **/ | ||
1088 | +int alsa_prepare_for_zy(p_zy_acocec_context_t * p_p_zy_ctxt) | ||
1089 | +{ | ||
1090 | + if (p_zy_ctxt) { | ||
1091 | + p_zy_ctxt->use_count++; | ||
1092 | + *p_p_zy_ctxt = p_zy_ctxt; | ||
1093 | + return 0; | ||
1094 | + } | ||
1095 | + | ||
1096 | + p_zy_ctxt = kzalloc(sizeof(zy_acocec_context_t), GFP_KERNEL); | ||
1097 | + if (!p_zy_ctxt) | ||
1098 | + return -ENOMEM; | ||
1099 | + | ||
1100 | + /* enable CLK_POUT as CODEC clock input */ | ||
1101 | + OSCC |= 0x800; | ||
1102 | + | ||
1103 | + p_saved_memory = kzalloc(sizeof(ZY_9713_CONTEXT_SAVE_T) + | ||
1104 | + sizeof(zy_ac97_save_context_t), GFP_KERNEL); | ||
1105 | + if (NULL == p_saved_memory) { | ||
1106 | + if (p_zy_ctxt) | ||
1107 | + kfree(p_zy_ctxt); | ||
1108 | + return -ENOMEM; | ||
1109 | + } | ||
1110 | + | ||
1111 | + p_zy_ctxt->acodec_id = (zy_acodec_device_id_t) (WM_9713_ID); | ||
1112 | + p_zy_ctxt->use_count++; | ||
1113 | + /* | ||
1114 | + p_zy_ctxt->pMfpRegBase = (unsigned long) (MFP_BASE); | ||
1115 | + p_zy_ctxt->pMfpRmDb = ZY_MFP_RM_DATABASE; | ||
1116 | + p_zy_ctxt->p_ost_regs = OST_BASE; | ||
1117 | + */ | ||
1118 | + p_zy_ctxt->p_voice_reg = NULL; | ||
1119 | + p_zy_ctxt->p_hifi_reg = (void *) (&POCR); | ||
1120 | + p_zy_ctxt->p_ctrl_reg = (void *) (&POCR); | ||
1121 | + p_zy_ctxt->u_max_read_write_time_out_ms = ZY_AC97_RW_TIMEOUT_DEF; | ||
1122 | + p_zy_ctxt->u_max_setup_time_out_ms = ZY_AC97_SETUP_TIMEOUT_DEF; | ||
1123 | + p_zy_ctxt->p_save_memory = p_saved_memory; | ||
1124 | + p_zy_ctxt->p_zy_scenario = p_zy_scenario; | ||
1125 | +// pxa_set_cken(24, 1); | ||
1126 | + CKENA |= (1 << 24); | ||
1127 | + AC97_DIV = 1625<<12 | 128; | ||
1128 | +#ifdef DEBUG_ALSA_ZY | ||
1129 | + debug_pac97ctxt = p_zy_ctxt; | ||
1130 | + misc_register(&audio_dev); | ||
1131 | +#endif | ||
1132 | + | ||
1133 | + (*p_p_zy_ctxt) = p_zy_ctxt; | ||
1134 | + | ||
1135 | + return 0; | ||
1136 | +} | ||
1137 | + | ||
1138 | + | ||
1139 | +/* this is platform specific */ | ||
1140 | +/* do later: not to enable recording route and playback route in this function, | ||
1141 | + * leave it to driver to call other function | ||
1142 | + */ | ||
1143 | +zy_acodec_error_t zy_wm9713_specific_init (zy_acocec_context_t *p_device_context) | ||
1144 | +{ | ||
1145 | + | ||
1146 | + unsigned short value; | ||
1147 | + | ||
1148 | + /* this assumes that the aclink is initialized wait some time and then | ||
1149 | + * do a warm reset to enabled the ACLINK, required for wm9713 | ||
1150 | + * (not wm9712 or ucb1400) | ||
1151 | + */ | ||
1152 | + | ||
1153 | + /* pay attention: whether the workaround is still needed? */ | ||
1154 | + p_zy_ac97acodec_t p_ac97_reg = (p_zy_ac97acodec_t)(p_device_context->p_ctrl_reg); | ||
1155 | + | ||
1156 | + p_ac97_reg->gcr |= ZY_AC97_GCR_WARM_RESET_MSK; | ||
1157 | + | ||
1158 | + mdelay(5); | ||
1159 | + | ||
1160 | + /* power on all the necessary unit */ | ||
1161 | + zy_ac97_acodec_write(p_device_context,POWERDOWN_CTRL_STAT, 0x000); /*26*/ | ||
1162 | + /* open left headphone mixer */ | ||
1163 | + /* open right headphone mixer */ | ||
1164 | + /* open right/left dac */ | ||
1165 | + /* open right/left adc */ | ||
1166 | + /* open temperature sensor */ | ||
1167 | + /* enable reference generator */ | ||
1168 | + zy_ac97_acodec_write(p_device_context,POWER_DOWN_1, 0xda00); /*3c */ | ||
1169 | + /* open microphone bias */ | ||
1170 | + /* open HPL output PGA */ | ||
1171 | + /* open HPR output PGA */ | ||
1172 | + /* open mic PGA MA */ | ||
1173 | + /* open mic pre-amp MPA */ | ||
1174 | + /* if here we enable SPKL and SPKR PGA, then Touch screen will doesn't work */ | ||
1175 | + zy_ac97_acodec_write(p_device_context,POWER_DOWN_2,0xb9f5); /*3e */ | ||
1176 | + | ||
1177 | + /* recording route and microphone input */ | ||
1178 | + /* microphone selection, now fixed to MIC1 input and mic bias output */ | ||
1179 | + /* MIC1 only, MICBIAS enable */ | ||
1180 | + zy_ac97_acodec_write (p_device_context, MIC_BIAS, 0xC440); /*0x22h*/ | ||
1181 | + | ||
1182 | + /* mic pga setting to mixer (side tone) */ | ||
1183 | + /* comment the below code to make MICA/B play back volume gain + 0db */ | ||
1184 | + /* zy_ac97_acodec_write (p_device_context, MIC_PGA_VOLUME, 0x0000); */ /*0x0eh*/ | ||
1185 | + | ||
1186 | + /* recording side tone and ADC boost, now fixed to default (14h) */ | ||
1187 | + /* recording volume 0dB */ | ||
1188 | + zy_ac97_acodec_write(p_device_context, REC_PGA_VOL, 0x0); /*12*/ | ||
1189 | + | ||
1190 | + /* hifi playback route and output mixer */ | ||
1191 | + /* by default, fixed to enable headphone only */ | ||
1192 | + | ||
1193 | + /* comment the below code to make SPEAKER default MUTE */ | ||
1194 | + zy_ac97_acodec_write (p_device_context, SPEAKER_VOLUME, 0x0); /*02*/ | ||
1195 | + | ||
1196 | + /* comment the below code to make OUT3_OUT4 default MUTE */ | ||
1197 | + /* zy_ac97_acodec_write (p_device_context, OUT3_OUT4_VOLUME, 0x8000); */ /*06*/ | ||
1198 | + | ||
1199 | + /* remove all the mute bit volume gain + 0db */ | ||
1200 | + zy_ac97_acodec_write(p_device_context, HEADPHONE_VOLUME, 0x0); /*04*/ | ||
1201 | + | ||
1202 | + /* DAC route */ | ||
1203 | + /* open DAC to headphone mixer path */ | ||
1204 | + /* left DAC gain +0db */ | ||
1205 | + /* right DAC gain +0db */ | ||
1206 | + zy_ac97_acodec_write(p_device_context, DAC_PGA_VOL_ROUTE,0x0808); /*0c*/ | ||
1207 | + | ||
1208 | + /* out3 configure, invert to HPMIXR */ | ||
1209 | + /* zy_ac97_acodec_write(p_device_context,DAC_3D_CTRL_INV_MUX_SEL, 0x8000); */ /*1e*/ | ||
1210 | + | ||
1211 | + /* output control */ | ||
1212 | + /* select HPMIXR HPMIXL out */ | ||
1213 | + /* other out are all VIM */ | ||
1214 | + zy_ac97_acodec_write(p_device_context,OUTPUT_PGA_MUX, 0x9BA8); /*1c*/ | ||
1215 | + | ||
1216 | + /* set sample rates */ | ||
1217 | + /* enable variable rate conversion */ | ||
1218 | + zy_ac97_acodec_write(p_device_context, EXTENDED_AUD_STAT_CTRL , 0x1); /*2a*/ | ||
1219 | + /* DAC 44kHZ */ | ||
1220 | + zy_ac97_acodec_write(p_device_context,AUDIO_DAC_RATE,0xac44); /*2c*/ | ||
1221 | + /* ADC 16KHZ */ | ||
1222 | + zy_ac97_acodec_write(p_device_context,AUDIO_ADC_RATE,0x3E80); /*32*/ | ||
1223 | + | ||
1224 | + /* clock scheme, use external clock, it is 24MHZ from MCLK_A */ | ||
1225 | + | ||
1226 | + | ||
1227 | + zy_ac97_acodec_read(p_device_context, MCLK_PLL_CTRL_1, &value); | ||
1228 | + zy_ac97_acodec_write(p_device_context, MCLK_PLL_CTRL_1, value | 0x2); | ||
1229 | + | ||
1230 | + return ZY_ACODEC_SUCCESS; | ||
1231 | +} | ||
1232 | + | ||
1233 | +zy_acodec_error_t zy_wm9713_specific_deinit (zy_acocec_context_t *p_device_context) | ||
1234 | +{/* do later: shut down all power */ | ||
1235 | + unsigned short value = 0; | ||
1236 | + | ||
1237 | + /* close the power of all units */ | ||
1238 | + zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, 0xffff); | ||
1239 | + zy_ac97_acodec_write(p_device_context, POWER_DOWN_2, 0xffff); | ||
1240 | + zy_ac97_acodec_read(p_device_context, POWER_DOWN_1, &value); | ||
1241 | + value &= ~(ZY_AC97_9713_PWR_MBIAS); | ||
1242 | + zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, value); | ||
1243 | + | ||
1244 | + return ZY_ACODEC_SUCCESS; | ||
1245 | +} | ||
1246 | + | ||
1247 | +zy_acodec_error_t zy_acodec_set_pen_down_interrupt(zy_acocec_context_t *p_device_context, int enable) | ||
1248 | +{/* disable/enable pen down interrupt in the codec. This function is not implemented for Wm9713 */ | ||
1249 | + /* because the pen down detection could not be disabled in codec */ | ||
1250 | + return ZY_ACODEC_SUCCESS; | ||
1251 | +} | ||
1252 | + | ||
1253 | +zy_acodec_error_t zy_wm9713_enable_touch(zy_acocec_context_t *p_device_context) | ||
1254 | +{/* enable touch functionality in the codec */ | ||
1255 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
1256 | + unsigned short value; | ||
1257 | + | ||
1258 | + /* power setting */ | ||
1259 | + status = zy_ac97_acodec_read(p_device_context, POWER_DOWN_1, &value); | ||
1260 | + value &= ~(ZY_AC97_9713_PWR_PADCPD); | ||
1261 | + status = zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, value); | ||
1262 | + | ||
1263 | + /* basic touch setting */ | ||
1264 | + status = zy_ac97_acodec_write(p_device_context, DIGITIZER_3_WM13, 0xc008); | ||
1265 | + status = zy_ac97_acodec_write(p_device_context, DIGITIZER_2_WM13, 0x6); | ||
1266 | + | ||
1267 | + | ||
1268 | + /* 9713 powerdown virtual gpio setting (polarity, sticky, wakeup) */ | ||
1269 | + /* 9713 gpio 2(pin45) route to IRQ */ | ||
1270 | + /* Notes: Can use defaults for IRQ polarity, PENDOWN polarity in IRQ, */ | ||
1271 | + /* sticky for PENDOWN in IRQ and wakeup for PENDOWN. */ | ||
1272 | + status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_CFG, &value); | ||
1273 | + value &= ~(0x4); | ||
1274 | + status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_CFG, value); | ||
1275 | + | ||
1276 | + status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_SHARING, &value); | ||
1277 | + value &= ~(0x4); | ||
1278 | + status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_SHARING, value); | ||
1279 | + | ||
1280 | + status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_WAKEUP, &value); | ||
1281 | + value |= (0x2000); | ||
1282 | + status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_WAKEUP, value); | ||
1283 | + | ||
1284 | + status = zy_ac97_acodec_read(p_device_context, GPIO_PIN_STICKY, &value); | ||
1285 | + value |= (0x2000); | ||
1286 | + status = zy_ac97_acodec_write(p_device_context, GPIO_PIN_STICKY, value); | ||
1287 | + | ||
1288 | + return status; | ||
1289 | +} | ||
1290 | + | ||
1291 | +zy_acodec_error_t zy_wm9713_disable_touch(zy_acocec_context_t *p_device_context) | ||
1292 | +{/* disable touch functionality in the codec */ | ||
1293 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
1294 | + unsigned short value; | ||
1295 | + | ||
1296 | + /* power setting */ | ||
1297 | + status = zy_ac97_acodec_read(p_device_context, POWER_DOWN_1, &value); | ||
1298 | + value |= (ZY_AC97_9713_PWR_PADCPD); | ||
1299 | + status = zy_ac97_acodec_write(p_device_context, POWER_DOWN_1, value); | ||
1300 | + | ||
1301 | + return status; | ||
1302 | +} | ||
1303 | +zy_acodec_error_t zy_ac97_acodec_mfp_deinit(zy_acocec_context_t *p_device_context) | ||
1304 | +{/* do later: free all MFP resources. */ | ||
1305 | + return ZY_ACODEC_SUCCESS; | ||
1306 | +} | ||
1307 | + | ||
1308 | +static zy_acodec_error_t zy_ac97_acodec_shut_down_aclink(p_zy_ac97acodec_t p_ac97_reg, int * p_ost_regs) | ||
1309 | +{ | ||
1310 | + zy_acodec_error_t status = ZY_ACODEC_SUCCESS; | ||
1311 | + unsigned long time_remaining = ZY_AC97_LINKOFF_TIMEOUT_DEF; | ||
1312 | + | ||
1313 | + p_ac97_reg->gcr |= ZY_AC97_GCR_LINK_OFF_MSK; | ||
1314 | + p_ac97_reg->gcr |= ZY_AC97_GCR_CLKBPB_MSK; | ||
1315 | + | ||
1316 | + while (!(p_ac97_reg->gsr & ZY_AC97_GSR_ACOFFD_MSK)) | ||
1317 | + { | ||
1318 | + time_remaining --; | ||
1319 | + if (0 == time_remaining) | ||
1320 | + { | ||
1321 | + status = ZY_ACODEC_CONTROLLER_INTERFACE_TIMEOUT; | ||
1322 | + break; | ||
1323 | + } | ||
1324 | + udelay(1); | ||
1325 | + } | ||
1326 | + p_ac97_reg->gcr |= ZY_AC97_GCR_FRCRST_MSK; | ||
1327 | + /* check later: any delay needed */ | ||
1328 | + p_ac97_reg->gcr &= ~ZY_AC97_GCR_FRCRST_MSK; | ||
1329 | + p_ac97_reg->gcr &= ~ZY_AC97_GCR_CLKBPB_MSK; | ||
1330 | + | ||
1331 | + return(status); | ||
1332 | +} | ||
1333 | + | ||
1334 | + | ||
1335 | +zy_acodec_error_t zy_ac97_acodec_deinit(zy_acocec_context_t * p_ac97_ctxt) | ||
1336 | +{ | ||
1337 | + zy_acodec_error_t status ; | ||
1338 | + | ||
1339 | + status = zy_ac97_acodec_shut_down_aclink((p_zy_ac97acodec_t)(p_ac97_ctxt->p_ctrl_reg), p_ac97_ctxt->p_ost_regs); | ||
1340 | + | ||
1341 | + return (status); | ||
1342 | +} | ||
1343 | + | ||
1344 | +zy_acodec_error_t zy_acodec_deinit(zy_acocec_context_t *p_device_context) | ||
1345 | +{ | ||
1346 | + /* power down codec by codec specific power down function */ | ||
1347 | + if (p_device_context->g_pfn_codec_specific_dinit) | ||
1348 | + { | ||
1349 | + p_device_context->g_pfn_codec_specific_dinit(p_device_context); | ||
1350 | + } | ||
1351 | + /* call bus deinit function */ | ||
1352 | + zy_ac97_acodec_deinit(p_device_context); | ||
1353 | + /* restore MFP, set GPIO to suitable value */ | ||
1354 | + zy_ac97_acodec_mfp_deinit(p_device_context); | ||
1355 | + | ||
1356 | + return ZY_ACODEC_SUCCESS; | ||
1357 | +} | ||
1358 | + | ||
1359 | +void alsa_zy_codec_put(p_zy_acocec_context_t p_acodectxt) | ||
1360 | +{ | ||
1361 | + | ||
1362 | + zy_acodec_deinit(p_acodectxt); | ||
1363 | + //pxa_set_cken(24, 0); | ||
1364 | + CKENA &= ~(1 << 24); | ||
1365 | + | ||
1366 | + if(p_acodectxt->p_save_memory){ | ||
1367 | + kfree(p_saved_memory); | ||
1368 | + } | ||
1369 | + if(p_acodectxt->p_zy_scenario){ | ||
1370 | + kfree(p_zy_scenario); | ||
1371 | + } | ||
1372 | +} | ||
1373 | + | ||
1374 | + | ||
1375 | +zy_acodec_error_t zy_acodec_init(zy_acocec_context_t *p_device_context, int hw_init) | ||
1376 | +{ | ||
1377 | + /* set codec specific functions | ||
1378 | + * set mfp for Zylonite platform | ||
1379 | + * call bus init function (AC97, I2S, I2C, SSP) | ||
1380 | + * call specific init of codec | ||
1381 | + */ | ||
1382 | + zy_acodec_error_t retval = ZY_ACODEC_SUCCESS; | ||
1383 | + | ||
1384 | + if (p_device_context->acodec_id != WM_9713_ID) | ||
1385 | + {/* on Zylonite, it is Wolfson 9713 codec only */ | ||
1386 | + return ZY_ACODEC_GENERAL_SW_ERR; | ||
1387 | + } | ||
1388 | + | ||
1389 | + if (1 == hw_init) | ||
1390 | + { | ||
1391 | + zy_ac97_acodec_mfp_init(p_device_context); | ||
1392 | + zy_ac97_acodec_init(p_device_context); /* codec init common to ac97 */ | ||
1393 | + } | ||
1394 | + | ||
1395 | + /* wm9713-specific functions */ | ||
1396 | + (p_device_context->g_pfn_codec_specific_init) = zy_wm9713_specific_init; | ||
1397 | + (p_device_context->g_pfn_codec_specific_dinit) = zy_wm9713_specific_deinit; | ||
1398 | + (p_device_context->g_pfn_acodec_read) = zy_ac97_acodec_read; | ||
1399 | + (p_device_context->g_pfn_acodec_write) = zy_ac97_acodec_write; | ||
1400 | + | ||
1401 | + (p_device_context->g_pfn_event_ack) = zy_wm9713_event_ack; | ||
1402 | + (p_device_context->g_pfn_get_event) = zy_wm9713_get_event; | ||
1403 | + (p_device_context->g_pfn_disable_touch) = zy_wm9713_disable_touch; | ||
1404 | + (p_device_context->g_pfn_enable_touch) = zy_wm9713_enable_touch; | ||
1405 | + | ||
1406 | + if (1 == hw_init) | ||
1407 | + { | ||
1408 | + retval = p_device_context->g_pfn_codec_specific_init(p_device_context); | ||
1409 | + } | ||
1410 | + | ||
1411 | + return retval; | ||
1412 | +} | ||
1413 | + | ||
1414 | +static int __devinit touch_codec_zy_probe(struct platform_device *dev) | ||
1415 | +{ | ||
1416 | + int ret = 0; | ||
1417 | + struct snd_card *card = NULL; | ||
1418 | + zy_acodec_error_t status; | ||
1419 | + | ||
1420 | + /* will increase codec context use count */ | ||
1421 | + ret = alsa_prepare_for_zy(&p_zy_codec_ctxt); | ||
1422 | + if (ret) | ||
1423 | + goto err; | ||
1424 | + | ||
1425 | + /* codec specific initialization, audio will do it either */ | ||
1426 | + if (1 == p_zy_codec_ctxt->use_count) { | ||
1427 | + status = zy_acodec_init(p_zy_codec_ctxt, 1); | ||
1428 | + if (ZY_ACODEC_SUCCESS != status) { | ||
1429 | + printk(KERN_ERR "initialize codec error\n"); | ||
1430 | + ret = -EIO; | ||
1431 | + goto err; | ||
1432 | + } | ||
1433 | + | ||
1434 | + /* power down the units of the acodec, sleep the acodec, zy_acodec_init() | ||
1435 | + * will open all the units' power of the codec while ALSA need all the codec | ||
1436 | + * units power down and the codec should sleep if it can. | ||
1437 | + * So on the zylonite platform we call below function to power down and sleep | ||
1438 | + * wm9713 codec. | ||
1439 | + */ | ||
1440 | + p_zy_codec_ctxt->g_pfn_codec_specific_dinit(p_zy_codec_ctxt); | ||
1441 | + | ||
1442 | + } | ||
1443 | + | ||
1444 | + alsa_ts_init(); | ||
1445 | + | ||
1446 | + //mhn_mfp_set_afds(MFP_AC97_INT_N_GPIO,0,0); | ||
1447 | + //mhn_gpio_set_direction(MFP_AC97_INT_N_GPIO, GPIO_DIR_IN); | ||
1448 | + //mhn_gpio_clear_edge_detect_status(MFP_AC97_INT_N_GPIO); | ||
1449 | + gpio_direction_input(mfp_to_gpio(MFP_PIN_GPIO26)); | ||
1450 | + ret = request_irq(IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO26)), | ||
1451 | + pxa_touch_irq, IRQF_TRIGGER_RISING, | ||
1452 | + "wm9713 touch event interrupt", NULL); | ||
1453 | + if (ret) { | ||
1454 | + printk(KERN_ERR "Request IRQ for touch failed (%d).\n", ret); | ||
1455 | + goto err; | ||
1456 | + } | ||
1457 | + | ||
1458 | + return 0; | ||
1459 | +err: | ||
1460 | + if (p_zy_codec_ctxt && (!--p_zy_codec_ctxt->use_count)) { | ||
1461 | + zy_acodec_deinit(p_zy_codec_ctxt); | ||
1462 | + //pxa_set_cken(24, 0); | ||
1463 | + CKENA &= ~(1 << 24); | ||
1464 | + kfree(p_zy_codec_ctxt); | ||
1465 | + p_zy_codec_ctxt = NULL; | ||
1466 | + } | ||
1467 | + | ||
1468 | + if (card) | ||
1469 | + snd_card_free(card); | ||
1470 | + | ||
1471 | + return ret; | ||
1472 | +} | ||
1473 | + | ||
1474 | +static int __devexit touch_codec_zy_remove(struct platform_device *dev) | ||
1475 | +{ | ||
1476 | + struct snd_card *card = platform_get_drvdata(dev); | ||
1477 | + | ||
1478 | + input_unregister_device(codec_zy_ts_input); | ||
1479 | + | ||
1480 | + if (p_zy_codec_ctxt && (!--p_zy_codec_ctxt->use_count)) { | ||
1481 | + alsa_zy_codec_put(p_zy_codec_ctxt); | ||
1482 | + kfree(p_zy_codec_ctxt); | ||
1483 | + p_zy_codec_ctxt = NULL; | ||
1484 | + } | ||
1485 | + | ||
1486 | + if (card) { | ||
1487 | + snd_card_free(card); | ||
1488 | + platform_set_drvdata(dev, NULL); | ||
1489 | + } | ||
1490 | + | ||
1491 | + return 0; | ||
1492 | +} | ||
1493 | + | ||
1494 | +#ifdef CONFIG_PM | ||
1495 | +static int touch_codec_zy_suspend(struct platform_device *_dev, pm_message_t state, u32 level) | ||
1496 | +{ | ||
1497 | + int ret=0; | ||
1498 | + | ||
1499 | + if (level == SUSPEND_DISABLE) { | ||
1500 | + ret = audio_codec_zy_do_suspend(NULL, SNDRV_CTL_POWER_D3cold, p_zy_codec_ctxt); | ||
1501 | + touch_suspend = 1; | ||
1502 | + } | ||
1503 | + return ret; | ||
1504 | +} | ||
1505 | + | ||
1506 | +static int touch_codec_zy_resume(struct platform_device *_dev, u32 level) | ||
1507 | +{ | ||
1508 | + int ret = 0; | ||
1509 | + | ||
1510 | + if (level == RESUME_ENABLE) { | ||
1511 | + ret = audio_codec_zy_do_resume(NULL, SNDRV_CTL_POWER_D0, p_zy_codec_ctxt); | ||
1512 | + touch_suspend = 0; | ||
1513 | + } | ||
1514 | + return ret; | ||
1515 | +} | ||
1516 | +#else | ||
1517 | +#define touch_codec_zy_suspend NULL | ||
1518 | +#define touch_codec_zy_resume NULL | ||
1519 | +#endif | ||
1520 | + | ||
1521 | +static struct platform_driver touch_codec_zy_driver = { | ||
1522 | + .probe = touch_codec_zy_probe, | ||
1523 | + .remove = __devexit_p(touch_codec_zy_remove), | ||
1524 | + .suspend= touch_codec_zy_suspend, | ||
1525 | + .resume = touch_codec_zy_resume, | ||
1526 | + .driver = { | ||
1527 | + .name = "pxa2xx-touch", | ||
1528 | + }, | ||
1529 | +}; | ||
1530 | + | ||
1531 | +static int __init touch_codec_zy_init(void) | ||
1532 | +{ | ||
1533 | + return platform_driver_register(&touch_codec_zy_driver); | ||
1534 | +} | ||
1535 | + | ||
1536 | +static void __exit touch_code_zy_exit(void) | ||
1537 | +{ | ||
1538 | + platform_driver_unregister(&touch_codec_zy_driver); | ||
1539 | +} | ||
1540 | +module_init(touch_codec_zy_init); | ||
1541 | +module_exit(touch_code_zy_exit); | ||
1542 | + | ||
1543 | +EXPORT_SYMBOL(p_zy_codec_ctxt); | ||
1544 | + | ||
1545 | +MODULE_AUTHOR("bridge.wu@marvell.com"); | ||
1546 | +MODULE_DESCRIPTION("zylonite audio touch codec driver on ALSA"); | ||
1547 | +MODULE_LICENSE("GPL"); | ||
1548 | + | ||
diff --git a/meta/packages/linux/linux-rp_2.6.23.bb b/meta/packages/linux/linux-rp_2.6.23.bb index b4579ce9f4..32564a2f66 100644 --- a/meta/packages/linux/linux-rp_2.6.23.bb +++ b/meta/packages/linux/linux-rp_2.6.23.bb | |||
@@ -1,6 +1,6 @@ | |||
1 | require linux-rp.inc | 1 | require linux-rp.inc |
2 | 2 | ||
3 | PR = "r31" | 3 | PR = "r32" |
4 | 4 | ||
5 | # Handy URLs | 5 | # Handy URLs |
6 | # git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046 | 6 | # git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046 |
@@ -139,6 +139,7 @@ SRC_URI_append_zylonite ="\ | |||
139 | file://pxa_fb_overlay.patch;patch=1 \ | 139 | file://pxa_fb_overlay.patch;patch=1 \ |
140 | file://zylonite-boot.patch;patch=1 \ | 140 | file://zylonite-boot.patch;patch=1 \ |
141 | file://zylonite_mtd-r0.patch;patch=1 \ | 141 | file://zylonite_mtd-r0.patch;patch=1 \ |
142 | file://zylonite_touch-r0.patch;patch=1 \ | ||
142 | " | 143 | " |
143 | 144 | ||
144 | S = "${WORKDIR}/linux-2.6.23" | 145 | S = "${WORKDIR}/linux-2.6.23" |