Index: tlinux/Makefile diff -u tlinux/Makefile:1.1.1.6 tlinux/Makefile:1.1.1.6.2.1 --- tlinux/Makefile:1.1.1.6 Mon Dec 10 14:45:42 2001 +++ tlinux/Makefile Mon Dec 10 15:11:04 2001 @@ -1,11 +1,12 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 16 -EXTRAVERSION =-rmk2 +EXTRAVERSION =-rmk2-tux1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) +#ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) +ARCH := arm KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//") CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -19,7 +20,7 @@ HOSTCC = gcc HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -CROSS_COMPILE = +CROSS_COMPILE = arm-linux- # # Include the make variables (CC, etc...) Index: tlinux/Documentation/fb/backlight.txt diff -u /dev/null tlinux/Documentation/fb/backlight.txt:1.1.6.1 --- /dev/null Mon Dec 10 16:54:47 2001 +++ tlinux/Documentation/fb/backlight.txt Mon Dec 10 15:11:04 2001 @@ -0,0 +1,223 @@ + Linux Backlight Drivers + (c) 2001 Russ Dill + $Id: backlight.txt,v 1.1.6.1 2001/12/10 22:11:04 russ Exp $ +---------------------------------------------------------------------------- + +0. Disclaimer +~~~~~~~~~~~~~ + This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + + This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + + You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., 59 +Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For your convenience, the GNU General Public License version 2 is included +in the package: See the file COPYING. + +1. Introduction +~~~~~~~~~~~~~~~ + This is a collection of drivers that provide a standarized interface for +backlights. This code allows a standardized interface to backlights, as well as +a standardized interface to register devices. + +1.1 Device drivers +~~~~~~~~~~~~~~~~~~ + Backlight drivers register themselves to backlight.c. Once registered, +keventd is scheduled to set the defaults for the device. The backlight device +is associated with a framebuffer device. Currently, the backlight interface +only attempts to register the driver with the first backlight device, although +this can be changed in the future. + +1.2 Helper modules +~~~~~~~~~~~~~~~~~~ +2.2.1 backlight_pm.o +~~~~~~~~~~~~~~~~~~~~~ + backlight_pm.o registers with the power management subsystem and turns the +backlight off and on when pm callbacks are made. + +2.2.2 backlight_input.o +~~~~~~~~~~~~~~~~~~~~~~~ + backlight_input.o watches for key presses from the input layer and modifies +backlight settings (contrast/power/brightness). Keypresses are defined per +board. + +1.3 Available Hooks +~~~~~~~~~~~~~~~~~~~ + Calls are provided to the kernel to modify/read backlight settings. The calls +can be safetly made from any context, and reguardless of it a backlight driver +is registered or not. The info argument can be obtained by using the +registered_fb[] array. The type specified the desired setting (BL_POWER, +BL_BRIGHTNESS, or BL_CONTRAST). + +1.3.1 int fb_backlight_get(struct fb_info *info, int type, struct bl_setting *dest) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Reads the current setting, max value, and default value into the dest struct. +On success, 0 is returned. + +1.3.2 int fb_backlight_set(struct fb_info *info, int type, u_int new) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Sets the specified setting to new. The change will be carried out in the context +of keventd. If there is already a pending change for the specifed setting, the old +request will be dropped. + +1.3.3 macros +~~~~~~~~~~~~ + Various macros are provided in linux/fb.h to make more readable code. + +#define fb_backlight_on(info) fb_backlight_set(info, BL_POWER, 1) +#define fb_backlight_off(info) fb_backlight_set(info, BL_POWER, 0) +#define fb_backlight_set_power(info, new) fb_backlight_set(info, BL_POWER, new) +#define fb_backlight_set_contrast(info, new) fb_backlight_set(info, BL_CONTRAST, new) +#define fb_backlight_set_brightness(info, new) fb_backlight_set(info, BL_BRIGHTNESS, new) +#define fb_backlight_get_power(info, new) fb_backlight_get(info, BL_POWER, new) +#define fb_backlight_get_contrast(info, new) fb_backlight_get(info, BL_CONTRAST, new) +#define fb_backlight_get_brightness(info, new) fb_backlight_get(info, BL_BRIGHTNESS, new) + +1.4 Available IOCTLs +~~~~~~~~~~~~~~~~~~~~ + +1.4.1 Read settings +~~~~~~~~~~~~~~~~~~~ +FB_BACKLIGHT_GET_POWER +FB_BACKLIGHT_GET_BRIGHTNESS +FB_BACKLIGHT_GET_CONTRAST + +1.4.2 Write settings +~~~~~~~~~~~~~~~~~~~~ +FB_BACKLIGHT_SET_POWER +FB_BACKLIGHT_SET_BRIGHTNESS +FB_BACKLIGHT_SET_CONTRAST + +2. Detailed Description +~~~~~~~~~~~~~~~~~~~~~~~ +2.1 Device drivers +~~~~~~~~~~~~~~~~~~ + Calls to backlight drivers are done in the context of keventd, so drivers can +sleep and use semaphores. The backlight interface gauruntees that only one +function will be excecuted concurently. + +2.1.1 struct backlight_ops +~~~~~~~~~~~~~~~~~~~~~~~~~~ + This struct describes the default settings, maximum settings, and the +function that should be called to change that setting. An example struct is +below: + +static struct backlight_ops freebird_ops = { + power: { + set: freebird_power, + }, + brightness: { + set: freebird_brightness, + max: MAX_BRIGHTNESS, + def: 27, + }, + contrast: { + set: freebird_contrast, + max: MAX_CONTRAST, + def: 18, + }, +}; + +The power setting max value and default value is set automatically. The scale +of settings should be normalized to 0 (arg = arg - MIN_SETTING) and the passed +arguments should be inverted (arg = MAX_SETTING - arg) if the scale is +reversed. + +2.1.2 int fb_register_backlight(struct backlight_ops *ops, void *private, struct module *module) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + This function should be called once the backlight hardware is initialized. +The ops argument is described above. The private argument will be passed back +to the module when individual functions are called, as well as returned when +fb_deregister_backlight is called. The module argument should be THIS_MODULE. +Zero is returned on success. + +2.1.3 void *fb_deregister_backlight(void) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + This function should be called when the devices module is unloaded. Because +the backlight code increments your module count while it is calling any of your +functions, your module unload function will not be called while any of your +other code is excecuting. The function returns the private info passed to +fb_register_backlight so the structure can be dealloced if neccessary. + +3. Sample IOCTL source +~~~~~~~~~~~~~~~~~~~~~~ + +--- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE -- + +/* + * backlight_test.c - Test the backlight ioctls + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* from linux/fb.h + * struct bl_setting { + * u_int curr; + * u_int max; + * u_int def; + * }; + */ + +int main(int argc, char *argv[]) +{ + struct bl_setting setting; + char name[][12] = { "power", "brightness", "contrast" }; + int read_ioctl[] = { FB_BACKLIGHT_GET_POWER, + FB_BACKLIGHT_GET_BRIGHTNESS, + FB_BACKLIGHT_GET_CONTRAST }; + int write_ioctl[] = { FB_BACKLIGHT_SET_POWER, + FB_BACKLIGHT_SET_BRIGHTNESS, + FB_BACKLIGHT_SET_CONTRAST }; + int fd, i; + + if ((fd = open("/dev/fb0", O_RDWR)) < 0) { + perror("could not open /dev/fb"); + return 0; + } + + for (i = 0; i < 3; i++) { + if ((ioctl(fd, read_ioctl[i], &setting)) < 0) { + printf("Could not read %s: %s\n", name[i], sys_errlist[errno]); + continue; + } + printf("max %s: %d\n", name[i], setting.max); + printf("default %s: %d\n", name[i], setting.def); + printf("current %s: %d\n", name[i], setting.curr); + } + + if (argc > 2) { + for (i = 0; i < 3; i++) if (!strcmp(name[i], argv[1])) break; + if (i == 3) { + printf("invalid option\n"); + return 0; + } + if ((ioctl(fd, write_ioctl[i], atoi(argv[2]))) < 0) { + perror("writeback failed"); + return 0; + } + } + return 0; +} + Index: tlinux/arch/arm/Makefile diff -u tlinux/arch/arm/Makefile:1.1.1.3 tlinux/arch/arm/Makefile:1.1.1.3.2.1 --- tlinux/arch/arm/Makefile:1.1.1.3 Mon Dec 10 14:47:12 2001 +++ tlinux/arch/arm/Makefile Mon Dec 10 15:11:04 2001 @@ -61,7 +61,11 @@ ifeq ($(CONFIG_CPU_32),y) PROCESSOR = armv +ifeq ($(CONFIG_SA1100_SHANNON_32M),y) +TEXTADDR = 0xD0008000 +else TEXTADDR = 0xC0008000 +endif LDSCRIPT = arch/arm/vmlinux-armv.lds.in endif Index: tlinux/arch/arm/config.in diff -u tlinux/arch/arm/config.in:1.1.1.5 tlinux/arch/arm/config.in:1.1.1.5.2.1 --- tlinux/arch/arm/config.in:1.1.1.5 Mon Dec 10 14:47:12 2001 +++ tlinux/arch/arm/config.in Mon Dec 10 15:11:04 2001 @@ -111,6 +111,7 @@ dep_bool ' Pangolin' CONFIG_SA1100_PANGOLIN $CONFIG_ARCH_SA1100 dep_bool ' PLEB' CONFIG_SA1100_PLEB $CONFIG_ARCH_SA1100 dep_bool ' Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100 +dep_bool ' Support for 32M SODIMM on Shannon' CONFIG_SA1100_SHANNON_32M $CONFIG_SA1100_SHANNON dep_bool ' Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100 dep_bool ' Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100 dep_bool ' Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100 Index: tlinux/arch/arm/boot/Makefile diff -u tlinux/arch/arm/boot/Makefile:1.1.1.1 tlinux/arch/arm/boot/Makefile:1.1.1.1.12.1 --- tlinux/arch/arm/boot/Makefile:1.1.1.1 Wed Oct 31 13:20:53 2001 +++ tlinux/arch/arm/boot/Makefile Mon Dec 10 15:11:04 2001 @@ -112,6 +112,10 @@ ifeq ($(CONFIG_SA1111),y) ZRELADDR = 0xc0208000 endif +ifeq ($(CONFIG_SA1100_SHANNON_32M),y) + ZTEXTADDR = 0xd0008000 + ZRELADDR = 0xd0008000 +endif endif ifeq ($(CONFIG_ARCH_ANAKIN),y) Index: tlinux/arch/arm/def-configs/shannon diff -u tlinux/arch/arm/def-configs/shannon:1.1.1.1 tlinux/arch/arm/def-configs/shannon:1.1.1.1.6.2 --- tlinux/arch/arm/def-configs/shannon:1.1.1.1 Mon Nov 19 01:07:39 2001 +++ tlinux/arch/arm/def-configs/shannon Mon Dec 10 15:12:04 2001 @@ -48,19 +48,30 @@ # # Archimedes/A5000 Implementations (select only ONE) # +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set # # Footbridge Implementations # +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set # # SA11x0 Implementations # # CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set # CONFIG_SA1100_ADSBITSY is not set # CONFIG_SA1100_BRUTUS is not set # CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set # CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set @@ -75,6 +86,7 @@ # CONFIG_SA1100_PANGOLIN is not set # CONFIG_SA1100_PLEB is not set CONFIG_SA1100_SHANNON=y +# CONFIG_SA1100_SHANNON_32M is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set # CONFIG_SA1100_PFS168 is not set @@ -82,10 +94,18 @@ # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set # CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set # # CLPS711X/EP721X Implementations # +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set # CONFIG_ARCH_EP7211 is not set # CONFIG_ARCH_EP7212 is not set # CONFIG_ARCH_ACORN is not set @@ -125,9 +145,11 @@ # PCMCIA/CardBus support # CONFIG_PCMCIA=y +CONFIG_PCMCIA_PROBE=y # CONFIG_I82092 is not set # CONFIG_I82365 is not set # CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set CONFIG_PCMCIA_SA1100=y CONFIG_NET=y CONFIG_SYSVIPC=y @@ -144,7 +166,7 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +CONFIG_PM=y # CONFIG_ARTHUR is not set CONFIG_CMDLINE="console=ttySA0,9600 console=tty1 root=/dev/mtdblock2 init=/linuxrc" # CONFIG_LEDS is not set @@ -186,6 +208,9 @@ # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set # # Mapping drivers for chip access @@ -193,15 +218,20 @@ # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_NORA is not set # CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set CONFIG_MTD_SA1100=y +# CONFIG_MTD_DC21285 is not set # CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_PCI is not set # # Self-contained MTD device drivers # +# CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set +CONFIG_MTD_SHANNON_SERIALFLASH=y # # Disk-On-Chip Device Drivers @@ -220,12 +250,17 @@ # Plug and Play configuration # # CONFIG_PNP is not set +# CONFIG_ISAPNP is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -236,6 +271,13 @@ # Multi-device support (RAID and LVM) # # CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -257,6 +299,7 @@ # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set # # @@ -297,6 +340,12 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set @@ -311,9 +360,16 @@ # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set +# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -327,6 +383,7 @@ # # CONFIG_TR is not set # CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -345,6 +402,9 @@ # CONFIG_PCMCIA_NMCLAN is not set CONFIG_PCMCIA_SMC91C92=y # CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set # CONFIG_NET_PCMCIA_RADIO is not set # @@ -373,22 +433,35 @@ # CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set # CONFIG_BLK_DEV_IDEDISK is not set +# CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_BLK_DEV_IDESCSI is not set # # IDE chipset support/bugfixes # # CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set # # SCSI support @@ -399,6 +472,10 @@ # I2O device support # # CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set # # ISDN subsystem @@ -420,15 +497,34 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y CONFIG_SA1100_DEFAULT_BAUDRATE=9600 # CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y @@ -443,10 +539,13 @@ # L3 serial bus support # # CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set # # Other L3 adapters # +# CONFIG_L3_SA1111 is not set # CONFIG_BIT_SA1100_GPIO is not set # @@ -459,11 +558,36 @@ # Joysticks # # CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set # CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set # # Joysticks # +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set # @@ -477,6 +601,8 @@ # CONFIG_PCWATCHDOG is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set CONFIG_SA1100_WATCHDOG=y # CONFIG_EUROTECH_WDT is not set # CONFIG_IB700_WDT is not set @@ -485,9 +611,13 @@ # CONFIG_60XX_WDT is not set # CONFIG_W83877F_WDT is not set # CONFIG_MACHZ_WDT is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set CONFIG_SA1100_RTC=y +CONFIG_SHANNON_IRKBD=y +CONFIG_SHANNON_SPI=y +CONFIG_SHANNON_WHEATIES=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -515,13 +645,16 @@ # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set @@ -534,19 +667,27 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set CONFIG_MINIX_FS=y -# CONFIG_FREEVXFS_FS is not set +# CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set # CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems @@ -555,11 +696,21 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set # CONFIG_ZLIB_FS_INFLATE is not set @@ -636,8 +787,28 @@ # CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set CONFIG_FB_SA1100=y +# CONFIG_FB_CYBER2000 is not set # CONFIG_FB_VIRTUAL is not set + +# +# Backlight support +# +CONFIG_FB_BACKLIGHT=y +CONFIG_BACKLIGHT_PM=y +CONFIG_BACKLIGHT_INPUT=y + +# +# Devices +# +# CONFIG_ASSABET_BACKLIGHT is not set +# CONFIG_HUW_WEBPANEL_BACKLIGHT is not set +# CONFIG_FREEBIRD_BACKLIGHT is not set +# CONFIG_OMNIMETER_BACKLIGHT is not set +CONFIG_SHANNON_BACKLIGHT=y # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB2=y CONFIG_FBCON_CFB4=y @@ -653,17 +824,34 @@ # CONFIG_SOUND=y # CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set CONFIG_SOUND_SA1100=y +# CONFIG_SOUND_UDA1341 is not set +# CONFIG_SOUND_ASSABET_UDA1341 is not set +# CONFIG_SOUND_H3600_UDA1341 is not set +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +# CONFIG_SOUND_SA1111_UDA1341 is not set # CONFIG_SOUND_SA1100SSP is not set # CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_TVMIXER is not set # # Multimedia Capabilities Port drivers @@ -682,18 +870,45 @@ # # USB Controllers # +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set # # USB Device Class drivers # +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set # # USB Human Interface Devices (HID) # +# CONFIG_USB_HID is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set # # USB Imaging devices # +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -706,18 +921,50 @@ # # USB Network adaptors # +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set # # USB port drivers # +# CONFIG_USB_USS720 is not set # # USB Serial Converter support # +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set # # USB Miscellaneous drivers # +# CONFIG_USB_RIO500 is not set # # Bluetooth support @@ -728,10 +975,16 @@ # Kernel hacking # # CONFIG_NO_FRAME_POINTER is not set -CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_USER=y # CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SLAB is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set Index: tlinux/arch/arm/kernel/debug-armv.S diff -u tlinux/arch/arm/kernel/debug-armv.S:1.1.1.1 tlinux/arch/arm/kernel/debug-armv.S:1.1.1.1.12.1 --- tlinux/arch/arm/kernel/debug-armv.S:1.1.1.1 Wed Oct 31 13:20:54 2001 +++ tlinux/arch/arm/kernel/debug-armv.S Mon Dec 10 15:11:07 2001 @@ -169,8 +169,11 @@ tst \rx, #1 @ MMU enabled? moveq \rx, #0x80000000 @ physical base address movne \rx, #0xf8000000 @ virtual address - @add \rx, \rx, #0x00050000 @ Ser3 +#if defined(CONFIG_SA1100_SHANNON) + add \rx, \rx, #0x00050000 @ Ser3 +#else add \rx, \rx, #0x00010000 @ Ser1 +#endif .endm .macro senduart,rd,rx Index: tlinux/arch/arm/mach-sa1100/shannon.c diff -u tlinux/arch/arm/mach-sa1100/shannon.c:1.1.1.2 tlinux/arch/arm/mach-sa1100/shannon.c:1.1.1.2.4.1 --- tlinux/arch/arm/mach-sa1100/shannon.c:1.1.1.2 Thu Nov 29 20:31:22 2001 +++ tlinux/arch/arm/mach-sa1100/shannon.c Mon Dec 10 15:11:07 2001 @@ -13,6 +13,8 @@ #include #include +#include + #include "generic.h" @@ -24,21 +26,40 @@ static void __init shannon_map_io(void) { + unsigned long gpio_inputs; + unsigned long gpio_outputs; sa1100_map_io(); iotable_init(shannon_io_desc); sa1100_register_uart(0, 3); sa1100_register_uart(1, 1); Ser1SDCR0 |= SDCR0_SUS; - GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); - GPDR |= GPIO_UART_TXD; - GPDR &= ~GPIO_UART_RXD; PPAR |= PPAR_UPR; + + gpio_outputs = GPIO_UART_TXD | SHANNON_GPIO_CODEC_RESET | + SHANNON_GPIO_DISP_EN | SHANNON_GPIO_SPI_FLASH | + SHANNON_GPIO_SPI_DSP | SHANNON_GPIO_SPI_OUTPUT | + SHANNON_GPIO_SPI_CLOCK | SHANNON_GPIO_SPI_FRAME | + SHANNON_GPIO_SPI_CTS | SHANNON_GPIO_DSP_RESET; + + gpio_inputs = GPIO_UART_RXD | SHANNON_GPIO_IRQ_CODEC | + SHANNON_GPIO_SPI_INPUT | SHANNON_GPIO_SPI_RTS | + SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | + SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1 | + SHANNON_GPIO_SENSE_12V; + + GAFR &= ~(gpio_inputs | gpio_outputs); + GPDR = gpio_outputs; } MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") +#ifdef CONFIG_SA1100_SHANNON_32M + BOOT_MEM(0xd0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xd0000100) +#else BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) BOOT_PARAMS(0xc0000100) +#endif MAPIO(shannon_map_io) INITIRQ(sa1100_init_irq) MACHINE_END Index: tlinux/drivers/char/Config.in diff -u tlinux/drivers/char/Config.in:1.1.1.3 tlinux/drivers/char/Config.in:1.1.1.3.6.1 --- tlinux/drivers/char/Config.in:1.1.1.3 Mon Nov 19 01:12:06 2001 +++ tlinux/drivers/char/Config.in Mon Dec 10 15:11:07 2001 @@ -188,6 +188,11 @@ fi if [ "$CONFIG_ARCH_SA1100" = "y" ]; then tristate 'SA1100 Real Time Clock' CONFIG_SA1100_RTC + if [ "$CONFIG_SA1100_SHANNON" = "y" ]; then + dep_tristate 'Shannon IR keyboard support' CONFIG_SHANNON_IRKBD $CONFIG_INPUT + tristate 'Shannon SPI bus support' CONFIG_SHANNON_SPI + dep_tristate 'Shannon DSP1653 aka wheaties support' CONFIG_SHANNON_WHEATIES $CONFIG_SHANNON_SPI + fi fi tristate 'Double Talk PC internal speech card support' CONFIG_DTLK Index: tlinux/drivers/char/Makefile diff -u tlinux/drivers/char/Makefile:1.1.1.3 tlinux/drivers/char/Makefile:1.1.1.3.2.1 --- tlinux/drivers/char/Makefile:1.1.1.3 Mon Dec 10 14:51:39 2001 +++ tlinux/drivers/char/Makefile Mon Dec 10 15:11:07 2001 @@ -23,7 +23,8 @@ export-objs := busmouse.o console.o keyboard.o sysrq.o \ misc.o pty.o random.o selection.o serial.o \ - sonypi.o tty_io.o tty_ioctl.o generic_serial.o + sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ + spi.o mod-subdirs := joystick ftape drm pcmcia @@ -89,6 +90,9 @@ KEYMAP = gckeymap.o KEYBD += gc_keyb.o endif + ifeq ($(CONFIG_SA1100_SHANNON),y) + KEYBD = input_keyb.o + endif ifeq ($(CONFIG_SA1100_CERF_CPLD),y) KEYBD += cerf_keyb.o endif @@ -150,6 +154,9 @@ obj-$(CONFIG_SERIAL) += $(SERIAL) obj-$(CONFIG_SERIAL_ACPI) += acpi_serial.o obj-$(CONFIG_TOUCHSCREEN_ANAKIN) += anakin_ts.o +obj-$(CONFIG_SHANNON_IRKBD) += shannon_irkbd.o +obj-$(CONFIG_SHANNON_SPI) += spi.o +obj-$(CONFIG_SHANNON_WHEATIES) += wheaties.o ifndef CONFIG_SUN_KEYBOARD obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD) Index: tlinux/drivers/char/defkeymap.c diff -u tlinux/drivers/char/defkeymap.c:1.1.1.1 tlinux/drivers/char/defkeymap.c:1.1.1.1.12.1 --- tlinux/drivers/char/defkeymap.c:1.1.1.1 Wed Oct 31 13:22:40 2001 +++ tlinux/drivers/char/defkeymap.c Mon Dec 10 15:11:07 2001 @@ -37,7 +37,7 @@ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, @@ -56,7 +56,7 @@ 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, @@ -94,7 +94,7 @@ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, @@ -132,7 +132,7 @@ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a, 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, Index: tlinux/drivers/char/input_keyb.c diff -u /dev/null tlinux/drivers/char/input_keyb.c:1.1.12.1 --- /dev/null Mon Dec 10 16:54:51 2001 +++ tlinux/drivers/char/input_keyb.c Mon Dec 10 15:11:07 2001 @@ -0,0 +1,176 @@ +/* + * linux/drivers/char/input_keyb.c by Russ Dill + * taken from pc_keyb.c + * + * This code grabs keypresses from the input layer and makes them + * available to the console. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* Simple translation table for the SysRq keys */ + +#ifdef CONFIG_MAGIC_SYSRQ +unsigned char input_sysrq_xlate[128] = + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/"; /* 0x60 - 0x6f */ +#endif + +/* + * Translation of escaped scancodes to keycodes. + * This is now user-settable. + * The keycodes 1-88,96-111,119 are fairly standard, and + * should probably not be changed - changing might confuse X. + * X also interprets scancode 0x5d (KEY_Begin). + * + * For 1-88 keycode equals scancode. + */ + +#define E0_KPENTER 96 +#define E0_RCTRL 97 +#define E0_KPSLASH 98 +#define E0_PRSCR 99 +#define E0_RALT 100 +#define E0_BREAK 101 /* (control-pause) */ +#define E0_HOME 102 +#define E0_UP 103 +#define E0_PGUP 104 +#define E0_LEFT 105 +#define E0_RIGHT 106 +#define E0_END 107 +#define E0_DOWN 108 +#define E0_PGDN 109 +#define E0_INS 110 +#define E0_DEL 111 + +#define E1_PAUSE 119 + +/* + * New microsoft keyboard is rumoured to have + * e0 5b (left window button), e0 5c (right window button), + * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] + * [or: Windows_L, Windows_R, TaskMan] + */ +#define E0_MSLW 125 + +static unsigned char e0_keys[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ + 0, 0, 0, 0, 0, E0_RCTRL, 0, 0, /* 0x18-0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ + 0, 0, 0, 0, 0, 0, 0, E0_PRSCR, /* 0x30-0x37 */ + E0_RALT, 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f */ + 0, 0, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */ + E0_UP, E0_PGUP, 0, E0_LEFT, 0, E0_RIGHT, 0, E0_END, /* 0x48-0x4f */ + E0_DOWN, E0_PGDN, 0, 0, 0, 0, 0, 0, /* 0x50-0x57 */ + 0, 0, 0, E0_MSLW, 0, 0, 0, 0, /* 0x58-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */ +}; + +int input_setkeycode(unsigned int scancode, unsigned int keycode) +{ + if (scancode > 255 || keycode > 127) return -EINVAL; + e0_keys[scancode - 128] = keycode; + return 0; +} + +int input_getkeycode(unsigned int scancode) +{ + return scancode > 255 ? -EINVAL : e0_keys[scancode - 128]; +} + +/* #define KBD_REPORT_UNKN */ +int input_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + static int prev_scancode; + + /* special prefix scancodes.. */ + if (scancode == 0xe0 || scancode == 0xe1) { + prev_scancode = scancode; + return 0; + } + + if (prev_scancode) { + /* + * usually it will be 0xe0, but a Pause key generates + * e1 1d 45 e1 9d c5 when pressed, and nothing when released + */ + if (prev_scancode != 0xe0) { + if (prev_scancode == 0xe1 && scancode == 0x1d) { + prev_scancode = 0x100; + return 0; + } else if (prev_scancode == 0x100 && scancode == 0x45) { + *keycode = E1_PAUSE; + prev_scancode = 0; + } else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown e1 escape sequence\n"); +#endif + prev_scancode = 0; + return 0; + } + } else { + prev_scancode = 0; + + if (e0_keys[scancode]) + *keycode = e0_keys[scancode]; + else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n", + scancode); +#endif + return 0; + } + } + } else + *keycode = scancode; + return 1; +} + +char input_unexpected_up(unsigned char keycode) +{ + return 0200; +} + Index: tlinux/drivers/char/shannon_irkbd.c diff -u /dev/null tlinux/drivers/char/shannon_irkbd.c:1.1.10.1 --- /dev/null Mon Dec 10 16:54:51 2001 +++ tlinux/drivers/char/shannon_irkbd.c Mon Dec 10 15:11:07 2001 @@ -0,0 +1,433 @@ +/* + * Shannon IR keyboard driver, (C) 2001 Russ Dill + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Madule Information + */ +#define DRIVER_AUTHOR "Russ Dill dev.key)) { +#ifdef DEBUG + printk(KERN_INFO "Breaking 0x%02x\n", shannon_kbd_keycode[i]); +#endif + input_report_key(&kbd->dev, shannon_kbd_keycode[i], 0); + } + } +} + + +static void shannon_kbd_timeout(unsigned long data) +{ + struct shannon_kbd *kbd = (struct shannon_kbd *) data; + int flags; + + /* avoid interference with interrupt */ + spin_lock_irqsave(&kbd->timer_lock, flags); + break_all(kbd); + + spin_unlock_irqrestore(&kbd->timer_lock, flags); +} + + +static void start_timer(struct shannon_kbd *kbd) +{ + if (kbd->timer_running) return; + kbd->timer.expires = jiffies + (HZ * 5); + add_timer(&kbd->timer); + kbd->timer_running = 1; +} + + +static void stop_timer(struct shannon_kbd *kbd) +{ + if (!kbd->timer_running) return; + del_timer(&kbd->timer); + kbd->timer_running = 0; +} + + +static void shannon_kbd_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct shannon_kbd *kbd = (struct shannon_kbd *) dev_id; + unsigned long data; + int status, err; + int flags; + + spin_lock_irqsave(&kbd->timer_lock, flags); + stop_timer(kbd); + + status = Ser2UTSR0; + + while (Ser2UTSR1 & UTSR1_RNE) { + err = Ser2UTSR1; + data = Ser2UTDR; + + if (err & (UTSR1_FRE | UTSR1_ROR | UTSR1_PRE)) { + kbd->last_key = 0; + continue; + } + + if (kbd->last_key == KEY_MAKE) { + input_report_key(&kbd->dev, shannon_kbd_keycode[data], 1); + + /* restart timer */ + start_timer(kbd); + } else if (kbd->last_key == KEY_BREAK) { + if (data) { + input_report_key(&kbd->dev, shannon_kbd_keycode[data], 0); + /* restart timer */ + start_timer(kbd); + } else { + stop_timer(kbd); + + break_all(kbd); + } + } + kbd->last_key = data; + } + spin_unlock_irqrestore(&kbd->timer_lock, flags); + + /* + * We must clear certain bits. + */ + status &= UTSR0_RID | UTSR0_RBB | UTSR0_REB; + if (status) Ser2UTSR0 = status; + +} + +#if DEBUG +static void dump_regs(void) +{ + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTCR0: %02x\n",Ser2UTCR0); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTCR1: %02x\n",Ser2UTCR1); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTCR2: %02x\n",Ser2UTCR2); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTCR3: %02x\n",Ser2UTCR3); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTCR4: %02x\n",Ser2UTCR4); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTDR: %02x\n",Ser2UTDR); + + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTSR0: %02x\n",Ser2UTSR0); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2UTSR1: %02x\n",Ser2UTSR1); + + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2HSCR0: %02x\n",Ser2HSCR0); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2HSCR1: %02x\n",Ser2HSCR1); + printk(KERN_INFO LIRC_DRIVER_NAME " Ser2HSCR2: %02x\n",Ser2HSCR2); +} +#endif + +static int init_hardware(struct shannon_kbd *kbd) +{ + int flags; + + spin_lock_irqsave(&kbd->hardware_lock, flags); + /* reset UART */ +#ifdef DEBUG + dump_regs(); +#endif + kbd->sr.hscr0 = Ser2HSCR0; + + kbd->sr.utcr0 = Ser2UTCR0; + kbd->sr.utcr1 = Ser2UTCR1; + kbd->sr.utcr2 = Ser2UTCR2; + kbd->sr.utcr3 = Ser2UTCR3; + kbd->sr.utcr4 = Ser2UTCR4; + + kbd->sr.utdr = Ser2UTDR; + kbd->sr.utsr0 = Ser2UTSR0; + kbd->sr.utsr1 = Ser2UTSR1; + + /* + * Enable NRZ modulation, and ensure that the port is disabled. + */ + Ser2UTCR3 = 0; + Ser2HSCR0 = kbd->sr.hscr0 & ~HSCR0_HSSP; + + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= UTSR0_RID | UTSR0_RBB | UTSR0_REB; + + /* 8O1 */ + Ser2UTCR0 = UTCR0_8BitData | UTCR0_PE | UTCR0_OddPar | UTCR0_1StpBit; + /* 1266 baud */ + Ser2UTCR1 = 0; + Ser2UTCR2 = 0xb5; + + Ser2UTCR4 = UTCR4_NRZ; + Ser2HSCR2 = HSCR2_RcDataH | HSCR2_TrDataH; + + /* enable receiver, receive fifo interrupt */ + Ser2UTCR3 = UTCR3_RXE | UTCR3_RIE; + + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= UTSR0_RID | UTSR0_RBB | UTSR0_REB; + +#ifdef DEBUG + dump_regs(); +#endif + + kbd->last_key = 0; + + spin_unlock_irqrestore(&kbd->hardware_lock, flags); + return 0; +} + +static int init_irq(struct shannon_kbd *kbd) +{ + int retval; + + kbd->irq = IRQ_Ser2ICP; + + retval = request_irq(kbd->irq, shannon_kbd_irq, SA_INTERRUPT, "IR Keyboard", kbd); + if (retval < 0) { + printk(KERN_ERR "IRQ %d already in use.\n", kbd->irq); + return retval; + } + + return 0; +} + + +static int shannon_kbd_open(struct input_dev *dev) +{ + struct shannon_kbd *kbd = dev->private; + int retval; + + if (kbd->open++) return 0; + + init_timer(&kbd->timer); + kbd->timer.function = shannon_kbd_timeout; + kbd->timer.data = (unsigned long) kbd; + + retval = init_irq(kbd); + if (retval < 0) { + kbd->open_failed = 1; + return retval; + } + + init_hardware(kbd); + enable_irq(kbd->irq); + return 0; +} + +static void shannon_kbd_close(struct input_dev *dev) +{ + struct shannon_kbd *kbd = dev->private; + int flags; + + if (!--kbd->open && !kbd->open_failed) { + spin_lock_irqsave(&kbd->hardware_lock, flags); + + del_timer(&kbd->timer); + + Ser2UTCR3 = 0; + + Ser2UTCR0 = kbd->sr.utcr0; + Ser2UTCR1 = kbd->sr.utcr1; + Ser2UTCR2 = kbd->sr.utcr2; + Ser2UTCR4 = kbd->sr.utcr4; + Ser2UTCR3 = kbd->sr.utcr3; + + Ser2HSCR0 = kbd->sr.hscr0; + + disable_irq(kbd->irq); + free_irq(kbd->irq, kbd); + + spin_unlock_irqrestore(&kbd->hardware_lock, flags); + + } +} + + +static int __init shannon_kbd_init(void) +{ + int i; + struct shannon_kbd *kbd; + + global_kbd = kbd = kmalloc(sizeof(struct shannon_kbd), GFP_KERNEL); + if (!kbd) return -ENOMEM; + + memset(kbd, 0, sizeof(struct shannon_kbd)); + kbd->hardware_lock = SPIN_LOCK_UNLOCKED; + kbd->timer_lock = SPIN_LOCK_UNLOCKED; + strcpy(kbd->name, "Shannon IR Keyboard"); + + kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + + for (i = 0; i < 256; i++) { + if (shannon_kbd_keycode[i]) + set_bit(shannon_kbd_keycode[i], kbd->dev.keybit); + } + + kbd->dev.private = kbd; + kbd->dev.open = shannon_kbd_open; + kbd->dev.close = shannon_kbd_close; + kbd->dev.name = kbd->name; + kbd->dev.idbus = BUS_RS232; + + input_register_device(&kbd->dev); + + k_setkeycode = input_setkeycode; + k_getkeycode = input_getkeycode; + k_translate = input_translate; + k_unexpected_up = input_unexpected_up; +#ifdef CONFIG_MAGIC_SYSRQ + k_sysrq_key = 0x54; + k_sysrq_xlate = input_sysrq_xlate; +#endif + + printk(KERN_INFO "IR Keyboard driver installed\n"); + + return 0; +} + + +static void __exit shannon_kbd_exit(void) +{ + input_unregister_device(&global_kbd->dev); + kfree(global_kbd); + printk(KERN_INFO "IR Keyboard driver unloaded\n"); +} + +module_init(shannon_kbd_init); +module_exit(shannon_kbd_exit); Index: tlinux/drivers/char/spi.c diff -u /dev/null tlinux/drivers/char/spi.c:1.1.8.1 --- /dev/null Mon Dec 10 16:54:51 2001 +++ tlinux/drivers/char/spi.c Mon Dec 10 15:11:07 2001 @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spi.h" + +spinlock_t spi_lock = SPIN_LOCK_UNLOCKED; + +/* + * xfer_bits - write and read n bits - takes the bits from the top + * return the bits read - returns the bits at the bottom + * + * The SPI connection to the DSP is the meanest interface ever. It + * doesn't return a bit until we send it one. Nothin for nothin. How + * this impacts reading from DSP flash memory without simultaneously + * writing to it is for future investigation. + * + * To transfer a bit we set/clear the SPI_OUTPUT GPIO line, raise + * SPI_CLOCK, read the input bit from SPI_INPUT and lower + * SPI_CLOCK. The first bit is treated outside the loop, this is to + * improve performance. + */ +unsigned int +spi_xfer_bits(int device, unsigned int obits, int n) { + unsigned int ibits = 0; + + /* enable SPI connection to the device */ + if (device) + GPCR = device; + + /* set the first bit on the output line */ + if (obits & 0x80000000) + GPSR = SPI_OUTPUT; + else + GPCR = SPI_OUTPUT; + + for ( ; n > 0; n--) { + ibits <<= 1; + + udelay(1); + + GPSR = SPI_CLOCK; + if (GPLR & SPI_INPUT) + ibits |= 1; + + udelay(1); + + obits <<= 1; + if (obits & 0x80000000) + GPSR = SPI_OUTPUT; + else + GPCR = SPI_OUTPUT; + GPCR = SPI_CLOCK; + } + + /* disable SPI connection to the device */ + if (device) + GPSR = device; + + return ibits; +} + +unsigned char +spi_xfer_byte(unsigned char obyte) { + return spi_xfer_bits(SPI_DSP, obyte << 24, 8) & 0xff; +} + +/* + * read_byte - read a single byte from the Wheaties module. + * return 1 for success, 0 for failure. + * + * The xfer_byte command always requires a byte to transfer to the + * Wheaties, even when reading. Giving it 0 to transfer seems to keep + * it happy. + * + * The RTS bit is 0 when a byte is available on the SPI. This is + * checked first and 0 is returned if the RTS bit is set (no data). + * CTS is set to 1 to indicate that it is clear to send data. We loop + * waiting for Wheaties to set RTS to indicate the byte is available. + * After reading the byte we clear CTS and wait for RTS to clear. + * + * An additonal twist, for the last byte in a message RTS never + * clears, thus we hang around for a while, 500usecs, and then give + * up. So we exit this routine with RTS clear and that means more + * bytes in this message, or RTS set and that means we are done. It is + * not clear what would happen if the next message started within the + * 500 usec window. + */ +int +spi_read_byte(unsigned char *data) { + int i; + + if (GPLR & SPI_RTS) { + return 0; + } + + /* assert CTS */ + GPSR = SPI_CTS; + + /* wait for RTS to set - need to break after 2ms */ + do { + } while ((GPLR & SPI_RTS) == 0); + *data = spi_xfer_byte(0); + + udelay(100); + + /* clear CTS */ + GPCR = SPI_CTS; + + /* wait for RTS to clear, or 500usec */ + i = 0; + do { + i++; + udelay(1); + } while ((GPLR & SPI_RTS) && (i < 500)); + + return 1; +} + +void __exit +spi_cleanup(void) +{ +} + +/* + * init_spi - configure the GPIO lines and SA-1100 registers for the SPI. + */ +int __init +spi_init(void) +{ + int result = 0; + + /* configure alternative function mode for SPI */ + /* Note: we don't initialise SPI_RTS, but it's an input so who cares */ + /* Note: we DO initialise SPI_INPUT, which is also an input, weird */ + /* Note: SPI_RTS and SPI_CTS in GAFR should not need to be + cleared, someone else is setting them in another driver. */ + GAFR &= ~(SPI_RTS | SPI_CTS | SPI_OUTPUT | SPI_INPUT | SPI_CLOCK | SPI_FRAME); + GPCR = SPI_OUTPUT | SPI_INPUT | SPI_CLOCK | SPI_FRAME; + GPSR = SPI_FLASH | SPI_DSP; + GPCR = SPI_CTS; + + /* set GPIO inputs and outputs for SPI */ + GPDR |= SPI_FLASH; + GPDR |= SPI_DSP; + GPDR |= SPI_OUTPUT; + GPDR &= ~SPI_INPUT; + GPDR |= SPI_CLOCK; + GPDR |= SPI_FRAME; + GPDR &= ~SPI_RTS; + GPDR |= SPI_CTS; + GPDR |= DSP_RESET; + + /* RTS generates falling edge interrupts when it transitions from 1 to 0 */ + GFER |= SPI_RTS; + + /* + * Enable SSP on alternate function pins, SSP is still not really + * enabled until we set SCE in the Ser4MCCR0 register, but this + * allows us to use it when required. + * Note: that this accidentally clears UPR but may not be an issue. + */ + PPAR = PPAR_SPR; + + /* Clear the SSP control registers */ + Ser4SSCR0 = 0; + Ser4SSCR1 = 0; + + return result; +} + +module_init(spi_init); +module_exit(spi_cleanup); + +EXPORT_SYMBOL(spi_xfer_bits); +EXPORT_SYMBOL(spi_xfer_byte); +EXPORT_SYMBOL(spi_read_byte); +EXPORT_SYMBOL(spi_cleanup); Index: tlinux/drivers/char/spi.h diff -u /dev/null tlinux/drivers/char/spi.h:1.1.8.1 --- /dev/null Mon Dec 10 16:54:51 2001 +++ tlinux/drivers/char/spi.h Mon Dec 10 15:11:07 2001 @@ -0,0 +1,23 @@ +#define SPI_NODEV 0 /* Fake Output device, disables repeated + device selection */ +#define SPI_FLASH GPIO_GPIO0 /* Output - Driven low, + enables SPI to flash */ +#define SPI_DSP GPIO_GPIO1 /* Output - Driven low, + enables SPI to DSP */ +#define SPI_OUTPUT GPIO_GPIO10 /* Output - SPI output to DSP */ +#define SPI_INPUT GPIO_GPIO11 /* Input - SPI input from DSP */ +#define SPI_CLOCK GPIO_GPIO12 /* Output - Clock for SPI */ +#define SPI_FRAME GPIO_GPIO13 /* Output - Frame marker - not used */ +#define SPI_RTS GPIO_GPIO14 /* Input - SPI Ready to Send */ +#define SPI_CTS GPIO_GPIO15 /* Output - SPI Clear to Send */ +#define DSP_RESET GPIO_GPIO17 /* Output - Drive low to reset + the DSP */ + +#define IRQ_RTS IRQ_GPIO14 + +#define SPI_ALT (SPI_OUTPUT | SPI_INPUT | SPI_CLOCK | SPI_FRAME) + +extern int spi_read_byte(unsigned char *data); +extern unsigned int spi_xfer_bits(int device, unsigned int obits, int n); +extern unsigned char spi_xfer_byte(unsigned char obyte); +extern spinlock_t spi_lock; Index: tlinux/drivers/char/wheaties.c diff -u /dev/null tlinux/drivers/char/wheaties.c:1.1.12.1 --- /dev/null Mon Dec 10 16:54:51 2001 +++ tlinux/drivers/char/wheaties.c Mon Dec 10 15:11:08 2001 @@ -0,0 +1,521 @@ +/* + * wheaties.c + * + * TuxScreen aka Shannon device driver for the Wheaties DSP aka Lucent DSP1650. + * + * $Id: wheaties.c,v 1.1.12.1 2001/12/10 22:11:08 russ Exp $ + * + * (C) Copyright 2001 Derek Mulcahy + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Currently we delay 10ms after each message. Need to implement a write queue + * which will set a timer to ensure that messages are pumped out with the required + * spacing. This will remove the last serious delay (apart from the ~1sec in open). + * + * Currently we use a spin lock to protect everything, this is not nice and locks + * out all interrupts whilst we are reading/writing. The write queue will help. + * The serial ports are particularly unhappy with this situation and they say so! + * + * Search for Note: to find those areas which definitely need investigation. + * + */ + +/* Glossary: + * + * MCP - An 8 bit bus with DMA and FIFOs used to talk to the + * UCB1200. Mentioned here because it takes the pins from the SSP, + * which then defaults to using the pins we want for the SPI. + * Enabling and disabling the MCP/SSP happens in another driver + * and may impact this driver. You now understand why this driver + * has a glossary. + * + * SA-1100 - The StrongArm processor used in the TuxScreen, if you + * didn't know this then you probably don't want to read + * further. + * + * SPI - Serial Peripheral Interface, the serial interface connecting + * the SA-1100 with the Wheaties module, includes i/o, rts, cts and + * clock pins. Uses SA-1100 GPIO lines. The clock line is used to + * indicate when data is ready. When talking to the DSP we use the + * rts/cts lines to impose a message structure on the transfer. + * + * SSP - SA-1100 serial bus which can use the same lines as we use for + * the SPI. This appears to be a real mans bus with hardware + * support. SPI is a bit twiddling nightmare. Don't confuse the two. + * Further investigation indicates that we need to use the SSP + * mode for some transfers. + * + * Wheaties - The name of the modules which includes the DSP1650 chip + * and other hardware. Provides GPIO lines connected to LEDs, + * keypad etc. Generates and recognizes audio tones on speaker, + * telephone line, handset. Also talks to the UCB1200 and can + * emulate a modem (in your dreams buddy). + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WHEATIES_MAJOR 60 /* need a proper allocation, or use devfs? */ +#define WHEATIES_NAME "wheaties" + +#define SPI_NODEV 0 /* Fake Output device, disables repeated + device selection */ +#define SPI_FLASH GPIO_GPIO0 /* Output - Driven low, + enables SPI to flash */ +#define SPI_DSP GPIO_GPIO1 /* Output - Driven low, + enables SPI to DSP */ +#define SPI_OUTPUT GPIO_GPIO10 /* Output - SPI output to DSP */ +#define SPI_INPUT GPIO_GPIO11 /* Input - SPI input fro DSP */ +#define SPI_CLOCK GPIO_GPIO12 /* Output - Clock for SPI */ +#define SPI_FRAME GPIO_GPIO13 /* Output - Frame marker - not used */ +#define SPI_RTS GPIO_GPIO14 /* Input - SPI Ready to Send */ +#define SPI_CTS GPIO_GPIO15 /* Output - SPI Clear to Send */ +#define DSP_RESET GPIO_GPIO17 /* Output - Drive low to reset + the DSP */ + +#define IRQ_RTS IRQ_GPIO14 + +#define SPI_ALT (SPI_OUTPUT | SPI_INPUT | SPI_CLOCK | SPI_SFRM) + +/* + * we want to throw away old messages and a fixed size array which wraps around + * is the simplest way of doing this. The ancient kludge of storing the data in + * the pointer itself rather than allocating a tiny chunk is also used. If it + * was good enough for Dennis Ritchie it is good enough for us. + */ +#define MAX_MSGS 64 +#define MAX_MESSAGE_SIZE 1024 + +static struct msg { + int len; + int offset; + unsigned char *data; +} *msgs; +static int head; +static int tail; + +static spinlock_t lock = SPIN_LOCK_UNLOCKED; +static DECLARE_WAIT_QUEUE_HEAD(waitq); + +static int wheaties_open(struct inode * inode, struct file * filp); +static int wheaties_release(struct inode * inode, struct file * filp); +static ssize_t wheaties_read(struct file * , char * , size_t , loff_t * l); +static ssize_t wheaties_write(struct file *file, const char *buf, + size_t count, loff_t *ppos); +static unsigned int wheaties_poll(struct file *file, struct poll_table_struct *pts); +static int wheaties_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg); + +static struct file_operations wheaties_fops = { + open: wheaties_open, + release: wheaties_release, + read: wheaties_read, + write: wheaties_write, + poll: wheaties_poll, + ioctl: wheaties_ioctl, + owner: THIS_MODULE, +}; + +/* + * xfer_byte - write and read a byte + * return the character read + * + * The SPI connection to the DSP is the meanest interface ever. It + * doesn't return a bit until we send it one. Nothin for nothin. How + * this impacts reading from DSP flash memory without simultaneously + * writing to it is for future investigation. + * + * To transfer a bit we set/clear the SPI_OUTPUT GPIO line, raise + * SPI_CLOCK, read the input bit from SPI_INPUT and lower + * SPI_CLOCK. The first bit is treated outside the loop, this is to + * improve performance. + */ +static unsigned char xfer_byte(unsigned char obyte) { + unsigned char ibyte = 0; + int i; + int t; + + /* enable SPI connection to the DSP */ + GPCR = SPI_DSP; + + if (obyte & 0x80) + GPSR = SPI_OUTPUT; + else + GPCR = SPI_OUTPUT; + + t = 1; + for (i = 8; i > 0; i--) { + ibyte <<= 1; + udelay(t); + t = 5; + + GPSR = SPI_CLOCK; + if (GPLR & SPI_INPUT) + ibyte |= 1; + + udelay(t); + + obyte <<= 1; + if (obyte & 0x80) + GPSR = SPI_OUTPUT; + else + GPCR = SPI_OUTPUT; + GPCR = SPI_CLOCK; + } + + /* enable SPI connection to the DSP */ + GPSR = SPI_DSP; + + return ibyte; +} + +/* + * write_message - write a multi byte message to the Wheaties module. + * + * Round em up and head em out. + */ +static void write_message(int count, unsigned char *msg) { + int i; + + for (i = 0; i < count; i++) { + xfer_byte(msg[i]); + udelay(100); + } + /* not happy with this delay, 10ms after each message :-) */ + udelay(10 * 1000); +} + +/* + * read_byte - read a single byte from the Wheaties module. + * return 1 for success, 0 for failure. + * + * The xfer_byte command always requires a byte to transfer to the + * Wheaties, even when reading. Giving it 0 to transfer seems to keep + * it happy. + * + * The RTS bit is 0 when a byte is available on the SPI. This is + * checked first and 0 is returned if the RTS bit is set (no data). + * CTS is set to 1 to indicate that it is clear to send data. We loop + * waiting for Wheaties to set RTS to indicate the byte is available. + * After reading the byte we clear CTS and wait for RTS to clear. + * + * An additonal twist, for the last byte in a message RTS never + * clears, thus we hang around for a while, 500usecs, and then give + * up. So we exit this routine with RTS clear and that means more + * bytes in this message, or RTS set and that means we are done. It is + * not clear what would happen if the next message started within the + * 500 usec window. + */ +static int read_byte(unsigned char *data) { + int i; + + if (GPLR & SPI_RTS) { + return 0; + } + + /* assert CTS */ + GPSR = SPI_CTS; + + /* wait for RTS to set - need to break after 2ms */ + do { + } while ((GPLR & SPI_RTS) == 0); + *data = xfer_byte(0); + + udelay(200); + + /* clear CTS */ + GPCR = SPI_CTS; + + /* wait for RTS to clear, or 500usec */ + i = 0; + do { + i++; + udelay(1); + } while ((GPLR & SPI_RTS) && (i < 500)); + + return 1; +} + +/* + * read_message: read a message + * returns the number of bytes read. + */ +static int read_message(unsigned char *data, int limit) { + int i = 0; + + while((limit > 0) && read_byte(data + i)) { + i++; + limit--; + } + return i; +} + +static void +dsp_reset(void) +{ + GPCR = DSP_RESET; + + /* the reset needs a pulse width of at least 150us */ + udelay(200); + + GPSR = DSP_RESET; + + /* wait 800ms */ + sleep_on_timeout(&waitq, (800 * HZ) / 1000); +} + +static int +wheaties_open(struct inode * inode, struct file * filp) +{ + dsp_reset(); + return 0; +} + +static int +wheaties_release(struct inode * inode, struct file * filp) +{ + return 0; +} + +static ssize_t +wheaties_read(struct file * file, char * buf, size_t count, loff_t *ppos) +{ + struct msg *m; + void *p; + ssize_t result; + unsigned long flags; + + if( wait_event_interruptible(waitq, head != -1)) + return -ERESTARTSYS; + + spin_lock_irqsave(&lock, flags); + m = msgs + head; + if (m->len > sizeof(m->data)) { + p = m->data; + } else { + p = &m->data; + } + if (count > (m->len - m->offset)) { + count = m->len - m->offset; + } + /* Note: shouldn't hold spinlock while copying */ + if (copy_to_user(buf, p + m->offset, count)) { + result = -EFAULT; + goto out; + } + m->offset += count; + if (m->offset >= m->len) { + if (m->len > sizeof(m->data)) + kfree(m->data); + m->len = 0; + m->offset = 0; + head = (head + 1) % MAX_MSGS; + if (head == tail) { + head = -1; + tail = 0; + } + } + *ppos += count; + result = count; + + out: + spin_unlock_irqrestore(&lock, flags); + + return result; +} + +static ssize_t +wheaties_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + void *data; + ssize_t result = -ENOMEM; + unsigned long flags; + + data = kmalloc(count, GFP_KERNEL); + if (!data) + goto out; + if (copy_from_user(data,buf,count)) { + result = -EFAULT; + goto out; + } + spin_lock_irqsave(&lock, flags); + write_message(count, data); + spin_unlock_irqrestore(&lock, flags); + *ppos += count; + result = count; + + out: + if (data) + kfree(data); + return result; +} + +static unsigned int +wheaties_poll(struct file *file, struct poll_table_struct *pts) +{ + unsigned int mask = POLLOUT | POLLWRNORM; + + poll_wait(file, &waitq, pts); + if (head != -1) mask |= POLLIN | POLLRDNORM; + return mask; +} + +static int wheaties_ioctl(struct inode *inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case WHEATIES_IOC_RESET: + dsp_reset(); + break; + } + return 0; +} + +static void +rts_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + /* Note: kernel stack is pretty small - should allocate this */ + unsigned char data[MAX_MESSAGE_SIZE]; + struct msg *m; + void *p; + int n; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + while((n = read_message(data, sizeof(data)))) { + if (head == tail || head == -1) { + head = (head + 1) % MAX_MSGS; + } + m = msgs + tail; + if (m->len > sizeof(m->data)) + kfree(m->data); + /* Note: need to handle out of memory */ + if (n > sizeof(m->data)) { + m->data = kmalloc(n, GFP_ATOMIC); + p = m->data; + } else { + p = &m->data; + } + m->len = n; + m->offset = 0; + memcpy(p, data, n); + tail = (tail + 1) % MAX_MSGS; + } + spin_unlock_irqrestore(&lock, flags); + wake_up_interruptible(&waitq); +} + +/* + * init_spi - configure the GPIO lines and SA-1100 registers for the SPI. + */ +static void +init_spi(void) +{ + /* configure alternative function mode for SPI */ + /* Note: we don't initialise SPI_RTS, but it's an input so who cares */ + /* Note: we DO initialise SPI_INPUT, which is also an input, weird */ + /* Note: SPI_RTS and SPI_CTS in GAFR should not need to be + cleared, someone else is setting them in another driver. */ + GAFR &= ~(SPI_RTS | SPI_CTS | SPI_OUTPUT | SPI_INPUT | SPI_CLOCK | SPI_FRAME); + GPCR = SPI_OUTPUT | SPI_INPUT | SPI_CLOCK | SPI_FRAME; + GPSR = SPI_FLASH | SPI_DSP; + GPCR = SPI_CTS; + + /* set GPIO inputs and outputs for SPI */ + GPDR |= SPI_FLASH; + GPDR |= SPI_DSP; + GPDR |= SPI_OUTPUT; + GPDR &= ~SPI_INPUT; + GPDR |= SPI_CLOCK; + GPDR |= SPI_FRAME; + GPDR &= ~SPI_RTS; + GPDR |= SPI_CTS; + GPDR |= DSP_RESET; + + /* RTS generates falling edge interrupts when it transitions from 1 to 0 */ + GFER |= SPI_RTS; + + /* + * Enable SSP on alternate function pins, SSP is still not really + * enabled until we set SCE in the Ser4MCCR0 register, but this + * allows us to use it when required. + * Note: that this accidentally clears UPR but may not be an issue. + */ + PPAR = PPAR_SPR; + + /* Clear the SSP control registers */ + Ser4SSCR0 = 0; + Ser4SSCR1 = 0; +} + +int __init +wheaties_init(void) +{ + int result; + + result = register_chrdev(WHEATIES_MAJOR, WHEATIES_NAME, &wheaties_fops); + if (result) { + printk("Can't get major device %d for " WHEATIES_NAME " - result=%d.\n", + WHEATIES_MAJOR, result); + goto fail_chrdev; + } + + init_spi(); + + set_GPIO_IRQ_edge(SPI_RTS, GPIO_FALLING_EDGE); + result = request_irq(IRQ_RTS, rts_handler, SA_SHIRQ, WHEATIES_NAME, rts_handler); + if (result) { + printk("Can't get IRQ for " WHEATIES_NAME " RTS line - result=%d.\n", result); + goto fail_irq; + } + + if (!msgs) { + msgs = kmalloc(sizeof(struct msg) * MAX_MSGS, GFP_KERNEL); + if (!msgs) { + printk("Can't allocate memory for msgs in " WHEATIES_NAME "\n"); + result = -ENOMEM; + goto fail_msgs; + } + memset(msgs, 0, sizeof(struct msg) * MAX_MSGS); + head = -1; + tail = 0; + } + + return result; + +fail_msgs: + free_irq(IRQ_RTS, rts_handler); +fail_irq: + unregister_chrdev(WHEATIES_MAJOR, WHEATIES_NAME); +fail_chrdev: + return result; +} + +void __exit +wheaties_cleanup(void) +{ + if (msgs) { + kfree(msgs); + msgs = 0; + } + free_irq(IRQ_RTS, rts_handler); + unregister_chrdev(WHEATIES_MAJOR, WHEATIES_NAME); +} + +module_init(wheaties_init); +module_exit(wheaties_cleanup); Index: tlinux/drivers/misc/mcp-sa1100.c diff -u tlinux/drivers/misc/mcp-sa1100.c:1.1.1.2 tlinux/drivers/misc/mcp-sa1100.c:1.1.1.2.4.1 --- tlinux/drivers/misc/mcp-sa1100.c:1.1.1.2 Thu Nov 29 20:36:09 2001 +++ tlinux/drivers/misc/mcp-sa1100.c Mon Dec 10 15:11:09 2001 @@ -108,7 +108,7 @@ Ser4MCSR = -1; Ser4MCCR1 = 0; - Ser4MCCR0 = 0x00007f7f; + Ser4MCCR0 = 0x00047f7f; mcp_register(&mcp_sa1100); } Index: tlinux/drivers/misc/ucb1x00-audio.c diff -u tlinux/drivers/misc/ucb1x00-audio.c:1.1.1.2 tlinux/drivers/misc/ucb1x00-audio.c:1.1.1.2.4.1 --- tlinux/drivers/misc/ucb1x00-audio.c:1.1.1.2 Thu Nov 29 20:36:09 2001 +++ tlinux/drivers/misc/ucb1x00-audio.c Mon Dec 10 15:11:09 2001 @@ -196,6 +196,7 @@ a->state.input_id = "UCB1x00 audio in"; a->state.output_dma = ucb->mcp->dma_audio_wr; a->state.output_id = "UCB1x00 audio out"; + a->state.need_tx_for_rx = 1; a->dev_id = register_sound_dsp(&a->fops, -1); audio = a; } Index: tlinux/drivers/misc/ucb1x00-core.c diff -u tlinux/drivers/misc/ucb1x00-core.c:1.1.1.3 tlinux/drivers/misc/ucb1x00-core.c:1.1.1.3.4.1 --- tlinux/drivers/misc/ucb1x00-core.c:1.1.1.3 Thu Nov 29 20:36:09 2001 +++ tlinux/drivers/misc/ucb1x00-core.c Mon Dec 10 15:11:09 2001 @@ -454,6 +454,13 @@ unsigned int id; int ret = -ENODEV; + if (machine_is_shannon()) { + /* reset the codec */ + GPCR = SHANNON_GPIO_CODEC_RESET; + GPSR = SHANNON_GPIO_CODEC_RESET; + + } + mcp = mcp_get(); if (!mcp) goto no_mcp; @@ -470,14 +477,6 @@ ret = -ENOMEM; if (!my_ucb) goto out; - - if (machine_is_shannon()) { - /* reset the codec */ - GPDR |= SHANNON_GPIO_CODEC_RESET; - GPCR = SHANNON_GPIO_CODEC_RESET; - GPSR = SHANNON_GPIO_CODEC_RESET; - - } memset(my_ucb, 0, sizeof(struct ucb1x00)); Index: tlinux/drivers/mtd/bootldr.c diff -u tlinux/drivers/mtd/bootldr.c:1.1.1.1 tlinux/drivers/mtd/bootldr.c:1.1.1.1.12.1 --- tlinux/drivers/mtd/bootldr.c:1.1.1.1 Wed Oct 31 13:22:25 2001 +++ tlinux/drivers/mtd/bootldr.c Mon Dec 10 15:11:09 2001 @@ -51,10 +51,12 @@ #define BOOTLDR_MAGIC_OFFSET 0x20 /* offset 0x20 into the bootldr */ #define BOOTCAP_OFFSET 0X30 /* offset 0x30 into the bootldr */ +#define BOOTOFFSET_OFFSET 0X34 /* offset 0x34 into the bootldr */ #define BOOTCAP_WAKEUP (1<<0) #define BOOTCAP_PARTITIONS (1<<1) /* partition table stored in params sector */ #define BOOTCAP_PARAMS_AFTER_BOOTLDR (1<<2) /* params sector right after bootldr sector(s), else in last sector */ +#define BOOTCAP_BY_OFFSET (1<<3) /* offset is found by offset in the boot loader */ int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts) { @@ -64,6 +66,7 @@ long partition_table_offset; long bootmagic = 0; long bootcap = 0; + long offset; int namelen = 0; struct BootldrFlashPartitionTable *partition_table = NULL; char *names; @@ -79,12 +82,25 @@ if (ret) goto out; - if (!(bootcap & BOOTCAP_PARTITIONS)) + if (bootcap & BOOTCAP_PARTITIONS) { + if (bootcap & BOOTCAP_PARAMS_AFTER_BOOTLDR) + partition_table_offset = master->erasesize; + else + partition_table_offset = master->size - master->erasesize; + } else if (bootcap & BOOTCAP_BY_OFFSET) { + /* Get the offset to the offset from the boot loader */ + ret = master->read(master, BOOTOFFSET_OFFSET, sizeof(long), &retlen, (void *)&offset); + if (ret) + goto out; + + /* get the offset */ + ret = master->read(master, offset, sizeof(long), &retlen, (void *)&offset); + if (ret || !offset) /* NULL offset means no table */ + goto out; + + partition_table_offset = offset; + } else goto out; - if (bootcap & BOOTCAP_PARAMS_AFTER_BOOTLDR) - partition_table_offset = master->erasesize; - else - partition_table_offset = master->size - master->erasesize; printk(__FUNCTION__ ": partition_table_offset=%#lx\n", partition_table_offset); Index: tlinux/drivers/mtd/mtdblock.c diff -u tlinux/drivers/mtd/mtdblock.c:1.1.1.2 tlinux/drivers/mtd/mtdblock.c:1.1.1.2.10.1 --- tlinux/drivers/mtd/mtdblock.c:1.1.1.2 Mon Nov 5 23:12:59 2001 +++ tlinux/drivers/mtd/mtdblock.c Mon Dec 10 15:11:09 2001 @@ -376,7 +376,6 @@ if (inode == NULL) release_return(-ENODEV); - invalidate_device(inode->i_rdev, 1); dev = MINOR(inode->i_rdev); mtdblk = mtdblks[dev]; Index: tlinux/drivers/mtd/devices/Config.in diff -u tlinux/drivers/mtd/devices/Config.in:1.1.1.1 tlinux/drivers/mtd/devices/Config.in:1.1.1.1.12.1 --- tlinux/drivers/mtd/devices/Config.in:1.1.1.1 Wed Oct 31 13:22:25 2001 +++ tlinux/drivers/mtd/devices/Config.in Mon Dec 10 15:11:09 2001 @@ -23,6 +23,9 @@ fi fi dep_tristate ' MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD +if [ "$CONFIG_SA1100_SHANNON" = "y" ]; then + dep_tristate ' Shannon Atmel Serial FlashSupport' CONFIG_MTD_SHANNON_SERIALFLASH $CONFIG_MTD $CONFIG_SHANNON_SPI +fi comment 'Disk-On-Chip Device Drivers' dep_tristate ' M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD Index: tlinux/drivers/mtd/devices/Makefile diff -u tlinux/drivers/mtd/devices/Makefile:1.1.1.1 tlinux/drivers/mtd/devices/Makefile:1.1.1.1.12.1 --- tlinux/drivers/mtd/devices/Makefile:1.1.1.1 Wed Oct 31 13:22:25 2001 +++ tlinux/drivers/mtd/devices/Makefile Mon Dec 10 15:11:09 2001 @@ -20,6 +20,7 @@ obj-$(CONFIG_MTD_PMC551) += pmc551.o obj-$(CONFIG_MTD_MTDRAM) += mtdram.o obj-$(CONFIG_MTD_LART) += lart.o +obj-$(CONFIG_MTD_SHANNON_SERIALFLASH) += serial_flash.o obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o include $(TOPDIR)/Rules.make Index: tlinux/drivers/mtd/devices/serial_flash.c diff -u /dev/null tlinux/drivers/mtd/devices/serial_flash.c:1.1.8.1 --- /dev/null Mon Dec 10 16:54:51 2001 +++ tlinux/drivers/mtd/devices/serial_flash.c Mon Dec 10 15:11:09 2001 @@ -0,0 +1,305 @@ +/* + * serial_flash.c + * + * MTD style driver for Atmel Serial Flash on TuxScreen + * + * $Id: serial_flash.c,v 1.1.8.1 2001/12/10 22:11:09 russ Exp $ + * + * (C) Copyright 2001 Derek Mulcahy + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * $Id: serial_flash.c,v 1.1.8.1 2001/12/10 22:11:09 russ Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../char/spi.h" + +/*#define VERBOSE*/ + +static struct mtd_info *mtd; + +static void +flash_wait(void) +{ + GPCR = SPI_FLASH; + + spi_xfer_bits(SPI_NODEV, 0x57<<24, 9); + + /* loops about 14000 times (17ms) - should be replaced with something better */ + while (!(GPLR & SPI_INPUT)) { + udelay(1); + } + + GPSR = SPI_FLASH; + + /* Delay for Tcs - 250ns between disable and enable of flash */ + udelay(1); +} + +static void +read_page(int page, unsigned char *data, int len) { + int sssr; + unsigned long flags; + int j = 0; + int i = 0; + + flash_wait(); + + GPCR = SPI_FLASH; + /* Delay 250ns between enable flash and clock */ + + spin_lock_irqsave(&spi_lock, flags); + spi_xfer_bits(SPI_NODEV, (0x52 << 24) | (page << 9) | 0x00, 32); + spi_xfer_bits(SPI_NODEV, 0, 32 + 1); + + Ser4SSCR0 = (0 << 8) | SSCR0_SSE | SSCR0_Motorola | SSCR0_DataSize(8); + + /* configure alternate function mode for GPIO pins */ + GAFR |= SPI_ALT; + + while (1) { + sssr = Ser4SSSR; + if (sssr & SSSR_RNE) { + data[j] = Ser4SSDR; + if (++j >= len) + break; + } + if ((i < len) && (sssr & SSSR_TNF)) { + Ser4SSDR = 0; + i++; + } + } + spin_unlock_irqrestore(&spi_lock, flags); + + Ser4SSCR0 = 0; + + /* unconfigure alternate function mode for GPIO pins */ + GAFR &= ~SPI_ALT; + + GPSR = SPI_FLASH; + /* Delay 250ns between disable and enable of flash */ + udelay(1); +} + +#if 0 +/* neither of the erase routines work - they don't set the busy bit */ + +static void +erase_page(int page) { + flash_wait(); + + spi_xfer_bits(SPI_FLASH, (0x81 << 24) | (page << 9) | 0x00, 32); + + /* Delay for Tcs - 250ns between disable and enable of flash */ + udelay(1); +} + +static void +erase_block(int block) { + flash_wait(); + + spi_xfer_bits(SPI_FLASH, (0x50 << 24) | (block << 12) | 0x00, 32); + + /* Delay for Tcs - 250ns between disable and enable of flash */ + udelay(1); +} +#endif + +static void +write_page(int page, const unsigned char *data, int len) { + int sssr; + int ssdr; + unsigned long flags; + int j = 0; + int i = 0; + + flash_wait(); + + GPCR = SPI_FLASH; + + spin_lock_irqsave(&spi_lock, flags); + spi_xfer_bits(SPI_NODEV, (0x82 << 24) | (page << 9) | 0x00, 32); + + Ser4SSCR0 = (0 << 8) | SSCR0_SSE | SSCR0_Motorola | SSCR0_DataSize(8); + + /* configure alternate function mode for GPIO pins */ + GAFR |= SPI_ALT; + + while (1) { + sssr = Ser4SSSR; + if ((j < len) && (sssr & SSSR_TNF)) { + Ser4SSDR = data[j++] << 8; + } + if ((i < len) && (sssr & SSSR_RNE)) { + ssdr = Ser4SSDR; + i++; + } + /* + * Break when all the data sent has been received, this ensures + * that the data in the fifo has been flushed out. + */ + if ((j >= len) && (i >= len)) + break; + } + spin_unlock_irqrestore(&spi_lock, flags); + + Ser4SSCR0 = 0; + + /* unconfigure alternate function mode for GPIO pins */ + GAFR &= ~SPI_ALT; + + GPSR = SPI_FLASH; + + /* Delay for Tcs - 250ns between disable and enable of flash */ + udelay(1); +} + +/* struct erase_info { */ +/* struct mtd_info *mtd; */ +/* u_int32_t addr; */ +/* u_int32_t len; */ +/* u_long time; */ +/* u_long retries; */ +/* u_int dev; */ +/* u_int cell; */ +/* void (*callback) (struct erase_info *self); */ +/* u_long priv; */ +/* u_char state; */ +/* struct erase_info *next; */ +/* }; */ + +static int +serial_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + int i; + unsigned char data[264]; + +#ifdef VERBOSE + printk(__FUNCTION__ " addr=%08x len=%08x\n", instr->addr, instr->len); +#endif + + memset(data, 0xff, sizeof(data)); + + for (i = 0; i < instr->len; i += 256) { + write_page((instr->addr + i) / 256, data, 264); + } + instr->state = MTD_ERASE_DONE; + if (instr->callback) + (*(instr->callback))(instr); + return 0; +} + +static int +serial_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, + unsigned char *buf) +{ + int i; + unsigned char data[264]; + +#ifdef VERBOSE + printk(__FUNCTION__ " from=%d len=%d buf=%p\n", (int)from, len, buf); +#endif + + for (i = 0; i < len; i += 256) { + read_page((from + i) / 256, data, 264); + memcpy(buf + i, data, 256); + } + *retlen = len; + return 0; +} + +static int +serial_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, + const unsigned char *buf) +{ + int i; + unsigned char data[264]; + +#ifdef VERBOSE + printk(__FUNCTION__ " to=%d len=%d buf=%p\n", (int)to, len, buf); +#endif + + memset(data, 0, sizeof(data)); + + for (i = 0; i < len; i += 256) { + memcpy(data, buf + i, 256); + write_page((to + i) / 256, data, 264); + } + *retlen = len; + return 0; +} + +static void serial_sync (struct mtd_info *mtd) +{ +#ifdef VERBOSE + printk(__FUNCTION__ "\n"); +#endif +} + +static void __exit +serial_flash_cleanup(void) +{ + if (mtd) { + del_mtd_device(mtd); + kfree(mtd); + mtd = 0; + } +} + +static int __init +serial_flash_init(void) +{ + int result = 0; + + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); + if (mtd == 0) { + result = -ENOMEM; + goto out; + } + memset(mtd, 0, sizeof(*mtd)); + mtd->name = "atmel"; + mtd->type = MTD_NORFLASH; + mtd->flags = MTD_CAP_NORFLASH; + mtd->size = 256 * 2048; + mtd->read = serial_read; + mtd->write = serial_write; + mtd->sync = serial_sync; + mtd->erase = serial_erase; + mtd->erasesize = 4096; + + add_mtd_device(mtd); + + out: + return result; +} + +module_init(serial_flash_init); +module_exit(serial_flash_cleanup); + +MODULE_AUTHOR("Derek Mulcahy "); +MODULE_DESCRIPTION("Shannon ATMEL serial flash driver"); + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ Index: tlinux/drivers/pcmcia/rsrc_mgr.c diff -u tlinux/drivers/pcmcia/rsrc_mgr.c:1.1.1.3 tlinux/drivers/pcmcia/rsrc_mgr.c:1.1.1.3.2.3 --- tlinux/drivers/pcmcia/rsrc_mgr.c:1.1.1.3 Mon Dec 10 14:54:07 2001 +++ tlinux/drivers/pcmcia/rsrc_mgr.c Mon Dec 10 15:50:38 2001 @@ -176,7 +176,7 @@ ======================================================================*/ -#ifdef CONFIG_PCMCIA_PROBE +#if defined(CONFIG_PCMCIA_PROBE) && !defined(CONFIG_ARCH_SA1100) static void do_io_probe(ioaddr_t base, ioaddr_t num) { @@ -575,7 +575,7 @@ case ADD_MANAGED_RESOURCE: if (add_interval(&io_db, base, num) != 0) return CS_IN_USE; -#ifdef CONFIG_PCMCIA_PROBE +#if defined(CONFIG_PCMCIA_PROBE) && !defined(CONFIG_ARCH_SA1100) if (probe_io) do_io_probe(base, num); #endif Index: tlinux/drivers/pcmcia/sa1100_shannon.c diff -u tlinux/drivers/pcmcia/sa1100_shannon.c:1.1.1.1 tlinux/drivers/pcmcia/sa1100_shannon.c:1.1.1.1.6.1 --- tlinux/drivers/pcmcia/sa1100_shannon.c:1.1.1.1 Mon Nov 19 01:14:16 2001 +++ tlinux/drivers/pcmcia/sa1100_shannon.c Mon Dec 10 15:11:09 2001 @@ -16,12 +16,6 @@ { int irq, res; - /* All those are inputs */ - GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | - SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); - GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | - SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); - /* Set transition detect */ set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1, GPIO_BOTH_EDGES); set_GPIO_IRQ_edge(SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1, GPIO_FALLING_EDGE); Index: tlinux/drivers/video/Config.in diff -u tlinux/drivers/video/Config.in:1.1.1.2 tlinux/drivers/video/Config.in:1.1.1.2.6.1 --- tlinux/drivers/video/Config.in:1.1.1.2 Mon Nov 19 01:14:05 2001 +++ tlinux/drivers/video/Config.in Mon Dec 10 15:11:09 2001 @@ -213,6 +213,8 @@ tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL fi + source drivers/video/backlight/Config.in + bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then tristate ' Monochrome support' CONFIG_FBCON_MFB Index: tlinux/drivers/video/Makefile diff -u tlinux/drivers/video/Makefile:1.1.1.1 tlinux/drivers/video/Makefile:1.1.1.1.12.1 --- tlinux/drivers/video/Makefile:1.1.1.1 Wed Oct 31 13:23:46 2001 +++ tlinux/drivers/video/Makefile Mon Dec 10 15:11:09 2001 @@ -4,7 +4,7 @@ O_TARGET := video.o -mod-subdirs := matrox +mod-subdirs := backlight matrox # All of the (potential) objects that export symbols. # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. @@ -118,6 +118,11 @@ obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o obj-$(CONFIG_FB_ANAKIN) += anakinfb.o + +subdir-$(CONFIG_FB_BACKLIGHT) += backlight +ifeq ($(CONFIG_FB_BACKLIGHT),y) +obj-y += backlight/fb_backlight.o +endif # Generic Low Level Drivers Index: tlinux/drivers/video/fbcon.c diff -u tlinux/drivers/video/fbcon.c:1.1.1.1 tlinux/drivers/video/fbcon.c:1.1.1.1.12.1 --- tlinux/drivers/video/fbcon.c:1.1.1.1 Wed Oct 31 13:23:47 2001 +++ tlinux/drivers/video/fbcon.c Mon Dec 10 15:11:09 2001 @@ -1590,6 +1590,10 @@ return 1; } } +#ifdef CONFIG_FB_BACKLIGHT + fb_backlight_blank(blank, info); +#endif + (*info->blank)(blank, info); return 0; } Index: tlinux/drivers/video/fbmem.c diff -u tlinux/drivers/video/fbmem.c:1.1.1.2 tlinux/drivers/video/fbmem.c:1.1.1.2.6.1 --- tlinux/drivers/video/fbmem.c:1.1.1.2 Mon Nov 19 01:14:00 2001 +++ tlinux/drivers/video/fbmem.c Mon Dec 10 15:11:09 2001 @@ -25,6 +25,7 @@ #include #include #include +#include #include #ifdef CONFIG_KMOD #include @@ -449,6 +450,11 @@ struct fb_fix_screeninfo fix; struct fb_con2fbmap con2fb; int i; + +#ifdef CONFIG_FB_BACKLIGHT + int retval; + struct bl_setting new; +#endif if (! fb) return -ENODEV; @@ -521,10 +527,33 @@ set_con2fb_map(i, con2fb.framebuffer); return 0; case FBIOBLANK: +#ifdef CONFIG_FB_BACKLIGHT + fb_backlight_blank(arg, info); +#endif if (info->blank == 0) return -EINVAL; (*info->blank)(arg, info); return 0; +#ifdef CONFIG_FB_BACKLIGHT + case FB_BACKLIGHT_GET_POWER: + retval = fb_backlight_get_power(info, &new); + if (retval != 0) return retval; + else return copy_to_user((void *)arg, &new, sizeof(struct bl_setting)); + case FB_BACKLIGHT_GET_BRIGHTNESS: + retval = fb_backlight_get_brightness(info, &new); + if (retval != 0) return retval; + else return copy_to_user((void *)arg, &new, sizeof(struct bl_setting)); + case FB_BACKLIGHT_GET_CONTRAST: + retval = fb_backlight_get_contrast(info, &new); + if (retval != 0) return retval; + else return copy_to_user((void *)arg, &new, sizeof(struct bl_setting)); + case FB_BACKLIGHT_SET_POWER: + return fb_backlight_set_power(info, arg); + case FB_BACKLIGHT_SET_BRIGHTNESS: + return fb_backlight_set_brightness(info, arg); + case FB_BACKLIGHT_SET_CONTRAST: + return fb_backlight_set_contrast(info, arg); +#endif default: if (fb->fb_ioctl == NULL) return -EINVAL; @@ -734,6 +763,7 @@ if (!registered_fb[i]) break; fb_info->node = MKDEV(FB_MAJOR, i); + spin_lock_init(&fb_info->backlight_lock); registered_fb[i] = fb_info; if (!fb_ever_opened[i]) { struct module *owner = fb_info->fbops->owner; Index: tlinux/drivers/video/sa1100fb.c diff -u tlinux/drivers/video/sa1100fb.c:1.1.1.4 tlinux/drivers/video/sa1100fb.c:1.1.1.4.2.1 --- tlinux/drivers/video/sa1100fb.c:1.1.1.4 Mon Dec 10 14:53:49 2001 +++ tlinux/drivers/video/sa1100fb.c Mon Dec 10 15:11:09 2001 @@ -1719,7 +1719,6 @@ #endif if (machine_is_shannon()) { - GPDR |= SHANNON_GPIO_DISP_EN; GPSR |= SHANNON_GPIO_DISP_EN; } Index: tlinux/drivers/video/backlight/Config.in diff -u /dev/null tlinux/drivers/video/backlight/Config.in:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/Config.in Mon Dec 10 15:11:09 2001 @@ -0,0 +1,20 @@ +mainmenu_option next_comment +comment 'Backlight support' + +bool 'Backlight support' CONFIG_FB_BACKLIGHT + +if [ "$CONFIG_FB_BACKLIGHT" = "y" ]; then + dep_tristate 'Backlight power management hooks' CONFIG_BACKLIGHT_PM $CONFIG_PM + dep_tristate 'Control backlight through input layer' CONFIG_BACKLIGHT_INPUT $CONFIG_INPUT + comment 'Devices' + dep_tristate 'Assabet backlight support' CONFIG_ASSABET_BACKLIGHT $CONFIG_SA1100_ASSABET + dep_tristate 'HuW Webpanel backlight support' CONFIG_HUW_WEBPANEL_BACKLIGHT $CONFIG_SA1100_HUW_WEBPANEL + dep_tristate 'Freebird backlight support' CONFIG_FREEBIRD_BACKLIGHT $CONFIG_SA1100_FREEBIRD + dep_tristate 'Omnimeter backlight support' CONFIG_OMNIMETER_BACKLIGHT $CONFIG_SA1100_OMNIMETER + if [ "$CONFIG_SA1100_SHANNON" = "y" ]; then + dep_tristate 'Shannon backlight support' CONFIG_SHANNON_BACKLIGHT $CONFIG_MCP_UCB1200 + fi +fi + +endmenu + Index: tlinux/drivers/video/backlight/Makefile diff -u /dev/null tlinux/drivers/video/backlight/Makefile:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/Makefile Mon Dec 10 15:11:09 2001 @@ -0,0 +1,23 @@ +# Backlight Drivers + +O_TARGET := fb_backlight.o + +export-objs := backlight.o + +obj-y += backlight.o + +# Misc helpers + +obj-$(CONFIG_BACKLIGHT_PM) += backlight_pm.o +obj-$(CONFIG_BACKLIGHT_INPUT) += backlight_input.o + +# devices + +obj-$(CONFIG_ASSABET_BACKLIGHT) += assabet_frontlight.o +obj-$(CONFIG_HUW_WEBPANEL_BACKLIGHT) += huw_webpanel_backlight.o +obj-$(CONFIG_FREEBIRD_BACKLIGHT) += freebird_frontlight.o +obj-$(CONFIG_OMNIMETER_BACKLIGHT) += omnimeter_backlight.o +obj-$(CONFIG_SHANNON_BACKLIGHT) += shannon_backlight.o + +include $(TOPDIR)/Rules.make + Index: tlinux/drivers/video/backlight/assabet_frontlight.c diff -u /dev/null tlinux/drivers/video/backlight/assabet_frontlight.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/assabet_frontlight.c Mon Dec 10 15:11:09 2001 @@ -0,0 +1,110 @@ +/************************************************************* + * Assabet Frontlight Device + * + * linux/drivers/video/backlight/assabet_frontlight.c + ************************************************************* + * + * Taken from sa1100_frontlight.c (written by Nicholas Mistry ) + * + * This driver provides basic functionality for the frontlight + * provided with the Assabet board. It will enable and disable + * the light. + * + * Because the assabet does not come with its own power supply for the + * one can be obtained/made. Below is a list of the parts i used to + * enable mine. + * + * ** The parts/cable described below assume that your assabet + * ** is using the Sharp LQ039Q2DS54 Screen. + * + * Parts List: + * ------------ + * 1 ERG power 8m122375 DC to AC inverter. + * obtain from: Endicott Research Group Inc. (http://www.ergpower.com) + * + * Assabet Side Connector: + * 1 Minitek 90312-005 Housing + * 3 Minitek 77138-101 Pins + * obtain both from: FCI Framatome Group (http://www.fciconnect.com) + * * Samples Available * + * + * Inverter Side Connector: + * 1 Standard 0.1" 4 pin Housing + * 3 Standard 0.1" Pins (crimp is preferred) + * + * 3 pieces of 26 AWG Stranded Wire each aprox 4"-6" long + * (3 colors optional: red,black,white) + * + * Cable Diagram: + * -------------- + * + * Inverter: Assabet: + * + * _____ _______ + * | ______ /---------------| |1 [| (red wire) + * V+ 1|---- |] 1 |---/ /------------|_ |2 [| (black wire) + * GND 2|---- |] 2 |------(------\ |_||3 [| + * CTL 3|---- |] 3 |-----/ \-----| |4 [| (white wire) + * NE 4|---- |]___4_| |__|5__[| + * _____| + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Russell Dill "); +MODULE_DESCRIPTION("Assabet Frontlight Driver"); +MODULE_LICENSE("GPL"); + +#warning The assabet maintainers should check over this + +static u_int +assabet_power(void *private, u_int arg) +{ + if (arg) ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); + else ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); + return 0; +} + +static struct backlight_ops assabet_ops = { + power: { + set: assabet_power, + }, +}; + +static int __init +assabet_frontlight_init(void) +{ + int retval = 0; + + if (!machine_is_assabet()) return -ENODEV; + + retval = fb_register_backlight(&assabet_ops, NULL, THIS_MODULE); + if (retval == 0) printk(KERN_INFO "Assabet frontlight driver loaded\n"); + return retval; +} + +static void __exit +assabet_frontlight_exit(void) +{ + fb_deregister_backlight(); +} + +module_init(assabet_frontlight_init); +module_exit(assabet_frontlight_exit); + Index: tlinux/drivers/video/backlight/backlight.c diff -u /dev/null tlinux/drivers/video/backlight/backlight.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/backlight.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,191 @@ +/* + * linux/drivers/video/backlight/backlight.c + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +fb_backlight_blank(int blank, struct fb_info *info) +{ + switch (blank) { + case VESA_POWERDOWN: + case VESA_VSYNC_SUSPEND: + case VESA_HSYNC_SUSPEND: + fb_backlight_off(info); + break; + case VESA_NO_BLANKING: + fb_backlight_on(info); + } +} + +int +fb_backlight_get(struct fb_info *info, int type, struct bl_setting *dest) +{ + unsigned long flags; + int retval = 0; + struct backlight *backlight; + if (!info) return -ENODEV; + + spin_lock_irqsave(&info->backlight_lock, flags); + if (!(backlight = info->backlight) || !backlight->ops[type].set) + retval = -ENODEV; + else { + dest->max = backlight->ops[type].max; + dest->def = backlight->ops[type].def; + dest->curr = backlight->new[type]; + } + spin_unlock_irqrestore(&info->backlight_lock, flags); + return retval; +} + +static void +fb_backlight_routine(void *data) +{ + struct fb_info *info = (struct fb_info *) data; + struct backlight *backlight = info->backlight; + int type, new; + unsigned long flags; + + spin_lock_irqsave(&info->backlight_lock, flags); + for (type = 0; type < BL_NUM_SETTINGS; type++) + if (backlight->curr[type] != backlight->new[type]) + break; + if (type == BL_NUM_SETTINGS) { + backlight->open = 0; + goto out; + } + new = backlight->new[type]; + spin_unlock_irqrestore(&info->backlight_lock, flags); + + backlight->ops[type].set(backlight->private, new); + + spin_lock_irqsave(&info->backlight_lock, flags); + backlight->curr[type] = new; + for (type = 0; type < BL_NUM_SETTINGS; type++) + if (backlight->curr[type] != backlight->new[type]) + break; + if (type != BL_NUM_SETTINGS) { + schedule_task(&backlight->task); + } else { + backlight->open = 0; + if (backlight->owner) + __MOD_DEC_USE_COUNT(backlight->owner); + } +out: + spin_unlock_irqrestore(&info->backlight_lock, flags); +} + +int +fb_backlight_set(struct fb_info *info, int type, u_int new) +{ + int retval = 0; + struct backlight *backlight; + unsigned long flags; + if (!info) return -ENODEV; + + spin_lock_irqsave(&info->backlight_lock, flags); + if (!(backlight = info->backlight)) { + retval = -ENODEV; + goto out; + } + + if (new != backlight->new[type] && backlight->ops[type].set) { + if (new > backlight->ops[type].max) { + retval = -EINVAL; + goto out; + } + backlight->new[type] = new; + if (!backlight->open) { + if (backlight->owner && !try_inc_mod_count(backlight->owner)) + retval = -ENODEV; + else { + backlight->open = 1; + schedule_task(&backlight->task); + } + } + } +out: + spin_unlock_irqrestore(&info->backlight_lock, flags); + return retval; +} + +/* call this function to register a backlight. pass a allocated and filled + * struct backlight *. This function will call back to set the defaults */ +int +fb_register_backlight(struct backlight_ops *ops, void *private, struct module *owner) +{ + /* possibly handle multiple framebuffers here, trying each */ + struct backlight *backlight; + int i; + struct fb_info *fbi = (struct fb_info *) registered_fb[0]; + if (!fbi) return -ENODEV; + + if (!(backlight = kmalloc(sizeof(struct backlight), GFP_KERNEL))) + return -ENOMEM; + + memset(backlight, 0, sizeof(struct backlight)); + + if (fbi->fbops->owner && !try_inc_mod_count(fbi->fbops->owner)) { + kfree(backlight); + return -ENODEV; + } + + memcpy(backlight->ops, ops, sizeof(backlight->ops)); + + if (backlight->ops[BL_POWER].set) { + backlight->ops[BL_POWER].def = 1; + backlight->ops[BL_POWER].max = 1; + } + backlight->owner = owner; + backlight->private = private; + backlight->task.routine = fb_backlight_routine; + backlight->task.data = (void *) fbi; + + + fbi->backlight = backlight; + for (i = 0; i < BL_NUM_SETTINGS; i++) { + fb_backlight_set(fbi, i, backlight->ops[i].def); + } + return 0; +} + +/* call this if the backlight driver gets unloaded */ +void * +fb_deregister_backlight(void) +{ + struct fb_info *fbi = (struct fb_info *)registered_fb[0]; + void *private; + unsigned long flags; + if (!fbi) BUG(); + + spin_lock_irqsave(&fbi->backlight_lock, flags); + private = fbi->backlight->private; + fbi->backlight = NULL; + spin_unlock_irqrestore(&fbi->backlight_lock, flags); + if (fbi->fbops->owner) + __MOD_DEC_USE_COUNT(fbi->fbops->owner); + return private; +} + +EXPORT_SYMBOL(fb_backlight_blank); +EXPORT_SYMBOL(fb_register_backlight); +EXPORT_SYMBOL(fb_deregister_backlight); +EXPORT_SYMBOL(fb_backlight_get); +EXPORT_SYMBOL(fb_backlight_set); + Index: tlinux/drivers/video/backlight/backlight_input.c diff -u /dev/null tlinux/drivers/video/backlight/backlight_input.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/backlight_input.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,160 @@ +/* + * linux/drivers/video/backlight/backlight_input.c + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * The driver allows input events to change the backlight. Its pretty primative + * right now, and could use some cleaning up and extending. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +MODULE_AUTHOR("Russ Dill private; + struct input_dev *dev = handle->dev; + struct bl_setting curr; + int mask; + + if (type != EV_KEY || !value) return; + + mask = (test_bit(KEY_LEFTALT, dev->key) || test_bit(KEY_RIGHTALT, dev->key)) * ALT_MOD; + mask |= (test_bit(KEY_LEFTMETA, dev->key) || test_bit(KEY_RIGHTMETA, dev->key)) * META_MOD; + mask |= (test_bit(KEY_LEFTSHIFT, dev->key) || test_bit(KEY_RIGHTSHIFT, dev->key)) * SHIFT_MOD; + mask |= (test_bit(KEY_LEFTCTRL, dev->key) || test_bit(KEY_RIGHTCTRL, dev->key)) * CTRL_MOD; + + if (mask == ops->contrast_mask) { + if (ops->contrast_up_key == code || ops->contrast_down_key == code) { + if (fb_backlight_get_contrast(registered_fb[0], &curr) < 0) + return; + if (ops->contrast_up_key == code) { + if (curr.curr < curr.max) curr.curr++; + fb_backlight_set_contrast(registered_fb[0], curr.curr); + } else { + if (curr.curr > 0) curr.curr--; + fb_backlight_set_contrast(registered_fb[0], curr.curr); + } + } + } + if (mask == ops->brightness_mask) { + if (ops->brightness_up_key == code || ops->brightness_down_key == code) { + if (fb_backlight_get_brightness(registered_fb[0], &curr) < 0) + return; + if (ops->brightness_up_key == code) { + if (curr.curr < curr.max) curr.curr++; + fb_backlight_set_brightness(registered_fb[0], curr.curr); + } else { + if (curr.curr > 0) curr.curr--; + fb_backlight_set_brightness(registered_fb[0], curr.curr); + } + } + } + if (mask == ops->power_mask) { + if (ops->power_on_key == code) { + fb_backlight_on(registered_fb[0]); + } else if (ops->power_off_key == code) { + fb_backlight_off(registered_fb[0]); + } + } +} + +static struct input_handle * +bl_input_connect(struct input_handler *handler, struct input_dev *dev) +{ + struct input_handle *handle; + + if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) + return NULL; + memset(handle, 0, sizeof(struct input_handle)); + + handle->dev = dev; + handle->handler = handler; + +#ifdef CONFIG_SA1100_SHANNON + if (machine_is_shannon()) { + handle->private = (void *) &shannon_ops; + } +#endif + + input_open_device(handle); + return handle; +} + +static void +bl_input_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + kfree(handle); +} + +static struct input_handler bl_input_handler = { + event: bl_input_event, + connect: bl_input_connect, + disconnect: bl_input_disconnect, +}; + +static int __init +bl_input_init(void) +{ + input_register_handler(&bl_input_handler); + return 0; +} + +static void __exit +bl_input_exit(void) +{ + input_unregister_handler(&bl_input_handler); +} + +module_init(bl_input_init); +module_exit(bl_input_exit); + Index: tlinux/drivers/video/backlight/backlight_pm.c diff -u /dev/null tlinux/drivers/video/backlight/backlight_pm.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/backlight_pm.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,64 @@ +/* + * linux/drivers/video/backlight_pm.c + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("Backlight PM hooks"); +MODULE_AUTHOR("Russ Dill "); +MODULE_LICENSE("GPL"); + +static struct pm_dev *pm; + +/* + * Power management hook. Note that we won't be called from IRQ context, + * so we may sleep. + */ +static int +backlight_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) +{ + printk("Backlight PM callback\n"); + if (req == PM_SUSPEND || req == PM_RESUME) { + int state = (int)data; + + if (state == 0) { + /* Enter D0. */ + printk("Shutting off backlight\n"); + fb_backlight_on(registered_fb[0]); + } else { + /* Enter D1-D3. Disable the backlight. */ + printk("Turning on backlight\n"); + fb_backlight_off(registered_fb[0]); + } + } + return 0; +} + +static int __init +backlight_pm_init(void) +{ + pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, backlight_pm_callback); + if (!pm) return -ENODEV; + printk("Backlight PM hooks registered\n"); + return 0; +} + +static void __exit +backlight_pm_exit(void) +{ + pm_unregister(pm); +} + +module_init(backlight_pm_init); +module_exit(backlight_pm_exit); + Index: tlinux/drivers/video/backlight/freebird_frontlight.c diff -u /dev/null tlinux/drivers/video/backlight/freebird_frontlight.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/freebird_frontlight.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,178 @@ +/************************************************************* + * StrongARM 11xx LCD Frontlight Device + * + * linux/drivers/video/backlight/freebird_frontlight.c + ************************************************************* + * + * Initial Version by: Nicholas Mistry (nmistry@lhsl.com) + ************************************************************* + * Revision History: + * 07/07/2000 - Nicholas Mistry (nmistry@lhsl.com) + * Initial release for assabet, no dimming support, + * can enable and disable the frontlight via ioctl. + * Initial framework for dimming included. + * + * 30/1/2001 - Chester Kuo (chester@linux.or.tw) + * Add the backlight/contrast control of SA-1110 board. + * Test with FreeBird-1.1 board,but i think it's useful + * for other SA-11x0 based board. + * + * 4/3/2001 - Tim Wu +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Nicholas N. Mistry (nmistry@lhsl.com)"); +MODULE_DESCRIPTION("SA1100 LCD light Driver"); +MODULE_LICENSE("GPL"); + +#warning The freebird maintainers should check over this + +#define MAX_BRIGHTNESS 31 +#define MAX_CONTRAST 31 + +struct freebird_info { + int curr_brightness; + int curr_contrast; +}; + +static int +freebird_power(void *private, u_int arg) +{ + if (arg) BCR_set(BCR_FREEBIRD_LCD_BACKLIGHT); + else BCR_clear(BCR_FREEBIRD_LCD_BACKLIGHT); + return 0; +} + +static void +freebird_pulse(unsigned long bcr) +{ + BCR_set(bcr); + udelay(1000); + BCR_clear(bcr); +} + +static int +freebird_brightness(void *private, u_int arg) +{ + struct freebird_info *info = (struct freebird_info *) private; + int inc; + + if (arg > info->curr_brightness) { + BCR_set(BCR_FREEBIRD_LCD_LIGHT_DU); + inc = 1; + } else { + BCR_clear(BCR_FREEBIRD_LCD_LIGHT_DU); + inc = -1; + } + while (arg != info->curr_brightness) { + freebird_pulse(BCR_FREEBIRD_LCD_LIGHT_INC) + info->curr_brightness += inc; + } + return 0; +} + +static int +freebird_contrast(void *private, u_int arg) +{ + struct freebird_info *info = (struct freebird_info *) private; + int inc; + + if (arg >info->curr_contrast) { + BCR_set(BCR_FREEBIRD_LCD_DU); + inc = 1; + } else { + BCR_clear(BCR_FREEBIRD_LCD_DU); + inc = -1; + } + while (arg != info->curr_contrast) { + freebird_pulse(BCR_FREEBIRD_LCD_INC) + info->curr_contrast += inc; + } + return 0; +} + +/* put the backlight in a known state */ +static void __init +freebird_init_backlight(void) +{ + int i; + + BCR_clear(BCR_FREEBIRD_LCD_LIGHT_INC); + BCR_clear(BCR_FREEBIRD_LCD_INC); + + BCR_set(BCR_FREEBIRD_LCD_LIGHT_DU); + for (i = 0; i < MAX_BRIGHTNESS; i++) + freebird_pulse(BCR_FREEBIRD_LCD_LIGHT_INC); + + BCR_set(BCR_FREEBIRD_LCD_DU); + for (i = 0; i < MAX_CONTRAST; i++) + freebird_pulse(BCR_FREEBIRD_LCD_INC); +} + +static struct backlight_ops freebird_ops = { + power: { + set: freebird_power, + }, + brightness: { + set: freebird_brightness, + max: MAX_BRIGHTNESS, + def: 27, + }, + contrast: { + set: freebird_contrast, + max: MAX_CONTRAST, + def: 18, + }, +}; + + +static int __init +freebird_backlight_init(void) +{ + int retval = 0; + struct freebird_info *private; + + if (!machine_is_freebird()) return -ENODEV; + if (!(private = kmalloc(sizeof(struct freebird_info), GFP_KERNEL))) + return -ENOMEM; + + memset(private, 0, sizeof(struct freebird_info)); + + freebird_init_backlight(); + + retval = fb_register_backlight(&freebird_ops, private, THIS_MODULE); + if (retval == 0) printk(KERN_INFO "Freebird backlight driver loaded\n"); + else kfree(private); + return retval; +} + + +static void __exit +freebird_backlight_exit(void) +{ + void *private = fb_deregister_backlight(); + if (!private) BUG(); + kfree(private); +} + +module_init(freebird_backlight_init); +module_exit(freebird_backlight_exit); + + Index: tlinux/drivers/video/backlight/huw_webpanel_backlight.c diff -u /dev/null tlinux/drivers/video/backlight/huw_webpanel_backlight.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/huw_webpanel_backlight.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,78 @@ + +#include +#include +/* + * linux/drivers/video/backlight/huw_webpanel_backlight.c + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Russell Dill "); +MODULE_DESCRIPTION("HuW Webpanel Backlight Driver"); +MODULE_LICENSE("GPL"); + +#warning The HuW Webpanel maintainers should check over this + +static u_int +huw_webpanel_power(void *private, u_int arg) +{ + if (arg) { + BCR_set(BCR_CCFL_POW + BCR_PWM_BACKLIGHT); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_task(200 * HZ / 1000); + BCR_set(BCR_TFT_ENA); + } else { + BCR_clear(BCR_TFT_ENA); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_task(200 * HZ / 1000); + BCR_clear(BCR_CCFL_POW + BCR_PWM_BACKLIGHT); + } + + return 0; +} + +static struct backlight_ops huw_webpanel_ops = { + power: { + set: huw_webpanel_power, + }, +}; + +static int __init +huw_webpanel_backlight_init(void) +{ + int retval = 0; + + if (!machine_is_huw_webpanel()) return -ENODEV; + + retval = fb_register_backlight(&huw_webpanel_ops, NULL, THIS_MODULE); + if (retval == 0) printk(KERN_INFO "HuW Webpanel backlight driver loaded\n"); + return retval; +} + +static void __exit +huw_webpanel_backlight_exit(void) +{ + fb_deregister_backlight(); +} + +module_init(huw_webpanel_backlight_init); +module_exit(huw_webpanel_backlight_exit); + Index: tlinux/drivers/video/backlight/omnimeter_backlight.c diff -u /dev/null tlinux/drivers/video/backlight/omnimeter_backlight.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/omnimeter_backlight.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,82 @@ +/* + * linux/drivers/video/backlight/omnimeter_backlight.c + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Russ Dill "); +MODULE_DESCRIPTION("Omnimeter backlight driver"); +MODULE_LICENSE("GPL"); + +#warning The Omnimeter maintainers should check over this + +static u_int +omnimeter_contrast(void *private, u_int arg) +{ + SetSMB(SMB_LCDVEE, arg); + return 0; +} + +static u_int +omnimeter_power(void *private, u_int arg) +{ + if (arg) ClearGPIOpin(GPIO_key6); + else SetGPIOpin(GPIO_key6); + return 0; +} + +static struct backlight_ops omnimeter_ops = { + power: { + set: omnimeter_power, + }, + contrast: { + set: omnimeter_contrast, +#error "the max value is a guess" + max: 32, + def: 16, + }, +}; + +static int __init +omnimeter_backlight_init(void) +{ + int retval; + + if (!machine_is_omnimeter()) return -ENODEV; + + retval = fb_register_backlight(&omnimeter_ops, NULL, THIS_MODULE); + if (retval == 0) printk(KERN_INFO "Omnimeter backlight driver loaded\n"); + return retval; +} + + +static void __exit +omnimeter_backlight_exit(void) +{ + fb_deregister_backlight(); +} + +module_init(omnimeter_backlight_init); +module_exit(omnimeter_backlight_exit); + Index: tlinux/drivers/video/backlight/shannon_backlight.c diff -u /dev/null tlinux/drivers/video/backlight/shannon_backlight.c:1.1.6.1 --- /dev/null Mon Dec 10 16:54:54 2001 +++ tlinux/drivers/video/backlight/shannon_backlight.c Mon Dec 10 15:11:10 2001 @@ -0,0 +1,121 @@ +/* + * linux/drivers/video/backlight/shannon_backlight.c + * + * Copyright (C) 2001 Russell Dill, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../../misc/ucb1x00.h" /* this include should probably be elsewhere */ + +MODULE_AUTHOR("Russ Dill "); +MODULE_DESCRIPTION("Shannon backlight driver"); +MODULE_LICENSE("GPL"); + +static u_int +shannon_contrast(void *private, u_int arg) +{ + struct ucb1x00 *ucb = (struct ucb1x00 *) private; + ucb1x00_enable(ucb); + ucb1x00_io_write(ucb, arg << SHANNON_UCB_GPIO_CONTRAST, + (~arg & SHANNON_UCB_GPIO_CONTRAST_MASK) << SHANNON_UCB_GPIO_CONTRAST); + ucb1x00_disable(ucb); + return 0; +} + + +static u_int +shannon_brightness(void *private, u_int arg) +{ + struct ucb1x00 *ucb = (struct ucb1x00 *) private; + arg = SHANNON_UCB_GPIO_BRIGHT_MASK - arg; + ucb1x00_enable(ucb); + ucb1x00_io_write(ucb, arg << SHANNON_UCB_GPIO_BRIGHT, + (~arg & SHANNON_UCB_GPIO_BRIGHT_MASK) << SHANNON_UCB_GPIO_BRIGHT); + ucb1x00_disable(ucb); + return 0; +} + + +static u_int +shannon_power(void *private, u_int arg) +{ + struct ucb1x00 *ucb = (struct ucb1x00 *) private; + arg = 1 - arg; + ucb1x00_enable(ucb); + ucb1x00_io_write(ucb, arg << SHANNON_UCB_GPIO_BACKLIGHT, + (~arg & 1) << SHANNON_UCB_GPIO_BACKLIGHT); + ucb1x00_disable(ucb); + return 0; +} + +static struct backlight_ops shannon_ops = { + power: { + set: shannon_power, + }, + brightness: { + set: shannon_brightness, + max: SHANNON_UCB_GPIO_BRIGHT_MASK, + def: 5, + }, + contrast: { + set: shannon_contrast, + max: SHANNON_UCB_GPIO_CONTRAST_MASK, + def: 0x1F, + }, +}; + +static int __init +shannon_backlight_init(void) +{ + unsigned long mask; + int retval = 0; + struct ucb1x00 *ucb; + + if (!machine_is_shannon()) return -ENODEV; + + if (!(ucb = ucb1x00_get())) { + printk(KERN_ERR "Could not get ucb struct (ucb1x00 not loaded?)\n"); + return -ENODEV; + } + + ucb1x00_enable(ucb); + mask = (SHANNON_UCB_GPIO_CONTRAST_MASK << SHANNON_UCB_GPIO_CONTRAST) | + (SHANNON_UCB_GPIO_BRIGHT_MASK << SHANNON_UCB_GPIO_BRIGHT) | + (1 << SHANNON_UCB_GPIO_BACKLIGHT); + ucb1x00_io_set_dir(ucb, 0, mask); + ucb1x00_disable(ucb); + + retval = fb_register_backlight(&shannon_ops, ucb, THIS_MODULE); + if (retval == 0) printk(KERN_INFO "Shannon backlight driver loaded\n"); + return retval; +} + + +static void __exit +shannon_backlight_exit(void) +{ + fb_deregister_backlight(); +} + +module_init(shannon_backlight_init); +module_exit(shannon_backlight_exit); + Index: tlinux/include/asm-arm/wheaties.h diff -u /dev/null tlinux/include/asm-arm/wheaties.h:1.1.12.1 --- /dev/null Mon Dec 10 16:54:55 2001 +++ tlinux/include/asm-arm/wheaties.h Mon Dec 10 15:11:10 2001 @@ -0,0 +1,198 @@ +/* wheaties.h + * + * Declarations to make programing for /dev/wheaties a bit easier. + * I hope this makes sense. This file format may change a bit over + * time to suit everyones needs or correct errors. Hopefully, things + * will only get added to the file. + * + * Written by John Laur 10/20/2001 + * + * Share and enjoy. + */ + +/* ------------------ * + * ---- Commands ---- * + * ------------------ */ + +/* Commands to get and set the DSP clock */ +#define CMD_TIME_SET 0x50 /* Set the DSP Clock */ +#define CMD_TIME_GET 0x52 /* Get the DSP Clock */ + +/* Commands to control the volume */ +#define CMD_VOLUME 0x4C /* Volume Functions */ + +#define VOLUME_HANDSET 0x00 /* Handset Volume 0-3 */ +#define VOLUME_SPEAKER 0x10 /* Speakerphone Volume 0-7 */ +#define VOLUME_AM 0x20 /* ??? 0-7 */ +#define VOLUME_RINGER 0x30 /* Ring Volume 0-7 */ + +/* CallerID Commands and parameters */ +#define CMD_CALLERID 0x22 /* CallerID Functions */ + +#define CALLERID_REPORT 0x25 /* Report CallerID Settings */ +#define CALLERID_NEW 0x20 /* New CallerID Data */ +#define CALLERID_GET_1 0x09 /* Get CallerID Block 1 */ +#define CALLERID_BLOCK1 0x27 /* Number/Date/Time */ +#define CALLERID_GET_2 0x0A /* Get CallerID Block 2 */ +#define CALLERID_BLOCK2 0x28 /* Name */ +#define CALLERID_SET_ALL 0x13 /* Set all CallerID options */ +#define CALLERID_SET_ALL_NOCW 0x03 /* Except for Call Waiting */ + +#define CMD_CALLERID_SETOPTS 0x17 /* Set CallerID Options */ +#define CMD_CALLERID_GETOPTS 0x18 /* Get CallerID Options */ + +/* Commands for dialtone detection */ +#define CMD_DIALTONEDETECT_ON 0x1A /* Start dialtone detect */ +#define CMD_DIALTONEDETECT_OFF 0x1B /* Abort dialtone detect */ + +#define DIALTONEDETECT_STUTTER 0x34 /* Detected stutter dialtone */ +#define DIALTONEDETECT_NORMAL 0x35 /* Detected normal dialtone */ +#define DIALTONEDETECT_ERROR 0x36 /* No dialtone detected */ + +/* Play rings/alert tones */ +#define CMD_TONE 0x42 /* Tone/Sound functions */ + +#define TONE_DEST_SPK 0x01 /* Loudspeaker */ +#define TONE_DEST_LINE1 0x02 /* Line One */ +#define TONE_DEST_LINE2 0x03 /* Line 2? */ +#define TONE_DEST_WH 0x04 /* ??? Handset? */ +#define TONE_DEST_CH 0x10 /* ??? Handset? */ + +#define TONE_RING 0x01 /* Normal Single Ring */ +#define TONE_RING_P 0x08 /* Priority Ring */ +#define TONE_RING_3S 0x03 /* 3 Short Rings */ +#define TONE_HAPPY 0x04 /* HAPPY TONE!!! :)) */ +#define TONE_BEEP_2S 0x08 /* Short Double Beeps */ +#define TONE_BEEP_1M 0x0A /* Medium Single Beep */ +#define TONE_BEEP_3M 0x07 /* Triple Medium Beeps */ +#define TONE_BEEP_1L 0x02 /* One Long Beep */ +#define TONE_BUZZER 0x05 /* SAD TONE :(( Buzzer */ + +/* Make the DSP perform dialing actions */ +#define CMD_DIAL 0x58 /* Dialing functions */ + +#define DIAL_DTMF_0 0x0A /* DTMF 0 */ +#define DIAL_DTMF_1 0x01 /* DTMF 1 */ +#define DIAL_DTMF_2 0x02 /* DTMF 2 */ +#define DIAL_DTMF_3 0x03 /* DTMF 3 */ +#define DIAL_DTMF_4 0x04 /* DTMF 4 */ +#define DIAL_DTMF_5 0x05 /* DTMF 5 */ +#define DIAL_DTMF_6 0x06 /* DTMF 6 */ +#define DIAL_DTMF_7 0x07 /* DTMF 7 */ +#define DIAL_DTMF_8 0x08 /* DTMF 8 */ +#define DIAL_DTMF_9 0x09 /* DTMF 9 */ +#define DIAL_DTMF_STAR 0x0B /* DTMF * */ +#define DIAL_DTMF_POUND 0x0C /* DTMF # */ +#define DIAL_PAUSE 0x0E /* Pause 1 second */ +#define DIAL_FLASH 0x0D /* Flash switchook */ +#define DIAL_S 0x0B /* ??? stop dtmf tone? */ +#define DIAL_W 0x0F /* ??? Wait for dialtone?*/ + +#define DIAL_MODE_CONST 0x40 /* Continuous DTMF generation */ +#define DIAL_MODE_BURST 0x00 /* DTMF Burst */ +#define DIAL_MODE_PULSE 0x80 /* Pulse dialing, ick! */ + +/* Control the LED lights and line relays */ +#define CMD_LED 0xA3 /* LED and line relay functions */ + +#define LED_BLINKSPEED_4 0x00 /* Fastest blink speed */ +#define LED_BLINKSPEED_3 0x01 /* Fast blink speed */ +#define LED_BLINKSPEED_2 0x02 /* Medium blink speed */ +#define LED_BLINKSPEED_1 0x03 /* Slow blink speed */ +#define LED_BLINKSPEED_0 0x04 /* Slowestt blink speed */ + +#define LED_OFF 0x00 /* Off */ +#define LED_BLINK_1 0x01 /* Blink (To timer 1) */ +#define LED_BLINK_2 0x02 /* Blink (To timer 2) */ +#define LED_ON 0x03 /* On */ + +/* Set the DSP audio paths */ +#define CMD_AUDIO 0xA6 /* Audio path functions */ + +#define AUDIO_IDLE 0x01 /* Idle audio - not routed */ +#define AUDIO_HANDSET 0x02 /* Audio routed to handset */ +#define AUDIO_SPEAKER 0x0D /* Audio routed to loudspeaker */ +#define AUDIO_HANDSET_MUTE 0x16 /* Audio out only to handset */ +#define AUDIO_SPEAKER_MUTE 0x04 /* Audio out only to speaker */ + +/* Control the telephone line */ +#define CMD_LINE 0xA7 /* Line hook functions */ + +#define LINE_ONHOOK 0x00 /* Put line on hook */ +#define LINE_OFFHOOK_HANDSET 0x02 /* Take line off hook on handset */ +#define LINE_OFFHOOK_SPEAKER 0x06 /* Take line off hook on speaker */ + +/* Check the status of the DSP */ +#define CMD_SANITY 0xB7 /* DSP Sanity Check */ + +/* Detect parallel handsets in use on the line */ +#define CMD_PARALLEL 0xA2 /* Detect parallel handset pickup */ + +/* Detect busy signal */ +#define CMD_BUSYDETECT_ON 0xAC /* Detect busy signal on line */ +#define CMD_BUSYDETECT_OFF 0xAD /* Stop detecting for busy signal */ + +#define BUSYDETECT_ON 0x01 +#define BUSYDETECT_OFF 0x02 +#define BUSYDETECT_REPORT 0x03 + +/* ------------------- * + * ---- Responses ---- * + * ------------------- */ + +/* Basic Command Responses */ +#define RSP_ACK 0x80 /* Command OK */ +#define RSP_NAK 0x84 /* Not OK or Unknown Command */ + +#define RSP_RING 0x10 /* Ring event */ + +#define RSP_CALLERID 0x22 /* CallerID Event */ + +#define RSP_TIME 0xEA /* Clock response */ + +#define RSP_BUSY 0x85 /* Response to busy command */ + +/* Response to DSP Sanity Check */ +#define RSP_SANITY 0xDB /* Response to sanity check */ + +/* response to line status */ +#define RSP_LINE 0xB0 /* Response to line event */ + +#define LINE_INUSE 0xD8 /* Line is in use */ +#define LINE_NOTINUSE 0xD9 /* Line not in use */ + +/* Response to indicate a delay in responding.. ?!?! */ +#define RSP_DELAY 0xB2 /* Command is still processing */ + +#define RSP_PARALLEL 0x08 /* Parallel set detected */ + +/* Messages that indicate a button was pushed or released */ +#define RSP_BTN 0x04 /* Button Event */ + +#define BTN_0 0x39 /* Keypad 0 */ +#define BTN_1 0x08 /* Keypad 1 */ +#define BTN_2 0x09 /* keypad 2 */ +#define BTN_3 0x0A /* Keypad 3 */ +#define BTN_4 0x18 /* Keypad 4 */ +#define BTN_5 0x19 /* Keypad 5 */ +#define BTN_6 0x1A /* Keypad 6 */ +#define BTN_7 0x28 /* Keypad 7 */ +#define BTN_8 0x29 /* Keypad 8 */ +#define BTN_9 0x2A +#define BTN_STAR 0x38 /* Keypad * */ +#define BTN_POUND 0x3A /* Keyapd # */ +#define BTN_VOLUP 0x1C /* Volume Rocker UP */ +#define BTN_VOLDN 0x2C /* Volume Rocker DOWN */ +#define BTN_SPK 0x3C /* Speakerphone Button */ +#define BTN_HOLD 0x0B /* Hold Button */ +#define BTN_FLASH 0x1B /* Flash Button */ +#define BTN_MUTE 0x0C /* Mute Button */ +#define BTN_UP 0xF7 /* Any keypad button UP */ +#define SWITCHOOK_ON 0x80 /* Switchook down */ +#define SWITCHOOK_OFF 0x88 /* Switchook up */ + +#include + +#define WHEATIES_IOC_MAGIC 'w' + +#define WHEATIES_IOC_RESET _IO(WHEATIES_IOC_MAGIC,0) Index: tlinux/include/asm-arm/arch-sa1100/memory.h diff -u tlinux/include/asm-arm/arch-sa1100/memory.h:1.1.1.1 tlinux/include/asm-arm/arch-sa1100/memory.h:1.1.1.1.12.1 --- tlinux/include/asm-arm/arch-sa1100/memory.h:1.1.1.1 Wed Oct 31 13:25:22 2001 +++ tlinux/include/asm-arm/arch-sa1100/memory.h Mon Dec 10 15:11:10 2001 @@ -24,12 +24,20 @@ /* * Page offset: 3GB */ +#ifdef CONFIG_SA1100_SHANNON_32M +#define PAGE_OFFSET (0xd0000000UL) +#else #define PAGE_OFFSET (0xc0000000UL) +#endif /* * Physical DRAM offset is 0xc0000000 on the SA1100 */ +#ifdef CONFIG_SA1100_SHANNON_32M +#define PHYS_OFFSET (0xd0000000UL) +#else #define PHYS_OFFSET (0xc0000000UL) +#endif /* * We take advantage of the fact that physical and virtual address can be the @@ -79,8 +87,13 @@ /* * Given a kernel address, find the home node of the underlying memory. */ +#ifdef CONFIG_SA1100_SHANNON_32M +#define KVADDR_TO_NID(addr) \ + (((unsigned long)(addr) - 0xd0000000) >> 27) +#else #define KVADDR_TO_NID(addr) \ (((unsigned long)(addr) - 0xc0000000) >> 27) +#endif /* * Given a physical address, convert it to a node id. Index: tlinux/include/linux/fb.h diff -u tlinux/include/linux/fb.h:1.1.1.1 tlinux/include/linux/fb.h:1.1.1.1.12.1 --- tlinux/include/linux/fb.h:1.1.1.1 Wed Oct 31 13:24:21 2001 +++ tlinux/include/linux/fb.h Mon Dec 10 15:11:10 2001 @@ -2,6 +2,7 @@ #define _LINUX_FB_H #include +#include #include /* Definitions of frame buffers */ @@ -324,6 +325,9 @@ void *pseudo_palette; /* Fake palette of 16 colors and the cursor's color for non palette mode */ + struct backlight *backlight; /* Backlight information, if there is + one for this fb */ + spinlock_t backlight_lock; /* lock for backlight operations */ /* From here on everything is device dependent */ void *par; }; @@ -532,5 +536,68 @@ #define FB_CURSOR_FLASH 2 #endif /* Preliminary */ + +/* backlight stuff */ +struct backlight_op { + u_int max; /* maximum setting */ + u_int def; /* default setting */ + /* set a new value */ + u_int (*set)(void *private, u_int new); +}; + +struct backlight_ops { + struct backlight_op power; + struct backlight_op brightness; + struct backlight_op contrast; +}; + +struct bl_setting { + u_int curr; + u_int max; + u_int def; +}; + +#define BL_POWER 0 +#define BL_BRIGHTNESS 1 +#define BL_CONTRAST 2 + +#define BL_NUM_SETTINGS 3 + +#ifdef __KERNEL__ + +struct backlight { + struct backlight_op ops[BL_NUM_SETTINGS]; + u_int curr[BL_NUM_SETTINGS]; + u_int new[BL_NUM_SETTINGS]; + struct fb_info *fbi; + struct module *owner; + struct tq_struct task; + int open; + void *private; +}; + +#define fb_backlight_on(info) fb_backlight_set(info, BL_POWER, 1) +#define fb_backlight_off(info) fb_backlight_set(info, BL_POWER, 0) +#define fb_backlight_set_power(info, new) fb_backlight_set(info, BL_POWER, new) +#define fb_backlight_set_contrast(info, new) fb_backlight_set(info, BL_CONTRAST, new) +#define fb_backlight_set_brightness(info, new) fb_backlight_set(info, BL_BRIGHTNESS, new) +#define fb_backlight_get_power(info, new) fb_backlight_get(info, BL_POWER, new) +#define fb_backlight_get_contrast(info, new) fb_backlight_get(info, BL_CONTRAST, new) +#define fb_backlight_get_brightness(info, new) fb_backlight_get(info, BL_BRIGHTNESS, new) + +void fb_backlight_blank(int blank, struct fb_info *info); +int fb_backlight_get(struct fb_info *info, int type, struct bl_setting *dest); +int fb_backlight_set(struct fb_info *info, int type, u_int new); +int fb_register_backlight(struct backlight_ops *ops, void *private, struct module *module); +void *fb_deregister_backlight(void); + +#endif /* __KERNEL__ */ + +#define FB_BACKLIGHT_GET_POWER _IOR('F', 0, struct bl_setting) /* read power */ +#define FB_BACKLIGHT_SET_POWER _IOW('F', 0, u_int) /* set power */ +#define FB_BACKLIGHT_GET_BRIGHTNESS _IOR('F', 1, struct bl_setting) /* read brightness */ +#define FB_BACKLIGHT_SET_BRIGHTNESS _IOW('F', 1, u_int) /* set brightness */ +#define FB_BACKLIGHT_GET_CONTRAST _IOR('F', 2, struct bl_setting) /* read contrast */ +#define FB_BACKLIGHT_SET_CONTRAST _IOW('F', 2, u_int) /* set contrast */ #endif /* _LINUX_FB_H */