diff options
| author | Richard Purdie <richard@openedhand.com> | 2008-02-13 16:29:55 +0000 |
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2008-02-13 16:29:55 +0000 |
| commit | 89213d9bd144f345135751c7c0ea19020f5832e3 (patch) | |
| tree | e589e9ec9211ba5f4df0ac731385cd145eb87ee5 | |
| parent | f090aee8f1e4be6b6a164a8aa10d6f62765c2826 (diff) | |
| download | poky-89213d9bd144f345135751c7c0ea19020f5832e3.tar.gz | |
linux-rp-2.6.23: Add zyonite touchscreend driver forward port
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3793 311d38ba-8fff-0310-9ca6-ca027cbcb966
| -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" |
