diff --git a/Documentation/arm/ep93xx/config.txt b/Documentation/arm/ep93xx/config.txt new file mode 100644 index 0000000..9d13a15 --- /dev/null +++ b/Documentation/arm/ep93xx/config.txt @@ -0,0 +1,207 @@ +------------------------------------------------------------------------- +config.txt + +Information on configuration options in the Linux kernel for the Cirrus +EP93xx. + +Note to developers: Let's stick to the essentials on "how to turn things +on in the Linux build." This information is presented from the standpoint +of someone doing a build, looking at a make menuconfig screen. If what you +are describing doesn't fit here, it should get its own document to go into +the level of detail you feel is most practicle. +------------------------------------------------------------------------- + +All options configured as built-in drivers, not loadable modules. +So on options that are selected by < >, select <*>, not . To +do this either hit 'y' or hit the space bar twice. + + +---------------- +Audio +---------------- +Needed by: +Needs: DMA Support, dev fs. + +Ac97 and I2S audio are currently mutually exclusive. + +To enable Ac97 Audio: + Go into "Sound --->" + Enable "Sound Support" + Enable "OSS sound modules" + Select "Ac97" for "Cirrus EP93xx Sound Support" + +To enable I2S Audio: + Go into "Sound --->" + Enable "Sound Support" + Enable "OSS sound modules" + Select "I2S" for "Cirrus EP93xx Sound Support" + If you have an EDB9312 board, select "CS4228A" for "Cirrus I2S Codec Support" + If you have an EDB9301 board, select "CS4271" for "Cirrus I2S Codec Support" + + +---------------- +Dev Fs +---------------- + DEVFS support is no longer available. + Please consider using udev or create device nodes manually instead. + You might also need to adapt your startup scripts and userspace + apps. + +---------------- +DMA +---------------- +Needed by: Audio, IDE/DMA +Needs: + +To enable DMA: + Go into "System Type --->" + Go into "EP93XX Options --->" + Enable "EP93XX Internal DMA Support" + + +---------------- +IDE +---------------- +Needed by: +Needs: + To Turn on IDE support for the platform, you need to enable +General IDE support first - CONFIG_BLK_DEV_IDE, CONFIG_BLK_DEV_IDEDISK, +CONFIG_BLK_DEV_IDECD. + + If multiword DMA and ultra DMA support is needed, general DMA support for +the platform must be enabled first. See DMA section of this document for +options to enable DMA for the platform. + + If CDROM support is enabled, ISO9660 file system support should be enabled. +If a DVD support is needed, UDF file system support should be enabled. + +To enable CONFIG_BLK_DEV_IDE: + Go into "ATA /ATAPI/MFM/RLL support --->" + Enable "ATA/ATAPI/MFM/RLL support" + Go into "IDE, ATA, and ATAPI Block devices --->" + Enable "Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support" + +To enable CONFIG_BLK_DEV_IDEDISK: + Go into "ATA /ATAPI/MFM/RLL support --->" + Go into "IDE, ATA, and ATAPI Block devices --->" + Enable "Include IDE/ATA-2 DISK support" + +To enable CONFIG_BLK_DEV_IDECD: + Go into "ATA /ATAPI/MFM/RLL support --->" + Go into "IDE, ATA, and ATAPI Block devices --->" + Enable "Include IDE/ATAPI CDROM support" + +To enable EP93XX IDE (PIO mode only): + Go into "ATA /ATAPI/MFM/RLL support --->" + Go into "IDE, ATA, and ATAPI Block devices --->" + Enable "EP93XX IDE Support" + +To enable EP93XX IDE DMA (mdma and udma modes): + Go into "ATA /ATAPI/MFM/RLL support --->" + Go into "IDE, ATA, and ATAPI Block devices --->" + Enable "EP93XX IDE DMA support" + +To enabled ISO 9660 file system support: + Go into "File systems --->" + Enable "ISo 9660 CDROM file system support" + Enable "Microsoft Joliet CDROM extensions" + +To enable UDF file system support: + Go into "File systems --->" + Enable "UDF file system support (read only)" + +See also /Documentation/arm/ep93xx/ide-hard-drive-support.txt for information +on configuring the hard drive. + +---------------- +IrDA +---------------- +Described in /Documentation/arm/ep93xx/irda.txt + + +---------------- +NFS +---------------- +Described in /Documentation/arm/ep93xx/nfs.txt + + +---------------- +Serial Terminal +---------------- +To enable serial terminal: + Go into "Character devices --->" + Turn off "Support for console on virtual terminal" + Turn off "Virtual terminal" + Go into "Serial drivers --->" + Turn on "Cirrus EP93xx ARM AMBA serial port support" + Turn on "Support for console on EP93xx serial port" + +Serial terminal is the bottom jack of J7. +Format is 57600,8N1, flow control: "none". + + +---------------- +Touchscreen +---------------- +To enable touchscreen driver: + Go into "Character devices --->" + Go into "Mice --->" + Enable "Mouse Support (not serial and bus mice)" + Disable "PS/2 Mouse (aka "auxiliary device") support + Enable "EP93xx touch screen support" + + +---------------- +USB +---------------- +The order of all of the following statements is critical as some options enable +other options. + +To enable basic USB support(required for all devices listed below): + Go into "USB support --->" + Enable "Support for USB" + Enable "Preliminary USB device filesystem" (optional) + Enable "EP93XX OHCI-compatible host interface support" + +To enable support for USB mouse: + Go into "Input core support --->" + Enable "Input core support" + Enable "Mouse support" + + Go back to the top level of menuconfig + + Go into "USB support --->" + Enable "USB Human Interface Device (full HID) support" + Enable "HID input layer support" + +To enable support for USB Keyboard: + Go into "Input core support --->" + Enable "Input core support" + Enable "Keyboard support" + + Go back to the top level of menuconfig + + Go into "USB support --->" + Enable "USB Human Interface Device (full HID) support" + Enable "HID input layer support" + + Go back to the top level of menuconfig + Go into "Character devices --->" + Set EP93xx Keyboard Support to "USB" + +To enable USB Mass Storage support: + Go into "SCSI Support --->" + Enable "SCSI Support" + Enable "SCSI disk support" + + Go back to the top level of menuconfig + + Go into "USB support --->" + Enable "USB Mass Storage support" + + Go back to the top level of menuconfig + +(optional - Do this if you want to mount a USB flash drive) + Go into "File systems --->" + Enable "DOS FAT fs support" + Enable "VFAT (Windows-95) fs support" diff --git a/Documentation/arm/ep93xx/dma.txt b/Documentation/arm/ep93xx/dma.txt new file mode 100644 index 0000000..e7fc1bb --- /dev/null +++ b/Documentation/arm/ep93xx/dma.txt @@ -0,0 +1,300 @@ +Support Functions for the Cirrus Logic ep93xx Internal DMA controller. +============================================================================== + +State diagram + +States: +Uninitialized (!pause & !xfer_enable) +Stopped (pause & !xfer_enable) +Transferring (!pause & xfer_enable) +Stopped by starvation (pause & xfer_enable) + + _______________ + request ----------> | | <------- free ----------- + | Uninitialized | /\ + |_______________| || + || + || || + init || ------------------------------>|| + || /\ || + \/ || || + _________ || + ||<-- start && new_buffers <= 1 -- | | <----- flush <--------- || + || | Stopped | /\ || + || ---------> pause------> |_________| -------------------->|| || + || /\ || + || || || || + || || || start && new_buffers > 1 || + || || || || + || || \/ || + || || ______________ || + || || | | ------------------------->|| + || ||<---------------- | Transferring | ------------------->|| || + || || |______________| || || + || || || || + || || || || || + || || || new_buffers = 0 || || + || || /\ || || || + || || || \/ || || + || || new_buffers > 1 || || || + || || || || || + || || _______________________ || || + || ||<-------------- | | || || + \/ | Stopped by starvation | ------------>|| || + ---------------------------> |_______________________| || || + || || + || /\ || || + || || || || + || ||<-------- flush <--------------- || + || || + ------------------------------------------->|| + + +------------------------------------------------------------------------------ +EP93XX DMA API Functions +------------------------------------------------------------------------------ + + int ep93xx_dma_request(int * handle, const char * device_id, + ep93xx_dma_dev_t device) + +This function will allocate a DMA channel for a particular hardware +peripheral. Before initiating a transfer on the allocated channel, the +channel has to be setup, and buffers have to be added to the channel. + +Parameters: + int * handle A pointer which is filled in with a unique + integer value, or handle. The handle is used + to verify the validity of each call to + access the dma channel. + + const char * device_id string which is the name of the device + attached to the dma channel. + + ep93xx_dma_dev_t device hardware port to attach to the dma channel + +------------------------------------------------------------------------------ + + int ep93xx_dma_free(int handle) + +This function disables and powers down the dma channel, and releases it +for future requests. Buffers queued up for the specified channel are +released without transferring. + +Parameters: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a DMA channel. + +------------------------------------------------------------------------------ + + int ep93xx_dma_add_buffer(int handle, unsigned int source, + unsigned int dest, unsigned int size + unsigned int last, unsigned int buf_id) + +This function adds a buffer entry to the DMA buffer queue. If the channel is +in the active transfer state, the buffer is immediately transferred, +otherwise the buffer is not transferred until a start or resume +command is issued. A -1 is returned if an error occurs, otherwise +a 0 is returned. + +Parameter: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. + + unsigned int source physical address for the start of this + buffer. + + unsigned int source physical address destination of the data. + + unsigned int size buffer size in bytes + + unsigned int last 1 if this is the last buffer in the transfer. + If 1, disable the NFBint so we aren't + interrupted for another buffer + when we know there won't be another. + + unsigned int buf_id Unique value used to identify this buffer. + +------------------------------------------------------------------------------ + + int ep93xx_dma_remove_buffer(int handle, unsigned int * address, + unsigned int * size) + +This function removes a buffer entry from the DMA buffer queue. If a buffer +was removed successfully, a 0 is returned, otherwise -1 is returned. + +Parameter: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. + + unsigned int * buf_id Pointer to an integer which is filled in + with the buffer id.. + +------------------------------------------------------------------------------ + + int ep93xx_dma_queue_full(int handle) + +This function queries to determine if the buffer queue for the specified +channel is full. A return value of 1 indicates the queue is not full, and a +0 indicates the queue is full. + +Parameters: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. + +------------------------------------------------------------------------------ + + int ep93xx_dma_get_position(int handle, unsigned int * buf_id, + unsigned int * total) + +This function fills in the buffer ID of the current buffer and fills in the +total bytes transferred on the channel. If no buffer is active on the channel, +buf_id is filled in with a -1, otherwise it is the active buffer. + +Parameter: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. + + unsigned int * buf_id pointer to an integer which is filled in with + buffer ID of the buffer currently + transferring. + + unsigned int * total pointer to an integer which is filled in + with the total bytes transferred on the channel. + +------------------------------------------------------------------------------ + + int ep93xx_dma_config(int handle, unsigned int flags_m2m, + unsigned int flags_m2p, dma_callback callback, + unsigned int user_data) + +This function configures the DMA channel registers and installs a dma +callback function into the DMA instance. The DMA callback function is +defined by the driver which is using this DMA channel. It is called in +response to DMA interrupts, at the end of the DMA channel's interrupt +handler. A -1 is returned if an error occurs, otherwise a 0 is returned. + +Parameter: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. + + unsigned int flags_m2m Flags used for M2M channel configuration. + + unsigned int flags_m2p Flags used for M2P/P2M channel + configuration. + + dma_callback callback Pointer to the callback function which will + be called at the end of the dma interrupt + service routine. + + unsigned int user_data Data defined by the driver installing the + callback function. This piece of data will + be returned to the driver when the callback + function is called. + +Callback function prototype: + + void (* dma_callback)(ep93xx_dma_int_t interrupt, + ep93xx_dma_dev_t device, unsigned int user_data) + + Parameters: + ep93xx_dma_int_t interrupt + used by the DMA driver to inform the DMA callback + function of the type of DMA interrupt that happened. + + ep93xx_dma_dev_t device + hardware port attached to the dma channel. + + unsigned int user_data + is a value defined and passed in by the driver which + registered the callback function. + +------------------------------------------------------------------------------ + + int ep93xx_dma_start(int handle, unsigned int channels, + unsigned int * handles + +This function enables the DMA channel, and initiates the transfer. If the +peripheral interface calls for it, multiple DMA channels can be started +with one call to this IOCTL. A -1 is returned if an error occurs, +otherwise a 0 is returned. + +Parameter: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. For a start + multiple, this handle can be the handle + for any of the channels to be started. + + unsigned int channels Number of channels to start for this transfer. + Specifically this applies to an audio interface + where you can have up to 3 dma channels + servicing a 6 audio channel output, in which case + you need to initiate transfers on all 3 dma + channels as closely together as possible. For + the case of only one channel to be started, this + field should be a 1. + + unsigned int * handles Pointer to an array of handles, one for + each channel which is to be started. If only one + channel is to be started, this field should be + NULL. + +------------------------------------------------------------------------------ + + int ep93xx_dma_pause(int handle, unsigned int channels, + unsigned int * handles) + +This function disables the DMA channel, pausing the transfer. The +position within the currently transferring buffer is saved, and restored upon +restarting the transfer on this channel. If the peripheral interface calls +for it, multiple DMA channels can be paused with one call to this IOCTL. +A -1 is returned if an error occurs, otherwise a 0 is returned. + +Parameter: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. + + unsigned int channels Number of channels to pause for this + transfer. Specifically this applies to + an audio interface where you can have + up to 3 dma channels servicing a 6 + audio channel output, in which case you + need to pause transfers on all 3 dma + channels as closely together as possible. + + unsigned int * handles Pointer to an array of handles, one for + each channel which is to be paused. + +NOTE: There is another way to pause the DMA channel - starve it. +When the dma channel reaches the point where there are no buffers in +the queue, but the interface has not been paused, then the dma instance +will indicate that the channel is in the transfer state, but the +channel itself is disabled until a new buffer is added to the queue +If the channel is stopped via this method, a resume command is not +required to restart a transfer. A transfer is started immediately +after two new buffers are added to the queue. The reason for two is +so that both channel buffer descriptors can be programmed with valid +buffers + +------------------------------------------------------------------------------ + + int ep93xx_dma_flush(int handle) + +This function completely flushes all queued buffers and any on going +DMA transfers on a given channel. If the dma channel is in the +active transfer state, once two buffers are added to the queue, the +channel will begin transferring data right away. If in the stop +state, a start command must be issued before any new buffers are +processed. A -1 is returned if an error occurs, otherwise a 0 is returned. + +Parameters: + int handle A unique integer value, assigned + during open, used to verify the validity of + this call to access a dma channel. diff --git a/Documentation/arm/ep93xx/status.txt b/Documentation/arm/ep93xx/status.txt new file mode 100644 index 0000000..082c2dd --- /dev/null +++ b/Documentation/arm/ep93xx/status.txt @@ -0,0 +1,288 @@ +# +# EP93xx driver support status +# + +====================================================================== +(I) Introduction +====================================================================== + +The EP93xx are embedded System On Chip (SOC) processors produced +by Cirrus (www.cirrus.com). They provided support based on 2.4.21-rmk1 +kernels, and they said that there might be 2.6.x support some day. +Meanwhile they've released a 2.6.8.1 based kernel called "ursus". + +Currently we still have got a communication problem with cirrus, +for some reason it seems to be impossible to directly talk to their +developers. Hope this will change some day, but we really cannot afford +to just sit down and wait. + +The purpose of this file is to document success and todo's. + + - Section II describes hardware support, organized according to the + EP9315 datasheet. Other device datasheets are ordered similarly, + though section numbers may vary. + + - Section III contains other miscellaneous information. + +The latest version of this document may be found at: + + linux/Documentation/arm/ep93xx/status.txt + +projects homepage can be found at: + + http://members.inode.at/m.burian/ep93xx/index.html + + +====================================================================== +(II) Hardware Support +====================================================================== + +These section numbers mirror the EP9315 datasheet. + +1. Introduction +--------------- +N/A + +2. ARM920T Core and Advanced High-Speed Bus (AHB) +------------------------------------------------- +We have standard Linux 2.6 support for ARM920T Core. Thumb support +is pretty shaky, as most people do not seem to use Thumb in the +kernel. Address translation uses 16K small pages exclusively (FIXME: +is this true?) + +3. MaverickCrunch Coprocessor +----------------------------- +People have started with forward porting. Note that there's more +to it than just kernel support. You also need to have a toolchain +supporting it. We're in need of a comprehensive HOWTO that explains kernel, +toolchain and userspace aspects to a point where average developers can use it + + +4. Boot ROM +----------- +Well, not really kernel related, most people start with redboot. Make +sure to use a version that passes the correct machine type. Some +people also started porting blob / uboot. + +If any support is added for this device, it will likely be a simple +char device that allows you to read the contents of the boot rom +for interests sake. + +5. System Controller +-------------------- +System Controllers registers are set by startup code and by individual +drivers as needed, we try to keep the processor dependent stuff to +a minimum. + +Ray really wants to overhaul the system configuration stuff and move +towards something like the SA1100 people are doing. It should make +things a lot cleaner for drivers that share physical pins, or for +multifunctional blocks that require several drivers (eg: UART2 with +IrDA support) + +There is currently no dynamic clock control support. We'll probably +want to tie into the CPUfreq code at some point. + +There is no support for querying the system boot configuration or +last reset source. + +There is no power management support. Individual drivers may power +up silicon blocks as required. Some research is needed to map the +EP93xx power states onto the ACPI or PCI states that everyone seems +to use. + +There is no support for the TICK and WATCHDOGEXPIRED interrupts +generated by this block. + +There is no support for the AHB bus arbiter priority settings. + +6. Vectored Interrupt Controller +-------------------------------- +Since we can boot this can't be done dead wrong. Standard level-triggered +interrupt support is present. + +No FIQ interrupts are supported. + +Support for demultiplexing GPIO IRQs is available. + + +7. Raster Engine With Analog/LCD Integrated Timing and Interface +---------------------------------------------------------------- + +Michael has rewritten large parts of the framebuffer driver based on +skeleton.c. You need to adapt this in case you can't live with +the standard display(s) that are included. Framebuffer is fixed +size, you can change some settings at compile time, though. +TODO: clean ups, different resolutions, etc + + +8. Graphics Accelerator +----------------------- +not available yet, will be done after the framebuffer code has been +cleaned up. + + +9. 1/10/100 Mbps Ethernet LAN Controller +---------------------------------------- +Supported. Driver has been reviewed and cleaned up. +Uses generic mii routines now. It might be possible +to use DMA - but in that case we'd need to find a +workaround to get around the fact that it can only +transfer 32bit aligned data, while we'd need to transfer +data that's only 16 bit aligned. + +NICE-TO-HAVE: Could be ported to use NAPI. + +10. DMA Controller +------------------ +There is some code and documentation ported forward from the Cirrus +2.4 port. + +11. Universal Serial Bus Host Controller +---------------------------------------- +Ray has written some glue code to plug the OHCI host controller into +the Linux 2.6 USB stack. This has been tested on an EDB9301 board with +a single port populated. A serial dongle worked fine, and several +different flash keys seem to work okay with the USB mass storage +driver using SCSI disk emulation. This hasn't really been stress tested +yet, but initial results look very encouraging. + +12. Static Memory Controller +---------------------------- +Not sure how much kernel support is required here. Flash and memory +timing needs to be setup by the bootloader, so there's not much +that needs to be done here. + +No support for PCMCIA at this time. + +13. SDRAM, SyncROM, and SyncFLASH Controller +-------------------------------------------- +Again, this is probably the bootloaders problem. + +There is an errata about system instability when suspending with +an SDRAM bus speed over 50 MHz. May need to tweak this if we start +doing power management modes. + +14. UART1 With HDLC and Modem Control Signals +--------------------------------------------- +We've got a driver to use this one as UART. No DMA support. FIFO support +works. No HDLC support. Needs some syscon support to cleanly handle +HDLC and some modem signals. + +15. UART2 +--------- +We've got a driver to use this one as UART. No DMA support. FIFO support +works. No IrDA SIR support. Needs some syscon support to cleanly handle +IrDA SIR. + +16. UART3 With HDLC Encoder +--------------------------- +We've got a driver to use this one as UART. No DMA support. FIFO support +works. No HDLC or RS-485 support. Needs some syscon support to cleanly +handle HDLC and RS-485. + +17. IRDA +-------- +There is some code and documentation ported forward from the Cirrus +2.4 port. No idea how well this works, if at all. + +18. TIMERS +---------- +Timer1 is used at 508 kHz with a reload value of 5080 to provide a 100 Hz +tick signal to drive the kernel. + +Timer 2 and 3 are not currently used, nor is the debug timer 4. + + +19. WATCHDOG Timer +------------------ +Ray has some initial experimental code written (not pushed) to drive this. +The onboard watchdog seems to have a 250 ms (!) timeout, while most PC +dogs seem to have timeouts on the order of one minute or more. The standard +approach of having a user level process open the watchdog device and +kick it every so often seems like a bad idea here... a momentary system +load spike could easily delay the monitor from being scheduled, and the +system would reboot. + +Test out a watchdog monitor running at a high scheduling priority, or else +design a kernel watchdog that kicks the dog every timer tick and exports +a more reasonable timeout value to userspace. + +20. Real Time Clock With Software Trim +-------------------------------------- +We did not bother to write a driver yet, it would require a design +that ensures CPU is always powered on, and always have at least +a 32kHz clock running. Most people prefer to use and external RTC. +We've got support for the DS1337 RTC that seems to be popular on +ep93xx based boards. + +21. I2S Controller +------------------ +No support yet. Klaus is working on it. + +22. AC97 Controller +------------------- +Supported but could need some testing. + +23. Synchronous Serial Port +--------------------------- +Two driver are available, a forward port from the cirrus driver and +another driver from Ray. + +24. Pulse Width Modulator +------------------------- +No support yet. + +25. Analog Touch Screen Interface +--------------------------------- +People already played with this, AFAIK one would need a silicon +revision > D1 (November 2004) for this to work properly. + +26. Keypad Interface +-------------------- +We've got a driver for the 8x8 keypad. Chances are that you might +want to create a custom keymap. There's also support for mobile +phone like input (key 1 becomes -> A -> B -> C) if pressed repeatedly +within half a second. + +27. IDE interface +----------------- +We've got IDE working in polling only, no DMA support so far. +It needs to be cleaned up, too. + +28. GPIO +-------- +Standard LED support for red and green leds is present. + +Michael has written an I2C bus driver using the new Linux device driver model. +It supports an external DS1337 RTC device on the EECLK/EEDAT pins. + +Need some syscon support to cleanly handle the multi-function GPIO pins. + +Demultiplexing of GPIO interrupts is possible now. + +29. Security +------------ +No information available on this, so support is unlikely in the near future. + +30. Glossary +------------ +N/A + + +====================================================================== +(III) Stuff not found in the datasheet +====================================================================== + +1. printascii hack has been removed from our tree. + +2. I2C driver +We've got a bit banging I2C driver + +3. External RTC (DS1337) +Setting and getting the time works +TODO: advanced features, such as alarm, timer for /dev/rtc + +4. Controller Area Network (CAN) +We have got a character device based driver for the OKI ML9620 CAN Controller. + diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4b15f5f..f23341e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -103,6 +103,17 @@ config ARCH_EBSA110 Ethernet interface, two PCMCIA sockets, two serial ports and a parallel port. +config ARCH_EP93XX + bool "EP93xx" + select ARM_AMBA + help + Say Y here to enable support for the Cirrus EP93xx CPU family + and choose your specific CPU below. + + See the Cirrus web page for details. + + + config ARCH_CAMELOT bool "Epxa10db" help @@ -219,6 +230,8 @@ endchoice source "arch/arm/mach-clps711x/Kconfig" +source "arch/arm/mach-ep93xx/Kconfig" + source "arch/arm/mach-epxa10db/Kconfig" source "arch/arm/mach-footbridge/Kconfig" @@ -403,7 +416,7 @@ config NO_IDLE_HZ config ARCH_DISCONTIGMEM_ENABLE bool - default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) + default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) || ARCH_EP93XX help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access) @@ -415,7 +428,7 @@ source "mm/Kconfig" config LEDS bool "Timer and CPU usage LEDs" depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \ - ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \ + ARCH_EBSA285 || ARCH_EP93XX || ARCH_IMX || ARCH_INTEGRATOR || \ ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE @@ -432,7 +445,7 @@ config LEDS config LEDS_TIMER bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \ - MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 + MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 depends on LEDS default y if ARCH_EBSA110 help @@ -702,9 +715,10 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ - || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ - || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE +if PCMCIA || ARCH_CLPS7500 || ARCH_EP9312 || ARCH_EP9315 \ + || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X \ + || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK \ + || FOOTBRIDGE source "drivers/ide/Kconfig" endif diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 81bd219..924d31f 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -92,6 +92,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0x machine-$(CONFIG_ARCH_IOP3XX) := iop3xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 + machine-$(CONFIG_ARCH_EP93XX) := ep93xx machine-$(CONFIG_ARCH_OMAP1) := omap1 machine-$(CONFIG_ARCH_OMAP2) := omap2 incdir-$(CONFIG_ARCH_OMAP) := omap diff --git a/arch/arm/configs/adssphere_defconfig b/arch/arm/configs/adssphere_defconfig new file mode 100644 index 0000000..195d80e --- /dev/null +++ b/arch/arm/configs/adssphere_defconfig @@ -0,0 +1,1240 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12.2 +# Wed Jul 6 13:49:08 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# EP93xx +# +# CONFIG_ARCH_EP9301 is not set +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9312 is not set +CONFIG_ARCH_EP9315=y +# CONFIG_MACH_EDB9315 is not set +CONFIG_MACH_ADSSPHERE=y +# CONFIG_MACH_ZEFEERDZQ is not set +CONFIG_EP93XX_DMA=y +# CONFIG_ARCH_EP93XX_IDE is not set +# CONFIG_EP93XX_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_TCIC is not set +CONFIG_PCMCIA_EP93XX=y + +# +# Kernel Features +# +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyAM0,38400 rw root=/dev/ram initrd=0x00600000,5m ramdisk_size=12288 rootfstype=ext2 mtdparts=flash:256k(boot),256k(bootvars),1536k(zImage),5m(ramdisk.gz),-(flashfs1) SERIALGETTY=ttyAM0 SERIALBAUD=38400" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_ADSFLASH=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_EP93XX=y +# CONFIG_BLK_DEV_IDEDMA_EP93XX is not set +CONFIG_IDE_ARM=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +# CONFIG_BT_SCO is not set +# CONFIG_BT_RFCOMM is not set +CONFIG_BT_BNEP=y +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +# CONFIG_BT_HIDP is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=y +# CONFIG_BT_HCIUSB_SCO is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIDTL1 is not set +# CONFIG_BT_HCIBT3C is not set +# CONFIG_BT_HCIBLUECARD is not set +# CONFIG_BT_HCIBTUART is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_HERMES=y +CONFIG_ATMEL=y + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=y +CONFIG_AIRO_CS=y +CONFIG_PCMCIA_ATMEL=y +CONFIG_PCMCIA_WL3501=y +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_TSDEV=y +CONFIG_INPUT_TSDEV_SCREEN_X=640 +CONFIG_INPUT_TSDEV_SCREEN_Y=480 +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_EP93XX is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +CONFIG_TOUCHSCREEN_EP93XX=y +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_EP93XX_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_EP93XX_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_EP93XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +CONFIG_SENSORS_DS1307=y +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_MAESTRO is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CX25871_I2C is not set +CONFIG_FB_EP93XX=y +# CONFIG_FB_CRT_EP93XX is not set +# CONFIG_FB_LCD_EP93XX is not set +# CONFIG_FB_LCD_EP93XX_SHARP is not set +CONFIG_FB_LCD_EP93XX_SHARP_LQ64D343=y +# CONFIG_FB_CX25871 is not set +# CONFIG_FB_EP93XX_8BPP is not set +CONFIG_FB_EP93XX_16BPP_565=y +# CONFIG_FB_EP93XX_24BPP is not set +# CONFIG_FB_EP93XX_32BPP is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 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_OSS=y +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_EP93XX_AC97=y +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +CONFIG_USB_OV511=y +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_PEGASUS=y +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set + +# +# USB ATM/DSL drivers +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +# CONFIG_DEVPTS_FS_SECURITY is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/dma03_defconfig b/arch/arm/configs/dma03_defconfig new file mode 100644 index 0000000..59b677c --- /dev/null +++ b/arch/arm/configs/dma03_defconfig @@ -0,0 +1,1281 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.15-rc4 +# Fri Dec 9 21:21:27 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set + +# +# EP93xx +# +# CONFIG_ARCH_EP9301 is not set +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9312 is not set +CONFIG_ARCH_EP9315=y +# CONFIG_MACH_EDB9315 is not set +# CONFIG_MACH_ADSSPHERE is not set +# CONFIG_MACH_ZEFEERDZQ is not set +CONFIG_MACH_DMA03=y +CONFIG_ARCH_EP93XX_GPIO_IRQ=y +CONFIG_EP93XX_DMA=y +CONFIG_EP93XX_SSP=y +CONFIG_EP93XX_SSP_CIRRUS=y +# CONFIG_EP93XX_SSP_LINUX is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/hda1 slram=sram,0x20000000,0x2010000 parport=0xD0000020,74 lp=parport0" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_MISC=y +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=y +CONFIG_MTD_ABSENT=y +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x60000000 +CONFIG_MTD_PHYSMAP_LEN=0x02000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=4 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_SLRAM=y +CONFIG_MTD_PHRAM=y +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=12288 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_EP93XX=y +# CONFIG_BLK_DEV_IDEDMA_EP93XX is not set +CONFIG_IDE_ARM=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_EP93XX=y +CONFIG_KEYBOARD_EP93XX_SPI=y +CONFIG_KEYBOARD_EP93XX_8X8=y +CONFIG_KEYBOARD_EP93XX_8X8_CYCLING=y +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +CONFIG_TOUCHSCREEN_EP93XX=y +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_EP93XX_RTC is not set +CONFIG_DS1337_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# CAN bus devices +# +CONFIG_CAN_BUS=y +CONFIG_OKI_CAN_ML9620=y +# CONFIG_OKI_CAN_ML9620_MICRO9 is not set +CONFIG_OKI_CAN_ML9620_GASSNER=y +CONFIG_OKI_CAN_ML9620_2DEV=y +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_EP93XX=y +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=y +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_DS1307 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CX25871_I2C is not set +CONFIG_FB_EP93XX=y +# CONFIG_FB_CRT_EP93XX is not set +# CONFIG_FB_LCD_EP93XX is not set +CONFIG_FB_LCD_EP93XX_SHARP=y +# CONFIG_FB_LCD_EP93XX_SHARP_LQ64D343 is not set +# CONFIG_FB_CX25871 is not set +# CONFIG_FB_LCD_TX09D50VM1CCA is not set +# CONFIG_FB_EP93XX_8BPP is not set +# CONFIG_FB_EP93XX_16BPP_565 is not set +# CONFIG_FB_EP93XX_24BPP is not set +CONFIG_FB_EP93XX_32BPP=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_FONT_6x11=y +CONFIG_FONT_7x14=y +CONFIG_FONT_PEARL_8x8=y +CONFIG_FONT_ACORN_8x8=y +CONFIG_FONT_MINI_4x6=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +CONFIG_FONT_10x18=y + +# +# Logo configuration +# +# CONFIG_LOGO is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_DEVICE=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_OBSOLETE_OSS_DRIVER is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_EP93XX_AC97=m +CONFIG_SOUND_EP93XX_AC97_CODEC_CS4297=y +# CONFIG_SOUND_EP93XX_AUDIO_PIO is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=850 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +CONFIG_RELAYFS_FS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_9P_FS=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_WP512=y +CONFIG_CRYPTO_TGR192=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_CAST5=y +CONFIG_CRYPTO_CAST6=y +CONFIG_CRYPTO_TEA=y +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_KHAZAD=y +CONFIG_CRYPTO_ANUBIS=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/edb9301_defconfig b/arch/arm/configs/edb9301_defconfig new file mode 100644 index 0000000..e105976 --- /dev/null +++ b/arch/arm/configs/edb9301_defconfig @@ -0,0 +1,965 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-rc2-ep93xx +# Mon Nov 8 16:32:53 2004 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_HOTPLUG=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +# CONFIG_TINY_SHMEM is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set +# CONFIG_ARCH_IMX is not set + +# +# EP93xx +# +CONFIG_ARCH_EP9301=y +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9312 is not set +# CONFIG_ARCH_EP9315 is not set +CONFIG_MACH_EDB9301=y +# CONFIG_MACH_TTML is not set +CONFIG_EP93XX_DMA=y +CONFIG_EP93XX_SSP=y +CONFIG_EP93XX_SSP_CIRRUS=y +# CONFIG_EP93XX_SSP_LINUX is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# General setup +# +CONFIG_DISCONTIGMEM=y +CONFIG_ARM_AMBA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=/dev/nfs ip=dhcp" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x60000000 +CONFIG_MTD_PHYSMAP_LEN=0x01000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_EP93XX_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_EP93XX_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_EP93XX is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +CONFIG_I2C_DEBUG_CORE=y +CONFIG_I2C_DEBUG_ALGO=y +CONFIG_I2C_DEBUG_BUS=y +CONFIG_I2C_DEBUG_CHIP=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Graphics support +# +# CONFIG_FB is not set +# CONFIG_FB_CX25871_I2C is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +CONFIG_SND_DEBUG_MEMORY=y +CONFIG_SND_DEBUG_DETECT=y + +# +# Generic devices +# +CONFIG_SND_DUMMY=y +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# + +# +# ALSA USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# Misc devices +# + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811HS is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_RW_DETECT=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM 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_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE 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_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +CONFIG_USB_SERIAL_PL2303=y +# CONFIG_USB_SERIAL_SAFE 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_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_TEST is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LL_PRINTK_HACK is not set +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/edb9312_defconfig b/arch/arm/configs/edb9312_defconfig new file mode 100644 index 0000000..1a0aa51 --- /dev/null +++ b/arch/arm/configs/edb9312_defconfig @@ -0,0 +1,920 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-rc2-ep93xx +# Mon Nov 8 16:40:30 2004 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +# CONFIG_TINY_SHMEM is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set +# CONFIG_ARCH_IMX is not set + +# +# EP93xx +# +# CONFIG_ARCH_EP9301 is not set +# CONFIG_ARCH_EP9302 is not set +CONFIG_ARCH_EP9312=y +# CONFIG_ARCH_EP9315 is not set +CONFIG_MACH_EDB9312=y +# CONFIG_MACH_ACC is not set +CONFIG_EP93XX_DMA=y +CONFIG_ARCH_EP93XX_IDE=y +CONFIG_EP93XX_SSP=y +CONFIG_EP93XX_SSP_CIRRUS=y +# CONFIG_EP93XX_SSP_LINUX is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# General setup +# +CONFIG_DISCONTIGMEM=y +CONFIG_ARM_AMBA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_MISC=y + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=/dev/hda1" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CONCAT=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_FTL=y +CONFIG_NFTL=y +CONFIG_NFTL_RW=y +CONFIG_INFTL=y + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=y +CONFIG_MTD_ABSENT=y +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x60000000 +CONFIG_MTD_PHYSMAP_LEN=0x02000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=4 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_SLRAM=y +CONFIG_MTD_PHRAM=y +CONFIG_MTD_MTDRAM=y +CONFIG_MTDRAM_TOTAL_SIZE=512 +CONFIG_MTDRAM_ERASE_SIZE=1 +CONFIG_MTDRAM_ABS_POS=0x20000000 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=12288 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_EP93XX=y +# CONFIG_BLK_DEV_IDEDMA_EP93XX is not set +CONFIG_IDE_ARM=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_EP93XX=y +CONFIG_KEYBOARD_EP93XX_SPI=y +CONFIG_KEYBOARD_EP93XX_8X8=y +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +CONFIG_TOUCHSCREEN_EP93XX=y +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_EP93XX_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_EP93XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_DS1337=y +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CX25871_I2C is not set +CONFIG_FB_EP93XX=y +# CONFIG_FB_CRT_EP93XX is not set +CONFIG_FB_LCD_EP93XX=y +# CONFIG_FB_LCD_EP93XX_SHARP is not set +# CONFIG_FB_CX25871 is not set +# CONFIG_FB_EP93XX_8BPP is not set +# CONFIG_FB_EP93XX_16BPP_565 is not set +# CONFIG_FB_EP93XX_24BPP is not set +CONFIG_FB_EP93XX_32BPP=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_FONT_6x11=y +CONFIG_FONT_PEARL_8x8=y +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 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_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# Misc devices +# + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_PRINTK_HACK=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/edb9315_defconfig b/arch/arm/configs/edb9315_defconfig new file mode 100644 index 0000000..3e6033b --- /dev/null +++ b/arch/arm/configs/edb9315_defconfig @@ -0,0 +1,954 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-rc2-ep93xx +# Mon Nov 8 17:01:50 2004 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +# CONFIG_TINY_SHMEM is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set +# CONFIG_ARCH_IMX is not set + +# +# EP93xx +# +# CONFIG_ARCH_EP9301 is not set +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9312 is not set +CONFIG_ARCH_EP9315=y +CONFIG_MACH_EDB9315=y +CONFIG_EP93XX_DMA=y +# CONFIG_ARCH_EP93XX_IDE is not set +CONFIG_EP93XX_SSP=y +CONFIG_EP93XX_SSP_CIRRUS=y +# CONFIG_EP93XX_SSP_LINUX is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# General setup +# +CONFIG_DISCONTIGMEM=y +CONFIG_ARM_AMBA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttyCL0 map=mtd6,0x30000000,+0x200000 root=/dev/nfs nfsroot=192.168.1.224:/nfsarm_grma video=ep93xxfb ip=192.168.1.220:192.168.1.224:192.168.1.2:255.255.255.0::eth0:" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x60000000 +CONFIG_MTD_PHYSMAP_LEN=0x2000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=4 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +CONFIG_MTD_MTDRAM=y +CONFIG_MTDRAM_TOTAL_SIZE=512 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_ABS_POS=0x20000000 +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_EP93XX=y +# CONFIG_KEYBOARD_EP93XX_SPI is not set +# CONFIG_KEYBOARD_EP93XX_8X8 is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +CONFIG_TOUCHSCREEN_EP93XX=y +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_EP93XX_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_EP93XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_DS1337=y +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +CONFIG_I2C_DEBUG_CORE=y +CONFIG_I2C_DEBUG_ALGO=y +CONFIG_I2C_DEBUG_BUS=y +CONFIG_I2C_DEBUG_CHIP=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +# CONFIG_DEVPTS_FS_SECURITY is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=2 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CX25871_I2C is not set +CONFIG_FB_EP93XX=y +# CONFIG_FB_CRT_EP93XX is not set +CONFIG_FB_LCD_EP93XX=y +# CONFIG_FB_LCD_EP93XX_SHARP is not set +# CONFIG_FB_CX25871 is not set +# CONFIG_FB_EP93XX_8BPP is not set +CONFIG_FB_EP93XX_16BPP_565=y +# CONFIG_FB_EP93XX_24BPP is not set +# CONFIG_FB_EP93XX_32BPP is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Misc devices +# + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811HS is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_RW_DETECT is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM 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_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETSERVO is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LL_PRINTK_HACK is not set +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ttml_defconfig b/arch/arm/configs/ttml_defconfig new file mode 100644 index 0000000..e0b96ae --- /dev/null +++ b/arch/arm/configs/ttml_defconfig @@ -0,0 +1,1052 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.13 +# Thu Sep 8 16:54:14 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set + +# +# EP93xx +# +CONFIG_ARCH_EP9301=y +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9312 is not set +# CONFIG_ARCH_EP9315 is not set +# CONFIG_MACH_EDB9301 is not set +CONFIG_MACH_TTML=y +# CONFIG_ARCH_EP93XX_GPIO_IRQ is not set +CONFIG_EP93XX_DMA=y +CONFIG_EP93XX_SSP=y +# CONFIG_EP93XX_SSP_CIRRUS is not set +CONFIG_EP93XX_SSP_LINUX=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=off root=1f02 rootfstype=jffs2" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x60000000 +CONFIG_MTD_PHYSMAP_LEN=0x01000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTML_DEVICES=y +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_EP93XX_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_EP93XX_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# CAN bus devices +# +# CONFIG_CAN_BUS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_EP93XX is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C_SENSOR is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_DS1307 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +CONFIG_I2C_DEBUG_CORE=y +CONFIG_I2C_DEBUG_ALGO=y +CONFIG_I2C_DEBUG_BUS=y +CONFIG_I2C_DEBUG_CHIP=y + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set +# CONFIG_FB_CX25871_I2C is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRPRIME 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_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 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_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +CONFIG_USB_SERIAL_PL2303=y +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI 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_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/zefeerdzb_defconfig b/arch/arm/configs/zefeerdzb_defconfig new file mode 100644 index 0000000..39aefdd --- /dev/null +++ b/arch/arm/configs/zefeerdzb_defconfig @@ -0,0 +1,961 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-rc2-ep93xx +# Fri Jan 7 11:19:19 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_HOTPLUG=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +# CONFIG_TINY_SHMEM is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set +# CONFIG_ARCH_IMX is not set + +# +# EP93xx +# +# CONFIG_ARCH_EP9301 is not set +CONFIG_ARCH_EP9302=y +# CONFIG_ARCH_EP9312 is not set +# CONFIG_ARCH_EP9315 is not set +# CONFIG_MACH_EDB9302 is not set +CONFIG_MACH_ZEFEERDZB=y +CONFIG_ARCH_EP93XX_GPIO_IRQ=y +CONFIG_EP93XX_DMA=y +# CONFIG_EP93XX_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# General setup +# +CONFIG_DISCONTIGMEM=y +CONFIG_ARM_AMBA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=/dev/nfs ip=dhcp" +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +CONFIG_MTD_ZEFEERDZB=y + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_NAND_ZEFEEREVB=y +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=6144 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_EP93XX=y +# CONFIG_KEYBOARD_EP93XX_SPI is not set +# CONFIG_KEYBOARD_EP93XX_8X8 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_EP93XX_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_EP93XX_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_EP93XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_M41T00 is not set +CONFIG_I2C_DEBUG_CORE=y +CONFIG_I2C_DEBUG_ALGO=y +CONFIG_I2C_DEBUG_BUS=y +CONFIG_I2C_DEBUG_CHIP=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_NAND=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Graphics support +# +# CONFIG_FB is not set +# CONFIG_FB_CX25871_I2C is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +CONFIG_SND_DEBUG_MEMORY=y +CONFIG_SND_DEBUG_DETECT=y + +# +# Generic devices +# +CONFIG_SND_DUMMY=y +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# + +# +# ALSA USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# Misc devices +# + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811HS is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_RW_DETECT=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM 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_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_TEST is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_DONT_REORDER_CODE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LL_PRINTK_HACK is not set +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/zefeerdzq_defconfig b/arch/arm/configs/zefeerdzq_defconfig new file mode 100644 index 0000000..8314eee --- /dev/null +++ b/arch/arm/configs/zefeerdzq_defconfig @@ -0,0 +1,1174 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.13 +# Tue Oct 4 10:04:06 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set + +# +# EP93xx +# +# CONFIG_ARCH_EP9301 is not set +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9312 is not set +CONFIG_ARCH_EP9315=y +# CONFIG_MACH_EDB9315 is not set +# CONFIG_MACH_ADSSPHERE is not set +CONFIG_MACH_ZEFEERDZQ=y +# CONFIG_MACH_DMA03 is not set +# CONFIG_ARCH_EP93XX_GPIO_IRQ is not set +CONFIG_EP93XX_DMA=y +# CONFIG_ARCH_EP93XX_IDE is not set +# CONFIG_EP93XX_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/ram" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_MISC=y +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PLATRAM is not set +CONFIG_MTD_ZEFEERDZQ=y + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_NAND_ZEFEEREVB=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=12288 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_EP93XX=y +# CONFIG_BLK_DEV_IDEDMA_EP93XX is not set +CONFIG_IDE_ARM=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_EP93XX_ETHERNET=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ATMEL is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_EP93XX=y +# CONFIG_KEYBOARD_EP93XX_SPI is not set +# CONFIG_KEYBOARD_EP93XX_8X8 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_EP93XX=y +CONFIG_SERIAL_EP93XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_EP93XX_RTC is not set +# CONFIG_DS1337_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# CAN bus devices +# +# CONFIG_CAN_BUS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_EP93XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C_SENSOR is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_DS1307 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CX25871_I2C is not set +CONFIG_FB_EP93XX=y +# CONFIG_FB_CRT_EP93XX is not set +# CONFIG_FB_LCD_EP93XX is not set +# CONFIG_FB_LCD_EP93XX_SHARP is not set +# CONFIG_FB_LCD_EP93XX_SHARP_LQ64D343 is not set +# CONFIG_FB_CX25871 is not set +CONFIG_FB_LCD_TX09D50VM1CCA=y +# CONFIG_FB_EP93XX_8BPP is not set +# CONFIG_FB_EP93XX_16BPP_565 is not set +CONFIG_FB_EP93XX_24BPP=y +# CONFIG_FB_EP93XX_32BPP is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +CONFIG_FONT_SUN8x16=y +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_DONT_REORDER_CODE=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig new file mode 100644 index 0000000..2b5c2d6 --- /dev/null +++ b/arch/arm/mach-ep93xx/Kconfig @@ -0,0 +1,193 @@ + +menu "EP93xx" + depends on ARCH_EP93XX + +choice + prompt "EP93xx CPU Type" + default EP9312 + help + There are several types of EP93xx CPUs available. + Choosing the right one here enables you to select + model specific drivers later. + +config ARCH_EP9301 + bool "EP9301" + help + Say Y here if you have intend to run this kernel on a EP9301 CPU. + +config ARCH_EP9302 + bool "EP9302" + help + Say Y here if you have intend to run this kernel on a EP9302 CPU. + +config ARCH_EP9312 + bool "EP9312" + help + Say Y here if you intend to run this kernel on a EP9312 CPU. + + +config ARCH_EP9315 + bool "EP9315" + help + Say Y here if you intend to run this kernel on a EP9315 CPU. +endchoice + +choice + prompt "EP9301 Boards" + depends on ARCH_EP9301 + default EDB9301 + help + There are several EP9301-based boards available. + Choosing the right one here enables various board- + specific options. + +config MACH_EDB9301 + bool "Cirrus Logic EDB9301" + select MTD + select MTD_PHYSMAP + help + Say Y here if you intend to run this kernel on an EDB9301. + +config MACH_TTML + bool "TTML TripDawg" + help + Say Y here if you intend to run this kernel on an TTML TripDawg. + +endchoice + +choice + prompt "EP9302 Boards" + depends on ARCH_EP9302 + default EDB9302 + help + There are several EP9302-based boards available. + Choosing the right one here enables various board- + specific options. + +config MACH_EDB9302 + bool "Cirrus Logic EDB9302" + select MTD + select MTD_PHYSMAP + help + Say Y here if you intend to run this kernel on an EDB9302. + +config MACH_ZEFEERDZB + bool "Dave Zefeer DZB on ZefeerEVB-L" + select MTD + help + Say Y here if you intend to run this kernel on an Zefeer DZB. + pluggend onto ZefeerEVB-L board. + +config MACH_ZEFEER_EVBL_107 + bool " Dave ZefeerEVB-L - version 1.0.7 (PCB CS044404)" + depends on MACH_ZEFEERDZB + default n + help + Say Y here if you intend to run this kernel on an ZefeerEVB-L + version 1.0.7. + +endchoice + +choice + prompt "EP9312 Boards" + depends on ARCH_EP9312 + default EDB9312 + help + There are several EP9312-based boards available. + Choosing the right one here enables various board- + specific options. + +config MACH_EDB9312 + bool "Cirrus Logic EDB9312" + select MTD + select MTD_PHYSMAP + help + Say Y here if you intend to run this kernel on an EDB9312. + + +config MACH_ACC + bool "HiFish ACC" + help + Say Y here if you are using the HiFish Audio Control Center" + +endchoice + +choice + prompt "EP9315 Boards" + depends on ARCH_EP9315 + default EDB9315 + help + There are several EP9315-based boards available. + Choosing the right one here enables various board- + specific options. + +config MACH_EDB9315 + bool "Cirrus Logic EDB9315" + select MTD + select MTD_PHYSMAP + help + Say Y here if you intend to run this kernel on an EDB9315. + +config MACH_ADSSPHERE + bool "Applied Data Systems Sphere" + select MTD + help + Say Y here if you intend to run this kernel on an ADSSPHERE. + +config MACH_ZEFEERDZQ + bool "Dave Zefeer DZQ on ZefeerEVB (L or H)" + select MTD + help + Say Y here if you intend to run this kernel on an Zefeer DZQ. + Both evaluation board are supported (ZefeerEVB-L/ZefeerEVB-H). + +config MACH_DMA03 + bool "Gassner DMA03" + select MTD + select MTD_PHYSMAP + help + Say Y here if you intend to run this kernel on an DMA03. + +endchoice + +config ARCH_EP93XX_GPIO_IRQ + bool " EP93xx GPIO IRQ demux" + depends on ARCH_EP93XX + help + Say Y here if you want to expand the IRQ number to GPIO IRQ. + +config EP93XX_DMA + bool " EP93xx Internal DMA Support" + default y + help + Say Y here if you want to enable DMA Support for EP93XX family + CPUs. + +config EP93XX_SSP + bool "SSP support" + help + If you require SSP support, there are two SSP drivers + available to choose from. + +choice + prompt "SSP driver" + depends on EP93XX_SSP + default EP93XX_SSP_LINUX + +config EP93XX_SSP_CIRRUS + tristate "Cirrus Logic SSP driver" + depends on EP93XX_SSP + help + Say Y here for the Cirrus-supplied SSP driver. It is + quite specific to the EDB93xx evaluation boards. + +config EP93XX_SSP_LINUX + tristate "Linux SSP driver" + depends on EP93XX_SSP + help + Say Y here for an SSP driver which is heavily based on the + SA-1100 and PXA2xx SSP drivers. + +endchoice + +endmenu diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile new file mode 100644 index 0000000..19c56b3 --- /dev/null +++ b/arch/arm/mach-ep93xx/Makefile @@ -0,0 +1,17 @@ +obj-y += ep93xx.o irq.o time.o + +obj-$(CONFIG_MACH_ACC) += mach-acc.o +obj-$(CONFIG_MACH_EDB9301) += mach-edb9301.o +obj-$(CONFIG_MACH_EDB9302) += mach-edb9302.o +obj-$(CONFIG_MACH_EDB9312) += mach-edb9312.o +obj-$(CONFIG_MACH_EDB9315) += mach-edb9315.o +obj-$(CONFIG_MACH_ADSSPHERE) += mach-adssphere.o +obj-$(CONFIG_MACH_TTML) += mach-ttml.o +obj-$(CONFIG_MACH_ZEFEERDZB) += mach-zefeerdzb.o +obj-$(CONFIG_MACH_ZEFEERDZQ) += mach-zefeerdzq.o +obj-$(CONFIG_MACH_DMA03) += mach-dma03.o + +obj-$(CONFIG_EP93XX_DMA) += dma_ep93xx.o + +obj-$(CONFIG_EP93XX_SSP_LINUX) += ssp.o ssp2.o +obj-$(CONFIG_EP93XX_SSP_CIRRUS) += ssp-cirrus.o diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot new file mode 100644 index 0000000..c87653e --- /dev/null +++ b/arch/arm/mach-ep93xx/Makefile.boot @@ -0,0 +1,6 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 + zreladdr-$(CONFIG_MACH_ZEFEERDZB) := 0xD0008000 +params_phys-$(CONFIG_MACH_ZEFEERDZB) := 0xD0000100 + zreladdr-$(CONFIG_MACH_ZEFEERDZQ) := 0xD0008000 +params_phys-$(CONFIG_MACH_ZEFEERDZQ) := 0xD0000100 diff --git a/arch/arm/mach-ep93xx/dma_ep93xx.c b/arch/arm/mach-ep93xx/dma_ep93xx.c new file mode 100644 index 0000000..817de48 --- /dev/null +++ b/arch/arm/mach-ep93xx/dma_ep93xx.c @@ -0,0 +1,3346 @@ +/****************************************************************************** + * arch/arm/mach-ep9312/dma_ep93xx.c + * + * Support functions for the ep93xx internal DMA channels. + * (see also Documentation/arm/ep93xx/dma.txt) + * + * Copyright (C) 2003 Cirrus Logic + * + * A large portion of this file is based on the dma api implemented by + * Nicolas Pitre, dma-sa1100.c, copyrighted 2000. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "dma_ep93xx.h" + +/***************************************************************************** + * + * Debugging macros + * + ****************************************************************************/ +#undef DEBUG +/*#define DEBUG 1 */ +#ifdef DEBUG +#define DPRINTK( x... ) printk( ##x ) +#else +#define DPRINTK( x... ) +#endif + +/***************************************************************************** + * + * static global variables + * + ****************************************************************************/ +ep93xx_dma_t dma_chan[MAX_EP93XX_DMA_CHANNELS]; + +/* + * Maximum physical DMA buffer size + */ +#define MAX_DMA_SIZE 0xffff +#define MAX_DMA_ORDER 12 + +/* + * lock used to protect the list of dma channels while searching for a free + * channel during dma_request. + */ +static spinlock_t dma_list_lock = SPIN_LOCK_UNLOCKED; + +/***************************************************************************** + * + * Internal DMA processing functions. + * + ****************************************************************************/ +/***************************************************************************** + * + * get_dma_channel_from_handle() + * + * If Handle is valid, returns the DMA channel # (0 to 9 for channels 1-10) + * If Handle is not valid, returns -1. + * + ****************************************************************************/ +static int dma_get_channel_from_handle(int handle) +{ + int channel; + + /* + * Get the DMA channel # from the handle. + */ + channel = ((int)handle & DMA_HANDLE_SPECIFIER_MASK) >> 28; + + /* + * See if this is a valid handle. + */ + if (dma_chan[channel].last_valid_handle != (int)handle) { + DPRINTK("DMA ERROR - invalid handle 0x%x \n", handle); + /* + * Fail, invalid handle + */ + return (-1); + } + + /* + * See if this instance is still open + */ + if (!dma_chan[channel].ref_count) { + /* + * Fail, instance closed + */ + return (-1); + } + + return (channel); +} + +/***************************************************************************** + * + * dma_m2m_irq_handler + * + * TODO: need to add support for M2M interrupt handling!!! + * + ****************************************************************************/ +static irqreturn_t +dma_m2m_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + ep93xx_dma_t *dma = (ep93xx_dma_t *) dev_id; + unsigned int M2M_reg_base = dma->reg_base; + ep93xx_dma_dev_t dma_int = UNDEF_INT; + unsigned int read_back, loop, uiCONTROL, uiINTERRUPT; + + loop = readl(M2M_reg_base + M2M_OFFSET_INTERRUPT); + + /* + * Determine what kind of dma interrupt this is. + */ + if (readl(M2M_reg_base + M2M_OFFSET_INTERRUPT) & + INTERRUPT_M2M_STALLINT) + dma_int = STALL; + else if (readl(M2M_reg_base + M2M_OFFSET_INTERRUPT) & + INTERRUPT_M2M_NFBINT) + dma_int = NFB; + else if (readl(M2M_reg_base + M2M_OFFSET_INTERRUPT) & + INTERRUPT_M2M_DONEINT) + dma_int = DONE; + + DPRINTK("IRQ: b=%#x st=%#x\n", (int)dma->current_buffer->source, + dma_int); + + /* + * Stall Interrupt: The Channel is stalled, meaning nothing is + * programmed to transfer right now. So, we're back to the + * beginnning. If there's a buffer to transfer, program it into + * max and base 0 registers. + */ + if (dma_int == STALL) { + DPRINTK("1 "); + + if (dma->total_buffers) { + + if (readl(M2M_reg_base + M2M_OFFSET_BCR0) != + 0) { + writel(0x0, M2M_reg_base + M2M_OFFSET_INTERRUPT); + return IRQ_HANDLED; + + } + + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current_buffer + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + + /* + * check if there's a new buffer to transfer. + */ + if (dma->new_buffers && dma->xfer_enable) { + /* + * We have a new buffer to transfer so program in the buffer + * values. Since a STALL interrupt was triggered, we + * program the buffer descriptor 0 + * + * Set the SAR_BASE/DAR_BASE/BCR registers with values from the + * next buffer in the queue. + */ + writel(dma->buffer_queue[dma->current_buffer]. + source, + M2M_reg_base + M2M_OFFSET_SAR_BASE0); + writel(dma->buffer_queue[dma->current_buffer]. + dest, + M2M_reg_base + M2M_OFFSET_DAR_BASE0); + writel(dma->buffer_queue[dma->current_buffer]. + size, + M2M_reg_base + M2M_OFFSET_BCR0); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + /* + * If there's a second new buffer, we program the second + * buffer descriptor. + */ +#if 0 + if (dma->new_buffers) { + DPRINTK("A "); + + /* + * Set the SAR_BASE/DAR_BASE/BCR registers with values from the + * next buffer in the queue. + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + source, + M2M_reg_base + M2M_OFFSET_SAR_BASE1); + + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + dest, + M2M_reg_base + M2M_OFFSET_DAR_BASE0); + + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + size, + M2M_reg_base + M2M_OFFSET_BCR0); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + /* + * Enable the NFB Interrupt. + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_NFBINTEN; + writel(uiCONTROL, + M2M_reg_base + M2M_OFFSET_CONTROL); + } +#endif + } + /* + * Read my lips. No new buffers. + */ + else { + DPRINTK("2 \n"); + /* + * There's a chance we setup both buffer descriptors, but + * didn't service the NFB quickly enough, causing the channel + * to transfer both buffers, then enter the stall state. + * So, we need to be able to process the second buffer. + */ + if ((dma->used_buffers + dma->new_buffers) < + dma->total_buffers) { + DPRINTK("3 "); + + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma-> + current_buffer]. + size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer]. + used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current buffer pointer. + */ + dma->current_buffer = + (dma->current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS; + + } + + /* + * No new buffers to transfer, so disable the channel. + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + writel(uiCONTROL, + M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Indicate that this channel is in the pause by starvation + * state by setting the pause bit to true. + */ + dma->pause = TRUE; + + DPRINTK("End of stall handling. \n"); + DPRINTK("STATUS - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", + readl(M2M_reg_base + M2M_CONTROL.Value)); + DPRINTK("REMAIN - 0x%x \n", + readl(M2M_reg_base + M2M_REMAIN.Value)); + DPRINTK("PPALLOC - 0x%x \n", + readl(M2M_reg_base + M2M_PPALLOC.Value)); + DPRINTK("BASE0 - 0x%x \n", + readl(M2M_reg_base + M2M_BASE0.Value)); + DPRINTK("MAXCNT0 - 0x%x \n", + readl(M2M_reg_base + M2M_MAXCNT0.Value)); + DPRINTK("CURRENT0 - 0x%x \n", + readl(M2M_reg_base + M2M_CURRENT0.Value)); + DPRINTK("BASE1 - 0x%x \n", + readl(M2M_reg_base + M2M_BASE1.Value)); + DPRINTK("MAXCNT1 - 0x%x \n", + readl(M2M_reg_base + M2M_MAXCNT1.Value)); + DPRINTK("CURRENT1 - 0x%x \n", + readl(M2M_reg_base + M2M_CURRENT1.Value)); + + DPRINTK + ("Buffer buf_id source size last used \n"); + for (loop = 0; loop < 32; loop++) { + DPRINTK + ("%d 0x%x 0x%x 0x%x %d %d \n", + loop, + dma->buffer_queue[loop].buf_id, + dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, + dma->buffer_queue[loop].used); + } + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", + dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", + dma->total_bytes); + DPRINTK("total buffer - %d \n", + dma->total_buffers); + DPRINTK("new buffers - %d \n", + dma->new_buffers); + DPRINTK("current buffer - %d \n", + dma->current_buffer); + DPRINTK("last buffer - %d \n", + dma->last_buffer); + DPRINTK("used buffers - %d \n", + dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", + dma->callback); + } + } + /* + * Total number of buffers in the queue is 0. + */ + else { + /* + * No buffers to transfer, or old buffers to mark as used, + * so Disable the channel + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + writel(uiCONTROL, + M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Must read the control register back after a write. + */ + read_back = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Indicate that this channel is in the pause by + * starvation state by setting the pause bit to true. + */ + dma->pause = TRUE; + } + } + /* + * Next Frame Buffer Interrupt. If there's a new buffer program it + * Check if this is the last buffer in the transfer, + * and if it is, disable the NFB int to prevent being + * interrupted for another buffer when we know there won't be + * another. + */ + if (dma_int == NFB) { + DPRINTK("5 "); + + if (dma->total_buffers) { + DPRINTK("6 "); + /* + * The iCurrentBuffer has already been transfered. so add the + * byte count from the current buffer to the total byte count. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the Current Buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + if ((dma->buffer_queue[(dma->current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS].last) + || (dma->new_buffers == 0) + || (dma->xfer_enable == FALSE)) { + DPRINTK("7 "); + + /* + * This is the last Buffer in this transaction, so disable + * the NFB interrupt. We shouldn't get an NFB int when the + * FSM moves to the ON state where it would typically get the + * NFB int indicating a new buffer can be programmed. + * Instead, once in the ON state, the DMA will just proceed + * to complet the transfer of the current buffer, move the + * FSB directly to the STALL state where a STALL interrupt + * will be generated. + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_NFBINTEN; + writel(uiCONTROL, + M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * The current buffer has been transferred, so increment + * the current buffer counter to reflect this. + */ + dma->current_buffer = + (dma->current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS; + + DPRINTK("End of NFB handling. \n"); + DPRINTK("STATUS - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_CONTROL)); + DPRINTK("REMAIN - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_REMAIN)); + DPRINTK("PPALLOC - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_PPALLOC)); + DPRINTK("BASE0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_BASE0)); + DPRINTK("MAXCNT0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_MAXCNT0)); + DPRINTK("CURRENT0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_CURRENT0)); + DPRINTK("BASE1 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_BASE1)); + DPRINTK("MAXCNT1 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_MAXCNT1)); + DPRINTK("CURRENT1 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_CURRENT1)); + + DPRINTK + ("Buffer buf_id source size last used \n"); + for (loop = 0; loop < 32; loop++) { + DPRINTK + ("%d 0x%x 0x%x 0x%x %d %d \n", + loop, + dma->buffer_queue[loop].buf_id, + dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, + dma->buffer_queue[loop].used); + } + DPRINTK + ("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, + dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", + dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", + dma->total_bytes); + DPRINTK("total buffer - %d \n", + dma->total_buffers); + DPRINTK("new buffers - %d \n", + dma->new_buffers); + DPRINTK("current buffer - %d \n", + dma->current_buffer); + DPRINTK("last buffer - %d \n", + dma->last_buffer); + DPRINTK("used buffers - %d \n", + dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", + dma->callback); + + } else if (dma->new_buffers) { + DPRINTK("8 "); + /* + * we have a new buffer, so increment the current buffer to + * point to the next buffer, which is already programmed into + * the DMA. Next time around, it'll be pointing to the + * current buffer. + */ + dma->current_buffer = + (dma->current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS; + + /* + * we know we have a new buffer to program as the next + * buffer, so check which set of SAR_BASE/DAR_BASE/BCR registers + * to program. + */ + if (readl(M2M_reg_base + M2M_OFFSET_STATUS) & STATUS_M2M_NB) { + /* + * Set the SAR_BASE1/DAR_BASE1/BCR1 registers with values from the + * next buffer in the queue. + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + source, + M2M_reg_base + M2M_OFFSET_SAR_BASE1); + + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + dest, + M2M_reg_base + M2M_OFFSET_DAR_BASE1); + + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + size, + M2M_reg_base + M2M_OFFSET_BCR1); + } else { + /* + * Set the SAR_BASE0/DAR_BASE0/BCR0 registers with values from the + * next buffer in the queue. + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + source, + M2M_reg_base + M2M_OFFSET_SAR_BASE0); + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + dest, + M2M_reg_base + M2M_OFFSET_DAR_BASE0); + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + size, + M2M_reg_base + M2M_OFFSET_BCR0); + } + + /* + * Decrement the new buffers counter + */ + dma->new_buffers--; + } + } + /* + * Total number of buffers is 0 - really we should never get here, + * but just in case. + */ + else { + DPRINTK("9 \n"); + + /* + * No new buffers to transfer, so Disable the channel + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Indicate that the channel is paused by starvation. + */ + dma->pause = 1; + } + } + + /* + * Done interrupt generated, indicating that the transfer is complete. + */ + if (dma_int == DONE) { +#if 0 + /* The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + /* + * Increment the current_buffer + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; +#endif + /* + * Clear the interrupt. + */ + uiINTERRUPT = + readl(M2M_reg_base + M2M_OFFSET_INTERRUPT); + uiINTERRUPT &= ~INTERRUPT_M2M_DONEINT; + writel(uiINTERRUPT, + M2M_reg_base + M2M_OFFSET_INTERRUPT); + + DPRINTK("STATUS - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_CONTROL)); + DPRINTK("SAR_BASE0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_SAR_BASE0)); + DPRINTK("DAR_BASE0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_DAR_BASE0)); + DPRINTK("SAR_CURRENT0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_SAR_CURRENT0)); + DPRINTK("DAR_CURRENT0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_DAR_CURRENT0)); + DPRINTK("BCR0 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_BCR0)); + DPRINTK("SAR_BASE1 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_SAR_BASE1)); + DPRINTK("DAR_BASE1 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_DAR_BASE1)); + DPRINTK("BCR1 - 0x%x \n", + readl(M2M_reg_base + M2M_OFFSET_BCR1)); + + /* + * Disable the channel. + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Indicate that we're in the stopped mode. + */ + dma->pause = 1; + dma->xfer_enable = 0; + } + + /* + * Make sure the interrupt was valid, and if it was, then check + * if a callback function was installed for this DMA channel. If a + * callback was installed call it. + */ + if ((dma_int != UNDEF_INT) && dma->callback) { + dma->callback(dma_int, dma->device, dma->user_data); + } + return IRQ_HANDLED; +} + +/***************************************************************************** + * + * dma_m2p_irq_handler + * + * + * + ****************************************************************************/ +static irqreturn_t +dma_m2p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + ep93xx_dma_t *dma = (ep93xx_dma_t *) dev_id; + unsigned int M2P_reg_base = dma->reg_base; + unsigned int read_back; + ep93xx_dma_dev_t dma_int = UNDEF_INT; + unsigned int loop, uiCONTROL, uiINTERRUPT; + + /* + * Determine what kind of dma interrupt this is. + */ + if (readl(M2P_reg_base + M2P_OFFSET_INTERRUPT) & + INTERRUPT_M2P_STALLINT) + dma_int = STALL; + else if (readl(M2P_reg_base + M2P_OFFSET_INTERRUPT) & + INTERRUPT_M2P_NFBINT) + dma_int = NFB; + else if (readl(M2P_reg_base + M2P_OFFSET_INTERRUPT) & + INTERRUPT_M2P_CHERRORINT) + dma_int = CHERROR; + + /* + * Stall Interrupt: The Channel is stalled, meaning nothing is + * programmed to transfer right now. So, we're back to the + * beginnning. If there's a buffer to transfer, program it into + * max and base 0 registers. + */ + if (dma_int == STALL) { + DPRINTK("1 "); + + if (dma->total_buffers) { + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current_buffer + */ + dma->current_buffer = (dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS; + + /* + * check if there's a new buffer to transfer. + */ + if (dma->new_buffers && dma->xfer_enable) { + /* + * We have a new buffer to transfer so program in the buffer + * values. Since a STALL interrupt was triggered, we + * program the base0 and maxcnt0 + * + * Set the MAXCNT0 register with the buffer size + */ + writel(dma->buffer_queue[dma->current_buffer].size, + M2P_reg_base + M2P_OFFSET_MAXCNT0); + + /* + * Set the BASE0 register with the buffer base address + */ + writel(dma->buffer_queue[dma->current_buffer].source, + M2P_reg_base + M2P_OFFSET_BASE0); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + if (dma->new_buffers) { + DPRINTK("A "); + /* + * Set the MAXCNT1 register with the buffer size + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + size, + M2P_reg_base + M2P_OFFSET_MAXCNT1); + + /* + * Set the BASE1 register with the buffer base address + */ + writel(dma-> + buffer_queue[dma-> + current_buffer + + 1 % + MAX_EP93XX_DMA_BUFFERS]. + source, + M2P_reg_base + M2P_OFFSET_BASE1); + + /* + * Decrement the new buffer counter + */ + dma->new_buffers--; + + /* + * Enable the NFB Interrupt. + */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_NFBINTEN; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + } + } + /* + * No new buffers. + */ + else { + DPRINTK("2 \n"); + /* + * There's a chance we setup both buffer descriptors, but + * didn't service the NFB quickly enough, causing the channel + * to transfer both buffers, then enter the stall state. + * So, we need to be able to process the second buffer. + */ + if ((dma->used_buffers + dma->new_buffers) < + dma->total_buffers) { + DPRINTK("3 "); + + /* + * The current_buffer has already been tranfered, so add the + * byte count to the total_bytes field. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma-> + current_buffer]. + size; + + /* + * Mark the current_buffer as used. + */ + dma->buffer_queue[dma->current_buffer]. + used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + /* + * Increment the current buffer pointer. + */ + dma->current_buffer = + (dma->current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS; + + } + + /* + * No new buffers to transfer, so disable the channel. + */ + /* go dma_regs->CONTROL.Field.ENABLE = 0; */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * Indicate that this channel is in the pause by starvation + * state by setting the pause bit to true. + */ + dma->pause = TRUE; + + DPRINTK("STATUS - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CONTROL)); + DPRINTK("REMAIN - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_REMAIN)); + DPRINTK("PPALLOC - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_PPALLOC)); + DPRINTK("BASE0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_BASE0)); + DPRINTK("MAXCNT0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_MAXCNT0)); + DPRINTK("CURRENT0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CURRENT0)); + DPRINTK("BASE1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_BASE1)); + DPRINTK("MAXCNT1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_MAXCNT1)); + DPRINTK("CURRENT1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CURRENT1)); + + DPRINTK + ("Buffer buf_id source size last used \n"); + for (loop = 0; loop < 32; loop++) { + DPRINTK + ("%d 0x%x 0x%x 0x%x %d %d \n", + loop, + dma->buffer_queue[loop].buf_id, + dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, + dma->buffer_queue[loop].used); + } + DPRINTK + ("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, + dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", + dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", + dma->total_bytes); + DPRINTK("total buffer - %d \n", + dma->total_buffers); + DPRINTK("new buffers - %d \n", + dma->new_buffers); + DPRINTK("current buffer - %d \n", + dma->current_buffer); + DPRINTK("last buffer - %d \n", + dma->last_buffer); + DPRINTK("used buffers - %d \n", + dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", + dma->callback); + } + } + /* + * Total number of buffers in the queue is 0. + */ + else { + /* + * No buffers to transfer, or old buffers to mark as used, + * so Disable the channel + */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * Must read the control register back after a write. + */ + read_back = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * Indicate that this channel is in the pause by + * starvation state by setting the pause bit to true. + */ + dma->pause = TRUE; + } + } + /* + * Next Frame Buffer Interrupt. If there's a new buffer program it + * Check if this is the last buffer in the transfer, + * and if it is, disable the NFB int to prevent being + * interrupted for another buffer when we know there won't be + * another. + */ + if (dma_int == NFB) { + DPRINTK("5 "); + + if (dma->total_buffers) { + DPRINTK("6 "); + /* + * The iCurrentBuffer has already been transfered. so add the + * byte count from the current buffer to the total byte count. + */ + dma->total_bytes = dma->total_bytes + + dma->buffer_queue[dma->current_buffer].size; + + /* + * Mark the Current Buffer as used. + */ + dma->buffer_queue[dma->current_buffer].used = TRUE; + + /* + * Increment the used buffer counter + */ + dma->used_buffers++; + + DPRINTK("#%d", dma->current_buffer); + + if ((dma->buffer_queue[(dma->current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS].last) + || (dma->new_buffers == 0) + || (dma->xfer_enable == FALSE)) { + DPRINTK("7 "); + + /* + * This is the last Buffer in this transaction, so disable + * the NFB interrupt. We shouldn't get an NFB int when the + * FSM moves to the ON state where it would typically get the + * NFB int indicating a new buffer can be programmed. + * Instead, once in the ON state, the DMA will just proceed + * to complet the transfer of the current buffer, move the + * FSB directly to the STALL state where a STALL interrupt + * will be generated. + */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_NFBINTEN; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * The current buffer has been transferred, so increment + * the current buffer counter to reflect this. + */ + dma->current_buffer = + (dma->current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS; + + DPRINTK("End of NFB handling. \n"); + DPRINTK("STATUS - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CONTROL)); + DPRINTK("REMAIN - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_REMAIN)); + DPRINTK("PPALLOC - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_PPALLOC)); + DPRINTK("BASE0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_BASE0)); + DPRINTK("MAXCNT0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_MAXCNT0)); + DPRINTK("CURRENT0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CURRENT0)); + DPRINTK("BASE1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_BASE1)); + DPRINTK("MAXCNT1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_MAXCNT1)); + DPRINTK("CURRENT1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CURRENT1)); + + DPRINTK + ("Buffer buf_id source size last used \n"); + for (loop = 0; loop < 32; loop++) { + DPRINTK + ("%d 0x%x 0x%x 0x%x %d %d \n", + loop, + dma->buffer_queue[loop].buf_id, + dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, + dma->buffer_queue[loop].used); + } + DPRINTK + ("pause 0x%x 0x%x 0x%x %d %d \n", + dma->pause_buf.buf_id, + dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", + dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", + dma->total_bytes); + DPRINTK("total buffer - %d \n", + dma->total_buffers); + DPRINTK("new buffers - %d \n", + dma->new_buffers); + DPRINTK("current buffer - %d \n", + dma->current_buffer); + DPRINTK("last buffer - %d \n", + dma->last_buffer); + DPRINTK("used buffers - %d \n", + dma->used_buffers); + DPRINTK("callback addr - 0x%x \n", + dma->callback); + + } else if (dma->new_buffers) { + DPRINTK("8 "); + /* + * we have a new buffer, so increment the current buffer to + * point to the next buffer, which is already programmed into + * the DMA. Next time around, it'll be pointing to the + * current buffer. + */ + dma->current_buffer = + (dma->current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS; + + /* + * we know we have a new buffer to program as the next + * buffer, so check which set of MAXCNT and BASE registers + * to program. + */ + if (readl(M2P_reg_base + M2P_OFFSET_STATUS) & + STATUS_M2P_NEXTBUFFER) { + /* + * Set the MAXCNT1 register with the buffer size + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + size, + M2P_reg_base + M2P_OFFSET_MAXCNT1); + + /* + * Set the BASE1 register with the buffer base address + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + source, + M2P_reg_base + M2P_OFFSET_BASE1); + } else { + /* + * Set the MAXCNT0 register with the buffer size + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + size, + M2P_reg_base + M2P_OFFSET_MAXCNT0); + + /* + * Set the BASE0 register with the buffer base address + */ + writel(dma-> + buffer_queue[(dma-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS]. + source, + M2P_reg_base + M2P_OFFSET_BASE0); + } + + /* + * Decrement the new buffers counter + */ + dma->new_buffers--; + } + } + /* + * Total number of buffers is 0 - really we should never get here, + * but just in case. + */ + else { + DPRINTK("9 \n"); + + /* + * No new buffers to transfer, so Disable the channel + */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + } + } + /* + * Channel Error Interrupt, or perhipheral interrupt, specific to the + * memory to/from peripheral channels. + */ + if (dma_int == CHERROR) { + /* + * just clear the interrupt, it's really up to the peripheral + * driver to determine if any further action is necessary. + */ + uiINTERRUPT = + readl(M2P_reg_base + M2P_OFFSET_INTERRUPT); + uiINTERRUPT &= ~INTERRUPT_M2P_CHERRORINT; + writel(uiINTERRUPT, M2P_reg_base + M2P_OFFSET_INTERRUPT); + } + + /* + * Make sure the interrupt was valid, and if it was, then check + * if a callback function was installed for this DMA channel. If a + * callback was installed call it. + */ + if ((dma_int != UNDEF_INT) && dma->callback) { + dma->callback(dma_int, dma->device, dma->user_data); + } + return IRQ_HANDLED; +} + +/***************************************************************************** + * + * ep9312_dma_open_m2p(int device) + * + * Description: This function will attempt to open a M2P/P2M DMA channel. + * If the open is successful, the channel number is returned, + * otherwise a negative number is returned. + * + * Parameters: + * device: device for which the dma channel is requested. + * + ****************************************************************************/ +static int dma_open_m2p(int device) +{ + int channel = -1; + unsigned int loop; + unsigned int M2P_reg_base; + unsigned int uiPWRCNT; + + DPRINTK("DMA Open M2P with hw dev %d\n", device); + + /* + * Lock the dma channel list. + */ + spin_lock(&dma_list_lock); + DPRINTK("1\n"); + /* + * Verify that the device requesting DMA isn't already using a DMA channel + */ + if (device >= 10) { + loop = 1; /* Rx transfer requested */ + } else { + loop = 0; /* Tx transfer requested */ + } + + for (; loop < 10; loop = loop + 2) { + /* + * Before checking for a matching device, check that the + * channel is in use, otherwise the device field is + * invalid. + */ + if (dma_chan[loop].ref_count) { + if (device == dma_chan[loop].device) { + DPRINTK("DMA Open M2P - Error\n"); + /* + * Fail. + */ + return (-1); + } + } + } + + /* + * Get a DMA channel instance for the given hardware device. + * If this is a TX look for even numbered channels, else look for + * odd numbered channels + */ + if (device >= 10) { + loop = 1; /* Rx transfer requested */ + } else { + loop = 0; /* Tx transfer requested */ + } + + for (; loop < 10; loop = loop + 2) { + if (!dma_chan[loop].ref_count) { + /* + * Capture the channel and increment the reference count. + */ + channel = loop; + dma_chan[channel].ref_count++; + break; + } + } + + /* + * Unlock the dma channel list. + */ + spin_unlock(&dma_list_lock); + + /* + * See if we got a valid channel. + */ + if (channel < 0) { + /* + * Fail. + */ + return (-1); + } + + /* + * Point regs to the correct dma channel register base. + */ + M2P_reg_base = dma_chan[channel].reg_base; + + /* + * Turn on the clock for the specified DMA channel + * TODO: need to use the correct register name for the + * power control register. + */ + uiPWRCNT = readl(SYSCON_PWRCNT); + switch (channel) { + case 0: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH0; + break; + } + + case 1: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH1; + break; + } + + case 2: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH2; + break; + } + + case 3: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH3; + break; + } + + case 4: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH4; + break; + } + + case 5: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH5; + break; + } + + case 6: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH6; + break; + } + + case 7: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH7; + break; + } + case 8: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH8; + break; + } + case 9: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH9; + break; + } + + default: + { + return (-1); + } + } + writel(uiPWRCNT, SYSCON_PWRCNT); + + /* + * Clear out the control register before any further setup. + */ + writel(0, M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * Setup the peripheral port value in the DMA channel registers. + */ + if (device < 10) { + writel((unsigned int)device, + M2P_reg_base + M2P_OFFSET_PPALLOC); + } else { + writel((unsigned int)(device - 10), + M2P_reg_base + M2P_OFFSET_PPALLOC); + } + + /* + * Let's hold on to the value of the Hw device for comparison later. + */ + dma_chan[channel].device = device; + + /* + * Success. + */ + return (channel); +} + +/***************************************************************************** + * + * dma_open_m2m(int device) + * + * Description: This function will attempt to open a M2M DMA channel. + * If the open is successful, the channel number is returned, + * otherwise a negative number is returned. + * + * Parameters: + * device: device for which the dma channel is requested. + * + ****************************************************************************/ +static int dma_open_m2m(int device) +{ + int channel = -1; + unsigned int loop; + unsigned int M2M_reg_base; + unsigned int uiPWRCNT, uiCONTROL; + + DPRINTK("DMA Open M2M with hw dev %d\n", device); + + /* + * Lock the dma channel list. + */ + spin_lock(&dma_list_lock); + DPRINTK("1\n"); + + /* + * Check if this device is already allocated a channel. + * TODO: can one M2M device be allocated multiple channels? + */ + for (loop = DMA_MEMORY; loop < UNDEF; loop++) { + /* + * Before checking for a matching device, check that the + * channel is in use, otherwise the device field is + * invalid. + */ + if (dma_chan[loop].ref_count) { + if (device == dma_chan[loop].device) { + DPRINTK + ("Error - dma_open_m2m - already allocated channel\n"); + + /* + * Unlock the dma channel list. + */ + spin_unlock(&dma_list_lock); + + /* + * Fail. + */ + return (-1); + } + } + } + + /* + * Get a DMA channel instance for the given hardware device. + */ + for (loop = 10; loop < 12; loop++) { + if (!dma_chan[loop].ref_count) { + /* + * Capture the channel and increment the reference count. + */ + channel = loop; + dma_chan[channel].ref_count++; + break; + } + } + + /* + * Unlock the dma channel list. + */ + spin_unlock(&dma_list_lock); + + /* + * See if we got a valid channel. + */ + if (channel < 0) { + /* + * Fail. + */ + return (-1); + } + + /* + * Point regs to the correct dma channel register base. + */ + M2M_reg_base = dma_chan[channel].reg_base; + + /* + * Turn on the clock for the specified DMA channel + * TODO: need to use the correct register name for the + * power control register. + */ + uiPWRCNT = readl(SYSCON_PWRCNT); + switch (channel) { + case 10: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH0; + break; + } + + case 11: + { + uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH1; + break; + } + + default: + { + return (-1); + } + } + writel(uiPWRCNT, SYSCON_PWRCNT); + + DPRINTK("DMA Open - power control: 0x%x \n", + readl(SYSCON_PWRCNT)); + + /* + * Clear out the control register before any further setup. + */ + writel(0, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Setup the transfer mode and the request source selection within + * the DMA M2M channel registers. + */ + switch (device) { + case DMA_MEMORY: + { + /* + * Clear TM field, set RSS field to 0 + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= + ~(CONTROL_M2M_TM_MASK | CONTROL_M2M_RSS_MASK); + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + break; + } + + case DMA_IDE: + { + /* + * Set RSS field to 3, Set NO_HDSK, Set PW field to 1 + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= + ~(CONTROL_M2M_RSS_MASK | CONTROL_M2M_PW_MASK); + uiCONTROL |= + (3 << CONTROL_M2M_RSS_SHIFT) | CONTROL_M2M_NO_HDSK | + (2 << CONTROL_M2M_PW_SHIFT); + + uiCONTROL &= ~(CONTROL_M2M_ETDP_MASK); + uiCONTROL &= ~(CONTROL_M2M_DACKP); + uiCONTROL &= ~(CONTROL_M2M_DREQP_MASK); + + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + break; + } + + case DMARx_SSP: + { + /* + * Set RSS field to 1, Set NO_HDSK, Set TM field to 2 + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= + ~(CONTROL_M2M_RSS_MASK | CONTROL_M2M_TM_MASK); + uiCONTROL |= + (1 << CONTROL_M2M_RSS_SHIFT) | CONTROL_M2M_NO_HDSK | + (2 << CONTROL_M2M_TM_SHIFT); + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + break; + } + + case DMATx_SSP: + { + /* + * Set RSS field to 2, Set NO_HDSK, Set TM field to 1 + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= + ~(CONTROL_M2M_RSS_MASK | CONTROL_M2M_TM_MASK); + uiCONTROL |= + (2 << CONTROL_M2M_RSS_SHIFT) | CONTROL_M2M_NO_HDSK | + (1 << CONTROL_M2M_TM_SHIFT); + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + break; + } + + case DMATx_EXT_DREQ: + { + /* + * Set TM field to 2, set RSS field to 0 + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= + ~(CONTROL_M2M_RSS_MASK | CONTROL_M2M_TM_MASK); + uiCONTROL |= 1 << CONTROL_M2M_TM_SHIFT; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + break; + } + + case DMARx_EXT_DREQ: + { + + /* + * Set TM field to 2, set RSS field to 0 + */ + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= + ~(CONTROL_M2M_RSS_MASK | CONTROL_M2M_TM_MASK); + uiCONTROL |= 2 << CONTROL_M2M_TM_SHIFT; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + break; + } + + default: + { + return -1; + } + } + + /* + * Let's hold on to the value of the Hw device for comparison later. + */ + dma_chan[channel].device = device; + + /* + * Success. + */ + return (channel); +} + +/***************************************************************************** + * + * int dma_config_m2m(ep93xx_dma_t * dma, unsigned int flags_m2m, + * dma_callback callback, unsigned int user_data) + * + * Description: Configure the DMA channel and install a callback function. + * This function will have to be called for every transfer + * + * dma: Pointer to the dma instance data for the M2M channel to + * configure. + * flags_m2m Flags used to configure an M2M dma channel and determine + * if a callback function and user_data information are included + * in this call. + * callback function pointer which is called near the end of the + * dma channel's irq handler. + * user_data defined by the calling driver. + * + ****************************************************************************/ +static int +dma_config_m2m(ep93xx_dma_t * dma, unsigned int flags_m2m, + dma_callback callback, unsigned int user_data) +{ + unsigned long flags; + unsigned int M2M_reg_base, uiCONTROL; + + /* + * Make sure the channel is disabled before configuring the channel. + * + * TODO: Is this correct?? Making a big change here... + */ + /* if(!dma->pause || (!dma->pause && dma->xfer_enable)) */ + if (dma->xfer_enable) { + /* + * DMA channel is not paused, so we can't configure it. + */ + DPRINTK("DMA channel not paused, so can't configure! \n"); + return (-1); + } + + /* + * Mask interrupts. + */ + local_irq_save(flags); + + /* + * Setup a pointer into the dma channel's register set. + */ + M2M_reg_base = dma->reg_base; + + /* + * By default we enable the stall interrupt. + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_STALLINTEN; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * By default we enable the done interrupt. + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_DONEINTEN; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Set up the transfer control fields based on values passed in + * the flags_m2m field. + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + + if (flags_m2m & DESTINATION_HOLD) { + uiCONTROL |= CONTROL_M2M_DAH; + } else { + uiCONTROL &= ~CONTROL_M2M_DAH; + } + + if (flags_m2m & SOURCE_HOLD) { + uiCONTROL |= CONTROL_M2M_SAH; + } else { + uiCONTROL &= ~CONTROL_M2M_SAH; + } + + uiCONTROL &= ~CONTROL_M2M_TM_MASK; + uiCONTROL |= + (((flags_m2m & TRANSFER_MODE_MASK) >> TRANSFER_MODE_SHIFT) << + CONTROL_M2M_TM_SHIFT) & CONTROL_M2M_TM_MASK; + + uiCONTROL &= ~CONTROL_M2M_PWSC_MASK; + uiCONTROL |= (((flags_m2m & WAIT_STATES_MASK) >> WAIT_STATES_SHIFT) << + CONTROL_M2M_PWSC_SHIFT) & CONTROL_M2M_PWSC_MASK; + + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Save the callback function in the dma instance for this channel. + */ + dma->callback = callback; + + /* + * Save the user data in the the dma instance for this channel. + */ + dma->user_data = user_data; + + /* + * Put the dma instance into the pause state by setting the + * pause bit to true. + */ + dma->pause = TRUE; + + local_irq_restore(flags); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * int dma_start(int handle, unsigned int channels, unsigned int * handles) + * + * Description: Initiate a transfer on up to 3 channels. + * + * handle: handle for the channel to initiate transfer on. + * channels: number of channels to initiate transfers on. + * handles: pointer to an array of handles, one for each channel which + * is to be started. + * + ****************************************************************************/ +static int dma_start_m2m(int channel, ep93xx_dma_t * dma) +{ + unsigned long flags; + unsigned int M2M_reg_base = dma->reg_base; + unsigned int uiCONTROL; + + /* + * Mask interrupts while we get this started. + */ + local_irq_save(flags); + + /* + * Make sure the channel has at least one buffer in the queue. + */ + if (dma->new_buffers < 1) { + /* + * Unmask irqs + */ + local_irq_restore(flags); + + DPRINTK("DMA Start: Channel starved.\n"); + + /* + * This channel does not have enough buffers queued up, + * so enter the pause by starvation state. + */ + dma->xfer_enable = TRUE; + dma->pause = TRUE; + + /* + * Success. + */ + return (0); + } + + /* + * Clear any pending interrupts. + */ + writel(0x0, M2M_reg_base + M2M_OFFSET_INTERRUPT); + + /* + * Set up one or both buffer descriptors with values from the next one or + * two buffers in the queue. By default enable the next frame buffer + * interrupt on the channel. + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_NFBINTEN; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * enable the stall interrupt. + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_STALLINTEN; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Update the dma channel instance transfer state. + */ + dma->xfer_enable = TRUE; + dma->pause = FALSE; + + /* + * Decrement the new buffers counter. + */ + dma->new_buffers--; + + /* + * Program up the first buffer descriptor with a source and destination + * and a byte count. + */ + writel(dma->buffer_queue[dma->current_buffer].source, + M2M_reg_base + M2M_OFFSET_SAR_BASE0); + + writel(dma->buffer_queue[dma->current_buffer].dest, + M2M_reg_base + M2M_OFFSET_DAR_BASE0); + + writel(dma->buffer_queue[dma->current_buffer].size, + M2M_reg_base + M2M_OFFSET_BCR0); + + /* + * Now we enable the channel. This initiates the transfer. + */ + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_ENABLE; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + + /* + * Before restoring irqs set up the second buffer descriptor + * with a second buffer if we have a second buffer. + */ + /* if(dma->new_buffers) + { + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].source, + M2M_reg_base+M2M_OFFSET_SAR_BASE1 ); + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].dest, + M2M_reg_base+M2M_OFFSET_DAR_BASE1 ); + + outl( dma->buffer_queue[(dma->current_buffer + 1) % + MAX_EP93XX_DMA_BUFFERS].size, + M2M_reg_base+M2M_OFFSET_BCR1 ); + } */ + + /* + * If this is a memory to memory transfer, we need to s/w trigger the + * transfer by setting the start bit within the control register. + */ + if (dma->device == DMA_MEMORY) { + uiCONTROL = + readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2M_START; + writel(uiCONTROL, + M2M_reg_base + M2M_OFFSET_CONTROL); + } + + DPRINTK("DMA - It's been started!!"); + DPRINTK("STATUS - 0x%x \n", readl(M2M_reg_base + M2M_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", readl(M2M_reg_base + M2M_CONTROL.Value)); + DPRINTK("REMAIN - 0x%x \n", readl(M2M_reg_base + M2M_REMAIN.Value)); + DPRINTK("PPALLOC - 0x%x \n", readl(M2M_reg_base + M2M_PPALLOC.Value)); + DPRINTK("BASE0 - 0x%x \n", readl(M2M_reg_base + M2M_BASE0.Value)); + DPRINTK("MAXCNT0 - 0x%x \n", readl(M2M_reg_base + M2M_MAXCNT0.Value)); + DPRINTK("CURRENT0 - 0x%x \n", readl(M2M_reg_base + M2M_CURRENT0.Value)); + DPRINTK("BASE1 - 0x%x \n", readl(M2M_reg_base + M2M_BASE1.Value)); + DPRINTK("MAXCNT1 - 0x%x \n", readl(M2M_reg_base + M2M_MAXCNT1.Value)); + DPRINTK("CURRENT1 - 0x%x \n", readl(M2M_reg_base + M2M_CURRENT1.Value)); + + DPRINTK("Pause - %d \n", dma_pointers[0]->pause); + DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes); + DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers); + DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers); + DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer); + DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer); + DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers); + + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * DMA interface functions + * + ****************************************************************************/ + +/***************************************************************************** + * + * int dma_init(int handle, unsigned int flags_m2p, unsigned int flags_m2m, + * dma_callback callback, unsigned int user_data) + * + * Description: Configure the DMA channel and install a callback function. + * + * handle: Handle unique the each instance of the dma interface, used + * to verify this call. + * flags_m2p Flags used to configure an M2P/P2M dma channel and determine + * if a callback function and user_data information are included + * in this call. This field should be NULL if handle represents + * an M2M channel. + * flags_m2m Flags used to configure an M2M dma channel and determine + * if a callback function and user_data information are included + * in this call. This field should be NULL if handle represents + * an M2P/P2M channel. + * callback function pointer which is called near the end of the + * dma channel's irq handler. + * user_data defined by the calling driver. + * + ****************************************************************************/ +int +ep93xx_dma_config(int handle, unsigned int flags_m2p, unsigned int flags_m2m, + dma_callback callback, unsigned int user_data) +{ + int channel; + ep93xx_dma_t *dma; + unsigned long flags; + unsigned int M2P_reg_base, uiCONTROL; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Config: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + DPRINTK("DMA Config \n"); + + dma = &dma_chan[channel]; + + local_irq_save(flags); + + /* + * Check if the channel is currently transferring. + */ + if (dma->xfer_enable) { + local_irq_restore(flags); + + /* + * Already transferring, invalid command. + */ + return (-EINVAL); + } + + /* + * Check if this is an m2m function. + */ + if (channel >= 10) { + local_irq_restore(flags); + + /* + * Call another function to handle m2m config. + */ + return (dma_config_m2m(dma, flags_m2m, callback, user_data)); + } + + /* + * Setup a pointer into the dma channel's register set. + */ + M2P_reg_base = dma->reg_base; + + /* + * By default we enable the stall interrupt. + */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_STALLINTEN; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * Configure the channel for an error from the peripheral. + */ + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + if (flags_m2p && CHANNEL_ERROR_INT_ENABLE) + uiCONTROL |= CONTROL_M2P_CHERRORINTEN; + else + uiCONTROL &= ~CONTROL_M2P_CHERRORINTEN; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + if (flags_m2p && EP93XX_DMA_ABORT) + uiCONTROL |= CONTROL_M2P_ABRT; + else + uiCONTROL &= ~CONTROL_M2P_ABRT; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + if (flags_m2p && IGNORE_CHANNEL_ERROR) + uiCONTROL |= CONTROL_M2P_ICE; + else + uiCONTROL &= ~CONTROL_M2P_ICE; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + + /* + * Save the callback function in the dma instance for this channel. + */ + dma->callback = callback; + + /* + * Save the user data in the the dma instance for this channel. + */ + dma->user_data = user_data; + + /* + * Put the dma instance into the pause state by setting the + * pause bit to true. + */ + dma->pause = TRUE; + + local_irq_restore(flags); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * int dma_start(int handle, unsigned int channels, unsigned int * handles) + * + * Description: Initiate a transfer on up to 3 channels. + * + * handle: handle for the channel to initiate transfer on. + * channels: number of channels to initiate transfers on. + * handles: pointer to an array of handles, one for each channel which + * is to be started. + * + ****************************************************************************/ +int ep93xx_dma_start(int handle, unsigned int channels, unsigned int *handles) +{ + ep93xx_dma_t *dma_pointers[3]; + unsigned int M2P_reg_bases[3]; + unsigned int loop, uiCONTROL; + unsigned long flags; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Start: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + if (channels < 1) { + printk(KERN_ERR "DMA Start: Invalid parameter.\n"); + + return (-EINVAL); + } + + DPRINTK("DMA Start \n"); + + /* + * Mask off registers. + */ + local_irq_save(flags); + + /* + * Check if this is a start multiple. + */ + if (channels > 1) { + DPRINTK + ("DMA ERROR: Start, multiple start not supported yet \n"); + return (-1); + } + /* + * Only one channel + */ + else { + /* + * Check if this channel is already transferring. + */ + if (dma_chan[channel].xfer_enable && !dma_chan[channel].pause) { + printk(KERN_ERR + "DMA Start: Invalid command for channel %d.\n", + channel); + DPRINTK("DMA Start: Invalid command for channel %d.\n", + channel); + + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * This channel is already transferring, so return an error. + */ + return (-EINVAL); + } + + /* + * If this is an M2M channel, call a different function. + */ + if (channel >= 10) { + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * Call the m2m start function. Only start one channel. + */ + return (dma_start_m2m(channel, &dma_chan[channel])); + } + + /* + * Make sure the channel has at least one buffer in the queue. + */ + if (dma_chan[channel].new_buffers < 1) { + DPRINTK("DMA Start: Channel starved.\n"); + + /* + * This channel does not have enough buffers queued up, + * so enter the pause by starvation state. + */ + dma_chan[channel].xfer_enable = TRUE; + dma_chan[channel].pause = TRUE; + + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * Success. + */ + return (0); + } + + /* + * Set up a dma instance pointer for this dma channel. + */ + dma_pointers[0] = &dma_chan[channel]; + + /* + * Set up a pointer to the register set for this channel. + */ + M2P_reg_bases[0] = dma_pointers[0]->reg_base; + } + + /* + * Setup both MAXCNT registers with values from the next two buffers + * in the queue, and enable the next frame buffer interrupt on the channel. + */ + for (loop = 0; loop < channels; loop++) { + /* + * By default we enable the next frame buffer interrupt. + */ + uiCONTROL = readl(M2P_reg_bases[loop] + M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_NFBINTEN; + writel(uiCONTROL, M2P_reg_bases[loop] + M2P_OFFSET_CONTROL); + + /* + * Check if we need to restore a paused transfer. + */ + if (dma_pointers[loop]->pause_buf.buf_id != -1) { + writel(dma_pointers[loop]->pause_buf.size, + M2P_reg_bases[loop] + M2P_OFFSET_MAXCNT0); + } else { + writel(dma_pointers[loop]-> + buffer_queue[dma_pointers[loop]->current_buffer]. + size, + M2P_reg_bases[loop] + M2P_OFFSET_MAXCNT0); + } + } + + for (loop = 0; loop < channels; loop++) { + /* + * Enable the specified dma channels. + */ + uiCONTROL = + readl(M2P_reg_bases[loop] + M2P_OFFSET_CONTROL); + uiCONTROL |= CONTROL_M2P_ENABLE; + writel(uiCONTROL, + M2P_reg_bases[loop] + M2P_OFFSET_CONTROL); + + /* + * Update the dma channel instance transfer state. + */ + dma_pointers[loop]->xfer_enable = TRUE; + dma_pointers[loop]->pause = FALSE; + + if (dma_pointers[loop]->pause_buf.buf_id == -1) { + dma_pointers[loop]->new_buffers--; + } + } + + /* + * Program up the BASE0 registers for all specified channels, this + * will initiate transfers on all specified channels. + */ + for (loop = 0; loop < channels; loop++) { + /* + * Check if we need to restore a paused transfer. + */ + if (dma_pointers[loop]->pause_buf.buf_id != -1) { + writel(dma_pointers[loop]->pause_buf.source, + M2P_reg_bases[loop] + M2P_OFFSET_BASE0); + + /* + * Set the pause buffer to NULL + */ + dma_pointers[loop]->pause_buf.buf_id = -1; + dma_pointers[loop]->pause_buf.size = 0; + } else { + writel(dma_pointers[loop]-> + buffer_queue[dma_pointers[loop]->current_buffer]. + source, + M2P_reg_bases[loop] + M2P_OFFSET_BASE0); + } + } + + /* + * Before restoring irqs setup the second MAXCNT/BASE + * register with a second buffer. + */ + for (loop = 0; loop < channels; loop++) { + if (dma_pointers[loop]->new_buffers) { + writel(dma_pointers[loop]-> + buffer_queue[(dma_pointers[loop]-> + current_buffer + + 1) % MAX_EP93XX_DMA_BUFFERS].size, + M2P_reg_bases[loop] + M2P_OFFSET_MAXCNT1); + writel(dma_pointers[loop]-> + buffer_queue[(dma_pointers[loop]-> + current_buffer + + 1) % + MAX_EP93XX_DMA_BUFFERS].source, + M2P_reg_bases[loop] + M2P_OFFSET_BASE1); + } + } + +/* + DPRINTK("DMA - It's been started!!"); + DPRINTK("STATUS - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_STATUS))); + DPRINTK("CONTROL - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_CONTROL))); + DPRINTK("REMAIN - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_REMAIN))); + DPRINTK("PPALLOC - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_PPALLOC))); + DPRINTK("BASE0 - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_BASE0))); + DPRINTK("MAXCNT0 - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_MAXCNT0))); + DPRINTK("CURRENT0 - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_CURRENT0))); + DPRINTK("BASE1 - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_BASE1))); + DPRINTK("MAXCNT1 - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_MAXCNT1))); + DPRINTK("CURRENT1 - 0x%x \n", readl(M2P_reg_base+M2P_OFFSET_CURRENT1))); + + DPRINTK("Pause - %d \n", dma_pointers[0]->pause); + DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes); + DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers); + DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers); + DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer); + DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer); + DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers); +*/ + /* + * Unmask irqs + */ + local_irq_restore(flags); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * int ep93xx_dma_add_buffer(int handle, unsigned int * address, + * unsigned int size, unsigned int last) + * + * Description: Add a buffer entry to the DMA buffer queue. + * + * handle: handle for the channel to add this buffer to. + * address: Pointer to an integer which is the start address of the + * buffer which is to be added to the queue. + * size: size of the buffer in bytes. + * last: 1 if this is the last buffer in this stream, 0 otherwise. + * + ****************************************************************************/ +int +ep93xx_dma_add_buffer(int handle, unsigned int source, unsigned int dest, + unsigned int size, unsigned int last, unsigned int buf_id) +{ + unsigned long flags; + ep93xx_dma_t *dma; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Add Buffer: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + /* + * Get a pointer to the dma instance. + */ + dma = &dma_chan[channel]; + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * If the buffer queue is full, last_buffer is the same as current_buffer and + * we're not tranfering, or last_buffer is pointing to a used buffer, then exit. + * TODO: do I need to do any more checks? + */ + if (dma->total_buffers >= MAX_EP93XX_DMA_BUFFERS) { + /* + * Restore the state of the irqs + */ + local_irq_restore(flags); + + /* + * Fail. + */ + return (-1); + } + + /* + * Add this buffer to the queue + */ + dma->buffer_queue[dma->last_buffer].source = source; + dma->buffer_queue[dma->last_buffer].dest = dest; + dma->buffer_queue[dma->last_buffer].size = size; + dma->buffer_queue[dma->last_buffer].last = last; + dma->buffer_queue[dma->last_buffer].buf_id = buf_id; + + /* + * Reset the used field of the buffer structure. + */ + dma->buffer_queue[dma->last_buffer].used = FALSE; + + /* + * Increment the End Item Pointer. + */ + dma->last_buffer = (dma->last_buffer + 1) % MAX_EP93XX_DMA_BUFFERS; + + /* + * Increment the new buffers counter and the total buffers counter + */ + dma->new_buffers++; + dma->total_buffers++; + + /* + * restore the interrupt state. + */ + local_irq_restore(flags); + + /* + * Check if the channel was starved into a stopped state. + */ + if (dma->pause && dma->xfer_enable) { + if (dma->new_buffers >= 1) { + DPRINTK + ("DMA - calling start from add after starve. \n"); + + /* + * The channel was starved into a stopped state, and we've got + * 2 new buffers, so start tranferring again. + */ + ep93xx_dma_start(handle, 1, NULL); + } + } + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * int ep93xx_dma_remove_buffer(int handle, unsigned int * address, + * unsigned int * size) + * + * Description: Remove a buffer entry from the DMA buffer queue. If + * buffer was removed successfully, return 0, otherwise + * return -1. + * + * handle: handle for the channel to remove a buffer from. + * address: Pointer to an integer which is filled in with the start + * address of the removed buffer. + * size: Pointer to an integer which is filled in with the size in + * bytes of the removed buffer. + * + ****************************************************************************/ +int ep93xx_dma_remove_buffer(int handle, unsigned int *buf_id) +{ + unsigned int test; + unsigned int loop; + int return_val = -1; + unsigned long flags; + ep93xx_dma_t *dma; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Remove Buffer: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + dma = &dma_chan[channel]; + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * Make sure there are used buffers to be returned. + */ + if (dma->used_buffers) { + test = dma->last_buffer; + + for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) { + if (dma->buffer_queue[test].used + && (dma->buffer_queue[test].buf_id != -1)) { + /*DPRINTK("buffer %d used \n", test); */ + + /* + * This is a used buffer, fill in the buf_id pointer + * with the buf_id for this buffer. + */ + *buf_id = dma->buffer_queue[test].buf_id; + + /* + * Reset this buffer structure + */ + dma->buffer_queue[test].buf_id = -1; + + /* + * Decrement the used buffer counter, and the total buffer counter. + */ + dma->used_buffers--; + dma->total_buffers--; + + /* + * Successful removal of a buffer, so set the return + * value to 0, then exit this loop. + */ + return_val = 0; + break; + } + + /* + * This buffer isn't used, let's see if the next one is. + */ + test = (test + 1) % MAX_EP93XX_DMA_BUFFERS; + } + } + + /* + * Restore interrupts. + */ + local_irq_restore(flags); + + /* + * Success. + */ + return (return_val); +} + +/***************************************************************************** + * + * int ep93xx_dma_pause(int handle, unsigned int channels, + * unsigned int * handles) + * + * Description: Disable any ongoing transfer for the given channel, retaining + * the state of the current buffer transaction so that upon + * resume, the dma will continue where it left off. + * + * handle: Handle for the channel to be paused. If this is a pause for + * for multiple channels, handle is a valid handle for one of + * the channels to be paused. + * channels: number of channel to pause transfers on. + * handles: Pointer to an array of handles, one for each channel which + * to be paused. If this pause is intended only for one + * channel, this field should be set to NULL. + * + ****************************************************************************/ +int ep93xx_dma_pause(int handle, unsigned int channels, unsigned int *handles) +{ + unsigned long flags; + ep93xx_dma_t *dma; + int channel; + unsigned int M2M_reg_base, M2P_reg_base; + + DPRINTK("ep93xx_dma_pause \n"); + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + /* + * restore interrupts. + */ + local_irq_restore(flags); + + printk(KERN_ERR "DMA Pause: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + DPRINTK("DMA %d: pause \n", channel); + + /* + * Set up a pointer to the dma instance data. + */ + dma = &dma_chan[channel]; + + /* + * Set a pointer to the dma channel registers. + */ + if (channel < 10) { + M2P_reg_base = dma->reg_base; + } else { + M2M_reg_base = dma->reg_base; + } + + /* + * Check if we're already paused. + */ + if (dma->pause) { + /* + * We're paused, but are we stopped? + */ + if (dma->xfer_enable) { + /* + * Put the channel in the stopped state. + */ + dma->xfer_enable = FALSE; + } + + DPRINTK("DMA Pause - already paused."); + } else { + /* + * Put the channel into the stopped state. + */ + dma->xfer_enable = FALSE; + dma->pause = TRUE; + } + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + /* + * Already paused, so exit. + */ + return (0); +} + +/***************************************************************************** + * + * void ep93xx_dma_flush(int handle) + * + * Description: Flushes all queued buffers and transfers in progress + * for the given channel. Return the buffer entries + * to the calling function. + * + * handle: handle for the channel for which the flush is intended. + * + ****************************************************************************/ +int ep93xx_dma_flush(int handle) +{ + unsigned int loop; + unsigned long flags; + ep93xx_dma_t *dma; + int channel; + unsigned int M2P_reg_base; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Flush: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + DPRINTK("DMA %d: flush \n", channel); + + /* + * Set up a pointer to the dma instance data for this channel + */ + dma = &dma_chan[channel]; + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) { + dma->buffer_queue[loop].buf_id = -1; + } + + /* + * Set the Current and Last item to zero. + */ + dma->current_buffer = 0; + dma->last_buffer = 0; + + /* + * Reset the Buffer counters + */ + dma->used_buffers = 0; + dma->new_buffers = 0; + dma->total_buffers = 0; + + /* + * reset the Total bytes counter. + */ + dma->total_bytes = 0; + + M2P_reg_base = dma_chan[channel].reg_base; + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * int ep93xx_dma_queue_full(int handle) + * + * Description: Query to determine if the DMA queue of buffers for + * a given channel is full. + * 0 = queue is full + * 1 = queue is not full + * + * handle: handle for the channel to query. + * + ****************************************************************************/ +int ep93xx_dma_queue_full(int handle) +{ + int list_full = 0; + unsigned long flags; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Queue Full: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + DPRINTK("DMA %d: queue full \n", channel); + + /* + * Mask interrupts and hold on to the original state. + */ + local_irq_save(flags); + + /* + * If the last item is equal to the used item then + * the queue is full. + */ + if (dma_chan[channel].total_buffers < MAX_EP93XX_DMA_BUFFERS) { + list_full = FALSE; + } else { + list_full = TRUE; + } + + /* + * restore interrupts. + */ + local_irq_restore(flags); + + return (list_full); +} + + +/***************************************************************************** + * + * int ep93xx_dma_get_position() + * + * Description: Takes two integer pointers and fills them with the start + * and current address of the buffer currently transferring + * on the specified DMA channel. + * + * handle handle for the channel to query. + * *buf_id buffer id for the current buffer transferring on the + * dma channel. + * *total total bytes transferred on the channel. Only counts + * whole buffers transferred. + * *current_frac number of bytes transferred so far in the current buffer. + ****************************************************************************/ +int +ep93xx_dma_get_position(int handle, unsigned int * buf_id, + unsigned int * total, unsigned int * current_frac ) +{ + int channel; + ep93xx_dma_t * dma; + unsigned int buf_id1, total1, current_frac1, buf_id2, total2; + unsigned int Status, NextBuffer, StateIsBufNext, M2P_reg_base=0; + unsigned int pause1, pause2; + + /* + * Get the DMA hw channel # from the handle. See if this is a + * valid handle. + */ + channel = dma_get_channel_from_handle(handle); + if (channel < 0) { + printk(KERN_ERR "DMA Get Position: Invalid dma handle.\n"); + return(-EINVAL); + } + + dma = &dma_chan[channel]; + + /* + * If DMA moves to a new buffer in the middle of us grabbing the + * buffer info, then do it over again. + */ + do{ + buf_id1 = dma->buffer_queue[dma->current_buffer].buf_id; + total1 = dma->total_bytes; + pause1 = dma->pause; + + if (channel < 10) { + /* M2P */ + M2P_reg_base = dma->reg_base; + + Status = inl(M2P_reg_base+M2P_OFFSET_STATUS); + + NextBuffer = ((Status & STATUS_M2P_NEXTBUFFER) != 0); + + StateIsBufNext = ((Status & STATUS_M2P_CURRENT_MASK) == + STATUS_M2P_DMA_BUF_NEXT); + + if( NextBuffer ^ StateIsBufNext ) + current_frac1 = inl(M2P_reg_base+M2P_OFFSET_CURRENT1) - + inl(M2P_reg_base+M2P_OFFSET_BASE1); + else + current_frac1 = inl(M2P_reg_base+M2P_OFFSET_CURRENT0) - + inl(M2P_reg_base+M2P_OFFSET_BASE0); + + } else { + /* M2M - TODO implement this for M2M */ + current_frac1 = 0; + } + + buf_id2 = dma->buffer_queue[dma->current_buffer].buf_id; + total2 = dma->total_bytes; + pause2 = dma->pause; + + } while ( (buf_id1 != buf_id2) || (total1 != total2) || (pause1 != pause2) ); + + if (pause1) + current_frac1 = 0; + + if (buf_id) + *buf_id = buf_id1; + + if (total) + *total = total1; + + if (current_frac) + *current_frac = current_frac1; + + /* + * Success. + */ + return(0); +} + +/* changed for AC97 port from Virgo 1-4-3 */ +#if 0 +/***************************************************************************** + * + * int ep93xx_dma_get_position(int handle, unsigned int * buf_id, + unsigned int * total) + * + * Description: Takes two integer pointers and fills them with the start + * and current address of the buffer currently transferring + * on the specified DMA channel. + * + * handle: handle for the channel to query. + * buf_id: pointer which is filled in with the buffer id for the + * current buffer transferring on the dma channel. + * buffer being transferred. + * total : pointer which is filled in with the total bytes + * transferred on the channel. + ****************************************************************************/ +int +ep93xx_dma_get_position(int handle, unsigned int *buf_id, unsigned int *total) +{ + int channel; + ep93xx_dma_t *dma; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Get Position: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + dma = &dma_chan[channel]; + + /* + * TODO: should irqs be disabled here? + */ + + *buf_id = dma->buffer_queue[dma->current_buffer].buf_id; + + *total = dma->total_bytes; + + DPRINTK("DMA buf_id %d, total %d\n", *buf_id, *total); + + /* + * Success. + */ + return (0); +} +#endif + + + +/***************************************************************************** + * + * int ep93xx_dma_get_total(int handle) + * + * Description: Returns the total number of bytes transferred on the + * specified channel since the channel was requested. + * + * handle: handle for the channel to query. + * + ****************************************************************************/ +int ep93xx_dma_get_total(int handle) +{ + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Get Total: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + DPRINTK("DMA %d: total: %d \n", channel, dma_chan[channel].total_bytes); + + /* + * Return the total number of bytes transferred on this channel since + * it was requested. + */ + return (dma_chan[channel].total_bytes); +} + +/***************************************************************************** + * ep93xx_dma_request + * + * Description: This function will allocate a DMA channel for a particular + * hardware peripheral. Before initiating a transfer on the allocated + * channel, the channel must be set up and buffers have to queued up. + * + * handle: pointer to an integer which is filled in with a unique + * handle for this instance of the dma interface. + * device_id string with the device name, primarily used by /proc. + * device hardware device ID for which the requested dma channel will + * transfer data. + * + ****************************************************************************/ +int +ep93xx_dma_request(int *handle, const char *device_id, ep93xx_dma_dev_t device) +{ + ep93xx_dma_t *dma = NULL; + int channel; + unsigned int error = 0; + unsigned int loop; + unsigned int M2P_reg_base; + + /* + * Check if the device requesting a DMA channel is a valid device. + */ + if ((device >= UNDEF) || (device < 0)) { + /* + * Invalid device, so return an error. + */ + return (-ENODEV); + } + + /* + * We've got a valid hardware device requesting a DMA channel. + * Now check if the device should open an M2P or M2M channel + */ + if (device < 20) { + channel = dma_open_m2p(device); + } else { + channel = dma_open_m2m(device); + } + + /* + * Check if we successfully opened a DMA channel + */ + if (channel < 0) { + printk(KERN_ERR + "%s: Could not open dma channel for this device.\n", + device_id); + + /* + * Fail. + */ + return (-EBUSY); + } + + dma = &dma_chan[channel]; + + /* + * Request the appropriate IRQ for the specified channel + */ + if (channel < 10) { + error = request_irq(dma->irq, dma_m2p_irq_handler, SA_INTERRUPT, + device_id, (void *)dma); + } else { + error = + request_irq(dma->irq, &dma_m2m_irq_handler, SA_INTERRUPT, + device_id, (void *)dma); + } + + /* + * Check for any errors during the irq request + */ + if (error) { + printk(KERN_ERR + "%s: unable to request IRQ %d for DMA channel\n", + device_id, dma->irq); + /* + * Fail. + */ + return (error); + } + + /* + * Generate a valid handle and exit. + * + * Increment the last valid handle. + * Check for wraparound (unlikely, but we like to be complete). + */ + dma->last_valid_handle++; + + if ((dma->last_valid_handle & DMA_HANDLE_SPECIFIER_MASK) != + (channel << 28)) { + /* + * If we wrapped around start over. + */ + dma->last_valid_handle = (channel << 28) + 1; + } + + /* + * Fill in the handle pointer with a valid handle for + * this dma channel instance. + */ + *handle = dma->last_valid_handle; + + DPRINTK("Handle for channel %d: 0x%x\n", channel, *handle); + + /* + * Save the device ID and device name. + */ + dma->device = device; + dma->device_id = device_id; + + /* + * Init all fields within the dma instance. + */ + for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) { + dma->buffer_queue[loop].buf_id = -1; + } + + /* + * Initialize all buffer queue variables. + */ + dma->current_buffer = 0; + dma->last_buffer = 0; + + dma->new_buffers = 0; + dma->used_buffers = 0; + dma->total_buffers = 0; + + /* + * Initialize the total bytes variable + */ + dma->total_bytes = 0; + + /* + * Initialize the transfer and pause state variables to 0. + */ + dma->xfer_enable = 0; + + dma->pause = 0; + + /* + * Initialize the pause buffer structure. + */ + dma->pause_buf.buf_id = -1; + + /* + * Initialize the callback function and user data fields. + */ + dma->callback = NULL; + + /* + * User data used as a parameter for the Callback function. The user + * sets up the data and sends it with the callback function. + */ + dma->user_data = 0; + + M2P_reg_base = dma_chan[channel].reg_base; + + /* + * Debugging message. + */ + DPRINTK("Successfully requested dma channel %d\n", channel); + DPRINTK("STATUS - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_STATUS)); + DPRINTK("CONTROL - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CONTROL)); + DPRINTK("REMAIN - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_REMAIN)); + DPRINTK("PPALLOC - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_PPALLOC)); + DPRINTK("BASE0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_BASE0)); + DPRINTK("MAXCNT0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_MAXCNT0)); + DPRINTK("CURRENT0 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CURRENT0)); + DPRINTK("BASE1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_BASE1)); + DPRINTK("MAXCNT1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_MAXCNT1)); + DPRINTK("CURRENT1 - 0x%x \n", readl(M2P_reg_base + M2P_OFFSET_CURRENT1)); + + DPRINTK("Buffer source size last used \n"); + for (loop = 0; loop < 5; loop++) { + DPRINTK("%d 0x%x 0x%x %d %d \n", + loop, dma->buffer_queue[loop].source, + dma->buffer_queue[loop].size, + dma->buffer_queue[loop].last, + dma->buffer_queue[loop].used); + } + DPRINTK("pause 0x%x 0x%x %d %d \n", + dma->pause_buf.source, dma->pause_buf.size, + dma->pause_buf.last, dma->pause_buf.used); + + DPRINTK("Pause - %d \n", dma->pause); + DPRINTK("xfer_enable - %d \n", dma->xfer_enable); + DPRINTK("total bytes - 0x%x \n", dma->total_bytes); + DPRINTK("total buffer - %d \n", dma->total_buffers); + DPRINTK("new buffers - %d \n", dma->new_buffers); + DPRINTK("current buffer - %d \n", dma->current_buffer); + DPRINTK("last buffer - %d \n", dma->last_buffer); + DPRINTK("used buffers - %d \n", dma->used_buffers); + + DPRINTK("CURRENT1 - 0x%x \n", + readl(M2P_reg_base + M2P_OFFSET_CURRENT1)); + DPRINTK("VIC0IRQSTATUS - 0x%x, VIC0INTENABLE - 0x%x \n", + *(unsigned int *)(VIC0IRQSTATUS), + *(unsigned int *)(VIC0INTENABLE)); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * ep93xx_dma_free + * + * Description: This function will free the dma channel for future requests. + * + * handle: handle for the channel to be freed. + * + ****************************************************************************/ +int ep93xx_dma_free(int handle) +{ + ep93xx_dma_t *dma; + unsigned int M2M_reg_base, M2P_reg_base, uiCONTROL; + int channel; + + /* + * Get the DMA hw channel # from the handle. + */ + channel = dma_get_channel_from_handle(handle); + + /* + * See if this is a valid handle. + */ + if (channel < 0) { + printk(KERN_ERR "DMA Free: Invalid dma handle.\n"); + + /* + * Fail. + */ + return (-EINVAL); + } + + /* + * Get a pointer to the dma instance. + */ + dma = &dma_chan[channel]; + + /* + * Disable the dma channel + */ + if (channel < 10) { + /* + * M2P channel + */ + M2P_reg_base = dma->reg_base; + + uiCONTROL = readl(M2P_reg_base + M2P_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2P_ENABLE; + writel(uiCONTROL, M2P_reg_base + M2P_OFFSET_CONTROL); + } else { + /* + * M2M channel + */ + M2M_reg_base = dma->reg_base; + + uiCONTROL = readl(M2M_reg_base + M2M_OFFSET_CONTROL); + uiCONTROL &= ~CONTROL_M2M_ENABLE; + writel(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL); + } + + /* + * Free the interrupt servicing this dma channel + */ + free_irq(dma->irq, (void *)dma); + + /* + * Decrement the reference count for this instance of the dma interface + */ + dma->ref_count--; + + /* + * Set the transfer and pause state variables to 0 + * (unititialized state). + */ + dma->xfer_enable = 0; + dma->pause = 0; + + /* + * Debugging message. + */ + DPRINTK("Successfully freed dma channel %d\n", channel); + + /* + * Success. + */ + return (0); +} + +/***************************************************************************** + * + * ep93xx_dma_init(void) + * + * Description: This function is called during system initialization to + * setup the interrupt number and register set base address for each DMA + * channel. + * + ****************************************************************************/ +static int __init ep93xx_dma_init(void) +{ + int channel; + + /* + * Init some values in each dma instance. + */ + for (channel = 0; channel < MAX_EP93XX_DMA_CHANNELS; channel++) { + /* + * IRQ for the specified dma channel. + */ + dma_chan[channel].irq = IRQ_DMAM2P0 + channel; + + /* + * Initial value of the dma channel handle. + */ + dma_chan[channel].last_valid_handle = channel << 28; + + /* + * Give the instance a pointer to the dma channel register + * base. + */ + if (channel < 10) { + dma_chan[channel].reg_base = DMAM2PChannelBase[channel]; + } else { + dma_chan[channel].reg_base = + DMAM2MChannelBase[channel - 10]; + } + + /* + * Initialize the reference count for this channel. + */ + dma_chan[channel].ref_count = 0; + } + + DPRINTK("DMA Interface intitialization complete\n"); + + /* + * Success + */ + return 0; +} + +__initcall(ep93xx_dma_init); + +EXPORT_SYMBOL(ep93xx_dma_add_buffer); +EXPORT_SYMBOL(ep93xx_dma_config); +EXPORT_SYMBOL(ep93xx_dma_flush); +EXPORT_SYMBOL(ep93xx_dma_free); +EXPORT_SYMBOL(ep93xx_dma_get_position); +EXPORT_SYMBOL(ep93xx_dma_get_total); +EXPORT_SYMBOL(ep93xx_dma_init); +EXPORT_SYMBOL(ep93xx_dma_pause); +EXPORT_SYMBOL(ep93xx_dma_queue_full); +EXPORT_SYMBOL(ep93xx_dma_remove_buffer); +EXPORT_SYMBOL(ep93xx_dma_request); +EXPORT_SYMBOL(ep93xx_dma_start); + diff --git a/arch/arm/mach-ep93xx/dma_ep93xx.h b/arch/arm/mach-ep93xx/dma_ep93xx.h new file mode 100644 index 0000000..3ec0b0d --- /dev/null +++ b/arch/arm/mach-ep93xx/dma_ep93xx.h @@ -0,0 +1,194 @@ +/***************************************************************************** + * + * arch/arm/mach-ep93xx/dma_ep93xx.h + * + * DESCRIPTION: 93XX DMA controller API private defintions. + * + * Copyright Cirrus Logic Corporation, 2003. 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 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 + * + ****************************************************************************/ +#ifndef _EP93XX_DMA_H_ +#define _EP93XX_DMA_H_ + +#define MAX_EP93XX_DMA_BUFFERS 32 + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/***************************************************************************** + * + * DMA buffer structure type. + * + ****************************************************************************/ +typedef struct ep93xx_dma_buffer_s { + unsigned int source; /* buffer physical source address. */ + unsigned int dest; /* buffer physical destination address, */ + /* only used with the 2 M2M channels. */ + unsigned int size; /* buffer size in bytes */ + unsigned int last; /* 1 if this is the last buffer */ + /* in this transaction. If 1, */ + /* disable the NFBint so we aren't */ + /* interrupted for another buffer */ + /* when we know there won't be another. */ + unsigned int used; /* This field is set to 1 by the DMA */ + /* interface after the buffer is transferred */ + int buf_id; /* unique identifyer specified by the */ + /* the driver which requested the dma */ +} ep93xx_dma_buffer_t; + +typedef ep93xx_dma_buffer_t *ep93xx_dma_buffer_p; + +/***************************************************************************** + * + * Instance definition for the DMA interface. + * + ****************************************************************************/ +typedef struct ep7312_dma_s { + /* + * This 1 when the instance is in use, and 0 when it's not. + */ + unsigned int ref_count; + + /* + * This is the last valid handle for this instance. When giving out a + * new handle this will be incremented and given out. + */ + int last_valid_handle; + + /* + * device specifies one of the 20 DMA hardware ports this + * DMA channel will service. + */ + ep93xx_dma_dev_t device; + + /* + * DMABufferQueue is the queue of buffer structure pointers which the + * dma channel will use to setup transfers. + */ + ep93xx_dma_buffer_t buffer_queue[MAX_EP93XX_DMA_BUFFERS]; + + /* + * currnt_buffer : This is the buffer currently being transfered on + * this channel. + * last_buffer : This is the last buffer for this transfer. + * Note: current_buffer + 1 is already programmed into the dma + * channel as the next buffer to transfer. Don't write + * over either entry. + */ + int current_buffer; + int last_buffer; + + /* + * The following 3 fields are buffer counters. + * + * iNewBuffers: Buffers in the queue which have not been transfered. + * iUsedBuffers: Buffers in the queue which have have been tranferred, + * and are waiting to be returned. + * iTotalBuffers: Total number of buffers in the queue. + */ + int new_buffers; + int used_buffers; + int total_buffers; + + /* + * uiTotalBytes has the total bytes transfered on the channel since the + * last flush. This value does not include the bytes tranfered in the + * current buffer. A byte count is only added after a complete buffer + * is tranfered. + */ + unsigned int total_bytes; + + /* + * Interrupt number for this channel + */ + unsigned int irq; + + /* + * Indicates whether or not the channel is currently enabled to transfer + * data. + */ + unsigned int xfer_enable; + + /* + * pause indicates if the dma channel was paused by calling the pause + * ioctl. + */ + unsigned int pause; + + /* + * buffer structure used during a pause to capture the current + * address and remaining bytes for the buffer actively being transferred + * on the channel. This buffer will be used to reprogram the dma + * channel upon a resume. + */ + ep93xx_dma_buffer_t pause_buf; + + /* + * DMACallback is a function pointer which the calling application can + * use install a function to. this fuction can be used to notify the + * calling application of an interrupt. + */ + dma_callback callback; + + /* + * User data used as a parameter for the Callback function. The user + * sets up the data and sends it with the callback function. + */ + unsigned int user_data; + + /* + * A string representation of the device attached to the channel. + */ + const char *device_id; + + /* + * The register base address for this dma channel. + */ + unsigned int reg_base; + +} ep93xx_dma_t; + +/***************************************************************************** + * + * DMA macros + * + ****************************************************************************/ +#define DMA_HANDLE_SPECIFIER_MASK 0xF0000000 +#define DMA_CH0_HANDLE_SPECIFIER 0x00000000 +#define DMA_CH1_HANDLE_SPECIFIER 0x10000000 +#define DMA_CH2_HANDLE_SPECIFIER 0x20000000 +#define DMA_CH3_HANDLE_SPECIFIER 0x30000000 +#define DMA_CH4_HANDLE_SPECIFIER 0x40000000 +#define DMA_CH5_HANDLE_SPECIFIER 0x50000000 +#define DMA_CH6_HANDLE_SPECIFIER 0x60000000 +#define DMA_CH7_HANDLE_SPECIFIER 0x70000000 +#define DMA_CH8_HANDLE_SPECIFIER 0x80000000 +#define DMA_CH9_HANDLE_SPECIFIER 0x90000000 +#define DMA_CH10_HANDLE_SPECIFIER 0xA0000000 +#define DMA_CH11_HANDLE_SPECIFIER 0xB0000000 + +#endif + diff --git a/arch/arm/mach-ep93xx/ep93xx.c b/arch/arm/mach-ep93xx/ep93xx.c new file mode 100644 index 0000000..a565f14 --- /dev/null +++ b/arch/arm/mach-ep93xx/ep93xx.c @@ -0,0 +1,571 @@ +/* + * linux/arch/arm/mach-ep93xx/ep93xx.c + * + * Copyright (C) 2000-2003 Deep Blue Solutions Ltd + * Copyright (C) 2004 Ray Lehtiniemi + * Copyright (C) 2005 Michael Burian + * + * 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 + +static __init void check_model(void) +{ + unsigned long x; + char *model; + char *rev; + + printk(KERN_INFO "CPU model: "); + + x = readl(USRFLG); + switch (x) { + case 0: + model = "15"; + break; + case 2: + model = "12"; + break; + case 4: + model = "01"; + break; + default: + printk("(unknown model %ld) ", x); + model = "xx"; + break; + } + + x = readl(SYSCON_SYSCFG) >> 28; + switch (x) { + case 0: + rev = "A"; + break; + case 1: + rev = "B"; + break; + case 2: + rev = "C"; + break; + case 3: + rev = "D0"; + break; + case 4: + rev = "D1"; + break; + case 5: + rev = "E"; + break; + default: + printk("(unknown revision %ld) ", x); + rev = "unknown"; + break; + } + + printk("Cirrus Logic EP93%s, silicon rev %s\n", model, rev); +} + +static struct amba_device dma_device = { + .dev = { + .bus_id = "0x80000000:dma", + }, + .res = { + .start = DMA_BASE, + .end = DMA_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80000000, +}; + +static struct amba_device mac_device = { + .dev = { + .bus_id = "0x80010000:mac", + }, + .res = { + .start = MAC_BASE, + .end = MAC_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80010000, +}; + +static struct amba_device usb_device = { + .dev = { + .bus_id = "0x80020000:usb", + .coherent_dma_mask = 0xffffffff, + }, + .res = { + .start = USB_BASE, + .end = USB_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_USH, NO_IRQ}, + .periphid = 0x80020000, +}; + +#if defined(CONFIG_ARCH_EP9312) || defined (CONFIG_ARCH_EP9315) +static struct amba_device raster_device = { + .dev = { + .bus_id = "0x80030000:raster", + }, + .res = { + .start = RASTER_BASE, + .end = RASTER_BASE + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80030000, +}; +#endif + +static struct amba_device sdram_device = { + .dev = { + .bus_id = "0x80060000:sdram", + }, + .res = { + .start = SDRAM_BASE, + .end = SDRAM_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80060000, +}; + +static struct amba_device smc_device = { + .dev = { + .bus_id = "0x80080000:smc", + }, + .res = { + .start = SMC_BASE, + .end = SMC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80080000, +}; + +static struct amba_device boot_device = { + .dev = { + .bus_id = "0x80090000:boot", + }, + .res = { + .start = BOOT_BASE, + .end = BOOT_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80090000, +}; + +#if defined(CONFIG_ARCH_EP9312) || defined (CONFIG_ARCH_EP9315) +static struct amba_device ide_device = { + .dev = { + .bus_id = "0x800a0000:ide", + }, + .res = { + .start = IDE_BASE, + .end = IDE_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x800a0000, +}; +#endif + +static struct amba_device vic1_device = { + .dev = { + .bus_id = "0x800b0000:vic1", + }, + .res = { + .start = VIC0_BASE, + .end = VIC0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x800b0000, +}; + +static struct amba_device vic2_device = { + .dev = { + .bus_id = "0x800c0000:vic2", + }, + .res = { + .start = VIC1_BASE, + .end = VIC1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x800c0000, +}; + +static struct amba_device timer_device = { + .dev = { + .bus_id = "0x80810000:timer", + }, + .res = { + .start = TIMERS_BASE, + .end = TIMERS_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80810000, +}; + +static struct amba_device i2s_device = { + .dev = { + .bus_id = "0x80820000:i2s", + }, + .res = { + .start = I2S_BASE, + .end = I2S_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80820000, +}; + +static struct amba_device security_device = { + .dev = { + .bus_id = "0x80830000:security", + }, + .res = { + .start = SECURITY_BASE, + .end = SECURITY_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80830000, +}; + +static struct amba_device gpio_device = { + .dev = { + .bus_id = "0x80840000:gpio", + }, + .res = { + .start = GPIO_BASE, + .end = GPIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80840000, +}; + +static struct amba_device ac97_device = { + .dev = { + .bus_id = "0x80880000:ac97", + }, + .res = { + .start = AC97_BASE, + .end = AC97_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80880000, +}; + +static struct amba_device ssp_device = { + .dev = { + .bus_id = "0x808a0000:ssp", + }, + .res = { + .start = SSP_BASE, + .end = SSP_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x808a0000, +}; + +static struct amba_device irda_device = { + .dev = { + .bus_id = "0x808b0000:irda", + }, + .res = { + .start = IRDA_BASE, + .end = IRDA_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x808b0000, +}; + +static struct amba_device uart1_device = { + .dev = { + .bus_id = "0x808c0000:uart1", + }, + .res = { + .start = UART1_BASE, + .end = UART1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART1, NO_IRQ}, + .periphid = 0x808c0000, +}; + +static struct amba_device uart2_device = { + .dev = { + .bus_id = "0x808d0000:uart2", + }, + .res = { + .start = UART2_BASE, + .end = UART2_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART2, NO_IRQ}, + .periphid = 0x808d0000, +}; + +#if defined(CONFIG_ARCH_EP9312) || defined (CONFIG_ARCH_EP9315) +static struct amba_device uart3_device = { + .dev = { + .bus_id = "0x808e0000:uart3", + }, + .res = { + .start = UART3_BASE, + .end = UART3_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART3, NO_IRQ}, + .periphid = 0x808e0000, +}; + +static struct amba_device key_device = { + .dev = { + .bus_id = "0x808f0000:key", + }, + .res = { + .start = KEY_BASE, + .end = KEY_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x808f0000, +}; + +static struct amba_device touch_device = { + .dev = { + .bus_id = "0x80900000:touch", + }, + .res = { + .start = TOUCH_BASE, + .end = TOUCH_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80900000, +}; + +static struct amba_device pwm_device = { + .dev = { + .bus_id = "0x80910000:pwm", + }, + .res = { + .start = PWM_BASE, + .end = PWM_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80910000, +}; +#endif + +static struct amba_device rtc_device = { + .dev = { + .bus_id = "0x80920000:rtc", + }, + .res = { + .start = RTC_BASE, + .end = RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_RTC, NO_IRQ}, + .periphid = 0x80920000, +}; + +static struct amba_device syscon_device = { + .dev = { + .bus_id = "0x80930000:syscon", + }, + .res = { + .start = SYSCON_BASE, + .end = SYSCON_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80930000, +}; + +static struct amba_device watchdog_device = { + .dev = { + .bus_id = "0x80940000:watchdog", + }, + .res = { + .start = WATCHDOG_BASE, + .end = WATCHDOG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {NO_IRQ, NO_IRQ}, + .periphid = 0x80940000, +}; + +static struct amba_device *amba_devs[] __initdata = { + /* AHB devices */ + &dma_device, + &mac_device, + &usb_device, +#if defined(CONFIG_ARCH_EP9312) || defined (CONFIG_ARCH_EP9315) + &raster_device, +#endif + &sdram_device, + &smc_device, + &boot_device, +#if defined(CONFIG_ARCH_EP9312) || defined (CONFIG_ARCH_EP9315) + &ide_device, +#endif + &vic1_device, + &vic2_device, + + /* APB devices */ + &timer_device, + &i2s_device, + &security_device, + &gpio_device, + &ac97_device, + &ssp_device, + &irda_device, + &uart1_device, + &uart2_device, +#if defined(CONFIG_ARCH_EP9312) || defined (CONFIG_ARCH_EP9315) + &uart3_device, + &key_device, + &touch_device, + &pwm_device, +#endif + &rtc_device, + &syscon_device, + &watchdog_device, +}; + +static int __init ep93xx_init(void) +{ + int i; + + check_model(); + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + + return 0; +} + +arch_initcall(ep93xx_init); + +#define TIMER_INTERVAL (508 * mSEC_10 / 1000) +#define TICKS2USECS(x) ((x) * 1000 / 508) + +static unsigned long timer_reload; + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long ep93xx_gettimeoffset(void) +{ + unsigned long ticks1, ticks2, status; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = readl(TIMER1VALUE) & 0xffff; + do { + ticks1 = ticks2; + status = readl(VIC0RAWINTR); + ticks2 = readl(TIMER1VALUE) & 0xffff; + } while (ticks2 > ticks1); + + /* + * Number of ticks since last interrupt. + */ + ticks1 = timer_reload - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + */ + if (status & (1 << IRQ_TIMER1)) + ticks1 += timer_reload; + + return TICKS2USECS(ticks1); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + /* ...clear the interrupt */ + writel(1, TIMER1CLEAR); + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction ep93xx_timer_irq = { + .name = "timer", + .flags = SA_INTERRUPT, + .handler = ep93xx_timer_interrupt +}; + +/* + * Set up timer interrupt + */ +static void __init __ep93xx_init_timer(unsigned long reload, unsigned int ctrl) +{ + unsigned int timer_ctrl = 0x80 | 0x40 | 0x08; /* periodic at 508 kHz */ + + timer_reload = reload; + timer_ctrl |= ctrl; + + /* + * Initialise to a known state (all timers off) + */ + + writel(0, TIMER1CONTROL); + writel(0, TIMER2CONTROL); + writel(0, TIMER3CONTROL); + + writel(timer_reload, TIMER1LOAD); + writel(timer_reload, TIMER1VALUE); + writel(timer_ctrl, TIMER1CONTROL); + + setup_irq(IRQ_TIMER1, &ep93xx_timer_irq); +} + +static void __init ep93xx_init_timer(void) +{ + /* 10 ms interval on a 508 kHz clock */ + __ep93xx_init_timer(5080, 0); +} + +struct sys_timer ep93xx_timer = { + .init = ep93xx_init_timer, + .offset = ep93xx_gettimeoffset, +}; diff --git a/arch/arm/mach-ep93xx/ep93xx_gpio_irq.h b/arch/arm/mach-ep93xx/ep93xx_gpio_irq.h new file mode 100644 index 0000000..d396e96 --- /dev/null +++ b/arch/arm/mach-ep93xx/ep93xx_gpio_irq.h @@ -0,0 +1,41 @@ +/* + * linux/arch/arm/mach-ep93xx/ep93xx_gpio_irq.h + * + * Copyright (C) 2004 Contec Steuerungstechnik & Automation GmbH + * Manfred Gruber + * + * 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 + */ + +/* + * configuration struct for GPIO IRQs + * + * enable = 1 --> this EGIO is a irq + * enable = 0 --> this EGIO is a GPIO + * flags can be IRQT_RISING + * IRQT_FALLING + * IRQT_LOW + * IRQT_HIGH + * IRQT_PROBE + * + * On IRQT_PROBE nothing is done in setup irq code + */ + +struct ep93xx_egpio_irq +{ + unsigned int enable; + unsigned int flags; +}; + diff --git a/arch/arm/mach-ep93xx/irq.c b/arch/arm/mach-ep93xx/irq.c new file mode 100644 index 0000000..578c783 --- /dev/null +++ b/arch/arm/mach-ep93xx/irq.c @@ -0,0 +1,601 @@ +/* + * linux/arch/arm/mach-ep93xx/irq.c + * + * Copyright (C) 1999 ARM Limited + * + * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA. All rights reserved. + * + * Copyright (C) 2002-2003 Cirrus Logic, Inc. + * + * Demux IRQ 59 by + * Copyright (C) 2004 Contec Steuerungstechnik & Automation GmbH + * Manfred Gruber + * + * 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 + * + * + * Modified by Stefano Lena , DAVE s.r.l. + * for Cirrus Logic EP93xx series + * + * + */ + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +#include +#include +#include "ep93xx_gpio_irq.h" +extern struct ep93xx_egpio_irq egpio_irqs[]; + +/* GPIO Port A/B debug messages */ +/* #define DEBUG_GPIO */ +#ifdef DEBUG_GPIO +#define IRQDBG(args...) printk(args) +#else +#define IRQDBG(args...) do {} while(0) +#endif +#endif +/******************************************************************** + * Interrupt functions are defined as machine specific here. + * + * Note: + * 1. Only normal interrupts are defined here. + * FIQs are a separate class of interrupts and would + * be slowed down if handled like normal interrupts. + * + * 2. TBD Invalid interrupt numbers are not checked. + * Some interrupt inputs are tied to GND, which means + * they will immediately activate when unmasked. + * Which may be useful for some devices. + * + * 3. TBD Edge triggered interrupts are not specially + * handled. The architecture should provide a way to + * set up the edge trigger features and then a way to + * control the acknowledge to the interrupt. + * + ************************************************************************/ + + /******************************************************************** + * demux interrupt handler for GPIO Port A and B on ep93xx + * + * Note: + That IRQs from 64 to 79 defined as GPIO_IRQ0 - GPIO_IRQ15 + * GPIO IRQs on port F are as the are defined as IRQ_GPIOX + * which are NOT handled in demux interrupt handler !!!!! + * + * Default in mach-xy file a struct ep93xx_egpio_irq + * can be set up, there you can configure which gpio + * of Port A/B should be used as interrupt on startup. + * Setting up this IRQs in your driver direct not on startup + * you have to do a set_irq_type(GPIO_IRQX, flags) before + * calling request irq. Possible Flags are: + * IRQT_RISING, IRQT_FALLING, IRQT_LOW, IRQT_HIGH, IRQT_PROBE, IRQ_DB, IRQ_NOTDB + * On IRQT_PROBE nothing is done. + ************************************************************************/ + + /******************************************************************** + * TODO: + * + * Configure ack, mask, unsmask to use the right + * Port F GPIO registers. + * +************************************************************************/ + +static void ep93xx_vic1_mask(unsigned int irq) +{ + writel((1 << irq), VIC0INTENCLEAR); +} + +static void ep93xx_vic1_unmask(unsigned int irq) +{ + writel((1 << irq), VIC0INTENABLE); +} + +static struct irqchip vic1_chip = { + .ack = ep93xx_vic1_mask, + .mask = ep93xx_vic1_mask, + .unmask = ep93xx_vic1_unmask, +}; + +static void ep93xx_vic2_mask(unsigned int irq) +{ + writel((1 << (irq - 32)), VIC1INTENCLEAR); +} + +static void ep93xx_vic2_unmask(unsigned int irq) +{ + writel((1 << (irq - 32)), VIC1INTENABLE); +} + +static struct irqchip vic2_chip = { + .ack = ep93xx_vic2_mask, + .mask = ep93xx_vic2_mask, + .unmask = ep93xx_vic2_unmask, +}; + +static void ep93xx_rtc_ack(unsigned int irq) +{ +} + +static struct irqchip rtc_chip = { + .ack = ep93xx_rtc_ack, + .mask = ep93xx_vic2_mask, + .unmask = ep93xx_vic2_unmask, +}; + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +/* + * ack EGPIO irq's + * Ack only for edge triggered int's valid + */ +static void inline ep93xx_ack_gpio_irq(u32 irq) +{ + u32 irq_status; + u32 bit = IRQ_TO_BIT(irq); + + IRQDBG("%s irq: %d bit 0x%x\n",__FUNCTION__, irq, bit); + + /* Port A */ + if(bit & 0xFF) { + irq_status = readl(GPIO_INTSTATUSA); + if(irq_status & bit) + writel(bit, GPIO_AEOI); + } + + /* Port B */ + if(bit & 0xFF00) { + irq_status = readl(GPIO_INTSTATUSB); + if(irq_status & (bit >> 8)) + writel((bit >> 8), GPIO_BEOI); + + } +} + +/* + * unmask EGPIO irq's (enable) + */ +static void inline ep93xx_unmask_gpio_irq(u32 irq) +{ + u32 irq_status; + u32 bit = IRQ_TO_BIT(irq); + + IRQDBG("%s irq: %d bit 0x%x\n",__FUNCTION__, irq, bit); + + /* Port A */ + if(bit & 0xFF) { + irq_status = readl(GPIO_AINTEN); + irq_status |= bit; + writel(irq_status, GPIO_AINTEN); + } + + /* Port B */ + if(bit & 0xFF00) { + irq_status = readl(GPIO_BINTEN); + irq_status |= (bit >> 8); + writel(irq_status, GPIO_BINTEN); + } +} + +/* + * Enable debounce on EGPIO IRQ + */ + +static void ep93xx_debounce_enable(u32 irq) +{ + u32 db_status; + u32 bit = IRQ_TO_BIT(irq); + + IRQDBG("%s irq: %d bit 0x%x\n",__FUNCTION__, irq, bit); + + /* Port A */ + if (bit & 0xFF) { + db_status = readl(GPIO_ADB); + db_status |= bit ; + writel(db_status, GPIO_ADB); + } + + /* Port B */ + if (bit & 0xFF00 ) { + db_status = readl(GPIO_BDB); + db_status |= (bit >> 8) ; + writel(db_status, GPIO_BDB); + } + +} + +/* + * Disable debounce on EGPIO IRQ + */ +static void ep93xx_debounce_disable(u32 irq) +{ + u32 db_status; + u32 bit = IRQ_TO_BIT(irq); + + IRQDBG("%s irq: %d bit 0x%x\n",__FUNCTION__, irq, bit); + + /* Port A */ + if (bit & 0xFF) { + db_status = readl(GPIO_ADB); + db_status &= ~bit ; + writel(db_status, GPIO_ADB); + } + + /* Port B */ + if (bit & 0xFF00 ) { + db_status = readl(GPIO_BDB); + db_status &= ~(bit >> 8) ; + writel(db_status, GPIO_BDB); + } + +} + +/* + * mask EGPIO irq's (disable) + */ +static void inline ep93xx_mask_gpio_irq(u32 irq) +{ + u32 irq_status; + u32 bit = IRQ_TO_BIT(irq); + + IRQDBG("%s irq: %d bit 0x%x\n",__FUNCTION__, irq, bit); + + /* Port A */ + if(bit & 0xFF) { + irq_status = readl(GPIO_AINTEN); + irq_status &= ~bit; + writel(irq_status, GPIO_AINTEN); + } + + /* Port B */ + if(bit & 0xFF00) { + irq_status = readl(GPIO_BINTEN); + irq_status &= ~(bit >> 8); + writel(irq_status, GPIO_BINTEN); + } +} + + + +/* + * make a EGPIO to a irq input + */ +static int ep93xx_make_egio_to_irq(u32 bit,u32 irq) +{ + u32 irq_value; + int ret; + + IRQDBG("%s irq: %d bit 0x%x\n",__FUNCTION__, irq, bit); + + if(bit & 0xFF) { + /* Set direction to input for EGPIOA */ + irq_value = readl(GPIO_PADDR); + irq_value &= ~bit; + if((ret = writel(irq_value, GPIO_PADDR)) != irq_value) { + printk("%s irq: %d cannot set direction register(GPIO_PADDR) value 0x%x written 0x%x\n",__FUNCTION__,irq,irq_value,ret); + return -EFAULT; + } + } + /* Port B */ + if(bit & 0xFF00) { + /* Set direction to input for EGPIOB */ + irq_value = readl(GPIO_PBDDR); + irq_value &= ~(bit >> 8); + if((ret = writel(irq_value, GPIO_PBDDR)) != irq_value) { + printk("%s irq: %d cannot set direction register(GPIO_PBDDR) value 0x%x written 0x%x\n",__FUNCTION__,irq,irq_value,ret); + return -EFAULT; + } + } + + return 0; +} + +/* + * make a EGPIO edge/level sensitive + */ +static int ep93xx_make_egio_sensitive(u32 bit, unsigned int flags,u32 irq) +{ + u32 irq_value; + int ret; + + /* PORT A */ + if(bit & 0xFF) { + /* Enable edge/level sensitive IRQ on EGPIO PORT A */ + irq_value = readl(GPIO_AINTTYPE1); + if(flags && 1) + irq_value |= bit; + else + irq_value &= ~bit; + if((ret = writel(irq_value, GPIO_AINTTYPE1)) != irq_value) { + printk("%s irq: %d cannot set IRQ parameter(GPIO_AINTYPE1) value 0x%x written 0x%x\n",__FUNCTION__,irq,irq_value,ret); + return -EFAULT; + } + } + + /* Port B */ + if(bit & 0xFF00) { + /* Enable edge/level sensitive IRQ on EGPIO PORT B */ + irq_value = readl(GPIO_BINTTYPE1); + if(flags && 1) + irq_value |= (bit >> 8); + else + irq_value &= ~(bit >> 8); + if((ret = writel(irq_value, GPIO_BINTTYPE1)) != irq_value) { + /* printk("%s irq: %d cannot set IRQ parameter(GPIO_BINTYPE1) value 0x%x written 0x%x\n",__FUNCTION__,irq,irq_value,ret); */ + return -EFAULT; + } + } + + return 0; +} + +/* + * make a EGPIO high/low sensitive + */ +static int ep93xx_make_egio_high_low_sensitive(u32 bit, unsigned int flags,u32 irq) +{ + u32 irq_value; + int ret; + + /* PORT A */ + if(bit & 0xFF) { + /* Enable high/low sensitive IRQ on EGPIO PORT A */ + irq_value = readl(GPIO_AINTTYPE2); + if(flags && 1) + irq_value |= bit; + else + irq_value &= ~bit; + if((ret = writel(irq_value, GPIO_AINTTYPE2)) != irq_value) { + printk("%s irq: %d cannot set IRQ parameter(GPIO_AINTTYPE2) value 0x%x written 0x%x\n",__FUNCTION__,irq,irq_value,ret); + return -EFAULT; + } + } + + /* Port B */ + if(bit & 0xFF00) { + /* Enable high/low sensitive IRQ on EGPIO PORT B */ + irq_value = readl(GPIO_BINTTYPE2); + if(flags && 1) + irq_value |= (bit >> 8); + else + irq_value &= ~(bit >> 8); + if((ret = writel(irq_value, GPIO_BINTTYPE2)) != irq_value) + { + printk("%s irq: %d cannot set IRQ parameter(GPIO_BINTYPE2) value 0x%x written 0x%x\n",__FUNCTION__,irq,irq_value,ret); + return -EFAULT; + } + } + + return 0; +} + + + + +/* + * type of GPIO irq's + */ +static int ep93xx_gpio_demux_handler_type(unsigned int irq, unsigned int flags) +{ + u32 bit = IRQ_TO_BIT(irq); + unsigned int debounce = 0; + + IRQDBG("%s irq: %d\n",__FUNCTION__,irq); + + /*if (flags == IRQT_PROBE) + return 0;*/ + + if ((flags & __IRQT_RISEDGE) | (flags & __IRQT_FALEDGE) | (flags & __IRQT_LOWLVL) | (flags & __IRQT_HIGHLVL) | (flags & IRQT_DB) | (flags & IRQT_NOTDB)) { + if(0 != ep93xx_make_egio_to_irq(bit,irq)) { + printk("%s irq: %d cannot set direction register GPIO_PXDDR\n",__FUNCTION__,irq); + return -EINVAL; + } else { + if ((flags & IRQT_DB) | (flags & IRQT_NOTDB)) { /* To use switch structure extract debounce + flags from flags variable */ + debounce = (flags & IRQT_DB) | (flags & IRQT_NOTDB); + flags &= ~debounce; + } + if((flags & __IRQT_RISEDGE) | (flags & __IRQT_FALEDGE)) { + /* Configure for edge IRQ */ + if(0 == ep93xx_make_egio_sensitive(bit, 1,irq)) { + switch(flags) { + case __IRQT_RISEDGE: + if(0 != ep93xx_make_egio_high_low_sensitive(bit, 1,irq)) { + printk("%s irq: %d cannot set sensitive register GPIO_XINTYPE2\n",__FUNCTION__,irq); + return -EINVAL; + } + break; + case __IRQT_FALEDGE: + if(0 != ep93xx_make_egio_high_low_sensitive(bit, 0,irq)) { + printk("%s irq: %d cannot set sensitive register GPIO_XINTYPE2\n",__FUNCTION__,irq); + return -EINVAL; + } + break; + } + + /* Now we set IRQ handler for edge */ + /* set_irq_handler(irq, do_edge_IRQ); */ + } else { + printk("%s irq: %d cannot set sensitive register GPIO_XINTYPE1\n",__FUNCTION__,irq); + return -EINVAL; + } + + } else { + if((flags & __IRQT_LOWLVL) | (flags & __IRQT_HIGHLVL)) { + /* Configure for level IRQ */ + if(0 == ep93xx_make_egio_sensitive(bit, 0,irq)) { + switch(flags) + { + case __IRQT_HIGHLVL: + if(0 != ep93xx_make_egio_high_low_sensitive(bit, 1,irq)) + { + printk("%s irq: %d cannot set sensitive register GPIO_XINTYPE2\n",__FUNCTION__,irq); + return -EINVAL; + } + break; + case __IRQT_LOWLVL: + if(0 != ep93xx_make_egio_high_low_sensitive(bit, 0,irq)) + { + printk("%s irq: %d cannot set sensitive register GPIO_XINTYPE2\n",__FUNCTION__,irq); + return -EINVAL; + } + break; + } + + /* Now we set IRQ handler level sensitive */ + /* set_irq_handler(irq, do_level_IRQ); */ + } else { + printk("%s irq: %d cannot set sensitive register GPIO_XINTYPE1\n",__FUNCTION__,irq); + return -EINVAL; + } + + } + } + } + /* For debounce flags handling */ + if ((debounce & IRQT_DB) | (debounce & IRQT_NOTDB)) { + switch(debounce) + { + case IRQT_DB: + ep93xx_debounce_enable(irq); + break; + case IRQT_NOTDB: + ep93xx_debounce_disable(irq); + break; + } + } + } else { + printk("ep93xx_type_gpio_irq: IRQ:%d no flags defined\n",irq); + return -EINVAL; + } +return 0; +} + +/* + * GPIO call handler + */ +static void ep93xx_gpio_handler(unsigned int mask, unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + IRQDBG("%s irq: %d\n",__FUNCTION__,irq); + + desc = irq_desc + irq; + + while (mask) { + if (mask & 1) { + IRQDBG("handling irq %d\n", irq); + desc->handle(irq, desc, regs); + } + irq++; + desc++; + mask >>= 1; + } + +} + +/* + * GPIO dmux handler + */ +static void ep93xx_gpio_demux_handler(unsigned int irq_gpio, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned int mask; + unsigned int irq = IRQ_CHAINED_GPIO(0); + + /* + * Mask the parent IRQ. + */ + ep93xx_vic2_mask(irq_gpio); + + mask = readl(GPIO_INTSTATUSA) | (readl(GPIO_INTSTATUSB) << 8); + + irq = IRQ_CHAINED_GPIO(0); + IRQDBG("%s mask: 0x%x irq: %d\n",__FUNCTION__,mask,irq); + ep93xx_gpio_handler(mask, irq, desc, regs); + + /* + * Unmask the parent IRQ + */ + ep93xx_vic2_unmask(irq_gpio); +} + + +static struct irqchip ep93xx_gpio_irq = { + .ack = ep93xx_ack_gpio_irq, + .mask = ep93xx_mask_gpio_irq, + .unmask = ep93xx_unmask_gpio_irq, + .set_type = ep93xx_gpio_demux_handler_type, +}; + +#endif + + +void __init ep93xx_init_irq(void) +{ + unsigned int i; + + /* Interrupt bits 0 and 1 are unused */ +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ + for (i = 2; i < NR_GLBL_IRQS; i++) { +#else + for (i = 2; i < NR_IRQS; i++) { +#endif + if(i < 32){ + /* Interrupts below 32 belong to VIC1 */ + set_irq_handler(i, do_level_IRQ); + set_irq_chip(i, &vic1_chip); + set_irq_flags(i, IRQF_VALID); + + } else { + if (i == IRQ_1HZ) { + /* 1 Hz int is edge trigered, and not ackable */ + set_irq_handler(i, do_edge_IRQ); + set_irq_chip(i, &rtc_chip); + set_irq_flags(i, IRQF_VALID | IRQF_NOAUTOEN); + } else { + /* Interrupt 32 and above belong to VIC2 */ + set_irq_handler(i, do_level_IRQ); + set_irq_chip(i, &vic2_chip); + set_irq_flags(i, IRQF_VALID); + } + } + } +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ + for (i = IRQ_CHAINED_GPIO(0) ; i <= IRQ_CHAINED_GPIO(15); i++) { + + IRQDBG("%s irq: %d init \n",__FUNCTION__, i); + + /* GPIO Interrupt is demux to 16 IRQs */ + set_irq_chip(i, &ep93xx_gpio_irq); + set_irq_flags(i, IRQF_VALID); + + if(egpio_irqs[i - NR_GLBL_IRQS].enable == 1) { + set_irq_handler(i, do_level_IRQ); + set_irq_type(i, egpio_irqs[i - NR_GLBL_IRQS].flags); + } else { + set_irq_handler(i, do_edge_IRQ); + } + } + set_irq_chained_handler(IRQ_GPIO, ep93xx_gpio_demux_handler); +#endif +} diff --git a/arch/arm/mach-ep93xx/mach-acc.c b/arch/arm/mach-ep93xx/mach-acc.c new file mode 100644 index 0000000..aa002ac --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-acc.c @@ -0,0 +1,67 @@ +/* + * linux/arch/arm/mach-ep93xx/acc.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * Copyright (C) 2004 Klaus Fetscher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc acc_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init acc_map_io(void) +{ + iotable_init(acc_io_desc, ARRAY_SIZE(acc_io_desc)); +} + +static void __init acc_init(void) +{ +} + +MACHINE_START(ACC, "acc") + /* Maintainer HiFish */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = acc_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = acc_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-adssphere.c b/arch/arm/mach-ep93xx/mach-adssphere.c new file mode 100644 index 0000000..2cbf5ca --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-adssphere.c @@ -0,0 +1,281 @@ +/* + * linux/arch/arm/mach-ep93xx/adssphere.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * Copyright (C) 2005 Robert Whaley, ADS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc adssphere_io_desc[] __initdata = +{ + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, + { ADSSPHERE_BASE_VIRT, ADSSPHERE_BASE_PHYS, SZ_1M, MT_DEVICE }, +}; + +static void __init adssphere_map_io(void) +{ + iotable_init(adssphere_io_desc, ARRAY_SIZE(adssphere_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .id = 0, + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN) + +void adssphere_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + break; + + case led_idle_end: + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + break; + + case led_red_off: + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + local_irq_restore(flags); +} + +#endif + +#ifdef CONFIG_SOUND_EP93XX_AC97 +void adssphere_audio_power(int on) +{ + unsigned int tmp; + + tmp = readb(ADSSPHERE_CR1); + if (on) { + tmp |= ADSSPHERE_CR1_AMP_ON; + tmp &= ~ADSSPHERE_CR1_CDC_ON; + } else { + tmp &= ~ADSSPHERE_CR1_AMP_ON; + tmp |= ADSSPHERE_CR1_CDC_ON; + } + writeb(tmp, ADSSPHERE_CR1); +} + +#endif + +#ifdef CONFIG_FB_EP93XX +void adssphere_blank(int blank_mode) +{ + unsigned int tmp; + + switch (blank_mode) { + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: + /* turn on backlight via enable and pwm */ + /* enable fb signals */ + tmp = readl(ADSSPHERE_CR1); + tmp &= ~ADSSPHERE_CR1_PNL_ON; + tmp |= ADSSPHERE_CR1_PNL_EN | ADSSPHERE_CR1_BL_ON; + writel(tmp, ADSSPHERE_CR1); + + writel(100, PWM0_TC); + writel(99, PWM0_DC); + writel(1, PWM0_EN); + + break; + + + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + + /* disable fb signals */ + /* turn off backlight via enable and pwm */ + tmp = readl(ADSSPHERE_CR1); + tmp |= ADSSPHERE_CR1_PNL_ON; + tmp &= ~(ADSSPHERE_CR1_PNL_EN | ADSSPHERE_CR1_BL_ON); + writel(tmp, ADSSPHERE_CR1); + + writel(0, PWM0_EN); + + break; + } +} +#endif + +static void __init adssphere_init (void) +{ +#if 0 + printk("physmap_configure\n"); + physmap_configure(0x60000000, 0x02000000, 4, NULL); +#endif + printk("platform_device_register\n"); + platform_device_register(&cfi_flash_device); +#ifdef CONFIG_LEDS + leds_event = adssphere_leds_event; +#endif + leds_event(led_start); +#ifdef CONFIG_SOUND_EP93XX_AC97 + adssphere_audio_power(1); +#endif +} + +MACHINE_START(ADSSPHERE, "adssphere") + /* Maintainer: Applied Data Systems */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = adssphere_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = adssphere_init, + .timer = &ep93xx_timer, +MACHINE_END + diff --git a/arch/arm/mach-ep93xx/mach-dma03.c b/arch/arm/mach-ep93xx/mach-dma03.c new file mode 100644 index 0000000..2223f80 --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-dma03.c @@ -0,0 +1,343 @@ +/* + * linux/arch/arm/mach-ep93xx/mach-dma03.c + * Copyright (C) 2005 Michael Burian + * + * based on arch/arm/mach-ep93xx/mach-edb9315.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_8250 +#include +#endif + +#ifdef CONFIG_PARPORT_PC +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_8250 +#include +#endif + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +#include "ep93xx_gpio_irq.h" +#endif + + + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc dma03_io_desc[] __initdata = { + {EP93XX_AHB_BASE, __phys_to_pfn(io_v2p(EP93XX_AHB_BASE)), SZ_1M, MT_DEVICE}, + {EP93XX_APB_BASE, __phys_to_pfn(io_v2p(EP93XX_APB_BASE)), SZ_8M, MT_DEVICE}, +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_PARPORT_PC) + { 0xD0000000, __phys_to_pfn(0x70000000), SZ_4K, MT_DEVICE }, /* 2x UARTS, LPT; 16C552 */ +#endif +}; + +static void __init dma03_map_io(void) +{ + iotable_init(dma03_io_desc, ARRAY_SIZE(dma03_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void dma03_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + + + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +/* GPIO irq description + * IRQs are set up in arch/arm/mach-ep93xx/irq.c + * flags can be IRQT_RISING + * IRQT_FALLING + * IRQT_LOW + * IRQT_HIGH + * IRQT_PROBE + * + * On IRQT_PROBE nothing is done in setup irq code + */ + +/* For IRQ Demux */ + +#define DISABLED 0 +#define ENABLED 1 +struct ep93xx_egpio_irq egpio_irqs[] __initdata = +{ + /* EGPIO IRQ 0 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 1 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 2 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 3 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 4 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 5 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 6 */ + { ENABLED, IRQT_HIGH }, /* OKI ML9620 CAN controller can0 */ + /* EGPIO IRQ 7 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 8 */ + { ENABLED, IRQT_HIGH }, /* 16C552 serial UART 1 */ + /* EGPIO IRQ 9 */ + { ENABLED, IRQT_HIGH }, /* 16C552 serial UART 2 */ + /* EGPIO IRQ 10 */ + { ENABLED, IRQT_RISING }, /* 16C552 parallel port 1 */ + /* EGPIO IRQ 11 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 12 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 13 */ + { ENABLED, IRQT_HIGH }, /* OKI ML9620 CAN controller can1 */ + /* EGPIO IRQ 14 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 15 */ + { DISABLED, IRQT_PROBE }, +}; +#endif + +#ifdef CONFIG_SERIAL_8250 +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = 0x70000008, + .irq = GPIO_IRQ8, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = BASE_BAUD*16, + } , { + .mapbase = 0x70000010, + .irq = GPIO_IRQ9, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = BASE_BAUD*16, + }, { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_platform_data, + }, +}; +#endif + +static struct platform_device *devices[] __initdata = { + &cfi_flash_device, +#ifdef CONFIG_SERIAL_8250 + &serial_device, +#endif +}; + +static void __init dma03_init(void) +{ + struct parport *port; + physmap_configure(0x60000000, 0x02000000, 4, NULL); + platform_add_devices(devices, ARRAY_SIZE(devices)); + +#ifdef CONFIG_PARPORT_PC + port = parport_pc_probe_port(0xD0000020, 0, GPIO_IRQ10, 0, NULL); +// How to register that beast without crashing? +// if(port) +// port = parport_register_port(0xD0000020, GPIO_IRQ10, 0, NULL); // note that passing NULL as fops arg is a bad idea(tm) +// if(port) +// parport_announce_port(port); +#endif + +#ifdef CONFIG_LEDS + leds_event = dma03_leds_event; +#endif + leds_event(led_start); +} + +MACHINE_START(DMA03, "dma03") + /* Maintainer: Michael Burian */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = dma03_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = dma03_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-edb9301.c b/arch/arm/mach-ep93xx/mach-edb9301.c new file mode 100644 index 0000000..68004e2 --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-edb9301.c @@ -0,0 +1,219 @@ +/* + * linux/arch/arm/mach-ep93xx/edb9301.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc edb9301_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init edb9301_map_io(void) +{ + iotable_init(edb9301_io_desc, ARRAY_SIZE(edb9301_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 2, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_16M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void edb9301_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init edb9301_init(void) +{ + physmap_configure(0x60000000, 0x01000000, 2, NULL); + platform_device_register(&cfi_flash_device); +#ifdef CONFIG_LEDS + leds_event = edb9301_leds_event; +#endif + leds_event(led_start); +} + +MACHINE_START(EDB9301, "edb9301") + /* Maintainer: Michael Burian */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = edb9301_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = edb9301_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-edb9302.c b/arch/arm/mach-ep93xx/mach-edb9302.c new file mode 100644 index 0000000..ac74a1e --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-edb9302.c @@ -0,0 +1,362 @@ +/* + * linux/arch/arm/mach-ep93xx/edb9302.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc edb9302_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init edb9302_map_io(void) +{ + iotable_init(edb9302_io_desc, ARRAY_SIZE(edb9302_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 2, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_16M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +/* SSP hackery */ + +static void ssp_cs_flash(struct ssp_slave *s, int enable) +{ + unsigned long x = readl(GPIO_PADR); + if (enable) + x &= ~0x80; + else + x |= 0x80; + writel(x, GPIO_PADR); +} + +struct ep93xx_ssp_slave ep93xx_ssp_flash = { + { + LIST_HEAD_INIT(ep93xx_ssp_flash.slave.list), + NULL, + 0, + 0, + 8, + 1, + ssp_cs_flash}, + ((0 << SSPCR0_SCR_SHIFT) | (SSPCR0_FRF_MOTOROLA << SSPCR0_FRF_SHIFT) | + SSPCR0_SPO | SSPCR0_SPH | (SSPCR0_DSS_8BIT << SSPCR0_DSS_SHIFT)), + (SSPC1_SSE | SSPC1_RORIE), + 2 +}; + +EXPORT_SYMBOL(ep93xx_ssp_flash); + +static void ssp_cs_codec(struct ssp_slave *s, int enable) +{ + unsigned long x = readl(GPIO_PADR); + if (enable) + x &= ~0x40; + else + x |= 0x40; + writel(x, GPIO_PADR); +} + +struct ep93xx_ssp_slave ep93xx_ssp_codec = { + { + LIST_HEAD_INIT(ep93xx_ssp_codec.slave.list), + NULL, + 0, + 0, + 8, + 1, + ssp_cs_codec}, + ((31 << SSPCR0_SCR_SHIFT) | (SSPCR0_FRF_TI << SSPCR0_FRF_SHIFT) | + (SSPCR0_DSS_8BIT << SSPCR0_DSS_SHIFT)), + (SSPC1_SSE | SSPC1_RORIE), + 48 +}; + +EXPORT_SYMBOL(ep93xx_ssp_codec); + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void edb9302_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init edb9302_init_gpio(void) +{ + /* port A */ + /* EGPIO0-7 */ + writel(0xc2, GPIO_PADDR); + writel(0xc0, GPIO_PADR); + + /* port B */ + /* EGPIO8-15 */ + writel(0x00, GPIO_PBDDR); + writel(0x00, GPIO_PBDR); + + /* port C */ + /* GPIO0 */ + writel(0x00, GPIO_PCDDR); + writel(0x00, GPIO_PCDR); + + /* port E */ + /* RDLED, GRLED */ + writel(0x03, GPIO_PEDDR); + writel(0x03, GPIO_PEDR); + + /* port F */ + /* GPIO5, GPIO6, GPIO7 */ + writel(0x00, GPIO_PFDDR); + writel(0x00, GPIO_PFDR); + + /* port G */ + /* EECLK, EEDAT */ + writel(0x00, GPIO_PGDDR); + writel(0x00, GPIO_PGDR); + + /* port H */ + /* GPIO1, GPIO2, GPIO3, GPIO4 */ + writel(0x00, GPIO_PHDDR); + writel(0x00, GPIO_PHDR); +} + +/* looks like this might be more generic than just edb9302... */ +int ssp_do_asymmetric(struct ep93xx_ssp_slave *ss, void *tx, int tlen, void *rx, + int rlen) +{ + struct ssp_slave *s = (struct ssp_slave *)ss; + int err; + + if ((err = ssp_start(s)) < 0) + goto out1; + + ssp_select(s); + + if ((err = ssp_post(s, tlen, tx, NULL)) < 0) + goto out2; + + ssp_wait(s); + + if ((err = ssp_post(s, rlen, NULL, rx)) < 0) + goto out2; + + ssp_wait(s); + + out2: + ssp_deselect(s); + ssp_finish(s); + out1: + return err; +} + +/* start poking at the Atmel AT25F1024 flash chip */ +void poke_flash(void) +{ + unsigned char rdsr[1] = { 0x05 }; + unsigned char rdid[1] = { 0x15 }; + unsigned char rsp[10]; + + ssp_do_asymmetric(&ep93xx_ssp_flash, rdsr, 1, rsp, 1); + printk(KERN_WARNING "RDSR returns %02x\n", rsp[0]); + + ssp_do_asymmetric(&ep93xx_ssp_flash, rdid, 1, rsp, 2); + printk(KERN_WARNING "RDID returns %02x:%02x\n", rsp[0], rsp[1]); +} + +static void __init edb9302_init(void) +{ + physmap_configure(0x60000000, 0x01000000, 2, NULL); + platform_device_register(&cfi_flash_device); + edb9302_init_gpio(); +#ifdef CONFIG_LEDS + leds_event = edb9302_leds_event; +#endif + leds_event(led_start); + if (ssp_add_slave(&ep93xx_ssp_master, &ep93xx_ssp_flash.slave) < 0) + printk(KERN_ERR "EDB9302: unable to add flash slave\n"); + if (ssp_add_slave(&ep93xx_ssp_master, &ep93xx_ssp_codec.slave) < 0) + printk(KERN_ERR "EDB9302: unable to add codec slave\n"); +} + +MACHINE_START(EDB9302, "edb9302") + /* Maintainer: Michael Burian */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = edb9302_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = edb9302_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-edb9312.c b/arch/arm/mach-ep93xx/mach-edb9312.c new file mode 100644 index 0000000..e67b673 --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-edb9312.c @@ -0,0 +1,219 @@ +/* + * linux/arch/arm/mach-ep93xx/edb9312.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc edb9312_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init edb9312_map_io(void) +{ + iotable_init(edb9312_io_desc, ARRAY_SIZE(edb9312_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void edb9312_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init edb9312_init(void) +{ + physmap_configure(0x60000000, 0x02000000, 4, NULL); + platform_device_register(&cfi_flash_device); +#ifdef CONFIG_LEDS + leds_event = edb9312_leds_event; +#endif + leds_event(led_start); +} + +MACHINE_START(EDB9312, "edb9312") + /* Maintainer: Michael Burian */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = edb9312_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = edb9312_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-edb9315.c b/arch/arm/mach-ep93xx/mach-edb9315.c new file mode 100644 index 0000000..14c680a --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-edb9315.c @@ -0,0 +1,219 @@ +/* + * linux/arch/arm/mach-ep93xx/edb9315.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx + * Copyright (C) 2004 Ray Lehtiniemi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc edb9315_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init edb9315_map_io(void) +{ + iotable_init(edb9315_io_desc, ARRAY_SIZE(edb9315_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void edb9315_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init edb9315_init(void) +{ + physmap_configure(0x60000000, 0x02000000, 4, NULL); + platform_device_register(&cfi_flash_device); +#ifdef CONFIG_LEDS + leds_event = edb9315_leds_event; +#endif + leds_event(led_start); +} + +MACHINE_START(EDB9315, "edb9315") + /* Maintainer: Michael Burian */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = edb9315_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = edb9315_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-ttml.c b/arch/arm/mach-ep93xx/mach-ttml.c new file mode 100644 index 0000000..872dd01 --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-ttml.c @@ -0,0 +1,369 @@ +/* + * linux/arch/arm/mach-ep93xx/mach-ttml.c + * + * Copyright (C) 2004 Ray Lehtiniemi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc ttml_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init ttml_map_io(void) +{ + iotable_init(ttml_io_desc, ARRAY_SIZE(ttml_io_desc)); +} + +/* + * Flash handling. + */ + +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 2, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_16M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +/* SSP hackery */ + +static void ssp_cs_timicro(struct ssp_slave *s, int enable) +{ + unsigned long x = readl(GPIO_PBDR); + if (enable) + x &= ~0x10; + else + x |= 0x10; + writel(x, GPIO_PBDR); +} + +struct ep93xx_ssp_slave ep93xx_ssp_micro = { + { + LIST_HEAD_INIT(ep93xx_ssp_micro.slave.list), + NULL, + 0, + 0, + 8, + 1, + ssp_cs_timicro}, + ((31 << SSPCR0_SCR_SHIFT) | (SSPCR0_FRF_TI << SSPCR0_FRF_SHIFT) | + (SSPCR0_DSS_8BIT << SSPCR0_DSS_SHIFT)), + (SSPC1_SSE | SSPC1_RORIE), + 48 +}; + +EXPORT_SYMBOL(ep93xx_ssp_micro); + +static void ssp_cs_expansion(struct ssp_slave *s, int enable) +{ + unsigned long x = readl(GPIO_PBDR); + if (enable) + x &= ~0x20; + else + x |= 0x20; + writel(x, GPIO_PBDR); +} + +struct ep93xx_ssp_slave ep93xx_ssp_expansion = { + { + LIST_HEAD_INIT(ep93xx_ssp_expansion.slave.list), + NULL, + 0, + 0, + 8, + 1, + ssp_cs_expansion}, + 0, + 0, + 0 +}; + +EXPORT_SYMBOL(ep93xx_ssp_expansion); + +/** + * ssp_do_ttml - perform a single SSP transaction to the TTML micro + * @s: the slave + * @len: the number of words to transfer + * @tx: a buffer of @len words to clock out to slave + * @rx: a buffer of @len words to clock in from slave + * + * Use the SSP transaction interface to drive the TTML micro. The + * first byte back from the micro is the length of the reply, excluding + * the len and the csum bytes. @rlen and @rx had better be bigger + * than any reply the micro might generate. + */ +int ssp_do_ttml(struct ep93xx_ssp_slave *ss, void *tx, int tlen, void *rx, + int rlen) +{ + struct ssp_slave *s = (struct ssp_slave *)ss; + int len; + int err; + + if ((err = ssp_start(s)) < 0) + goto out1; + + ssp_select(s); + + if ((err = ssp_post(s, tlen, tx, NULL)) < 0) + goto out2; + + ssp_wait(s); + + if ((err = ssp_post(s, 1, NULL, rx)) < 0) + goto out2; + + ssp_wait(s); + + { + char *b = rx; + len = ((b[0] >> 4) & 0x07) + 2; + } + + if (len > rlen) { + printk(KERN_WARNING "SSP: rx buffer truncated\n"); + len = rlen; + } + + if ((err = ssp_post(s, len - 1, NULL, rx + 1)) < 0) + goto out2; + + err = ssp_wait(s); + + out2: + ssp_deselect(s); + out1: + ssp_finish(s); + return err; +} + +EXPORT_SYMBOL(ssp_do_ttml); + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void ttml_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init ttml_init_gpio(void) +{ + /* port A */ + writel(0x00, GPIO_PADDR); + + /* port B */ + writel(0xf1, GPIO_PBDDR); + writel(0xf1, GPIO_PBDR); + + /* port C */ + writel(0x01, GPIO_PCDDR); + writel(0x01, GPIO_PCDR); + + /* port E */ + writel(0x03, GPIO_PEDDR); + writel(0x03, GPIO_PEDR); + + /* port F */ + writel(0x00, GPIO_PFDDR); + writel(0x00, GPIO_PFDR); + + /* port G */ + writel(0x00, GPIO_PGDDR); + writel(0x00, GPIO_PGDR); + + /* port H */ + writel(0x04, GPIO_PHDDR); + writel(0x00, GPIO_PHDR); +} + +static void __init ttml_init(void) +{ + physmap_configure(0x60000000, 0x01000000, 2, NULL); + platform_device_register(&cfi_flash_device); + ttml_init_gpio(); +#ifdef CONFIG_LEDS + leds_event = ttml_leds_event; +#endif + leds_event(led_start); + + if (ssp_add_slave(&ep93xx_ssp_master, &ep93xx_ssp_micro.slave) < 0) + printk(KERN_ERR "EP93XX: unable to add micro slave\n"); + + if (ssp_add_slave(&ep93xx_ssp_master, &ep93xx_ssp_expansion.slave) < 0) + printk(KERN_ERR "EP93XX: unable to add expansion slave\n"); + +} + +MACHINE_START(EDB9301, "ttml") + /* Maintainer: Michael Burian */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = ttml_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = ttml_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-zefeerdzb.c b/arch/arm/mach-ep93xx/mach-zefeerdzb.c new file mode 100644 index 0000000..c224ca1 --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-zefeerdzb.c @@ -0,0 +1,237 @@ +/* + * linux/arch/arm/mach-ep93xx/zefeerdzb.c + * + * Copyright (C) 2004, 2005 DAVE Srl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc zefeerdzb_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init zefeerdzb_map_io(void) +{ + iotable_init(zefeerdzb_io_desc, ARRAY_SIZE(zefeerdzb_io_desc)); +} + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void zefeerdzb_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init zefeerdzb_init(void) +{ + /* + physmap_configure(0x60000000, 0x01000000, 2, NULL); + platform_device_register(&cfi_flash_device); + */ + +#ifdef CONFIG_LEDS + leds_event = zefeerdzb_leds_event; +#endif + leds_event(led_start); +} + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +#include "ep93xx_gpio_irq.h" +#endif + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +/* GPIO irq description + * IRQs are set up in arch/arm/mach-ep93xx/irq.c + * flags can be IRQT_RISING + * IRQT_FALLING + * IRQT_LOW + * IRQT_HIGH + * IRQT_PROBE + * + * On IRQT_PROBE nothing is done in setup irq code + */ + +/* For IRQ Demux */ + +#define DISABLED 0 +#define ENABLED 1 +struct ep93xx_egpio_irq egpio_irqs[] __initdata = +{ + /* EGPIO IRQ 0 */ + { DISABLED , IRQT_PROBE }, + /* EGPIO IRQ 1 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 2 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 3 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 4 */ + { ENABLED, IRQT_LOW }, /* CAN 0 GPIO IRQ */ + /* EGPIO IRQ 5 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 6 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 7 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 8 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 9 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 10 */ + { ENABLED, IRQT_LOW }, /* CAN 1 GPIO IRQ */ + /* EGPIO IRQ 11 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 12 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 13 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 14 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 15 */ + { DISABLED, IRQT_PROBE }, +}; +#endif + +MACHINE_START(ZEFEERDZB, "Zefeer DZB") + /* Maintainer: DAVE Srl */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = zefeerdzb_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = zefeerdzb_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/mach-zefeerdzq.c b/arch/arm/mach-ep93xx/mach-zefeerdzq.c new file mode 100644 index 0000000..4cae7a7 --- /dev/null +++ b/arch/arm/mach-ep93xx/mach-zefeerdzq.c @@ -0,0 +1,279 @@ +/* + * linux/arch/arm/mach-ep93xx/zefeerdzq.c + * + * Copyright (C) 2004, 2005 DAVE Srl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +extern void ep93xx_init_irq(void); + +/* break this up into individual register blocks and map them in + the associated device drivers */ + +static struct map_desc zefeerdzq_io_desc[] __initdata = { + { EP93XX_AHB_BASE, io_v2p(EP93XX_AHB_BASE), SZ_1M, MT_DEVICE }, + { EP93XX_APB_BASE, io_v2p(EP93XX_APB_BASE), SZ_8M, MT_DEVICE }, +}; + +static void __init zefeerdzq_map_io(void) +{ + iotable_init(zefeerdzq_io_desc, ARRAY_SIZE(zefeerdzq_io_desc)); +} + +/* + * Flash handling. + */ + +/* +static int flash_init(void) +{ + return 0; +} + +static void flash_exit(void) +{ +} + +static void flash_set_vpp(int on) +{ +} + +static struct flash_platform_data flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = flash_init, + .exit = flash_exit, + .set_vpp = flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = 0x60000000, + .end = 0x60000000 + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "ZefeerDZQ Boot Flash", + .dev = { + .platform_data = &flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; +*/ + +#ifdef CONFIG_LEDS + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED 2 +#define LED_GREEN 1 +#define LED_MASK (LED_GREEN | LED_RED) + +void zefeerdzq_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + led_state = LED_STATE_ENABLED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_RED | LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; + + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + default: + break; + } + + writel(0x03, GPIO_PEDDR); + + if (led_state & LED_STATE_ENABLED) + writel(hw_led_state, GPIO_PEDR); + + local_irq_restore(flags); +} + +#endif + +static void __init zefeerdzq_init(void) +{ + /* + physmap_configure(0x60000000, 0x01000000, 2, NULL); + platform_device_register(&cfi_flash_device); + */ + +#ifdef CONFIG_LEDS + leds_event = zefeerdzq_leds_event; +#endif + leds_event(led_start); +} + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +#include "ep93xx_gpio_irq.h" +#endif + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +/* GPIO irq description + * IRQs are set up in arch/arm/mach-ep93xx/irq.c + * flags can be IRQT_RISING + * IRQT_FALLING + * IRQT_LOW + * IRQT_HIGH + * IRQT_PROBE + * + * On IRQT_PROBE nothing is done in setup irq code + */ + +/* For IRQ Demux */ + +#define DISABLED 0 +#define ENABLED 1 +struct ep93xx_egpio_irq egpio_irqs[] __initdata = +{ + /* EGPIO IRQ 0 */ + { DISABLED , IRQT_PROBE }, + /* EGPIO IRQ 1 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 2 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 3 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 4 */ + { ENABLED, IRQT_LOW }, /* CAN 0 GPIO IRQ */ + /* EGPIO IRQ 5 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 6 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 7 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 8 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 9 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 10 */ + { ENABLED, IRQT_LOW }, /* CAN 1 GPIO IRQ */ + /* EGPIO IRQ 11 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 12 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 13 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 14 */ + { DISABLED, IRQT_PROBE }, + /* EGPIO IRQ 15 */ + { DISABLED, IRQT_PROBE }, +}; +#endif + +MACHINE_START(ZEFEERDZQ, "Zefeer DZQ") + /* Maintainer: DAVE Srl */ + .phys_ram = SDRAM_START, + .phys_io = 0x80000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = (SDRAM_START + 0x00000100), + + .map_io = zefeerdzq_map_io, + .init_irq = ep93xx_init_irq, + .init_machine = zefeerdzq_init, + .timer = &ep93xx_timer, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/ssp-cirrus.c b/arch/arm/mach-ep93xx/ssp-cirrus.c new file mode 100644 index 0000000..853c6c4 --- /dev/null +++ b/arch/arm/mach-ep93xx/ssp-cirrus.c @@ -0,0 +1,646 @@ +/* + * FILE: ssp.c + * + * DESCRIPTION: SSP Interface Driver Module implementation + * + * Copyright Cirrus Logic Corporation, 2001-2003. 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 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 + */ + +/* + * This driver provides a way to read and write devices on the SSP + * interface. + * + * For Tx devices, EGPIO7 is used as an address pin: + * I2S Codec CS4228 = EGPIO7 == 1 + * Serial Flash AT25F1024 = EGPIO7 == 0 + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef DEBUG +/* #define DEBUG 1 */ +#ifdef DEBUG +#define DPRINTK( x... ) printk( ##x ) +#else +#define DPRINTK( x... ) +#endif + +#define EP93XX_KEY_TIMER_PERIOD_MSEC 20 + +static int SSP_Open(enum SSPDeviceType Device, SSPDataCallback Callback); +static int SSP_Close(int Handle); +static int SSP_Read(int Handle, unsigned int Addr, unsigned int *pValue); +static int SSP_Write(int Handle, unsigned int Addr, unsigned int Value); +static int CheckHandle(int Handle); + +static void SetSSPtoPS2(void); +static void SetSSPtoI2S(void); +static int ReadIntoBuffer(void); + +static int SSP_Write_I2SCodec(int Handle, unsigned int RegAddr, + unsigned int RegValue); + +/* + * Key buffer... + */ +#define KEYBUF_SIZE 256 +static unsigned int uiKeyBuffer[KEYBUF_SIZE]; + +static spinlock_t ssp_spinlock = SPIN_LOCK_UNLOCKED; + +enum SSPmodes { + SSP_MODE_UNKNOWN = 0, + SSP_MODE_PS2, + SSP_MODE_I2S, + SSP_MODE_FLASH, +}; + +static struct timer_list g_KbdTimer; +static enum SSPmodes gSSPmode = SSP_MODE_UNKNOWN; +static SSPDataCallback gKeyCallback = NULL; +static int gHookedInterrupt = 0; + +/* + * Keep the last valid handle for SSP for kbd, i2s, and flash + */ +static int iLastValidHandle = -1; +static int KeyboardHandle = 0; +static int I2SHandle = 0; +static int FlashHandle = 0; + +#define SSP_DEVICE_MASK 0xf0000000 +#define SSP_DEVICE_SHIFT 28 + +SSP_DRIVER_API SSPinstance = { + SSP_Open, + SSP_Read, + SSP_Write, + SSP_Close, +}; + +/* + * The only instance of this driver. + */ +SSP_DRIVER_API *SSPDriver = &SSPinstance; + +/** + * SSPIrqHandler - get all of the keys out of the SPI FIFO. + */ +irqreturn_t SSPIrqHandler(int irq, void *dev_id, struct pt_regs *regs) +{ + /* + * Get key codes from SSP and send them to the keyboard callback. + */ + ReadIntoBuffer(); + + /* + * Clear the interrupt. + */ + writel(0, SSPIIR); + return IRQ_HANDLED; +} + +/** + * TimerRoutine + * + * This function is called periodically to make sure that no keys are stuck in + * the SPI FIFO. This is necessary because the SPI only interrupts on half + * full FIFO which can leave up to one keyboard event in the FIFO until another + * key is pressed. + */ +static void TimerRoutine(unsigned long Data) +{ + int keycount; + + /* + * Get key codes from SSP and send them to the keyboard callback. + */ + keycount = ReadIntoBuffer(); + + /* + * If no keys were received, call the Data callback anyway so it can + * check for stuck keys. + */ + if ((keycount == 0) && gKeyCallback) + gKeyCallback(-1); + + /* + * Reschedule our timer in another 20 mSec. + */ + g_KbdTimer.expires = + jiffies + MSECS_TO_JIFFIES(EP93XX_KEY_TIMER_PERIOD_MSEC); + add_timer(&g_KbdTimer); +} + +/** + * HookInterrupt + * + * Requests SSP interrupt, sets up interrupt handler, sets up keyboard polling + * timer. + */ +static int HookInterrupt(void) +{ + if (gHookedInterrupt) { + printk(KERN_ERR "SSP driver interrupt already hooked\n"); + return -1; + } + + if (request_irq + (IRQ_SSPRX, SSPIrqHandler, SA_INTERRUPT, "ep93xxsspd", NULL)) { + printk(KERN_ERR "SSP driver failed to get IRQ handler\n"); + return -1; + } + + gHookedInterrupt = 1; + + /* + * Initialize the timer that we will use to poll the SPI. + */ + init_timer(&g_KbdTimer); + g_KbdTimer.function = TimerRoutine; + g_KbdTimer.data = 1; + g_KbdTimer.expires = + jiffies + MSECS_TO_JIFFIES(EP93XX_KEY_TIMER_PERIOD_MSEC); + + add_timer(&g_KbdTimer); + + return 0; +} + +static int SSP_Open(enum SSPDeviceType Device, SSPDataCallback Callback) +{ + int Handle; + + /* + * Generate a handle and pass it back. + * + * Increment the last valid handle. + * Check for wraparound (unlikely, but we like to be complete). + */ + iLastValidHandle++; + + /* + * If we wrapped around start over. Unlikely. + */ + if ((iLastValidHandle & ~SSP_DEVICE_MASK) == 0) + iLastValidHandle = 1; + + Handle = iLastValidHandle | (Device << SSP_DEVICE_SHIFT); + + switch (Device) { + case PS2_KEYBOARD: + { + DPRINTK("SSP_Open - PS2_KEYBOARD\n"); + if (KeyboardHandle) + return -1; + + DPRINTK("Handle:%08x Callback:%08x -- Success\n", + Handle, (unsigned int)Callback); + + KeyboardHandle = Handle; + /* Hook the interrupt if we have not yet. */ + HookInterrupt(); + SetSSPtoPS2(); + gKeyCallback = Callback; + + break; + } + case I2S_CODEC: + { + DPRINTK("SSP_Open - I2S_CODEC\n"); + if (I2SHandle) + return -1; + + DPRINTK("Handle:%08x Callback:%08x -- Success\n", + Handle, (unsigned int)Callback); + + I2SHandle = Handle; + break; + } + case SERIAL_FLASH: + { + DPRINTK("SSP_Open - SERIAL_FLASH\n"); + if (FlashHandle) + return -1; + + DPRINTK("Handle:%08x Callback:%08x -- Success\n", + Handle, (unsigned int)Callback); + + FlashHandle = Handle; + break; + } + default: + { + return -1; + } + } + + return Handle; +} + +/** + * SSP_Close + * + * Release that Handle! + */ +static int SSP_Close(int Handle) +{ + /* + * Find out which device this API was called for. + */ + switch (CheckHandle(Handle)) { + case PS2_KEYBOARD: + { + DPRINTK("SSP_Open - PS2_KEYBOARD\n"); + del_timer(&g_KbdTimer); + free_irq(IRQ_SSPRX, NULL); + gKeyCallback = NULL; + KeyboardHandle = 0; + gHookedInterrupt = 0; + break; + } + case I2S_CODEC: + { + DPRINTK("SSP_Open - I2S_CODEC\n"); + I2SHandle = 0; + break; + } + case SERIAL_FLASH: + { + DPRINTK("SSP_Open - SERIAL_FLASH\n"); + FlashHandle = 0; + break; + } + default: + { + return -1; + } + } + return 0; +} + +static int SSP_Read(int Handle, unsigned int Addr, unsigned int *pValue) +{ + DPRINTK("SSP_Read\n"); + return 0; +} + +static int SSP_Write(int Handle, unsigned int Addr, unsigned int Value) +{ + int iRet = 0; + /* DPRINTK("SSP_Write - Handle:0x%08x Addr:0x%08x Value:0x%08x\n", + Handle, Addr, Value ); */ + + /* + * Find out which device this API was called for. + */ + switch (CheckHandle(Handle)) { + case PS2_KEYBOARD: + { + break; + } + case I2S_CODEC: + { + iRet = SSP_Write_I2SCodec(Handle, Addr, Value); + break; + } + case SERIAL_FLASH: + { + break; + } + default: + { + return -1; + } + } + + return iRet; +} + +static void SetSSPtoPS2(void) +{ + unsigned int uiRegTemp; + + if (gSSPmode == SSP_MODE_PS2) + return; + + /* + * Disable the SSP, disable interrupts + */ + writel(0, SSPCR1); + + /* + * It takes almost a millisecond for a key to come in so + * make sure we have completed all transactions. + */ + mdelay(1); + + /* + * Set EGPIO7 to disable EEPROM device on EDB9312. + */ + uiRegTemp = readl(GPIO_PADDR); + writel(uiRegTemp | 0x80, GPIO_PADDR); + + uiRegTemp = readl(GPIO_PADR); + writel(uiRegTemp | 0x80, GPIO_PADR); + + /* + * Still haven't enabled the keyboard. So anything in + * the rx fifo is garbage. Time to take out the trash. + */ + while (readl(SSPSR) & SSPSR_RNE) { + uiRegTemp = readl(SSPDR); + } + + /* + * SPICR0_SPO - SCLKOUT Polarity + * SPICR0_SPH - SCLKOUT Phase + * Motorola format, 11 bit, one start, 8 data, one bit for + * parity, one stop bit. + */ + writel((SSPCR0_FRF_MOTOROLA | SSPCR0_SPH | SSPCR0_SPO | + SSPCR0_DSS_11BIT), SSPCR0); + /* + * Configure the device as a slave, Clear FIFO overrun interrupts, + * enable interrupts and reset the device. + */ + writel((SSPC1_MS | SSPC1_RIE | SSPC1_SOD), SSPCR1); + writel(0, SSPIIR); + writel((SSPC1_MS | SSPC1_RIE | SSPC1_SOD | SSPC1_SSE), + SSPCR1); + + /* + * Configure EGPIO pins 12 and 14 as outputs because they are used + * as buffer enables for the SPI interface to the ps2 keyboard. + * Clear EGPIO pins 12 and 14, this will enable the SPI keyboard. + */ + uiRegTemp = readl(GPIO_PBDDR); + writel(uiRegTemp | 0x50, GPIO_PBDDR); + + uiRegTemp = readl(GPIO_PBDR); + writel(uiRegTemp & ~0x50, GPIO_PBDR); + + gSSPmode = SSP_MODE_PS2; +} + +static void SetSSPtoI2S(void) +{ + unsigned int uiRegTemp; + + if (gSSPmode == SSP_MODE_I2S) + return; + + /* + * Disable recieve interrupts. + */ + writel((SSPC1_MS | SSPC1_SSE), SSPCR1); + + /* + * Set GPIO pins 12 and 14, this will bring the clock line low + * which signals to the keyboard to buffer keystrokes. + * Note that EGPIO 14 is the clock line and EGPIO 12 is data line. + */ + uiRegTemp = readl(GPIO_PBDR); + writel(0x50 | uiRegTemp, GPIO_PBDR); + + /* + * It takes almost a millisecond for an partial keystrokes to come in. + * Delay to make sure we have completed all transactions. + */ + mdelay(1); + + /* + * Anything we just recieved is garbage. Time to take out the trash. + */ + while (readl(SSPSR) & SSPSR_RNE) { + uiRegTemp = readl(SSPDR); + } + + /* + * Disable the SSP and disable interrupts + */ + writel(0, SSPCR1); + + /* + * Clock will be 14.7 MHz divided by 4. + */ + writel(2, SSPCPSR); + + /* + * Configure EGPIO7 as an output and set it. This selects + * I2S codec as the device on the SSP output instead of + * the serial flash. + */ + uiRegTemp = readl(GPIO_PADDR); + writel(uiRegTemp | 0x80, GPIO_PADDR); + + uiRegTemp = readl(GPIO_PADR); + writel(uiRegTemp | 0x80, GPIO_PADR); + + /* + * Motorola format, 8 bit. + */ + writel((SSPCR0_SPO | SSPCR0_SPH | SSPCR0_FRF_MOTOROLA | + SSPCR0_DSS_8BIT), SSPCR0); + + /* + * Configure the device as master, reenable the device. + */ + writel(SSPC1_SSE, SSPCR1); + + gSSPmode = SSP_MODE_I2S; + + udelay(10); +} + +/** + * CheckHandle + * + * If Handle is valid, returns 0. Otherwise it returns -1. + */ +static int CheckHandle(int Handle) +{ + int iRet; + + if ((Handle != KeyboardHandle) && + (Handle != I2SHandle) && (Handle != FlashHandle)) { + DPRINTK("OOPS! Invalid SSP Handle!\n"); + return -1; + } + + /* + * Get the SSP driver instance number from the handle. + */ + iRet = (((int)Handle & SSP_DEVICE_MASK) >> SSP_DEVICE_SHIFT); + +#if 0 + switch (iRet) { + case PS2_KEYBOARD: + DPRINTK("CheckHandle - valid - Keyboard\n"); + break; + + case I2S_CODEC: + DPRINTK("CheckHandle - valid - I2S\n"); + break; + + case SERIAL_FLASH: + DPRINTK("CheckHandle - valid - Keyboard\n"); + break; + } +#endif + + return iRet; +} + +/** + * ReadIntoBuffer + * + * Drains the SSP rx fifo into a buffer here. If we overflow this buffer + * then something's wrong. + */ +static int ReadIntoBuffer(void) +{ + unsigned int count, index, saved_count, uiRegTemp; + + count = 0; + index = 0; + + if (gSSPmode != SSP_MODE_PS2) + return 0; + + /* + * This spinlock will prevent I2S from grabbing the SSP to do a + * write while we are using the SSP for PS2. + * + * There is a slight chance that we are in the beginning phase + * of doing an I2S write but the mode flag hadn't yet switched + * to I2S. If that happens we will end up waiting on I2S to + * finish a write. Not great. + */ + spin_lock(&ssp_spinlock); + + while (readl(SSPSR) & SSPSR_RNE) { + /* + * Read in the value from the SPI controller into + * the partial key buffer. + */ + uiKeyBuffer[count] = readl(SSPDR); + if (((uiKeyBuffer[count] & 0x3fc) != 0x3e0) && + ((uiKeyBuffer[count] & 0x3fc) != 0x3c0)) { + /* + * Set GPIO pins 12 and 14, this will bring the clock line low + * which signals to the keyboard to buffer keystrokes. + * Note that EGPIO 14 is the clock line and EGPIO 12 is data line. + */ + uiRegTemp = readl(GPIO_PBDR); + writel(0x50 | uiRegTemp, GPIO_PBDR); + + writel(0, SSPCR1); + writel((SSPC1_MS | SSPC1_RIE | SSPC1_SSE), + SSPCR1); + + /* + * Clear EGPIO pins 12 and 14, this will enable the SPI keyboard. + */ + uiRegTemp = readl(GPIO_PBDR); + writel(uiRegTemp & ~0x50, GPIO_PBDR); + + count++; + break; + } + count++; + } + + saved_count = count; + index = 0; + while (count) { + /* + * No callback, dump data. + */ + if (gKeyCallback) + gKeyCallback(uiKeyBuffer[index++]); + + count--; + } + + spin_unlock(&ssp_spinlock); + + return saved_count; +} + +/** + * SSP_Write_I2SCodec + * + */ +static int SSP_Write_I2SCodec + (int Handle, unsigned int RegAddr, unsigned int RegValue) { + enum SSPmodes saved_mode; + + DPRINTK("SSP_Write_I2SCodec\n"); + + spin_lock(&ssp_spinlock); + + /* + * Save the SSP mode. Switch to I2S mode if we're not + * already in I2S mode. + */ + saved_mode = gSSPmode; + SetSSPtoI2S(); + + /* + * Let TX fifo clear out. Poll the Transmit Fifo Empty bit. + */ + while (!(readl(SSPSR) & SSPSR_TFE)) ; + + /* + * Write the data out to the tx fifo. + */ + writel(0x20, SSPDR); /* chip address for CS4228 */ + writel((RegAddr & 0xff), SSPDR); + writel((RegValue & 0xff), SSPDR); + + /* + * Let TX fifo clear out. Poll the Transmit Fifo Empty bit. + */ + while (!(readl(SSPSR) & SSPSR_TFE)) ; + + /* + * Delay to let stuff make it out of the SR before doing + * anthing else to the SSP. It takes 6.8 uSec to do a + * I2S codec register write. + */ + udelay(10); + + /* + * If we were in PS2 mode, switch back to PS2 mode. + * If we weren't in PS2 mode, that means we didn't compile in + * the PS2 keyboard support, so no need to switch to PS2 mode. + */ + if (saved_mode == SSP_MODE_PS2) + SetSSPtoPS2(); + + spin_unlock(&ssp_spinlock); + + return 0; +} diff --git a/arch/arm/mach-ep93xx/ssp.c b/arch/arm/mach-ep93xx/ssp.c new file mode 100644 index 0000000..4e1b973 --- /dev/null +++ b/arch/arm/mach-ep93xx/ssp.c @@ -0,0 +1,246 @@ +/* + * linux/arch/arm/mach-ep93xx/ssp.c + * + * Generic SSP driver. This provides shared access to the SSP + * interface operating in master mode. + * + * Copyright (C) 2004 Ray Lehtiniemi. + * Copyright (C) 2004 Siconix, Inc. + * + * 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 + +/* ================================================================ + Front End Interface + ================================================================ */ + +/*** + * ssp_add_slave - register an ssp_slave with an ssp_master + * @m: the master + * @s: the slave + * + * Grabs the frontend lock and adds slave to list. + */ +int ssp_add_slave(struct ssp_master *m, struct ssp_slave *s) +{ + if (s->master != NULL) + return -EBUSY; + down(&m->sem); + list_add(&s->list, &m->slave); + s->master = m; + up(&m->sem); + return 0; +} + +EXPORT_SYMBOL(ssp_add_slave); + +/*** + * ssp_remove_slave - de-register an ssp_slave from its master + * @m: the master + * @s: the slave + * + * Grabs the frontend lock and removes slave from list. + */ +void ssp_remove_slave(struct ssp_master *m, struct ssp_slave *s) +{ + if (s->master != m) + return; + down(&m->sem); + list_del(&s->list); + s->master = NULL; + up(&m->sem); +} + +EXPORT_SYMBOL(ssp_remove_slave); + +/*** + * ssp_do - perform a single SSP transaction on the slave + * @s: the slave + * @len: the number of words to transfer + * @tx: a buffer of @len words to clock out to slave + * @rx: a buffer of @len words to clock in from slave + * + * Grabs the frontend lock, configures the ssp master as required + * by the slave, asserts the slave devices chip select line, and + * schedules the backend to perform the transfer. + * + * Once the backend signals completion, the chip select is negated + * and the frontend lock is released. + * + * The backend will transfer @len * @s->nbytes from @tx and + * into @rx. Make sure your buffers are big enough! If @tx + * or @rx are null, then null data will be clocked in and/or out. + */ +int ssp_do(struct ssp_slave *s, int len, void *tx, void *rx) +{ + int err; + + if ((err = ssp_start(s)) < 0) + goto out1; + + ssp_select(s); + + if ((err = ssp_post(s, len, tx, rx)) < 0) + goto out2; + + err = ssp_wait(s); + + out2: + ssp_deselect(s); + ssp_finish(s); + out1: + return err; +} + +EXPORT_SYMBOL(ssp_do); + +/* ================================================================ + Transaction Interface + ================================================================ */ + +static int __ssp_txn_start(struct ssp_slave *s); + +/*** + * ssp_start - Grab and configure the SSP bus (blocking) + * @s: the slave + * + * This call will grab and initialize the SSP bus, blocking + * until the bus is ready. + */ +int ssp_start(struct ssp_slave *s) +{ + down(&s->master->sem); + return __ssp_txn_start(s); +} + +EXPORT_SYMBOL(ssp_start); + +/*** + * ssp_trystart - Grab and configure the SSP bus (non-blocking) + * @s: the slave + * + * This call will grab and initialize the SSP bus, returning + * with an error if the bus is not free. + */ +int ssp_trystart(struct ssp_slave *s) +{ + if (!down_trylock(&s->master->sem)) + return -EBUSY; + return __ssp_txn_start(s); +} + +EXPORT_SYMBOL(ssp_trystart); + +static int __ssp_txn_start(struct ssp_slave *s) +{ + return s->master->ops->configure(s); +} + +/*** + * ssp_select - assert the slave CS line + * @s: the slave + * + * assert the device-specific CS line + */ +void ssp_select(struct ssp_slave *s) +{ + s->chip_select(s, 1); +} + +EXPORT_SYMBOL(ssp_select); + +/*** + * ssp_post - start the backend for the slave's master + * @s: the slave + * + * Start the backend data transfer for this master. + */ +int ssp_post(struct ssp_slave *s, int len, void *tx, void *rx) +{ + struct ssp_transfer *t; + + t = &s->master->transfer; + + t->size = s->nbytes; + t->len = len; + t->rlen = len; + t->tx = tx; + t->rx = rx; + t->c = &s->master->completion; + init_completion(t->c); + + return s->master->ops->enable(t); +} + +EXPORT_SYMBOL(ssp_post); + +/*** + * ssp_wait - block until the SP transfer is complete + * @s: the slave + * + * block until the SP transfer is complete. + */ +int ssp_wait(struct ssp_slave *s) +{ + wait_for_completion(&s->master->completion); + return s->master->ops->disable(); +} + +EXPORT_SYMBOL(ssp_wait); + +/*** + * ssp_deselect - assert the slave CS line + * @s: the slave + * + * negate the device-specific CS line + */ +void ssp_deselect(struct ssp_slave *s) +{ + s->chip_select(s, 0); +} + +EXPORT_SYMBOL(ssp_deselect); + +/*** + * ssp_finish - release the ssp bus + * @s: the slave + * + * Releases the frontend lock. + */ +void ssp_finish(struct ssp_slave *s) +{ + up(&s->master->sem); +} + +EXPORT_SYMBOL(ssp_finish); + +/* ================================================================ + Module Stuff + ================================================================ */ + +int __init ssp_init(void) +{ + printk(KERN_INFO "Generic SSP Support version 0.1\n"); + return 0; +} + +void __exit ssp_exit(void) +{ +} + +module_init(ssp_init); +module_exit(ssp_exit); + +MODULE_AUTHOR("Ray Lehtiniemi"); +MODULE_DESCRIPTION("Generic SSP driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-ep93xx/ssp2.c b/arch/arm/mach-ep93xx/ssp2.c new file mode 100644 index 0000000..6a4ff10 --- /dev/null +++ b/arch/arm/mach-ep93xx/ssp2.c @@ -0,0 +1,354 @@ +/* + * linux/arch/arm/mach-ep93xx/ssp.c + * + * EP93xx SSP driver. This provides shared access to the SSP + * interface operating in master mode. + * + * Copyright (C) 2004 Ray Lehtiniemi. + * Copyright (C) 2004 Siconix, Inc. + * + * 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 + +/* print out all chars tx, rx, and dropped */ +#define _(x...) /* printk(KERN_WARNING x); printk("\n") */ + +/* the current transfer */ +static struct ssp_transfer *transfer; + +/* stupid SSP gives rx int only when rx fifo > half full :-P */ +static void do_rx_poll(void *x); +static DECLARE_WORK(work, do_rx_poll, NULL); + +/* also implement a timeout in the worker, to prevent hard lockups + if something goes south... */ +static int timeout; + +/* serialize the rx irq and the work poller routines */ +static spinlock_t spinlock = SPIN_LOCK_UNLOCKED; + +/* ----------------- Hardware Control --------------------- */ + +/* send a word */ +static __inline__ void x_ssp_send(__u16 dat) +{ + writel(dat, SSPDR); + _("\ttx %08x", dat); +} + +/* send a word to clock the recv */ +static __inline__ void x_ssp_clock(void) +{ + writel(0, SSPDR); + _("\tt- --------"); +} + +/* recv a word */ +static __inline__ __u16 x_ssp_recv(void) +{ + unsigned long dat = readl(SSPDR); + _("\trx %08lx", dat); + return dat & 0xffff; +} + +/* discard a word */ +static __inline__ void x_ssp_discard(void) +{ +#if 1 + unsigned long dat = readl(SSPDR); + _("\tr- %08lx (discard)", dat); +#else + (void)readl(SSPDR); + _("\tr- --------"); +#endif +} + +/* are there chars in the rx fifo? */ +static __inline__ int x_ssp_available(void) +{ + return (readl(SSPSR) & SSPSR_RNE) ? 1 : 0; +} + +/* is there room in the tx fifo? */ +static __inline__ int x_ssp_has_room(void) +{ + return (readl(SSPSR) & SSPSR_TNF) ? 1 : 0; +} + +/* is the transmitter busy? */ +static __inline__ int x_ssp_busy(void) +{ + return (readl(SSPSR) & SSPSR_BSY) ? 1 : 0; +} + +/* flush the RX and TX fifos */ +static void x_ssp_flush(void) +{ + do { + while (x_ssp_available()) + x_ssp_discard(); + } while (x_ssp_busy()); + + /* just in case there is a race... in any event, this should be harmless */ + x_ssp_discard(); +} + +/* set up all regs as required by the slave */ +static void x_ssp_configure(struct ep93xx_ssp_slave *s) +{ + writel(s->cr1, SSPCR1); + writel(s->cr0, SSPCR0); + writel(s->cpsr, SSPCPSR); + writel(s->cr1 & ~SSPC1_SSE, SSPCR1); + writel(s->cr1, SSPCR1); +} + +/* enable chip select and all ints */ +static __inline__ void x_ssp_enable(void) +{ + unsigned long x = readl(SSPCR1); + writel(x | SSPC1_TIE | SSPC1_RIE | SSPC1_RORIE, SSPCR1); +} + +/* disable chip select and all ints */ +static __inline__ void x_ssp_disable(void) +{ + unsigned long x = readl(SSPCR1); + writel(x & ~(SSPC1_TIE | SSPC1_RIE | SSPC1_RORIE), SSPCR1); +} + +/* disable tx int */ +static __inline__ void x_ssp_stop_tx(void) +{ + unsigned long x = readl(SSPCR1); + writel(x & ~SSPC1_TIE, SSPCR1); +} + +/* ---------------------- Master Methods ------------------------- */ + +static int ep93xx_ssp_configure(struct ssp_slave *ss) +{ + struct ep93xx_ssp_slave *s = (struct ep93xx_ssp_slave *)ss; + _("SSP transfer"); + x_ssp_configure(s); + return 0; +} + +static int ep93xx_ssp_enable(struct ssp_transfer *t) +{ + _("{"); + transfer = t; + timeout = 0; + schedule_delayed_work(&work, 1); + x_ssp_enable(); + return 0; +} + +static int ep93xx_ssp_disable(void) +{ + x_ssp_disable(); + cancel_delayed_work(&work); + transfer = NULL; + _("}"); + return 0; +} + +static struct ssp_master_ops my_ops = { + .configure = ep93xx_ssp_configure, + .enable = ep93xx_ssp_enable, + .disable = ep93xx_ssp_disable, +}; + +/* ----------------- Registration Stuff FIXME ------------- */ + +#include +#include +#include + +struct ssp_master ep93xx_ssp_master = { + __MUTEX_INITIALIZER(ep93xx_ssp_master.sem), + COMPLETION_INITIALIZER(ep93xx_ssp_master.completion), + LIST_HEAD_INIT(ep93xx_ssp_master.slave), + { + 0, + 0, + 0, + NULL, + NULL, + NULL}, + &my_ops +}; + +EXPORT_SYMBOL(ep93xx_ssp_master); + +/* -------------------- Bottom Half ----------------------- */ + +static void do_tx(void) +{ + if (transfer == NULL) { + printk(KERN_WARNING "Null tx transfer...\n"); + return; + } + + while (transfer->len != 0) { + + if (!x_ssp_has_room()) + return; + + if (transfer->tx == NULL) { + x_ssp_clock(); + + } else if (transfer->size == 1) { + __u8 *t = transfer->tx; + x_ssp_send(*t); + transfer->tx += 1; + + } else if (transfer->size == 2) { + __u16 *t = transfer->tx; + x_ssp_send(*t); + transfer->tx += 2; + + } else if (transfer->size == 4) { + __u32 *t = transfer->tx; + x_ssp_send(*t); + transfer->tx += 4; + } + + transfer->len--; + } + + x_ssp_stop_tx(); +} + +static void __do_rx(void) +{ + if (transfer == NULL) { + printk(KERN_WARNING "Null rx transfer...\n"); + return; + } + + while (transfer->rlen != 0) { + + if (!x_ssp_available()) + return; + + if (transfer->rx == NULL) { + x_ssp_discard(); + + } else if (transfer->size == 1) { + __u8 *t = transfer->rx; + *t = x_ssp_recv(); + transfer->rx += 1; + + } else if (transfer->size == 2) { + __u16 *t = transfer->rx; + *t = x_ssp_recv(); + transfer->rx += 2; + + } else if (transfer->size == 4) { + __u32 *t = transfer->rx; + *t = x_ssp_recv(); + transfer->rx += 4; + } + + transfer->rlen--; + timeout = 0; + } + + complete(transfer->c); +} + +static void do_rx(void) +{ + unsigned long flags; + spin_lock_irqsave(&spinlock, flags); + __do_rx(); + spin_unlock_irqrestore(&spinlock, flags); +} + +static void do_rx_poll(void *x) +{ + unsigned long flags; + spin_lock_irqsave(&spinlock, flags); + __do_rx(); + timeout++; + if (timeout == 100) { + x_ssp_disable(); + complete(transfer->c); + } else { + schedule_delayed_work(&work, 1); + } + spin_unlock_irqrestore(&spinlock, flags); +} + +static irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int status = readl(SSPIIR); + + if (transfer == NULL) { + printk(KERN_WARNING "SSP: no active transfer\n"); + x_ssp_flush(); + x_ssp_disable(); + } + + if (status & SSPIIR_RORIS) + printk(KERN_WARNING "SSP: receiver overrun\n"); + + if (status & SSPIIR_TIS) + do_tx(); + + if (status & SSPIIR_RIS) + do_rx(); + + writel(0, SSPICR); + + return status ? IRQ_HANDLED : IRQ_NONE; +} + +/* -------------------- Module Stuff ---------------------- */ + +int __init ep93xx_ssp_init(void) +{ + int i; + + if (readl(SYSCON_DEVCFG) & SYSCON_DEVCFG_I2SonSSP) + return -ENODEV; + + i = request_irq(IRQ_SSP, irq_handler, 0, "SSP", NULL); + + if (i) + printk(KERN_ERR + "EP93XX: unable to grab SSP interrupt, error %d\n", i); + + printk(KERN_INFO "EP93xx SSP driver version 0.1\n"); + return 0; +} + +void __exit ep93xx_ssp_exit(void) +{ + free_irq(IRQ_SSP, NULL); +} + +module_init(ep93xx_ssp_init); +module_exit(ep93xx_ssp_exit); + +MODULE_AUTHOR("Ray Lehtiniemi"); +MODULE_DESCRIPTION("EP93xx SSP driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-ep93xx/time.c b/arch/arm/mach-ep93xx/time.c new file mode 100644 index 0000000..459a179 --- /dev/null +++ b/arch/arm/mach-ep93xx/time.c @@ -0,0 +1,40 @@ +/* + * linux/arch/arm/mach-ep93xx/time.c + * + * Copyright (C) 2000-2001 Deep Blue Solutions + * + * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA. All rights reserved. + * Copyright (C) 2002-2003 Cirrus Logic, Inc. + * + * 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 + +extern int (*set_rtc) (void); + +static int ep93xx_set_rtc(void) +{ + writel(xtime.tv_sec, RTCLR); + return 1; +} + +static int ep93xx_rtc_init(void) +{ + writel(0, RTCCR); + writel(0, RTCEOI); + + writel(xtime.tv_sec, RTCDR); + + set_rtc = ep93xx_set_rtc; + + return 0; +} + +__initcall(ep93xx_rtc_init); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index e84fdde..85c90bf 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -62,8 +62,8 @@ config CPU_ARM720T # ARM920T config CPU_ARM920T bool "Support ARM920T processor" if !ARCH_S3C2410 - depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 - default y if ARCH_S3C2410 + depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_EP93XX + default y if ARCH_S3C2410 || ARCH_EP93XX select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 8b276ee..cc8aedb 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -212,6 +212,10 @@ static __init void reserve_node_zero(pg_ if (machine_is_integrator() || machine_is_cintegrator()) res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + /* TBD vector table and initial stack below pg_dir */ + if (machine_is_edb9301() || machine_is_edb9312() || machine_is_edb9315() || machine_is_acc()) + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + /* * These should likewise go elsewhere. They pre-reserve the * screen memory region at the start of main system memory. diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 84e68cd..c4a267b 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -4,6 +4,16 @@ menu "Character devices" +config TTML_DEVICES + tristate "TTML TripDawg system devices" + depends on MACH_TTML + default m + ---help--- + If you say y or m here, you will get several character devices + which allow you to use the LEDs, buzzer, speedometer, and so + on. These devices are mapped into the 10,{240-254} range, which + is reserved for local devices. + config VT bool "Virtual terminal" if EMBEDDED select INPUT @@ -762,6 +772,26 @@ config EFI_RTC bool "EFI Real Time Clock Services" depends on IA64 +config EP93XX_RTC + bool "Cirrus EP93xx Real Time Clock support" + depends on ARCH_EP93XX + help + Provides EFI and legacy RTC support on the Cirrus EP93xx family of + devices via the /dev/rtc character node (10/135). + +config DS1337_RTC + tristate "Dallas Semiconductor DS1337 Real Time Clock /dev/rtc interface" + depends on I2C && EXPERIMENTAL && !EP93XX_RTC + select SENSORS_DS1337 + help + Say Y here you have got a DS1337 real time clock on your I2C bus. + This here is just an interface to access it via the /dev/rtc + character node (10/135). All the hard work will be done + in the I2C driver (drivers/i2c/chips/ds1337.c). + + This driver can also be built as a module. If so, the module + will be called ds1337glue. + config DS1302 tristate "DS1302 RTC support" depends on M32R && (PLAT_M32700UT || PLAT_OPSPUT) @@ -893,6 +923,8 @@ source "drivers/char/drm/Kconfig" source "drivers/char/pcmcia/Kconfig" +source "drivers/char/can/Kconfig" + config MWAVE tristate "ACP Modem (Mwave) support" depends on X86 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 4aeae68..579570d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -9,6 +9,7 @@ FONTMAPFILE = cp437.uni obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o +obj-$(CONFIG_TTML_DEVICES) += ttml.o obj-$(CONFIG_LEGACY_PTYS) += pty.o obj-$(CONFIG_UNIX98_PTYS) += pty.o obj-y += misc.o @@ -65,6 +66,8 @@ obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o obj-$(CONFIG_DS1302) += ds1302.o obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o obj-$(CONFIG_RTC_VR41XX) += vr41xx_rtc.o +obj-$(CONFIG_EP93XX_RTC) += ep93xx-rtc.o +obj-$(CONFIG_DS1337_RTC) += ds1337glue.o ifeq ($(CONFIG_GENERIC_NVRAM),y) obj-$(CONFIG_NVRAM) += generic_nvram.o else @@ -119,3 +122,6 @@ $(obj)/defkeymap.c $(obj)/qtronixmap.c: rm $@.tmp endif + +obj-$(CONFIG_CAN_BUS) += can/ + diff --git a/drivers/char/can/Kconfig b/drivers/char/can/Kconfig new file mode 100644 index 0000000..9834c66 --- /dev/null +++ b/drivers/char/can/Kconfig @@ -0,0 +1,46 @@ +# +# CAN bus character devices configuration +# + +menu "CAN bus devices" + +config CAN_BUS + bool "CAN bus character devices" + help + If you say y here, you will get support for CAN bus + character device drivers. + +config OKI_CAN_ML9620 + tristate "OKI ML9620 CAN BUS" + depends on CAN_BUS + help + If you say y or m here, you will get support for OKI ML9620 + character device based CAN driver for one CAN bus. + +choice + prompt "OKI ML9620 configuration" + depends on OKI_CAN_ML9620 + help + Specific configuration for OKI ML9620 configuration. + +config OKI_CAN_ML9620_MICRO9 + bool "OKI ML9620 Contec Hypercontrol Micro9 configuration" + depends on OKI_CAN_ML9620 + help + Select this if you have Contec Hypercontrol Micro9 board. + +config OKI_CAN_ML9620_GASSNER + bool "OKI ML9620 Gassner configuration" + help + Select this if you want to have Gassner specific changes. + +endchoice + +config OKI_CAN_ML9620_2DEV + bool "OKI ML9620 CAN BUS 2nd DEVICE" + depends on OKI_CAN_ML9620 + help + If you say y here, you will get support for a second + OKI ML9620 CAN bus. + +endmenu diff --git a/drivers/char/can/Makefile b/drivers/char/can/Makefile new file mode 100644 index 0000000..f9bcf2a --- /dev/null +++ b/drivers/char/can/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for CAN BUS character devices +# +obj-$(CONFIG_OKI_CAN_ML9620) += oki_ml9620.o diff --git a/drivers/char/can/oki_ml9620.c b/drivers/char/can/oki_ml9620.c new file mode 100644 index 0000000..d60cca4 --- /dev/null +++ b/drivers/char/can/oki_ml9620.c @@ -0,0 +1,1006 @@ +/* + * drivers/char/can/oki_ml9620_core.c + * + * OKI ML9620 CAN Controler driver + * + * Author: Manfred Gruber + * + * Copyright 2004 (c) Manfred Gruber + * Copyright 2004 (c) Contec Steuerungstechnik & Automation Ges.m.b.H + * Kufstein/Austria www.contec.at + * + * This driver was written for Contec Hypercontrol Micro9 Board: + * 1. CAN Controller is on Hypercontrol Micro9 CPU board + * 2. CAN Controller is on Hypercontrol Micro9 Eval board + * + * Contec uses this driver on their Hypercontrol Micro9 boards based on + * Cirrus Logic EP93XX, we have changed Adr-/Databus timing to use OKI ML9620. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + */ + +/*Versions: + - 0.01 Inital version Only worked CAN1 + - 0.02 CAN1/CAN2 worked, EVAL-board and CPU-BOARD Micro9 + - 0.03 changes from Michael Burian to correct: + errors, functions, adr/databus-problems - thanks a lot Michael + changed to correct name oki_ml9620_X and put in drivers/char/can/ + deleted some wrong statements + - 0.04 Michael Burian: read/write expect/return count in bytes now, cleanups + - 0.05 Michael Burian: use mux'd IRQs for both devices now + - 0.06 Michael Burian: only queue messages when /dev/can[01] is open + - 0.07 Michael Burian: implement non-blocking read + - 0.08 Michael Burian: replace completion with waitq, implement poll support +*/ + +/*Todo: + - Baudrate over /proc configure + - remove potential infinite loop in write / make write return immediately + (no longer wait for hardware, do this in background) + - implement fsync to allow waiting till hardware has written, if desired + - implement poll for write + - implement buffered write + - use kfifo for buffering read + - use kfifo for buffering write + - look for a more elegant solution for +*/ + +/* Enable for debugging */ +/*#define OKI_DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* offsetof(), etc. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "oki_ml9620.h" + +/* fops */ +static int oki_read(struct file *file, char *buf, size_t count,loff_t *ppos); +static int oki_write(struct file *file, const char *buf, size_t count,loff_t *ppos); +static int oki_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int oki_open(struct inode *inode, struct file *file); +static int oki_release(struct inode *inode, struct file *file); +static unsigned int oki_poll(struct file *file, poll_table *wait); + +/* IRQ */ +static irqreturn_t oki_irqhandler(int irq, void *dev_id, struct pt_regs *regs); + +/* CAN */ +static void hw_init(struct can_device *c); +static int set_baudrate(struct can_device *c, int baud); +static int check_status(struct can_device *c); +static int activate(struct can_device *c, unsigned char new_status); +static void store_data_in_buffer(struct can_device *c, struct can_msg *data); + +void store_data_in_buffer(struct can_device *c, struct can_msg *data) +{ + /* No need to fill up the queue when nobody cares. */ + if (atomic_read(&c->can_opened)) + return; + + DBG_OKI(KERN_INFO, "DATA Stored: ID 0x%x dlc 0x%x rtr 0x%x ext 0x%x DATA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",data->id,data->dlc,data->rtr,data->ext,data->data[0],data->data[1],data->data[2],data->data[3],data->data[4],data->data[5],data->data[6],data->data[7]); + + if (memcpy(&c->tail->msg, data, sizeof(struct can_msg)) != NULL) { + c->tail->next = kmalloc(sizeof(struct recbuf), GFP_KERNEL); + if (c->tail->next != NULL) { + c->tail->next->prev = c->tail; + c->tail = c->tail->next; + /* up sema to allow read */ + wake_up_interruptible(&c->rx_waitq); + return; + } + } +} + +int set_baudrate(struct can_device *c, int baud) +{ + unsigned long v = (unsigned long)c->virt_addr_can; + int index = 0; + + /* unlock hardware */ + c->reg.cancont = readb(v + CANCONT); + c->reg.cancont |= CONT_FLAG_INIT; + writeb(c->reg.cancont, v + CANCONT); + + c->reg.cancont = readb(v + CANCONT); + c->reg.cancont |= CONT_FLAG_CCE; + writeb(c->reg.cancont, v + CANCONT); + + DBG_OUT(KERN_DEBUG, ": /dev/can%d set_baudrate %dkb\n", c->minor, baud); + + /* Lookuptable baudrate => Timing array index */ + switch (baud){ + case 10: index = 0; break; + case 20: index = 1; break; + case 50: index = 2; break; + case 100: index = 3; break; + case 125: index = 4; break; + case 250: index = 5; break; + case 500: index = 6; break; + case 800: index = 7; break; + case 1000: index = 8; break; + default: index = 4; break; + } + + /* set baudrate */ + c->reg.canbitt[0] = bd_tbl[index].btiming0; + c->reg.canbitt[1] = bd_tbl[index].btiming1; + c->reg.canbpre = bd_tbl[index].bpre; + writeb(c->reg.canbitt[0], v + CANBITT0); + writeb(c->reg.canbitt[1], v + CANBITT1); + writeb(c->reg.canbpre, v + CANBPRE); + + /* lock hardware */ + c->reg.cancont = readb(v + CANCONT); + c->reg.cancont &= ~CONT_FLAG_CCE; + writeb(c->reg.cancont, v + CANCONT); + + c->reg.cancont = readb(v + CANCONT); + c->reg.cancont &= ~CONT_FLAG_INIT; + writeb(c->reg.cancont, v + CANCONT); + + return baud; +} + +void hw_init(struct can_device *c) +{ + unsigned char i; + unsigned long v = (unsigned long)c->virt_addr_can; + + spin_lock_init(&c->can_lock); + + c->reg.cancont |= CONT_FLAG_INIT; + writeb(c->reg.cancont, v + CANCONT); + + /* All Messages disabled with MsgVal = 0 */ + c->reg.if1id[3] = 0x00; + writeb(c->reg.if1id[3], v + IF1ID3); + + /* set, so that ID Register will get transfered */ + c->reg.if1cmask = 0x38; + writeb(c->reg.if1cmask, v + IF1CMASK); + + for (i = 1; i < (NUM_MSG + 1); i++) { + while ((c->reg.if1busy = readb(v + IF1BUSY)) & 0x80) ; + c->reg.if1creq = i; + writeb(c->reg.if1creq, v + IF1CREQ); + } + + for (i = CAN_STD_RX_BUFFER_START; i < (CAN_STD_RX_BUFFER_END + 1); i++) { + c->reg.if1id[3] = 0x80; + writeb(c->reg.if1id[3], v + IF1ID3); + + c->reg.if1id[2] = 0x00; + writeb(c->reg.if1id[2], v + IF1ID2); + + /*c->reg.if1mask[3] = 0x00; */ + c->reg.if1mask[3] = 0x20; + writeb(c->reg.if1mask[3], v + IF1MASK3); + + c->reg.if1mask[2] = 0x00; + writeb(c->reg.if1mask[2], v + IF1MASK2); + + /* Transfer Controll u. ID bits */ + c->reg.if1cmask = 0xF8; + writeb(c->reg.if1cmask, v + IF1CMASK); + + if (i == CAN_STD_RX_BUFFER_END) { + c->reg.if1mcont[0] = 0x80; /* FIFO END */ + writeb(c->reg.if1mcont[0], v + IF1MCONT0); + } else { + c->reg.if1mcont[0] = 0x00; + writeb(c->reg.if1mcont[0], v + IF1MCONT0); + } + + c->reg.if1mcont[1] = 0x14; /* this MsgObj trig. Int on Rx */ + writeb(c->reg.if1mcont[1], v + IF1MCONT1); + + c->reg.if1creq = i; + writeb(c->reg.if1creq, v + IF1CREQ); + + while ((c->reg.if1busy = readb(v + IF1BUSY) & 0x80)) ; + } + + /* Extended Frames */ + c->reg.if1id[3] = 0xC0; + writeb(c->reg.if1id[3], v + IF1ID3); + + c->reg.if1id[2] = 0x00; + writeb(c->reg.if1id[2], v + IF1ID2); + + c->reg.if1id[1] = 0x00; + writeb(c->reg.if1id[1], v + IF1ID1); + + c->reg.if1id[0] = 0x00; + writeb(c->reg.if1id[0], v + IF1ID0); + + c->reg.if1mask[3] = 0x00; + writeb(c->reg.if1mask[3], v + IF1MASK3); + + c->reg.if1mask[2] = 0x00; + writeb(c->reg.if1mask[2], v + IF1MASK2); + + c->reg.if1mask[1] = 0x00; + writeb(c->reg.if1mask[1], v + IF1MASK1); + + c->reg.if1mask[0] = 0x00; + writeb(c->reg.if1mask[0], v + IF1MASK0); + + /* Transfer Control and ID bits */ + c->reg.if1cmask = 0xF8; + writeb(c->reg.if1cmask, v + IF1CMASK); + + c->reg.if1mcont[0] = 0x80; /* EOB = 1 */ + writeb(c->reg.if1mcont[0], v + IF1MCONT0); + + c->reg.if1mcont[1] = 0x14; /* this MsgObj trig. Int on Rx */ + writeb(c->reg.if1mcont[1], v + IF1MCONT1); + + c->reg.if1creq = CAN_EXT_RX_BUFFER; + writeb(c->reg.if1creq, v + IF1CREQ); + + /* Wait till everything has been written */ + while ((c->reg.if1busy = readb(v + IF1BUSY) & 0x80)) ; + + c->reg.cancont = readl(v + CANCONT); + c->reg.cancont |= CONT_FLAG_IE + CONT_FLAG_SIE + CONT_FLAG_EIE; + writeb(c->reg.cancont, v + CANCONT); + + /*End Init */ + c->reg.cancont = readb(v + CANCONT); + c->reg.cancont &= ~CONT_FLAG_INIT; + writeb(c->reg.cancont, v + CANCONT); + + /* store baudrate default 125 kBit/sec */ + c->baudrate = (unsigned short)set_baudrate(c, 125); + + /* reset overrun counter */ + c->overrun = 0; +} + +static irqreturn_t oki_irqhandler(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned short int_type = 0; + unsigned short i; + unsigned char stat_reg, k; + struct can_msg msg; + struct can_device *c = dev_id; + unsigned long v = (unsigned long)c->virt_addr_can; + int minor = c->minor; + unsigned long flags; + int irq_count = 0; + + spin_lock_irqsave(&c->can_lock, flags); + + /* + * read can interrupt register1, + * we only want to detect if it is a status interrupt! + */ + int_type += (readb(v + CANINT1) << 8); + + DBG_OKI(KERN_ERR, ": /dev/can%d IRQ 0x%x occured, virt addr:0x%08x\n",minor,int_type,v); + + /* STATUS IRQ */ + if (int_type & 0x8000) { + c->reg.canstat = stat_reg = readb(v + CANSTAT); + c->reg.canstat = 0x00; + writeb(c->reg.canstat, v + CANSTAT); + + DBG_OKI(KERN_ERR, "/dev/can%d IRQ is STATUS IRQ BSTAT is 0x%x\n",minor,stat_reg); + + /*if ((stat_reg & 0xE0) == 0xE0) */ + /* changed back to get bus off state */ + if ((stat_reg & 0x80) == 0x80) { + DBG_OKI(KERN_ERR, ": /dev/can%d IRQ is BUS OFF\n",minor); + /* set "Bus off" flag */ + c->status |= CAN_STS_BUS_OFF; + /* clear flag */ + c->status &= ~CAN_STS_TXOK; + + c->last_error_code = 10; + } else { + /* clear "Bus off" flag */ + c->status &= ~CAN_STS_BUS_OFF; + } + + if ((stat_reg & 0x60) == 0x60) { + DBG_OKI(KERN_ERR, ": /dev/can%d IRQ is STATUS CAN_STS_WARNING %x \n",minor,(stat_reg & 0x7)); + c->last_error_code = (stat_reg & 0x7); + /* set WARNING flag */ + c->status |= CAN_STS_WARNING; + } else { + /* clear WARNING flag */ + c->status &= ~CAN_STS_WARNING; + } + + /* TXOK */ + if ((stat_reg & 0x08) == 0x08) { + DBG_OKI(KERN_ERR, ": /dev/can%d IRQ is STATUS TXOK\n",minor); + + /* clear error */ + c->last_error_code_write = 0; + /* clear error --> no error */ + c->last_error_code = 0; + /* clear error var for debug */ + c->last_error_code_debug = 0; + } + + /* ROK */ + if ((stat_reg & 0x10) == 0x10) { + DBG_OKI(KERN_ERR, ": /dev/can%d IRQ is STATUS IRQ RXOK\n",minor); + + /* clear error --> no error */ + c->last_error_code = 0; + /* clear error var for debug */ + c->last_error_code_debug = 0; + } + + if((c->last_error_code >= 1 && c->last_error_code <= 7) || c->last_error_code == 10){ + if(c->last_error_code < 10 && ((stat_reg & 0x80) == 0x80) && (c->last_error_code != c->last_error_code_debug)){ + c->last_error_code_debug = 10; + DBG_OUT(KERN_ERR, ": /dev/can%d Error BUS OFF, do ioctl STATUS\n",minor); + + } + + if (c->last_error_code != c->last_error_code_debug) { + c->last_error_code_debug = c->last_error_code; + DBG_OUT(KERN_ERR, ": /dev/can%d %s\n",minor,err[c->last_error_code]); + } + + if (c->last_error_code > 0) { + /* switch off controller, warning state is higher than 1 */ + /* so CAN message has a form error or was not */ + /* acknwledged by other devices or we are in bus off state */ + activate(c, CAN_STS_CNTRL_OFF); + } + goto out; + } + + DBG_OKI(KERN_ERR, ": /dev/can%d IRQ is STATUS IRQ END \n",minor); + } + + /* read next IRQ */ + /* only read can interrupt register0, we don't want detect a status interrupt here! */ + int_type = readb(v + CANINT0); + + while (int_type && (irq_count++ < OKI_CAN_MAX_IRQS)) { + switch (int_type) { + case CAN_TX_BUFFER: + case CAN_RTX_BUFFER: + + DBG_OKI(KERN_ERR, "/dev/can%d IRQ is CAN_TX_BUFFER/CAN_RTX_BUFFER IRQ 0x%x\n",minor,int_type); + while ((c->reg.if1busy = readb(v + IF1BUSY)) & 0x80) ; + + /* Clear Int Pnd */ + c->reg.if1cmask = 0x08; + writeb(c->reg.if1cmask, v + IF1CMASK); + + c->reg.if1creq = (unsigned char)int_type; + writeb(c->reg.if1creq, v + IF1CREQ); + + CAN_DEBUG(IF1CMASK,"CAN_TX_BUFFER/CAN_RTX_BUFFER IF1CMASK"); + CAN_DEBUG(IF1CREQ,"CAN_TX_BUFFER/CAN_RTX_BUFFER IF1CREQ"); + + /* Wait till everything has been written */ + while ((c->reg.if1busy = readb(v + IF1BUSY)) & 0x80) ; + c->status |= CAN_STS_TXOK; + c->tx_in_progress = 0; + DBG_OKI(KERN_ERR, "/dev/can%d IRQ is CAN_TX_BUFFER/CAN_RTX_BUFFER IRQ 0x%x END\n",minor,int_type); + break; + case CAN_STD_RX_BUFFER_START: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case CAN_STD_RX_BUFFER_END: + DBG_OKI(KERN_ERR, "/dev/can%d IRQ is CAN_STD_RX_BUFFER_START/CAN_STD_RX_BUFFER_END IRQ 0x%x\n",minor,int_type); + do { + while ((c->reg.if2busy = readb(v + IF2BUSY)) & 0x80); + /* Get all unsigned chars */ + c->reg.if2cmask = 0x3F; + writeb(c->reg.if2cmask, v + IF2CMASK); + c->reg.if2creq = (unsigned char)int_type; + writeb(c->reg.if2creq, v + IF2CREQ); + + /* Wait till everything has been written */ + while ((c->reg.if2busy = readb(v + IF2BUSY)) & 0x80); + /* is NewData set? */ + if ((c->reg.if2mcont[1] = readb(v + IF2MCONT1)) & 0x80) { + /* Extended Frame? */ + if ((c->reg.if2id[3] = readb(v + IF2ID3)) & 0x40) + msg.ext = 1; + else + msg.ext = 0; + + msg.dlc = ((c->reg.if2mcont[0] = readb(v + IF2MCONT0)) & 0x0F); + msg.id = (((c->reg.if2id[3] = readb(v + IF2ID3)) & 0x1F) << 6); + msg.id += ((c->reg.if2id[2] = readb(v + IF2ID2)) >> 2); + + k = (unsigned char)((msg.dlc <= 8) ? (msg.dlc) : 8); + for (i = 0; i < k; i++) + msg.data[i] = c->reg.if2data[i] = readb(v + IF2DATA0 +i); + + /* Is MsgLost set? */ + if ((c->reg.if2mcont[1] = readb(v + IF2MCONT1)) & 0x40) + c->status |= CAN_STS_OVERRUN; + else + c->status &= ~CAN_STS_OVERRUN; + /* is DIR set? */ + if ((c->reg.if2id[3] = readb(v + IF2ID3)) & 0x20) + msg.rtr = 1; + else + msg.rtr = 0; + /* clear MsgLst */ + c->reg.if2mcont[1] &= 0xBF; + writeb(c->reg.if2mcont[1], v + IF2MCONT1); + c->reg.if2cmask = 0x10; + writeb(c->reg.if2cmask, v + IF2CMASK); + c->reg.if2creq = (unsigned char)int_type; + writeb(c->reg.if2creq, v + IF2CREQ); + + /* Wait till everything has been written */ + while ((c->reg.if2busy = readb(v + IF2BUSY)) & 0x80); + + /* Store Data */ + store_data_in_buffer(c,&msg); + } else { + /* exit while loop */ + break; + } + int_type++; + } + while (int_type <= CAN_STD_RX_BUFFER_END); + DBG_OKI(KERN_ERR, " /dev/can%d IRQ is CAN_STD_RX_BUFFER_START/CAN_STD_RX_BUFFER_END IRQ 0x%x\n",minor,int_type); + break; + /* Extended Frames */ + case CAN_EXT_RX_BUFFER: + DBG_OKI(KERN_ERR, " /dev/can%d IRQ is CAN_EXT_RX_BUFFER IRQ 0x%x\n",minor,int_type); + while ((c->reg.if2busy = readb(v + IF2BUSY)) & 0x80); + /* Get all unsigned chars */ + c->reg.if2cmask = 0x3F; + writeb(c->reg.if2cmask, v + IF2CMASK); + c->reg.if2creq = (unsigned char)int_type; + writeb(c->reg.if2creq, v + IF2CREQ); + /* Wait till everything has been written */ + while ((c->reg.if2busy = readb(v + IF2BUSY)) & 0x80) ; + /* is NewData set? */ + if ((c->reg.if2mcont[1] = readb(v + IF2MCONT1)) & 0x80) { + /* Extended Frame? */ + if ((c->reg.if2id[3] = readb(v + IF2ID3)) & 0x40) + msg.ext = 1; + else + msg.ext = 0; + + msg.dlc = ((c->reg.if2mcont[0] = readb(v + IF2MCONT0)) & 0x0F); + msg.id = c->reg.if2id[0] = readb(v + IF2ID0); + msg.id += ((c->reg.if2id[1] = readb(v + IF2ID1)) << 8); + msg.id += ((c->reg.if2id[2] = readb(v + IF2ID2)) << 16); + msg.id += (((c->reg.if2id[3] = readb(v + IF2ID2)) & 0x1F) << 24); + + k = (unsigned char)((msg.dlc <= 8) ? (msg.dlc) : 8); + for (i = 0; i < k; i++) + msg.data[i] = c->reg.if2data[i] = readb(v + IF2DATA0 + i); + /* Is MsgLost set? */ + if ((c->reg.if2mcont[1] = readb(v + IF2MCONT1)) & 0x40) + c->status |= CAN_STS_OVERRUN; + else + c->status &= ~CAN_STS_OVERRUN; + + /* clear MsgLst */ + c->reg.if2mcont[1] &= 0xBF; + writeb(c->reg.if2mcont[1], v + IF2MCONT1); + c->reg.if2cmask = 0x10; + writeb(c->reg.if2cmask, v + IF2CMASK); + c->reg.if2creq = (unsigned char)int_type; + writeb(c->reg.if2creq, v + IF2CREQ); + + /* Wait till everything has been written */ + while ((c->reg.if2busy = readb(v + IF2BUSY)) & 0x80); + /* Store Data */ + store_data_in_buffer(c, &msg); + } + DBG_OKI(KERN_ERR, " /dev/can%d IRQ is CAN_EXT_RX_BUFFER IRQ 0x%x\n",minor,int_type); + break; + default: + DBG_OKI(KERN_ERR, " /dev/can%d IRQ is default 0x%x\n",minor,int_type); + goto out; + break; + } + /* read next IRQ */ + /* only read can interrupt register0, we don't want detect a status interrupt here! */ + int_type = readb(v + CANINT0); + } /* while */ +out: + spin_unlock_irqrestore(&c->can_lock, flags); + return IRQ_HANDLED; +} + +static struct file_operations oki_fops = { + .owner = THIS_MODULE, + .read = oki_read, + .write = oki_write, + .ioctl = oki_ioctl, + .open = oki_open, + .release = oki_release, + .poll = oki_poll, +}; + +int oki_read(struct file *file, char *buf, size_t count, loff_t * ppos) +{ + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); + struct can_device *c = info_can[minor]; + int ret = 0; + int i, tmp; + + if (count < sizeof(struct can_msg)) + return -EINVAL; + + if ((c->head == c->tail) && (file->f_flags & O_NONBLOCK)) + return -EAGAIN; + + ret = wait_event_interruptible(c->rx_waitq, c->head != c->tail); + if (ret) + return -ERESTARTSYS; + + for (i = 0; i < (count / sizeof(struct can_msg)); i++) { + if (c->head == c->tail) + break; + + tmp = copy_to_user(buf, &c->head->msg, sizeof(struct can_msg)); + if (tmp > 0) { + printk("copy_to_user could not copy %d bytes", ret); + ret = -EIO; + } else { + buf += sizeof(struct can_msg); + ret += sizeof(struct can_msg); + } + + c->head = c->head->next; + kfree(c->head->prev); + } + + return ret; +} + +int oki_write(struct file *file, const char *buf, size_t count, loff_t * ppos) +{ + unsigned char i; /* counter, temp var */ + unsigned char k; /* counter */ + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); + struct can_device *c = info_can[minor]; + unsigned long v = (unsigned long)c->virt_addr_can; + struct can_msg tmp; + struct can_msg *txbuf = &tmp; + + if (!buf || !count) + return 0; + + /* be stricter than in read here, require multiples of whole msgs */ + if (count % sizeof(struct can_msg)) { + printk("count must be N * sizeof(struct can_msg)!\n"); + return -EINVAL; + } + + /* + * This can be removed as soon as we have implemented support for + * writing multiple messages + */ + if (count != sizeof(struct can_msg)) { + printk("FIXME: support writing multiple messages at once!\n"); + return -EINVAL; + } + + if (0 != copy_from_user(txbuf, buf, count)) { + printk("%s: Error: copy from user failed!\n", __FUNCTION__); + return -EIO; + } + + DBG_OKI(KERN_ERR, ": WRITE minor %d\n", c->minor); + DBG_OKI(KERN_ERR, ": WRITE virt 0x%x\n", c->virt_addr_can); + DBG_OKI(KERN_ERR, ": WRITE id %d\n", txbuf->id); + DBG_OKI(KERN_ERR, ": WRITE dlc %d\n", txbuf->dlc); + DBG_OKI(KERN_ERR, ": WRITE rtr %d\n", txbuf->rtr); + DBG_OKI(KERN_ERR, ": WRITE ext %d\n", txbuf->ext); + for (i = 0; i < 8; i++) + DBG_OKI(KERN_ERR, ": WRITE data[%d] %d\n", i, txbuf->data[i]); + + c->reg.cancont = readb(v + CANCONT); + + CAN_DEBUG(CANCONT, "CANCONT"); + + if ((c->reg.cancont & CONT_FLAG_INIT) == CONT_FLAG_INIT) { + if (c->last_error_code_write < 1) { + c->last_error_code_write = 1; + DBG_OUT(KERN_ERR, ": /dev/can%d not initalised or switched off, do ioctl: COMMAND CAN_STS_CNTRL_ON \n",minor ); + } + return -EAGAIN; + } + + /* Check the status, so we can handle warning and bus off state */ + check_status(c); + + if (c->status == CAN_STS_WARNING) { + if (c->last_error_code_write < 2) { + c->last_error_code_write = 2; + DBG_OUT(KERN_ERR, ": /dev/can%d is in WARNING State, do ioctl STATUS\n",minor ); + } + return -EAGAIN; + } + + if (c->status == CAN_STS_BUS_OFF) { + if (c->last_error_code_write < 3) { + c->last_error_code_write = 3; + DBG_OUT(KERN_ERR, ": /dev/can%d is in BUS OFF State, do ioctl STATUS\n",minor ); + } + return -EAGAIN; + } + + c->status &= ~CAN_STS_TXOK; + + /* Wait till everything has been written */ + if (c->tx_in_progress) { + DBG_OKI(KERN_ERR, ": WRITE CAN%d BUSY\n", minor); + return -EBUSY; + } else { + c->tx_in_progress = 1; + CAN_DEBUG(IF1BUSY, " WRITE 2 for while IF1BUSY"); + while ((c->reg.if1busy = readb(v + IF1BUSY)) & 0x80) ; + + /* set, so that ID Register will get transfered */ + c->reg.if1cmask = 0xB7; + writeb(c->reg.if1cmask, v + IF1CMASK); + CAN_DEBUG(IF1CMASK, " WRITE 3 for while IF1CMASK"); + } + + if (txbuf->ext == 0) { + /* DIR and WR */ + c->reg.if1id[3] = 0xA0; + c->reg.if1id[3] |= (unsigned char)((txbuf->id >> 6) & 0x1F); + DBG_OKI(KERN_ERR, "WRITE c->reg.if1id[3] 0x%x\n",c->reg.if1id[3]); + writeb(c->reg.if1id[3], v + IF1ID3); + CAN_DEBUG(IF1ID3, " WRITE 4 IF1ID3"); + c->reg.if1id[2] = (unsigned char)((txbuf->id << 2) & 0xFC); + DBG_OKI(KERN_ERR, "WRITE c->reg.if1id[2] 0x%x\n",c->reg.if1id[2]); + writeb(c->reg.if1id[2], v + IF1ID2); + CAN_DEBUG(IF1ID2, "WRITE 4 IF1ID2"); + } else { + /* extended Frame */ + c->reg.if1id[3] = 0xE0; + c->reg.if1id[3] += (unsigned char)((txbuf->id >> 24) & 0x1F); + c->reg.if1id[2] = (unsigned char)((txbuf->id >> 16) & 0xFF); + c->reg.if1id[1] = (unsigned char)((txbuf->id >> 8) & 0xFF); + c->reg.if1id[0] = (unsigned char)(txbuf->id & 0xFF); + writeb(c->reg.if1id[3], v + IF1ID3); + CAN_DEBUG(IF1ID3, "WRITE 4 IF1ID3"); + writeb(c->reg.if1id[2], v + IF1ID2); + CAN_DEBUG(IF1ID2, "WRITE 4 IF1ID2"); + writeb(c->reg.if1id[1], v + IF1ID1); + CAN_DEBUG(IF1ID1, "WRITE 4 IF1ID1"); + writeb(c->reg.if1id[0], v + IF1ID0); + CAN_DEBUG(IF1ID1, "WRITE 4 IF1ID1"); + } + + k = (unsigned char)(((txbuf->dlc) <= 8) ? (txbuf->dlc) : 8); + for (i = 0; i < k; i++) { + c->reg.if1data[i] = txbuf->data[i]; + writeb(c->reg.if1data[i], v + IF1DATA0 + i); + DBG_OKI(KERN_ERR, ": WRITE in for data[%d] %d\n",i,txbuf->data[i]); + CAN_DEBUG(IF1DATA0 + i, "WRITE 4 IF1DATA0 + i"); + } + /* End of Buffer (EOB) */ + + c->reg.if1mcont[0] = 0x80 + (txbuf->dlc & 0x0F); + DBG_OKI(KERN_ERR, ": WRITE 5 if1mcont[0] 0x%x\n", c->reg.if1mcont[0]); + writeb(c->reg.if1mcont[0], v + IF1MCONT0); + CAN_DEBUG(IF1MCONT0, "WRITE 5 IF1MCONT0"); + + if (txbuf->rtr == 1) { + c->reg.if1id[3] &= 0xDF; + DBG_OKI(KERN_ERR, ": WRITE 6 if1id[3] 0x%x\n", c->reg.if1id[3]); + writeb(c->reg.if1id[3], v + IF1ID3); + CAN_DEBUG(IF1ID3, "WRITE 6 IF1ID3"); + /* TXIE, TXRqst and RXIE */ + c->reg.if1mcont[1] = 0x0D; + DBG_OKI(KERN_ERR, ": WRITE 6 if1mcont[1] 0x%x\n",c->reg.if1mcont[1]); + writeb(c->reg.if1mcont[1], v + IF1MCONT1); + CAN_DEBUG(IF1MCONT1, "WRITE 6 IF1MCONT1"); + c->reg.if1creq = CAN_RTX_BUFFER; + DBG_OKI(KERN_ERR, ": WRITE 6 if1creq 0x%x\n", c->reg.if1creq); + writeb(c->reg.if1creq, v + IF1CREQ); + CAN_DEBUG(IF1CREQ, "WRITE 6 IF1CREQ"); + } else { + c->reg.if1mcont[1] = 0x09; + DBG_OKI(KERN_ERR, ": WRITE 6 if1mcont[1] 0x%x\n",c->reg.if1mcont[1]); + writeb(c->reg.if1mcont[1], v + IF1MCONT1); + CAN_DEBUG(IF1MCONT1, "WRITE 6 IF1MCONT1"); + c->reg.if1creq = CAN_TX_BUFFER; + DBG_OKI(KERN_ERR, ": WRITE 6 if1creq 0x%x\n", c->reg.if1creq); + writeb(c->reg.if1creq, v + IF1CREQ); + CAN_DEBUG(IF1CREQ, "WRITE 6 IF1CREQ"); + } + return count; +} + +int oki_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + unsigned int minor = iminor(inode); + struct can_device *c = info_can[minor]; /* better ideas than using globals anyone? */ + int ret = -ENOIOCTLCMD; + int new_options = 0; + void __user *argp = (void __user *)arg; + int __user *p = argp; + int cntr_ret; + + switch (cmd) { + case COMMAND: + { + if (get_user(new_options, p) != 0) + return -EFAULT; + + DBG_OKI(KERN_ERR, ": IOCTL COMMAND WITH %d\n", new_options); + cntr_ret = activate(c, new_options); + if ((ret = put_user(cntr_ret, (int __user *)argp)) == 0) + return 0; + else + return ret; + + break; + } + case CONFIG: + { + if (get_user(new_options, p) != 0) + return -EFAULT; + + cntr_ret = set_baudrate(c, new_options); + if ((ret = put_user(cntr_ret, (int __user *)argp)) == 0) + return 0; + else + return ret; + + break; + } + case SEND: + break; + case RECEIVE: + break; + case STATUS: + { + int cntr_ret; + /* Check status */ + cntr_ret = check_status(c); + if ((ret = put_user(cntr_ret, (int __user *)argp)) == 0) + return 0; + else + return ret; + break; + } + default: + return -ENOIOCTLCMD; + break; + } + + return -ENOIOCTLCMD; +} + +static unsigned int oki_poll(struct file *file, poll_table * wait) +{ + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); + struct can_device *c = info_can[minor]; + unsigned int mask = 0; + + poll_wait(file, &c->rx_waitq, wait); + if (c->head != c->tail) + mask |= POLLIN | POLLRDNORM; + return mask; +} + +int check_status(struct can_device *c) +{ + int stat_reg; + unsigned long v = (unsigned long)c->virt_addr_can; + + stat_reg = readb(v + CANSTAT); + DBG_OKI(KERN_DEBUG, "check_status canstat 0x%x\n", stat_reg); + + /* Bus is in "Error Passive" state */ + if ((stat_reg & 0x20) == 0) { + c->status &= ~CAN_STS_WARNING; + c->status &= ~CAN_STS_BUS_OFF; + } + + if ((stat_reg & 0x60) == 0x60) { + if (c->last_error_code != (stat_reg & 0x7)) { + c->last_error_code = (stat_reg & 0x7); + } + c->status |= CAN_STS_WARNING; + } + + if ((stat_reg & 0x80) == 0x80) { + if (c->last_error_code < 10) { + c->last_error_code = 10; + } + c->status |= CAN_STS_BUS_OFF; + } + + /* clear overrun */ + c->status &= ~CAN_STS_OVERRUN; + return c->status; +} + +int activate(struct can_device *c, unsigned char new_status) +{ + unsigned long v = (unsigned long)c->virt_addr_can; + + switch (new_status) { + case CAN_STS_CNTRL_OFF: + do { + c->reg.cancont |= CONT_FLAG_INIT; + writeb(c->reg.cancont, v + CANCONT); + } + while (!((c->reg.cancont = readb(v + CANCONT)) & CONT_FLAG_INIT)); + + c->status |= CAN_STS_RESET; + + DBG_OKI(KERN_DEBUG, " /dev/can%d activate CAN_STS_CNTRL_OFF CANCONT 0x%x\n",c->minor,c->reg.cancont); + break; + case CAN_STS_CNTRL_ON: + do { + c->reg.cancont &= ~CONT_FLAG_INIT; + writeb(c->reg.cancont, v + CANCONT); + } + while (((c->reg.cancont = readb(v + CANCONT)) & CONT_FLAG_INIT)); + + c->status &= ~CAN_STS_RESET; + + DBG_OKI(KERN_DEBUG, " /dev/can%d activate CAN_STS_CNTRL_ON CANCONT 0x%x\n",c->minor,c->reg.cancont); + break; + case CAN_STS_CNTRL_SLEEP: + break; + case CAN_STS_CNTRL_AWAKE: + break; + default: + break; + } + + return c->status; +} + +int oki_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct can_device *c = info_can[minor]; /* better ideas than using globals anyone? */ + + if (!atomic_dec_and_test(&c->can_opened)) { + DBG_OUT(KERN_ERR, ": /dev/can%d already opened.\n", minor); + atomic_inc(&c->can_opened); + return -EBUSY; + } + return 0; +} + +int oki_release(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct can_device *c = info_can[minor]; /* better ideas than using globals anyone? */ + + atomic_dec(&c->can_opened); + if (!atomic_inc_and_test(&c->can_opened)) { + DBG_OUT(KERN_ERR, ": /dev/can%d open, busy.\n", minor); + return -EBUSY; + } + + atomic_inc(&c->can_opened); + return 0; +} + +int can_register(struct can_device *c) +{ + atomic_set(&c->can_opened, 1); + + /* map memory */ + c->virt_addr_can = ioremap(c->phys_addr_can, c->phys_size_can); + if (!c->virt_addr_can) { + DBG_OUT(KERN_ERR, ": Unable to remap /dev/can%d memory.\n", c->minor); + return -ENOMEM; + } + + DBG_OUT(KERN_INFO, ": remap /dev/can%d memory physical 0x%x to virtual 0x%x.\n",c->minor,c->phys_addr_can,c->virt_addr_can); + + /* Message buffers */ + c->tail = kzalloc(sizeof(struct recbuf), GFP_KERNEL); + c->head = c->tail; + + /* CAN init */ + hw_init(c); + + /* waitq init */ + init_waitqueue_head(&c->rx_waitq); + + /* Install IRQ handler */ + if(0 != request_irq(c->irq, oki_irqhandler, c->irq_flags, "OKI_CAN", (void *)c)){ + DBG_OUT(KERN_ERR, ": /dev/can%d cannot install IRQ-handler\n",c->minor); + return -ENOMEM; + } + + DBG_OUT(KERN_INFO, ": /dev/can%d IRQ-handler installed.\n", c->minor); + + return 0; +} + +int __init oki_init(void) +{ + can_register(info_can[0]); +#ifdef CONFIG_OKI_CAN_ML9620_2DEV + can_register(info_can[1]); +#endif + + /* Register char device */ + if (register_chrdev(OKI_CAN_CHAR_MAJOR, OKI_CAN_DEVICE_NAME, &oki_fops)) { + DBG_OUT(KERN_ERR, "Can't allocate major number %d for CAN driver.\n",OKI_CAN_CHAR_MAJOR); + return -EIO; + } + + DBG_OUT(KERN_INFO, ": Version: " OKI_CAN_VERSION " registered successfully.\n"); + /*DBG_OUT(KERN_INFO, "Installed %d IRQ handlers for %d CAN devices.\n",irq_nr,can_dev); */ + + printk(KERN_INFO "Contec Steuerungstechnik und Automation Ges.m.b.H\n"); + printk(KERN_INFO "Waldeck 1 / 6330 Kufstein / Austria\n"); + + return 0; +} + +module_init(oki_init); + +void unregister_can(struct can_device *c) +{ + DBG_OUT(KERN_INFO, ": unregister /dev/can%d .\n", c->minor); + free_irq(c->irq, (void *)c); + + if (c->virt_addr_can != NULL) { + iounmap(c->virt_addr_can); + } else { + DBG_OUT(KERN_ERR, ": /dev/can%d was not mapped, skipping iounmap!\n", c->minor); + } +} + +void __exit oki_exit(void) +{ + unregister_can(info_can[0]); +#ifdef CONFIG_OKI_CAN_ML9620_2DEV + unregister_can(info_can[1]); +#endif + unregister_chrdev(OKI_CAN_CHAR_MAJOR, OKI_CAN_DEVICE_NAME); +} + +module_exit(oki_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Manfred Gruber "); +MODULE_DESCRIPTION("OKI ML9620 CAN Driver"); diff --git a/drivers/char/can/oki_ml9620.h b/drivers/char/can/oki_ml9620.h new file mode 100644 index 0000000..f8ece1e --- /dev/null +++ b/drivers/char/can/oki_ml9620.h @@ -0,0 +1,397 @@ +/* + * drivers/char/can/oki_ml9620_core.h + * + * OKI ML9620 CAN Controler driver + * + * Author: Manfred Gruber + * + * Copyright 2004 (c) Manfred Gruber + * Copyright 2004 (c) Contec Steuerungstechnik & Automation Ges.m.b.H + * Kufstein/Austria www.contec.at + * + * This driver was written for Contec Hypercontrol Micro9 Board: + * 1. CAN Controller is on Hypercontrol Micro9 CPU board + * 2. CAN Controller is on Hypercontrol Micro9 Eval board + * + * Contec uses this driver on their Hypercontrol Micro9 boards based on + * Cirrus Logic EP93XX,we have changed Adr-/Databus timinig to use OKI ML9620. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + */ + +#ifndef _OKI_ML9620_CORE_H_ +#define _OKI_ML9620_CORE_H_ + +#include +#include + +#define OKI_CAN_CHAR_MAJOR 91 +#define OKI_CAN_DEVICE_NAME "oki_ml9260" +#define OKI_CAN_VERSION "0.08" + +#define OKI_CAN_MAX_IRQS 20 +#define PHYS_SIZE_CAN 0x00000100 + +/* Contec */ +#ifdef CONFIG_OKI_CAN_ML9620_MICRO9 +#define CAN_CLOCK_8MHZ +#define PHYS_ADDR_CAN0 0x20000000 +#define PHYS_ADDR_CAN1 0x21000000 +#define IRQ_CAN0 GPIO_IRQ4 +#define IRQ_CAN1 GPIO_IRQ10 +#ifdef CONFIG_GENERIC_HARDIRQS +#define IRQ_FLAGS_CAN0 (SA_INTERRUPT) +#define IRQ_FLAGS_CAN1 (SA_INTERRUPT) +#else +#define IRQ_FLAGS_CAN0 (SA_INTERRUPT | SA_SHIRQ) +#define IRQ_FLAGS_CAN1 (SA_INTERRUPT | SA_SHIRQ) +#endif +#endif /* CONFIG_OKI_CAN_ML9620_MICRO9 */ + +/* Gassner */ +#ifdef CONFIG_OKI_CAN_ML9620_GASSNER +#define CAN_CLOCK_8MHZ +#define PHYS_ADDR_CAN0 0x10000000 +#define PHYS_ADDR_CAN1 0x30000000 +#define IRQ_CAN0 GPIO_IRQ6 /* Line EGPIO6 (multiplexed) */ +#define IRQ_CAN1 GPIO_IRQ13 /* Line EGPIO13 (multiplexed) */ +#define IRQ_FLAGS_CAN0 (SA_INTERRUPT | SA_SHIRQ) +#define IRQ_FLAGS_CAN1 (SA_INTERRUPT | SA_SHIRQ) +#endif /* CONFIG_OKI_CAN_ML9620_GASSNER */ + +char *err[7] = { + "Warning 1, Stuff Error", + "Warning 2, Form Error", + "Warning 3, ACK Error", + "Warning 4, Bits 1 Error", + "Warning 5, Bits 0 Error", + "Warning 6, CRC Error", + "Warning 7, MCU has produced this Error", +}; + +#define DRIVER_MAX_MINOR 2 + +struct CANML9620REG { + unsigned char cancont; + unsigned char reserve1; + unsigned char canstat; + unsigned char reserve2; + unsigned char cantxerrc; + unsigned char canrxerrc; + unsigned char canbitt[2]; + unsigned char canint[2]; + unsigned char canopt; + unsigned char reserve3; + unsigned char canbpre; + unsigned char reserve4[3]; + + unsigned char if1creq; + unsigned char if1busy; + unsigned char if1cmask; + unsigned char reserve5; + unsigned char if1mask[4]; + unsigned char if1id[4]; + unsigned char if1mcont[2]; + unsigned char if1data[8]; + unsigned char reserve6[26]; + + unsigned char if2creq; + unsigned char if2busy; + unsigned char if2cmask; + unsigned char reserve7; + unsigned char if2mask[4]; + unsigned char if2id[4]; + unsigned char if2mcont[2]; + unsigned char if2data[8]; + unsigned char reserve8[42]; + + unsigned char cantreq[4]; + unsigned char reserve9[12]; + + unsigned char canndata[4]; + unsigned char reserve10[12]; + + unsigned char canipend[4]; + unsigned char reserve11[12]; + + unsigned char canmval[4]; + unsigned char reserve12[12]; + + unsigned char canstby; + unsigned char reserve13[12]; +}; + +#define CANCONT 0x0 +#define RESERVE1 0x1 +#define CANSTAT 0x2 +#define RESERVE2 0x3 +#define CANTXERRC 0x4 +#define CANRXERRC 0x5 +#define CANBITT0 0x6 +#define CANBITT1 0x7 +#define CANINT0 0x8 +#define CANINT1 0x9 +#define CANOPT 0xA + +#define CANBPRE 0xC + +#define IF1CREQ 0x10 +#define IF1BUSY 0x11 +#define IF1CMASK 0x12 + +#define IF1MASK0 0x14 +#define IF1MASK1 0x15 +#define IF1MASK2 0x16 +#define IF1MASK3 0x17 + +#define IF1ID0 0x18 +#define IF1ID1 0x19 +#define IF1ID2 0x1A +#define IF1ID3 0x1B + +#define IF1MCONT0 0x1C +#define IF1MCONT1 0x1D + +#define IF1DATA0 0x1E +#define IF1DATA1 0x1F +#define IF1DATA2 0x20 +#define IF1DATA3 0x21 +#define IF1DATA4 0x22 +#define IF1DATA5 0x23 +#define IF1DATA6 0x24 +#define IF1DATA7 0x25 + +#define IF2CREQ 0x40 +#define IF2BUSY 0x41 +#define IF2CMASK 0x42 + +#define IF2MASK0 0x44 +#define IF2MASK1 0x45 +#define IF2MASK2 0x46 +#define IF2MASK3 0x47 + +#define IF2ID0 0x48 +#define IF2ID1 0x49 +#define IF2ID2 0x4A +#define IF2ID3 0x4B + +#define IF2MCONT0 0x4C +#define IF2MCONT1 0x4D + +#define IF2DATA0 0x4E +#define IF2DATA1 0x4F +#define IF2DATA2 0x50 +#define IF2DATA3 0x51 +#define IF2DATA4 0x52 +#define IF2DATA5 0x53 +#define IF2DATA6 0x54 +#define IF2DATA7 0x55 + +#define CANTREQ0 0x80 +#define CANTREQ1 0x81 +#define CANTREQ2 0x82 +#define CANTREQ3 0x83 + +#define CANNDATA0 0x90 +#define CANNDATA1 0x91 +#define CANNDATA2 0x92 +#define CANNDATA3 0x93 + +#define CANIPEND0 0xA0 +#define CANIPEND1 0xA1 +#define CANIPEND2 0xA2 +#define CANIPEND3 0xA3 + +#define CANMVAL0 0xB0 +#define CANMVAL1 0xB1 +#define CANMVAL2 0xB2 +#define CANMVAL3 0xB3 + +#define CANSTBY 0xC0 +struct recbuf { + struct can_msg msg; + struct recbuf *next; + struct recbuf *prev; +}; + +struct can_device { + /* Phys addresses and size */ + unsigned long phys_addr_can; + unsigned long phys_size_can; + /* IRQ */ + unsigned int irq; + unsigned long irq_flags; + + /* Device node */ + int minor; + + /* waitqueue for read, poll */ + wait_queue_head_t rx_waitq; + + atomic_t can_opened; + + struct recbuf *tail; + struct recbuf *head; + + /* Virt addresses size */ + unsigned char __iomem *virt_addr_can; + + /* CAN-Baustein */ + struct CANML9620REG reg; + unsigned short baudrate; /* baudrate */ + unsigned short overrun; /* overrun counter */ + struct can_msg msg; /* CAN message buffer */ + int status; /* actual CAN status */ + int last_error_code_write; + unsigned char tx_in_progress; + unsigned char last_error_code; /* LEC */ + unsigned char last_error_code_debug; /* LEC when printed out */ + spinlock_t can_lock; +}; + +/* Global Device Struct can0 */ +static struct can_device info_can0 = { + .phys_addr_can = PHYS_ADDR_CAN0, + .phys_size_can = PHYS_SIZE_CAN, + .irq = IRQ_CAN0, + .minor = 0, + .irq_flags = IRQ_FLAGS_CAN0, + .can_opened = ATOMIC_INIT(1), + .status = CAN_STS_NORMAL, +}; + +/* Global Device Struct can1 */ +static struct can_device info_can1 = { + .phys_addr_can = PHYS_ADDR_CAN1, + .phys_size_can = PHYS_SIZE_CAN, + .irq = IRQ_CAN1, + .irq_flags = IRQ_FLAGS_CAN1, + .minor = 1, + .can_opened = ATOMIC_INIT(1), + .status = CAN_STS_NORMAL, +}; + +static struct can_device *info_can[] = { &info_can0, &info_can1 }; + +#define NUM_MSG 32 + +#define CONT_FLAG_INIT 0x01 +#define CONT_FLAG_IE 0x02 +#define CONT_FLAG_SIE 0x04 +#define CONT_FLAG_EIE 0x08 +#define CONT_FLAG_CCE 0x40 + +/* message buffers */ + +#define CAN_STD_RX_BUFFER_START 1 /* CAN standard receive buffer */ +#define CAN_STD_RX_BUFFER_END 12 /* CAN standard receive buffer */ +#define CAN_EXT_RX_BUFFER 13 /* CAN extended receive buffer */ + +#define CAN_TX_BUFFER 14 /* CAN transmit buffer */ +#define CAN_RTX_BUFFER 15 /* CAN remote frame transmit buffer */ + +struct ML9620BDRATE { + unsigned char btiming0; + unsigned char btiming1; + unsigned char bpre; +}; + +const struct ML9620BDRATE bd_tbl[9] = { +#ifdef CAN_CLOCK_16MHZ +/* for 16 Mhz Quarz */ +/* bus timing 0 | bus timing 1 */ +/* SJW PRESCALER | SAM TSEG1 TSEG2 */ + {0x23, 0x1C}, /* 10K bit/s */ + {0x31, 0x1C}, /* 20K bit/s */ + {0x13, 0x1C}, /* 50K bit/s */ + {0x09, 0x1C}, /* 100K bit/s */ + {0x07, 0x1C}, /* 125K bit/s */ + {0x03, 0x1C}, /* 250K bit/s */ + {0x01, 0x1C}, /* 500K bit/s */ + {0x01, 0x16}, /* 800K bit/s */ + {0x01, 0x14} /* 1M bit/s */ +#endif +#ifdef CAN_CLOCK_8MHZ +/* for 8 Mhz Quarz */ +/* bus timing 0 | bus timing 1 */ +/* SJW PRESCALER | SAM TSEG1 TSEG2 | CANBRPE */ + {0x31, 0x1C, 0x01}, /* 10K bit/s */ + {0x18, 0x1C, 0x00}, /* 20K bit/s */ + {0x09, 0x1C, 0x00}, /* 50K bit/s */ + {0x04, 0x1C, 0x00}, /* 100K bit/s */ + {0x03, 0x1C, 0x00}, /* 125K bit/s */ + {0x01, 0x1C, 0x00}, /* 250K bit/s */ + {0x00, 0x1C, 0x00}, /* 500K bit/s */ + {0x00, 0x16, 0x00}, /* 800K bit/s */ + {0x00, 0x14, 0x00} /* 1M bit/s */ +#endif +}; + +/* DEBUG STUFF */ + +#ifdef OKI_DEBUG +#define CAN_DEBUG(REG,string) \ +{ \ + DBG_OUT(KERN_ERR, " %s 0x%x\n",string,readb(v+REG)); \ +} +#else +#define CAN_DEBUG(REG,string) +#endif + +#ifdef OKI_DEBUG +#define DBG_OKI DBG_OUT +#else +#define DBG_OKI(...) +#endif + +int drv_dbg = 7; + +void DBG_OUT(const char *type, const char *dbg_msg, ...) +{ + va_list ap; + char buf[1024]; + int len; + unsigned int level; + + va_start(ap, dbg_msg); + len = vsprintf(buf, dbg_msg, ap); + va_end(ap); + buf[len] = '\0'; + + if (0 == sscanf(type, "<%i>", &level)) + printk(KERN_ALERT "%s", buf); + + if (level > drv_dbg) + return; + + switch (level) { + case 0: + printk(KERN_EMERG OKI_CAN_DEVICE_NAME "EMERG: %s", buf); + break; + case 1: + printk(KERN_ALERT OKI_CAN_DEVICE_NAME "%s", buf); + break; + case 2: + printk(KERN_CRIT OKI_CAN_DEVICE_NAME "%s", buf); + break; + case 3: + printk(KERN_ERR OKI_CAN_DEVICE_NAME "%s", buf); + break; + case 4: + printk(KERN_WARNING OKI_CAN_DEVICE_NAME "%s", buf); + break; + case 5: + printk(KERN_NOTICE OKI_CAN_DEVICE_NAME "%s", buf); + break; + case 6: + printk(KERN_INFO OKI_CAN_DEVICE_NAME "%s", buf); + break; + case 7: + printk(KERN_DEBUG OKI_CAN_DEVICE_NAME "%s", buf); + break; + } +} +#endif /* _OKI_ML9620_CORE_H_ */ diff --git a/drivers/char/ds1337glue.c b/drivers/char/ds1337glue.c new file mode 100644 index 0000000..c7d168b --- /dev/null +++ b/drivers/char/ds1337glue.c @@ -0,0 +1,69 @@ +/* + * linux/arch/arm/mach-ep93xx/ds1337glue.c + * + * Copyright (C) 2005 Michael Burian + * + * 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. + * + * /dev/rtc interface for Dallas Semiconductor DS133[79]RTC I2C driver + * + * Also see "drivers/i2c/chips/ds1337.c" + * + */ +#include +#include +#include +#include +#include + +#include + +/* FIXME BEGIN: include this from "ds1337.h" as soon as there exists one */ +#warning FIXME: no official ds1337 interface available, hardcoding defaults. +#define DS1337_GET_DATE 0 +#define DS1337_SET_DATE 1 +extern int ds1337_do_command(int bus, int cmd, void *arg); +/* FIXME END */ + +static int rtc_read_time(struct rtc_time *tm) +{ + return ds1337_do_command(0, DS1337_GET_DATE, (void*)(tm)); +} + +static int rtc_set_time(struct rtc_time *tm) +{ + return ds1337_do_command(0, DS1337_SET_DATE, (void*)(tm)); +} + +static struct rtc_ops dma03_rtc_ops = { + .owner = THIS_MODULE, + .read_time = rtc_read_time, + .set_time = rtc_set_time, +}; + +static int __init rtc_interface_init(void) +{ + int err; + printk(KERN_INFO "registering /dev/rtc interface for DS133[79]\n"); + + err = register_rtc(&dma03_rtc_ops); + if(err) + printk(KERN_ERR "could not register DS1337 /dev/rtc interface:" + " error=%d!\n",err); + + return err; +} + +static void __exit rtc_interface_exit(void) +{ + unregister_rtc(&dma03_rtc_ops); +} + +MODULE_AUTHOR("Michael Burian"); +MODULE_DESCRIPTION("/dev/rtc interface for ds1337.c"); +MODULE_LICENSE("GPL"); + +module_init(rtc_interface_init); +module_exit(rtc_interface_exit); diff --git a/drivers/char/ep93xx-rtc.c b/drivers/char/ep93xx-rtc.c new file mode 100644 index 0000000..399d0b0 --- /dev/null +++ b/drivers/char/ep93xx-rtc.c @@ -0,0 +1,376 @@ +/* + * Real Time Clock for Cirrus EP93xx + * + * Copyright (C) 2004 Ray Lehtiniemi + * + * Support for realtime clock device on the Cirrus + * EP93xx family of devices. + * + * Based on rtc.c, and other rtc drivers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define RTC_VERSION "0.01" + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ + +extern spinlock_t rtc_lock; /* seems to be only present in older rtc header? */ +static spinlock_t rtc_task_lock = SPIN_LOCK_UNLOCKED; +static rtc_task_t *rtc_callback = NULL; +static unsigned long rtc_status = 0; +static unsigned long rtc_irq_data = 0; +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); + +/* + * the 1 Hz real time interrupt + */ + +irqreturn_t interrupt_1hz(int irq, void *dev_id, struct pt_regs *regs) +{ + static unsigned long x = 0; + static int i = 0; + + rtc_irq_data += 0x100; + rtc_irq_data &= ~0xff; + + wake_up_interruptible(&rtc_wait); + + printk(KERN_ERR); + printk(" delta: %04ld", jiffies - x); + printk(" data: %08x", readl(RTCDR)); + printk(" match: %08x", readl(RTCMR)); + printk(" stat: %08x", readl(RTCSTAT)); + printk(" load: %08x", readl(RTCLR)); + printk(" ctrl: %08x", readl(RTCCR)); + printk(" comp: %08x", readl(RTCSCOMP)); + printk("\n"); + + x = jiffies; + i++; + + if ((i & 0x7) == 0) { + writel(i << 5, RTCLR); + printk(KERN_ERR "NEW LOAD VALUE: %08x\n", i << 5); + } + + writel(0, RTCEOI); + + return IRQ_HANDLED; +} + +/* + * the RTC match interrupt + */ + +irqreturn_t interrupt_match(int irq, void *dev_id, struct pt_regs * regs) +{ + return IRQ_HANDLED; +} + +/* + * the bulk of the usr interface is done here + */ + +static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) +{ + return -ENOSYS; +} + +/* + * file operations for character device node + */ + +static ssize_t rtc_read(struct file *file, char __user * buf, size_t count, + loff_t * ppos) +{ + unsigned long data; + ssize_t retval; + DECLARE_WAITQUEUE(wait, current); + + if (count < sizeof(unsigned int)) + return -EINVAL; + + add_wait_queue(&rtc_wait, &wait); + + do { + __set_current_state(TASK_INTERRUPTIBLE); + + spin_lock_irq(&rtc_lock); + data = rtc_irq_data; + rtc_irq_data = 0; + spin_unlock_irq(&rtc_lock); + + if (data != 0) + break; + + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto out; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + + schedule(); + } while (1); + + if (count < sizeof(unsigned long)) + retval = + put_user(data, (unsigned int __user *)buf) ? : sizeof(int); + else + retval = + put_user(data, + (unsigned long __user *)buf) ? : sizeof(long); + + out: + current->state = TASK_RUNNING; + remove_wait_queue(&rtc_wait, &wait); + + return retval; +} + +static unsigned int rtc_poll(struct file *file, poll_table * wait) +{ + return -ENOSYS; +} + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + return rtc_do_ioctl(cmd, arg, 0); +} + +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + rtc_irq_data = 0; + enable_irq(IRQ_1HZ); + + spin_unlock_irq(&rtc_lock); + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + disable_irq(IRQ_1HZ); + rtc_irq_data = 0; + rtc_status &= ~RTC_IS_OPEN; + + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static int rtc_fasync(int fd, struct file *filp, int on) +{ + return -ENOSYS; +} + +static struct file_operations rtc_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = rtc_read, + .poll = rtc_poll, + .ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, + .fasync = rtc_fasync, +}; + +static struct miscdevice rtc_dev = { + RTC_MINOR, + "rtc", + &rtc_fops +}; + +/* + * sysctl-tuning infrastructure. + */ + +int no_proc(ctl_table * table, int write, struct file *filp, + void __user * buffer, size_t * lenp, loff_t * ppos) +{ + return -ENOSYS; +} + +static ctl_table rtc_table[] = { + { + .ctl_name = 1, + .procname = "max-user-freq", + .data = NULL, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &no_proc, + }, + {.ctl_name = 0} +}; + +static ctl_table rtc_root[] = { + { + .ctl_name = 1, + .procname = "rtc", + .maxlen = 0, + .mode = 0555, + .child = rtc_table, + }, + {.ctl_name = 0} +}; + +static ctl_table dev_root[] = { + { + .ctl_name = CTL_DEV, + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .child = rtc_root, + }, + {.ctl_name = 0} +}; + +static struct ctl_table_header *sysctl_header; + +static int __init init_sysctl(void) +{ + sysctl_header = register_sysctl_table(dev_root, 0); + return 0; +} + +static void __exit cleanup_sysctl(void) +{ + unregister_sysctl_table(sysctl_header); +} + +/* + * Public functions from rtc.h + */ + +EXPORT_SYMBOL(rtc_register); +EXPORT_SYMBOL(rtc_unregister); +EXPORT_SYMBOL(rtc_control); + +int rtc_register(rtc_task_t * task) +{ + if (task == NULL || task->func == NULL) + return -EINVAL; + + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + spin_lock(&rtc_task_lock); + + if (rtc_callback) { + spin_unlock(&rtc_task_lock); + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + rtc_callback = task; + + spin_unlock(&rtc_task_lock); + spin_unlock_irq(&rtc_lock); + + return 0; +} + +int rtc_unregister(rtc_task_t * task) +{ + spin_lock_irq(&rtc_lock); + spin_lock(&rtc_task_lock); + + if (rtc_callback != task) { + spin_unlock(&rtc_task_lock); + spin_unlock_irq(&rtc_lock); + return -ENXIO; + } + + /* disable PIE/AIE/UIE interrupts */ + + rtc_status &= ~RTC_IS_OPEN; + rtc_callback = NULL; + + spin_unlock(&rtc_task_lock); + spin_unlock_irq(&rtc_lock); + + return 0; +} + +int rtc_control(rtc_task_t * task, unsigned int cmd, unsigned long arg) +{ + spin_lock_irq(&rtc_task_lock); + + if (rtc_callback != task) { + spin_unlock_irq(&rtc_task_lock); + return -ENXIO; + } + + spin_unlock_irq(&rtc_task_lock); + + return rtc_do_ioctl(cmd, arg, 1); +} + +void rtc_get_rtc_time(struct rtc_time *rtc_tm) +{ +} + +/* + * Module init/exit + */ + +static int __init rtc_init(void) +{ + if (request_irq(IRQ_1HZ, interrupt_1hz, SA_INTERRUPT, "rtc-1hz", NULL)) { + printk(KERN_ERR "rtc: IRQ %d is not free.\n", IRQ_1HZ); + return -EIO; + } + + if (misc_register(&rtc_dev)) { + free_irq(IRQ_1HZ, NULL); + return -ENODEV; + } + + init_sysctl(); + + printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n"); + return 0; +} + +static void __exit rtc_exit(void) +{ + cleanup_sysctl(); + misc_deregister(&rtc_dev); + free_irq(IRQ_1HZ, NULL); +} + +module_init(rtc_init); +module_exit(rtc_exit); + +MODULE_AUTHOR("Ray Lehtiniemi"); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/ttml.c b/drivers/char/ttml.c new file mode 100644 index 0000000..ba2cb8e --- /dev/null +++ b/drivers/char/ttml.c @@ -0,0 +1,643 @@ +/* + * linux/drivers/char/ttml.c + * + * TTML TripDawg system devices. + * + * Copyright 2004, Ray Lehtiniemi + * Copyright 2004, Siconix, Inc + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +/* device open/release stuff */ +static DECLARE_MUTEX(mutex); +static struct cdev ttml_cdev; +static struct class *ttml_class; +static int is_open[MAX_TTML_MINORS]; + +#define minor_get(minor) is_open[(minor)-TTML_MINOR_LED] = 1 +#define minor_put(minor) is_open[(minor)-TTML_MINOR_LED] = 0 +#define minor_busy(minor) (is_open[(minor)-TTML_MINOR_LED] != 0) + +static struct { + int minor; + char *name; +} devlist[] = { + { + TTML_MINOR_LED, "led"}, { + TTML_MINOR_BUZZER, "buzzer"}, { + TTML_MINOR_SPEEDO, "speedo"}, { + TTML_MINOR_GPIO, "gpio"}, { + TTML_MINOR_BUTTON, "button"}, { +TTML_MINOR_WD, "wd"},}; + +/* button and gpio event handling */ +static kmem_cache_t *event_cachep; +static spinlock_t event_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(button_events); +static LIST_HEAD(gpio_events); +static DECLARE_WAIT_QUEUE_HEAD(button_wait); +static DECLARE_WAIT_QUEUE_HEAD(gpio_wait); + +enum ttml_events { + TTML_BUTTON_PRESS, + TTML_BUTTON_RELEASE, + TTML_PTO_RISE, + TTML_PTO_FALL, + TTML_IGNITION_RISE, + TTML_IGNITION_FALL, + TTML_SPARE_RISE, + TTML_SPARE_FALL, +}; + +struct ttml_event { + struct list_head l; + struct timeval t; + enum ttml_events e; +}; + +/* Button and GPIO event monitoring timer */ + +static struct timer_list monitor_timer; +static void handle_timer(unsigned long); + +static void setup_timer(void) +{ + monitor_timer.expires = jiffies + 1; + monitor_timer.data = 0; + monitor_timer.function = handle_timer; + add_timer(&monitor_timer); +} + +static void handle_timer_button(void) +{ + static int state = 0; + int portf = readl(GPIO_PFDR); + int new = (portf & 0x04) ? 0 : 1; + + if (state ^ new) { + struct ttml_event *b = + kmem_cache_alloc(event_cachep, GFP_KERNEL); + if (b != NULL) { + do_gettimeofday(&b->t); + b->t.tv_usec |= + ((new ? TTML_BUTTON_PRESS : TTML_BUTTON_RELEASE) << + 24); + list_add(&b->l, &button_events); + wake_up_interruptible(&button_wait); + } + state = new; + } +} + +static void handle_timer_pto(void) +{ + static int state = 0; + int portf = readl(GPIO_PFDR); + int new = (portf & 0x08) ? 1 : 0; + + if (state ^ new) { + struct ttml_event *b = + kmem_cache_alloc(event_cachep, GFP_KERNEL); + if (b != NULL) { + do_gettimeofday(&b->t); + b->t.tv_usec |= + ((new ? TTML_PTO_RISE : TTML_PTO_FALL) << 24); + list_add(&b->l, &gpio_events); + wake_up_interruptible(&gpio_wait); + } + state = new; + } +} + +static void handle_timer_ignition(void) +{ + static int state = 0; + int portf = readl(GPIO_PFDR); + int new = (portf & 0x02) ? 1 : 0; + + if (state ^ new) { + struct ttml_event *b = + kmem_cache_alloc(event_cachep, GFP_KERNEL); + if (b != NULL) { + do_gettimeofday(&b->t); + b->t.tv_usec |= + ((new ? TTML_IGNITION_RISE : TTML_IGNITION_FALL) << + 24); + list_add(&b->l, &gpio_events); + wake_up_interruptible(&gpio_wait); + } + state = new; + } +} + +static void handle_timer_spare(void) +{ + static int state = 0; + int porta = readl(GPIO_PADR); + int new = (porta & 0x08) ? 1 : 0; + + if (state ^ new) { + struct ttml_event *b = + kmem_cache_alloc(event_cachep, GFP_KERNEL); + if (b != NULL) { + do_gettimeofday(&b->t); + b->t.tv_usec |= + ((new ? TTML_SPARE_RISE : TTML_SPARE_FALL) << 24); + list_add(&b->l, &gpio_events); + wake_up_interruptible(&gpio_wait); + } + state = new; + } +} + +static void handle_timer(unsigned long foo) +{ + handle_timer_button(); + handle_timer_pto(); + handle_timer_ignition(); + handle_timer_spare(); + setup_timer(); +} + +static int ttml_read_gpio(struct file *filp, char __user * buf, size_t size, + loff_t * off); +static int ttml_read_button(struct file *filp, char __user * buf, size_t size, + loff_t * off); +static unsigned int ttml_poll_gpio(struct file *filp, + struct poll_table_struct *poll); +static unsigned int ttml_poll_button(struct file *filp, + struct poll_table_struct *poll); +static int ttml_ioctl(struct inode *inode, struct file *filp, + unsigned int command, unsigned long arg); +static int ttml_open(struct inode *inode, struct file *filp); +static int ttml_release(struct inode *inode, struct file *filp); + +static struct file_operations ttml_fops = { + .owner = THIS_MODULE, + .ioctl = ttml_ioctl, + .open = ttml_open, + .release = ttml_release, +}; + +static struct file_operations ttml_fops_gpio = { + .owner = THIS_MODULE, + .read = ttml_read_gpio, + .poll = ttml_poll_gpio, + .ioctl = ttml_ioctl, + .open = ttml_open, + .release = ttml_release, +}; + +static struct file_operations ttml_fops_button = { + .owner = THIS_MODULE, + .read = ttml_read_button, + .poll = ttml_poll_button, + .ioctl = ttml_ioctl, + .open = ttml_open, + .release = ttml_release, +}; + +static int do_get_led(void __user * arg) +{ + struct ttml_ioctl_led a; + int porte = readl(GPIO_PEDR); + int portb = readl(GPIO_PBDR); + + a.blue = (portb & 0x01) ? 1 : 0; + a.red = (porte & 0x02) ? 1 : 0; + a.yellow = (porte & 0x01) ? 1 : 0; + + return (copy_to_user(arg, &a, sizeof(a)) == sizeof(a)) ? -EIO : 0; +} + +static int do_get_buzzer(void __user * arg) +{ + struct ttml_ioctl_buzzer a; + + a.buzzer1 = 0; /* FIXME */ + + return (copy_to_user(arg, &a, sizeof(a)) == sizeof(a)) ? -EIO : 0; +} + +static int do_get_speedo(void __user * arg) +{ + struct ttml_ioctl_speedo a; + unsigned char msg[3] = { 0xaa, 0x82, 0xd7 }; + unsigned char reply[10]; + int err; + + err = ssp_do_ttml(&ep93xx_ssp_micro, msg, 3, reply, 10); + + if (err != 0) + return err; + + a.instant = 0; /* FIXME */ + a.average = (reply[1] << 8) | (reply[2]); + + return (copy_to_user(arg, &a, sizeof(a)) == sizeof(a)) ? -EIO : 0; +} + +static int do_get_gpio(void __user * arg) +{ + struct ttml_ioctl_gpio a; + int porta = readl(GPIO_PADR); + int portf = readl(GPIO_PFDR); + + a.pto = (portf & 0x08) ? 0 : 1; + a.ignition = (portf & 0x02) ? 0 : 1; + a.spare = (porta & 0x08) ? 0 : 1; + + return (copy_to_user(arg, &a, sizeof(a)) == sizeof(a)) ? -EIO : 0; +} + +static int do_get_button(void __user * arg) +{ + struct ttml_ioctl_button a; + int portf = readl(GPIO_PFDR); + + a.button1 = (portf & 0x04) ? 0 : 1; + + return (copy_to_user(arg, &a, sizeof(a)) == sizeof(a)) ? -EIO : 0; +} + +static int do_set_led(void __user * arg) +{ + struct ttml_ioctl_led a; + int porte = readl(GPIO_PEDR); + int portb = readl(GPIO_PBDR); + + if (copy_from_user(&a, arg, sizeof(a))) + return -EIO; + + if (a.yellow) + porte |= 0x01; + else + porte &= ~0x01; + + if (a.red) + porte |= 0x02; + else + porte &= ~0x02; + + if (a.blue) + portb |= 0x01; + else + portb &= ~0x01; + + writel(porte, GPIO_PEDR); + writel(portb, GPIO_PBDR); + + return 0; +} + +static int do_set_buzzer(void __user * arg) +{ + struct ttml_ioctl_buzzer a; + unsigned char msg0[4] = { 0xaa, 0x93, 0x00, 0xc6 }; + unsigned char msg1[4] = { 0xaa, 0x93, 0x01, 0xc7 }; + unsigned char reply[10]; + int err = 0; + + if (copy_from_user(&a, arg, sizeof(a))) + return -EIO; + + if (a.buzzer1) + err = ssp_do_ttml(&ep93xx_ssp_micro, msg1, 4, reply, 10); + else + err = ssp_do_ttml(&ep93xx_ssp_micro, msg0, 4, reply, 10); + + return err; +} + +static int ttml_read_gpio(struct file *filp, char __user * buf, size_t size, + loff_t * off) +{ + DECLARE_WAITQUEUE(wait, current); + struct ttml_event *g = NULL; + int retval = -EINVAL; + + if (size != sizeof(struct timeval)) + return -EINVAL; + + add_wait_queue(&gpio_wait, &wait); + + while (1) { + unsigned long flags; + + __set_current_state(TASK_INTERRUPTIBLE); + + spin_lock_irqsave(&event_lock, flags); + if (!list_empty(&gpio_events)) + list_for_each_entry(g, &gpio_events, l) { + list_del(&g->l); + break; + } + + spin_unlock_irqrestore(&event_lock, flags); + + if (g != NULL) + break; + + if (filp->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto out; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + + schedule(); + + }; + + if (copy_to_user(buf, &g->t, sizeof(struct timeval))) + retval = -EFAULT; + else + retval = sizeof(struct timeval); + + kmem_cache_free(event_cachep, g); + + out: + current->state = TASK_RUNNING; + remove_wait_queue(&gpio_wait, &wait); + + return retval; +} + +static unsigned int ttml_poll_gpio(struct file *filp, + struct poll_table_struct *poll) +{ + unsigned long flags; + int retval = 0; + + poll_wait(filp, &gpio_wait, poll); + + spin_lock_irqsave(&event_lock, flags); + if (!list_empty(&gpio_events)) + retval = (POLLIN | POLLRDNORM); + spin_unlock_irqrestore(&event_lock, flags); + + return retval; +} + +static int ttml_read_button(struct file *filp, char __user * buf, size_t size, + loff_t * off) +{ + DECLARE_WAITQUEUE(wait, current); + struct ttml_event *b = NULL; + int retval = -EINVAL; + + if (size != sizeof(struct timeval)) + return -EINVAL; + + add_wait_queue(&button_wait, &wait); + + while (1) { + unsigned long flags; + + __set_current_state(TASK_INTERRUPTIBLE); + + spin_lock_irqsave(&event_lock, flags); + if (!list_empty(&button_events)) { + list_for_each_entry(b, &button_events, l) { + list_del(&b->l); + break; + } + } + spin_unlock_irqrestore(&event_lock, flags); + + if (b != NULL) + break; + + if (filp->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto out; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + + schedule(); + + }; + + if (copy_to_user(buf, &b->t, sizeof(struct timeval))) + retval = -EFAULT; + else + retval = sizeof(struct timeval); + + kmem_cache_free(event_cachep, b); + + out: + current->state = TASK_RUNNING; + remove_wait_queue(&button_wait, &wait); + + return retval; +} + +static unsigned int ttml_poll_button(struct file *filp, + struct poll_table_struct *poll) +{ + unsigned long flags; + int retval = 0; + + poll_wait(filp, &button_wait, poll); + + spin_lock_irqsave(&event_lock, flags); + if (!list_empty(&button_events)) + retval = (POLLIN | POLLRDNORM); + spin_unlock_irqrestore(&event_lock, flags); + + return retval; +} + +static int ttml_ioctl(struct inode *inode, struct file *filp, + unsigned int command, unsigned long arg) +{ + void __user *p = (void __user *)arg; + const int minor = iminor(inode); + int err = -ENOSYS; + + switch (command) { + case TTML_GET_LED: + if (minor == TTML_MINOR_LED) + err = do_get_led(p); + break; + case TTML_GET_BUZZER: + if (minor == TTML_MINOR_BUZZER) + err = do_get_buzzer(p); + break; + case TTML_GET_SPEEDO: + if (minor == TTML_MINOR_SPEEDO) + err = do_get_speedo(p); + break; + case TTML_GET_GPIO: + if (minor == TTML_MINOR_GPIO) + err = do_get_gpio(p); + break; + case TTML_GET_BUTTON: + if (minor == TTML_MINOR_BUTTON) + err = do_get_button(p); + break; + case TTML_SET_LED: + if (minor == TTML_MINOR_LED) + err = do_set_led(p); + break; + case TTML_SET_BUZZER: + if (minor == TTML_MINOR_BUZZER) + err = do_set_buzzer(p); + break; + } + + return err; +} + +static int ttml_open(struct inode *inode, struct file *filp) +{ + const int minor = iminor(inode); + int err = -EBUSY; + + if (minor == TTML_MINOR_WD) { + unsigned char msg[3] = { 0xaa, 0x82, 0xd7 }; + unsigned char reply[10]; + ssp_do_ttml(&ep93xx_ssp_micro, msg, 3, reply, 10); + } + + down(&mutex); + if (minor_busy(minor)) + goto err; + minor_get(minor); + if (minor == TTML_MINOR_GPIO) + filp->f_op = &ttml_fops_gpio; + if (minor == TTML_MINOR_BUTTON) + filp->f_op = &ttml_fops_button; + err = 0; + + err: + up(&mutex); + return err; +} + +static int ttml_release(struct inode *inode, struct file *filp) +{ + down(&mutex); + minor_put(iminor(inode)); + up(&mutex); + return 0; +} + +static int __init ttml_init(void) +{ + dev_t dev = MKDEV(TTML_MAJOR, 240); + int err = -EIO; + int i; + + err = -ENOMEM; + event_cachep = kmem_cache_create("ttml_event", + sizeof(struct ttml_event), + 0, 0, NULL, NULL); + if (event_cachep == NULL) + goto err; + + err = -EIO; + if (register_chrdev_region(dev, MAX_TTML_MINORS, "ttml")) + goto err_uncache; + + cdev_init(&ttml_cdev, &ttml_fops); + + if (cdev_add(&ttml_cdev, dev, MAX_TTML_MINORS)) { + kobject_put(&ttml_cdev.kobj); + goto err_unreg; + } + + ttml_class = class_create(THIS_MODULE, "ttml"); + + if (IS_ERR(ttml_class)) { + err = PTR_ERR(ttml_class); + cdev_del(&ttml_cdev); + goto err_unreg; + } + + for (i = 0; i < ARRAY_SIZE(devlist); i++) + class_device_create(ttml_class, + MKDEV(TTML_MAJOR, devlist[i].minor), + NULL, "%s", devlist[i].name); + + init_timer(&monitor_timer); + setup_timer(); + + printk(KERN_INFO "TTML system devices version 0.1\n"); + return 0; + + err_unreg: + unregister_chrdev_region(dev, MAX_TTML_MINORS); + err_uncache: + kmem_cache_destroy(event_cachep); + err: + printk(KERN_WARNING "unable to register ttml devices\n"); + return err; +} + +static void __exit ttml_exit(void) +{ + struct ttml_event *b; + int i; + + /* stop our button polling timer */ + del_timer_sync(&monitor_timer); + + /* delete any events captured but not yet read */ + list_for_each_entry(b, &button_events, l) { + list_del(&b->l); + kmem_cache_free(event_cachep, b); + } + + list_for_each_entry(b, &gpio_events, l) { + list_del(&b->l); + kmem_cache_free(event_cachep, b); + } + + /* free up the event cache */ + kmem_cache_destroy(event_cachep); + + /* clean up the device */ + for (i = 0; i < ARRAY_SIZE(devlist); i++) + class_device_destroy(ttml_class, + MKDEV(TTML_MAJOR, devlist[i].minor)); + class_destroy(ttml_class); + cdev_del(&ttml_cdev); + unregister_chrdev_region(MKDEV(TTML_MAJOR, 240), MAX_TTML_MINORS); +} + +module_init(ttml_init); +module_exit(ttml_exit); + +MODULE_AUTHOR("Ray Lehtiniemi"); +MODULE_DESCRIPTION("TTML system devices"); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 344001b..b5a7a90 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -148,6 +148,17 @@ config MPCORE_WATCHDOG To compile this driver as a module, choose M here: the module will be called mpcore_wdt. +config EP93XX_WATCHDOG + tristate "EP93xx Watchdog" + depends on WATCHDOG && ARCH_EP93XX + help + Say Y here if to include support for the watchdog timer + in the Cirrus EP93xx family of devices. This driver can + be built as a module by choosing M. The module will + be called ep93xx_wdt. + + Say N if you are unsure. + # X86 (i386 + ia64 + x86_64) Architecture config ACQUIRE_WDT diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index cfd0a39..061671b 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb. # ARM Architecture obj-$(CONFIG_21285_WATCHDOG) += wdt285.o obj-$(CONFIG_977_WATCHDOG) += wdt977.o +obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c new file mode 100644 index 0000000..a2a7a49 --- /dev/null +++ b/drivers/char/watchdog/ep93xx_wdt.c @@ -0,0 +1,210 @@ +/* + * drivers/watchdog/ep93xx_wdt.c + * + * Watchdog driver for Cirrus EP93xx family of devices. + * + * Author: Ray Lehtiniemi + * + * Copyright 2004 (c) Ray Lehtiniemi + * Based on ep93xx driver. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/* + Todo: + + - test last rst from watchdog status + - test module loading + - test nowayout + - test all ioctl, add missing ones + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define WD_VERSION "0.01" + +#ifdef CONFIG_WATCHDOG_NOWAYOUT +static int nowayout = 1; +#else +static int nowayout = 0; +#endif + +static unsigned long wdt_status; +static unsigned long boot_status; + +#define WDT_IN_USE 0 +#define WDT_OK_TO_CLOSE 1 + +static void wdt_enable(void) +{ + writel(0xaaaa, WATCHDOG); +} + +static void wdt_disable(void) +{ + writel(0xaa55, WATCHDOG); +} + +static void wdt_ping(void) +{ + writel(0x5555, WATCHDOG); +} + +static int ep93xx_wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(WDT_IN_USE, &wdt_status)) + return -EBUSY; + + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + wdt_enable(); + + return 0; +} + +static ssize_t +ep93xx_wdt_write(struct file *file, const char __user * data, size_t len, + loff_t * ppos) +{ + /* Can't seek (pwrite) on this device */ + if (*ppos != file->f_pos) + return -ESPIPE; + + if (len) { + if (!nowayout) { + size_t i; + + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + for (i = 0; i != len; i++) { + char c; + + if (get_user(c, data + i)) + return -EFAULT; + + if (c == 'V') + set_bit(WDT_OK_TO_CLOSE, &wdt_status); + else + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + } + } + wdt_ping(); + } + + return len; +} + +static struct watchdog_info ident = { + .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, + .identity = "EP93xx Watchdog", +}; + +static int +ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret = -ENOIOCTLCMD; + + switch (cmd) { + case WDIOC_GETSUPPORT: + ret = copy_to_user((struct watchdog_info __user *)arg, &ident, + sizeof(ident)) ? -EFAULT : 0; + break; + + case WDIOC_GETSTATUS: + ret = put_user(0, (int __user *)arg); + break; + + case WDIOC_GETBOOTSTATUS: + ret = put_user(boot_status, (int __user *)arg); + break; + + case WDIOC_GETTIMEOUT: + /* actually, it is 0.250 seconds.... */ + ret = put_user(1, (int __user *)arg); + break; + + case WDIOC_KEEPALIVE: + wdt_ping(); + ret = 0; + break; + } + return ret; +} + +static int ep93xx_wdt_release(struct inode *inode, struct file *file) +{ + if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) + wdt_disable(); + else + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " + "timer will not stop\n"); + + clear_bit(WDT_IN_USE, &wdt_status); + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + return 0; +} + +static struct file_operations ep93xx_wdt_fops = { + .owner = THIS_MODULE, + .write = ep93xx_wdt_write, + .ioctl = ep93xx_wdt_ioctl, + .open = ep93xx_wdt_open, + .release = ep93xx_wdt_release, +}; + +static struct miscdevice ep93xx_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "EP93xx Watchdog", + .fops = &ep93xx_wdt_fops, +}; + +static int __init ep93xx_wdt_init(void) +{ + int ret; + + ret = misc_register(&ep93xx_wdt_miscdev); + + boot_status = readl(WATCHDOG) & 0x01 ? 1 : 0; + + printk("EP93xx Watchdog: Version " WD_VERSION "%s\n", + (readl(WATCHDOG) & 0x08) ? " (nCS1 disable detected)" + : ""); + + return ret; +} + +static void __exit ep93xx_wdt_exit(void) +{ + misc_deregister(&ep93xx_wdt_miscdev); +} + +module_init(ep93xx_wdt_init); +module_exit(ep93xx_wdt_exit); + +MODULE_AUTHOR("Ray Lehtiniemi "); +MODULE_DESCRIPTION("EP93xx Watchdog"); + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 4010fe9..895dfa8 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -95,6 +95,19 @@ config I2C_ELEKTOR This support is also available as a module. If so, the module will be called i2c-elektor. +config I2C_EP93XX + tristate "Cirrus EP93XX interface" + depends on I2C && ARCH_EP93XX + select I2C_ALGOBIT + help + This supports the Cirrus EP93xx CPU family I2C bus. Choose this + if you want to access I2C devices connected to EECLK and EEDAT pins + of your EP93XX. + + This support is also available as a module. If so, the module + will be called i2c-ep93xx. + + config I2C_HYDRA tristate "CHRP Apple Hydra Mac I/O I2C interface" depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index f1df00f..fbb35f7 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-am obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o +obj-$(CONFIG_I2C_EP93XX) += i2c-ep93xx.o obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_I810) += i2c-i810.o diff --git a/drivers/i2c/busses/i2c-ep93xx.c b/drivers/i2c/busses/i2c-ep93xx.c new file mode 100644 index 0000000..1477bf3 --- /dev/null +++ b/drivers/i2c/busses/i2c-ep93xx.c @@ -0,0 +1,180 @@ +/* ------------------------------------------------------------------------ * + * i2c-ep933xx.c I2C bus glue for Cirrus EP93xx * + * ------------------------------------------------------------------------ * + + Copyright (C) 2004 Michael Burian + + Based on i2c-parport-light.c + Copyright (C) 2003-2004 Jean Delvare + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * ------------------------------------------------------------------------ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 1/(2*clockfrequency) */ +#define EE_DELAY_USEC 50 +#define GPIOG_EECLK 1 +#define GPIOG_EEDAT 2 + +/* ----- I2C algorithm call-back functions and structures ----------------- */ + +static void ep93xx_setscl(void *data, int state) +{ + unsigned int val, dir; + + val = readl(GPIO_PGDR); + dir = readl(GPIO_PGDDR); + + /* Configure the clock line as output. */ + dir |= GPIOG_EECLK; + writel(dir, GPIO_PGDDR); + + /* Set clock line to state */ + if (state) + val |= GPIOG_EECLK; + else + val &= ~GPIOG_EECLK; + + writel(val, GPIO_PGDR); +} + +static void ep93xx_setsda(void *data, int state) +{ + unsigned int val, dir; + val = readl(GPIO_PGDR); + dir = readl(GPIO_PGDDR); + + /* Configure the data line as output. */ + dir |= GPIOG_EEDAT; + writel(dir, GPIO_PGDDR); + + /* Set data line to state */ + if (state) + val |= GPIOG_EEDAT; + else + val &= ~GPIOG_EEDAT; + + writel(val, GPIO_PGDR); +} + +static int ep93xx_getscl(void *data) +{ + unsigned int val, dir; + val = readl(GPIO_PGDR); + dir = readl(GPIO_PGDDR); + + /* Configure the clock line as input */ + dir &= ~GPIOG_EECLK; + writel(dir, GPIO_PGDDR); + + /* Return state of the clock line */ + return (readl(GPIO_PGDR) & GPIOG_EECLK) ? 1 : 0; +} + +static int ep93xx_getsda(void *data) +{ + unsigned int val, dir; + val = readl(GPIO_PGDR); + dir = readl(GPIO_PGDDR); + + /* Configure the data line as input */ + dir &= ~GPIOG_EEDAT; + writel(dir, GPIO_PGDDR); + + /* Return state of the data line */ + return (readl(GPIO_PGDR) & GPIOG_EEDAT) ? 1 : 0; +} + +static struct i2c_algo_bit_data ep93xx_algo_data = { + .setsda = ep93xx_setsda, + .setscl = ep93xx_setscl, + .getsda = ep93xx_getsda, + .getscl = ep93xx_getscl, + .udelay = EE_DELAY_USEC, + .mdelay = EE_DELAY_USEC * 1000, + .timeout = HZ, +}; + +/* ----- I2c structure ---------------------------------------------------- */ + +static struct i2c_adapter ep93xx_adapter = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .id = I2C_HW_B_LP, + .algo_data = &ep93xx_algo_data, + .name = "EP93XX I2C interface", +}; + +/* ----- Module loading, unloading and information ------------------------ */ + +static int __init i2c_ep93xx_init(void) +{ + unsigned long uiVal, uiDDR; + + /* Read the current value of the GPIO data and data direction registers. */ + uiVal = readl(GPIO_PGDR); + uiDDR = readl(GPIO_PGDDR); + + /* If the GPIO pins have not been configured since reset, the data + * and clock lines will be set as inputs and with data value of 0. + * External pullup resisters are pulling them high. + * Set them both high before configuring them as outputs. */ + uiVal |= (GPIOG_EEDAT | GPIOG_EECLK); + writel(uiVal, GPIO_PGDR); + + /* Delay to meet the EE Interface timing specification. */ + udelay(EE_DELAY_USEC); + + /* Configure the EE data and clock lines as outputs. */ + writel(0x3, GPIO_EEDRIVE); /* use open drain outputs! */ + uiDDR |= (GPIOG_EEDAT | GPIOG_EECLK); + writel(uiDDR, GPIO_PGDDR); + + /* Delay to meet the EE Interface timing specification. */ + udelay(EE_DELAY_USEC); + + /* Reset hardware to a sane state (SCL and SDA high) */ + ep93xx_setsda(NULL, 1); + ep93xx_setscl(NULL, 1); + + if (i2c_bit_add_bus(&ep93xx_adapter) < 0) { + printk(KERN_ERR "i2c-ep93xx: Unable to register with I2C\n"); + return -ENODEV; + } + + return 0; +} + +static void __exit i2c_ep93xx_exit(void) +{ + i2c_bit_del_bus(&ep93xx_adapter); +} + +MODULE_AUTHOR("Michael Burian"); +MODULE_DESCRIPTION("I2C bus glue for Cirrus EP93xx processors"); +MODULE_LICENSE("GPL"); + +module_init(i2c_ep93xx_init); +module_exit(i2c_ep93xx_exit); diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index f9fae28..45f9286 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -25,6 +25,18 @@ config SENSORS_DS1374 This driver can also be built as a module. If so, the module will be called ds1374. +config SENSORS_DS1307 + tristate "Dallas Semiconductor DS1307 RTC" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Dallas Semiconductor + DS1307 RTC. Usually only embedded devices will need this. + + Only say yes here if your sure you have such a chip. + + This driver can also be built as a module. If so, the module + will be called ds1307. + config SENSORS_EEPROM tristate "EEPROM reader" depends on I2C && EXPERIMENTAL diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 46178b5..90be351 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_SENSORS_DS1337) += ds1337.o +obj-$(CONFIG_SENSORS_DS1307) += ds1307.o obj-$(CONFIG_SENSORS_DS1374) += ds1374.o obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o obj-$(CONFIG_SENSORS_MAX6875) += max6875.o diff --git a/drivers/i2c/chips/ds1307.c b/drivers/i2c/chips/ds1307.c new file mode 100644 index 0000000..76ea8b8 --- /dev/null +++ b/drivers/i2c/chips/ds1307.c @@ -0,0 +1,651 @@ +/* + * ds1307.c + * + * Device driver for Dallas Semiconductor's Real Time Controller DS1307. + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * + * 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 "ds1307.h" + +#undef DEBUG +#ifdef DEBUG +static unsigned int rtc_debug = DEBUG; +#define DPRINTK(i,x...) do { if (rtc_debug > (i)) printk(x); } while (0) +#else +#define rtc_debug 0 /* gcc will remove all the debug code for us */ +#define DPRINTK(i,x...) do { } while (0) +#endif + +static unsigned short slave_address = DS1307_I2C_SLAVE_ADDR; + +struct i2c_driver ds1307_driver; +struct i2c_client *ds1307_i2c_client = 0; + +static unsigned short ignore[] = { I2C_CLIENT_END }; +static unsigned short normal_addr[] = { DS1307_I2C_SLAVE_ADDR, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c: normal_addr, + probe: ignore, + ignore: ignore, + force: ignore, +}; + +static int ds1307_rtc_ioctl( struct inode *, struct file *, unsigned int, unsigned long); +static int ds1307_rtc_open(struct inode *inode, struct file *file); +static int ds1307_rtc_release(struct inode *inode, struct file *file); + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + ioctl: ds1307_rtc_ioctl, + open: ds1307_rtc_open, + release: ds1307_rtc_release, +}; + +static struct miscdevice ds1307_rtc_miscdev = { + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int ds1307_probe(struct i2c_adapter *adap); +static int ds1307_detach(struct i2c_client *client); +static int ds1307_command(struct i2c_client *client, unsigned int cmd, void *arg); + +struct i2c_driver ds1307_driver = { + .owner = THIS_MODULE, + .name = "DS1307", + .id = I2C_DRIVERID_DS1307, + .flags = I2C_DF_NOTIFY, + .attach_adapter = ds1307_probe, + .detach_client = ds1307_detach, + .command = ds1307_command, +}; + +static spinlock_t ds1307_rtc_lock = SPIN_LOCK_UNLOCKED; + +static int +ds1307_readram( char *buf, int len) +{ + unsigned long flags; + unsigned char ad[1] = { 0 }; + int ret; + struct i2c_msg msgs[2] = { + { ds1307_i2c_client->addr , 0, 1, ad }, + { ds1307_i2c_client->addr , I2C_M_RD, len, buf } }; + + spin_lock_irqsave(&ds1307_rtc_lock, flags); + ret = i2c_transfer(ds1307_i2c_client->adapter, msgs, 2); + spin_unlock_irqrestore(&ds1307_rtc_lock,flags); + + return ret; +} + +static void +ds1307_dumpram( void) +{ + unsigned char buf[DS1307_RAM_SIZE]; + int ret; + + ret = ds1307_readram( buf, DS1307_RAM_SIZE); + + if( ret > 0) + { + int i; + for( i=0; iaddr , 0, 1, ad }, + { ds1307_i2c_client->addr , I2C_M_RD, 1, buf } + }; + unsigned char ctrl_info; + int ret; + + DPRINTK(1, "%s()\n", __FUNCTION__); + + if (enable) + ctrl_info = SQW_ENABLE | RATE_32768HZ; + else + ctrl_info = SQW_DISABLE; + ret = ds1307_command(ds1307_i2c_client, DS1307_SETCTRL, &ctrl_info); + DPRINTK(2, "%s: set ctrl rtn'd %d\n", __FUNCTION__, ret); + + /* read addr 0 (Clock-Halt bit and second counter */ + ret = i2c_transfer(ds1307_i2c_client->adapter, msgs, 2); + DPRINTK(2, "%s: %s msg xfer rtn'd %d\n", __FUNCTION__, enable ? "enable" : "disable", ret); + + if (enable) + buf[1] = buf[0] & ~CLOCK_HALT; /* clear Clock-Halt bit */ + else + buf[1] = buf[0] | CLOCK_HALT; /* set Clock-Halt bit */ + buf[0] = 0; /* control register address on DS1307 */ + + ret = i2c_master_send(ds1307_i2c_client, (char *)buf, 2); + DPRINTK(2, "%s: master send rtn'd %d\n", __FUNCTION__, ret); +} + +static int +ds1307_get_datetime(struct i2c_client *client, struct rtc_time *dt); + +static int +ds1307_attach(struct i2c_adapter *adap, int addr, int kind) +{ + struct i2c_client *c; + + DPRINTK(1, "%s()\n", __FUNCTION__); + + c = (struct i2c_client *)kmalloc(sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + memset(c, 0, sizeof(*c)); + + strcpy(c->name, "DS1307"); + c->flags = 0; + c->addr = addr; + c->adapter = adap; + c->driver = &ds1307_driver; + + ds1307_i2c_client = c; + ds1307_enable_clock(1); + +#define DS1307_SET_TIME_ON_BOOT +#ifdef DS1307_SET_TIME_ON_BOOT + { + struct rtc_time dt; + ds1307_get_datetime(c, &dt); + xtime.tv_sec = mktime(dt.tm_year + 1900, + dt.tm_mon + 1, /* tm_mon starts from 0 */ + dt.tm_mday, + dt.tm_hour, + dt.tm_min, + dt.tm_sec); + } +#endif + + return i2c_attach_client(c); +} + +static int +ds1307_probe(struct i2c_adapter *adap) +{ + DPRINTK(1, "%s()\n", __FUNCTION__); + + return i2c_probe(adap, &addr_data, ds1307_attach); +} + +static int +ds1307_detach(struct i2c_client *client) +{ + DPRINTK(1, "%s()\n", __FUNCTION__); + + i2c_detach_client(client); + ds1307_enable_clock(0); + + return 0; +} + +static void +ds1307_convert_to_time( struct rtc_time *dt, char *buf) +{ + dt->tm_sec = BCD_TO_BIN(buf[0]); + dt->tm_min = BCD_TO_BIN(buf[1]); + + if ( TWELVE_HOUR_MODE(buf[2]) ) + { + dt->tm_hour = HOURS_12(buf[2]); + if (HOURS_AP(buf[2])) /* PM */ + { + dt->tm_hour += 12; + } + } + else /* 24-hour-mode */ + { + dt->tm_hour = HOURS_24(buf[2]); + } + + dt->tm_mday = BCD_TO_BIN(buf[4]); + /* dt->tm_mon is zero-based */ + dt->tm_mon = BCD_TO_BIN(buf[5]) - 1; + /* year is 1900 + dt->tm_year */ + dt->tm_year = BCD_TO_BIN(buf[6]) + 100; + + if (rtc_debug > 1) + { + printk("ds1307_get_datetime: year = %d\n", dt->tm_year); + printk("ds1307_get_datetime: mon = %d\n", dt->tm_mon); + printk("ds1307_get_datetime: mday = %d\n", dt->tm_mday); + printk("ds1307_get_datetime: hour = %d\n", dt->tm_hour); + printk("ds1307_get_datetime: min = %d\n", dt->tm_min); + printk("ds1307_get_datetime: sec = %d\n", dt->tm_sec); + } +} + +static int +ds1307_get_datetime(struct i2c_client *client, struct rtc_time *dt) +{ + unsigned char buf[7], addr[1] = { 0 }; + struct i2c_msg msgs[2] = { + { 0, 0, 1, addr }, + { 0, I2C_M_RD, 7, buf } + }; + int ret = -EIO; + + DPRINTK(1, "%s()\n", __FUNCTION__); + + if (client) { + + msgs[0].addr = client->addr; + msgs[1].addr = client->addr; + + memset(buf, 0, sizeof(buf)); + + ret = i2c_transfer(client->adapter, msgs, 2); + + if (ret == 2) { + ds1307_convert_to_time( dt, buf); + ret = 0; + } else { + DPRINTK(0, "%s: i2c_transfer() returned %d\n", __FUNCTION__, ret); + } + } + return ret; +} + +static int +ds1307_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo) +{ + unsigned char buf[8]; + int ret, len = 4; + + DPRINTK(1, "%s()\n", __FUNCTION__); + + if (!client) return -EIO; + + if (rtc_debug > 1) + { + printk("ds1307_set_datetime: tm_year = %d\n", dt->tm_year); + printk("ds1307_set_datetime: tm_mon = %d\n", dt->tm_mon); + printk("ds1307_set_datetime: tm_mday = %d\n", dt->tm_mday); + printk("ds1307_set_datetime: tm_hour = %d\n", dt->tm_hour); + printk("ds1307_set_datetime: tm_min = %d\n", dt->tm_min); + printk("ds1307_set_datetime: tm_sec = %d\n", dt->tm_sec); + } + + buf[0] = 0; /* register address on DS1307 */ + buf[1] = (BIN_TO_BCD(dt->tm_sec)); + buf[2] = (BIN_TO_BCD(dt->tm_min)); + buf[3] = (BIN_TO_BCD(dt->tm_hour)); + + if (datetoo) { + len = 8; + /* we skip buf[4] as we don't use day-of-week. */ + buf[5] = (BIN_TO_BCD(dt->tm_mday)); + buf[6] = (BIN_TO_BCD(dt->tm_mon + 1)); + /* The year only ranges from 0-99, we are being passed an offset from 1900, + * and the chip calulates leap years based on 2000, thus we adjust by 100. + */ + buf[7] = (BIN_TO_BCD(dt->tm_year - 100)); + } + ret = i2c_master_send(client, (char *)buf, len); + if (ret == len) + ret = 0; + else + DPRINTK(0, "%s: i2c_master_send() returned %d\n", __FUNCTION__, ret); + + return ret; +} + +static int +ds1307_get_ctrl(struct i2c_client *client, unsigned char *ctrl) +{ + unsigned char addr[1] = { 7 }; /* control register address on DS1307 */ + struct i2c_msg msgs[2] = { + { 0, 0, 1, addr }, + { 0, I2C_M_RD, 1, ctrl } + }; + int ret = -EIO; + + DPRINTK(1, "%s()\n", __FUNCTION__); + + if (client) { + + msgs[0].addr = client->addr; + msgs[1].addr = client->addr; + + *ctrl = 0; + + ret = i2c_transfer(client->adapter, msgs, 2); + + if (ret == 2) { + DPRINTK(2, "%s: info %d\n", __FUNCTION__, *ctrl); + ret = 0; + } else { + DPRINTK(0, "%s: i2c_transfer() returned %d\n", __FUNCTION__, ret); + } + } + + return ret; +} + +static int +ds1307_set_ctrl(struct i2c_client *client, unsigned char *cinfo) +{ + unsigned char buf[2]; + int ret; + + buf[0] = 7; /* control register address on DS1307 */ + buf[1] = *cinfo; + + DPRINTK(2, "%s: info %d\n", __FUNCTION__, buf[1]); + + ret = i2c_master_send(client, (char *)buf, 2); + + return ret; +} + +static int +ds1307_read_mem(struct i2c_client *client, struct rtc_mem *mem) +{ + unsigned char addr[1]; + struct i2c_msg msgs[2] = { + { client->addr, 0, 1, addr }, + { client->addr, I2C_M_RD, mem->nr, mem->data } + }; + + if ( (mem->loc < DS1307_RAM_ADDR_START) || + ((mem->loc + mem->nr -1) > DS1307_RAM_ADDR_END) ) + return -EINVAL; + + addr[0] = mem->loc; + + return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; +} + +static int +ds1307_write_mem(struct i2c_client *client, struct rtc_mem *mem) +{ + unsigned char addr[1]; + struct i2c_msg msgs[2] = { + { client->addr, 0, 1, addr }, + { client->addr, 0, mem->nr, mem->data } + }; + + if ( (mem->loc < DS1307_RAM_ADDR_START) || + ((mem->loc + mem->nr -1) > DS1307_RAM_ADDR_END) ) + return -EINVAL; + + addr[0] = mem->loc; + + return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; +} + +static int +ds1307_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + DPRINTK(1, "%s: cmd %d\n", __FUNCTION__, cmd); + + switch (cmd) { + case DS1307_GETDATETIME: + return ds1307_get_datetime(client, arg); + + case DS1307_SETTIME: + return ds1307_set_datetime(client, arg, 0); + + case DS1307_SETDATETIME: + return ds1307_set_datetime(client, arg, 1); + + case DS1307_GETCTRL: + return ds1307_get_ctrl(client, arg); + + case DS1307_SETCTRL: + return ds1307_set_ctrl(client, arg); + + case DS1307_MEM_READ: + return ds1307_read_mem(client, arg); + + case DS1307_MEM_WRITE: + return ds1307_write_mem(client, arg); + + default: + return -EINVAL; + } +} + +static int +ds1307_rtc_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int +ds1307_rtc_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static int +ds1307_rtc_ioctl( struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + unsigned long flags; + struct rtc_time wtime; + int status = 0; + + DPRINTK(2, "%s: cmd %c %x\n", __FUNCTION__, (char)(cmd>>8)&0xff, cmd&0xff); + + switch (cmd) { + default: + case RTC_UIE_ON: + case RTC_UIE_OFF: + case RTC_PIE_ON: + case RTC_PIE_OFF: + case RTC_AIE_ON: + case RTC_AIE_OFF: + case RTC_ALM_SET: + case RTC_ALM_READ: + case RTC_IRQP_READ: + case RTC_IRQP_SET: + case RTC_EPOCH_READ: + case RTC_EPOCH_SET: + case RTC_WKALM_SET: + case RTC_WKALM_RD: + status = -EINVAL; + break; + + case RTC_RD_TIME: + spin_lock_irqsave(&ds1307_rtc_lock, flags); + ds1307_command( ds1307_i2c_client, DS1307_GETDATETIME, &wtime); + spin_unlock_irqrestore(&ds1307_rtc_lock,flags); + + if( copy_to_user((void *)arg, &wtime, sizeof (struct rtc_time))) + status = -EFAULT; + break; + + case RTC_SET_TIME: + if (!capable(CAP_SYS_TIME)) + { + status = -EACCES; + break; + } + + if (copy_from_user(&wtime, (struct rtc_time *)arg, sizeof(struct rtc_time)) ) + { + status = -EFAULT; + break; + } + + spin_lock_irqsave(&ds1307_rtc_lock, flags); + ds1307_command( ds1307_i2c_client, DS1307_SETDATETIME, &wtime); + spin_unlock_irqrestore(&ds1307_rtc_lock,flags); + break; + } + + return status; +} + +static char * +ds1307_mon2str( unsigned int mon) +{ + char *mon2str[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + if( mon > 11) return "error"; + else return mon2str[ mon]; +} + +static int ds1307_rtc_proc_output( char *buf) +{ +#define CHECK(ctrl,bit) ((ctrl & bit) ? "yes" : "no") + unsigned char ram[DS1307_RAM_SIZE]; + int ret; + + char *p = buf; + + ret = ds1307_readram( ram, DS1307_RAM_SIZE); + if( ret > 0) + { + int i; + struct rtc_time dt; + char text[9]; + + p += sprintf(p, "DS1307 (64x8 Serial Real Time Clock)\n"); + + ds1307_convert_to_time( &dt, ram); + p += sprintf(p, "Date/Time : %02d-%s-%04d %02d:%02d:%02d\n", + dt.tm_mday, ds1307_mon2str(dt.tm_mon), dt.tm_year + 1900, + dt.tm_hour, dt.tm_min, dt.tm_sec); + + p += sprintf(p, "Clock halted : %s\n", CHECK(ram[0],0x80)); + p += sprintf(p, "24h mode : %s\n", CHECK(ram[2],0x40)); + p += sprintf(p, "Square wave enabled : %s\n", CHECK(ram[7],0x10)); + p += sprintf(p, "Freq : "); + + switch( ram[7] & 0x03) + { + case RATE_1HZ: + p += sprintf(p, "1Hz\n"); + break; + case RATE_4096HZ: + p += sprintf(p, "4.096kHz\n"); + break; + case RATE_8192HZ: + p += sprintf(p, "8.192kHz\n"); + break; + case RATE_32768HZ: + default: + p += sprintf(p, "32.768kHz\n"); + break; + + } + + p += sprintf(p, "RAM dump:\n"); + text[8]='\0'; + for( i=0; i126)) ram[i]='.'; + text[i%8] = ram[i]; + if( (i%8) == 7) p += sprintf(p, "%s\n",text); + } + p += sprintf(p, "\n"); + } + else + { + p += sprintf(p, "Failed to read RTC memory!\n"); + } + + return p - buf; +} + +static int ds1307_rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = ds1307_rtc_proc_output (page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static __init int ds1307_init(void) +{ + int retval=0; + + DPRINTK(1, "%s()\n", __FUNCTION__); + + if (slave_address != 0xffff) + { + DPRINTK(2, "%s: slave address is %#x\n", __FUNCTION__, slave_address); + normal_addr[0] = slave_address; + } + + if (normal_addr[0] == 0xffff) + { + printk(KERN_ERR"I2C: Invalid slave address for DS1307 RTC (%#x)\n", + normal_addr[0]); + return -EINVAL; + } + + retval = i2c_add_driver(&ds1307_driver); + + if (retval==0) + { + misc_register (&ds1307_rtc_miscdev); + create_proc_read_entry (PROC_DS1307_NAME, 0, 0, ds1307_rtc_read_proc, NULL); + printk("I2C: DS1307 RTC driver successfully loaded\n"); + if (rtc_debug > 2) ds1307_dumpram(); + } + return retval; +} + +static __exit void ds1307_exit(void) +{ + DPRINTK(1, "%s()\n", __FUNCTION__); + remove_proc_entry (PROC_DS1307_NAME, NULL); + misc_deregister(&ds1307_rtc_miscdev); + i2c_del_driver(&ds1307_driver); +} + +module_init(ds1307_init); +module_exit(ds1307_exit); + +MODULE_PARM (slave_address, "i"); +MODULE_PARM_DESC (slave_address, "I2C slave address for DS1307 RTC."); + +MODULE_AUTHOR ("Intrinsyc Software Inc."); +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/chips/ds1307.h b/drivers/i2c/chips/ds1307.h new file mode 100644 index 0000000..bf8cc20 --- /dev/null +++ b/drivers/i2c/chips/ds1307.h @@ -0,0 +1,54 @@ +/* + * ds1307.h + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef DS1307_H +#define DS1307_H + +#define DS1307_I2C_SLAVE_ADDR 0x68 + +#define DS1307_RAM_ADDR_START 0x08 +#define DS1307_RAM_ADDR_END 0x3F +#define DS1307_RAM_SIZE 0x40 + +#define PROC_DS1307_NAME "driver/ds1307" + +struct rtc_mem { + unsigned int loc; + unsigned int nr; + unsigned char *data; +}; + +#define DS1307_GETDATETIME 0 +#define DS1307_SETTIME 1 +#define DS1307_SETDATETIME 2 +#define DS1307_GETCTRL 3 +#define DS1307_SETCTRL 4 +#define DS1307_MEM_READ 5 +#define DS1307_MEM_WRITE 6 + +#define SQW_ENABLE 0x10 /* Square Wave Enable */ +#define SQW_DISABLE 0x00 /* Square Wave disable */ + +#define RATE_32768HZ 0x03 /* Rate Select 32.768KHz */ +#define RATE_8192HZ 0x02 /* Rate Select 8.192KHz */ +#define RATE_4096HZ 0x01 /* Rate Select 4.096KHz */ +#define RATE_1HZ 0x00 /* Rate Select 1Hz */ + +#define CLOCK_HALT 0x80 /* Clock Halt */ + +#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) +#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) + +#define TWELVE_HOUR_MODE(n) (((n)>>6)&1) +#define HOURS_AP(n) (((n)>>5)&1) +#define HOURS_12(n) BCD_TO_BIN((n)&0x1F) +#define HOURS_24(n) BCD_TO_BIN((n)&0x3F) + +#endif diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 02682fb..6a28f08 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c @@ -338,12 +338,37 @@ exit: static void ds1337_init_client(struct i2c_client *client) { s32 val; + u8 status, control; + + /* On some boards, the RTC isn't configured by boot firmware. + * Handle that case by starting/configuring the RTC now. + */ + status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); + control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); + + if ((status & 0x80) || (control & 0x80)) { + /* RTC not running */ + u8 buf[16]; + struct i2c_msg msg[1]; + + dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__); + + /* Initialize all, including STATUS and CONTROL to zero */ + memset(buf, 0, sizeof(buf)); + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].len = sizeof(buf); + msg[0].buf = &buf[0]; + + i2c_transfer(client->adapter, msg, 1); + } else { + /* Running: ensure that device is set in 24-hour mode */ + val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); + if ((val >= 0) && (val & (1 << 6))) + i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, + val & 0x3f); + } - /* Ensure that device is set in 24-hour mode */ - val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); - if ((val >= 0) && (val & (1 << 6))) - i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, - val & 0x3f); } static int ds1337_detach_client(struct i2c_client *client) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1c81174..e0fcc08 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -314,6 +314,18 @@ config BLK_DEV_CMD640_ENHANCED and your BIOS does not already do this for you, then say Y here. Otherwise say N. +config BLK_DEV_EP93XX + bool "EP93xx support" + depends on (ARCH_EP9312 || ARCH_EP9315) + help + If you want IDE support for your EP93xx based board say Y here. + +config BLK_DEV_IDEDMA_EP93XX + bool "EP93xx DMA support" + depends on BLK_DEV_EP93XX && EP93XX_DMA + help + If you want DMA support for your EP93xx based board say Y here. + config BLK_DEV_IDEPNP bool "PNP EIDE support" depends on PNP @@ -813,7 +825,7 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ depends BLK_DEV_IDE_AU1XXX config IDE_ARM - def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) + def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK || BLK_DEV_EP93XX) config BLK_DEV_IDE_ICSIDE tristate "ICS IDE interface support" @@ -1047,7 +1059,7 @@ config BLK_DEV_UMC8672 endif config BLK_DEV_IDEDMA - def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA || BLK_DEV_IDEDMA_EP93XX config IDEDMA_IVB bool "IGNORE word93 Validation BITS" diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile index 6a78f07..cf0f91a 100644 --- a/drivers/ide/arm/Makefile +++ b/drivers/ide/arm/Makefile @@ -2,5 +2,6 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o +obj-$(CONFIG_BLK_DEV_EP93XX) += ide-ep93xx.o EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/arm/ide-ep93xx.c b/drivers/ide/arm/ide-ep93xx.c new file mode 100644 index 0000000..75fbbf5 --- /dev/null +++ b/drivers/ide/arm/ide-ep93xx.c @@ -0,0 +1,1957 @@ +/***************************************************************************** + * + * drivers/ide/ide-ep93xx.c + * + * Copyright (c) 2003 Cirrus Logic, Inc. + * + * Some code based in whole or in part on: + * + * linux/drivers/ide/ide-dma.c Version 4.13 May 21, 2003 + * + * Copyright (c) 1999-2000 Andre Hedrick + * May be copied or modified under the terms of the GNU General Public License + * + * Portions Copyright Red Hat 2003 + * + * Special Thanks to Mark for his Six years of work. + * + * Copyright (c) 1995-1998 Mark Lord + * May be copied or modified under the terms of the GNU General Public License + * + * + * Some code taken from the PowerMac implentation + * + * Copyright (C) 1998-2001 Paul Mackerras & Ben. Herrenschmidt + * + * 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 + * + * *************************************************************************** + * + * Cirrus Logic's EP93XX architecture specific ide driver. This driver + * supports the following ide transfer modes: + * PIO modes 0 - 4 + * MDMA modes 0 - 2 + * UDMA modes 0 - 4 + * + * 2/17/04 - TO - Initial DMA support. Only UDMA on ATA hard drives for now. + * + ****************************************************************************/ +#include +#include +#include +#include +#include + +#include + +#include +#include + +/***************************************************************************** + * + * Debugging macros + * + ****************************************************************************/ +#undef DEBUG + /* #define DEBUG 1 */ +#ifdef DEBUG +#define DPRINTK( x... ) printk( ##x ) +#else +#define DPRINTK( x... ) +#endif + +/* + * IDE control register mask used when setting the CS0n, CS1n and DA bits + * in this register. + */ +#define IDECR_REG_MASK (IDECtrl_CS0n | IDECtrl_CS1n | IDECtrl_DA_MASK) + +/***************************************************************************** + * + * Functions and macros for handling dma transfers. + * + ****************************************************************************/ +#ifdef CONFIG_BLK_DEV_IDEDMA_EP93XX + +/***************************************************************************** + * + * Our Physical Region Descriptor (PRD) table should be large enough + * to handle the biggest I/O request we are likely to see. Since requests + * can have no more than 256 sectors, and since the typical blocksize is + * two or more sectors, we could get by with a limit of 128 entries here for + * the usual worst case. Most requests seem to include some contiguous blocks, + * further reducing the number of table entries required. + * + * The driver reverts to PIO mode for individual requests that exceed + * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling + * 100% of all crazy scenarios here is not necessary. + * + * As it turns out though, we must allocate a full 4KB page for this, + * so the two PRD tables (ide0 & ide1) will each get half of that, + * allowing each to have about 256 entries (8 bytes each) from this. + * + ****************************************************************************/ +#define PRD_BYTES 8 +#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES)) + +/***************************************************************************** + * + * Global to keep track of the number of entries in the dma buffer + * table for each transfer. + * + ****************************************************************************/ +static int g_prd_count; +static unsigned int g_prd_total; +static unsigned int g_prd_returned; +static unsigned int g_dma_table_base; + +/***************************************************************************** + * + * Global to set during the dma callback function to indicate that from + * the dma perspective, the transfer is complete. + * + ****************************************************************************/ +static unsigned int g_done; + +/***************************************************************************** + * + * The following is directly from ide-dma.c. + * + ****************************************************************************/ +struct drive_list_entry { + const char *id_model; + const char *id_firmware; +}; + +static const struct +drive_list_entry drive_whitelist[] = { + {"Micropolis 2112A", "ALL"}, + {"CONNER CTMA 4000", "ALL"}, + {"CONNER CTT8000-A", "ALL"}, + {"ST34342A", "ALL"}, + {NULL, NULL} +}; + +static const struct +drive_list_entry drive_blacklist[] = { + {"WDC AC11000H", "ALL"}, + {"WDC AC22100H", "ALL"}, + {"WDC AC32500H", "ALL"}, + {"WDC AC33100H", "ALL"}, + {"WDC AC31600H", "ALL"}, + {"WDC AC32100H", "24.09P07"}, + {"WDC AC23200L", "21.10N21"}, + {"Compaq CRD-8241B", "ALL"}, + {"CRD-8400B", "ALL"}, + {"CRD-8480B", "ALL"}, + {"CRD-8480C", "ALL"}, + {"CRD-8482B", "ALL"}, + {"CRD-84", "ALL"}, + {"SanDisk SDP3B", "ALL"}, + {"SanDisk SDP3B-64", "ALL"}, + {"SANYO CD-ROM CRD", "ALL"}, + {"HITACHI CDR-8", "ALL"}, + {"HITACHI CDR-8335", "ALL"}, + {"HITACHI CDR-8435", "ALL"}, + {"Toshiba CD-ROM XM-6202B", "ALL"}, + {"CD-532E-A", "ALL"}, + {"E-IDE CD-ROM CR-840", "ALL"}, + {"CD-ROM Drive/F5A", "ALL"}, + {"RICOH CD-R/RW MP7083A", "ALL"}, + {"WPI CDD-820", "ALL"}, + {"SAMSUNG CD-ROM SC-148C", "ALL"}, + {"SAMSUNG CD-ROM SC-148F", "ALL"}, + {"SAMSUNG CD-ROM SC", "ALL"}, + {"SanDisk SDP3B-64", "ALL"}, + {"SAMSUNG CD-ROM SN-124", "ALL"}, + {"PLEXTOR CD-R PX-W8432T", "ALL"}, + {"ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL"}, + {"_NEC DV5800A", "ALL"}, + {NULL, NULL} +}; + +/***************************************************************************** + * + * This is directly from ide-dma.c + * + * in_drive_list - look for drive in black/white list + * @id: drive identifier + * @drive_table: list to inspect + * + * Look for a drive in the blacklist and the whitelist tables + * Returns 1 if the drive is found in the table. + * + ****************************************************************************/ +static int +in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) +{ + for (; drive_table->id_model; drive_table++) + if ((!strcmp(drive_table->id_model, id->model)) && + ((!strstr(drive_table->id_firmware, id->fw_rev)) || + (!strcmp(drive_table->id_firmware, "ALL")))) + return 1; + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_intr() is the handler for disk read/write DMA interrupts + * + ****************************************************************************/ +ide_startstop_t ep93xx_ide_dma_intr(ide_drive_t * drive) +{ + int i; + byte stat, dma_stat; + + DPRINTK("\n dma_intr \n"); + + /* + * Disable the dma for this transfer and cleanup. + */ + dma_stat = ep93xx_ide_dma_end(drive); + + /* + * Get status from the ide device. + */ + stat = HWIF(drive)->INB(IDE_STATUS_REG); + + if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) { + if (!dma_stat) { + struct request *rq = HWGROUP(drive)->rq; + + for (i = rq->nr_sectors; i > 0;) { + i -= rq->current_nr_sectors; + DRIVER(drive)->end_request(drive, 1); + } + + return ide_stopped; + } + + printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", + drive->name, dma_stat); + } + + return DRIVER(drive)->error(drive, __FUNCTION__, stat); +} + +/***************************************************************************** + * + * ide_build_sglist() + * + * Builds a table of buffers to be used by the dma. Each buffer consists + * of a region of memory which is contiguous in virtual memory. + * + ****************************************************************************/ +static int ide_build_sglist(ide_hwif_t * hwif, struct request *rq) +{ + struct buffer_head *buf_head; + struct scatterlist *sg = hwif->sg_table; + int nents = 0; + + if (hwif->sg_dma_active) + BUG(); + + DPRINTK("\nbuild_sglist: sg_table 0x%x, ", hwif->sg_table); + + /* + * Set up the direction of the command + */ + if (rq->cmd == READ) { + hwif->sg_dma_direction = EP93XX_DMA_FROMDEVICE; + } else { + hwif->sg_dma_direction = EP93XX_DMA_TODEVICE; + } + + /* + * Get a pointer to the buffer head. + */ + buf_head = rq->bh; + + do { + unsigned char *virt_addr = buf_head->b_data; + unsigned int size = buf_head->b_size; + + if (nents >= PRD_ENTRIES) { + return 0; + } + + while ((buf_head = buf_head->b_reqnext) != NULL) { + if ((virt_addr + size) != + (unsigned char *)buf_head->b_data) { + break; + } + + size += buf_head->b_size; + } + memset(&sg[nents], 0, sizeof(*sg)); + sg[nents].address = virt_addr; + sg[nents].length = size; + nents++; + } while (buf_head != NULL); + + /* + * This call to map_sg will return the number of entries + * for which DMAable memory could be mapped. + */ + return ep93xx_map_sg(sg, nents, hwif->sg_dma_direction); +} + +/**************************************************************************** + * + * report_drive_dmaing() + * + ****************************************************************************/ +int report_drive_dmaing(ide_drive_t * drive) +{ + struct hd_driveid *id = drive->id; + + if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && + (id->dma_ultra & (id->dma_ultra >> 14) & 3)) { + if ((id->dma_ultra >> 15) & 1) { + /* + * UDMA enabled + */ + printk(", UDMA(mode 7)"); + } else { + /* + * UDMA enabled. + */ + printk(", UDMA(133)"); + } + } else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && + (id->dma_ultra & (id->dma_ultra >> 11) & 7)) { + DPRINTK("\n report_drive_dmaing: %d \n", id->dma_ultra); + if ((id->dma_ultra >> 13) & 1) { + /* + * UDMA enabled! + */ + printk(", UDMA(100)"); + } else if ((id->dma_ultra >> 12) & 1) { + /* + * UDMA enabled. + */ + printk(", UDMA(66)"); + } else { + /* + * UDMA enabled. + */ + printk(", UDMA(44)"); + } + } else if ((id->field_valid & 4) && + (id->dma_ultra & (id->dma_ultra >> 8) & 7)) { + if ((id->dma_ultra >> 10) & 1) { + /* + * UDMA enabled. + */ + printk(", UDMA(33)"); + } else if ((id->dma_ultra >> 9) & 1) { + /* + * UDMA enabled. + */ + printk(", UDMA(25)"); + } else { + /* + * UDMA enabled. + */ + printk(", UDMA(16)"); + } + } else if (id->field_valid & 4) { + /* + * Can be enabled. + */ + printk(", (U)DMA capable, but not enabled"); + } else { + /* + * maybe MDMA? + */ + printk(", DMA"); + } + + return 1; +} + +/***************************************************************************** + * + * ide_build_dmatable() prepares a dma request. + * Returns 0 if all went okay, returns 1 otherwise. + * + ****************************************************************************/ +int ide_build_dmatable(ide_drive_t * drive) +{ + unsigned int *table = HWIF(drive)->dmatable_cpu; + unsigned int count = 0; + int i; + struct scatterlist *sg; + unsigned int is_trm290_chipset = 0; + + HWIF(drive)->sg_nents = i = + ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq); + + if (!i) + return 0; + + sg = HWIF(drive)->sg_table; + + while (i && sg_dma_len(sg)) { + u32 cur_addr; + u32 cur_len; + + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); + + /* 1 + * Fill in the dma table, without crossing any 64kB boundaries. + * Most hardware requires 16-bit alignment of all blocks, + * but the trm290 requires 32-bit alignment. + */ + while (cur_len) { + + if (count++ >= PRD_ENTRIES) { + printk("%s: DMA table too small\n", + drive->name); + goto use_pio_instead; + } else { + u32 xcount, bcount = + 0x10000 - (cur_addr & 0xffff); + + if (bcount > cur_len) + bcount = cur_len; + *table++ = cpu_to_le32(cur_addr); + xcount = bcount & 0xffff; + if (is_trm290_chipset) + xcount = ((xcount >> 2) - 1) << 16; + if (xcount == 0x0000) { + /* + * Most chipsets correctly interpret a length of 0x0000 as 64KB, + * but at least one (e.g. CS5530) misinterprets it as zero (!). + * So here we break the 64KB entry into two 32KB entries instead. + */ + if (count++ >= PRD_ENTRIES) { + printk + ("%s: DMA table too small\n", + drive->name); + goto use_pio_instead; + } + *table++ = cpu_to_le32(0x8000); + *table++ = + cpu_to_le32(cur_addr + 0x8000); + xcount = 0x8000; + } + *table++ = cpu_to_le32(xcount); + cur_addr += bcount; + cur_len -= bcount; + } + } + sg++; + i--; + } + + if (count) { + if (!is_trm290_chipset) + *--table |= cpu_to_le32(0x80000000); + return count; + } + printk("%s: empty DMA table?\n", drive->name); + + use_pio_instead: + /* + * Revert to PIO for this request. + */ + HWIF(drive)->sg_dma_active = 0; + return 0; +} + +/***************************************************************************** + * + * ide_destroy_dmatable() + * + * Teardown mappings after DMA has completed. + * + ****************************************************************************/ +void ide_destroy_dmatable(ide_drive_t * drive) +{ + /* + * Restore the original dma table base address. + */ + HWIF(drive)->dmatable_cpu = g_dma_table_base; + + /* + * Nothing much to do here. + */ + HWIF(drive)->sg_dma_active = 0; +} + +/***************************************************************************** + * + * ide_release_dma() + * + * This function releases the memory allocated for the scatter gather list + * and for the dma table, and frees the dma channel. + * + ****************************************************************************/ +void ep93xx_ide_release_dma(ide_hwif_t * hwif) +{ + /* + * Check if we have a valid dma handle. + */ + if (hwif->hw.dma != NULL) { + /* + * Pause the DMA channel. + */ + ep93xx_dma_pause(hwif->hw.dma, 1, 0); + + /* + * Flush the DMA channel + */ + ep93xx_dma_flush(hwif->hw.dma); + } +} + +/***************************************************************************** + * + * ep93xx_ide_callback() + * + * Registered with the ep93xx dma driver and called at the end of the dma + * interrupt handler, this function should process the dma buffers. + * + ****************************************************************************/ + +static void +ep93xx_ide_callback(ep93xx_dma_int_t dma_int, ep93xx_dma_dev_t device, + unsigned int user_data) +{ + ide_drive_t *drive = (ide_drive_t *) user_data; + ide_hwif_t *hwif = HWIF(drive); + unsigned int temp; + + /* + * Retrieve from the dma interface as many used buffers as are + * available. + */ + while (ep93xx_dma_remove_buffer(hwif->hw.dma, &temp) == 0) { + g_prd_returned++; + + } + + /* + * Add new buffers if we have any available. + */ + while (g_prd_count) { + /* + * Check if this is a read or write operation. + */ + if (hwif->sg_dma_direction == 2) { + /* + * Set up buffers for a read op. + */ + temp = + ep93xx_dma_add_buffer(hwif->hw.dma, hwif->dma_base, + *hwif->dmatable_cpu++, + *hwif->dmatable_cpu++, 0, + g_prd_count); + } else { + /* + * Set up buffers for a write op. + */ + temp = + ep93xx_dma_add_buffer(hwif->hw.dma, + *hwif->dmatable_cpu++, + hwif->dma_base, + *hwif->dmatable_cpu++, 0, + g_prd_count); + } + + /* + * Add a buffer to the dma interface. + */ + if (temp != 0) { + /* + * This buffer didn't make it into the dma + * interface, so move the dma table pointer + * to the start of the current entry. + */ + hwif->dmatable_cpu -= 4; + break; + } + + /* + * Decrement the count of dmatable entries + */ + g_prd_count--; + } + + /* + * Check if the transfer is complete. + */ + if (dma_int == DONE) { + g_done = 1; + } + + if (g_prd_returned == g_prd_total) { + g_done = 1; + } +} + +/***************************************************************************** + * + * ep93xx_dma_timer_expiry() + * + * + * dma_timer_expiry - handle a DMA timeout + * @drive: Drive that timed out + * + * An IDE DMA transfer timed out. In the event of an error we ask + * the driver to resolve the problem, if a DMA transfer is still + * in progress we continue to wait (arguably we need to add a + * secondary 'I dont care what the drive thinks' timeout here) + * Finally if we have an interrupt we let it complete the I/O. + * But only one time - we clear expiry and if it's still not + * completed after WAIT_CMD, we error and retry in PIO. + * This can occur if an interrupt is lost or due to hang or bugs. + * + * + ****************************************************************************/ +static int ep93xx_idedma_timer_expiry(ide_drive_t * drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 dev_stat = hwif->INB(IDE_ALTSTATUS_REG); + u8 irq_stat = ep93xx_ide_regs->IDECR.Value & IDECtrl_INTRQ; + + printk(KERN_WARNING + "%s: dma_timer_expiry: dev status == 0x%02x, done= %d, irq= %d\n", + drive->name, dev_stat, g_done, irq_stat); + + /* + * Check if the device is busy, or the dma engine is still working. + */ + if ((dev_stat & 0x80) || !g_done) /* BUSY Stupid Early Timer !! */ + return (2 * WAIT_CMD); + + /* + * Clear the expiry handler in case we decide to wait more, + * next time timer expires it is an error + */ + HWGROUP(drive)->expiry = NULL; + + /* + * the device is not busy, so check if there's an error, or if the + * interrupt is asserted. + */ + if (dev_stat & 0x01) /* ERROR */ + return -1; + + if (irq_stat || g_done) /* Got an Interrupt or the dma is done */ + return WAIT_CMD; + + return 0; /* Unknown status -- reset the bus */ +} + +/***************************************************************************** + * + * ep93xx_config_ide_dma() + * + * This function allocates dma-able memory and configures the ep93xx dma + * interface for use with the ide interface. This only need be done + * once for the interface. So, if this is the second drive, we don't have + * much to do here. + * + ****************************************************************************/ +static int ep93xx_config_ide_dma(ide_drive_t * drive) +{ + DPRINTK("ep93xx_config_ide_dma\n"); + + /* + * Success. + */ + return 0; +} + +/***************************************************************************** + * + * ep93xx_config_ide_device() + * + * This function sets up the ep93xx ide device for a dma transfer by first + * probing to find the best dma mode supported by the device. + * + * Returns a 0 for success, and a 1 otherwise. + * + ****************************************************************************/ +static unsigned int ep93xx_config_ide_device(ide_drive_t * drive) +{ + struct hd_driveid *id = drive->id; + byte transfer = 0; + + DPRINTK("%s: ep93xx_config_ide_device - dma on\n", HWIF(drive)->name); + + /* + * check if the device supports a udma mode. + */ + if (transfer = (id->dma_ultra & 0x001F)) { + DPRINTK("IDE: udma xfer support, transfer = %d \n", transfer); + + /* + * UDMA mode 4 support. + */ + if (transfer & 0x10) { + transfer = XFER_UDMA_4; + } + /* + * UDMA mode 3 support. + */ + else if (transfer & 0x08) { + transfer = XFER_UDMA_3; + } + /* + * UDMA mode 2. + */ + else if (transfer & 0x04) { + transfer = XFER_UDMA_2; + } + /* + * UDMA mode 1. + */ + else if (transfer & 0x02) { + transfer = XFER_UDMA_1; + } + /* + * UDMA mode 0. + */ + else if (transfer & 0x01) { + transfer = XFER_UDMA_0; + } + } + /* + * The device doesn't support a udma mode, so check if it + * supports an mdma mode. + */ + else if (transfer = (drive->id->dma_mword & 0x0007)) { + DPRINTK("IDE: mdma support, transfer = %d \n", transfer); + + /* + * MDMA mode 2. + */ + if (transfer & 0x04) { + transfer = XFER_MW_DMA_2; + } + /* + * MDMA mode 1. + */ + else if (transfer & 0x02) { + transfer = XFER_MW_DMA_1; + } + /* + * MDMA mode 0. + */ + else if (transfer & 0x01) { + transfer = XFER_MW_DMA_0; + } + } + + if (transfer == 0) { + DPRINTK("IDE: config device failed \n"); + + /* + * Fail. + */ + return 1; + } + + if (ide_config_drive_speed(drive, transfer) == 0) { + printk("%s: %s selected\n", drive->name, + ide_xfer_verbose(transfer)); + + /* + * Hold on to this value for use later. + */ + drive->current_speed = transfer; + + /* + * Success, so turn on DMA. + */ + return ep93xx_ide_dma_on(drive); + } else { + return ep93xx_ide_dma_off(drive); + } +} + +/***************************************************************************** + * + * ep93xx_set_pio() + * + * Configures the ep93xx controller for a PIO mode transfer. + * + ****************************************************************************/ +static void ep93xx_set_pio(void) +{ + /* + * Disable the interface. + */ + ep93xx_ide_regs->IDECFG.Field.IDEEN = 0; + + /* + * Enable PIO mode of operation. + */ + ep93xx_ide_regs->IDECFG.Field.PIO = 1; + ep93xx_ide_regs->IDECFG.Field.UDMA = 0; + ep93xx_ide_regs->IDECFG.Field.MDMA = 0; + + /* + * Enable the IDE interface. + */ + ep93xx_ide_regs->IDECFG.Field.IDEEN = 1; +} + +/***************************************************************************** + * + * ep93xx_rwproc() + * + * Initializes the ep93xx IDE controller interface with the transfer type, + * transfer mode, and transfer direction. + * + ****************************************************************************/ +static void ep93xx_rwproc(ide_drive_t * drive, int action) +{ + unsigned int temp; + + DPRINTK("\nep93xx_rwproc \n"); + /* + * Configure the IDE controller for the specified transfer mode. + */ + switch (drive->current_speed) { + /* + * Configure for an MDMA operation. + */ + case XFER_MW_DMA_0: + case XFER_MW_DMA_1: + case XFER_MW_DMA_2: + { + DPRINTK("\n ep93xx set up for MDMA \n"); + ep93xx_ide_regs->IDECFG.Field.PIO = 0; + ep93xx_ide_regs->IDECFG.Field.UDMA = 0; + ep93xx_ide_regs->IDECFG.Field.MDMA = 1; + ep93xx_ide_regs->IDECFG.Field.MODE = + (0x3 & drive->current_speed); + ep93xx_ide_regs->IDECFG.Field.IDEEN = 1; + ep93xx_ide_regs->IDEMDMAOP.Field.RWOP = action; + ep93xx_ide_regs->IDEMDMAOP.Field.MEN = 1; + break; + } + + /* + * Configure for a UDMA operation. + */ + case XFER_UDMA_0: + case XFER_UDMA_1: + case XFER_UDMA_2: + case XFER_UDMA_3: + case XFER_UDMA_4: + { + DPRINTK("\n ep93xx set up for UDMA \n"); + ep93xx_ide_regs->IDECFG.Field.IDEEN = 0; + ep93xx_ide_regs->IDEUDMAOP.Field.UEN = 0; + ep93xx_ide_regs->IDECFG.Field.PIO = 0; + ep93xx_ide_regs->IDECFG.Field.MDMA = 0; + ep93xx_ide_regs->IDECFG.Field.UDMA = 0; + ep93xx_ide_regs->IDECFG.Field.WST = 0; + ep93xx_ide_regs->IDECFG.Field.IDEEN = 1; + + ep93xx_ide_regs->IDECFG.Field.MODE = + (0x7 & drive->current_speed); + ep93xx_ide_regs->IDECFG.Field.UDMA = 1; + ep93xx_ide_regs->IDEUDMAOP.Field.RWOP = action; + temp = ep93xx_ide_regs->IDEUDMAOP.Value; + ep93xx_ide_regs->IDEUDMAOP.Field.UEN = 1; + temp = ep93xx_ide_regs->IDEUDMAOP.Value; + + DPRINTK("\nIDE Regs: config - 0x%x, udmaop - 0x%x \n", + ep93xx_ide_regs->IDECFG.Value, + ep93xx_ide_regs->IDEUDMAOP.Value); + + break;; + } + + default: + { + break; + } + } +} + +/***************************************************************************** + * + * ep93xx_ide_dma_check() + * + * This function determines if the device supports dma transfers, and if it + * does, then enables dma. + * + ****************************************************************************/ +int ep93xx_ide_dma_check(ide_drive_t * drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct hd_driveid *id = drive->id; + + DPRINTK("%s: ep93xx_ide_dma_check \n", drive->name); + + if (!id || !(id->capability & 1) || !hwif->autodma) { + /* + * Disable dma for this drive. + */ + ep93xx_ide_dma_off(drive); + } + + /* + * Consult the list of known "bad" drives + */ + if (in_drive_list(id, drive_blacklist)) { + printk("%s: Disabling DMA for %s (blacklisted)\n", + drive->name, id->model); + + /* + * Disable dma for this drive. + */ + ep93xx_ide_dma_off(drive); + } + + /* + * Check if the drive supports multiword dma or udma modes. + * If it does, then set the device up for that + * type of dma transfer, and call ep93xx_ide_dma_on. + */ + return ep93xx_config_ide_device(drive); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_host_off() + * + * This function disables dma for the host. + * + ****************************************************************************/ +int ep93xx_ide_dma_host_off(ide_drive_t * drive) +{ + ide_hwif_t *hwif = HWIF(drive); + + /* + * TODO: what's to be done here? + */ + DPRINTK("%s: ep93xx_ide_dma_host_off() \n", drive->name); + + /* + * Release the dma channel and all memory allocated for dma + * purposes. + */ + ep93xx_ide_release_dma(hwif); + + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_off_quietly() + * + * This function, without announcing it, disables dma for the device. + * + ****************************************************************************/ +int ep93xx_ide_dma_off_quietly(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_off_quietly: \n", drive->name); + + /* + * Clear the using_dma field to indicate that dma is disabled + * for this drive. + */ + drive->using_dma = 0; + + /* + * Disable dma on the host side. + */ + ep93xx_ide_dma_host_off(drive); + + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_off() + * + * This function disables dma for the device. + * + ****************************************************************************/ +int ep93xx_ide_dma_off(ide_drive_t * drive) +{ + printk("%s: DMA disabled\n", drive->name); + + return ep93xx_ide_dma_off_quietly(drive); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_on() + * + * This function enables dma for the device. + * + ****************************************************************************/ +int ep93xx_ide_dma_on(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_on: \n", drive->name); + + if (drive->using_dma) { + DPRINTK("%s: ep93xx_ide_dma_on, already on! \n", drive->name); + return 0; + } + + /* + * Set the using_dma field to indicate that dma is enabled. + */ + drive->using_dma = 1; + + /* + * Enable DMA on the host side. + */ + return ep93xx_ide_dma_host_on(drive); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_host_on() + * + * This function enables dma for the device. + * + ****************************************************************************/ +int ep93xx_ide_dma_host_on(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_host_on: \n", drive->name); + + /* + * Enable the ep93xx dma interface for use with IDE. + */ + return ep93xx_config_ide_dma(drive); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_read() + * + * This function sets up a dma read operation. + * + ****************************************************************************/ +int ep93xx_ide_dma_read(ide_drive_t * drive) +{ + unsigned int flags, result; + ide_hwif_t *hwif = HWIF(drive); + + DPRINTK("%s: ep93xx_ide_dma_read: \n", drive->name); + + /* + * Check if we are already transferring on this dma channel. + */ + BUG_ON(hwif->sg_dma_active); + + /* + * Configure DMA M2M channel flags for a source address hold, h/w + * initiated P2M transfer. + */ + flags = (SOURCE_HOLD | TRANSFER_MODE_HW_P2M); + + if (drive->current_speed & 0x20) { + flags |= (WS_IDE_MDMA_READ_WRITE << WAIT_STATES_SHIFT); + + /* + * MDMA data register address. + */ + hwif->dma_base = 0x800A001C; + } else { + flags |= (WS_IDE_UDMA_READ << WAIT_STATES_SHIFT); + + /* + * UDMA data register address. + */ + hwif->dma_base = 0x800a0024; + } + + /* + * Configure the dma interface for this IDE operation. + */ + if (ep93xx_dma_config(hwif->hw.dma, 0, flags, ep93xx_ide_callback, + (unsigned int)drive) != 0) { + DPRINTK("%s: ep93xx_ide_dma_read: ERROR- dma config failed", + drive->name); + + /* + * Fail. + */ + return 1; + } + + /* + * Build the table of dma-able buffers. + */ + if (!(g_prd_count = ide_build_dmatable(drive))) { + DPRINTK + ("%s: ep93xx_ide_dma_read: ERROR- failed to build dma table", + drive->name); + + /* + * Fail, try PIO instead of DMA + */ + return 1; + } + + /* + * Indicate that we're waiting for dma. + */ + drive->waiting_for_dma = 1; + + hwif->sg_dma_active = 1; + + /* + * test stuff + */ + g_prd_total = g_prd_count; + g_prd_returned = 0; + g_dma_table_base = hwif->dmatable_cpu; + + /* + * Prepare the dma interface with some buffers from the + * dma_table. + */ + do { + /* + * Add a buffer to the dma interface. + */ + result = ep93xx_dma_add_buffer(hwif->hw.dma, hwif->dma_base, + *hwif->dmatable_cpu++, + *hwif->dmatable_cpu++, 0, + g_prd_count); + + if (result != 0) { + /* + * This buffer didn't make it into the dma + * interface, so move the dma table pointer + * to the start of the current entry. + */ + hwif->dmatable_cpu -= 4; + break; + } + + /* + * Decrement the count of dmatable entries + */ + g_prd_count--; + + } while (g_prd_count); + + /* + * Check if this is a disk or cd drive. + */ + if (drive->media == ide_disk) { + /* + * Send the read command to the device. + */ + ide_execute_command(drive, WIN_READDMA, &ep93xx_ide_dma_intr, + 4 * WAIT_CMD, &ep93xx_idedma_timer_expiry); + + } + + /* + * Configure the ep93xx ide controller for a dma read operation. + */ + ep93xx_rwproc(drive, 0); + + /* + * initiate the dma transfer. + */ + return ep93xx_ide_dma_begin(drive); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_write() + * + * This function sets up a dma write operation. + * + ****************************************************************************/ +int ep93xx_ide_dma_write(ide_drive_t * drive) +{ + unsigned int flags, result; + ide_hwif_t *hwif = HWIF(drive); + + DPRINTK("%s: ep93xx_ide_dma_write: \n", drive->name); + + /* + * Check if we are already transferring on this dma channel. + */ + BUG_ON(hwif->sg_dma_active); + + /* + * Configure DMA M2M channel flags for a destination address + * hold, h/w initiated M2P transfer. + */ + flags = (DESTINATION_HOLD | TRANSFER_MODE_HW_M2P); + + /* + * Determine if we need the MDMA or UDMA data register. + */ + if (drive->current_speed & 0x20) { + flags |= (WS_IDE_MDMA_READ_WRITE << WAIT_STATES_SHIFT); + + /* + * MDMA data register address. + */ + hwif->dma_base = 0x800A0018; + } else { + flags |= (WS_IDE_UDMA_WRITE << WAIT_STATES_SHIFT); + + /* + * UDMA data register address. + */ + hwif->dma_base = 0x800a0020; + } + + /* + * Configure the dma interface for this IDE operation. + */ + if (ep93xx_dma_config(hwif->hw.dma, 0, flags, ep93xx_ide_callback, + (unsigned int)drive) != 0) { + return 1; + } + + /* + * Build the table of dma-able buffers. + */ + if (!(g_prd_count = ide_build_dmatable(drive))) { + /* + * Fail, try PIO instead of DMA + */ + return 1; + } + + /* + * Indicate that we're waiting for dma. + */ + drive->waiting_for_dma = 1; + + hwif->sg_dma_active = 1; + + /* + * test stuff + */ + g_prd_total = g_prd_count; + g_prd_returned = 0; + g_dma_table_base = hwif->dmatable_cpu; + + /* + * Prepare the dma interface with some buffers from the + * dma_table. + */ + do { + /* + * Add a buffer to the dma interface. + */ + result = + ep93xx_dma_add_buffer(hwif->hw.dma, *hwif->dmatable_cpu++, + hwif->dma_base, *hwif->dmatable_cpu++, + 0, g_prd_count); + + if (result != 0) { + /* + * This buffer didn't make it into the dma + * interface, so move the dma table pointer + * to the start of the current entry. + */ + hwif->dmatable_cpu -= 4; + break; + } + + /* + * Decrement the count of dmatable entries + */ + g_prd_count--; + + } while (g_prd_count); + + /* + * Check if this is a disk or cd drive. + */ + if (drive->media == ide_disk) { + /* + * Send the write dma command to the device. + */ + ide_execute_command(drive, WIN_WRITEDMA, &ep93xx_ide_dma_intr, + 4 * WAIT_CMD, &ep93xx_idedma_timer_expiry); + } + + /* + * Configure the ep93xx ide controller for a dma read operation. + */ + ep93xx_rwproc(drive, 1); + + /* + * initiate the dma transfer. + */ + return ep93xx_ide_dma_begin(drive); + +} + +/***************************************************************************** + * + * ep93xx_ide_dma_begin() + * + * This function initiates a dma transfer. + * + ****************************************************************************/ +int ep93xx_ide_dma_begin(ide_drive_t * drive) +{ + ide_hwif_t *hwif = HWIF(drive); + + DPRINTK("%s: ep93xx_ide_dma_begin: \n", drive->name); + + /* Note that this is done *after* the cmd has + * been issued to the drive, as per the BM-IDE spec. + * The Promise Ultra33 doesn't work correctly when + * we do this part before issuing the drive cmd. + */ + g_done = 0; + + /* + * Start the dma transfer. + */ + ep93xx_dma_start(hwif->hw.dma, 1, NULL); + + /* + * TODO: not sure if we need to keep track of the end + * of the transfer from the dma perspective, but + * for now, let's do it. + */ + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_end() + * + * This function performs any tasks needed to cleanup after a dma transfer. + * Returns 1 if an error occured, and 0 otherwise. + * + ****************************************************************************/ +int ep93xx_ide_dma_end(ide_drive_t * drive) +{ + unsigned char dev_stat; + ide_hwif_t *hwif = HWIF(drive); + + DPRINTK("%s: ep93xx_ide_dma_end: \n", drive->name); + + /* + * Indicate there's no dma transfer currently in progress. + */ + drive->waiting_for_dma = 0; + + /* + * Put the dma interface into pause mode. + */ + ep93xx_dma_pause(hwif->hw.dma, 1, 0); + ep93xx_dma_flush(hwif->hw.dma); + + /* + * Enable PIO mode on the IDE interface. + */ + ep93xx_set_pio(); + + /* + * Read the ide device status register. This clears the interrupt. + * TODO: should I read the alt status instead to prevent clearing + * an asserted interrupt?? + */ + dev_stat = hwif->INB(IDE_STATUS_REG); + + /* + * Purge the contents of the dma table of buffer entries. + */ + ide_destroy_dmatable(drive); + + hwif->sg_dma_active = 0; + + /* + * If the error bit is set in the device status register, + * return a positive value. + */ + if (dev_stat & ERR_STAT) { + printk("ide_dma_end: device error \n"); + return 1; + } else { + return 0; + } +} + +/***************************************************************************** + * + * ep93xx_ide_dma_test_irq() + * + * This function checks if the IDE interrupt is asserted and returns a + * 1 if it is, and 0 otherwise.. + * + ****************************************************************************/ +int ep93xx_ide_dma_test_irq(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_test_irq: \n", drive->name); + + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __FUNCTION__); + + /* + * TODO: need to use the io macros to get this value. + * Return the value of the IDE interrupt bit. + */ + return (ep93xx_ide_regs->IDECR.Value & IDECtrl_INTRQ); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_bad_drive() + * + ****************************************************************************/ +int ep93xx_ide_dma_bad_drive(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_bad_drive: \n", drive->name); + + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_good_drive() + * + ****************************************************************************/ +int ep93xx_ide_dma_good_drive(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_good_drive: \n", drive->name); + + /* + * TODO: need to implement. + */ + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_count() + * + ****************************************************************************/ +int ep93xx_ide_dma_count(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_count: \n", drive->name); + + return 0; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_verbose() + * + ****************************************************************************/ +int ep93xx_ide_dma_verbose(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_verbose: \n", drive->name); + + printk(", %s ", ide_xfer_verbose(drive->current_speed)); + + return 1; + +} + +/***************************************************************************** + * + * ep93xx_ide_dma_bad_timeout() + * + ****************************************************************************/ +int ep93xx_ide_dma_timeout(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_timeout: \n", drive->name); + + printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); + if (HWIF(drive)->ide_dma_test_irq(drive)) + return 0; + return HWIF(drive)->ide_dma_end(drive); +} + +/***************************************************************************** + * + * ep93xx_ide_dma_retune() + * + ****************************************************************************/ +int ep93xx_ide_dma_retune(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_retune\n", drive->name); + return 1; +} + +/***************************************************************************** + * + * ep93xx_ide_dma_lostirq() + * + ****************************************************************************/ +int ep93xx_ide_dma_lostirq(ide_drive_t * drive) +{ + DPRINTK("%s: ep93xx_ide_dma_lostirq\n", drive->name); + printk("%s: DMA interrupt recovery\n", drive->name); + + return 1; +} + +#endif /* CONFIG_BLK_DEV_IDEDMA_EP93XX */ + +/***************************************************************************** + * + * functions to set up the IDE control register and data register to read + * or write a byte of data to/from the specified IDE device register. + * + ****************************************************************************/ +static void ep93xx_ide_outb(u8 b, unsigned long addr) +{ + unsigned int uiIDECR; + + DPRINTK("ep93xx_ide_outb, addr:%02lx data: %04x\n", addr, b); + + /* + * Write the address out (CS0n, CS1n, DA) fields only. + */ + uiIDECR = (readl(IDECtrl) & ~IDECR_REG_MASK) | (addr & IDECR_REG_MASK); + writel(uiIDECR, IDECtrl); + + writel((unsigned int)b, IDEDataOut); + + /* + * Toggle Write signal. + */ + uiIDECR &= ~IDECtrl_DIOWn; + writel(uiIDECR, IDECtrl); + uiIDECR |= IDECtrl_DIOWn; + writel(uiIDECR, IDECtrl); +} + +static void ep93xx_ide_outbsync(ide_drive_t * drive, u8 b, unsigned long addr) +{ + unsigned int uiIDECR; + + DPRINTK("ep93xx_ide_outbsync, addr:%02lx data: %04x\n", addr, b); + + /* + * Write the address out (CS0n, CS1n, DA) fields only. + */ + uiIDECR = (readl(IDECtrl) & ~IDECR_REG_MASK) | (addr & IDECR_REG_MASK); + writel(uiIDECR, IDECtrl); + + writel((unsigned int)b, IDEDataOut); + + /* + * Toggle Write signal. + */ + uiIDECR &= ~IDECtrl_DIOWn; + writel(uiIDECR, IDECtrl); + uiIDECR |= IDECtrl_DIOWn; + writel(uiIDECR, IDECtrl); +} + +static unsigned char ep93xx_ide_inb(unsigned long addr) +{ + unsigned int uiIDECR; + + DPRINTK("ep93xx_ide_inb addr: %04lx ", addr); + + /* + * Write the address out (CS0n, CS1n, DA) fields only. + */ + uiIDECR = (readl(IDECtrl) & ~IDECR_REG_MASK) | (addr & IDECR_REG_MASK); + writel(uiIDECR, IDECtrl); + + /* + * Toggle Read signal. + */ + uiIDECR &= ~IDECtrl_DIORn; + writel(uiIDECR, IDECtrl); + uiIDECR |= IDECtrl_DIORn; + writel(uiIDECR, IDECtrl); + + DPRINTK("data: %02x\n", readl(IDEDataIn)); + return (unsigned char)readl(IDEDataIn); +} + +/***************************************************************************** + * + * functions to set up the IDE control register and data restister to read + * or write 16 bits of data to/from the specified IDE device register. + * These functions should only be used when reading/writing data to/from + * the data register. + * + ****************************************************************************/ +static void ep93xx_ide_outw(u16 w, unsigned long addr) +{ + unsigned int uiIDECR; + + DPRINTK("ep93xx_ide_outw addr: %04lx data: %04x\n", addr, w); + + /* + * Write the address out (CS0n, CS1n, DA) fields only. + */ + uiIDECR = (readl(IDECtrl) & ~IDECR_REG_MASK) | (addr & IDECR_REG_MASK); + writel(uiIDECR, IDECtrl); + + writel((unsigned int)w, IDEDataOut); + + /* + * Toggle Write signal. + */ + uiIDECR &= ~IDECtrl_DIOWn; + writel(uiIDECR, IDECtrl); + uiIDECR |= IDECtrl_DIOWn; + writel(uiIDECR, IDECtrl); +} + +static u16 ep93xx_ide_inw(unsigned long addr) +{ + unsigned int uiIDECR; + + DPRINTK("ep93xx_ide_inw addr: %04lx ", addr); + + /* + * Write the address out (CS0n, CS1n, DA) fields only. + */ + uiIDECR = (readl(IDECtrl) & ~IDECR_REG_MASK) | (addr & IDECR_REG_MASK); + writel(uiIDECR, IDECtrl); + + /* + * Toggle Read signal. + */ + uiIDECR &= ~IDECtrl_DIORn; + writel(uiIDECR, IDECtrl); + uiIDECR |= IDECtrl_DIORn; + writel(uiIDECR, IDECtrl); + + DPRINTK("data: %04x\n", readl(IDEDataIn)); + return (unsigned short)readl(IDEDataIn); +} + +/***************************************************************************** + * + * functions to read/write a block of data to/from the ide device using + * PIO mode. + * + ****************************************************************************/ +static void ep93xx_ide_insw(unsigned long addr, void *buf, u32 count) +{ + unsigned short *data = (unsigned short *)buf; + unsigned char status; + DPRINTK("ep93xx_ide_insw\n"); + + /* + * Read in data from the data register 16 bits at a time. + */ + while (count) { + /* + * Read the status register. + */ + status = ep93xx_ide_inb((STATUSREGISTER << 2) + 2); + + /* + * Check for the BSY to be clear and DRQ to be set. + */ + if ((status & ATADRQ) && !(status & ATABSY)) { + *data = ep93xx_ide_inw(addr); + data++; + count--; + } + } +} + +static void ep93xx_ide_outsw(unsigned long addr, void *buf, u32 count) +{ + unsigned short *data = (unsigned short *)buf; + unsigned char status; + + DPRINTK("ep93xx_ide_outsw\n"); + + /* + * Write out data to the data register 16 bits at a time. + */ + while (count) { + /* + * Read the status register. + */ + status = ep93xx_ide_inb((STATUSREGISTER << 2) + 2); + + /* + * Check for the BSY to be clear and DRQ to be set. + */ + if ((status & ATADRQ) && !(status & ATABSY)) { + ep93xx_ide_outw(*data, addr); + data++; + count--; + } + } +} + +static void ep93xx_ide_outl(u32 l, unsigned long addr) +{ + printk("ep93xx_ide_outl\n"); +} + +static u32 ep93xx_ide_inl(unsigned long addr) +{ + printk("ep93xx_ide_inl\n"); + return 0; +} + +static void ep93xx_ide_outsl(unsigned long addr, void *buf, u32 count) +{ + printk("ep93xx_ide_inl\n"); +} + +static void ep93xx_ide_insl(unsigned long addr, void *buf, u32 count) +{ + printk("ep93xx_ide_inl\n"); +} + +/***************************************************************************** + * + * Functions to read/write a block of data to/from the ide device using + * PIO mode, using an ATAPI interface. + * + ****************************************************************************/ +static void ep93xx_ide_insw_atapi(unsigned int addr, void *buf, int count) +{ + DPRINTK("ep93xx_ide_insw_atapi \n"); + + /* + * Convert count from bytes to half words. + */ + if (count % 2) { + count = count / 2; + count++; + } else { + count = count / 2; + } + + /* + * Call the function which will read in the data. + */ + ep93xx_ide_insw(addr, buf, count); +} + +static void ep93xx_ide_outsw_atapi(unsigned int addr, void *buf, int count) +{ + DPRINTK("ep93xx_ide_outsw_atapi \n"); + + /* + * Convert count from bytes to half words. + */ + if (count % 2) { + count = count / 2; + count++; + } else { + count = count / 2; + } + + /* + * Call the function which will write out the data. + */ + ep93xx_ide_outsw(addr, buf, count); +} + +void ep93xx_ata_input_data(ide_drive_t * drive, void *buffer, u32 count) +{ + DPRINTK("ep93xx_ata_input_data \n"); + + /* + * Read in the specified number of half words from the ide interface. + */ + ep93xx_ide_insw(IDE_DATA_REG, buffer, count << 1); +} + +void ep93xx_ata_output_data(ide_drive_t * drive, void *buffer, u32 count) +{ + DPRINTK("ep93xx_ata_output_data \n"); + + /* + * write the specified number of half words from the ide interface + * to the ide device. + */ + ep93xx_ide_outsw(IDE_DATA_REG, buffer, count << 1); +} + +void ep93xx_atapi_input_bytes(ide_drive_t * drive, void *buffer, u32 count) +{ + DPRINTK("ep93xx_atapi_input_bytes \n"); + + /* + * read in the specified number of bytes from the ide interface. + */ + ep93xx_ide_insw_atapi(IDE_DATA_REG, buffer, count); +} + +void ep93xx_atapi_output_bytes(ide_drive_t * drive, void *buffer, u32 count) +{ + DPRINTK("ep93xx_atapi_output_bytes \n"); + + /* + * Write the specified number of bytes from the ide interface + * to the ide device. + */ + ep93xx_ide_outsw_atapi(IDE_DATA_REG, buffer, count); +} + +/***************************************************************************** + * + * ep93xx_ide_init() + * + * This function sets up a pointer to the ep93xx specific ideproc funciton. + * + ****************************************************************************/ +void ep93xx_ide_init(struct hwif_s *hwif) +{ + + DPRINTK("ep93xx_ide_init \n"); + + /* + * Set up the HW interface function pointers with the ep93xx specific + * function. + */ + hwif->ata_input_data = ep93xx_ata_input_data; + hwif->ata_output_data = ep93xx_ata_output_data; + hwif->atapi_input_bytes = ep93xx_atapi_input_bytes; + hwif->atapi_output_bytes = ep93xx_atapi_output_bytes; + + hwif->OUTB = ep93xx_ide_outb; + hwif->OUTBSYNC = ep93xx_ide_outbsync; + hwif->OUTW = ep93xx_ide_outw; + hwif->OUTL = ep93xx_ide_outl; + hwif->OUTSW = ep93xx_ide_outsw; + hwif->OUTSL = ep93xx_ide_outsl; + + hwif->INB = ep93xx_ide_inb; + hwif->INW = ep93xx_ide_inw; + hwif->INL = ep93xx_ide_inl; + hwif->INSW = ep93xx_ide_insw; + hwif->INSL = ep93xx_ide_insl; + +#ifdef CONFIG_BLK_DEV_IDEDMA_EP93XX + + DPRINTK("ep93xx_ide_init- dma enabled \n"); + + printk(" %s: SG-DMA", hwif->name); + + /* + * Allocate dma-able memory space, in one consistent chunk. The call + * to alloc_consistent will return a virtual address and fill in a dma + * physical address. (arch/arm/mm/consistent.c) + * + */ + hwif->dmatable_cpu = consistent_alloc(GFP_KERNEL | GFP_DMA, + PRD_ENTRIES * PRD_BYTES, + &hwif->dmatable_dma); + + /* + * Check if we allocated memory for dma + */ + if (hwif->dmatable_cpu == NULL) { + printk(" -- disabled, UNABLE TO ALLOCATE DMA TABLES\n"); + return; + } + + DPRINTK(" %s: EP93XX-DMA at 0x%x - 0x%x \n", hwif->name, + hwif->dmatable_dma, + (unsigned int)(hwif->dmatable_dma + (PRD_ENTRIES * PRD_BYTES))); + + /* + * Allocate memory for the scatterlist structures. + */ + hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES, + GFP_KERNEL); + + /* + * Check if we allocated the memory we expected to. + */ + if (hwif->sg_table == NULL) { + /* + * Fail, so clean up. + */ + consistent_free(hwif->dmatable_cpu, PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_dma); + printk(" -- disabled, UNABLE TO ALLOCATE DMA TABLES\n"); + return; + } + + /* + * Init the dma handle to 0. This field is used to hold a handle to the + * dma instance. + */ + hwif->hw.dma = NULL; + + /* + * Open an instance of the ep93xx dma interface. + */ + if (ep93xx_dma_request(&hwif->hw.dma, hwif->name, DMA_IDE) != 0) { + /* + * Fail, so clean up. + */ + consistent_free(hwif->dmatable_cpu, PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_dma); + kfree(hwif->sg_table); + printk(" -- disabled, unable to allocate DMA channel.\n"); + } + + /* + * Now that we've got a dma channel allocated, set up the rest of the + * dma specific stuff. + */ + else { + DPRINTK("\n ide init- dma channel allocated: %d \n", + hwif->hw.dma); + + /* + * Enable dma support for atapi devices. + */ + hwif->atapi_dma = 1; + + /* + * TODO: how are these used? + */ + hwif->mwdma_mask = 7; /* MW0..2 */ + hwif->ultra_mask = 7; /* SW0..2 */ + + hwif->speedproc = NULL; + hwif->autodma = 1; + + hwif->ide_dma_check = ep93xx_ide_dma_check; + hwif->ide_dma_host_off = ep93xx_ide_dma_host_off; + hwif->ide_dma_off_quietly = ep93xx_ide_dma_off_quietly; + hwif->ide_dma_off = ep93xx_ide_dma_off; + hwif->ide_dma_host_on = ep93xx_ide_dma_host_on; + hwif->ide_dma_on = ep93xx_ide_dma_on; + hwif->ide_dma_read = ep93xx_ide_dma_read; + hwif->ide_dma_write = ep93xx_ide_dma_write; + hwif->ide_dma_count = ep93xx_ide_dma_count; + hwif->ide_dma_begin = ep93xx_ide_dma_begin; + hwif->ide_dma_end = ep93xx_ide_dma_end; + hwif->ide_dma_test_irq = ep93xx_ide_dma_test_irq; + hwif->ide_dma_verbose = ep93xx_ide_dma_verbose; + hwif->ide_dma_timeout = ep93xx_ide_dma_timeout; + hwif->ide_dma_lostirq = ep93xx_ide_dma_lostirq; + + printk(" capable%s\n", hwif->autodma ? ", auto-enable" : ""); + } + +#endif +} diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c index 23488c4..cc411c2 100644 --- a/drivers/ide/arm/ide_arm.c +++ b/drivers/ide/arm/ide_arm.c @@ -20,6 +20,15 @@ # define IDE_ARM_HOST (1) #endif +/* FIXME: Part 1 of dirty hack to get IDE working for EP93XX Processor */ +#ifdef CONFIG_BLK_DEV_EP93XX +#include +#ifndef IRQ_HARDDISK +# define IRQ_HARDDISK -1 +#endif +#endif +/* END OF HACK */ + #ifdef CONFIG_ARCH_CLPS7500 # include # @@ -36,8 +45,15 @@ void __init ide_arm_init(void) hw_regs_t hw; memset(&hw, 0, sizeof(hw)); + +/* FIXME: Part 2 of dirty hack to get IDE working for EP93XX Processor */ +#ifdef CONFIG_BLK_DEV_EP93XX + old_ide_init_default_hwifs(); +#else ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); hw.irq = IDE_ARM_IRQ; ide_register_hw(&hw, NULL); +#endif } + } diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 4a91774..68c06fa 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -193,4 +193,38 @@ config KEYBOARD_HIL This driver implements support for HIL-keyboards attached to your machine, so normally you should say Y here. +config KEYBOARD_EP93XX + tristate "EP93xx Keyboard support" + depends on ARCH_EP93XX && INPUT && INPUT_KEYBOARD + default y + help + This is support for the Cirrus EP93xx Keyboards. Say yes here if you + have such a CPU, and choose some drivers below. + +config KEYBOARD_EP93XX_SPI + bool "EP93xx PS2 Keyboard support" + depends on KEYBOARD_EP93XX + help + Say Y here if you want support for a PS2 keyboard connected via SPI. + +config KEYBOARD_EP93XX_8X8 + bool "EP93xx 8x8 keypad matrix support" + depends on KEYBOARD_EP93XX + help + Say Y here if you have a 8x8 keypad connected to your EP93xx. + You might want to generate a custom keymap for it. + If you do not have such a keypad, say N. + +config KEYBOARD_EP93XX_8X8_CYCLING + bool "EP93xx 8x8 keypad matrix keycode cycling support" + depends on KEYBOARD_EP93XX_8X8 + help + Key cycling feature - assign more than one keycode per key. + If you press such a key more than twice per second, alternative + keycodes will be cycled through. + This should result in a behavoir similar to some mobile phones. + You might want to generate a custom keymap for this feature, too. + See the sourcecode for known limitations. + Say N unless you really need it. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 9ce0b87..7ac6fca 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -17,4 +17,6 @@ obj-$(CONFIG_KEYBOARD_CORGI) += corgikb obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o +obj-$(CONFIG_KEYBOARD_EP93XX_8X8) += ep93xx_kbd_8x8.o +obj-$(CONFIG_KEYBOARD_EP93XX_SPI) += ep93xx_spi_kbd.o diff --git a/drivers/input/keyboard/ep93xx_kbd_8x8.c b/drivers/input/keyboard/ep93xx_kbd_8x8.c new file mode 100644 index 0000000..d772381 --- /dev/null +++ b/drivers/input/keyboard/ep93xx_kbd_8x8.c @@ -0,0 +1,482 @@ +/****************************************************************************** + * + * File: linux/drivers/input/keyboard/ep93xx_kbd_8x8.c + * + * Purpose: Support for Cirrus EP93xx architecture core keyboard scanner. + * + * + * History: 2005-08-10 Michael Burian added "cycling keys" support + * 2004-05-28 Michael Burian ported to 2.6.6 + * + * 010406 Norman Farquhar at LynuxWorks + * + * Initial version + * - Will scan keyboard and feed keyboard.c, which translates + * to input codes and puts them into tty console queue. + * - Raw mode tbd + * - keymaps other than default not supported + * - does not support standby mode yet + * + * Limitations: + * 1. The EP93xx is limited to supporting small keyboards + * and cannot handle full PC style keyboards and key usage: + * a) 64 key limit: 8x8 key matrix + * b) limited to 2 keys down MAXIMUM, + * which makes it impossible to support SHIFT+SHIFT+KEY + * states like shift-control or control-alt keys. + * 2. This means the default keyboard, 83key CherryG84-4001QAU/02, + * will have some dead keys. + * + * + * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA. All rights reserved. + * + *============================================================================= + * Overview of EP93xx Scan Keyboard driver + *============================================================================= + * + * The EP93xx scanned keyboard driver is a low-level hardware driver which + * supports the core logic scanned keyboard controller block of the + * EP93xx. These machines are embedded systems and this keyboard driver + * can support small keyboards. + * + * The keyboard driver does not have a normal device driver interface + * and instead interfaces to the keyboard.c driver through function calls. + * Note that not all interface function calls are implemented at this time. + * (see /asm/arch/keyboard.h for function definitions): + * + * ep93xxkbd_init + * initializes the scan keyboard hw. + * + * handle_scancode + * when scan controller generates interrupt, handler + * used to pass scan codes to queue in keyboard.c with this function call. + * + * UPDATE: Now this is inplemented right here and just used as a + * wrapper for the input layer + * + * Note that key scan codes will be delivered by this driver on both + * key down and key up events, using a coding similar to PC XT keyboard. + * + * Note however that scan compatibility and key code compatibility + * to PC standard are not required by Linux, and are not guaranteed. + * + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_KEYBOARD_EP93XX_8X8_CYCLING +#include "ep93xx_kbd_8x8_keymap-cycling.h" +#else +#include "ep93xx_kbd_8x8_keymap.h" +#endif + +#define EP93XX_KEYMAP_SIZE (8*8) + +/* #define DEBUG */ + +#define KEYREG_KEY1_MASK 0x0000003F +#define KEYREG_KEY1_SHIFT 0 +#define KEYREG_KEY2_MASK 0x00000Fc0 +#define KEYREG_KEY2_SHIFT 6 + +#define KEYREG_KEY1ROW_MASK 0x00000007 +#define KEYREG_KEY1ROW_SHIFT 0 +#define KEYREG_KEY1COL_MASK 0x00000038 +#define KEYREG_KEY1COL_SHIFT 3 + +#define KEYREG_KEY2ROW_MASK 0x000001c0 +#define KEYREG_KEY2ROW_SHIFT 6 +#define KEYREG_KEY2COL_MASK 0x00000E00 +#define KEYREG_KEY2COL_SHIFT 9 + +#define KEYREG_1KEY 0x00001000 +#define KEYREG_2KEYS 0x00002000 +#define KEYREG_INT 0x00004000 +#define KEYREG_K 0x00008000 + +#define SCANINIT_DIS3KY 0x00008000 + +static struct input_dev *dev; + +#ifdef CONFIG_KEYBOARD_EP93XX_8X8_CYCLING +struct last_key_event { + unsigned long jiffies; + unsigned char scancode; +}; + +static struct last_key_event lke; + +/** + * handle_scancode - wrapper + * + * We need to do two things here: + * 1. wrap old style (2.4.x) to 2.6.x input subsystem + * 2. also implement the key cycling feature here. + * CYCLING FEATURE: + * If the same key is pressed withing 500ms, we send a delete + * character to delete the former key, and use the keycode from the next layer + * instead. This should result "mobile phone" like behavior. + * KNOWN BUG: + * This will mess up anything that depends on single keystrokes + * (raw mode, non canonical mode, hotkeys, ...) + * TODO 1: + * A possible fix would be to delay till we know for sure what key it is + * and send just that key, but in that case the user would have to type + * blindly. :( + * TODO 2: + * A possible enhancement to the fix would be to provide some kind of preview + * with an additional character device and write some userspace app to display + * it in a seperate dialog. + * + */ +static void handle_scancode(unsigned char scancode, int down) +{ + unsigned char row = (scancode & 0xF) - 1; + unsigned char col = ((scancode & 0x70) >> 4); + unsigned char index = row * 8 + col; + static int layer = 0; + + /* + * straight forward processing in case of: + * "up" events + * repeated keypress events that happen after more than 500ms + * after different key has been pressed ( ignore up/down! ) + * there are no alternative keycodes available + */ + if (!down || time_before(lke.jiffies + msecs_to_jiffies(500), jiffies) + || (lke.scancode & 0x7f) != (scancode &0x7F) || + (keycode[1][index] == KEY_RESERVED) ) { + /* no cycling: process straightforward */ + input_report_key(dev, keycode[0][index], down); + input_sync(dev); + + /* end cycling on all but up events */ + if(down) + layer=0; + } else { + /* + * cycling mode: + * + * if we have an alternative keycode available: + * 1. pretend the former key was wrong (and delete it) + * 2. replace with the keycode from the next layer + */ + + /* suppress real "up" events, as we fake immediate "up" here */ + if (!down) + return; + + /* switch to next layer, with wraparound */ + if(++layer >= 16) + layer = 0; + + /* if alternative keycodes are available */ + if (keycode[layer][index] != KEY_RESERVED) { + /* pretend former key was wrong and delete it */ + input_report_key(dev, KEY_BACKSPACE, 1); + input_report_key(dev, KEY_BACKSPACE, 0); + } else { + /* no more valid keycodes? => switch to layer 0 */ + layer=0; + return; + } + + /* send alternative keycode */ + input_report_key(dev, keycode[layer][index], 1); + input_report_key(dev, keycode[layer][index], 0); + input_sync(dev); + + + } + lke.scancode = scancode; + lke.jiffies = jiffies; +} +#else +/** + * handle_scancode - wrapper + * + * wrap old style (2.4.x) to 2.6.x input subsystem + */ +static void handle_scancode(unsigned char scancode, int down) +{ + /* printk("handle_scancode(scancode=%04X, down=%d); %02X ", scancode, down, scancode &0x7f); */ + + unsigned char row = (scancode & 0xF) - 1; + unsigned char col = ((scancode & 0x70) >> 4); + unsigned char index = row * 8 + col; + + input_report_key(dev, keycode[index], down); + input_sync(dev); + + /* printk("index=%02X\n", index); */ +} +#endif + +static irqreturn_t ep93xxkbd_irq_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned int keystat, key1, key2; + static unsigned int lastkeystat = 0, lastkey1 = 0, lastkey2 = 0; + + /* Note: IRQ_KEY automatically disabled before entry, */ + /* and reenabled after exit by Linux interrupt code. */ + + /* Reading status clears keyboard interrupt */ + + keystat = readl(KEY_REG) & + (KEYREG_KEY1COL_MASK | KEYREG_KEY1ROW_MASK | + KEYREG_KEY2COL_MASK | KEYREG_KEY2ROW_MASK | + KEYREG_1KEY | KEYREG_2KEYS); + +#ifdef DEBUG /* DEBUGGING */ + if (keystat == lastkeystat) + printk("ep93xx_scan_keyb: spurious interrupt, stat %x\n", + keystat); + else + printk("ep93xx_scan_keyb: interrupt, stat %x\n", keystat); +#endif + if (keystat & KEYREG_1KEY) + key1 = + KEYCODE((keystat & KEYREG_KEY1ROW_MASK) >> + KEYREG_KEY1ROW_SHIFT, + (keystat & KEYREG_KEY1COL_MASK) >> + KEYREG_KEY1COL_SHIFT); + else + key1 = 0; /* invalid */ + + if (keystat & KEYREG_2KEYS) + key2 = + KEYCODE((keystat & KEYREG_KEY2ROW_MASK) >> + KEYREG_KEY2ROW_SHIFT, + (keystat & KEYREG_KEY2COL_MASK) >> + KEYREG_KEY2COL_SHIFT); + else + key2 = 0; /* invalid */ + + /* + * This 'monster' decision tree is used to decide what to report + * when last key state has changed to current key state. + * This may involve up to 4 keys changing state simultaneously: + * lastkey1, lastkey2 going up and key1, key2 going down. + * + * We use keyboard scanner hardware guarantees to simplify the logic: + * key1 < key2 if both are valid + * key1 is valid if key2 is valid + * + * handle_scancode called with down and up scancodes + * scancode = keycode when down + * scancode = keycode|KBUP when up + * + * Note that if more than one keys change state in the same scan period, + * then we really do NOT know the order in which the key events occurred. + * Our default behavior is to always report key up events before key down + * events. However, multiple key up events or multiple key down events + * will be reported in no special order. + */ + if (!(lastkeystat & (KEYREG_1KEY | KEYREG_2KEYS))) { /* No keys down lasttime */ + if (key1) + handle_scancode(key1, 1); + if (key2) + handle_scancode(key2, 1); + } else if (lastkey1 == key1) { /* means key still down */ + /* no change for key1 or lastkey1, both valid */ + if (lastkey2 != key2) { + /* lastkey2 went up if valid, key2 went down if valid */ + if (lastkey2) + handle_scancode(lastkey2 | KBUP, 0); + if (key2) + handle_scancode(key2, 1); + } + /* else no change for all keys */ + } else if (key1) + { /* key1 valid and */ + /* lastkey1 valid (because NOT no keys lasttime) */ + if (lastkey1 == key2) { + /* no change for lastkey1 or key2 */ + /* lastkey2 went up if valid, key1 went down */ + if (lastkey2) + handle_scancode(lastkey2 | KBUP, 0); + handle_scancode(key1, 1); + + } else { + /* we know: lastkey1 valid and went up, key1 valid */ + handle_scancode(lastkey1 | KBUP, 0); + + if (lastkey2 == key1) { + /* no change for lastkey2 or key1 */ + /* key2 went down if valid */ + if (key2) + handle_scancode(key2, 1); + + } else { + if (lastkey2 != key2) { + /* lastkey2 went up if valid */ + /* key2 went down if valid */ + if (lastkey2) + handle_scancode(lastkey2 | KBUP, + 0); + if (key2) + handle_scancode(key2, 1); + } + /* else no change for lastkey2 or key2 */ + + /* key1 valid and went down */ + handle_scancode(key1, 1); + } + } + } else { + /* key1 not valid and */ + /* lastkey1 valid (because NOT no keys lasttime) */ + + /* key1 not valid means both key1, key2 not valid */ + /* so lastkey1 went up and lastkey2 went up if valid */ + handle_scancode(lastkey1 | KBUP, 0); + if (lastkey2) + handle_scancode(lastkey2 | KBUP, 0); + } + + lastkeystat = keystat; + lastkey1 = key1; + lastkey2 = key2; + return IRQ_HANDLED; +} + +int __init ep93xxkbd_init(void) +{ + int i = 3; + unsigned int uiTemp; + int error = 0; + + dev = input_allocate_device(); + if (!dev) { + printk(KERN_ERR "ep93xx_kbd_8x8: not enough memory for input device\n"); + return -ENOMEM; + } + + dev->name = "Cirrus EP93xx 8x8 keypad matrix driver"; + dev->phys = "input0"; + dev->id.bustype = BUS_HOST; + dev->evbit[0] = BIT(EV_KEY); + + printk("%s\n", dev->name); + + /* Make sure scanner enabled, active and that */ + /* Keyboard ROW/COL interface enabled. */ + + uiTemp = readl(SYSCON_DEVCFG); + + uiTemp &= ~(SYSCON_DEVCFG_KEYS | SYSCON_DEVCFG_GONK); + + SysconSetLocked(SYSCON_DEVCFG, ep93xx_SYSCON_DEVCFG(uiTemp)); + + /* SYSCON locked automatically now after RSTCR written */ + + /* Enable Keyboard Clock and select clock rate + * + * TBD Boot ROM has already inited KTDIV = 0x20018004 + * TBD Measured default 64usec scan period with scope. + + * Assume that GPIO registers do not impact row,col pins since + * they are assigned to keyboard scanner. + + * Setup Keyboard Scanner + * + * Note that we change the scanner parameters on the fly + * while it is running, which is okay. No need to disable + * scanner while tweaking these. + * + * TBD Keyboard scan rate will change as master clocks/dividers change + * + * For now, this gives us measured rate of about 480Hz row scan rate, + * which implies 60Hz full kbd scan rate. Together with debounce + * count of 3, means debounce period = 3/60Hz = 50ms>30ms recommended, + * so okay. + */ + writel((0x00FC00FA | SCANINIT_DIS3KY), SCANINIT); + + /*TBD If too much capacitance on keyboard */ + /* writel( (0x00FC0020 | SCBACK | SCDIS3KEY), SCANINIT ); */ + + uiTemp = readl(SYSCON_KTDIV) | SYSCON_KTDIV_KEN; + + SysconSetLocked(SYSCON_KTDIV, uiTemp); + + error = + request_irq(IRQ_KEY, ep93xxkbd_irq_handler, 0, + "ep93xx_keypad_handler", + (void *)(ep93xxkbd_irq_handler)); + if (error) { + printk("Error: %s could not allocate IRQ%d\n", dev->name, IRQ_KEY); + return error; + } + /* Note: request_irq has just enabled IRQ_KEY for us. */ + + /* Warning: We have initialized last key status to indicate + * all keys up which may not be the current hardware state. + * + * TBD If this is important to detect, to alert user + * TBD to a possibly faulty keyboard, then we could + * TBD manually scan the keyboard to verify all keys up. + * + + * Three common cases here: + * 1. All keys up. This is normal, expected status of keyboard. + * 2. All keys up, although at some time ago during initialization + * a key was momentarily pressed, causing the hardware to latch it. + * 3. Some key is being held down now. + * + * Reading status clears any pending keyboard interrupt. + */ + + i = readl(KEY_REG); + + /* + * We believe this will have the following impact on common cases: + * + * 1. No impact. + * 2. Momentary presses will be cleared out so they do not + * bother us. Although we get a spurious key up immediately because + * the keyboard hardware will see change from last + * latched status and current status, higher level keyboard driver + * should ignore. + * 3. Key being held will generate a new pending key down + * event which is acceptable. + * + * Now keyboard is active and will generate interrupts + * on key presses. Driver only needs to handle interrupts. + * There are NO driver ioctl or deinit functions in lowlevel. + */ + +#ifdef CONFIG_KEYBOARD_EP93XX_8X8_CYCLING + for (i = 0; i < EP93XX_KEYMAP_SIZE * 16; i++) + set_bit(keycode[i/EP93XX_KEYMAP_SIZE][i%EP93XX_KEYMAP_SIZE], dev->keybit); +#else + for (i = 0; i < EP93XX_KEYMAP_SIZE; i++) + set_bit(keycode[i], dev->keybit); +#endif + + input_register_device(dev); + + return 0; +} + +static void __exit ep93xxkbd_cleanup(void) +{ + writel(0x000000AA, SYSCON_SWLOCK); /* unlock SYSCON Software Lock */ + writel(readl(SYSCON_KTDIV) & 0xFFFF7FFF, SYSCON_KTDIV); /* disable Key Matrix Clock KEN */ + free_irq(IRQ_KEY, NULL); + input_unregister_device(dev); +} + +module_init(ep93xxkbd_init); +module_exit(ep93xxkbd_cleanup); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/keyboard/ep93xx_kbd_8x8_keymap-cycling.h b/drivers/input/keyboard/ep93xx_kbd_8x8_keymap-cycling.h new file mode 100644 index 0000000..31fd4db --- /dev/null +++ b/drivers/input/keyboard/ep93xx_kbd_8x8_keymap-cycling.h @@ -0,0 +1,146 @@ +static unsigned char keycode[16][0x40] = +{{ + KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, 0, 0, + KEY_ESC, KEY_BACKSPACE, KEY_7, KEY_8, KEY_9, 0, 0, 0, + KEY_PROG1, KEY_PROG2, KEY_4, KEY_5, KEY_6, 0, 0, 0, + KEY_MENU, KEY_0, KEY_1, KEY_2, KEY_3, 0, 0, 0, + KEY_LEFTSHIFT, KEY_UP, KEY_TAB, 0, 0, 0, 0, 0, + KEY_LEFT, KEY_LEFTALT, KEY_RIGHT, 0, 0, 0, 0, 0, + KEY_LEFTCTRL, KEY_DOWN, KEY_ENTER, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, KEY_A, KEY_D, KEY_G, 0, 0, 0, + 0, 0, KEY_J, KEY_M, KEY_P, 0, 0, 0, + 0, KEY_DOT, KEY_S, KEY_V, KEY_Y, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, KEY_B, KEY_E, KEY_H, 0, 0, 0, + 0, 0, KEY_K, KEY_N, KEY_Q, 0, 0, 0, + 0, KEY_COMMA, KEY_T, KEY_W, KEY_Z, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, KEY_C, KEY_F, KEY_I, 0, 0, 0, + 0, 0, KEY_L, KEY_O, KEY_R, 0, 0, 0, + 0, KEY_SLASH, KEY_U, KEY_X, KEY_SPACE, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_KPASTERISK, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_KPPLUS, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_KPMINUS, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_EQUAL, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_SEMICOLON, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_APOSTROPHE, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_KPLEFTPAREN, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_KPRIGHTPAREN, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_LEFTBRACE, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, KEY_RIGHTBRACE, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}}; diff --git a/drivers/input/keyboard/ep93xx_kbd_8x8_keymap.h b/drivers/input/keyboard/ep93xx_kbd_8x8_keymap.h new file mode 100644 index 0000000..65dca77 --- /dev/null +++ b/drivers/input/keyboard/ep93xx_kbd_8x8_keymap.h @@ -0,0 +1,11 @@ +static unsigned char keycode[0x40] = +{ + KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, 0, 0, + KEY_ESC, KEY_BACKSPACE, KEY_7, KEY_8, KEY_9, 0, 0, 0, + KEY_PROG1, KEY_PROG2, KEY_4, KEY_5, KEY_6, 0, 0, 0, + KEY_MENU, KEY_0, KEY_1, KEY_2, KEY_3, 0, 0, 0, + KEY_LEFTSHIFT, KEY_UP, KEY_TAB, 0, 0, 0, 0, 0, + KEY_LEFT, KEY_LEFTALT, KEY_RIGHT, 0, 0, 0, 0, 0, + KEY_LEFTCTRL, KEY_DOWN, KEY_ENTER, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; diff --git a/drivers/input/keyboard/ep93xx_spi_kbd.c b/drivers/input/keyboard/ep93xx_spi_kbd.c new file mode 100644 index 0000000..b6ad607 --- /dev/null +++ b/drivers/input/keyboard/ep93xx_spi_kbd.c @@ -0,0 +1,407 @@ +/****************************************************************************** + * + * File: linux/drivers/char/ep93xx_spi_kbd.c + * + * Purpose: Support for SPI Keyboard for a Cirrus Logic EP93xx + * + * History: + * + * Limitations: + * Break and Print Screen keys not handled yet! + * + * + * Copyright 2003 Cirrus Logic Inc. + * 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 + * + ******************************************************************************/ + +/* + * FIXME: There are more parity problems than there ought to be. + * TODO: Track down + * WHERE: grep for "BAD_PARITY" + * + * WORKAROUND: Do not press too many keys and do not type too fast + * type key another time if it got lost + * + * WORKAROUND2: Use USB Keyboards or 8x8 matrix keypad instead + * + * FIXME2: Keymap should be done properly + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ep93xx_spi_kbd.h" + +#define EP93XX_MAX_KEY_DOWN_COUNT 6 + +void DataCallback(unsigned int Data); +static int g_SSP_Handle; +static struct input_dev *ep93xxkbd_dev; + +#undef UART_HACK_DEBUG +/* #define UART_HACK_DEBUG 1 */ + +#if defined(UART_HACK_DEBUG) && defined(CONFIG_DEBUG_LL) +char szBuf[256]; +#define DPRINTK( x... ) \ + sprintf( szBuf, ##x ); \ + printascii( szBuf ); +#else +#define DPRINTK( x... ) +#endif + +struct key_down_tracker_t { + unsigned char scancode; + unsigned char count; +}; + +/* + * In the interest of efficiency, let's only allow 5 keys to be down + * at a time, maximum. So if anybody is having a temper tantrum on + * their keyboard, they may get stuck keys, but that's to be expected. + */ + +#define MAX_KEYS_DOWN 8 +static struct key_down_tracker_t KeyTracker[MAX_KEYS_DOWN]; + +static unsigned char SPI2KScan(unsigned int uiSPIValue, int *pValid); +static void InitSniffer(void); +static void KeySniffer(unsigned char scancode, int down); +static void Check4StuckKeys(void); + +/** + * handle_scancode - wrapper + * + * wrap old style (2.4.x) to 2.6.x input subsystem + */ +static void handle_scancode(unsigned char scancode, int down) +{ + DPRINTK("handle_scancode(scancode=%04X, down=%d); %02X ", scancode, + down, scancode & 0x7f); + + if (scancode > KSCAN_TABLE_SIZE) + scancode &= ~EXTENDED_KEY; + + input_report_key(ep93xxkbd_dev, KScanCodeToVKeyTable[scancode], down); + input_sync(ep93xxkbd_dev); + + DPRINTK("(virtual) scancode=%02X\n", scancode); +} + +/** + * InitSniffer + * + * Clear our struct to indicate that no keys are down now. + * If somebody boots this thing while holding down keys, then they'll + * get what they deserve. + * + */ +static void InitSniffer(void) +{ + int i; + + for (i = 0; i < MAX_KEYS_DOWN; i++) { + KeyTracker[i].count = 0; + KeyTracker[i].scancode = 0; + } +} + +/** + * KeySniffer + * + * To prevent stuck keys, keep track of what keys are down. This information + * is used by Check4StuckKeys(). + */ +static void KeySniffer(unsigned char scancode, int down) +{ + int i; + + /* + * There are certain keys that will definately get held down + * and we can't interfere with that. + */ + switch (scancode) { + case 0x12: /* left shift */ + case 0x59: /* right shift */ + case 0x14: /* left ctrl */ + case 0x94: /* right ctrl */ + case 0x11: /* left alt */ + case 0x91: /* right alt */ + case 0x58: /* caps lock */ + case 0x77: /* Num lock */ + /* printk("Snuff - %02x, %d\n", scancode, down); */ + handle_scancode(scancode, down); + return; + + default: + break; + } + + /* printk("Sniff - %02x, %d\n", scancode, down ); */ + + /* + * Go thru our array, looking for the key. If it already + * is recorded, update its count. + * Also look for empty cells in the array in case we + * need one. + */ + for (i = 0; i < MAX_KEYS_DOWN; i++) { + /* If this is a key up in our list then we are done. */ + if (down == 0) { + if (KeyTracker[i].scancode == scancode) { + KeyTracker[i].count = 0; + KeyTracker[i].scancode = 0; + handle_scancode(scancode, down); + break; + } + } + /* Hey here's an unused cell. Save its index. */ + else if (KeyTracker[i].count == 0) { + KeyTracker[i].scancode = scancode; + KeyTracker[i].count = 1; + handle_scancode(scancode, down); + break; + } + } +} + +/** + * Check4StuckKeys + * + * When a key is held down longer than 1/2 sec, it start repeating + * 10 times a second. What we do is watch how long each key is + * held down. If longer than X where X is less than 1/2 second + * then we assume it is stuck and issue the key up. If we were + * wrong and the key really is being held down, no problem because + * the keyboard is about to start sending it to us repeatedly + * anyway. + */ +static void Check4StuckKeys(void) +{ + int i; + + for (i = 0; i < MAX_KEYS_DOWN; i++) { + if (KeyTracker[i].count) { + KeyTracker[i].count++; + if (KeyTracker[i].count >= EP93XX_MAX_KEY_DOWN_COUNT) { + handle_scancode(KeyTracker[i].scancode, 0); + KeyTracker[i].count = 0; + KeyTracker[i].scancode = 0; + } + } + } +} + +/** + * HandleKeyPress + * + * Checks if there are any keys in the FIFO and processes them if there are. + */ +void HandleKeyPress(unsigned int Data) +{ + static unsigned char ucKScan[4] = { 0, 0, 0, 0 }; + static unsigned int ulNum = 0; + int bParityValid; + + /* + * No keys to decode, but the timer went off and is calling us + * to check for stuck keys. + */ + if (Data == -1) { + Check4StuckKeys(); + return; + } + /* + * Read in the value from the SPI controller. + */ + ucKScan[ulNum++] = SPI2KScan(Data, &bParityValid); + + /* + * Bad parity? We should read the rest of the fifo and + * throw it away, because it will all be bad. Then the + * SSP will be reset when we close the SSP driver and + * all will be good again. + */ + if (!bParityValid) { + /* printk("_BAD_PARITY_"); */ + ulNum = 0; + } + /* If we have one character in the array, do the following. */ + if (ulNum == 1) { + /* + * If it is a simple key without the extended scan code perform + * following. + */ + if (ucKScan[0] < KSCAN_TABLE_SIZE) { + DPRINTK("1:Dn %02x\n", ucKScan[0]); + KeySniffer(ucKScan[0], 1); + ulNum = 0; + } + /* + * I don't know what type of character this is so erase the + * keys stored in the buffer and continue. + */ + else if ((ucKScan[0] != 0xF0) && (ucKScan[0] != 0xE0)) { + DPRINTK("1:oops - %02x\n", ucKScan[0]); + ulNum = 0; + } + } else if (ulNum == 2) { + /* + * 0xF0 means that a key has been released. + */ + if (ucKScan[0] == 0xF0) { + /* + * If it is a simple key without the extended scan code + * perform the following. + */ + if (ucKScan[1] < KSCAN_TABLE_SIZE) { + DPRINTK("2:Up %02x %02x\n", ucKScan[0], + ucKScan[1]); + KeySniffer(ucKScan[1], 0); + ulNum = 0; + } + /* + * If it a extended kscan continue to get the next byte. + */ + else if (ucKScan[1] != 0xE0) { + DPRINTK("2:oops - %02x %02x\n", ucKScan[0], + ucKScan[1]); + ulNum = 0; + } + } + /* + * Find out what extended code it is. + */ + else if (ucKScan[0] == 0xE0 && ucKScan[1] != 0xF0) { + DPRINTK("2:Dn %02x %02x\n", ucKScan[0], ucKScan[1]); + KeySniffer(EXTENDED_KEY | ucKScan[1], 1); + ulNum = 0; + } + } + /* This means that an extended code key has been released. */ + else if (ulNum == 3) { + /* 0xF0 means that a key has been released. */ + if (ucKScan[0] == 0xE0 && ucKScan[1] == 0xF0) { + DPRINTK("3:Up %02x %02x %02x", + ucKScan[0], ucKScan[1], ucKScan[2]); + KeySniffer(EXTENDED_KEY | ucKScan[2], 0); + } else { + DPRINTK("3:oops - %02x %02x %02x\n", + ucKScan[0], ucKScan[1], ucKScan[2]); + } + ulNum = 0; + } +} + +/** + * SPI2KScan - Get a character from the spi port if it is available. + * + * Below is a picture of the spi signal from the PS2. + * + * CK HHllllHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHllll + * DA HHHllllll000000111111222222333333444444555555666666777777ppppppssssssLLLLHHH + * ^ ^ + * start bit important bit + * + * where: l = 8042 driving the line + * L = KEYBOARD driving the line + * 1..7 data + * = Parity 8042 driving + * s = stop 8042 driving + * = PARITY KEYBOARD driving the line + * S = STOP KEYBOARD driving the line + * + * In our design the value comes high bit first and is inverted. So we must + * convert it to low byte first and then inverted it back. + * + */ +static unsigned char SPI2KScan(unsigned int uiSPIValue, int *pValid) +{ + unsigned char ucKScan = 0; + unsigned int uiParity = 0; + unsigned int uiCount = 0; + + for (uiCount = 1; uiCount < 10; uiCount++) { + uiParity += (uiSPIValue >> uiCount) & 0x1; + } + + if (!(uiParity & 0x1) && (uiSPIValue & 0x401) == 0x400) { + *pValid = 1; + + /* Invert the pattern. */ + uiSPIValue = ~uiSPIValue; + + /* Read in the value from the motorola spi file */ + ucKScan = (unsigned char)((uiSPIValue & 0x004) << 5); + ucKScan |= (unsigned char)((uiSPIValue & 0x008) << 3); + ucKScan |= (unsigned char)((uiSPIValue & 0x010) << 1); + ucKScan |= (unsigned char)((uiSPIValue & 0x020) >> 1); + ucKScan |= (unsigned char)((uiSPIValue & 0x040) >> 3); + ucKScan |= (unsigned char)((uiSPIValue & 0x080) >> 5); + ucKScan |= (unsigned char)((uiSPIValue & 0x100) >> 7); + ucKScan |= (unsigned char)((uiSPIValue & 0x200) >> 9); + } else { + *pValid = 0; + } + + return ucKScan; +} + +int __init EP93XXSpiKbdInit(void) +{ + int i; + + ep93xxkbd_dev = input_allocate_device(); + if (!ep93xxkbd_dev) { + printk(KERN_ERR "ep93xxkbd: not enough memory for input device\n"); + return -ENOMEM; + } + + ep93xxkbd_dev->name = "Cirrus EP93xx PS/2 keyboard driver"; + printk("%s\n", ep93xxkbd_dev->name); + + ep93xxkbd_dev->evbit[0] = BIT(EV_KEY); + + for (i = 0; i < KSCAN_TABLE_SIZE; i++) + set_bit(KScanCodeToVKeyTable[i], ep93xxkbd_dev->keybit); + + input_register_device(ep93xxkbd_dev); + + /* Open SSP driver for Keyboard input. */ + g_SSP_Handle = SSPDriver->Open(PS2_KEYBOARD, HandleKeyPress); + + InitSniffer(); + + DPRINTK("Leaving EP93XXSpiKbdInit()\n"); + + return 0; +} + +void __exit EP93XXSpiKbdCleanup(void) +{ + SSPDriver->Close(g_SSP_Handle); + input_unregister_device(ep93xxkbd_dev); +} + +module_init(EP93XXSpiKbdInit); +module_exit(EP93XXSpiKbdCleanup); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/keyboard/ep93xx_spi_kbd.h b/drivers/input/keyboard/ep93xx_spi_kbd.h new file mode 100644 index 0000000..7f4bd90 --- /dev/null +++ b/drivers/input/keyboard/ep93xx_spi_kbd.h @@ -0,0 +1,147 @@ +/* + * ep93xx_spi_kbd.h Keymap definitions (to be cleaned up) + */ + +#define KSCAN_TABLE_SIZE 0x88 + +#define EXTENDED_KEY 0x80 + +/* This table is used to map the scan code to the Linux default keymap. */ +static unsigned int const KScanCodeToVKeyTable[KSCAN_TABLE_SIZE] = { + KEY_RESERVED, /* Scan Code 0x0 */ + KEY_F9, /* Scan Code 0x1 */ + KEY_RESERVED, /* Scan Code 0x2 */ + KEY_F5, /* Scan Code 0x3 */ + KEY_F3, /* Scan Code 0x4 */ + KEY_F1, /* Scan Code 0x5 */ + KEY_F2, /* Scan Code 0x6 */ + KEY_F12, /* Scan Code 0x7 */ + KEY_RESERVED, /* Scan Code 0x8 */ + KEY_F10, /* Scan Code 0x9 */ + KEY_F8, /* Scan Code 0xA */ + KEY_F6, /* Scan Code 0xB */ + KEY_F4, /* Scan Code 0xC */ + KEY_TAB, /* Scan Code 0xD Tab */ + KEY_GRAVE, /* Scan Code 0xE ' */ + KEY_RESERVED, /* Scan Code 0xF */ + KEY_RESERVED, /* Scan Code 0x10 */ + KEY_LEFTALT, /* Scan Code 0x11 Left Menu */ + KEY_LEFTSHIFT, /* Scan Code 0x12 Left Shift */ + KEY_RESERVED, /* Scan Code 0x13 */ + KEY_LEFTCTRL, /* Scan Code 0x14 */ + KEY_Q, /* Scan Code 0x15 */ + KEY_1, /* Scan Code 0x16 */ + KEY_RESERVED, /* Scan Code 0x17 */ + KEY_RESERVED, /* Scan Code 0x18 */ + KEY_RESERVED, /* Scan Code 0x19 */ + KEY_Z, /* Scan Code 0x1A */ + KEY_S, /* Scan Code 0x1B */ + KEY_A, /* Scan Code 0x1C */ + KEY_W, /* Scan Code 0x1D */ + KEY_2, /* Scan Code 0x1E */ + KEY_RESERVED, /* Scan Code 0x1F */ + KEY_RESERVED, /* Scan Code 0x20 */ + KEY_C, /* Scan Code 0x21 */ + KEY_X, /* Scan Code 0x22 */ + KEY_D, /* Scan Code 0x23 */ + KEY_E, /* Scan Code 0x24 */ + KEY_4, /* Scan Code 0x25 */ + KEY_3, /* Scan Code 0x26 */ + KEY_RESERVED, /* Scan Code 0x27 */ + KEY_RESERVED, /* Scan Code 0x28 */ + KEY_SPACE, /* Scan Code 0x29 Space */ + KEY_V, /* Scan Code 0x2A */ + KEY_F, /* Scan Code 0x2B */ + KEY_T, /* Scan Code 0x2C */ + KEY_R, /* Scan Code 0x2D */ + KEY_5, /* Scan Code 0x2E */ + KEY_RESERVED, /* Scan Code 0x2F */ + KEY_RESERVED, /* Scan Code 0x30 */ + KEY_N, /* Scan Code 0x31 */ + KEY_B, /* Scan Code 0x32 B */ + KEY_H, /* Scan Code 0x33 */ + KEY_G, /* Scan Code 0x34 */ + KEY_Y, /* Scan Code 0x35 */ + KEY_6, /* Scan Code 0x36 */ + KEY_RESERVED, /* Scan Code 0x37 */ + KEY_RESERVED, /* Scan Code 0x38 */ + KEY_RESERVED, /* Scan Code 0x39 */ + KEY_M, /* Scan Code 0x3A */ + KEY_J, /* Scan Code 0x3B */ + KEY_U, /* Scan Code 0x3C */ + KEY_7, /* Scan Code 0x3D */ + KEY_8, /* Scan Code 0x3E */ + KEY_RESERVED, /* Scan Code 0x3F */ + KEY_RESERVED, /* Scan Code 0x40 */ + KEY_COMMA, /* Scan Code 0x41 */ + KEY_K, /* Scan Code 0x42 */ + KEY_I, /* Scan Code 0x43 */ + KEY_O, /* Scan Code 0x44 */ + KEY_0, /* Scan Code 0x45 */ + KEY_9, /* Scan Code 0x46 */ + KEY_RESERVED, /* Scan Code 0x47 */ + KEY_RESERVED, /* Scan Code 0x48 */ + KEY_DOT, /* Scan Code 0x49 */ + KEY_SLASH, /* Scan Code 0x4A */ + KEY_L, /* Scan Code 0x4B */ + KEY_SEMICOLON, /* Scan Code 0x4C */ + KEY_P, /* Scan Code 0x4D */ + KEY_MINUS, /* Scan Code 0x4E */ + KEY_RESERVED, /* Scan Code 0x4F */ + KEY_RESERVED, /* Scan Code 0x50 */ + KEY_RESERVED, /* Scan Code 0x51 */ + KEY_APOSTROPHE, /* Scan Code 0x52 */ + KEY_RESERVED, /* Scan Code 0x53 */ + KEY_LEFTBRACE, /* Scan Code 0x54 */ + KEY_EQUAL, /* Scan Code 0x55 */ + KEY_BACKSPACE, /* Scan Code 0x56 */ + KEY_RESERVED, /* Scan Code 0x57 */ + KEY_CAPSLOCK, /* Scan Code 0x58 Caps Lock */ + KEY_RIGHTSHIFT, /* Scan Code 0x59 Right Shift */ + KEY_ENTER, /* Scan Code 0x5A */ + KEY_RIGHTBRACE, /* Scan Code 0x5B */ + KEY_RESERVED, /* Scan Code 0x5C */ + KEY_BACKSLASH, /* Scan Code 0x5D */ + KEY_RESERVED, /* Scan Code 0x5E */ + KEY_RESERVED, /* Scan Code 0x5F */ + KEY_RESERVED, /* Scan Code 0x60 */ + KEY_BACKSLASH, /* Scan Code 0x61 ?? VK_BSLH, */ + KEY_RESERVED, /* Scan Code 0x62 */ + KEY_RESERVED, /* Scan Code 0x63 */ + KEY_RESERVED, /* Scan Code 0x64 */ + KEY_RESERVED, /* Scan Code 0x65 */ + KEY_BACKSPACE, /* Scan Code 0x66 ?? VK_BKSP, */ + KEY_RESERVED, /* Scan Code 0x67 */ + KEY_RESERVED, /* Scan Code 0x68 */ + KEY_KP1, /* Scan Code 0x69 */ + KEY_RESERVED, /* Scan Code 0x6A */ + KEY_KP4, /* Scan Code 0x6B */ + KEY_KP7, /* Scan Code 0x6C */ + KEY_RESERVED, /* Scan Code 0x6D */ + KEY_RESERVED, /* Scan Code 0x6E */ + KEY_RESERVED, /* Scan Code 0x6F */ + KEY_KP0, /* Scan Code 0x70 */ + KEY_KPDOT, /* Scan Code 0x71 DECIMAL?? */ + KEY_KP2, /* Scan Code 0x72 */ + KEY_KP5, /* Scan Code 0x73 */ + KEY_KP6, /* Scan Code 0x74 */ + KEY_KP8, /* Scan Code 0x75 */ + KEY_ESC, /* Scan Code 0x76 */ + KEY_NUMLOCK, /* Scan Code 0x77 */ + KEY_F11, /* Scan Code 0x78 */ + KEY_KPPLUS, /* Scan Code 0x79 */ + KEY_KP3, /* Scan Code 0x7A */ + KEY_KPMINUS, /* Scan Code 0x7B */ + KEY_KPASTERISK, /* Scan Code 0x7C */ + KEY_KP9, /* Scan Code 0x7D */ + KEY_SCROLLLOCK, /* Scan Code 0x7E */ + KEY_RESERVED, /* Scan Code 0x7F */ + KEY_RESERVED, /* Scan Code 0x80 */ + KEY_RESERVED, /* Scan Code 0x81 */ + KEY_RESERVED, /* Scan Code 0x82 */ + KEY_F7, /* Scan Code 0x83 */ + KEY_RESERVED, /* Scan Code 0x84 */ + KEY_RESERVED, /* Scan Code 0x85 */ + KEY_RESERVED, /* Scan Code 0x86 */ + KEY_RESERVED /* Scan Code 0x87 */ +}; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 21d55ed..5453395 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -95,4 +95,15 @@ config TOUCHSCREEN_HP600 To compile this driver as a module, choose M here: the module will be called hp680_ts_input. +config TOUCHSCREEN_EP93XX + tristate "EP93xx touchscreen" + depends on ARCH_EP93XX + help + Say Y here if you have a touchscreen connected to your EP93xx CPU. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called ep93xx_ts. + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 6842869..f8e6eb4 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o +obj-$(CONFIG_TOUCHSCREEN_EP93XX) += ep93xx_ts.o diff --git a/drivers/input/touchscreen/ep93xx_ts.c b/drivers/input/touchscreen/ep93xx_ts.c new file mode 100644 index 0000000..fc4622e --- /dev/null +++ b/drivers/input/touchscreen/ep93xx_ts.c @@ -0,0 +1,748 @@ +/* + * linux/drivers/char/ep93xx_ts.c + * + * Copyright (C) 2003-2004 Cirrus Corp. + * + * 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 + +/* + * To customize for a new touchscreen, there are various macros that + * have to be set. If you allow UART_HACK_DEBUG to be defined, you + * will get real time ts data scrolling up your serial terminal + * screen that will help you empirically determine good values for these. + * + * + * These are used as trigger levels to know when we have pen up/down + * + * The rules: + * 1. TS_HEAVY_INV_PRESSURE < TS_LIGHT_INV_PRESSURE because these + * are Inverse pressure. + * 2. Any touch lighter than TS_LIGHT_INV_PRESSURE is a pen up. + * 3. Any touch heavier than TS_HEAVY_INV_PRESSURE is a pen down. + */ +#define TS_HEAVY_INV_PRESSURE (0x1000 - pressure_max) +#define TS_LIGHT_INV_PRESSURE (0x1000 - pressure_min) + +/* + * If the x, y, or inverse pressure changes more than these values + * between two succeeding points, the point is not reported. + */ +#define TS_MAX_VALID_PRESSURE_CHANGE (pressure_jitter) +#define TS_MAX_VALID_XY_CHANGE (xy_jitter) + +/* old defaults */ +#if 0 +#define TS_X_MIN 0 +#define TS_Y_MIN 0 +#define TS_X_MAX 0xfff +#define TS_Y_MAX 0xfff +#endif + +/* "improved" defaults */ +#define TS_X_MIN 0x2d9 +#define TS_Y_MIN 0xd0a +#define TS_X_MAX 0xd42 +#define TS_Y_MAX 0x2e0 + +static uint16_t pressure_min = 0x001; +static uint16_t pressure_max = 0x010; +static uint16_t pressure_jitter = 0x300; +static uint16_t xy_jitter = 0x100; +module_param(pressure_min, ushort, 0); +module_param(pressure_max, ushort, 0); +module_param(pressure_jitter, ushort, 0); +module_param(xy_jitter, ushort, 0); +MODULE_PARM_DESC(pressure_min, "Minimum pressure (0 - 4095)"); +MODULE_PARM_DESC(pressure_max, "Maximum pressure (0 - 4095)"); +MODULE_PARM_DESC(pressure_jitter, "Minimum pressure jitter (0 - 4095)"); +MODULE_PARM_DESC(xy_jitter, "Minimum X-Y jitter (0 - 4095)"); + +/* This is the minimum Z1 Value that is valid. */ +#define MIN_Z1_VALUE 0x50 + +/* + * Settling delay for taking each ADC measurement. Increase this + * if ts is jittery. + */ +#define EP93XX_TS_ADC_DELAY_USEC 2000 + +/* Delay between TS points. */ + +#define EP93XX_TS_PER_POINT_DELAY_USEC 10000 + +/*----------------------------------------------------------------------------- + * Debug messaging thru the UARTs + *----------------------------------------------------------------------------- + * + * Hello there! Are you trying to get this driver to work with a new + * touschscreen? Turn this on and you will get useful info coming + * out of your serial port. + */ + +/* #define PRINT_CALIBRATION_FACTORS */ +#ifdef PRINT_CALIBRATION_FACTORS +#define UART_HACK_DEBUG 1 +int iMaxX = 0, iMaxY = 0, iMinX = 0xfff, iMinY = 0xfff; +#endif + +/* + * For debugging, let's spew messages out serial port 1 or 3 at 57,600 baud. + */ +#undef UART_HACK_DEBUG +#if defined(UART_HACK_DEBUG) && defined (CONFIG_DEBUG_LL) +static char szBuf[256]; +void UARTWriteString(char *msg); +extern void printascii(const char *msg); +#define DPRINTK( x... ) \ + sprintf( szBuf, ##x ); \ + printascii( szBuf ); +#else +#define DPRINTK( x... ) +#endif + +#define TSSETUP_DEFAULT ( TSSETUP_NSMP_32 | TSSETUP_DEV_64 | \ + ((128<= TS_LIGHT_INV_PRESSURE) { + DPRINTK(" -- up \n"); + bCurrentPenDown = 0; +/* input_report_key(dev, BTN_TOUCH, 0); */ + input_report_abs(dev, ABS_PRESSURE, 0); + input_sync(dev); + TS_Hardware_Scan_Mode(); + return; + } + /* + * Hystheresis: + * If the pen pressure is hard enough to be less than the 'min' OR + * the pen is already down and is still less than the 'max'... + */ + if ((uiInvPressure < TS_HEAVY_INV_PRESSURE) || + (bCurrentPenDown && (uiInvPressure < TS_LIGHT_INV_PRESSURE))) { + if (bCurrentPenDown) { + /* + * If pen was previously down, check the difference between + * the last sample and this one... if the difference between + * samples is too great, ignore the sample. + */ + uiXDiff = abs(guiLastX - sTouch.uiX); + uiYDiff = abs(guiLastY - sTouch.uiY); + uiInvPressureDiff = + abs(guiLastInvPressure - uiInvPressure); + + if ((uiXDiff < TS_MAX_VALID_XY_CHANGE) && + (uiYDiff < TS_MAX_VALID_XY_CHANGE) && + (uiInvPressureDiff < TS_MAX_VALID_PRESSURE_CHANGE)) + { + DPRINTK(" -- valid(two) \n"); + bValidPoint = 1; + } else { + DPRINTK(" -- INvalid(two) \n"); + } + } else { + DPRINTK(" -- valid \n"); + bValidPoint = 1; + } + + /* + * If either the pen was put down or dragged make a note of it. + */ + if (bValidPoint) { + guiLastX = sTouch.uiX; + guiLastY = sTouch.uiY; + guiLastInvPressure = uiInvPressure; + bCurrentPenDown = 1; + input_report_abs(dev, ABS_X, sTouch.uiX); + input_report_abs(dev, ABS_Y, sTouch.uiY); +/* input_report_key(dev, BTN_TOUCH, 1); */ + input_report_abs(dev, ABS_PRESSURE, 1); + input_sync(dev); + } + + TS_Soft_Scan_Mode(); + return; + } + + DPRINTK(" -- fallout \n"); + TS_Hardware_Scan_Mode(); +} + +static void ep93xx_ts_set_direct(unsigned int uiADCSwitch) +{ + unsigned int uiResult; + + /* Set the switch settings in the direct register. */ + writel(0xaa, TSSWLock); + writel(uiADCSwitch, TSDirect); + + /* Read and throw away the first sample. */ + do { + uiResult = readl(TSXYResult); + } while (!(uiResult & TSXYRESULT_SDR)); + +} + +static unsigned int ADCGetData(unsigned int uiSamples, unsigned int uiMaxDiff) +{ + unsigned int uiResult, uiValue, uiCount, uiLowest, uiHighest, uiSum, + uiAve; + + do { + /* Initialize our values. */ + uiLowest = 0xfffffff; + uiHighest = 0; + uiSum = 0; + + for (uiCount = 0; uiCount < uiSamples; uiCount++) { + /* Read the touch screen four more times and average. */ + do { + uiResult = readl(TSXYResult); + } while (!(uiResult & TSXYRESULT_SDR)); + + uiValue = + (uiResult & TSXYRESULT_AD_MASK) >> + TSXYRESULT_AD_SHIFT; + uiValue = + ((uiValue >> 4) + + ((1 + + TSXYRESULT_X_MASK) >> 1)) & TSXYRESULT_X_MASK; + + /* Add up the values. */ + uiSum += uiValue; + + /* Get the lowest and highest values. */ + if (uiValue < uiLowest) + uiLowest = uiValue; + + if (uiValue > uiHighest) + uiHighest = uiValue; + + } + + } while ((uiHighest - uiLowest) > uiMaxDiff); + + /* Calculate the Average value. */ + uiAve = uiSum / uiSamples; + + return uiAve; +} + +/** + * CalculateInvPressure + * + * Is the Touch Valid. Touch is not valid if the X or Y value is not + * in range and the pressure is not enough. + * + * Touch resistance can be measured by the following formula: + * + * Rx * X * Z2 + * Rtouch = --------- * (-- - 1) + * 4096 Z1 + * + * This is simplified in the ration of Rtouch to Rx. The lower the value, the + * higher the pressure. + * + * Z2 + * InvPressure = X * (-- - 1) + * Z1 + */ +static unsigned int CalculateInvPressure(void) +{ + unsigned int uiInvPressure; + + /* Check to see if the point is valid. */ + if (sTouch.uiZ1 < MIN_Z1_VALUE) + uiInvPressure = 0x10000; + + /* Can omit the pressure calculation if you need to get rid of the division. */ + else { + uiInvPressure = + ((sTouch.uiX * sTouch.uiZ2) / sTouch.uiZ1) - sTouch.uiX; + } + + return uiInvPressure; +} + +/** + * TS_Hardware_Scan_Mode + * Enables the ep93xx ts scanning engine so that when the pen goes down + * we will get an interrupt. + */ +static void TS_Hardware_Scan_Mode(void) +{ + unsigned int uiDevCfg; + + DPRINTK("S\n"); + + /* Disable the soft scanning engine. */ + sTouch.state = TS_STATE_STOPPED; + Stop_Timer2(); + + /* + * Clear the TIN (Touchscreen INactive) bit so we can go to + * automatic scanning mode. + */ + uiDevCfg = readl(SYSCON_DEVCFG); + SysconSetLocked(SYSCON_DEVCFG, + ep93xx_SYSCON_DEVCFG(uiDevCfg & ~SYSCON_DEVCFG_TIN)); + + /* + * Enable the touch screen scanning state machine by setting + * the ENABLE bit. + */ + writel((TSSETUP_DEFAULT | TSSETUP_ENABLE), TSSetup); + + /* Set the flag to show that we are in interrupt mode. */ + gScanningMode = TS_MODE_HARDWARE_SCAN; + + /* Initialize TSSetup2 register. */ + writel(TSSETUP2_DEFAULT, TSSetup2); + +} + +/** + * TS_Soft_Scan_Mode - Set the touch screen to manual polling mode. + */ +static void TS_Soft_Scan_Mode(void) +{ + unsigned int uiDevCfg; + + DPRINTK("M\n"); + + if (gScanningMode != TS_MODE_SOFT_SCAN) { + /* + * Disable the touch screen scanning state machine by clearing + * the ENABLE bit. + */ + writel(TSSETUP_DEFAULT, TSSetup); + + /* Set the TIN bit so we can do manual touchscreen polling. */ + uiDevCfg = readl(SYSCON_DEVCFG); + SysconSetLocked(SYSCON_DEVCFG, + ep93xx_SYSCON_DEVCFG(uiDevCfg | + SYSCON_DEVCFG_TIN)); + } + /* Set the switch register up for the first ADC reading */ + ep93xx_ts_set_direct(sSwitchSettings.uiSwitchZ1); + + /* + * Initialize our software state machine to know which ADC + * reading to take + */ + sTouch.state = TS_STATE_Z1; + + /* + * Set the timer so after a mSec or two settling delay it will + * take the first ADC reading. + */ + Set_Timer2_uSec(EP93XX_TS_PER_POINT_DELAY_USEC); + + /* Note that we are in sw scanning mode not hw scanning mode. */ + gScanningMode = TS_MODE_SOFT_SCAN; + +} + +static void Set_Timer2_uSec(unsigned int uiDelay_uSec) +{ + unsigned int uiClockTicks; + + /* + * Stop timer 2 + */ + writel(0, TIMER2CONTROL); + + uiClockTicks = ((uiDelay_uSec * 508) + 999) / 1000; + writel(uiClockTicks, TIMER2LOAD); + writel(uiClockTicks, TIMER2VALUE); + + /* + * Set up Timer 2 for 508 kHz clock and periodic mode. + */ + writel(0xC8, TIMER2CONTROL); + +} + +static void Stop_Timer2(void) +{ + writel(0, TIMER2CONTROL); +} + +static struct input_dev *ep93xx_ts_dev; + +static int __init ep93xx_ts_init(void) +{ + ep93xx_ts_dev = input_allocate_device(); + if (!ep93xx_ts_dev) { + printk(KERN_ERR "ep93xx_ts_dev: not enough memory for input device\n"); + return -ENOMEM; + } + + ep93xx_ts_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + ep93xx_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + ep93xx_ts_dev->keybit[LONG(BTN_RAW)] = BIT(BTN_RAW); + + /* untested, I haven't got a touchscreen (yet) :( */ + input_set_abs_params(ep93xx_ts_dev, ABS_X, 0, 4095, 0, 0); + input_set_abs_params(ep93xx_ts_dev, ABS_Y, 0, 4095, 0, 0); + input_set_abs_params(ep93xx_ts_dev, ABS_PRESSURE, 0, 1, 0, 0); + + ep93xx_ts_dev->open = ep93xx_ts_open; + ep93xx_ts_dev->close = ep93xx_ts_close; + ep93xx_ts_dev->name = "Cirrus Logic EP93xx Touchscreen"; + ep93xx_ts_dev->phys = "ep93xx_ts/input0"; + ep93xx_ts_dev->id.bustype = BUS_HOST; + ep93xx_ts_dev->id.vendor = PCI_VENDOR_ID_CIRRUS; + ep93xx_ts_dev->id.product = 0x9300; + + input_set_abs_params(ep93xx_ts_dev, ABS_X, TS_X_MIN, TS_X_MAX, 0, 0); + input_set_abs_params(ep93xx_ts_dev, ABS_Y, TS_Y_MIN, TS_Y_MAX, 0, 0); + input_register_device(ep93xx_ts_dev); + + sTouch.state = TS_STATE_STOPPED; + gScanningMode = TS_MODE_UN_INITIALIZED; + + printk(KERN_NOTICE + "EP93xx touchscreen driver configured for 4-wire operation\n"); + return 0; +} + +static void __exit ep93xx_ts_exit(void) +{ + input_unregister_device(ep93xx_ts_dev); +} + +module_init(ep93xx_ts_init); +module_exit(ep93xx_ts_exit); + +MODULE_DESCRIPTION("Cirrus EP93xx touchscreen driver"); +MODULE_SUPPORTED_DEVICE("touchscreen/ep93xx"); diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index b9b77cf..4e0e427 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -137,6 +137,13 @@ config MTD_MAINSTONE This provides a driver for the on-board flash of the Intel 'Mainstone PXA27x evaluation board. +config MTD_ADSFLASH + tristate "CFI Flash device mapped on ADS" + depends on ARM && MTD_CFI && MACH_ADSSPHERE && MTD_PARTITIONS + help + This enables access to on-board flash memory on ADS platforms that + have an Intel XScale PXA2xx CPU. + config MTD_OCTAGON tristate "JEDEC Flash device mapped on Octagon 5066 SBC" depends on X86 && MTD_JEDEC && MTD_COMPLEX_MAPPINGS @@ -639,5 +646,19 @@ config MTD_PLATRAM This selection automatically selects the map_ram driver. +config MTD_ZEFEERDZB + tristate "Map driver for DAVE Srl ZefeerDZB processor module" + depends on (MTD_CFI && MACH_ZEFEERDZB) + select MTD_PARTITIONS + help + Map driver for DAVE Srl ZefeerDZB processor module. + +config MTD_ZEFEERDZQ + tristate "Map driver for DAVE Srl ZefeerDZQ processor module" + depends on (MTD_CFI && MACH_ZEFEERDZQ) + select MTD_PARTITIONS + help + Map driver for DAVE Srl ZefeerDZQ processor module. + endmenu diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 2f7e254..a821568 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o +obj-$(CONFIG_MTD_ADSFLASH) += ads-flash.o obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o obj-$(CONFIG_MTD_MBX860) += mbx860.o obj-$(CONFIG_MTD_CEIVA) += ceiva.o @@ -72,3 +73,5 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o obj-$(CONFIG_MTD_TQM834x) += tqm834x.o +obj-$(CONFIG_MTD_ZEFEERDZB) += zefeerdzb.o +obj-$(CONFIG_MTD_ZEFEERDZQ) += zefeerdzq.o diff --git a/drivers/mtd/maps/ads-flash.c b/drivers/mtd/maps/ads-flash.c new file mode 100644 index 0000000..2428e9c --- /dev/null +++ b/drivers/mtd/maps/ads-flash.c @@ -0,0 +1,221 @@ +/* + * Map driver for the ADS PXA Boards. + * + * 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 + +#ifdef CONFIG_MACH_ADSVIX +#define NUM_CHIPS 1 +#else +#define NUM_CHIPS 2 +#endif + +#ifdef CONFIG_PXA27x +#define WINDOW_ADDR 0 +#elif defined(CONFIG_ARCH_EP93XX) +#define WINDOW_ADDR 0x60000000 +#else +#define WINDOW_ADDR 0x04000000 +#endif + +#define WINDOW_SIZE (NUM_CHIPS * 32*1024*1024) +#define BLOCKSIZE (NUM_CHIPS * 0x20000) +#define BANKWIDTH (NUM_CHIPS * 2) + +static void pxa_map_inval_cache(struct map_info *map, unsigned long from, ssize_t len) +{ + consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE); +} + +static struct map_info pxa_map = { + .name = "pxa", + .size = WINDOW_SIZE, + .phys = WINDOW_ADDR, + .virt = 0, + .cached = (void *)NULL, + .bankwidth = BANKWIDTH, + .inval_cache = pxa_map_inval_cache, +}; + +static struct mtd_partition ads_partitions[] = { + { + name: "boot", + size: BLOCKSIZE, + offset: 0, + }, { + name: "bootvars", + size: BLOCKSIZE, + offset: MTDPART_OFS_APPEND, + }, { + name: "zImage", + size: 0x00180000, + offset: MTDPART_OFS_APPEND, + }, { + name: "ramdisk.gz", + size: 0x00500000, + offset: MTDPART_OFS_APPEND, + }, { + name: "flashfs1", + size: MTDPART_SIZ_FULL, + offset: MTDPART_OFS_APPEND + } +}; + +unsigned char ads_flash_serial_id[32+2] = {0}; + +static struct mtd_info *mymtd = NULL; +static struct mtd_partition *parsed_parts = NULL; +static int num_parts = 0; +static const char *probes[] = { +#ifdef CONFIG_MTD_CMDLINE_PARTS + "cmdlinepart", +#endif +#ifdef CONFIG_MTD_REDBOOT_PARTS + "RedBoot", +#endif + NULL }; + +// This implementation supports 1 or 2 chips. +static void ads_get_flash_serial_id(int chips) +{ + map_word val; + unsigned int addr = 0x81 << chips; + unsigned int mask = chips == 1 ? 0xffff : 0xffffffff; + unsigned int tmp[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int i; + + /* read array mode */ + // *(__u32 *)pxa_map.virt = 0x00FF00FF; + // *(__u16 *)pxa_map.virt = 0x00ff; + val.x[0] = 0x00ff00ff & mask; + map_write(&pxa_map, val, 0); + + /* read id mode */ + // *(__u32 *)pxa_map.virt = 0x00900090; + // *(__u16 *)pxa_map.virt = 0x0090; + val.x[0] = 0x00900090 & mask; + map_write(&pxa_map, val, 0); + + for (i=0; i<8; i++) { + // tmp[i] = 0x0000ffff & *(__u32 *)(pxa_map.virt + addr); + // tmp[i] = *(__u16 *)(pxa_map.virt + addr); + val = map_read(&pxa_map, addr); + tmp[i] = val.x[0] & 0xffff; + addr += BANKWIDTH; + } + + /* back to read array mode */ + // *(__u32 *)pxa_map.virt = 0x00FF00FF; + // *(__u16 *)pxa_map.virt = 0x00ff; + val.x[0] = 0x00ff00ff & mask; + map_write(&pxa_map, val, 0); + + sprintf(ads_flash_serial_id, "%04x%04x%04x%04x.%04x%04x%04x%04x", + tmp[7], tmp[6], tmp[5], tmp[4], tmp[3], tmp[2], tmp[1], tmp[0]); + +} + +static int __init init_pxa_flash(void) +{ + struct mtd_partition *parts; + char *part_type; + int rtn; + + printk(KERN_NOTICE "Probing PXA flash at physical address 0x%08x\n", WINDOW_ADDR); + pxa_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); + if (!pxa_map.virt) { + printk(KERN_ERR "Failed to ioremap flash\n"); + return -EIO; + } + + pxa_map.cached = __ioremap(WINDOW_ADDR, WINDOW_SIZE, L_PTE_CACHEABLE, 1); + if (!pxa_map.cached) + printk(KERN_WARNING "Failed to ioremap cached flash\n"); + + simple_map_init(&pxa_map); + + mymtd = do_map_probe("cfi_probe", &pxa_map); + if (!mymtd) { + if (pxa_map.cached) + iounmap((void *)pxa_map.cached); + if (pxa_map.virt) + iounmap((void *)pxa_map.virt); + return -ENXIO; + } + +#ifdef CONFIG_MTD_CMDLINE_PARTS + pxa_map.name = "pxa"; + rtn = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0); + if (rtn <= 0) { + pxa_map.name = "sa1100"; + rtn = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0); + } + if (rtn > 0) { + num_parts = rtn; + parts = parsed_parts; + part_type = "command line"; + goto add_parts; + } +#endif + num_parts = ARRAY_SIZE(ads_partitions); + parts = ads_partitions; + part_type = "static"; +add_parts: + if (num_parts) { + printk(KERN_NOTICE "Using %s partition definition\n", part_type); + add_mtd_partitions(mymtd, parts, num_parts); +#if 0 + if (mymtd->unlock) { + int i; + for (i = 0; i < num_parts; i++) { + // unlock partition + mymtd->unlock(mymtd, parts[num_parts - 1].offset, + parts[num_parts - 1].size); + } + } +#endif + } + else { + add_mtd_device(mymtd); + } + + ads_get_flash_serial_id(NUM_CHIPS); + + return 0; +} + +static void __exit cleanup_pxa_flash(void) +{ + if (mymtd) { + if (num_parts) + del_mtd_partitions(mymtd); + else + del_mtd_device(mymtd); + map_destroy(mymtd); + if (parsed_parts) + kfree(parsed_parts); + } + if (pxa_map.cached) + iounmap((void *)pxa_map.cached); + if (pxa_map.virt) + iounmap((void *)pxa_map.virt); +} + +module_init(init_pxa_flash); +module_exit(cleanup_pxa_flash); + +MODULE_LICENSE("GPL"); diff --git a/drivers/mtd/maps/zefeerdzb.c b/drivers/mtd/maps/zefeerdzb.c new file mode 100644 index 0000000..bb47bc6 --- /dev/null +++ b/drivers/mtd/maps/zefeerdzb.c @@ -0,0 +1,134 @@ +/* + * $Id: zefeerdzb.c,v 1.8 2004/07/12 21:59:44 dwmw2 Exp $ + * + * drivers/mtd/maps/zefeerdzb.c + * + * FLASH map for the DAVE Srl ZefeerDZB processor module. + * + * + * 2004 (c) DAVE Srl. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if 0 +/* Support for ZELK <= 0.9.5 */ +#define WINDOW_ADDR 0x60000000 +#else +#define WINDOW_ADDR 0x00000000 +#endif +#define WINDOW_SIZE 0x00400000 + +/* 128 kB U-Boot */ +#define ZEFEERDZB_PART0_OF 0 +#define ZEFEERDZB_PART0_SZ 0x20000 +/* 128 kB U-Boot env #1 */ +#define ZEFEERDZB_PART1_OF ZEFEERDZB_PART0_OF + ZEFEERDZB_PART0_SZ +#define ZEFEERDZB_PART1_SZ 0x20000 +/* 128 kB U-Boot env #2 */ +#define ZEFEERDZB_PART2_OF ZEFEERDZB_PART1_OF + ZEFEERDZB_PART1_SZ +#define ZEFEERDZB_PART2_SZ 0x20000 +/* Linux kernel */ +#define ZEFEERDZB_PART3_OF ZEFEERDZB_PART2_OF + ZEFEERDZB_PART2_SZ +#define ZEFEERDZB_PART3_SZ (0x200000 - ZEFEERDZB_PART2_SZ - ZEFEERDZB_PART1_SZ - ZEFEERDZB_PART0_SZ) +/* spare */ +#define ZEFEERDZB_PART4_OF ZEFEERDZB_PART3_OF + ZEFEERDZB_PART3_SZ +#define ZEFEERDZB_PART4_SZ (0x400000 - ZEFEERDZB_PART3_SZ - ZEFEERDZB_PART2_SZ - ZEFEERDZB_PART1_SZ - ZEFEERDZB_PART0_SZ) + +static struct mtd_partition zefeerdzb_flash_partitions[] = { + { + .name = "U-Boot", + .offset = ZEFEERDZB_PART0_OF, + .size = ZEFEERDZB_PART0_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot environment #1", + .offset = ZEFEERDZB_PART1_OF, + .size = ZEFEERDZB_PART1_SZ, + }, + { + .name = "U-Boot environment #2", + .offset = ZEFEERDZB_PART2_OF, + .size = ZEFEERDZB_PART2_SZ, + }, + { + .name = "Linux kernel", + .offset = ZEFEERDZB_PART3_OF, + .size = ZEFEERDZB_PART3_SZ, + }, + { + .name = "spare 1", + .offset = ZEFEERDZB_PART4_OF, + .size = ZEFEERDZB_PART4_SZ, + } +}; + +struct map_info zefeerdzb_flash_map = { + .name = "DAVE Srl ZefeerDZB", + .size = WINDOW_SIZE, + .bankwidth = 2, + .phys = WINDOW_ADDR, +}; + +#define NUM_ZEFEERDZB_FLASH_PARTITIONS \ + (sizeof(zefeerdzb_flash_partitions)/sizeof(zefeerdzb_flash_partitions[0])) + +static struct mtd_info *zefeerdzb_mtd; + +int __init init_zefeerdzb_flash(void) +{ + printk(KERN_NOTICE "zefeerdzb: flash mapping: %x at %x\n", + WINDOW_SIZE, WINDOW_ADDR); + + zefeerdzb_flash_map.virt = + (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + + if (!zefeerdzb_flash_map.virt) { + printk("init_zefeerdzb_flash: failed to ioremap\n"); + return -EIO; + } + simple_map_init(&zefeerdzb_flash_map); + + zefeerdzb_mtd = do_map_probe("cfi_probe", &zefeerdzb_flash_map); + + if (zefeerdzb_mtd) { + zefeerdzb_mtd->owner = THIS_MODULE; + return add_mtd_partitions(zefeerdzb_mtd, + zefeerdzb_flash_partitions, + NUM_ZEFEERDZB_FLASH_PARTITIONS); + } + + return -ENXIO; +} + +static void __exit cleanup_zefeerdzb_flash(void) +{ + if (zefeerdzb_mtd) { + del_mtd_partitions(zefeerdzb_mtd); + /* moved iounmap after map_destroy - armin */ + map_destroy(zefeerdzb_mtd); + iounmap((void *)zefeerdzb_flash_map.virt); + } +} + +module_init(init_zefeerdzb_flash); +module_exit(cleanup_zefeerdzb_flash); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("DAVE Srl "); +MODULE_DESCRIPTION + ("MTD map driver for the DAVE Srl ZefeerDZB processor module"); diff --git a/drivers/mtd/maps/zefeerdzq.c b/drivers/mtd/maps/zefeerdzq.c new file mode 100644 index 0000000..dc0e402 --- /dev/null +++ b/drivers/mtd/maps/zefeerdzq.c @@ -0,0 +1,142 @@ +/* + * $Id: zefeerdzq.c,v 1.8 2004/07/12 21:59:44 dwmw2 Exp $ + * + * drivers/mtd/maps/zefeerdzq.c + * + * FLASH map for the DAVE Srl ZefeerDZQ processor module. + * + * + * 2004 (c) DAVE Srl. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if 0 +/* Support for ZELK <= 0.9.5 */ +#define WINDOW_ADDR 0x60000000 +#else +#define WINDOW_ADDR 0x00000000 +#endif +#define WINDOW_SIZE 0x01000000 + +/* 128 kB U-Boot */ +#define ZEFEERDZQ_PART0_OF 0 +#define ZEFEERDZQ_PART0_SZ 0x20000 +/* 128 kB U-Boot env #1 */ +#define ZEFEERDZQ_PART1_OF ZEFEERDZQ_PART0_OF + ZEFEERDZQ_PART0_SZ +#define ZEFEERDZQ_PART1_SZ 0x20000 +/* 128 kB U-Boot env #2 */ +#define ZEFEERDZQ_PART2_OF ZEFEERDZQ_PART1_OF + ZEFEERDZQ_PART1_SZ +#define ZEFEERDZQ_PART2_SZ 0x20000 +/* Linux kernel */ +#define ZEFEERDZQ_PART3_OF ZEFEERDZQ_PART2_OF + ZEFEERDZQ_PART2_SZ +#define ZEFEERDZQ_PART3_SZ (0x200000 - ZEFEERDZQ_PART2_SZ - ZEFEERDZQ_PART1_SZ - ZEFEERDZQ_PART0_SZ) +/* ramdisk */ +#define ZEFEERDZQ_PART4_OF ZEFEERDZQ_PART3_OF + ZEFEERDZQ_PART3_SZ +#define ZEFEERDZQ_PART4_SZ (0x400000 - ZEFEERDZQ_PART3_SZ - ZEFEERDZQ_PART2_SZ - ZEFEERDZQ_PART1_SZ - ZEFEERDZQ_PART0_SZ) +/* spare */ +#define ZEFEERDZQ_PART5_OF ZEFEERDZQ_PART4_OF + ZEFEERDZQ_PART4_SZ +#define ZEFEERDZQ_PART5_SZ (WINDOW_SIZE - ZEFEERDZQ_PART4_SZ - ZEFEERDZQ_PART3_SZ - ZEFEERDZQ_PART2_SZ - ZEFEERDZQ_PART1_SZ - ZEFEERDZQ_PART0_SZ) + +static struct mtd_partition zefeerdzq_flash_partitions[] = { + { + .name = "U-Boot", + .offset = ZEFEERDZQ_PART0_OF, + .size = ZEFEERDZQ_PART0_SZ, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot environment #1", + .offset = ZEFEERDZQ_PART1_OF, + .size = ZEFEERDZQ_PART1_SZ, + }, + { + .name = "U-Boot environment #2", + .offset = ZEFEERDZQ_PART2_OF, + .size = ZEFEERDZQ_PART2_SZ, + }, + { + .name = "Linux kernel", + .offset = ZEFEERDZQ_PART3_OF, + .size = ZEFEERDZQ_PART3_SZ, + }, + { + .name = "spare 1", + .offset = ZEFEERDZQ_PART4_OF, + .size = ZEFEERDZQ_PART4_SZ, + }, + { + .name = "spare 2", + .offset = ZEFEERDZQ_PART5_OF, + .size = ZEFEERDZQ_PART5_SZ, + } +}; + +struct map_info zefeerdzq_flash_map = { + .name = "DAVE Srl ZefeerDZQ", + .size = WINDOW_SIZE, + .bankwidth = 2, + .phys = WINDOW_ADDR, +}; + +#define NUM_ZEFEERDZQ_FLASH_PARTITIONS \ + (sizeof(zefeerdzq_flash_partitions)/sizeof(zefeerdzq_flash_partitions[0])) + +static struct mtd_info *zefeerdzq_mtd; + +int __init init_zefeerdzq_flash(void) +{ + printk(KERN_NOTICE "zefeerdzq: flash mapping: %x at %x\n", + WINDOW_SIZE, WINDOW_ADDR); + + zefeerdzq_flash_map.virt = + (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + + if (!zefeerdzq_flash_map.virt) { + printk("init_zefeerdzq_flash: failed to ioremap\n"); + return -EIO; + } + simple_map_init(&zefeerdzq_flash_map); + + zefeerdzq_mtd = do_map_probe("cfi_probe", &zefeerdzq_flash_map); + + if (zefeerdzq_mtd) { + zefeerdzq_mtd->owner = THIS_MODULE; + return add_mtd_partitions(zefeerdzq_mtd, + zefeerdzq_flash_partitions, + NUM_ZEFEERDZQ_FLASH_PARTITIONS); + } + + return -ENXIO; +} + +static void __exit cleanup_zefeerdzq_flash(void) +{ + if (zefeerdzq_mtd) { + del_mtd_partitions(zefeerdzq_mtd); + /* moved iounmap after map_destroy - armin */ + map_destroy(zefeerdzq_mtd); + iounmap((void *)zefeerdzq_flash_map.virt); + } +} + +module_init(init_zefeerdzq_flash); +module_exit(cleanup_zefeerdzq_flash); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("DAVE Srl "); +MODULE_DESCRIPTION + ("MTD map driver for the DAVE Srl ZefeerDZQ processor module"); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 1fc4c13..8e79d32 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -109,6 +109,12 @@ config MTD_NAND_S3C2410_HWECC currently not be able to switch to software, as there is no implementation for ECC method used by the S3C2410 +config MTD_NAND_ZEFEEREVB + tristate "NAND Flash device on ZefeerEVB (L/H) board" + depends on (MACH_ZEFEERDZA || MACH_ZEFEERDZB || MACH_ZEFEERDZG || MACH_ZEFEERDZN || MACH_ZEFEERDZQ) && MTD_NAND + help + This enables the NAND flash driver on the ZefeerEVB Board (L or H version). + config MTD_NAND_DISKONCHIP tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)" depends on MTD_NAND && EXPERIMENTAL diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 4174202..bee7760 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_MTD_NAND_H1900) += h1910.o obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o +obj-$(CONFIG_MTD_NAND_ZEFEEREVB) += zefeerevb.o nand-objs = nand_base.o nand_bbt.o diff --git a/drivers/mtd/nand/zefeerevb.c b/drivers/mtd/nand/zefeerevb.c new file mode 100644 index 0000000..b67e958 --- /dev/null +++ b/drivers/mtd/nand/zefeerevb.c @@ -0,0 +1,280 @@ +/* + * drivers/mtd/nand/zefeerevb.c + * + * Copyright (C) 2004 DAVE Srl (info@dave-tech.it) + * + * + * + * $Id: zefeerevb.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $ + * + * 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. + * + * Overview: + * This is a device driver for the NAND flash devices found on the + * ZefeerEVB board (Samsung K9F5608U0B 32MB). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_READY_BUSY_PIN +/* see datasheets (tR) */ +#define NAND_BIG_DELAY_US 25 +#define NAND_SMALL_DELAY_US 10 + +/* handy sizes */ +#define SZ_4M 0x00400000 +#define NAND_SMALL_SIZE 0x02000000 +#define NAND_EVB_MTD_NAME "zefeerevb-nand" + +/* Macros to perform I/O operations */ +#define MACRO_NAND_DISABLE_CE(nandptr) do \ +{ \ + writel(readl((volatile unsigned*)GPIO_PADR) | NAND_EVB_nCE_GPIO_PIN, (volatile unsigned*)GPIO_PADR); \ +} while(0) + +#define MACRO_NAND_ENABLE_CE(nandptr) do \ +{ \ + writel(readl((volatile unsigned*)GPIO_PADR) & ~NAND_EVB_nCE_GPIO_PIN, (volatile unsigned*)GPIO_PADR); \ +} while(0) + +#define MACRO_NAND_CTL_CLRALE(nandptr) do \ +{ \ + writel(readl((volatile unsigned*)GPIO_PADR) & ~NAND_EVB_ALE_GPIO_PIN, (volatile unsigned*)GPIO_PADR); \ +} while(0) + +#define MACRO_NAND_CTL_SETALE(nandptr) do \ +{ \ + writel(readl((volatile unsigned*)GPIO_PADR) | NAND_EVB_ALE_GPIO_PIN, (volatile unsigned*)GPIO_PADR); \ +} while(0) + +#define MACRO_NAND_CTL_CLRCLE(nandptr) do \ +{ \ + writel(readl((volatile unsigned*)GPIO_PADR) & ~NAND_EVB_CLE_GPIO_PIN, (volatile unsigned*)GPIO_PADR); \ +} while(0) + +#define MACRO_NAND_CTL_SETCLE(nandptr) do \ +{ \ + writel(readl((volatile unsigned*)GPIO_PADR) | NAND_EVB_CLE_GPIO_PIN, (volatile unsigned*)GPIO_PADR); \ +} while(0) + +#define MACRO_NAND_WAIT_READY(nand) \ +while ( !(readl((volatile unsigned*)GPIO_PADR) & NAND_EVB_RB_GPIO_PIN); ) + +/* + * MTD structure for ZefeerEVB board + */ +static struct mtd_info *zefeerevb_mtd = NULL; + +/* + * Module stuff + */ +static int zefeerevb_fio_pbase = ZEFEEREVB_NAND_PADDR; + +#ifdef MODULE +MODULE_PARM(zefeerevb_fio_pbase, "i"); +__setup("zefeerevb_fio_pbase=", zefeerevb_fio_pbase); +#endif + +#ifdef CONFIG_MTD_PARTITIONS +/* + * Define static partitions for flash devices + */ +static struct mtd_partition partition_info_evb[] = { + {name:"ZefeerEVB Nand Flash", + offset:0, + size:32 * 1024 * 1024} +}; + +#define NUM_PARTITIONS 1 + +extern int parse_cmdline_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + const char *mtd_id); +#endif + +static void zefeerevb_hwcontrol(struct mtd_info *mtdinfo, int cmd) +{ + switch (cmd) { + + case NAND_CTL_SETCLE: + MACRO_NAND_CTL_SETCLE((unsigned long)0); + break; + case NAND_CTL_CLRCLE: + MACRO_NAND_CTL_CLRCLE((unsigned long)0); + break; + case NAND_CTL_SETALE: + MACRO_NAND_CTL_SETALE((unsigned long)0); + break; + case NAND_CTL_CLRALE: + MACRO_NAND_CTL_CLRALE((unsigned long)0); + break; + case NAND_CTL_SETNCE: + MACRO_NAND_ENABLE_CE((unsigned long)0); + break; + case NAND_CTL_CLRNCE: + MACRO_NAND_DISABLE_CE((unsigned long)0); + break; + } +} + +#ifdef USE_READY_BUSY_PIN +/* + * read device ready pin + */ +static int zefeerevb_device_ready(struct mtd_info *minfo) +{ + return (readl((volatile unsigned *)GPIO_PADR) & + NAND_EVB_RB_GPIO_PIN); +} +#endif + +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes_evb[] = { "cmdlinepart", NULL }; +#endif + +/* + * Main initialization routine + */ +static int __init zefeerevb_init(void) +{ + struct nand_chip *this; + const char *part_type = 0; + int mtd_parts_nb = 0; + struct mtd_partition *mtd_parts = 0; + void __iomem *zefeerevb_fio_base; + u32 tmp; + + /* Init I/O pins */ + MACRO_NAND_DISABLE_CE(0); + MACRO_NAND_CTL_CLRALE(0); + MACRO_NAND_CTL_CLRCLE(0); + + tmp = (u32) readl(GPIO_PADDR); + tmp |= + (NAND_EVB_nCE_GPIO_PIN | NAND_EVB_CLE_GPIO_PIN | + NAND_EVB_ALE_GPIO_PIN); +#ifdef USE_READY_BUSY_PIN + tmp &= ~NAND_EVB_RB_GPIO_PIN; +#endif + writel(tmp, GPIO_PADDR); + + /* Init I/O pins */ + MACRO_NAND_DISABLE_CE(0); + MACRO_NAND_CTL_CLRALE(0); + MACRO_NAND_CTL_CLRCLE(0); + + /* Set up chip select */ + writel((0 << 30) | (0 << 28) | (0 << 27) | (0 << 26) | (0 << 11) | + (1 << 10) | (4 << 5) | (6 << 0), SMCBCR2); + + /* Allocate memory for MTD device structure and private data */ + zefeerevb_mtd = kmalloc(sizeof(struct mtd_info) + + sizeof(struct nand_chip), GFP_KERNEL); + if (!zefeerevb_mtd) { + printk + ("Unable to allocate ZefeerEVB NAND MTD device structure.\n"); + return -ENOMEM; + } + + /* map physical address */ + zefeerevb_fio_base = + (void __iomem *)ioremap(zefeerevb_fio_pbase, SZ_4M); + if (!zefeerevb_fio_base) { + printk("ioremap ZefeerEVB NAND flash failed\n"); + kfree(zefeerevb_mtd); + return -EIO; + } + + /* Get pointer to private data */ + this = (struct nand_chip *)(&zefeerevb_mtd[1]); + + /* Initialize structures */ + memset((char *)zefeerevb_mtd, 0, sizeof(struct mtd_info)); + memset((char *)this, 0, sizeof(struct nand_chip)); + + /* Link the private data with the MTD structure */ + zefeerevb_mtd->priv = this; + + /* insert callbacks */ + this->IO_ADDR_R = (void __iomem *)zefeerevb_fio_base; + this->IO_ADDR_W = (void __iomem *)zefeerevb_fio_base; + this->hwcontrol = zefeerevb_hwcontrol; +#ifdef USE_READY_BUSY_PIN + this->dev_ready = zefeerevb_device_ready; +#endif + this->chip_delay = NAND_SMALL_DELAY_US; + + /* ECC mode */ + this->eccmode = NAND_ECC_SOFT; + + /* Scan to find existence of the device */ + if (nand_scan(zefeerevb_mtd, 1)) { + iounmap((void *)zefeerevb_fio_base); + kfree(zefeerevb_mtd); + return -ENXIO; + } +#ifdef CONFIG_MTD_PARTITIONS + zefeerevb_mtd->name = NAND_EVB_MTD_NAME; + mtd_parts_nb = + parse_mtd_partitions(zefeerevb_mtd, part_probes_evb, &mtd_parts, 0); + if (mtd_parts_nb > 0) + part_type = "command line"; + else + mtd_parts_nb = 0; +#endif + if (mtd_parts_nb == 0) { +#ifdef CONFIG_MTD_PARTITIONS + mtd_parts = partition_info_evb; + mtd_parts_nb = NUM_PARTITIONS; +#endif + part_type = "static"; + } + + /* Register the partitions */ + printk(KERN_NOTICE "Using %s partition definition\n", part_type); + add_mtd_partitions(zefeerevb_mtd, mtd_parts, mtd_parts_nb); + + /* Return happy */ + return 0; +} + +module_init(zefeerevb_init); + +#ifdef MODULE +/* + * Clean up routine + */ +static void __exit zefeerevb_cleanup(void) +{ + struct nand_chip *this; + + /* Release resources, unregister device(s) */ + nand_release(zefeer_mtd); + nand_release(zefeerevb_mtd); + + /* Release iomaps */ + this = (struct nand_chip *)&zefeer_mtd[1]; + iounmap((void *)this->zefeer_fio_base; + this = (struct nand_chip *)&zefeerevb_mtd[1]; + iounmap((void *)this->zefeerevb_fio_base; + /* Free the MTD device structure */ + kfree(zefeer_mtd); + kfree(zefeerevb_mtd); + } + + module_exit(zefeerevb_cleanup); +#endif + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("DAVE Srl "); + MODULE_DESCRIPTION + ("MTD map driver for DAVE Srl ZefeerEVB (L/H) board"); diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 470364d..12afe1d 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig @@ -44,3 +44,13 @@ config ARM_ETHER00 will generate a suitable hw address based on the board serial number (MTD support is required for this). Otherwise you will need to set a suitable hw address using ifconfig. + +config EP93XX_ETHERNET + tristate "EP93xx Ethernet support" + depends on NET_ETHERNET && ARM && ARCH_EP93XX + select CRC32 + select MII + help + This is a driver for the ethernet hardware included in EP93xx CPUs. + Say Y if you are building a kernel for EP93xx based devices. + diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index b0d7068..c1539da 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_ARM_ETHER00) += ether00.o obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o +obj-$(CONFIG_EP93XX_ETHERNET) += ep93xx_eth.o diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c new file mode 100644 index 0000000..e314549 --- /dev/null +++ b/drivers/net/arm/ep93xx_eth.c @@ -0,0 +1,1412 @@ +/* + * ep93xx_eth.c + * Ethernet Device Driver for Cirrus Logic EP93xx. + * + * Copyright (C) 2003 by Cirrus Logic www.cirrus.com + * This software may be used and distributed according to the terms + * of the GNU Public License. + * + * This driver was written based on skeleton.c by Donald Becker and + * smc9194.c by Erik Stahlman. + * + * Getting a MAC address: + * + * Former versions of this driver got their MAC from I2C EEPROM or even used + * hardcoded ones. Unfortunately I had to remove the board dependant I2C stuff, + * and use a random generated MAC instead of the hardcoded one. Good news is + * the there is support for setting the MAC from userspace now. (see below) + * + * first consider some potential problems if you use this random generated MAC: + * + * you can no longer count on it to be really unique + * identifying a particular board over network will be difficult + * DHCP servers can no longer use the MAC for assigning static IPs + * DHCP servers with long leasetimes quickly run out of leases + * ... + * + * So how can you set a valid MAC from userspace then? + * + * Let's say you've just bought your OUI from IEEE and it's "aa:bb:cc" + * Now you'd like to assign the MAC for your EP93xx board with serial #5 + * MAC = OUI<<24 + serial number = aa:bb:cc:00:00:05 + * + * ifconfig eth0 hw ether aa:bb:cc:00:00:05 # first set the MAC + * ifconfig eth0 192.168.1.1 netmask 255.255.255.0 up # then set the IP + * + * Apart from hardcoding this lines in your startup scripts you could also use + * some userspace utility to read (and set) the MAC from eeprom, flash, ... + * + * History: + * 07/19/01 0.1 Sungwook Kim initial release + * 10/16/01 0.2 Sungwook Kim add workaround for ignorance of Tx request + * while sending frame + * add some error stuations handling + * + * 03/25/03 Melody Lee Modified for EP93xx + * + * 2004/2005 Michael Burian porting to linux-2.6 + * 2005-10-12 Michael Burian fix problems when setting MAC with ifconfig + * 2005-10-30 Michael Burian cleanups, ethtool support + */ + +/* TODO: + * 1. try if it's possible to use skbuff directly for RX/TX (avoid memcpy) + * 2. use kzalloc instead of kmalloc+memset + */ + +#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 +#include + +#include "ep93xx_eth.h" + +#define DRV_NAME "ep93xx_eth" +#define DRV_VERSION "2.8" +#define DRV_DATE "2005-11-08" + +static const char *version = DRV_NAME ": version " DRV_VERSION " " DRV_DATE \ + " Cirrus Logic\n"; + +/* total number of device instance, 0 means the 1st instance. */ +static int num_of_instance; +static struct net_device * ep93xx_etherdev; + +/* + * A List of default device port configuration for auto probing. + * At this time, the CPU has only one Ethernet device, + * but better to support multiple device configuration. + * Keep in mind that the array must end in zero. + */ + +/* We get the MAC_BASE from include/asm-arm/arch-ep93xx/regmap.h */ +static struct { + unsigned int base_addr; /* base address, (0:end mark) */ + int irq; /* IRQ number, (0:auto detect) */ +} port_list[] __initdata = { + { + MAC_BASE, 39}, { + 0 /* end mark */ , 0} +}; + +/* + * Some definitions belong to the operation of this driver. + * You should understand how it affect to driver before any modification. + */ + +/* Interrupt Sources in Use */ +#define DEF_INT_SRC (IntEn_TxSQIE|IntEn_RxEOFIE|IntEn_RxEOBIE|IntEn_RxHDRIE) + +/* + * Length of Device Queue in number of entries + * (must be less than or equal to 255) + */ + +/* length of Rx Descriptor Queue (4 or bigger) Must be power of 2. */ +#define LQRXD 64 +#define LQRXS LQRXD /* length of Rx Status Queue */ + +/* length of Tx Descriptor Queue (4 or bigger) Must be power of 2. */ +#define LQTXD 8 +#define LQTXS LQTXD /* length of Tx Status Queue */ + +/* Tx Queue fill-up level control */ +#define LVL_TXSTOP LQTXD - 2 /* level to ask the stack to stop Tx */ +#define LVL_TXRESUME 2 /* level to ask the stack to resume Tx */ + +/* Rx Buffer length in byte */ +#define LRXB (1518+2+16) /* length of Rx buf, must be 4-byte aligned */ +#define LTXB LRXB + +#define EP93XX_DEF_MSG (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK | \ + NETIF_MSG_RX_ERR | \ + NETIF_MSG_TX_ERR | \ + NETIF_MSG_HW) + +#define DBG(lvl,msg,args...) do { printk(lvl"%s:%d: %s(): " msg, __FILE__, \ + __LINE__, __FUNCTION__, ## args); } while (0) + +/* + * Custom Data Structures + */ + +/* + * the information about the buffer passed to device. + * there are matching bufdsc informations + * for each Tx/Rx Descriptor Queue entry to trace + * the buffer within those queues. + */ +struct bufdsc { + /* virtual address representing the buffer passed to device */ + void *vaddr; + /* free routine */ + int (*free_rout) (void *buf); +}; + +/* device private information */ +struct ep93xx_priv { + /* static device information */ + int id; /* device instance ID */ + /* pointers to various queues (virtual address) */ + struct rx_dsc *rdq; /* Rx Descriptor Queue */ + struct rx_sts *rsq; /* Rx Status Queue */ + struct tx_dsc *tdq; /* Tx Descriptor Queue */ + struct tx_sts *tsq; /* Tx Status Queue */ + unsigned char *rxbuf; /* base of Rx Buffer pool */ + unsigned char *txbuf; /* base of Tx Buffer pool */ + struct bufdsc *rxbd; /* Rx Buffers info */ + struct bufdsc *txbd; /* Tx Buffers info */ + /* physical addresses of the same queues */ + dma_addr_t p_qbase; /* base */ + dma_addr_t p_rdq; /* Rx Descriptor Queue */ + dma_addr_t p_rsq; /* Rx Status Queue */ + dma_addr_t p_tdq; /* Tx Descriptor Queue */ + dma_addr_t p_tsq; /* Tx Status Queue */ + dma_addr_t p_rxbuf; /* Rx Buffer pool */ + dma_addr_t p_txbuf; /* Tx Buffer pool */ + /* MII Bus ID of Ethernet PHY */ + struct mii_if_info mii; + /* lock for mii when using ioctls */ + spinlock_t mii_lock; + /* dynamic information, subject to clear when device open */ + struct net_device_stats stats; /* statistic data */ + /* next processing index of device queues */ + int idx_rdq; + int idx_rsq; + int idx_tdqhead; + int idx_tdqtail; + int idx_tsq; + void __iomem *base_addr; /* base address */ + u32 msg_enable; + int regs_len; +}; + +/* + * Internal Routines + */ + +static inline unsigned int next_index(unsigned int idx_cur, unsigned int len) +{ + return (idx_cur + 1) % len; /* next array index */ +} + +static inline u32 _rdl(struct net_device *dev, u32 reg) +{ + return readl(((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg); +} + +static inline void _wrl(struct net_device *dev, u32 val, u32 reg) +{ + writel(val, ((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg); +} + +static inline void _wrw(struct net_device *dev, u16 val, u32 reg) +{ + writew(val, ((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg); +} + +static inline void _wrb(struct net_device *dev, u8 val, u32 reg) +{ + writeb(val, ((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg); +} + +/** + * wait_on_reg() + */ +static int wait_on_reg(struct net_device *dev, int reg, unsigned long mask, unsigned long expect) +{ + int i, dt; + + for (i = 0; i < 10000; i++) { + dt = _rdl(dev, reg); + dt = (dt ^ expect) & mask; + if (0 == dt) + break; + } + return dt; +} + +/** + * mdio_write() + */ +static void mdio_write(struct net_device *dev, int idPhy, int reg, int dt) +{ + wait_on_reg(dev, REG_MIISts, MIISts_Busy, ~MIISts_Busy); + _wrl(dev, dt, REG_MIIData); + _wrl(dev, MIICmd_OP_WR | ((idPhy & 0x1f) << 5) | ((reg & 0x1f) << 0), REG_MIICmd); +} + +/** + * mdio_read() + */ +static int mdio_read(struct net_device *dev, int idPhy, int reg) +{ + int dt; + + wait_on_reg(dev, REG_MIISts, MIISts_Busy, ~MIISts_Busy); + _wrl(dev, MIICmd_OP_RD | ((idPhy & 0x1f) << 5) | ((reg & 0x1f) << 0), REG_MIICmd); + + wait_on_reg(dev, REG_MIISts, MIISts_Busy, ~MIISts_Busy); + dt = _rdl(dev, REG_MIIData); + + return dt & 0xffff; +} + +/** + * phy_init() + */ +static void phy_init(struct net_device *dev) +{ + + u32 oldval; + struct ep93xx_priv *priv = netdev_priv(dev); + + oldval = _rdl(dev, REG_SelfCTL); + + /* Set MDC clock to be divided by 8 and disable PreambleSuppress bit */ + _wrl(dev, 0x0e00, REG_SelfCTL); + + if (mii_link_ok(&(priv->mii))) + mii_check_media(&(priv->mii), netif_msg_link(priv), 1); + + /* restore the old value */ + _wrl(dev, oldval, REG_SelfCTL); +} + +/** + * devQue_start() + * + * make descriptor queues active + * allocate queue entries if needed + * and set device registers up to make it operational + * assume device has been initialized + */ +static int devQue_start(struct net_device *dev) +{ + int err; + int i; + void *buf; + u32 phy_addr; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* turn off device bus mastering */ + _wrl(dev, BMCtl_RxDis | BMCtl_TxDis | _rdl(dev, REG_BMCtl), REG_BMCtl); + err = wait_on_reg(dev, REG_BMSts, BMSts_TxAct, ~BMSts_TxAct); + err |= wait_on_reg(dev, REG_BMSts, BMSts_RxAct, ~BMSts_RxAct); + if (err && netif_msg_hw(priv)) + DBG(KERN_ERR, "%s: BM does not stop\n", dev->name); + + /* Tx Status Queue */ + memset(priv->tsq, 0, sizeof(priv->tsq[0]) * LQTXS); + priv->idx_tsq = 0; + _wrl(dev, priv->p_tsq, REG_TxSBA); + _wrl(dev, priv->p_tsq, REG_TxSCA); + _wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSBL); + _wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSCL); + + /* Tx Descriptor Queue */ + memset(priv->tdq, 0, sizeof(priv->tdq[0]) * LQTXD); + priv->idx_tdqhead = priv->idx_tdqtail = 0; + _wrl(dev, priv->p_tdq, REG_TxDBA); + _wrl(dev, priv->p_tdq, REG_TxDCA); + _wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDBL); + _wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDCL); + + /* Rx Status Queue */ + memset(priv->rsq, 0, sizeof(priv->rsq[0]) * LQRXS); + priv->idx_rsq = 0; + _wrl(dev, priv->p_rsq, REG_RxSBA); + _wrl(dev, priv->p_rsq, REG_RxSCA); + _wrw(dev, sizeof(priv->rsq[0]) * LQRXS, REG_RxSBL); + _wrw(dev, sizeof(priv->rsq[0]) * LQRXS, REG_RxSCL); + + /* Rx Descriptor Queue */ + memset(priv->rdq, 0, sizeof(priv->rdq[0]) * LQRXD); + phy_addr = priv->p_rxbuf; + for (i = 0; i < LQRXD; i++) { + priv->rdq[i].bi = i; /* index */ + priv->rdq[i].ba = phy_addr; /* physical address */ + priv->rdq[i].bl = LRXB; /* length */ + phy_addr += LRXB; + } + priv->idx_rdq = 0; + _wrl(dev, priv->p_rdq, REG_RxDBA); + _wrl(dev, priv->p_rdq, REG_RxDCA); + _wrw(dev, sizeof(priv->rdq[0]) * LQRXD, REG_RxDBL); + _wrw(dev, sizeof(priv->rdq[0]) * LQRXD, REG_RxDCL); + + /* init Rx Buffer Descriptors */ + buf = priv->rxbuf; + for (i = 0; i < LQRXD; i++) { + priv->rxbd[i].vaddr = buf; + priv->rxbd[i].free_rout = NULL; + buf += LRXB; + } + + /* init Tx Buffer Descriptors */ + memset(priv->txbd, 0x0, sizeof(*priv->txbd) * LQTXD); + + buf = priv->txbuf; + for (i = 0; i < LQTXD; i++) { + priv->txbd[i].vaddr = buf; + priv->txbd[i].free_rout = NULL; + buf += LTXB; + } + + /* turn on device bus mastering */ + _wrl(dev, BMCtl_TxEn | BMCtl_RxEn | _rdl(dev, REG_BMCtl), REG_BMCtl); + err = wait_on_reg(dev, REG_BMSts, BMSts_TxAct | BMSts_TxAct, BMSts_TxAct | BMSts_TxAct); + if (err && netif_msg_hw(priv)) + DBG(KERN_ERR, "%s: BM does not start\n", dev->name); + + /* Enqueue whole entries; this must be done after BM activation */ + _wrl(dev, LQRXS, REG_RxSEQ); /* Rx Status Queue */ + _wrl(dev, LQRXD, REG_RxDEQ); /* Rx Desc. queue */ + + return 0; +} + +/** + * devQue_init() + * init device descriptor queues at system level + * device access is not recommended at this point + * + */ +static int devQue_init(struct net_device *dev) +{ + void *buf; + void *tmp; + int size, size2; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* verify device Tx/Rx Descriptor/Status Queue data size */ + if (8 != sizeof(struct rx_dsc)) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "sizeof rx_dsc != 8 bytes!\n"); + return -ENOMEM; + } else if (8 != sizeof(struct rx_sts)) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "sizeof rx_sts != 8 bytes!\n"); + return -ENOMEM; + } else if (8 != sizeof(struct tx_dsc)) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "sizeof tx_dsc != 8 bytes!\n"); + return -ENOMEM; + } else if (4 != sizeof(struct tx_sts)) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "sizeof tx_sts != 4 bytes!\n"); + return -ENOMEM; + } + + /* + allocate kernel memory for whole queues + best if non-cached memory block due to DMA access by the device + if CPU doesn't have bus snooping + */ + size = sizeof(struct rx_dsc) * (LQRXD + 1) + + sizeof(struct rx_sts) * (LQRXS + 1) + + sizeof(struct tx_dsc) * (LQTXD + 1) + + sizeof(struct tx_sts) * (LQTXS + 1) + sizeof(unsigned long) * 4; + + buf = tmp = dma_alloc_coherent(NULL, size, &priv->p_qbase, GFP_KERNEL | GFP_DMA); + if (!buf) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "no memory for queue\n"); + return -ENOMEM; + } + + /* + * assign memory to each queue + */ + priv->rdq = buf; + buf = buf + sizeof(struct rx_dsc) * (LQRXD + 1); + priv->rsq = buf; + buf = buf + sizeof(struct rx_sts) * (LQRXS + 1); + priv->tdq = buf; + buf = buf + sizeof(struct tx_dsc) * (LQTXD + 1); + priv->tsq = buf; + buf = buf + sizeof(struct tx_sts) * (LQTXS + 1); + + /* + * store physical address of each queue + */ + priv->p_rdq = priv->p_qbase; + priv->p_rsq = priv->p_rdq + ((u32) priv->rsq - (u32) priv->rdq); + priv->p_tdq = priv->p_rdq + ((u32) priv->tdq - (u32) priv->rdq); + priv->p_tsq = priv->p_rdq + ((u32) priv->tsq - (u32) priv->rdq); + + /* + * init queue entries + */ + memset(priv->rdq, 0, sizeof(struct rx_dsc) * LQRXD); + memset(priv->rsq, 0, sizeof(struct rx_sts) * LQRXS); + memset(priv->tdq, 0, sizeof(struct tx_dsc) * LQTXD); + memset(priv->tsq, 0, sizeof(struct tx_sts) * LQTXS); + + /* Allocate Rx Buffer + (We might need to copy from Rx buf to skbuff in whatever case, + because device bus master requires 32bit aligned Rx buffer address + but Linux network stack requires odd 16bit aligned Rx buf address) */ + priv->rxbuf = dma_alloc_coherent(NULL, LRXB * LQRXD, &priv->p_rxbuf, GFP_KERNEL | GFP_DMA); + + if (!priv->rxbuf) { + priv->rxbuf = NULL; + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "no memory for RxBuf\n"); + goto err_free_qbase_1; + } + + /* Allocate Tx Buffer */ + priv->txbuf = dma_alloc_coherent(NULL, LTXB * LQTXD, &priv->p_txbuf, GFP_KERNEL | GFP_DMA); + + if (!priv->txbuf) { + priv->txbuf = NULL; + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "no memory for TxBuf\n"); + goto err_free_rxbuf_2; + } + + /* + * allocate kernel memory for buffer descriptors + */ + size2 = sizeof(struct bufdsc) * (LQRXD + LQTXD); + buf = kmalloc(size2, GFP_KERNEL); + if (!buf) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "no memory for buf desc\n"); + goto err_free_txbuf_3; + } + memset(buf, 0x0, size2); /* clear with 0 */ + priv->rxbd = buf; + priv->txbd = buf + sizeof(struct bufdsc) * LQRXD; + + return 0; + +err_free_txbuf_3: + dma_free_coherent(NULL, LTXB * LQTXD, priv->txbuf, priv->p_txbuf); +err_free_rxbuf_2: + dma_free_coherent(NULL, LRXB * LQRXD, priv->rxbuf, priv->p_rxbuf); +err_free_qbase_1: + dma_free_coherent(NULL, size, tmp, priv->p_qbase); + return -ENOMEM; +} + +/** + * devQue_cleanup() + * Release queue, Tx buffers and Rx buffers memory + * Only call after unregister_netdev + */ +static void devQue_cleanup(struct net_device *dev) +{ + int size; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* descriptor queues size */ + size = sizeof(struct rx_dsc) * (LQRXD + 1) + + sizeof(struct rx_sts) * (LQRXS + 1) + + sizeof(struct tx_dsc) * (LQTXD + 1) + + sizeof(struct tx_sts) * (LQTXS + 1) + sizeof(unsigned long) * 4; + + dma_free_coherent(NULL, size, priv->rdq, priv->p_qbase); + dma_free_coherent(NULL, LTXB * LQTXD, priv->txbuf, priv->p_txbuf); + dma_free_coherent(NULL, LRXB * LQRXD, priv->rxbuf, priv->p_rxbuf); + kfree(priv->rxbd); + +} + +/** + * set_multicast_tbl() + */ +static void set_multicast_tbl(struct net_device *dev, u8 *buf) +{ + int i; + unsigned char position; + struct dev_mc_list *cur_addr; + + memset(buf, 0x00, 8); + + cur_addr = dev->mc_list; + for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) { + + if (!cur_addr) + break; + if (!(*cur_addr->dmi_addr & 1)) + continue; /* make sure multicast addr */ + position = ether_crc_le(6, cur_addr->dmi_addr) >> 26; + buf[position >> 3] |= 1 << (position & 0x07); + } +} + +/** + * ind_addr_wr() + */ +static int ind_addr_wr(struct net_device *dev, int afp, char *buf) +{ + u32 rxctl; + int i, len; + struct ep93xx_priv *priv = netdev_priv(dev); + afp &= 0x07; + if (4 == afp || 5 == afp) { + if (netif_msg_hw(priv)) + DBG(KERN_ERR, "invalid afp value\n"); + return -1; + } + len = (AFP_AFP_HASH == afp) ? 8 : 6; + + rxctl = _rdl(dev, REG_RxCTL); /* turn Rx off */ + _wrl(dev, ~RxCTL_SRxON & rxctl, REG_RxCTL); + _wrl(dev, afp, REG_AFP); /* load new address pattern */ + for (i = 0; i < len; i++) + _wrb(dev, buf[i], REG_IndAD + i); + _wrl(dev, rxctl, REG_RxCTL); /* turn Rx back */ + + return 0; +} + +/** + * rx_ctl() + */ +static int rx_ctl(struct net_device *dev, int sw) +{ + unsigned long tmp = _rdl(dev, REG_RxCTL); + + /* + * Workaround for MAC lost 60-byte-long frames: + * must enable Runt_CRC_Accept bit + */ + if (sw) + _wrl(dev, tmp | RxCTL_SRxON | RxCTL_RCRCA, REG_RxCTL); + else + _wrl(dev, tmp & ~RxCTL_SRxON, REG_RxCTL); + + return 0; +} + +/** + * chk_tx_lvl() + */ +static void chk_tx_lvl(struct net_device *dev) +{ + int filled; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* check Tx Descriptor Queue fill-up level */ + filled = priv->idx_tdqhead - priv->idx_tdqtail; + if (filled < 0) + filled += LQTXD; + + if (filled <= (LVL_TXRESUME + 1)) + netif_wake_queue(dev); +} + +/** + * cleanup_tx() + */ +static void cleanup_tx(struct net_device *dev) +{ + struct tx_sts *txsts; + int idxsts, bi; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* + * process Tx Status Queue (no need to limit processing of TxStatus + * Queue because each queue entry consist of 1 dword) + */ + while (priv->tsq[priv->idx_tsq].flags & TXSTS_TXFP) { + idxsts = priv->idx_tsq; + priv->idx_tsq = next_index(priv->idx_tsq, LQTXS); + txsts = &priv->tsq[idxsts]; + if (!(txsts->flags & TXSTS_TXFP)) { /* empty? */ + if (netif_msg_tx_err(priv)) + DBG(KERN_ERR, "QueTxSts is empty\n"); + return; + } + txsts->flags &= ~TXSTS_TXFP; /* mark processed */ + + bi = txsts->bi & TXSTS_BI; /* buffer index */ + + /* statistics collection */ + if (txsts->flags & TXSTS_TXWE) { /* Sent without error */ + priv->stats.tx_packets++; + priv->stats.tx_bytes += ((struct tx_dsc *)(priv->txbd[bi].vaddr))->bl_af & TXDSC_BL; + } else { /* Tx failed due to error */ + if (netif_msg_tx_err(priv)) + DBG(KERN_ERR, "Tx failed QueTxSts"); + priv->stats.tx_errors++; + if (txsts->flags & TXSTS_LCRS) + priv->stats.tx_carrier_errors++; + if (txsts->flags & TXSTS_TXU) + priv->stats.tx_fifo_errors++; + if (txsts->flags & TXSTS_ECOLL) + priv->stats.collisions++; + } + + /* free Tx buffer */ + if (priv->txbd[bi].free_rout) { + (*priv->txbd[bi].free_rout)(priv->txbd[bi].vaddr); + priv->txbd[bi].free_rout = NULL; + } + + /* ahead Tx Descriptor Queue tail index */ + priv->idx_tdqtail = next_index(priv->idx_tdqtail, LQTXD); + } +} + +/** + * restart_tx() + */ +static int restart_tx(struct net_device *dev) +{ + int i; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* disable int */ + + /* turn off master INT control */ + _wrl(dev, _rdl(dev, REG_GIntMsk) & ~GIntMsk_IntEn, REG_GIntMsk); + + /* stop Tx and disable Tx DMA */ + _wrl(dev, _rdl(dev, REG_TxCTL) & ~TxCTL_STxON, REG_TxCTL); + _wrl(dev, _rdl(dev, REG_BMCtl) | BMCtl_TxDis, REG_BMCtl); + + /* reset Tx DMA */ + _wrl(dev, BMCtl_TxChR | _rdl(dev, REG_BMCtl), REG_BMCtl); + + /* release Tx buffers */ + for (i = 0; i < LQTXD; i++) { + if (priv->txbd[i].free_rout) { + priv->txbd[i].free_rout(priv->txbd[i].vaddr); + priv->txbd[i].free_rout = NULL; + } + priv->stats.tx_dropped++; + } + + /* init Tx Queues and flush cache */ + memset(priv->tsq, 0, sizeof(priv->tsq[0]) * LQTXS); + + /* init variables */ + priv->idx_tsq = priv->idx_tdqhead = priv->idx_tdqtail = 0; + + /* init registers */ + wait_on_reg(dev, REG_BMSts, BMCtl_TxChR, ~BMCtl_TxChR); + _wrl(dev, priv->p_tsq, REG_TxSBA); + _wrl(dev, priv->p_tsq, REG_TxSCA); + _wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSBL); + _wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSCL); + _wrl(dev, priv->p_tdq, REG_TxDBA); + _wrl(dev, priv->p_tdq, REG_TxDCA); + _wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDBL); + _wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDCL); + + /* start Tx and enable Tx DMA */ + _wrl(dev, _rdl(dev, REG_TxCTL) | TxCTL_STxON, REG_TxCTL); + _wrl(dev, _rdl(dev, REG_BMCtl) | BMCtl_TxEn, REG_BMCtl); + + /* enable int again */ + _wrl(dev, _rdl(dev, REG_GIntMsk) | GIntMsk_IntEn, REG_GIntMsk); + + return 0; +} + +/** + * reset() + */ +static void reset(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + /* soft reset command */ + _wrb(dev, SelfCTL_RESET, REG_SelfCTL); + if (wait_on_reg(dev, REG_SelfCTL, SelfCTL_RESET, ~SelfCTL_RESET)) + if (netif_msg_drv(priv)) + DBG(KERN_WARNING, "Soft Reset does not self-clear\n"); +} + +/** + * eth_shutdown()- closes down the Ethernet module + * + * Make sure to: + * 1. disable all interrupt mask + * 2. disable Rx + * 3. disable Tx + * + * TODO: + * (1) maybe utilize power down mode. + * Why not yet? Because while the chip will go into power down mode, + * the manual says that it will wake up in response to any I/O requests + * in the register space. Empirical results do not show this working. + */ +static int eth_shutdown(struct net_device *dev) +{ + reset(dev); + return 0; +} + +/** + * eth_init() - Reset and initialize the device. + * + * Device should be initialized enough to function in polling mode. + * Tx and Rx must be disabled and no INT generation. + */ +static int eth_init(struct net_device *dev) +{ + /* reset device */ + reset(dev); + + /* init PHY */ + phy_init(dev); + + /* init MAC */ + + /*i Set MDC clock to be divided by 8 and enable PreambleSuppress bit */ + _wrl(dev, 0x0f00, REG_SelfCTL); + /* mask Interrupt */ + _wrl(dev, 0x00, REG_GIntMsk); + /* no Rx on at this point */ + _wrl(dev, RxCTL_BA | RxCTL_IA0, REG_RxCTL); + _wrl(dev, 0x00, REG_TxCTL); + _wrl(dev, 0x00, REG_GT); + _wrl(dev, 0x00, REG_BMCtl); + /* Buffer Threshold */ + _wrl(dev, (0x80 << 16) | (0x40 << 0), REG_RxBTH); + _wrl(dev, (0x80 << 16) | (0x40 << 0), REG_TxBTH); + /* Status Threshold */ + _wrl(dev, (4 << 16) | (2 << 0), REG_RxSTH); + _wrl(dev, (4 << 16) | (2 << 0), REG_TxSTH); + /* Descriptor Threshold */ + _wrl(dev, (4 << 16) | (2 << 0), REG_RxDTH); + _wrl(dev, (4 << 16) | (2 << 0), REG_TxDTH); + /* Max Frame Length & Tx Start Threshold */ + _wrl(dev, ((1518 + 1) << 16) | (944 << 0), REG_MaxFL); + + _rdl(dev, REG_TxCollCnt); /* clear Tx Collision Count */ + _rdl(dev, REG_RxMissCnt); /* clear Rx Miss Counter */ + _rdl(dev, REG_RxRntCnt); /* clear Rx Runt Counter */ + + /* clear Pending INT */ + _rdl(dev, REG_IntStsC); + /* Tx on */ + _wrl(dev, TxCTL_STxON | _rdl(dev, REG_TxCTL), REG_TxCTL); + + /* Set MAC address */ + ind_addr_wr(dev, AFP_AFP_IA0, &dev->dev_addr[0]); + + /* init queue */ + devQue_start(dev); + + return 0; +} + +/** + * rx_isr() - Receive Interrupt Service Routine + */ +static void rx_isr(struct net_device *dev) +{ + struct rx_sts *rxsts; + /* index of Rx Status Queue Head from device (next put point) */ + int idx_rsqhead; + int idxsts; + int cnt_sts_processed, cnt_desc_processed; + char *dest; + struct sk_buff *skb; + int len; + unsigned int dt; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* get Current Rx Status Queue pointer */ + dt = _rdl(dev, REG_RxSCA); + + /* convert to array index */ + idx_rsqhead = (dt - priv->p_rsq) / sizeof(priv->rsq[0]); + if (!(0 <= idx_rsqhead && idx_rsqhead < LQRXS)) { + if (netif_msg_rx_err(priv)) + DBG(KERN_ERR, " invalid REG_RxSCA\n"); + return; + } + + /* process Rx (limit to idx_rsqhead due to cache) */ + cnt_sts_processed = cnt_desc_processed = 0; + while (idx_rsqhead != priv->idx_rsq) { + idxsts = priv->idx_rsq; + priv->idx_rsq = next_index(priv->idx_rsq, LQRXS); + rxsts = &priv->rsq[idxsts]; + if (!(rxsts->w1 & RXSTS_RFP)) { /* empty? */ + if (netif_msg_rx_err(priv)) + DBG(KERN_ERR, "QueRxSts empty\n"); + return; + } + rxsts->w1 &= ~RXSTS_RFP; /* mark processed */ + + cnt_sts_processed++; + + if (!(rxsts->w1 & RXSTS_EOB)) /* buffer has no data */ + continue; + + if ((rxsts->bi & RXSTS_BI) != priv->idx_rdq) { + if (netif_msg_rx_err(priv)) + DBG(KERN_ERR, "unmatching idx_rdq\n"); + continue; + } + priv->idx_rdq = next_index(priv->idx_rdq, LQRXD); + cnt_desc_processed++; + + /* received a frame with error */ + if (!((rxsts->w1 & RXSTS_EOF) && (rxsts->w1 & RXSTS_RWE))) { + if (netif_msg_rx_err(priv)) + DBG(KERN_WARNING, "Rx error RxSts\n"); + priv->stats.rx_errors++; + if (rxsts->w1 & RXSTS_OE) + priv->stats.rx_fifo_errors++; + if (rxsts->w1 & RXSTS_FE) + priv->stats.rx_frame_errors++; + if ((rxsts->w1 & RXSTS_RUNT) || (rxsts->w1 & RXSTS_EDATA)) + priv->stats.rx_length_errors++; + if (rxsts->w1 & RXSTS_CRCE) + priv->stats.rx_crc_errors++; + continue; + } + + len = rxsts->fl; + + /* alloc buffer for protocal stack */ + skb = dev_alloc_skb(len + 5); + if (NULL == skb) { + if (netif_msg_rx_err(priv)) + DBG(KERN_ERR, "Low Memory, Rx dropped\n"); + priv->stats.rx_dropped++; + continue; + } + + /* odd 16 bit alignment to make protocal stack happy */ + skb_reserve(skb, 2); + skb->dev = dev; + dest = skb_put(skb, len); + memcpy(dest, priv->rxbd[(rxsts->bi & RXSTS_BI)].vaddr, len); + skb->protocol = eth_type_trans(skb, dev); + /* pass Rx packet to system */ + netif_rx(skb); + dev->last_rx = jiffies; + priv->stats.rx_packets++; + priv->stats.rx_bytes += len; + if (RXSTS_AM == (rxsts->w1 & RXSTS_AM)) + priv->stats.multicast++; + } + + /* enqueue */ + _wrl(dev, cnt_sts_processed, REG_RxSEQ); + _wrl(dev, cnt_desc_processed, REG_RxDEQ); +} + +/** + * tx_isr() - Transmit Interrupt Service Routine + */ +static int tx_isr(struct net_device *dev) +{ + cleanup_tx(dev); + chk_tx_lvl(dev); /* resume Tx if it was stopped */ + return 0; +} + +/** + * ep93xx_isr() + */ +static irqreturn_t ep93xx_isr(int irq, void *dev_id, struct pt_regs *pRegs) +{ + struct net_device *dev = dev_id; + int lpCnt; + u32 intS; + + lpCnt = 0; + do { + /* get INT status and then clear */ + intS = _rdl(dev, REG_IntStsC); + + if (!intS) + break; /* no INT */ + if (IntSts_RxSQ & intS) + rx_isr(dev); /* Rx INT */ + if (IntSts_TxSQ & intS) + tx_isr(dev); /* Tx INT */ + } while (lpCnt++ < 64); /* limit loop to serve other interrupts too */ + return IRQ_HANDLED; +} + +/* Exposed Driver Routines to the Outside World */ + +/** + * ep93xx_get_stats() + */ +static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + return &priv->stats; +} + +/** + * ep93xx_set_multicast_list() + */ +static void ep93xx_set_multicast_list(struct net_device *dev) +{ + u8 tbl[8 + 1]; + + if (IFF_PROMISC & dev->flags) { + _wrl(dev, RxCTL_PA | _rdl(dev, REG_RxCTL), REG_RxCTL); + + } else if (IFF_ALLMULTI & dev->flags) { /* receive all multicast addr */ + _wrl(dev, RxCTL_MA | (~RxCTL_PA & _rdl(dev, REG_RxCTL)), REG_RxCTL); + memset(tbl, 0xff, 8); + ind_addr_wr(dev, AFP_AFP_HASH, &tbl[0]); + + } else if (dev->mc_count) { /* set H/W multicasting filter */ + _wrl(dev, RxCTL_MA | (~RxCTL_PA & _rdl(dev, REG_RxCTL)), REG_RxCTL); + set_multicast_tbl(dev, &tbl[0]); + ind_addr_wr(dev, AFP_AFP_HASH, &tbl[0]); + + } else { /* no multicasting */ + _wrl(dev, ~(RxCTL_PA | RxCTL_MA) & _rdl(dev, REG_RxCTL), REG_RxCTL); + } +} + +/** + * ep93xx_tx_timeout() + */ +static void ep93xx_tx_timeout(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + /* If we get here, some higher level has decided we are broken. + There should really be a "kick me" function call instead. */ + if (netif_msg_tx_err(priv)) + DBG(KERN_WARNING, "transmit timed out\n"); + + phy_init(dev); + + /* kick Tx engine */ + restart_tx(dev); + + /* ask the Network Stack to resume Tx if there is room available */ + chk_tx_lvl(dev); +} + +/** + * ep93xx_start_xmit() + */ +static int ep93xx_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ +/* @swk check H/W defect of Tx Underrun Error caused by certain frame length */ + struct tx_dsc *txdsc; + int idx_tdqhd; + int filled; + struct ep93xx_priv *priv = netdev_priv(dev); + + idx_tdqhd = priv->idx_tdqhead; + txdsc = &priv->tdq[idx_tdqhd]; + + /* check Tx Descriptor Queue fill-up level */ + filled = idx_tdqhd - priv->idx_tdqtail; + if (filled < 0) + filled += LQTXD; + filled += 1; + + /* check Queue level */ + if (LVL_TXSTOP <= filled) { + netif_stop_queue(dev); /* no more Tx allowed */ + if (netif_msg_tx_err(priv)) + DBG(KERN_INFO, "%s: Tx STOP requested\n", dev->name); + if (LVL_TXSTOP < filled) { + /* this situation can not be happen */ + if (netif_msg_tx_err(priv)) + DBG(KERN_ERR, "%s: Tx Request while stopped\n", dev->name); + return NETDEV_TX_BUSY; + } + } + + /* fill up Tx Descriptor Queue entry */ + if (skb->len < ETH_ZLEN) { + txdsc->bl_af = ETH_ZLEN & TXDSC_BL; /* also clears AF! */ + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return NETDEV_TX_OK; + } else { + txdsc->bl_af = skb->len & TXDSC_BL; /* also clears AF! */ + } + txdsc->ba = priv->p_txbuf + (idx_tdqhd * LTXB); + txdsc->bi_eof = (idx_tdqhd & TXDSC_BI) | TXDSC_EOF; + + dev->trans_start = jiffies; + + /* copy data to Tx buffer */ + memcpy(priv->txbd[idx_tdqhd].vaddr, skb->data, skb->len); + priv->txbd[idx_tdqhd].free_rout = NULL; + + /* Free the data buffer passed by upper layer */ + dev_kfree_skb_any(skb); + + /* ahead Tx Desc Queue */ + priv->idx_tdqhead = next_index(priv->idx_tdqhead, LQTXD); + wmb(); + + /* Enqueue a Tx Descriptor to the device */ + _wrl(dev, 1, REG_TxDEQ); + + if (netif_msg_tx_queued(priv)) + DBG(KERN_DEBUG, "%s: Tx packet queued\n", dev->name); + + return NETDEV_TX_OK; +} + +/** + * ep93xx_close() + * + * this makes the board clean up everything that it can + * and not talk to the outside world. Caused by + *. an 'ifconfig ethX down' + */ +static int ep93xx_close(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + free_irq(dev->irq, dev); + + netif_stop_queue(dev); + eth_shutdown(dev); + + if (netif_msg_ifdown(priv)) + DBG(KERN_INFO, "%s: ep93xx_close()\n", dev->name); + + return 0; +} + +/** + * ep93xx_open() - Open and Initialize the board + * + * Set up everything, reset the card, etc .. + */ +static int ep93xx_open(struct net_device *dev) +{ + int status; + struct ep93xx_priv *priv = netdev_priv(dev); + + /* clear dynamic device info */ + memset(&priv->stats, 0, sizeof(priv->stats)); + priv->idx_rdq = 0; + priv->idx_rsq = 0; + priv->idx_tdqhead = 0; + priv->idx_tdqtail = 0; + priv->idx_tsq = 0; + + /* reset/init device */ + status = eth_init(dev); + if (status != 0) { + return -EAGAIN; + } + + /* turn on INT, turn on Rx */ + status = request_irq(dev->irq, &ep93xx_isr, 0, DRV_NAME, dev); + if (status) { + if (netif_msg_ifup(priv)) + DBG(KERN_ERR, "%s: unable to get IRQ\n", dev->name); + return status; + } + + /* Enable interrupt driven operation. Also turn on Rx but no Tx. */ + /* setup Interrupt sources */ + _wrl(dev, DEF_INT_SRC, REG_IntEn); + /* turn on INT */ + _wrl(dev, GIntMsk_IntEn, REG_GIntMsk); + /* turn on Rx */ + rx_ctl(dev, 1); + + /* link to upper layer */ + netif_start_queue(dev); + + if (netif_msg_ifup(priv)) + DBG(KERN_INFO, "%s: irq=%d\n", dev->name, dev->irq); + + return 0; +} + +static int ep93xx_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + int rc; + + if (!netif_running(dev)) + return -EINVAL; + + spin_lock_irq(&priv->mii_lock); + rc = generic_mii_ioctl(&priv->mii, if_mii(rq), cmd, NULL); + spin_unlock_irq(&priv->mii_lock); + + return rc; +} + +/* + * Ethtool support + */ + +static void ep93xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); +} + +static int ep93xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + spin_lock_irq(&priv->mii_lock); + mii_ethtool_gset(&priv->mii, cmd); + spin_unlock_irq(&priv->mii_lock); + return 0; +} + +static int ep93xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + int rc; + spin_lock_irq(&priv->mii_lock); + rc = mii_ethtool_sset(&priv->mii, cmd); + spin_unlock_irq(&priv->mii_lock); + return rc; +} + +static int ep93xx_nway_reset(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + return mii_nway_restart(&priv->mii); +} + +static u32 ep93xx_get_link(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + return mii_link_ok(&priv->mii); +} + +static u32 ep93xx_get_msglevel(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + return priv->msg_enable; +} + +static void ep93xx_set_msglevel(struct net_device *dev, u32 datum) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + priv->msg_enable = datum; +} + +static void ep93xx_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + + spin_lock_irq(&priv->mii_lock); + memcpy_fromio(regbuf, priv->base_addr, regs->len); + spin_unlock_irq(&priv->mii_lock); +} + +static int ep93xx_get_regs_len(struct net_device *dev) +{ + struct ep93xx_priv *priv = netdev_priv(dev); + return priv->regs_len; +} + +static struct ethtool_ops ep93xx_ethtool_ops = { + .get_drvinfo = ep93xx_get_drvinfo, + .get_settings = ep93xx_get_settings, + .set_settings = ep93xx_set_settings, + .get_regs = ep93xx_get_regs, + .get_regs_len = ep93xx_get_regs_len, + .nway_reset = ep93xx_nway_reset, + .get_link = ep93xx_get_link, + .get_msglevel = ep93xx_get_msglevel, + .set_msglevel = ep93xx_set_msglevel, +}; + +/** + * driver_init() - Logical driver initialization for an individual device + * + * Minimum device H/W access at this point + * + * Task: + * Initialize the structure if needed + * print out my vanity message if not done so already + * print out what type of hardware is detected + * print out the ethernet address + * find the IRQ + * set up my private data + * configure the dev structure with my subroutines + * actually GRAB the irq. + * GRAB the region + * + */ +static int __init driver_init(struct net_device *dev, u32 baseA, int irq) +{ + int i; + struct resource *res; + struct sockaddr sa; + struct ep93xx_priv *priv = netdev_priv(dev); + + if (0 == num_of_instance) + printk("%s", version); + + /* skip probing for a second one, we _know_ that it does not exist */ + if (1 == num_of_instance) + return -ENODEV; + + memset(dev->priv, 0x00, sizeof(struct ep93xx_priv)); + + /* device instance ID */ + priv->id = num_of_instance; + + /* mii stuff */ + spin_lock_init(&priv->mii_lock); + priv->mii.dev = dev; + priv->mii.mdio_read = mdio_read; + priv->mii.mdio_write = mdio_write; + priv->mii.phy_id_mask = 0x1f; + priv->mii.reg_num_mask = 0x1f; + priv->msg_enable = EP93XX_DEF_MSG; + priv->regs_len = DEV_REG_SPACE; + + priv->base_addr = (void *)(baseA); + + dev->irq = irq; + + res = request_mem_region(baseA, DEV_REG_SPACE, DRV_NAME); + if (res == NULL) { + if (netif_msg_probe(priv)) + DBG(KERN_ERR, "request_mem_region failed!\n"); + goto err_free_priv_1; + } + + dev->open = &ep93xx_open; + dev->stop = &ep93xx_close; + dev->do_ioctl = &ep93xx_ioctl; + dev->hard_start_xmit = &ep93xx_start_xmit; + dev->tx_timeout = &ep93xx_tx_timeout; + dev->watchdog_timeo = HZ * 5; + dev->get_stats = &ep93xx_get_stats; + dev->set_multicast_list = &ep93xx_set_multicast_list; + dev->ethtool_ops = &ep93xx_ethtool_ops; + + ether_setup(dev); + + if (devQue_init(dev)) + goto err_free_bd_memregion_irq_2; + + reset(dev); + + /* + * use a random MAC for now - + * don't forget to set a valid MAC later on with ifconfig + */ + sa.sa_family = AF_INET; + random_ether_addr(sa.sa_data); + dev->set_mac_address(dev, &sa); + + if (netif_msg_probe(priv)) { + printk(KERN_INFO DRV_NAME ": #%d at 0x%p IRQ:%d\n", priv->id, priv->base_addr, dev->irq); + printk(KERN_INFO DRV_NAME ": using random number"); + for (i = 0; i < 6; i++) + printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); + + printk(" as MAC, don't forget to assign a valid MAC later!\n"); + } + num_of_instance++; + return 0; + +err_free_bd_memregion_irq_2: + kfree(priv->rxbd); + disable_irq(dev->irq); + free_irq(dev->irq, dev); + release_mem_region((u32)priv->base_addr, DEV_REG_SPACE); +err_free_priv_1: + kfree(dev->priv); + return -EAGAIN; +} + +/** + * ep93xx_probe - probe for ep93xx device + * + * Probe for the one (and only) ethernet device found on + * EP93xx SOC CPU. + */ +static int __init ep93xx_probe(void) +{ + int err; + struct ep93xx_priv *priv; + struct net_device *dev = alloc_etherdev(sizeof(struct ep93xx_priv)); + + if (!dev) + return -ENODEV; + + priv = netdev_priv(dev); + + SET_MODULE_OWNER(dev); + + sprintf(dev->name, "eth0"); + + priv->base_addr = (void *)(port_list[0].base_addr); + + dev->irq = port_list[0].irq; + + err = driver_init(dev, (u32)priv->base_addr, dev->irq); + if (err) + goto err_free_netdev; + + err = register_netdev(dev); + if (err) + goto err_free_memregion_irq_1; + + ep93xx_etherdev = dev; + disable_irq(dev->irq); + return 0; + +err_free_memregion_irq_1: + kfree(priv->rxbd); + disable_irq(dev->irq); + free_irq(dev->irq, dev); + release_mem_region((u32)priv->base_addr, DEV_REG_SPACE); +err_free_netdev: + free_netdev(dev); + return err; +} + +static void __exit ep93xx_exit(void) +{ + struct net_device *dev = ep93xx_etherdev; + struct ep93xx_priv *priv = netdev_priv(dev); + + if (dev) { + unregister_netdev(dev); + devQue_cleanup(dev); + free_irq(dev->irq, dev); + release_mem_region((u32)priv->base_addr, DEV_REG_SPACE); + free_netdev(dev); + } +} + +module_init(ep93xx_probe); +module_exit(ep93xx_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/arm/ep93xx_eth.h b/drivers/net/arm/ep93xx_eth.h new file mode 100644 index 0000000..1752eaf --- /dev/null +++ b/drivers/net/arm/ep93xx_eth.h @@ -0,0 +1,355 @@ +/* + * ep93xx_eth.h + * : header file of Ethernet Device Driver for Cirrus Logic EP93xx. + * + * Copyright (C) 2003 by Cirrus Logic www.cirrus.com + * This software may be used and distributed according to the terms + * of the GNU Public License. + * + * This file contains device related information like register info + * and register access method macros for the Ethernet device + * embedded within Cirrus Logic's EP93xx SOC chip. + * + * Information contained in this file was obtained from + * the EP9312 Manual Revision 0.12 and 0.14 from Cirrus Logic. + * + * History + * 05/18/01 Sungwook Kim Initial release + * 03/25/2003 Melody Modified for EP92xx + */ + +#ifndef _EP93xx_ETH_H_ +#define _EP93xx_ETH_H_ + +/* + * Definition of the registers. + * For details, refer to the datasheet . + * + * Basically, most registers are 32 bits width register. + * But some are 16 bits and some are 6 or 8 bytes long. + */ + +#define REG_RxCTL 0x0000 /*offset to Receiver Control Reg */ +#define RxCTL_PauseA (1<<20) +#define RxCTL_RxFCE1 (1<<19) +#define RxCTL_RxFCE0 (1<<18) +#define RxCTL_BCRC (1<<17) +#define RxCTL_SRxON (1<<16) +#define RxCTL_RCRCA (1<<13) +#define RxCTL_RA (1<<12) +#define RxCTL_PA (1<<11) +#define RxCTL_BA (1<<10) +#define RxCTL_MA (1<<9) +#define RxCTL_IAHA (1<<8) +#define RxCTL_IA3 (1<<3) +#define RxCTL_IA2 (1<<2) +#define RxCTL_IA1 (1<<1) +#define RxCTL_IA0 (1<<0) + +#define REG_TxCTL 0x0004 /*offset to Transmit Control Reg */ +#define TxCTL_DefDis (1<<7) +#define TxCTL_MBE (1<<6) +#define TxCTL_ICRC (1<<5) +#define TxCTL_TxPD (1<<5) +#define TxCTL_OColl (1<<3) +#define TxCTL_SP (1<<2) +#define TxCTL_PB (1<<1) +#define TxCTL_STxON (1<<0) + +#define REG_TestCTL 0x0008 /*Test Control Reg, R/W */ +#define TestCTL_MACF (1<<7) +#define TestCTL_MFDX (1<<6) +#define TestCTL_DB (1<<5) +#define TestCTL_MIIF (1<<4) + +#define REG_MIICmd 0x0010 /*offset to MII Command Reg, R/W */ +#define MIICmd_OP (0x03<<14) +#define MIICmd_OP_RD (2<<14) +#define MIICmd_OP_WR (1<<14) +#define MIICmd_PHYAD (0x1f<<5) +#define MIICmd_REGAD (0x1f<<0) + +#define REG_MIIData 0x0014 /*offset to MII Data Reg, R/W */ +#define MIIData_MIIData (0xffff<<0) + +#define REG_MIISts 0x0018 /*offset to MII Status Reg, R */ +#define MIISts_Busy (1<<0) + +#define REG_SelfCTL 0x0020 /*offset to Self Control Reg */ +#define SelfCTL_RWP (1<<7) /*Remote Wake Pin */ +#define SelfCTL_GPO0 (1<<5) +#define SelfCTL_PUWE (1<<4) +#define SelfCTL_PDWE (1<<3) +#define SelfCTL_MIIL (1<<2) +#define SelfCTL_RESET (1<<0) + +#define REG_IntEn 0x0024 /*Interrupt Enable Reg, R/W */ +#define IntEn_RWIE (1<<30) +#define IntEn_RxMIE (1<<29) +#define IntEn_RxBIE (1<<28) +#define IntEn_RxSQIE (1<<27) +#define IntEn_TxLEIE (1<<26) +#define IntEn_ECIE (1<<25) +#define IntEn_TxUHIE (1<<24) +#define IntEn_MOIE (1<<18) +#define IntEn_TxCOIE (1<<17) +#define IntEn_RxROIE (1<<16) +#define IntEn_MIIIE (1<<12) +#define IntEn_PHYSIE (1<<11) +#define IntEn_TIE (1<<10) +#define IntEn_SWIE (1<<8) +#define IntEn_TxSQIE (1<<3) +#define IntEn_RxEOFIE (1<<2) +#define IntEn_RxEOBIE (1<<1) +#define IntEn_RxHDRIE (1<<0) + +#define REG_IntStsP 0x0028 /*offset to Interrupt Status Preserve Reg, R/W */ +#define REG_IntStsC 0x002c /*offset to Interrupt Status Clear Reg, R */ +#define IntSts_RWI (1<<30) +#define IntSts_RxMI (1<<29) +#define IntSts_RxBI (1<<28) +#define IntSts_RxSQI (1<<27) +#define IntSts_TxLEI (1<<26) +#define IntSts_ECI (1<<25) +#define IntSts_TxUHI (1<<24) +#define IntSts_MOI (1<<18) +#define IntSts_TxCOI (1<<17) +#define IntSts_RxROI (1<<16) +#define IntSts_MIII (1<<12) +#define IntSts_PHYSI (1<<11) +#define IntSts_TI (1<<10) +#define IntSts_AHBE (1<<9) +#define IntSts_SWI (1<<8) +#define IntSts_OTHER (1<<4) +#define IntSts_TxSQ (1<<3) +#define IntSts_RxSQ (1<<2) + +#define REG_GT 0x0040 /*offset to General Timer Reg */ +#define GT_GTC (0xffff<<16) +#define GT_GTP (0xffff<<0) + +#define REG_FCT 0x0044 /*offset to Flow Control Timer Reg */ +#define FCT_FCT (0x00ffffff<<0) + +#define REG_FCF 0x0048 /*offset to Flow Control Format Reg */ +#define FCF_MACCT (0xffff<<16) +#define FCF_TPT (0xffff<<0) + +#define REG_AFP 0x004c /*offset to Address Filter Pointer Reg */ +#define AFP_AFP (0x07<<0) /*Address Filter Pointer + (bank control for REG_IndAD) */ +#define AFP_AFP_IA0 0 /*Primary Individual Address (MAC Addr) */ +#define AFP_AFP_IA1 1 /*Individual Address 1 */ +#define AFP_AFP_IA2 2 /*Individual Address 2 */ +#define AFP_AFP_IA3 3 /*Individual Address 3 */ +#define AFP_AFP_DTxP 6 /*Destination Address of Tx Pause Frame */ +#define AFP_AFP_HASH 7 /*Hash Table */ + +#define REG_IndAD 0x0050 /*offset to Individual Address Reg, + n bytes, R/W */ + +#define REG_GIntSts 0x0060 /*offset to Global Interrupt + Status Reg (writing 1 will clear) */ +#define REG_GIntROS 0x0068 /*offset to Global Interrupt + Status Read Only Reg */ +#define GIntSts_INT (1<<15) /*Global Interrupt Request Status */ + +#define REG_GIntMsk 0x0064 /*offset to Global Interrupt Mask Reg */ +#define GIntMsk_IntEn (1<<15) /*Global Interrupt Enable */ + +#define REG_GIntFrc 0x006c /*offset to Global Interrupt Force Reg */ +#define GIntFrc_INT (1<<15) /*Force to set GIntSts */ + +#define REG_TxCollCnt 0x0070 /*Transmit Collision Count Reg, R */ +#define REG_RxMissCnt 0x0074 /*Receive Miss Count Reg, R */ +#define REG_RxRntCnt 0x0078 /*Receive Runt Count Reg, R */ + +#define REG_BMCtl 0x0080 /*offset to Bus Master Control Reg, R/W */ +#define BMCtl_MT (1<<13) +#define BMCtl_TT (1<<12) +#define BMCtl_UnH (1<<11) +#define BMCtl_TxChR (1<<10) +#define BMCtl_TxDis (1<<9) +#define BMCtl_TxEn (1<<8) +#define BMCtl_EH2 (1<<6) +#define BMCtl_EH1 (1<<5) +#define BMCtl_EEOB (1<<4) +#define BMCtl_RxChR (1<<2) +#define BMCtl_RxDis (1<<1) +#define BMCtl_RxEn (1<<0) + +#define REG_BMSts 0x0084 /*offset to Bus Master Status Reg, R */ +#define BMSts_TxAct (1<<7) +#define BMSts_TP (1<<4) +#define BMSts_RxAct (1<<3) +#define BMSts_QID (0x07<<0) +#define BMSts_QID_RxDt (0<<0) +#define BMSts_QID_TxDt (1<<0) +#define BMSts_QID_RxSts (2<<0) +#define BMSts_QID_TxSts (3<<0) +#define BMSts_QID_RxDesc (4<<0) +#define BMSts_QID_TxDesc (5<<0) + +#define REG_RBCA 0x0088 /*offset to Receive Buffer + Current Address Reg, R */ +#define REG_TBCA 0x008c /*offset to Transmit Buffer + Current Address Reg, R */ + +#define REG_RxDBA 0x0090 /*offset to Receive Descriptor Queue + Base Address Reg, R/W */ +#define REG_RxDBL 0x0094 /*offset to Receive Descriptor Queue + Base Length Reg, R/W, 16bits */ +#define REG_RxDCL 0x0096 /*offset to Receive Descriptor Queue + Current Length Reg, R/W, 16bits */ +#define REG_RxDCA 0x0098 /*offset to Receive Descriptor Queue + Current Address Reg, R/W */ + +#define REG_RxDEQ 0x009c /*offset to Receive Descriptor + Enqueue Reg, R/W */ +#define RxDEQ_RDV (0xffff<<16) /*R 16bit; Receive Descriptor Value */ +#define RxDEQ_RDI (0xff<<0) /*W 8bit; Receive Descriptor Increment */ + +#define REG_RxSBA 0x00a0 /*offset to Receive Status Queue + Base Address Reg, R/W */ +#define REG_RxSBL 0x00a4 /*offset to Receive Status Queue + Base Length Reg, R/W, 16bits */ +#define REG_RxSCL 0x00a6 /*offset to Receive Status Queue + Current Length Reg, R/W, 16bits */ +#define REG_RxSCA 0x00a8 /*offset to Receive Status Queue + Current Address Reg, R/W */ + +#define REG_RxSEQ 0x00ac /*offset to Receive Status Queue + Current Address Reg, R/W */ +#define RxSEQ_RSV (0xffff<<16) +#define RxSEQ_RSI (0xff<<0) + +#define REG_TxDBA 0x00b0 /*offset to Transmit Descriptor Queue + Base Address Reg, R/W */ +#define REG_TxDBL 0x00b4 /*offset to Transmit Descriptor Queue + Base Length Reg, R/W, 16bits */ +#define REG_TxDCL 0x00b6 /*offset to Transmit Descriptor Queue + Current Length Reg, R/W, 16bits */ +#define REG_TxDCA 0x00b8 /*offset to Transmit Descriptor Queue + Current Address Reg, R/W */ + +#define REG_TxDEQ 0x00bc /*offset to Transmit Descriptor Queue + Current Address Reg, R/W */ +#define TxDEQ_TDV (0xffff<<16) +#define TxDEQ_TDI (0xff<<0) + +#define REG_TxSBA 0x00c0 /*offset to Transmit Status Queue + Base Address Reg, R/W */ +#define REG_TxSBL 0x00c4 /*offset to Transmit Status Queue + Base Length Reg, R/W, 16bits */ +#define REG_TxSCL 0x00c6 /*offset to Transmit Status Queue + Current Length Reg, R/W, 16bits */ +#define REG_TxSCA 0x00c8 /*offset to Transmit Status Queue + Current Address Reg, R/W */ + +#define REG_RxBTH 0x00d0 /*offset to Receive Buffer + Threshold Reg, R/W */ +#define RxBTH_RDHT (0x03ff<<16) +#define RxBTH_RDST (0x03ff<<0) + +#define REG_TxBTH 0x00d4 /*offset to Transmit Buffer + Threshold Reg, R/W */ +#define TxBTH_TDHT (0x03ff<<16) +#define TxBTH_TDST (0x03ff<<0) + +#define REG_RxSTH 0x00d8 /*offset to Receive Status + Threshold Reg, R/W */ +#define RxSTH_RSHT (0x003f<<16) +#define RxSTH_RSST (0x003f<<0) + +#define REG_TxSTH 0x00dc /*offset to Transmit Status + Threshold Reg, R/W */ +#define TxSTH_TSHT (0x003f<<16) +#define TxSTH_TSST (0x003f<<0) + +#define REG_RxDTH 0x00e0 /*offset to Receive Descriptor + Threshold Reg, R/W */ +#define RxDTH_RDHT (0x003f<<16) +#define RxDTH_RDST (0x003f<<0) + +#define REG_TxDTH 0x00e4 /*offset to Transmit Descriptor + Threshold Reg, R/W */ +#define TxDTH_TDHT (0x003f<<16) +#define TxDTH_TDST (0x003f<<0) + +#define REG_MaxFL 0x00e8 /*offset to Max Frame Length Reg, R/W */ +#define MaxFL_MFL (0x07ff<<16) +#define MaxFL_TST (0x07ff<<0) + +#define REG_RxHL 0x00ec /*offset to Receive Header Length Reg, R/W */ +#define RxHL_RHL2 (0x07ff<<16) +#define RxHL_RHL1 (0x03ff<<0) + +#define REG_MACCFG0 0x0100 /*offset to Test Reg #0, R/W */ +#define MACCFG0_DbgSel (1<<7) +#define MACCFG0_LCKEN (1<<6) +#define MACCFG0_LRATE (1<<5) +#define MACCFG0_RXERR (1<<4) +#define MACCFG0_BIT33 (1<<2) +#define MACCFG0_PMEEN (1<<1) +#define MACCFG0_PMEST (1<<0) + +#define REG_MACCFG1 0x0104 /*offset to Test Reg #1, R/W */ +#define REG_MACCFG2 0x0108 /*offset to Test Reg #2, R */ +#define REG_MACCFG3 0x010c /*offset to Test Reg #3, R */ + +/*--------------------------------------------------------------- + * Definition of Descriptor/Status Queue Entry + *-------------------------------------------------------------*/ +struct rx_dsc { + __be32 ba; + __be16 bl; + __be16 bi; /* let nsof flag be part of bi */ +}; + +#define RXSTS_RFP 0x80000000 +#define RXSTS_RWE 0x40000000 +#define RXSTS_EOF 0x20000000 +#define RXSTS_EOB 0x10000000 +#define RXSTS_AM 0x00C00000 +#define RXSTS_OE 0x00100000 +#define RXSTS_FE 0x00080000 +#define RXSTS_RUNT 0x00040000 +#define RXSTS_EDATA 0x00020000 +#define RXSTS_CRCE 0x00010000 + +#define RXSTS_BI 0x7FFF +struct rx_sts { /* Receive Status Queue Entry */ + __be32 w1; + __be16 fl; + __be16 bi; /* bi and rfp2 */ +}; + +#define TXDSC_BL 0x0FFF +#define TXDSC_AF 0x8000 +#define TXDSC_BI 0x7FFF +#define TXDSC_EOF 0x8000 +struct tx_dsc { /* Transmit Descriptor Queue Entry */ + __be32 ba; /*b31-0: physical Buffer Address */ + __be16 bl_af; /* Buffer Length, Abort Frame */ + __be16 bi_eof; /* Buffer Index, End Of Frame */ +}; + +#define TXSTS_BI 0x7fff +#define TXSTS_TXFP 0x80 +#define TXSTS_TXWE 0x40 +#define TXSTS_LCRS 0x10 +#define TXSTS_TXU 0x02 +#define TXSTS_ECOLL 0x01 + +struct tx_sts { + __be16 bi; + u8 ncoll; + u8 flags; +}; + +/* + * Size of device registers occupied in memory/IO address map + */ +#define DEV_REG_SPACE 0x00010000 + +#endif /* _EP93xx_ETH_H_ */ diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 309eb55..b7e03e3 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -198,6 +198,19 @@ config PCMCIA_PXA2XX help Say Y here to include support for the PXA2xx PCMCIA controller +config PCMCIA_EP93XX + tristate "EP93xx support" + depends on ARM && ARCH_EP93XX && PCMCIA + help + Say Y here to include support for the EP93xx PCMCIA controller + +config PCMCIA_ZEFEEREVBH + bool "ZefeerEVB-H support" + depends on ARM && ARCH_EP93XX && PCMCIA && PCMCIA_EP93XX && MACH_ZEFEERDZQ + help + Say Y here to include support for the PCMCIA interface on + ZefeerEVB-H board + config PCMCIA_PROBE bool default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index bcecf51..5878b5a 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_HD64465_PCMCIA) += hd6446 obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o +obj-$(CONFIG_PCMCIA_EP93XX) += ep93xx_core.o ep93xx_cs.o obj-$(CONFIG_M32R_PCC) += m32r_pcc.o obj-$(CONFIG_M32R_CFC) += m32r_cfc.o obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o @@ -39,6 +40,7 @@ obj-$(CONFIG_OMAP_CF) += omap_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o +ep93xx_core-y += soc_common.o ep93xx_base.o au1x00_ss-y += au1000_generic.o au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o @@ -69,3 +71,7 @@ pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o +ep93xx_cs-$(CONFIG_MACH_ADSSPHERE) += ep93xx_adssphere.o +ep93xx_cs-$(CONFIG_MACH_EDB9315) += ep93xx_edb9315.o +ep93xx_cs-$(CONFIG_MACH_DMA03) += ep93xx_edb9315.o +ep93xx_cs-$(CONFIG_PCMCIA_ZEFEEREVBH) += ep93xx_zefeerevbh.o diff --git a/drivers/pcmcia/ep93xx_adssphere.c b/drivers/pcmcia/ep93xx_adssphere.c new file mode 100644 index 0000000..8e1a181 --- /dev/null +++ b/drivers/pcmcia/ep93xx_adssphere.c @@ -0,0 +1,190 @@ +/* + * linux/drivers/pcmcia/ep93xx_adssphere.c + * + * Adapted from pxa27x_mainstone.c + * + * Robert Whaley 2005 rwhaley@applieddata.net + * + * Adssphere PCMCIA specific routines. + * + * Created: May 12, 2004 + * Author: Nicolas Pitre + * Copyright: MontaVista Software Inc. + * + * 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 "soc_common.h" + +static struct pcmcia_irqs irqs[] = { + { 0, IRQ_GPIO1, "CF CD1" }, + { 0, IRQ_GPIO2, "CF CD2" }, + { 0, IRQ_GPIO3, "CF STSCHG/BVD1" }, + { 0, IRQ_GPIO4, "CF SPKR/BVD2" }, +}; + + +static int adssphere_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int rtn; + + if (skt->nr != 0) + return -ENXIO; + + skt->irq = IRQ_GPIO6; + + rtn = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + + /* enable GPIO6 as interrupt */ + writel(0x40, GPIO_INTEN); + + /* enable GPIO1-4 and 6 as interrupt */ + /* Note: 1-4 need to be edge triggered, but + then the irq vectors need to hit GPIOxEIO + which they don't currently do - no big deal + since CD and BVD are polled anyway */ + /* writel(0x5e, GPIO_INTEN); */ + + return rtn; +} + +static void adssphere_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +} + +static void adssphere_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + unsigned long status; + + status = inl(GPIO_PFDR); + + state->detect = (status & PCMCIA_DETECT) ? 0 : 1; + state->ready = (status & PCMCIA_READY) ? 1 : 0; + state->bvd1 = (status & PCMCIA_BVD1) ? 1 : 0; + state->bvd2 = (status & PCMCIA_BVD2) ? 1 : 0; + state->vs_3v = (status & PCMCIA_VS_3V) ? 0 : 1; + state->vs_Xv = (status & PCMCIA_VS_XV) ? 0 : 1; + state->wrprot = (status & PCMCIA_WRPROT) ? 0 : 1; + +// printk("%s: nr: %d, status: %#x, state: %#x\n", __FUNCTION__, skt->nr, status, *((unsigned char *) state)); +} + +static int adssphere_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + unsigned long clrbits = 0, setbits = 0, cr0; + int ret = 0; + + switch (state->Vcc) { + case 0: { + clrbits = ADSSPHERE_CR0_CF_33 | ADSSPHERE_CR0_CF_50; + setbits = 0; + break; + } + case 33: { + clrbits = ADSSPHERE_CR0_CF_50; + setbits = ADSSPHERE_CR0_CF_33; + break; + } + case 50: { + clrbits = ADSSPHERE_CR0_CF_33; + setbits = ADSSPHERE_CR0_CF_50; + break; + } + default: + printk(KERN_ERR "%s(): bad Vcc %u\n", + __FUNCTION__, state->Vcc); + ret = -1; + } + + if (!ret && skt->nr == 0) { + cr0 = inl(ADSSPHERE_CR0); + cr0 &= ~clrbits; + cr0 |= setbits; + writel(cr0, ADSSPHERE_CR0); + + if (state->flags & SS_RESET) { + /* see EP93xx User's Guide */ + writel(0x15, PCMCIACNT); + } else { + /* CF mode - BIT1 for PCMCIA mode */ + writel(0x11, PCMCIACNT); + } + } + + return ret; +} + +static void adssphere_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void adssphere_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level adssphere_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = adssphere_pcmcia_hw_init, + .hw_shutdown = adssphere_pcmcia_hw_shutdown, + .socket_state = adssphere_pcmcia_socket_state, + .configure_socket = adssphere_pcmcia_configure_socket, + .socket_init = adssphere_pcmcia_socket_init, + .socket_suspend = adssphere_pcmcia_socket_suspend, + .nr = 1, +}; + +static struct platform_device *adssphere_pcmcia_device; + +static int __init adssphere_pcmcia_init(void) +{ + int ret; + + adssphere_pcmcia_device = kmalloc(sizeof(*adssphere_pcmcia_device), GFP_KERNEL); + if (!adssphere_pcmcia_device) + return -ENOMEM; + memset(adssphere_pcmcia_device, 0, sizeof(*adssphere_pcmcia_device)); + adssphere_pcmcia_device->name = "ep93xx-pcmcia"; + adssphere_pcmcia_device->dev.platform_data = &adssphere_pcmcia_ops; + + ret = platform_device_register(adssphere_pcmcia_device); + if (ret) + kfree(adssphere_pcmcia_device); + + return ret; +} + +static void __exit adssphere_pcmcia_exit(void) +{ + /* + * This call is supposed to free our adssphere_pcmcia_device. + * Unfortunately platform_device don't have a free method, and + * we can't assume it's free of any reference at this point so we + * can't free it either. + */ + platform_device_unregister(adssphere_pcmcia_device); +} + +module_init(adssphere_pcmcia_init); +module_exit(adssphere_pcmcia_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/ep93xx_base.c b/drivers/pcmcia/ep93xx_base.c new file mode 100644 index 0000000..2377989 --- /dev/null +++ b/drivers/pcmcia/ep93xx_base.c @@ -0,0 +1,190 @@ +/*====================================================================== + + Device driver for the PCMCIA control functionality of EP93xx + microprocessors. Derived from pxa2xx_base.c + + The contents of this file may be used under the + terms of the GNU Public License version 2 (the "GPL") + + (c) Ian Molton (spyro@f2s.com) 2003 + (c) Stefan Eletzhofer (stefan.eletzhofer@inquant.de) 2003,4 + (c) Robert Whaley (rwhaley@applieddata.net) 2005 + + derived from sa11xx_base.c + + Portions created by John G. Dorsey are + Copyright (C) 1999 John G. Dorsey. + + ======================================================================*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "cs_internal.h" +#include "soc_common.h" + +#define MIN(a,b) ((a)>(b) ? (b) : (a)) + +#define MCXX_SETUP_MAX 0xff +#define MCXX_ASST_MAX 0xff +#define MCXX_HOLD_MAX 0x0f + +#define MCXX_SETUP_SHIFT 0 +#define MCXX_ASST_SHIFT 16 +#define MCXX_HOLD_SHIFT 8 + + + +static inline u_int ep93xx_mcxx_hold(u_int pcmcia_cycle_ns, + u_int hclk_10khz) +{ + u_int code = pcmcia_cycle_ns * hclk_10khz; + return (code / 100000) + ((code % 100000) ? 1 : 0) - 1; +} + +static inline u_int ep93xx_mcxx_asst(u_int pcmcia_cycle_ns, + u_int hclk_10khz) +{ + u_int code = pcmcia_cycle_ns * hclk_10khz; + return (code / 100000) + ((code % 100000) ? 1 : 0) - 1; +} + +static inline u_int ep93xx_mcxx_setup(u_int pcmcia_cycle_ns, + u_int hclk_10khz) +{ + u_int code = pcmcia_cycle_ns * hclk_10khz; + return (code / 100000) + ((code % 100000) ? 1 : 0) - 1; +} + +static int ep93xx_pcmcia_set_mcmem( int sock, int speed, int clock ) +{ + writel(PC16BITSWIDE + | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << MCXX_SETUP_SHIFT) + | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << MCXX_ASST_SHIFT) + | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << MCXX_HOLD_SHIFT), + PC1COMMON); + + return 0; +} + +static int ep93xx_pcmcia_set_mcio( int sock, int speed, int clock ) +{ + writel(PC16BITSWIDE + | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << MCXX_SETUP_SHIFT) + | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << MCXX_ASST_SHIFT) + | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << MCXX_HOLD_SHIFT), + PC1IO); + + return 0; +} + +static int ep93xx_pcmcia_set_mcatt( int sock, int speed, int clock ) +{ + writel(PC16BITSWIDE + | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << MCXX_SETUP_SHIFT) + | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << MCXX_ASST_SHIFT) + | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << MCXX_HOLD_SHIFT), + PC1ATTRIB); + + return 0; +} + +static int ep93xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int clk) +{ + struct soc_pcmcia_timing timing; + int sock = skt->nr; + + soc_common_pcmcia_get_timing(skt, &timing); + + ep93xx_pcmcia_set_mcmem(sock, timing.mem, clk); + ep93xx_pcmcia_set_mcatt(sock, timing.attr, clk); + ep93xx_pcmcia_set_mcio(sock, timing.io, clk); + + return 0; +} + +static int ep93xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) +{ + unsigned int hclk = 10000; /* for now just hard code hclk to 100Mhz (in 10khz units)*/ + return ep93xx_pcmcia_set_mcxx(skt, hclk); +} + +int ep93xx_drv_pcmcia_probe(struct device *dev) +{ + int ret; + struct pcmcia_low_level *ops; + int first, nr; + + if (!dev || !dev->platform_data) + return -ENODEV; + + ops = (struct pcmcia_low_level *)dev->platform_data; + first = ops->first; + nr = ops->nr; + + /* Provide our EP93xx specific timing routines. */ + ops->set_timing = ep93xx_pcmcia_set_timing; + + ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr); + + return ret; +} +EXPORT_SYMBOL(ep93xx_drv_pcmcia_probe); + +static int ep93xx_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level) +{ + int ret = 0; + if (level == SUSPEND_SAVE_STATE) + ret = pcmcia_socket_dev_suspend(dev, state); + return ret; +} + +static int ep93xx_drv_pcmcia_resume(struct device *dev, u32 level) +{ + int ret = 0; + if (level == RESUME_RESTORE_STATE) + { + ret = pcmcia_socket_dev_resume(dev); + } + return ret; +} + +static struct device_driver ep93xx_pcmcia_driver = { + .probe = ep93xx_drv_pcmcia_probe, + .remove = soc_common_drv_pcmcia_remove, + .suspend = ep93xx_drv_pcmcia_suspend, + .resume = ep93xx_drv_pcmcia_resume, + .name = "ep93xx-pcmcia", + .bus = &platform_bus_type, +}; + +static int __init ep93xx_pcmcia_init(void) +{ + return driver_register(&ep93xx_pcmcia_driver); +} + +static void __exit ep93xx_pcmcia_exit(void) +{ + driver_unregister(&ep93xx_pcmcia_driver); +} + +module_init(ep93xx_pcmcia_init); +module_exit(ep93xx_pcmcia_exit); + +MODULE_AUTHOR("Robert Whaley (whaley@applieddata.net)"); +MODULE_DESCRIPTION("Linux PCMCIA Card Services: EP93xx core socket driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/ep93xx_edb9315.c b/drivers/pcmcia/ep93xx_edb9315.c new file mode 100644 index 0000000..519fc8d --- /dev/null +++ b/drivers/pcmcia/ep93xx_edb9315.c @@ -0,0 +1,283 @@ +/* + * linux/drivers/pcmcia/ep93xx_edb9315.c + * + * Adapted from pxa27x_mainstone.c + * + * Edb9315 PCMCIA specific routines. + * + * Created: May 12, 2004 + * Author: Nicolas Pitre + * Copyright: MontaVista Software Inc. + * + * 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 "soc_common.h" + +static struct pcmcia_irqs irqs[] = { + { 0, IRQ_GPIO1, "CF CD1" }, + { 0, IRQ_GPIO2, "CF CD2" }, + { 0, IRQ_GPIO3, "CF STSCHG/BVD1" }, + { 0, IRQ_GPIO4, "CF SPKR/BVD2" }, +}; + + +static int edb9315_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int rtn; + + if (skt->nr == 0) + return -ENXIO; + + skt->irq = IRQ_GPIO6; + + rtn = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + + /* enable GPIO6 as interrupt */ + writel(0x40, GPIO_INTEN); + + /* enable GPIO1-4 and 6 as interrupt */ + /* Note: 1-4 need to be edge triggered, but + then the irq vectors need to hit GPIOxEIO + which they don't currently do - no big deal + since CD and BVD are polled anyway */ + /* writel(0x5e, GPIO_INTEN); */ + + return rtn; +} + +static void edb9315_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +} + +static void edb9315_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + unsigned long status; + + status = inl(GPIO_PFDR); + + state->detect = (status & PCMCIA_DETECT) ? 0 : 1; + state->ready = (status & PCMCIA_READY) ? 1 : 0; + state->bvd1 = (status & PCMCIA_BVD1) ? 1 : 0; + state->bvd2 = (status & PCMCIA_BVD2) ? 1 : 0; + state->vs_3v = (status & PCMCIA_VS_3V) ? 0 : 1; + state->vs_Xv = (status & PCMCIA_VS_XV) ? 0 : 1; + state->wrprot = (status & PCMCIA_WRPROT) ? 0 : 1; + +// printk("%s: nr: %d, status: %#x, state: %#x\n", __FUNCTION__, skt->nr, status, *((unsigned char *) state)); +} + +/* + * We bit-bang the pcmcia power controller using this function. + */ +static void ep93xx_bitbang( unsigned long ulNewEEValue ) +{ + unsigned long ulGdata; + + ulGdata = inl( GPIO_PGDR ); + + ulGdata &= ~(GPIOA_EECLK | GPIOA_EEDAT | GPIOA_SLA0); + + ulNewEEValue &= (GPIOA_EECLK | GPIOA_EEDAT | GPIOA_SLA0); + + ulGdata |= ulNewEEValue; + + outl( ulGdata, GPIO_PGDR ); + ulGdata = inl( GPIO_PGDR ); // read to push write out wrapper + + // Voltage controller's data sheet says minimum pulse width is + // one microsecond. + udelay(5); +} + +static int +ep93xx_set_voltage( u_short sock, u_char NewVcc ) +{ + struct socket_info_t * skt = &socket_info[sock]; + unsigned long ulSwitchSettings, ulDataBit, ulGdirection; + int i; + + if (sock >= EP93XX_MAX_SOCK) + return -EINVAL; + + if( skt->Vcc == NewVcc ){ + DEBUG(3, "Power already set to %d\n", NewVcc ); + return 0; + } + + ulSwitchSettings = EE_ADDRESS | ENABLE; + switch( NewVcc ) + { + case 0: + DEBUG(3, "Configure the socket for 0 Volts\n"); + ulSwitchSettings |= AVCC_0V; + break; + + case 50: + ulSwitchSettings |= AVCC_5V; + DEBUG(3, "Configure the socket for 5 Volts\n"); + break; + + case 33: + DEBUG(3, "Configure the socket for 3.3 Volts\n"); + ulSwitchSettings |= AVCC_33V; + break; + + default: + printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, + NewVcc); + return -1; + } + + // + // Configure the proper GPIO pins as outputs. + // + ep93xx_bitbang( GPIOA_EECLK | GPIOA_EEDAT ); + + // + // Read modify write the data direction register, set the + // proper lines to be outputs. + // + ulGdirection = inl( GPIO_PGDDR ); + ulGdirection |= GPIOA_EECLK | GPIOA_EEDAT | GPIOA_SLA0; + outl( ulGdirection, GPIO_PGDDR ); + ulGdirection = inl( GPIO_PGDDR ); // read to push write out wrapper + + // + // Clear all except EECLK + // Lower the clock. + // + ep93xx_bitbang( GPIOA_EECLK ); + ep93xx_bitbang( 0 ); + + // + // Serial shift the command word out to the voltage controller. + // + for( i=18 ; i>=0 ; --i ) + { + if( (ulSwitchSettings >> i) & 0x1 ) + ulDataBit = GPIOA_EEDAT; + else + ulDataBit = 0; + + // + // Put the data on the bus and lower the clock. + // Raise the clock to latch the data in. + // Lower the clock again. + // + ep93xx_bitbang( ulDataBit ); + ep93xx_bitbang( ulDataBit | GPIOA_EECLK ); + ep93xx_bitbang( ulDataBit ); + } + + // + // Raise and lower the Latch. + // Raise EECLK, delay, raise EEDAT, leave them that way. + // + ep93xx_bitbang( GPIOA_SLA0 ); + ep93xx_bitbang( 0 ); + ep93xx_bitbang( GPIOA_EECLK ); + ep93xx_bitbang( GPIOA_EECLK | GPIOA_EEDAT ); + + skt->Vcc = NewVcc; + + DEBUG(3, "ep93xx_set_voltage - exit\n"); + + return 0; +} + +static int edb9315_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + unsigned long clrbits = 0, setbits = 0, cr0; + int ret = 0; + + ep93xx_set_voltage(skt->nr, state->Vxx); + + if (!ret && skt->nr == 0) { + + if (state->flags & SS_RESET) { + /* see EP93xx User's Guide */ + writel(0x15, PCMCIACNT); + } else { + /* CF mode - BIT1 for PCMCIA mode */ + writel(0x11, PCMCIACNT); + } + } + + return ret; +} + +static void edb9315_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void edb9315_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level edb9315_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = edb9315_pcmcia_hw_init, + .hw_shutdown = edb9315_pcmcia_hw_shutdown, + .socket_state = edb9315_pcmcia_socket_state, + .configure_socket = edb9315_pcmcia_configure_socket, + .socket_init = edb9315_pcmcia_socket_init, + .socket_suspend = edb9315_pcmcia_socket_suspend, + .nr = 1, +}; + +static struct platform_device *edb9315_pcmcia_device; + +static int __init edb9315_pcmcia_init(void) +{ + int ret; + + edb9315_pcmcia_device = kmalloc(sizeof(*edb9315_pcmcia_device), GFP_KERNEL); + if (!edb9315_pcmcia_device) + return -ENOMEM; + memset(edb9315_pcmcia_device, 0, sizeof(*edb9315_pcmcia_device)); + edb9315_pcmcia_device->name = "ep93xx-pcmcia"; + edb9315_pcmcia_device->dev.platform_data = &edb9315_pcmcia_ops; + + ret = platform_device_register(edb9315_pcmcia_device); + if (ret) + kfree(edb9315_pcmcia_device); + + return ret; +} + +static void __exit edb9315_pcmcia_exit(void) +{ + /* + * This call is supposed to free our edb9315_pcmcia_device. + * Unfortunately platform_device don't have a free method, and + * we can't assume it's free of any reference at this point so we + * can't free it either. + */ + platform_device_unregister(edb9315_pcmcia_device); +} + +module_init(edb9315_pcmcia_init); +module_exit(edb9315_pcmcia_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/ep93xx_zefeerevbh.c b/drivers/pcmcia/ep93xx_zefeerevbh.c new file mode 100644 index 0000000..44d44ed --- /dev/null +++ b/drivers/pcmcia/ep93xx_zefeerevbh.c @@ -0,0 +1,175 @@ +/* + * linux/drivers/pcmcia/ep93xx_zefeerevbh.c + * + * Adapted from ep93xx_zefeerevbh.c + * + * + * ZefeerEVB-H PCMCIA specific routines. + * + * Copyright: DAVE Srl + * + * 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 "soc_common.h" + +#if 0 +#define DPRINTK(fmt, args...) printk( "[%s:] \n" fmt, __FUNCTION__, ## args) +#else +#define DPRINTK(fmt, args...) +#endif + +static struct pcmcia_irqs irqs[] = { + { 0, IRQ_GPIO1, "CF CD1" }, + { 0, IRQ_GPIO2, "CF CD2" }, + { 0, IRQ_GPIO3, "CF STSCHG/BVD1" }, + { 0, IRQ_GPIO4, "CF SPKR/BVD2" }, +}; + + +static int zefeerevbh_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int rtn; + unsigned long tmp; + + if (skt->nr != 0) + return -ENXIO; + + /* Set interrupt lines as input */ + tmp = readl(GPIO_PFDDR); + tmp = (tmp & (~((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 6)))); + writel(tmp, GPIO_PFDDR); + + skt->irq = IRQ_GPIO6; + + rtn = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + + /* enable GPIO6 as interrupt */ + writel(0x40, GPIO_INTEN); + + /* enable GPIO1-4 and 6 as interrupt */ + /* Note: 1-4 need to be edge triggered, but + then the irq vectors need to hit GPIOxEIO + which they don't currently do - no big deal + since CD and BVD are polled anyway */ + /* writel(0x5e, GPIO_INTEN); */ + + return rtn; +} + +static void zefeerevbh_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +} + +static void zefeerevbh_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + unsigned long status; + + status = inl(GPIO_PFDR); + + state->detect = (status & PCMCIA_DETECT) ? 0 : 1; + state->ready = (status & PCMCIA_READY) ? 1 : 0; + state->bvd1 = (status & PCMCIA_BVD1) ? 1 : 0; + state->bvd2 = (status & PCMCIA_BVD2) ? 1 : 0; + state->vs_3v = (status & PCMCIA_VS_3V) ? 0 : 1; + state->vs_Xv = (status & PCMCIA_VS_XV) ? 0 : 1; + state->wrprot = (status & PCMCIA_WRPROT) ? 0 : 1; + + DPRINTK("%s: nr: %d, status: %#x, state: %#x\n", __FUNCTION__, skt->nr, status, *((unsigned char *) state)); +} + +static int zefeerevbh_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + + printk(KERN_INFO "[%s]: Vcc = %u, Vpp = %u\n", __FUNCTION__, state->Vcc, state->Vpp); + + /* By default power handling is managed by external controller automatically */ + + if (skt->nr == 0) { + if (state->flags & SS_RESET) { + /* see EP93xx User's Guide */ + writel(0x15, PCMCIACNT); + } else { + /* CF mode - BIT1 for PCMCIA mode */ + writel(0x11, PCMCIACNT); + } + } + + + return 0; +} + +static void zefeerevbh_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void zefeerevbh_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level zefeerevbh_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = zefeerevbh_pcmcia_hw_init, + .hw_shutdown = zefeerevbh_pcmcia_hw_shutdown, + .socket_state = zefeerevbh_pcmcia_socket_state, + .configure_socket = zefeerevbh_pcmcia_configure_socket, + .socket_init = zefeerevbh_pcmcia_socket_init, + .socket_suspend = zefeerevbh_pcmcia_socket_suspend, + .nr = 1, +}; + +static struct platform_device *zefeerevbh_pcmcia_device; + +static int __init zefeerevbh_pcmcia_init(void) +{ + int ret; + + zefeerevbh_pcmcia_device = kmalloc(sizeof(*zefeerevbh_pcmcia_device), GFP_KERNEL); + if (!zefeerevbh_pcmcia_device) + return -ENOMEM; + memset(zefeerevbh_pcmcia_device, 0, sizeof(*zefeerevbh_pcmcia_device)); + zefeerevbh_pcmcia_device->name = "ep93xx-pcmcia"; + zefeerevbh_pcmcia_device->dev.platform_data = &zefeerevbh_pcmcia_ops; + + ret = platform_device_register(zefeerevbh_pcmcia_device); + if (ret) + kfree(zefeerevbh_pcmcia_device); + + return ret; +} + +static void __exit zefeerevbh_pcmcia_exit(void) +{ + /* + * This call is supposed to free our zefeerevbh_pcmcia_device. + * Unfortunately platform_device don't have a free method, and + * we can't assume it's free of any reference at this point so we + * can't free it either. + */ + platform_device_unregister(zefeerevbh_pcmcia_device); +} + +module_init(zefeerevbh_pcmcia_init); +module_exit(zefeerevbh_pcmcia_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 812bae6..15bfa5d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -289,6 +289,25 @@ config SERIAL_CLPS711X_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_EP93XX + tristate "EP93XX serial port support" + depends on ARM && ARCH_EP93XX + select SERIAL_CORE + help + Support for the serial ports included in the EP93xx CPU SOC. + +config SERIAL_EP93XX_CONSOLE + bool "Support for console on EP93XX serial port" + depends on SERIAL_EP93XX=y + select SERIAL_CORE_CONSOLE + help + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttyCL1". (Try "man bootparam" or see the documentation of + your boot loader (lilo or loadlin) about how to pass options to the + kernel at boot time.) + config SERIAL_S3C2410 tristate "Samsung S3C2410 Serial port support" depends on ARM && ARCH_S3C2410 diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index d7c7c71..ef074dc 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o +obj-$(CONFIG_SERIAL_EP93XX) += ep93xx.o obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o diff --git a/drivers/serial/ep93xx.c b/drivers/serial/ep93xx.c new file mode 100644 index 0000000..60f91a6 --- /dev/null +++ b/drivers/serial/ep93xx.c @@ -0,0 +1,863 @@ +/* + * drivers/serial/ep93xx.c + * + * Driver for EP93xx serial ports + * + * Based on drivers/serial/amba-pl011.c + * + * Copyright 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * Copyright (C) 2004 Ray Lehtiniemi + * + * 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 + * + * $Id: ep93xx.c,v 1.42 2002/07/28 10:03:28 rmk Exp $ + * + */ + +/* todo: + * - correct major/minor numbers + * - implement request/release/verify port + * - from /dev/ttyAM0, 'stty -F /dev/ttyAM1 57600' not working right. + * looks like it changes the divisor, but it gets changed back as + * soon as you enter a char on /dev/ttyAM1. + * - do not enable modem status ints unless HW is setup + * - do not return modem status unless HW is setup + * - figure out a nice way to handle CL0 HDLC/modem, CL1 SIR IrDA, + * and CL2 HDLC/RS485 + * - UART DMA operation? + * - handle icount fields rng and buf_overrun? + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_SERIAL_EP93XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include + +#if defined(CONFIG_ARCH_EP9312) || defined(CONFIG_ARCH_EP9315) +#define UART_NR 3 +#else +#define UART_NR 2 +#endif + +#define SERIAL_EP93XX_MAJOR 204 +#define SERIAL_EP93XX_MINOR 16 + +#define ISR_PASS_LIMIT 256 + +#define REG(port,name) ((port)->membase + (name) - EP93XX_APB_BASE - UART1_OFFSET) + +#define UARTDR(port) REG(port,UART1DR) +#define UARTCR(port) REG(port,UART1CR) +#define UARTFR(port) REG(port,UART1FR) +#define UARTRSR(port) REG(port,UART1RSR) +#define UARTECR(port) REG(port,UART1ECR) +#define UARTMCR(port) REG(port,UART1MCR) +#define UARTMSR(port) REG(port,UART1MSR) +#define UARTIIR(port) REG(port,UART1IIR) +#define UARTICR(port) REG(port,UART1ICR) +#define UARTLCH(port) REG(port,UART1CR_H) +#define UARTLCM(port) REG(port,UART1CR_M) +#define UARTLCL(port) REG(port,UART1CR_L) + +#define UARTRSR_CREAD 0x100 + +static void enable_clocks(struct uart_port *port) +{ + unsigned int devcfg = readl(SYSCON_DEVCFG); + + switch (port->line) { + case 0: + devcfg |= SYSCON_DEVCFG_U1EN; + devcfg &= ~SYSCON_DEVCFG_MonG; /* handle this better... */ + break; + case 1: + devcfg |= SYSCON_DEVCFG_U2EN; + break; + case 2: + devcfg |= SYSCON_DEVCFG_U3EN; + break; + } + + SysconSetLocked(SYSCON_DEVCFG, ep93xx_SYSCON_DEVCFG(devcfg)); +} + +static void disable_clocks(struct uart_port *port) +{ + unsigned int devcfg = readl(SYSCON_DEVCFG); + + switch (port->line) { + case 0: + devcfg &= ~SYSCON_DEVCFG_U1EN; + break; + case 1: + devcfg &= ~SYSCON_DEVCFG_U2EN; + break; + case 2: + devcfg &= ~SYSCON_DEVCFG_U3EN; + break; + } + + SysconSetLocked(SYSCON_DEVCFG, ep93xx_SYSCON_DEVCFG(devcfg)); +} + +static int is_port_enabled(struct uart_port *port) +{ + unsigned int devcfg = readl(SYSCON_DEVCFG); + + switch (port->line) { + case 0: + devcfg &= SYSCON_DEVCFG_U1EN; + break; + case 1: + devcfg &= SYSCON_DEVCFG_U2EN; + break; + case 2: + devcfg &= SYSCON_DEVCFG_U3EN; + break; + } + + return devcfg ? 1 : 0; +} + +static void ep93xxuart_stop_tx(struct uart_port *port) +{ + unsigned long cr = readl(UARTCR(port)); + cr &= ~UARTCR_TIE; + writel(cr, UARTCR(port)); +} + +static void ep93xxuart_start_tx(struct uart_port *port) +{ + unsigned long cr = readl(UARTCR(port)); + cr |= UARTCR_TIE; + writel(cr, UARTCR(port)); +} + +static void ep93xxuart_stop_rx(struct uart_port *port) +{ + unsigned long cr = readl(UARTCR(port)); + cr &= ~(UARTCR_RIE | UARTCR_RTIE); + writel(cr, UARTCR(port)); +} + +static void ep93xxuart_enable_ms(struct uart_port *port) +{ + /* fixme: add an ms mask to a wrapper port struct */ + if (port->line == 0) { + unsigned long cr = readl(UARTCR(port)); + cr |= UARTCR_MSIE; + writel(cr, UARTCR(port)); + } +} + +#ifdef SUPPORT_SYSRQ +static void ep93xxuart_rx_chars(struct uart_port *port, struct pt_regs *regs) +#else +static void ep93xxuart_rx_chars(struct uart_port *port) +#endif +{ + struct tty_struct *tty = port->info->tty; + unsigned long fifo, chr, stat, flg; + unsigned int count = 256; + + fifo = readl(UARTFR(port)); + while (((fifo & UARTFR_RXFE) == 0) && count--) { + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty->flip.work.func((void *)tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + printk(KERN_WARNING "TTY_DONT_FLIP set\n"); + return; + } + } + + chr = readl(UARTDR(port)); + flg = TTY_NORMAL; + + port->icount.rx++; + + stat = readl(UARTRSR(port)) | UARTRSR_CREAD; + + if (stat & (UARTRSR_FE | UARTRSR_PE | UARTRSR_OE | UARTRSR_BE)) { + + writel(0, UARTECR(port)); + + if (stat & UARTRSR_BE) { + stat &= ~(UARTRSR_PE | UARTRSR_FE); + port->icount.brk++; + if (uart_handle_break(port)) + goto ignore_char; + } else if (stat & UARTRSR_PE) { + port->icount.parity++; + } else if (stat & UARTRSR_FE) { + port->icount.frame++; + } + + if (stat & UARTRSR_OE) + port->icount.overrun++; + + stat &= port->read_status_mask; + + if (stat & UARTRSR_BE) + flg = TTY_BREAK; + else if (stat & UARTRSR_PE) + flg = TTY_PARITY; + else if (stat & UARTRSR_FE) + flg = TTY_FRAME; + } + + if (uart_handle_sysrq_char(port, chr, regs)) + goto ignore_char; + + if ((stat & port->ignore_status_mask) == 0) { + *tty->flip.flag_buf_ptr++ = flg; + *tty->flip.char_buf_ptr++ = chr; + tty->flip.count++; + } + + if ((stat & UARTRSR_OE) && tty->flip.count < TTY_FLIPBUF_SIZE) { + *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; + *tty->flip.char_buf_ptr++ = 0; + tty->flip.count++; + } + + ignore_char: + fifo = readl(UARTFR(port)); + } + tty_flip_buffer_push(tty); +} + +static void ep93xxuart_tx_chars(struct uart_port *port) +{ + struct circ_buf *xmit = &port->info->xmit; + int count; + + if (port->x_char) { + writel(port->x_char, UARTDR(port)); + port->icount.tx++; + port->x_char = 0; + return; + } + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + ep93xxuart_stop_tx(port); + return; + } + + count = port->fifosize >> 1; + do { + writel(xmit->buf[xmit->tail], UARTDR(port)); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (--count > 0); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) + ep93xxuart_stop_tx(port); +} + +static void ep93xxuart_modem_status(struct uart_port *port) +{ + unsigned int status = readl(UARTFR(port)); + + writel(0, UARTICR(port)); + + if (status & UARTMSR_DDCD) + uart_handle_dcd_change(port, status & UARTMSR_DCD); + + if (status & UARTMSR_DDSR) + port->icount.dsr++; + + if (status & UARTMSR_DCTS) + uart_handle_cts_change(port, status & UARTMSR_CTS); + + if (status & (UARTMSR_DDCD | UARTMSR_DDSR | UARTMSR_DCTS)) + wake_up_interruptible(&port->info->delta_msr_wait); +} + +static irqreturn_t ep93xxuart_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct uart_port *port = dev_id; + unsigned int pass_counter = ISR_PASS_LIMIT; + int handled = 0; + unsigned long iir; + + spin_lock(&port->lock); + + iir = readl(UARTIIR(port)); + + if (iir) { + do { + if (iir & (UARTIIR_RIS | UARTIIR_RTIS)) +#ifdef SUPPORT_SYSRQ + ep93xxuart_rx_chars(port, regs); +#else + ep93xxuart_rx_chars(port); +#endif + if (iir & UARTIIR_TIS) + ep93xxuart_tx_chars(port); + if (iir & UARTIIR_MIS) + ep93xxuart_modem_status(port); + + if (pass_counter-- == 0) + break; + + iir = readl(UARTIIR(port)); + + } while (iir & + (UARTIIR_RIS | UARTIIR_RTIS | UARTIIR_TIS | + UARTIIR_MIS)); + handled = 1; + } + + spin_unlock(&port->lock); + + return IRQ_RETVAL(handled); +} + +static unsigned int ep93xxuart_tx_empty(struct uart_port *port) +{ + unsigned long status = readl(UARTFR(port)); + return status & UARTFR_TXFE ? 0 : TIOCSER_TEMT; /* FIXME: klaus used UARTFR_BUSY? */ +} + +static unsigned int ep93xxuart_get_mctrl(struct uart_port *port) +{ + unsigned int result = 0; + + /* fixme: use a wrapper struct w/ ms flags */ + if (port->line == 0) { + unsigned int msr = readl(UARTMSR(port)); + if (msr & UARTMSR_CTS) + result |= TIOCM_CTS; + if (msr & UARTMSR_DSR) + result |= TIOCM_DSR; + if (msr & UARTMSR_RI) + result |= TIOCM_RI; + if (msr & UARTMSR_DCD) + result |= TIOCM_CAR; + } + return result; +} + +static void ep93xxuart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + unsigned long mcr; + + if (port->line == 0) { + mcr = readl(UARTMCR(port)); + if (mctrl & TIOCM_RTS) + mcr |= UARTMCR_RTS; + else + mcr &= ~UARTMCR_RTS; + if (mctrl & TIOCM_DTR) + mcr |= UARTMCR_DTR; + else + mcr &= ~UARTMCR_DTR; + if (mctrl & TIOCM_OUT1) + mcr |= UARTMCR_OUT1; + else + mcr &= ~UARTMCR_OUT1; + if (mctrl & TIOCM_OUT2) + mcr |= UARTMCR_OUT2; + else + mcr &= ~UARTMCR_OUT2; + writel(mcr, UARTMCR(port)); + } +} + +/* FIXME: klaus grabbed the &port->lock spinlock here.. */ +static void ep93xxuart_break_ctl(struct uart_port *port, int break_state) +{ + unsigned long lch; + + lch = readl(UARTLCH(port)); + if (break_state) + lch |= UARTLCR_H_BRK; + else + lch &= ~UARTLCR_H_BRK; + writel(lch, UARTLCH(port)); +} + +static int ep93xxuart_startup(struct uart_port *port) +{ + unsigned int uartcr; + int retval; + + retval = request_irq(port->irq, ep93xxuart_int, 0, "ep93xxuart", port); + if (retval) + return retval; + + enable_clocks(port); + + uartcr = readl(UARTCR(port)); + uartcr |= UARTCR_UARTE | UARTCR_RIE | UARTCR_RTIE; + uartcr &= ~0x6; + writel(uartcr, UARTCR(port)); + + return 0; +} + +static void ep93xxuart_shutdown(struct uart_port *port) +{ + unsigned int uartcr; + unsigned int linectl; + + linectl = readl(UARTLCH(port)); + linectl &= ~(UARTLCR_H_FEN | UARTLCR_H_BRK); + writel(linectl, UARTLCH(port)); + + uartcr = readl(UARTCR(port)); + uartcr &= ~(UARTCR_UARTE | UARTCR_RIE | UARTCR_RTIE | UARTCR_TIE); + writel(uartcr, UARTCR(port)); + + disable_clocks(port); + + free_irq(port->irq, port); +} + +static void +ep93xxuart_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) +{ + unsigned int baud, quot; + unsigned long flags; + unsigned long lch; + + /* wait for fifo to drain.. is this needed? upper level should handle it.. */ + if (is_port_enabled(port)) + do { + flags = readl(UARTFR(port)); + } while (flags & UARTFR_BUSY); + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + quot = uart_get_divisor(port, baud); + + switch (termios->c_cflag & CSIZE) { + case CS5: + lch = UARTLCR_H_WLEN_5_DATA; + break; + case CS6: + lch = UARTLCR_H_WLEN_6_DATA; + break; + case CS7: + lch = UARTLCR_H_WLEN_7_DATA; + break; + default: + lch = UARTLCR_H_WLEN_8_DATA; + break; + } + + if (termios->c_cflag & CSTOPB) + lch |= UARTLCR_H_STP2; + + if (termios->c_cflag & PARENB) { + lch |= UARTLCR_H_PEN; + if (!(termios->c_cflag & PARODD)) + lch |= UARTLCR_H_EPS; + } + + if (port->fifosize > 1) + lch |= UARTLCR_H_FEN; + + spin_lock_irqsave(&port->lock, flags); + + lch |= readl(UARTLCH(port)) & UARTLCR_H_BRK; + + uart_update_timeout(port, termios->c_cflag, baud); + + port->read_status_mask = UARTRSR_OE; + if (termios->c_iflag & INPCK) + port->read_status_mask |= UARTRSR_FE | UARTRSR_PE; + if (termios->c_iflag & (BRKINT | PARMRK)) + port->read_status_mask |= UARTRSR_BE; + + port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= UARTRSR_FE | UARTRSR_PE; + if (termios->c_iflag & IGNBRK) { + port->ignore_status_mask |= UARTRSR_BE; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= UARTRSR_OE; + } + if ((termios->c_cflag & CREAD) == 0) + port->ignore_status_mask |= UARTRSR_CREAD; + + quot -= 1; + + writel(quot & 0xff, UARTLCL(port)); + writel((quot >> 8) & 0xff, UARTLCM(port)); + writel(lch, UARTLCH(port)); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *ep93xxuart_type(struct uart_port *port) +{ + return port->type == PORT_EP93XX ? "uart-ep93xx" : NULL; +} + +static void ep93xxuart_release_port(struct uart_port *port) +{ + /* update when we break up static io_desc maps */ +} + +static int ep93xxuart_request_port(struct uart_port *port) +{ + /* update when we break up static io_desc maps */ + return 0; +} + +static void ep93xxuart_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) + if (ep93xxuart_request_port(port) == 0) + port->type = PORT_EP93XX; + + /* FIXME: handle UART_CONFIG_IRQ? */ +} + +static int ep93xxuart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + if (ser->type != PORT_UNKNOWN && ser->type != PORT_EP93XX) + return -EINVAL; + if (ser->irq < 0 || ser->irq >= NR_IRQS) + return -EINVAL; + if (ser->baud_base < 9600) + return -EINVAL; + return 0; +} + +static struct uart_ops ep93xx_pops = { + .tx_empty = ep93xxuart_tx_empty, + .set_mctrl = ep93xxuart_set_mctrl, + .get_mctrl = ep93xxuart_get_mctrl, + .stop_tx = ep93xxuart_stop_tx, + .start_tx = ep93xxuart_start_tx, + .stop_rx = ep93xxuart_stop_rx, + .enable_ms = ep93xxuart_enable_ms, + .break_ctl = ep93xxuart_break_ctl, + .startup = ep93xxuart_startup, + .shutdown = ep93xxuart_shutdown, + .set_termios = ep93xxuart_set_termios, + .type = ep93xxuart_type, + .release_port = ep93xxuart_release_port, + .request_port = ep93xxuart_request_port, + .config_port = ep93xxuart_config_port, + .verify_port = ep93xxuart_verify_port, +}; + +static struct uart_port ep93xx_ports[UART_NR] = { + { + .membase = (void *)UART1_BASE, + .mapbase = UART1_BASE, + .iotype = UPIO_MEM, + .irq = IRQ_UART1, + .uartclk = EP93XX_UART_CLK, + .fifosize = 16, + .ops = &ep93xx_pops, + .flags = UPF_BOOT_AUTOCONF, + }, + { + .membase = (void *)UART2_BASE, + .mapbase = UART2_BASE, + .iotype = UPIO_MEM, + .irq = IRQ_UART2, + .uartclk = EP93XX_UART_CLK, + .fifosize = 16, + .ops = &ep93xx_pops, + .line = 1, + .flags = UPF_BOOT_AUTOCONF, + }, +#if UART_NR > 2 + { + .membase = (void *)UART3_BASE, + .mapbase = UART3_BASE, + .iotype = UPIO_MEM, + .irq = IRQ_UART3, + .uartclk = EP93XX_UART_CLK, + .fifosize = 16, + .ops = &ep93xx_pops, + .line = 2, + .flags = UPF_BOOT_AUTOCONF, + } +#endif +}; + +#ifdef CONFIG_SERIAL_EP93XX_CONSOLE +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + * + * Note that this is called with interrupts already disabled + */ +static void +ep93xxuart_console_write(struct console *co, const char *s, unsigned int count) +{ + struct uart_port *port = ep93xx_ports + co->index; + unsigned long cr, cr2, fr; + int i; + + /* + * Ensure that the port is enabled. + */ + cr = readl(UARTCR(port)); + cr2 = cr & ~(UARTCR_RIE | UARTCR_RTIE | UARTCR_TIE | UARTCR_MSIE); + writel((cr2 | UARTCR_UARTE), UARTCR(port)); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + do { + fr = readl(UARTFR(port)); + } while (fr & UARTFR_TXFF); + writel(s[i], UARTDR(port)); + if (s[i] == '\n') { + do { + fr = readl(UARTFR(port)); + } while (fr & UARTFR_TXFF); + writel('\r', UARTDR(port)); + } + } + + /* + * Finally, wait for transmitter to become empty + * and restore the uart state. + */ + do { + fr = readl(UARTFR(port)); + } while ((fr & UARTFR_TXFE) == 0); + + writel(cr, UARTCR(port)); +} + +static void __init +ep93xxuart_console_get_options(struct uart_port *port, int *baud, + int *parity, int *bits) +{ + if (readl(UARTCR(port)) & UARTCR_UARTE) { + unsigned long lch, quot; + + lch = readl(UARTLCH(port)); + + *parity = 'n'; + if (lch & UARTLCR_H_PEN) { + if (lch & UARTLCR_H_EPS) + *parity = 'e'; + else + *parity = 'o'; + } + + if ((lch & UARTLCR_H_WLEN) == UARTLCR_H_WLEN_7_DATA) + *bits = 7; + else + *bits = 8; + + quot = + ((readl(UARTLCM(port)) & 0xff) << 8) | (readl(UARTLCL(port)) + & 0xff); + + *baud = port->uartclk / (16 * (quot + 1)); + } +} + +static int __init ep93xxuart_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 57600; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + /* + * Check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + port = uart_get_console(ep93xx_ports, UART_NR, co); + + /* + * Temporary fix. + */ + spin_lock_init(&port->lock); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else + ep93xxuart_console_get_options(port, &baud, &parity, &bits); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +extern struct uart_driver ep93xx_reg; +static struct console ep93xx_console = { + .name = "ttyAM", + .write = ep93xxuart_console_write, + .device = uart_console_device, + .setup = ep93xxuart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &ep93xx_reg, +}; + +static int __init ep93xxuart_console_init(void) +{ + register_console(&ep93xx_console); + return 0; +} + +console_initcall(ep93xxuart_console_init); + +#define EP93XX_CONSOLE &ep93xx_console +#else +#define EP93XX_CONSOLE NULL +#endif + +static struct uart_driver ep93xx_reg = { + .driver_name = "ttyAM", + .dev_name = "ttyAM", + .major = SERIAL_EP93XX_MAJOR, + .minor = SERIAL_EP93XX_MINOR, + .nr = UART_NR, + .cons = EP93XX_CONSOLE, +}; + +static int ep93xxuart_probe(struct amba_device *dev, void *id) +{ + int i; + + for (i = 0; i < UART_NR; i++) { + if (ep93xx_ports[i].membase != (void *)dev->res.start) + continue; + + ep93xx_ports[i].dev = &dev->dev; + uart_add_one_port(&ep93xx_reg, &ep93xx_ports[i]); + amba_set_drvdata(dev, &ep93xx_ports[i]); + break; + } + + return 0; +} + +static int ep93xxuart_remove(struct amba_device *dev) +{ + struct uart_port *p = amba_get_drvdata(dev); + + if (p) + uart_remove_one_port(&ep93xx_reg, p); + + amba_set_drvdata(dev, NULL); + + return 0; +} + +static int ep93xxuart_suspend(struct amba_device *dev, pm_message_t msg) +{ + struct uart_port *p = amba_get_drvdata(dev); + + if (p) + uart_suspend_port(&ep93xx_reg, p); + + return 0; +} + +static int ep93xxuart_resume(struct amba_device *dev) +{ + struct uart_port *p = amba_get_drvdata(dev); + + if (p) + uart_resume_port(&ep93xx_reg, p); + + return 0; +} + +static struct amba_id ep93xxuart_ids[] __initdata = { + { /* UART1 */ + .id = 0x808c0000, + .mask = 0xffff0000, + }, + { /* UART2 */ + .id = 0x808d0000, + .mask = 0xffff0000, + }, + { /* UART3 */ + .id = 0x808e0000, + .mask = 0xffff0000, + }, + {0, 0}, +}; + +static struct amba_driver ep93xxuart_driver = { + .drv = { + .name = "uart-ep93xx", + }, + .id_table = ep93xxuart_ids, + .probe = ep93xxuart_probe, + .remove = ep93xxuart_remove, + .suspend = ep93xxuart_suspend, + .resume = ep93xxuart_resume, +}; + +static int __init ep93xxuart_init(void) +{ + int ret; + + printk(KERN_INFO "Serial: EP93xx driver $Revision: 1.42 $\n"); + + ret = uart_register_driver(&ep93xx_reg); + if (ret == 0) { + ret = amba_driver_register(&ep93xxuart_driver); + if (ret) + uart_unregister_driver(&ep93xx_reg); + } + + return ret; +} + +static void __exit ep93xxuart_exit(void) +{ + amba_driver_unregister(&ep93xxuart_driver); + uart_unregister_driver(&ep93xx_reg); +} + +module_init(ep93xxuart_init); +module_exit(ep93xxuart_exit); + +MODULE_AUTHOR("Ray Lehtiniemi"); +MODULE_DESCRIPTION("EP93XX generic serial driver $Revision: 1.42 $"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 85dacc9..e57292f 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -22,6 +22,7 @@ config USB_ARCH_HAS_OHCI default y if ARCH_LH7A404 default y if ARCH_S3C2410 default y if PXA27x + default y if ARCH_EP93XX # PPC: default y if STB03xxx default y if PPC_MPC52xx diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c new file mode 100644 index 0000000..8aec2fb --- /dev/null +++ b/drivers/usb/host/ohci-ep93xx.c @@ -0,0 +1,248 @@ +/* + * OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * (C) Copyright 2002 Hewlett-Packard Company + * (C) Copyright 2004 Ray Lehtiniemi + * + * EP93XX Bus Glue + * + * Written by Ray Lehtiniemi + * Based on SA-1111 glue. + * + * This file is licenced under the GPL. + */ + +#include +#include + +#ifndef CONFIG_ARCH_EP93XX +#error "This file is EP93xx bus glue. CONFIG_ARCH_EP93XX must be defined." +#endif + +extern int usb_disabled(void); + + +/*-------------------------------------------------------------------------*/ + +static void ep93xx_start_hc(struct amba_device *dev) +{ + unsigned int pwrcnt; + + printk(KERN_DEBUG __FILE__ ": starting EP93xx OHCI USB Controller\n"); + + pwrcnt = readl(SYSCON_PWRCNT); + pwrcnt |= SYSCON_PWRCNT_USHEN; + writel(pwrcnt, SYSCON_PWRCNT); +} + +static void ep93xx_stop_hc(struct amba_device *dev) +{ + unsigned int pwrcnt; + + printk(KERN_DEBUG __FILE__ ": stopping EP93xx OHCI USB Controller\n"); + + pwrcnt = readl(SYSCON_PWRCNT); + pwrcnt &= ~SYSCON_PWRCNT_USHEN; + writel(pwrcnt, SYSCON_PWRCNT); +} + +/*-------------------------------------------------------------------------*/ + +#if 0 +static void dump_hci_status(struct usb_hcd *hcd, const char *label) +{ + unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS); + + dbg("%s USB_STATUS = { %s%s%s%s%s}", label, + ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), + ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""), + ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "), + ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "), + ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : "")); +} +#endif + +/*-------------------------------------------------------------------------*/ + +void usb_hcd_ep93xx_remove(struct usb_hcd *, struct amba_device *); + +/* configure so an HC device and id are always provided */ +/* always called with process context; sleeping is OK */ + +/** + * usb_hcd_ep93xx_probe - initialize ep93xx HCD + * Context: !in_interrupt() + * + * Allocates basic resources for this USB host controller, and + * then invokes the start() method for the HCD associated with it + * through the hotplug entry's driver_data. + * + * Store this function in the HCD's struct pci_driver as probe(). + */ +int usb_hcd_ep93xx_probe(const struct hc_driver *driver, + struct amba_device *dev) +{ + int retval; + struct usb_hcd *hcd; + + hcd = usb_create_hcd(driver, &dev->dev, "ep93xx"); + + if (!hcd) + return -ENOMEM; + + hcd->rsrc_start = dev->res.start; + hcd->rsrc_len = dev->res.end - dev->res.start + 1; + + hcd->regs = (void __iomem *)dev->res.start; + + ep93xx_start_hc(dev); + ohci_hcd_init(hcd_to_ohci(hcd)); + + retval = usb_add_hcd(hcd, dev->irq[0], SA_INTERRUPT); + if (retval == 0) + return retval; + + ep93xx_stop_hc(dev); + + usb_put_hcd(hcd); + return retval; +} + +/* may be called without controller electrically present */ +/* may be called with controller, bus, and devices active */ + +/** + * usb_hcd_ep93xx_remove - shutdown processing for SA-1111-based HCDs + * @dev: USB Host Controller being removed + * Context: !in_interrupt() + * + * Reverses the effect of usb_hcd_ep93xx_probe(), first invoking + * the HCD's stop() method. It is always called from a thread + * context, normally "rmmod", "apmd", or something similar. + * + */ +void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, struct amba_device *dev) +{ + usb_remove_hcd(hcd); + ep93xx_stop_hc(dev); + usb_put_hcd(hcd); +} + +/*-------------------------------------------------------------------------*/ + +static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int ret; + + ohci_dbg(ohci, "ohci_ep93xx_start, ohci:%p", ohci); + + if ((ret = ohci_init(ohci)) < 0) + return ret; + + if ((ret = ohci_run(ohci)) < 0) { + err("can't start %s", hcd->self.bus_name); + ohci_stop(hcd); + return ret; + } + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static const struct hc_driver ohci_ep93xx_hc_driver = { + .description = hcd_name, + .product_desc = "EP93xx OHCI", + .hcd_priv_size = sizeof(struct ohci_hcd), + + /* + * generic hardware linkage + */ + .irq = ohci_irq, + .flags = HCD_USB11, + + /* + * basic lifecycle operations + */ + .start = ohci_ep93xx_start, +#ifdef CONFIG_PM + /* suspend: ohci_ep93xx_suspend, -- tbd */ + /* resume: ohci_ep93xx_resume, -- tbd */ +#endif + .stop = ohci_stop, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .endpoint_disable = ohci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ohci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ohci_hub_status_data, + .hub_control = ohci_hub_control, +}; + +/*-------------------------------------------------------------------------*/ + +static int ep93xxohci_probe(struct amba_device *dev, void *id) +{ + int ret = -ENODEV; + + if (usb_disabled()) + return -ENODEV; + + ret = usb_hcd_ep93xx_probe(&ohci_ep93xx_hc_driver, dev); + + return ret; +} + +static int ep93xxohci_remove(struct amba_device *dev) +{ + struct usb_hcd *hcd = amba_get_drvdata(dev); + + usb_hcd_ep93xx_remove(hcd, dev); + + return 0; +} + +static struct amba_id ep93xxohci_ids[] __initdata = { + { + .id = 0x80020000, + .mask = 0xffff0000, + }, + {0, 0}, +}; + +static struct amba_driver ep93xxohci_driver = { + .drv = { + .name = "ohci-ep93xx", + }, + .id_table = ep93xxohci_ids, + .probe = ep93xxohci_probe, + .remove = ep93xxohci_remove, +}; + +static int __init ep93xxohci_init(void) +{ + printk(KERN_INFO "USB: EP93xx driver $Revision: 1.42 $\n"); + return amba_driver_register(&ep93xxohci_driver); +} + +static void __exit ep93xxohci_cleanup(void) +{ + amba_driver_unregister(&ep93xxohci_driver); +} + +module_init(ep93xxohci_init); +module_exit(ep93xxohci_cleanup); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index bf1d9ab..bb525a2 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -909,6 +909,10 @@ MODULE_LICENSE ("GPL"); #include "ohci-pxa27x.c" #endif +#ifdef CONFIG_ARCH_EP93XX +#include "ohci-ep93xx.c" +#endif + #ifdef CONFIG_SOC_AU1X00 #include "ohci-au1xxx.c" #endif @@ -923,6 +927,7 @@ MODULE_LICENSE ("GPL"); || defined(CONFIG_ARCH_OMAP) \ || defined (CONFIG_ARCH_LH7A404) \ || defined (CONFIG_PXA27x) \ + || defined (CONFIG_ARCH_EP93XX) \ || defined (CONFIG_SOC_AU1X00) \ || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ ) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index cc8e3bf..1d46ab0 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -172,6 +172,122 @@ config FB_CLPS711X Say Y to enable the Framebuffer driver for the CLPS7111 and EP7212 processors. +config FB_CX25871_I2C + tristate "Conexant CX25871 video encoder" + depends on I2C && EXPERIMENTAL + help + + ! ! ! B R O K E N B R O K E N B R O K E N ! ! ! + + If you say yes here you get support for the Conexant CX25871 + video encoder. Currently only EP93xx CPUs use this for some + NTSC setup. This setup should be done in ep93xxfb.c instead. + It is currently hardcoded here in cx25871, which is wrong, as + it will happen anytime instead of exactly when it is needed. + I've got no NTSC hardware, and no time to test this either. + + Why I've written it then? Well I had to get I2C working and it + helped me on my way there. + + If nobody cares about NTSC support for EP93xx it will go away soon! + + Only say Y if you have such a chip and are prepared to fix the remaining + stuff yourself. + + See ep93xxfb.[ch] and cx25871.c for details. + + This driver can also be built as a module. If so, the module + will be called cx25871. + +config FB_EP93XX + bool "EP93XX Framebuffer support" + depends on FB && ARM && (ARCH_EP9312 || ARCH_EP9315) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y here if you want support for the on EP93XX framebuffer. + + You can also say M here to compile this as a module. However this + is not recommended as loading the module without a display can + be a problem. (Make sure you can login without display before you + say M or N here). + + The module will be called ep93xxfb. +choice + prompt "Display Type" + depends on FB_EP93XX + help + Choose the kind of display you want to attach to the EP93XX framebuffer. + +config FB_CRT_EP93XX + bool "CRT Display" + +config FB_LCD_EP93XX + bool "LCD Display" + help + Support for the Philips 640x480 Display on the EDB93XX evaluation board. + +config FB_LCD_EP93XX_SHARP + bool "LCD Display 320x200 SHARP" + help + Support for the Sharp LQ057Q3DC02 320x200 Color TFT LCD. + +config FB_LCD_EP93XX_SHARP_LQ64D343 + bool "LCD Display 640x480 SHARP" + help + Support for the Sharp LQ64D343 640x480 Color TFT LCD. + +config FB_CX25871 + bool "NTSC Display" + select FB_CX25871_I2C + +config FB_LCD_TX09D50VM1CCA + bool "LCD Display 240x320 Hitachi TX09D50VM1CCA" + help + Support for the Hitachi TX09D50VM1CCA 240x320 Color TFT LCD. + +endchoice + +choice + prompt "Display Color Depth" + depends on FB_EP93XX + default FB_EP93XX_8BPP + help + Choose the default color depth for you EP93xx display. Note that using + other than 8BPP depths tends to be slow. + +config FB_EP93XX_8BPP + bool "8bpp" + help + Use 8 bits per pixel (256 color). + Benefits: fastest available mode + Drawback: few colors available (might do for console work, though) + +config FB_EP93XX_16BPP_565 + bool "16bpp_565" + help + Use 16 bits per pixel. Weighting red:green:blue is 5:6:5 bits. + Make sure your Xserver / Framebuffer based applications use exactly this + weighting. + +config FB_EP93XX_24BPP + bool "24bpp" + help + Use 24 bits per pixel. Weighting red:green:blue is 8:8:8 bits. Say Y here + if you want lots of colors and do not care that much about performance. + + + +config FB_EP93XX_32BPP + bool "32bpp" + help + Use 32 bits per pixel. Weighting transparent:red:green:blue is 8:8:8:8 bits. + Note that transparency is seldom implemented so this one is just slower and + consumes more memory than 24BPP. +endchoice + + config FB_SA1100 bool "SA-1100 LCD support" depends on (FB = y) && ARM && ARCH_SA1100 diff --git a/drivers/video/Makefile b/drivers/video/Makefile index aa434e7..82f680b 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -99,6 +99,8 @@ obj-$(CONFIG_FB_S3C2410) += s3c2410fb. obj-$(CONFIG_FB_VESA) += vesafb.o obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o obj-$(CONFIG_FB_OF) += offb.o +obj-$(CONFIG_FB_EP93XX) += ep93xxfb.o +obj-$(CONFIG_FB_CX25871_I2C) += cx25871.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/cx25871.c b/drivers/video/cx25871.c new file mode 100644 index 0000000..816cbef --- /dev/null +++ b/drivers/video/cx25871.c @@ -0,0 +1,200 @@ +/* + cx25871.c + + Driver for the Conexant CX25871 VIDEO ENCODER + + based on: ds1621.c + + + + + BIG FAT WARNING: THIS IS EXPERIMENTAL AND UNTESTED CODE + + + + + + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * assign an invalid (local use) id for now + * TODO: get an official one! + */ +#define I2C_DRIVERID_EP93XX 0xffff + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x44, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + +static int cx25871_attach_adapter(struct i2c_adapter *adapter); +static int cx25871_detect(struct i2c_adapter *adapter, int address, int kind); +static void cx25871_init_client(struct i2c_client *client); +static int cx25871_detach_client(struct i2c_client *client); + +/* This is the driver that will be inserted */ +static struct i2c_driver cx25871_driver = { + .owner = THIS_MODULE, + .name = "cx25871", + .id = I2C_DRIVERID_EP93XX, + .flags = I2C_DF_NOTIFY, + .attach_adapter = cx25871_attach_adapter, + .detach_client = cx25871_detach_client, +}; + +static int cx25871_id = 0; + +/* Cleanup and introduce cx25871 specific data, if necessary */ +struct cx25871_data { + struct i2c_client client; + struct semaphore update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ +}; + +static int cx25871_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cx25871_write_value(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +static void cx25871_init_client(struct i2c_client *client) +{ + /*FIXME: This should be done in ep93xxfb.c, shouldn't it? */ + + int _todo__fix_this_ugly_hack_; + + cx25871_write_value(client, 0xB8, 0); + mdelay(1000); + /* After auto-configuration, setup pseudo-master mode BUT with EN_BLANKO bit cleared */ + cx25871_write_value(client, 0xBA, + CX25871_REGxBA_SLAVER | CX25871_REGxBA_DACOFF); + cx25871_write_value(client, 0xC6, (CX25871_REGxC6_INMODE_MASK & 0x3)); + cx25871_write_value(client, 0xC4, CX25871_REGxC4_EN_OUT); + cx25871_write_value(client, 0x32, 0); + cx25871_write_value(client, 0xBA, CX25871_REGxBA_SLAVER); +} + +static int cx25871_attach_adapter(struct i2c_adapter *adapter) +{ + printk("cx25871_attach_adapter\n"); + return i2c_probe(adapter, &addr_data, cx25871_detect); +} + +/* This function is called by i2c_detect */ +int cx25871_detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *new_client; + struct cx25871_data *data; + int err = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_WRITE_BYTE)) + goto exit; + + /* OK. For now, we presume we have a valid client. We now create the + client structure, even though we cannot fill it completely yet. + But it allows us to access cx25871_{read,write}_value. */ + if (!(data = kmalloc(sizeof(struct cx25871_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct cx25871_data)); + + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &cx25871_driver; + new_client->flags = 0; + + /* Fill in remaining client fields and put it into the global list */ + strlcpy(new_client->name, "cx25871", I2C_NAME_SIZE); + + new_client->id = cx25871_id++; + data->valid = 0; + init_MUTEX(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) + goto exit_free; + /* Initialize the EP93XX chip */ + cx25871_init_client(new_client); + +/* Register sysfs hooks */ +#if 0 + device_create_file(&new_client->dev, &dev_attr_alarms); + device_create_file(&new_client->dev, &dev_attr_temp1_input); + device_create_file(&new_client->dev, &dev_attr_temp1_min); + device_create_file(&new_client->dev, &dev_attr_temp1_max); +#endif + return 0; + +/* OK, this is not exactly good programming practice, usually. But it is + very code-efficient in this case. */ + exit_free: + kfree(data); + exit: + return err; +} + +static int cx25871_detach_client(struct i2c_client *client) +{ + int err; + + if ((err = i2c_detach_client(client))) { + dev_err(&client->dev, "Client deregistration failed, " + "client not detached.\n"); + return err; + } + + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static int __init cx25871_init(void) +{ + printk("cx25871_init\n"); + return i2c_add_driver(&cx25871_driver); +} + +static void __exit cx25871_exit(void) +{ + i2c_del_driver(&cx25871_driver); +} + +MODULE_DESCRIPTION("Conexant CX25871 video encoder"); +MODULE_LICENSE("GPL"); + +module_init(cx25871_init); +module_exit(cx25871_exit); diff --git a/drivers/video/ep93xxfb.c b/drivers/video/ep93xxfb.c new file mode 100644 index 0000000..475943a --- /dev/null +++ b/drivers/video/ep93xxfb.c @@ -0,0 +1,787 @@ +/****************************************************************************** + * + * File: linux/drivers/video/ep93xxfb.c + * + * Purpose: Framebuffer driver for EP9312/EP9315 evaluation board. + * + * based on: + * skeletonfb.c + * ep93xxfb.c from Linux 2.4.21-rmk1-cirrus-1-3-0 + * + *******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ep93xxfb.h" + +/* +#define DEBUG +#define USE_PRINTASCII +*/ + +#ifdef DEBUG +# if defined(CONFIG_DEBUG_LL) && defined(USE_PRINTASCII) +extern void printascii(const char *); +# define DPRINTK(fmt, args...) {char str[256];sprintf(str, "%s: " fmt, __FUNCTION__ , ## args);printascii(str);} +# else +# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) +# endif +#else +# define DPRINTK(fmt, args...) +#endif + +static struct fb_info info; +static struct fb_fix_screeninfo ep93xxfb_fix; +static struct fb_var_screeninfo ep93xxfb_var; +static struct ep93xxfb_par ep93xxfb_par; +static unsigned int pseudo_palette[MAX_PALETTE_NUM_ENTRIES]; + +int __init ep93xxfb_init(void); +static int ep93xxfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info); +static int ep93xxfb_blank(int blank_mode, struct fb_info *info); +int __init ep93xxfb_init(void); +static void __exit ep93xxfb_cleanup(void); +int __init ep93xxfb_setup(char *options); + +static struct fb_ops ep93xxfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = ep93xxfb_setcolreg, + .fb_blank = ep93xxfb_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +/* + * ep93xxfb_palette_write: + * Encode palette data to 24bit palette format. + * Write palette data to the master palette and inactive hw palette + * switch palettes. And handle asynchronous palette switches. + */ +static inline void +ep93xxfb_palette_write(u_int regno, u_int red, u_int green, + u_int blue, u_int trans) +{ + unsigned int cont, i, pal; + + /* Only supports color LUT, not gray LUT + * + * TBD if not in 4 or 8bpp, then does LUT logic operate? + * TBD or do we need to do nothing here? + * + * LCD: TBD RGB mapping may match spec p193. + * + * CRT: LUT RGB mapping is really R/G/B from high to low bits + * because really determined by wiring to video DAC. + * (disregard spec p 193 showing color LUT B/G/R order) + * Here are the details: + * + * Shift mode 1 directs LUT bits 7-2 onto P5-P0, + * LUT bits 15-10 onto P11-P6, and LUT bits 23-16 + * onto P17-P12. + * + * Board wired P17-12 to video DAC Red inputs, + * P11-P6 wired to video DAC Green inputs, and + * P5-P0 wired to video DAC Blue inputs. + */ + pal = ((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8); + + pseudo_palette[regno] = pal; + + /* Two cases here: + * 1. If LUT switch is pending, then write inactive LUT and when + * switch happens, this new palette entry will be active. + * Race condition here between LUT switch and this write is okay + * since we fix it below. + * + * 2. If LUT switch is not pending, then write here is incomplete + * and whole palette will be written below. + */ + + writel(pal, COLOR_LUT + (regno << 2)); + + cont = readl(LUTCONT); + + if ((cont & LUTCONT_STAT && cont & LUTCONT_RAM1) || + (!(cont & LUTCONT_STAT) && !(cont & LUTCONT_RAM1))) { + /* LUT switch is no longer pending + * + * We do not know if write to LUT above really went + * to currently active LUT. So need to make sure that + * data gets into inactive LUT and switch LUTs. + * + * But currently inactive LUT may be out of date + * in more entries than just last write. + * Need to update currently inactive LUT for all writes + * which went to currently active LUT. + * Fully update the LUT now, which is a simpler policy + * than trying to track writes and do partial update of LUT. + * (Worstcase impact: we update palette every frame) + */ + + for (i = 0; i < 256; i++) // Update inactive LUT + { + writel(pseudo_palette[i], + (COLOR_LUT + (i << 2))); + } + /* Switch active LUTs next frame */ + writel(cont ^ LUTCONT_RAM1, LUTCONT); + } +} + +/** + * xxxfb_setcolreg - Optional function. Sets a color register. + * @regno: Which register in the CLUT we are programming + * @red: The red value which can be up to 16 bits wide + * @green: The green value which can be up to 16 bits wide + * @blue: The blue value which can be up to 16 bits wide. + * @transp: If supported the alpha value which can be up to 16 bits wide. + * @info: frame buffer info structure + * + * Set a single color register. The values supplied have a 16 bit + * magnitude which needs to be scaled in this function for the hardware. + * Things to take into consideration are how many color registers, if + * any, are supported with the current color visual. With truecolor mode + * no color palettes are supported. Here a psuedo palette is created + * which we store the value in pseudo_palette in struct fb_info. For + * pseudocolor mode we have a limited color palette. To deal with this + * we can program what color is displayed for a particular pixel value. + * DirectColor is similar in that we can program each color field. If + * we have a static colormap we don't need to implement this function. + * + * Returns negative errno on error, or zero on success. + */ +static int +ep93xxfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, + unsigned transp, struct fb_info *info) +{ + if (regno >= MAX_PALETTE_NUM_ENTRIES) /* no. of hw registers */ + return 1; + /* + * Program hardware... do anything you want with transp + */ + + /* grayscale works only partially under directcolor */ + if (info->var.grayscale) { + /* grayscale = 0.30*R + 0.59*G + 0.11*B */ + red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; + } + + /* Directcolor: + * var->{color}.offset contains start of bitfield + * var->{color}.length contains length of bitfield + * {hardwarespecific} contains width of DAC + * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) + * RAMDAC[X] is programmed to (red, green, blue) + * + * Pseudocolor: + * uses offset = 0 && length = DAC register width. + * var->{color}.offset is 0 + * var->{color}.length contains widht of DAC + * cmap is not used + * DAC[X] is programmed to (red, green, blue) + * Truecolor: + * does not use RAMDAC (usually has 3 of them). + * var->{color}.offset contains start of bitfield + * var->{color}.length contains length of bitfield + * cmap is programmed to (red << red.offset) | (green << green.offset) | + * (blue << blue.offset) | (transp << transp.offset) + * RAMDAC does not exist + */ +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) + + switch (info->fix.visual) { + case FB_VISUAL_PSEUDOCOLOR: + /* Feed the dual 256x24 hardware LUT */ + ep93xxfb_palette_write(regno, red, green, blue, transp); + break; + case FB_VISUAL_TRUECOLOR: + /* Truecolor has hardware independent palette */ + if (regno >= 16) + return 1; + + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); + ((u32 *) (info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + break; + case FB_VISUAL_DIRECTCOLOR: + /* example here assumes 8 bit DAC. Might be different + * for your hardware */ + red = CNVT_TOHW(red, 8); + green = CNVT_TOHW(green, 8); + blue = CNVT_TOHW(blue, 8); + /* hey, there is bug in transp handling... */ + transp = CNVT_TOHW(transp, 8); + break; + } +#undef CNVT_TOHW + + return 0; +} + +/** + * xxxfb_blank - NOT a required function. Blanks the display. + * @blank_mode: the blank mode we want. + * @info: frame buffer structure that represents a single frame buffer + * + * Blank the screen if blank_mode != 0, else unblank. Return 0 if + * blanking succeeded, != 0 if un-/blanking failed due to e.g. a + * video mode which doesn't support it. Implements VESA suspend + * and powerdown modes on hardware that supports disabling hsync/vsync: + * blank_mode == 2: suspend vsync + * blank_mode == 3: suspend hsync + * blank_mode == 4: powerdown + * + * Returns negative errno on error, or zero on success. + * + */ +static int ep93xxfb_blank(int blank_mode, struct fb_info *info) +{ +#ifdef CONFIG_MACH_ADSSPHERE + void adssphere_blank(int blank_mode); + + adssphere_blank(blank_mode); +#endif + + return 1; +} + +static struct device ep93xxfb_device = { + .bus_id = "ep93xxfb", + .coherent_dma_mask = 0xffffffff, +}; + +/* + * ep9312fb_map_video_memory(): + * Allocates the DRAM memory for the frame buffer. This buffer is + * remapped into a non-cached, non-buffered, memory region to + * allow palette and pixel writes to occur without flushing the + * cache. Once this area is remapped, all virtual memory + * access to the video memory should occur at the new region. + */ +static int +__init ep9312fb_map_video_memory(void) +{ + dma_addr_t handle; + + ep93xxfb_par.dev = &ep93xxfb_device; + + ep93xxfb_par.v_screen_base = dma_alloc_writecombine(ep93xxfb_par.dev, + FB_MAPPED_MEM_SIZE, + &handle, + GFP_KERNEL); + + if (ep93xxfb_par.v_screen_base == NULL) { + printk(KERN_ERR "ep93xxfb: unable to allocate screen memory\n"); + return -ENOMEM; + } + + info.screen_base = ep93xxfb_par.v_screen_base; + info.fix.smem_start = (unsigned int)ep93xxfb_par.p_screen_base = handle; + info.fix.smem_len = FB_MAPPED_MEM_SIZE; + + return 0; +} + +static int ep93xxfb_probe_configuration(void) +{ + int xres, yres, bpp, pixelmode, total; + unsigned char lookup_bpp[] = {-1, -1, 8, -1, 16, -1, 24, 32}; + + pixelmode = readl(PIXELMODE); + + bpp = lookup_bpp[PIXELMODE_P_MASK & pixelmode]; + + if (bpp < 0) return 0; + + yres = readl(SCRNLINES); + + if (yres == 0) return 0; + + xres = (32 * readl(VLINESTEP)) / bpp; + + if (xres == 0) return 0; + + info.node = -1; + info.flags = FBINFO_FLAG_DEFAULT; + + info.fix = ep93xxfb_fix; + info.var = ep93xxfb_var; + info.fbops = &ep93xxfb_ops; + info.pseudo_palette = pseudo_palette; + + info.monspecs = monspecs; + + strcpy(info.fix.id, "Cirrus EP93xx"); + info.fix.type = FB_TYPE_PACKED_PIXELS; + info.fix.xpanstep = 0; + info.fix.ypanstep = 0; + info.fix.ywrapstep = 0; + info.fix.accel = FB_ACCEL_NONE; + + info.var.xres = xres; + info.var.yres = yres; + info.var.xres_virtual = xres; + info.var.yres_virtual = yres; + info.var.bits_per_pixel = bpp; + info.var.activate = FB_ACTIVATE_NOW; + info.var.height = -1; + info.var.width = -1; + + switch (bpp) { + case 8: + info.var.red.length = 8; + info.var.green.length = 8; + info.var.blue.length = 8; + + info.fix.visual = FB_VISUAL_PSEUDOCOLOR; + ep93xxfb_par.bits_per_pixel = 8; + break; + case 16: + info.var.red.length = 5; + info.var.green.length = 6; + info.var.blue.length = 5; + info.var.transp.length = 0; + info.var.red.offset = 11; + info.var.green.offset = 5; + info.var.blue.offset = 0; + info.var.transp.offset = 0; + + info.fix.visual = FB_VISUAL_TRUECOLOR; + info.pseudo_palette = ep93xxfb_par.palette; + + ep93xxfb_par.bits_per_pixel = 16; + break; + case 24: + info.var.red.length = 8; + info.var.blue.length = 8; + info.var.green.length = 8; + info.var.transp.length = 0; + info.var.red.offset = 16; + info.var.green.offset = 8; + info.var.blue.offset = 0; + info.var.transp.offset = 0; + + info.fix.visual = FB_VISUAL_TRUECOLOR; + + ep93xxfb_par.bits_per_pixel = 24; + break; + case 32: + info.var.red.length = 8; + info.var.blue.length = 8; + info.var.green.length = 8; + info.var.transp.length = 0; + info.var.red.offset = 16; + info.var.green.offset = 8; + info.var.blue.offset = 0; + info.var.transp.offset = 0; + + info.fix.visual = FB_VISUAL_TRUECOLOR; + + ep93xxfb_par.bits_per_pixel = 32; + break; + } + + total = readl(HCLKSTOTAL); + info.var.hsync_len = (0x7ff & readl(HSYNCSTRTSTOP)) - ((0x07ff0000 & readl(HSYNCSTRTSTOP)) >> 16); + info.var.right_margin = ((0x07ff0000 & readl(HSYNCSTRTSTOP)) >> 16) - (0x7ff & readl(HACTIVESTRTSTOP)); + info.var.left_margin = total - info.var.hsync_len - info.var.right_margin - xres + 1; + + total = readl(VLINESTOTAL); + info.var.vsync_len = (0x7ff & readl(VSYNCSTRTSTOP)) - ((0x07ff0000 & readl(VSYNCSTRTSTOP)) >> 16); + info.var.upper_margin = total - (0x7ff & readl(VSYNCSTRTSTOP)); + info.var.lower_margin = ((0x07ff0000 & readl(VSYNCSTRTSTOP)) >> 16) - yres + 1; + + info.var.sync = 0; + + info.var.vmode = FB_VMODE_NONINTERLACED; + + info.fix.line_length = info.var.xres_virtual * info.var.bits_per_pixel / 8; // stride in bytes + + info.par = &TimingValues[NULL_MODE]; + + ep93xxfb_par.screen_size = FB_MAX_MEM_SIZE; + ep93xxfb_par.palette_size = MAX_PALETTE_NUM_ENTRIES; + ep93xxfb_par.montype = 1; //TBD why not 0 since single entry? + ep93xxfb_par.currcon = 0; //TBD is this right? + + return 1; +} + +static void +__init ep93xxfb_init_fbinfo(void) +{ + info.node = -1; + info.flags = FBINFO_FLAG_DEFAULT; + + info.fix = ep93xxfb_fix; + info.var = ep93xxfb_var; + info.fbops = &ep93xxfb_ops; + info.pseudo_palette = pseudo_palette; + info.par = &ep93xxfb_par; + + info.monspecs = monspecs; + + strcpy(info.fix.id, "Cirrus EP93xx"); + info.fix.type = FB_TYPE_PACKED_PIXELS; + info.fix.visual = FB_VISUAL_PSEUDOCOLOR; + info.fix.xpanstep = 0; + info.fix.ypanstep = 0; + info.fix.ywrapstep = 0; + info.fix.accel = FB_ACCEL_NONE; + + info.var.xres = TimingValues[DEFAULT_MODE].HRes; + info.var.yres = TimingValues[DEFAULT_MODE].VRes; + info.var.xres_virtual = TimingValues[DEFAULT_MODE].HRes; + info.var.yres_virtual = TimingValues[DEFAULT_MODE].VRes; + info.var.bits_per_pixel = 32; + info.var.red.length = 8; + info.var.green.length = 8; + info.var.blue.length = 8; + info.var.activate = FB_ACTIVATE_NOW; + info.var.height = -1; + info.var.width = -1; + info.var.vmode = FB_VMODE_NONINTERLACED; + + /* + * setup initial parameters + */ + info.var.xres = TimingValues[DEFAULT_MODE].HRes; + info.var.yres = TimingValues[DEFAULT_MODE].VRes; + +#ifdef CONFIG_FB_EP93XX_8BPP + DPRINTK("Default framebuffer is 8bpp."); + info.var.bits_per_pixel = 8; + + info.var.red.length = 8; + info.var.green.length = 8; + info.var.blue.length = 8; + + info.fix.visual = FB_VISUAL_PSEUDOCOLOR; + ep93xxfb_par.bits_per_pixel = 8; +#endif /* CONFIG_FB_EP93XX_8BPP */ +#ifdef CONFIG_FB_EP93XX_16BPP_565 + DPRINTK("Default framebuffer is 16bpp 565."); + info.var.bits_per_pixel = 16; + + info.var.red.length = 5; + info.var.green.length = 6; + info.var.blue.length = 5; + info.var.transp.length = 0; + info.var.red.offset = 11; + info.var.green.offset = 5; + info.var.blue.offset = 0; + info.var.transp.offset = 0; + info.fix.visual = FB_VISUAL_TRUECOLOR; + info.pseudo_palette = ep93xxfb_par.palette; + + ep93xxfb_par.bits_per_pixel = 16; +#endif /* CONFIG_FB_EP93XX_16BPP */ +#ifdef CONFIG_FB_EP93XX_24BPP + DPRINTK("Default framebuffer is 24bpp."); + info.var.bits_per_pixel = 24; + + info.var.red.length = 8; + info.var.blue.length = 8; + info.var.green.length = 8; + info.var.transp.length = 0; + info.var.red.offset = 16; + info.var.green.offset = 8; + info.var.blue.offset = 0; + info.var.transp.offset = 0; + info.fix.visual = FB_VISUAL_TRUECOLOR; + + ep93xxfb_par.bits_per_pixel = 24; +#endif /* CONFIG_FB_EP93XX_24BPP */ +#ifdef CONFIG_FB_EP93XX_32BPP + DPRINTK("Default framebuffer is 32bpp."); + info.var.bits_per_pixel = 32; + + info.var.red.length = 8; + info.var.blue.length = 8; + info.var.green.length = 8; + info.var.transp.length = 0; + info.var.red.offset = 16; + info.var.green.offset = 8; + info.var.blue.offset = 0; + info.var.transp.offset = 0; + info.fix.visual = FB_VISUAL_TRUECOLOR; + + ep93xxfb_par.bits_per_pixel = 32; +#endif /* CONFIG_FB_EP93XX_32BPP */ + + info.var.activate = FB_ACTIVATE_NOW; + info.var.height = -1; /*TBD unknown */ + info.var.width = -1; /*TBD unknown */ + + info.var.left_margin = TimingValues[DEFAULT_MODE].HFrontPorch; + info.var.right_margin = TimingValues[DEFAULT_MODE].HBackPorch; + info.var.upper_margin = TimingValues[DEFAULT_MODE].VFrontPorch; + info.var.lower_margin = TimingValues[DEFAULT_MODE].VBackPorch; + info.var.hsync_len = TimingValues[DEFAULT_MODE].HSyncWidth; + info.var.vsync_len = TimingValues[DEFAULT_MODE].VSyncWidth; + info.var.sync = 0; + info.var.vmode = FB_VMODE_NONINTERLACED; + + info.fix.line_length = info.var.xres_virtual * info.var.bits_per_pixel / 8; /* stride in bytes */ + + info.par = &TimingValues[DEFAULT_MODE]; + + ep93xxfb_par.screen_size = FB_MAX_MEM_SIZE; + ep93xxfb_par.palette_size = MAX_PALETTE_NUM_ENTRIES; + ep93xxfb_par.montype = 1; /*TBD why not 0 since single entry? */ + ep93xxfb_par.currcon = 0; /*TBD is this right? */ +} + +static int +ep93xxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) +{ + u_long flags, ulVIDEOATTRIBS; + unsigned int total, uiDevCfg, uiBMAR; +#ifdef CONFIG_FB_LCD_EP93XX + unsigned int uiPADDR, uiPADR; +#endif + struct DisplayTimingValues *pTimingValues; + + switch (var->bits_per_pixel) { + case 4: + ep93xxfb_par.visual = FB_VISUAL_PSEUDOCOLOR; + ep93xxfb_par.palette_size = 16; + break; + case 8: + ep93xxfb_par.visual = FB_VISUAL_PSEUDOCOLOR; + ep93xxfb_par.palette_size = 256; + break; + case 16: + ep93xxfb_par.visual = FB_VISUAL_TRUECOLOR; + ep93xxfb_par.palette_size = 16; + break; + case 24: + ep93xxfb_par.visual = FB_VISUAL_TRUECOLOR; + ep93xxfb_par.palette_size = 16; + break; + case 32: + ep93xxfb_par.visual = FB_VISUAL_TRUECOLOR; + ep93xxfb_par.palette_size = 16; + break; + default: + printk("ERROR! Bad bpp %d\n", var->bits_per_pixel); + return -EINVAL; + } + + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST) + return 0; + else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) && + ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN)) + return -EINVAL; + + pTimingValues = (struct DisplayTimingValues *)info->par; + + /* Disable interrupts and save status */ + local_irq_save(flags); + + printk("Configuring %dx%dx%dbpp\n", var->xres, var->yres, + var->bits_per_pixel); + + /* Disable the video and outputs while changing the video mode. */ + writel(0, VIDEOATTRIBS); + if (pTimingValues->RasterConfigure) { + pTimingValues->RasterConfigure((struct DisplayTimingValues *)info->par); /*pTimingValues); */ + } else { + total = var->vsync_len + var->upper_margin + var->yres + + var->lower_margin - 1; + + RasterSetLocked(VLINESTOTAL, total); + + RasterSetLocked(VSYNCSTRTSTOP, total - var->lower_margin + + ((total - + (var->lower_margin + var->vsync_len)) << 16)); + + RasterSetLocked(VACTIVESTRTSTOP, var->yres + (total << 16)); + + /* Reverse start/stop since N_VBLANK output + * unblanked same as active + */ + RasterSetLocked(VBLANKSTRTSTOP, var->yres + (total << 16)); + + RasterSetLocked(VCLKSTRTSTOP, total + (total << 16)); + + /* Now configure the Horizontal timings. */ + total = var->hsync_len + var->left_margin + var->xres + + var->right_margin - 1; + + RasterSetLocked(HCLKSTOTAL, total); + + RasterSetLocked(HSYNCSTRTSTOP, total + + ((total - var->hsync_len) << 16)); + + RasterSetLocked(HACTIVESTRTSTOP, total - var->hsync_len - + var->left_margin + + ((var->right_margin - 1) << 16)); + + RasterSetLocked(HBLANKSTRTSTOP, total - var->hsync_len - + var->left_margin + + ((var->right_margin - 1) << 16)); + + RasterSetLocked(HCLKSTRTSTOP, total + (total << 16)); + + RasterSetLocked(LINECARRY, 0); + + RasterSetLocked(VIDEOATTRIBS, + VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_SYNCEN | + VIDEOATTRIBS_DATAEN); + } + + /* Configure the Frame Buffer size. */ + writel((unsigned int)ep93xxfb_par.p_screen_base, VIDSCRNPAGE); + writel(var->yres, SCRNLINES); + + /* Set up the Line size. */ + total = var->xres * var->bits_per_pixel / 32; + writel((total - 1), LINELENGTH); + writel(total, VLINESTEP); + + switch (var->bits_per_pixel) { + case 8: + writel((0x8 | PIXELMODE_P_8BPP | PIXELMODE_C_LUT), PIXELMODE); + break; + case 16: + writel(0x8 | PIXELMODE_P_16BPP | + ((PIXELMODE_C_565) << (PIXELMODE_C_SHIFT)), PIXELMODE); + break; + case 24: + writel(0x8 | PIXELMODE_P_24BPP | + ((PIXELMODE_C_888) << (PIXELMODE_C_SHIFT)), PIXELMODE); + break; + case 32: + writel(0x8 | PIXELMODE_P_32BPP | + ((PIXELMODE_C_888) << (PIXELMODE_C_SHIFT)), PIXELMODE); + break; + default: + printk("ERROR! Bad bpp %d\n", var->bits_per_pixel); + return -EINVAL; + } + + uiDevCfg = readl(SYSCON_DEVCFG); + SysconSetLocked(SYSCON_DEVCFG, + ep93xx_SYSCON_DEVCFG(uiDevCfg | SYSCON_DEVCFG_RasOnP3)); + + if (pTimingValues->VDiv) + SysconSetLocked(SYSCON_VIDDIV, pTimingValues->VDiv); + + uiBMAR = readl(SYSCON_BMAR); + writel((uiBMAR | 1), SYSCON_BMAR); + + ulVIDEOATTRIBS = readl(VIDEOATTRIBS); + RasterSetLocked(VIDEOATTRIBS, ulVIDEOATTRIBS | VIDEOATTRIBS_EN | +#if (defined(CONFIG_MACH_ZEFEERDZG) || defined(CONFIG_MACH_ZEFEERDZN) || defined(CONFIG_MACH_ZEFEERDZQ)) + (1 << VIDEOATTRIBS_SDSEL_SHIFT)); +#else + (3 << VIDEOATTRIBS_SDSEL_SHIFT)); +#endif + + +#ifdef CONFIG_FB_LCD_EP93XX + uiPADDR = readl(GPIO_PADDR) | 0x2; + writel(uiPADDR, GPIO_PADDR); + + uiPADR = readl(GPIO_PADR) | 0x2; + writel(uiPADR, GPIO_PADR); +#endif + + local_irq_restore(flags); + return 0; +} + +int __init ep93xxfb_init(void) +{ + char *option = NULL; + DPRINTK("ep93xxfb_init(void)\n"); + + /* + * For kernel boot options (in 'video=xxxfb:' format) + */ + + fb_get_options("ep93xxfb", &option); + ep93xxfb_setup(option); + + /* init all the important stuff in info */ + if (!ep93xxfb_probe_configuration()) + ep93xxfb_init_fbinfo(); + + /* Allocate and map framebuffer memory in system DRAM */ + if (ep9312fb_map_video_memory() != 0) + return -ENOMEM; + + /* This has to been done !!! */ + fb_alloc_cmap(&info.cmap, MAX_PALETTE_NUM_ENTRIES, 0); + + /* hard code, since we don't support modedb & friends yet */ + ep93xxfb_set_var(&info.var, -1, &info); + + if (register_framebuffer(&info) < 0) + return -EINVAL; + + ep93xxfb_blank(FB_BLANK_UNBLANK, &info); + + printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, + info.fix.id); + + printk(KERN_INFO + "ep93xxfb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", + info.fix.smem_start, info.screen_base, info.fix.smem_len / 1024); + printk(KERN_INFO + "ep93xxfb: mode is %dx%dx%d, linelength=%d, pages=%d\n", + ep93xxfb_var.xres, ep93xxfb_var.yres, + ep93xxfb_var.bits_per_pixel, info.fix.line_length, + screen_info.pages); + + return 0; +} + +static void __exit ep93xxfb_cleanup(void) +{ + DPRINTK("ep93xxfb_cleanup(void)\n"); + unregister_framebuffer(&info); +} + +int __init ep93xxfb_setup(char *options) +{ + DPRINTK("ep93xxfb_setup(char *options=\"%s\")\n", options); + /* TODO: Parse user speficied options (`video=ep93xxfb:') */ + return 0; +} + +module_init(ep93xxfb_init); +module_exit(ep93xxfb_cleanup); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Burian"); diff --git a/drivers/video/ep93xxfb.h b/drivers/video/ep93xxfb.h new file mode 100644 index 0000000..dec4857 --- /dev/null +++ b/drivers/video/ep93xxfb.h @@ -0,0 +1,287 @@ +/* + * ep93xxfb.h Cirrus Logic EP93xx Framebuffer header + */ + +/* + * TODO: + * Still lot's of messy stuff here that belongs elsewhere. + * + * I'd say that each display / display family get an own header file + * maybe even the whole ep93xx stuff should get an own directory, just like ati + * It also could not hurt to test the NTSC stuff, which already was split into cx25871.c + * but not tested to work so far. + * + * Display initialisation should become human readable, it should be changed + * to reflect what's going on in hardware. + * + * This means we should say which PLL, prescaler, divider, ... is used instead + * of just saying VDIV = 0x0000c207, same goes for all the other hardcoded values. + * + * How will we handle higher clocked EP93xx once they are available? + * + */ + +#define RasterSetLocked(registername,value) \ + { \ + writel( 0xAA, REALITI_SWLOCK ); \ + writel( value, registername); \ + } + +static void InitializeCX25871For640x480NTSC(void); + +struct ep93xxfb_par { + struct device *dev; + dma_addr_t p_screen_base; + unsigned char *v_screen_base; + unsigned long screen_size; + unsigned int palette_size; + unsigned int xres; + unsigned int yres; + unsigned int bits_per_pixel; + signed int montype; + unsigned int currcon; + unsigned int visual; + u16 palette[16]; /* Funky 16 table lookup used by "optional" Parameter. */ +}; + +#define MAX_PALETTE_NUM_ENTRIES 256 +#define MAX_CRT_XRES 640 +#define MAX_CRT_YRES 480 +#define MAX_BPP 32 +#define FB_MAX_MEM_SIZE ((MAX_CRT_XRES * MAX_CRT_YRES * MAX_BPP)/8) +#define FB_MAPPED_MEM_SIZE (PAGE_ALIGN(FB_MAX_MEM_SIZE + PAGE_SIZE)) + +#define EP93XX_NAME "EP93XX" +#define NR_MONTYPES 1 + +/* Fake monspecs to fill in fbinfo structure */ +static struct fb_monspecs monspecs __initdata = { + {30000, 70000, 50, 65, 0} /* Generic */ +}; + +#if defined (CONFIG_FB_LCD_EP93XX) +#define DEFAULT_MODE 1 +#elif defined (CONFIG_FB_LCD_EP93XX_SHARP_LQ64D343) +#define DEFAULT_MODE 2 +#elif defined (CONFIG_FB_CX25871) +#define DEFAULT_MODE 3 +#elif defined (CONFIG_FB_CRT_EP93XX) +#define DEFAULT_MODE 0 +#elif defined (CONFIG_FB_LCD_EP93XX_SHARP) +#define DEFAULT_MODE 5 +#define CONFIG_FB_LCD_EP93XX 1 /*hack!!! FIXME: put whole display support into different files */ +#elif defined (CONFIG_FB_LCD_TX09D50VM1CCA) +#define DEFAULT_MODE 6 +#else +#error What Display Setting was that!!! +#endif + +struct DisplayTimingValues { + const char *Name; + unsigned long DisplayID; + int (*RasterConfigure) (struct DisplayTimingValues * pTimingValues); + unsigned short Refresh; + unsigned long VDiv; + + unsigned short HRes; + unsigned short HFrontPorch; + unsigned short HBackPorch; + unsigned short HSyncWidth; + unsigned short HTotalClocks; + + unsigned short VRes; + unsigned short VFrontPorch; + unsigned short VBackPorch; + unsigned short VSyncWidth; + unsigned short VTotalClocks; +}; + +typedef int (*fRasterConfigure) (struct DisplayTimingValues *); + +enum DisplayType { + CRT_GENERIC, + Philips_LB064V02A1, + CX25871, + Sharp +}; + +static int Conexant_CX25871(struct DisplayTimingValues *pTimingValues); +static int NecLCD(struct DisplayTimingValues *pTimingValues); + +#define TIMING_VALUES(NAME, DISPID, FUNC, REFRESH, VDIV, \ + HRES, HFP, HBP, HSYNC, VRES, VFP, VBP, VSYNC) \ +{ \ + Name:NAME, \ + DISPID, FUNC, REFRESH, VDIV, \ + HRES, HFP, HBP, HSYNC, (HRES + HFP + HBP + HSYNC), \ + VRES, VFP, VBP, VSYNC, (VRES + VFP + VBP + VSYNC) \ +} + +/* TODO: + * + * This is a big, confusing mess right now. + * We really should see if we can do it like Documentation/fb/modedb.txt + * suggests. + * + * Fix it, probably by moving this into ep93xx_modes.c or something like that + */ + +static struct DisplayTimingValues TimingValues[] = { + /* 640x480 Progressive Scan */ + TIMING_VALUES("CRT_GENERIC", CRT_GENERIC, + (fRasterConfigure) NULL, + 60, 0x0000c108, 640, 16, 48, 96, 480, 11, 31, 2), + /* 640x480 Progressive Scan Philips LB064V02A1 on EDB9312 Board. */ + + /* Display can handle clocks from 22MHz(VDIV=0xc107)-28Mhz(VDIV=0xc106) */ + TIMING_VALUES("Philips LB064V02A1", Philips_LB064V02A1, + 0, + 68, 0x0000c106, 640, 16, 48, 96, 480, 11, 31, 2), + /*fast refresh rate (26.7MHz) */ + /*68, 0x0000c106, 640, 16, 48, 96, 480, 11, 31, 2), */ + /*original setting (slowest refresh) (22.8MHz) */ + /*68, 0x0000c107, 640, 16, 48, 96, 480, 11, 31, 2), */ + + /* Sharp LQ64D343 LCD Panel */ + TIMING_VALUES("Sharp LQ64d343", CRT_GENERIC, + (fRasterConfigure) NULL, + 60, 0x0000c205, 640, 32, 32, 96, 480, 34, 34, 4), + /* NEC LCD Panel */ + TIMING_VALUES("NEC", CRT_GENERIC, + NecLCD, + 60, 0x0000c204, 640, 32, 32, 96, 480, 34, 34, 4), + /* 640x480 NTSC Support for Conexant CX25871 */ + TIMING_VALUES("Conexant CX25871", CX25871, + Conexant_CX25871, + 60, 0x0000c317, 640, 0, 0, 0, 480, 0, 0, 0), + /* 320x240 Sharp LCD Panel */ + TIMING_VALUES("Sharp LQ057Q3DC02", CRT_GENERIC, + (fRasterConfigure) NULL, + 0, 0x0000c108, 320, 32, 32, 96, 240, 3, 3, 4), + /* + 240x320 Hitachi + + Max pixel clock freq = 1/83ns ~= 12.048 MHz (VDiv = 0x0000c10a) + Typ pixel clock freq = 5.33 MHz (VDiv = 0x0000c125) + */ + TIMING_VALUES("Hitachi TX09D50VM1CCA", CRT_GENERIC, + (fRasterConfigure)NULL, + 0, 0x0000c125, 240, 16/*HFP*/, 12/*HBP*/, 5/*HSYNC*/, 320, 3/*VFP*/, 3/*VBP*/, 1/*VSYNC*/), + /* NULL */ + TIMING_VALUES("Unknown", CRT_GENERIC, + (fRasterConfigure) NULL, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + +}; + +#define NUM_TIMING_VALUES (sizeof(TimingValues)/sizeof(struct DisplayTimingValues)) + +#define NULL_MODE (NUM_TIMING_VALUES-1) + +#define EE_DELAY_USEC 100 +#define EE_READ_TIMEOUT 100 +#define CX25871_DEV_ADDRESS 0x88 +#define CX25871_REGx32_AUTO_CHK 0x80 +#define CX25871_REGx32_DRVS_MASK 0x60 +#define CX25871_REGx32_DRVS_SHIFT 5 +#define CX25871_REGx32_SETUP_HOLD 0x10 +#define CX25871_REGx32_INMODE_ 0x08 +#define CX25871_REGx32_DATDLY_RE 0x04 +#define CX25871_REGx32_OFFSET_RGB 0x02 +#define CX25871_REGx32_CSC_SEL 0x01 + +/* Register 0xBA */ +#define CX25871_REGxBA_SRESET 0x80 +#define CX25871_REGxBA_CHECK_STAT 0x40 +#define CX25871_REGxBA_SLAVER 0x20 +#define CX25871_REGxBA_DACOFF 0x10 +#define CX25871_REGxBA_DACDISD 0x08 +#define CX25871_REGxBA_DACDISC 0x04 +#define CX25871_REGxBA_DACDISB 0x02 +#define CX25871_REGxBA_DACDISA 0x01 + +/* Register 0xC4 */ +#define CX25871_REGxC4_ESTATUS_MASK 0xC0 +#define CX25871_REGxC4_ESTATUS_SHIFT 6 +#define CX25871_REGxC4_ECCF2 0x20 +#define CX25871_REGxC4_ECCF1 0x10 +#define CX25871_REGxC4_ECCGATE 0x08 +#define CX25871_REGxC4_ECBAR 0x04 +#define CX25871_REGxC4_DCHROMA 0x02 +#define CX25871_REGxC4_EN_OUT 0x01 + +/* Register 0xC6 */ +#define CX25871_REGxC6_EN_BLANKO 0x80 +#define CX25871_REGxC6_EN_DOT 0x40 +#define CX25871_REGxC6_FIELDI 0x20 +#define CX25871_REGxC6_VSYNCI 0x10 +#define CX25871_REGxC6_HSYNCI 0x08 +#define CX25871_REGxC6_INMODE_MASK 0x07 +#define CX25871_REGxC6_INMODE_SHIFT 0 + +#define GPIOG_EEDAT 2 +#define GPIOG_EECLK 1 + +static int Conexant_CX25871(struct DisplayTimingValues *pTimingValues) +{ + unsigned int uiTemp; + InitializeCX25871For640x480NTSC(); + + RasterSetLocked(VIDEOATTRIBS, 0); + uiTemp = readl(SYSCON_DEVCFG); + SysconSetLocked(SYSCON_DEVCFG, (uiTemp | SYSCON_DEVCFG_EXVC)); + + RasterSetLocked(VLINESTOTAL, 0x0257); + RasterSetLocked(VSYNCSTRTSTOP, 0x01FF022C); /* was 024c */ + RasterSetLocked(VBLANKSTRTSTOP, 0x000001E0); + RasterSetLocked(VACTIVESTRTSTOP, 0x000001E0); + RasterSetLocked(VCLKSTRTSTOP, 0x07FF01E0); + + RasterSetLocked(HCLKSTOTAL, 0x30F); + RasterSetLocked(HSYNCSTRTSTOP, 0x02c0030F); + RasterSetLocked(HBLANKSTRTSTOP, 0x00000280); + RasterSetLocked(HACTIVESTRTSTOP, 0x00000280); + RasterSetLocked(HCLKSTRTSTOP, 0x07ff0280); + + RasterSetLocked(LINECARRY, 0); + + RasterSetLocked(VIDEOATTRIBS, + VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN); + + return 0; +} + +static int NecLCD(struct DisplayTimingValues *pTimingValues) +{ + RasterSetLocked(VIDEOATTRIBS, 0); + + RasterSetLocked(VLINESTOTAL, 0x020c); + RasterSetLocked(VSYNCSTRTSTOP, 0x01fe0200); /* was 024c */ + RasterSetLocked(VBLANKSTRTSTOP, 0x0000000); + RasterSetLocked(VACTIVESTRTSTOP, 0x020c01df); + RasterSetLocked(VCLKSTRTSTOP, 0x020c020c); + + RasterSetLocked(HCLKSTOTAL, 0x323); + RasterSetLocked(HSYNCSTRTSTOP, 0x02c00321); + RasterSetLocked(HBLANKSTRTSTOP, 0x00000); + RasterSetLocked(HACTIVESTRTSTOP, 0x00100290); + RasterSetLocked(HCLKSTRTSTOP, 0x03230323); + + RasterSetLocked(LINECARRY, 0); + + RasterSetLocked(VIDEOATTRIBS, VIDEOATTRIBS_INVCLK | + VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_SYNCEN | + VIDEOATTRIBS_DATAEN); + + return 0; +} + +void InitializeCX25871For640x480NTSC(void) +{ +/* + * If you need this see cx25871.[ch] and grep for "should be done". + * see if you can find a suitable and less messy way to do i2c stuff + * also see our patch against 2.6.11.7-ep93xx + */ + printk("ERROR: InitializeCX25871For640x480NTSC unimplemented!\n"); +} diff --git a/include/asm-arm/arch-ep93xx/adssphere.h b/include/asm-arm/arch-ep93xx/adssphere.h new file mode 100644 index 0000000..97874c1 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/adssphere.h @@ -0,0 +1,55 @@ +/* + * linux/include/asm-arm/arch-ep93xx/adssphere.h + * + * Copyright (C) 2005 Robert Whaley + * + * 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 + */ +#ifndef ASM_ARCH_ADSSPHERE_H +#define ASM_ARCH_ADSSPHERE_H + +#define ADSSPHERE_BASE_VIRT 0xe2000000 +#define ADSSPHERE_BASE_PHYS 0xf0000000 + +#define ADSSPHERE_CR0 (ADSSPHERE_BASE_VIRT+0x00) +#define ADSSPHERE_CR1 (ADSSPHERE_BASE_VIRT+0x04) +#define ADSSPHERE_SR (ADSSPHERE_BASE_VIRT+0x08) +#define ADSSPHERE_CAN_ADDR (ADSSPHERE_BASE_VIRT+0x0c) +#define ADSSPHERE_CAN_DATA (ADSSPHERE_BASE_VIRT+0x10) +#define ADSSPHERE_FW_FW_NUM (ADSSPHERE_BASE_VIRT+0x14) +#define ADSSPHERE_FW_FW_REV (ADSSPHERE_BASE_VIRT+0x18) +#define ADSSPHERE_FW_BD_REV (ADSSPHERE_BASE_VIRT+0x1c) + +#define ADSSPHERE_CR0_CF_33 0x01 +#define ADSSPHERE_CR0_CF_50 0x02 +#define ADSSPHERE_CR0_COMEN 0x04 +#define ADSSPHERE_CR0_IRDA 0x08 +#define ADSSPHERE_CR0_USB 0x10 +#define ADSSPHERE_CR0_PWSAV 0x20 + +#define ADSSPHERE_CR1_PNL_ON 0x01 +#define ADSSPHERE_CR1_PNL_EN 0x04 +#define ADSSPHERE_CR1_BL_ON 0x08 +#define ADSSPHERE_CR1_AMP_ON 0x10 +#define ADSSPHERE_CR1_CDC_ON 0x20 +#define ADSSPHERE_CR1_BTL_ON 0x40 + +#define ADSSPHERE_SR1_SW0 0x01 +#define ADSSPHERE_SR1_SW1 0x02 +#define ADSSPHERE_SR1_SW2 0x04 +#define ADSSPHERE_SR1_SW3 0x08 +#define ADSSPHERE_SR1_HP 0x10 + +#endif /* ASM_ARCH_ADSSPHERE_H */ diff --git a/include/asm-arm/arch-ep93xx/clocks.h b/include/asm-arm/arch-ep93xx/clocks.h new file mode 100644 index 0000000..acc8023 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/clocks.h @@ -0,0 +1,160 @@ +/* + * + * Filename: clocks.h + * + * Description: Header file for the clocks. + * + * Copyright(c) Cirrus Logic Corporation 2003, 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#ifndef _H_CLOCKS +#define _H_CLOCKS + +/* + * How this file works: + * Choose your FCLOCK value this causes FDIV, HDIV, PDIV values to be set + * + * The Real FDIV, HDIV, and PDIV are set according to the following table. + * Processor runs at (PLL1 speed/PLL Divide specified by FDIV) + * AHB runs at (PLL1 speed/PLL Divide specified by HDIV) + * APB runs at AHB/(2^PDIV) + * ------------------------------------------------------------------ + * HDIV PLL Divide FDIV PLL Divide + * 0 1 0 1 + * 1 2 1 2 + * 2 4 2 4 + * 3 5 3 8 + * 4 6 4 16 + * 5 8 + * 6 16 + * 7 32 + * + */ + +/* there is some confusion here about MACH vs. ARCH. clean it up + once we get a nice clock management system going */ +#ifdef CONFIG_ARCH_EP9301 +#define FCLOCK 166 +#define EP93XX_UART_CLK 14745600 +#endif + +#ifdef CONFIG_MACH_EDB9302 +#define FCLOCK 200 +#define EP93XX_UART_CLK 14745600 +#endif + +#if defined(CONFIG_MACH_EDB9312) || defined(CONFIG_MACH_EDB9315) || defined(CONFIG_MACH_ADSSPHERE) +#define FCLOCK 200 +#define EP93XX_UART_CLK 14745600 +#endif + +#if defined(CONFIG_MACH_DMA03) +#define FCLOCK 200 +#define EP93XX_UART_CLK 14745600 +#endif + +#ifdef CONFIG_MACH_ACC +#define EP93XX_UART_CLK 24576000 +#endif + +#if defined(CONFIG_MACH_ZEFEERDZA) +#define FCLOCK 166 +#define EP93XX_UART_CLK 14745600 +#endif + +#if defined(CONFIG_MACH_ZEFEERDZB) || defined(CONFIG_MACH_ZEFEERDZG) || \ + defined(CONFIG_MACH_ZEFEERDZN) || defined(CONFIG_MACH_ZEFEERDZQ) +#define FCLOCK 200 +#define EP93XX_UART_CLK 14745600 +#endif + +/* + * PLL1 Clock =442 Mhz + * + * FClock = 221 Mhz + * HCLock = 73 Mhz + * PClock = 46 Mhz + */ +#if (FCLOCK == 221) +#define FDIV 1 +#define HDIV 5 +#define PDIV 1 +#define PRE_CLKSET1_VALUE 0x0080b3b6 +#define PLL1_CLOCK 442368000 +#endif /* (FCLOCK == 221) */ + +/* + * PLL1 Clock =400 Mhz + * + * FClock = 200 Mhz + * HCLock = 100 Mhz + * PClock = 50 Mhz + * + */ +#if (FCLOCK == 200) +#define FDIV 1 +#define HDIV 2 +#define PDIV 1 +#define PRE_CLKSET1_VALUE 0x0080a3d7 +#define PLL1_CLOCK 399974400 +#endif /* (FCLOCK == 200) */ + +/* + * PLL1 Clock =368 Mhz + * + * FClock = 184 Mhz + * HCLock = 73 Mhz + * PClock = 46 Mhz + * + */ +#if (FCLOCK == 183) +#define FDIV 1 +#define HDIV 4 +#define PDIV 1 +#define PRE_CLKSET1_VALUE 0x0080ab15 +#define PLL1_CLOCK 368640000 +#endif /* (FCLOCK == 183) */ + +/* + * PLL1 Clock =332 Mhz + * + * FClock = 166 Mhz + * HCLock = 66 Mhz + * PClock = 33 Mhz + * + */ +#if (FCLOCK == 166) +#define FDIV 1 +#define HDIV 3 +#define PDIV 1 +#define PRE_CLKSET1_VALUE 0x0080fa5a +#define PLL1_CLOCK 332049067 +#endif /* (FCLOCK == 166) */ + +#define CLKSET1_VALUE ( PRE_CLKSET1_VALUE | \ + ( PDIV << SYSCON_CLKSET1_PCLK_DIV_SHIFT ) | \ + ( HDIV << SYSCON_CLKSET1_HCLK_DIV_SHIFT ) | \ + ( FDIV << SYSCON_CLKSET1_FCLK_DIV_SHIFT ) ) + +/* + * Value for the PLL 2 register. + */ +#define CLKSET2_VALUE 0x300dc317 +#define PLL2_CLOCK 192000000 + +#endif /* _H_CLOCKS */ diff --git a/include/asm-arm/arch-ep93xx/crunch.h b/include/asm-arm/arch-ep93xx/crunch.h new file mode 100644 index 0000000..db9fb2e --- /dev/null +++ b/include/asm-arm/arch-ep93xx/crunch.h @@ -0,0 +1,48 @@ +#ifndef __asm_crunch_h__ +#define __asm_crunch_h__ + +#define CRUNCH_INIT 0x00900000 +#define CRUNCH_IRQ 58 + +#ifndef __ASSEMBLY__ + +/* enable the MaverickCrunch clock */ +static inline void crunch_enable(void) +{ + int tmp, aa = 0xAA; + int *lock = (int *)0xe09300c0; + int *syscfg = (int *)0xe0930080; + + asm volatile ("str %3, [%1]\n\t" + "ldr %0, [%2]\n\t" + "orr %0, %0, #(1 << 23)\n\t" + "str %0, [%2]":"=r" (tmp) + :"r"(lock), "r"(syscfg), "r"(aa) + :"memory"); +} + +/* disable the MaverickCrunch clock */ +static inline void crunch_disable(void) +{ + int tmp, aa = 0xAA; + int *lock = (int *)0xe09300c0; + int *syscfg = (int *)0xe0930080; + + asm volatile ("str %3, [%1]\n\t" + "ldr %0, [%2]\n\t" + "bic %0, %0, #(1 << 23)\n\t" + "str %0, [%2]":"=r" (tmp) + :"r"(lock), "r"(syscfg), "r"(aa) + :"memory"); +} + +unsigned int read_dspsc_low(void); +unsigned int read_dspsc_high(void); +void write_dspsc(unsigned int); +void save_fpu(struct task_struct *); +void restore_fpu(struct task_struct *); +int setup_crunch(void); +void crunch_init(void); +#endif + +#endif /* __asm_crunch_h__ */ diff --git a/include/asm-arm/arch-ep93xx/cx25871.h b/include/asm-arm/arch-ep93xx/cx25871.h new file mode 100644 index 0000000..9d68ed9 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/cx25871.h @@ -0,0 +1,69 @@ +/* + * Filename: cx25871.h + * + * Description: Regisister Definitions and function prototypes for + * CX25871 NTSC/PAL encoder. + * + * Copyright(c) Cirrus Logic Corporation 2003, 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 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 + */ + +#ifndef _H_CX25871 +#define _H_CX25871 + +/* CS25871 Device Address. */ +#define CX25871_DEV_ADDRESS 0x88 + +/* Register 0x32 */ +#define CX25871_REGx32_AUTO_CHK 0x80 +#define CX25871_REGx32_DRVS_MASK 0x60 +#define CX25871_REGx32_DRVS_SHIFT 5 +#define CX25871_REGx32_SETUP_HOLD 0x10 +#define CX25871_REGx32_INMODE_ 0x08 +#define CX25871_REGx32_DATDLY_RE 0x04 +#define CX25871_REGx32_OFFSET_RGB 0x02 +#define CX25871_REGx32_CSC_SEL 0x01 + +/* Register 0xBA */ +#define CX25871_REGxBA_SRESET 0x80 +#define CX25871_REGxBA_CHECK_STAT 0x40 +#define CX25871_REGxBA_SLAVER 0x20 +#define CX25871_REGxBA_DACOFF 0x10 +#define CX25871_REGxBA_DACDISD 0x08 +#define CX25871_REGxBA_DACDISC 0x04 +#define CX25871_REGxBA_DACDISB 0x02 +#define CX25871_REGxBA_DACDISA 0x01 + +/* Register 0xC4 */ +#define CX25871_REGxC4_ESTATUS_MASK 0xC0 +#define CX25871_REGxC4_ESTATUS_SHIFT 6 +#define CX25871_REGxC4_ECCF2 0x20 +#define CX25871_REGxC4_ECCF1 0x10 +#define CX25871_REGxC4_ECCGATE 0x08 +#define CX25871_REGxC4_ECBAR 0x04 +#define CX25871_REGxC4_DCHROMA 0x02 +#define CX25871_REGxC4_EN_OUT 0x01 + +/* Register 0xC6 */ +#define CX25871_REGxC6_EN_BLANKO 0x80 +#define CX25871_REGxC6_EN_DOT 0x40 +#define CX25871_REGxC6_FIELDI 0x20 +#define CX25871_REGxC6_VSYNCI 0x10 +#define CX25871_REGxC6_HSYNCI 0x08 +#define CX25871_REGxC6_INMODE_MASK 0x07 +#define CX25871_REGxC6_INMODE_SHIFT 0 + +#endif diff --git a/include/asm-arm/arch-ep93xx/debug-macro.S b/include/asm-arm/arch-ep93xx/debug-macro.S new file mode 100644 index 0000000..3d97614 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/debug-macro.S @@ -0,0 +1,56 @@ +/* linux/include/asm-arm/arch-ep93xx/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ray Lehtiniemi + * + * 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. + * +*/ + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =IO_BASE_PHYS @ System peripherals (phys address) + ldrne \rx, =IO_BASE_VIRT @ System peripherals (virt address) + orr \rx,\rx,#0x008c0000 @ Advance to UART1Base + + @ We probe for the active serial port here. + @ We assume r1 can be clobbered. + + @ see if UART1 is active + ldr r1, [\rx, #0x14] @UART1Ctrl + tst r1, #1 + + @ if UART1 is inactive advance to UART2 + addeq \rx, \rx, #0x00010000 + ldreq r1, [\rx, #0x14] @UART2Ctrl + tsteq r1, #1 + + @ if UART2 is inactive advance to UART3 + addeq \rx, \rx, #0x00010000 + ldreq r1, [\rx, #0x14] @UART3Ctrl + tsteq r1, #1 + + @ if all ports are inactive, then there is nothing we can do + moveq pc, lr + .endm + + .macro senduart,rd,rx + strb \rd, [\rx] @ UARTxData + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTxFlag + tst \rd, #0x20 @ TXFF = 0 when ok to transmit + bne 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTxFlag + tst \rd, #0x08 @ BUSY = 1 while transmitting + bne 1001b + .endm diff --git a/include/asm-arm/arch-ep93xx/dma.h b/include/asm-arm/arch-ep93xx/dma.h new file mode 100644 index 0000000..d3b6493 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/dma.h @@ -0,0 +1,233 @@ +/***************************************************************************** + * linux/include/asm-arm/arch-ep93xx/dma.h + * + * Copyright (C) 2003 Cirrus Logic + * + * 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 + * + ****************************************************************************/ +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#define MAX_DMA_ADDRESS 0xffffffff + +/* + * Not using the regular generic DMA interface for ep93xx. + */ +#define MAX_DMA_CHANNELS 0 + +/* + * The ep93xx dma controller has 5 memory to peripheral (TX) channels, 5 + * peripheral to memory (RX) channels and 2 memory to memory channels. + */ +#define MAX_EP93XX_DMA_M2P_CHANNELS 10 +#define MAX_EP93XX_DMA_M2M_CHANNELS 2 + +/* + * The generic arm linux api does not support the ep93xx dma model, therefore + * we use a set of dma support functions written specifically for this dma + * controller. + */ +#define MAX_EP93XX_DMA_CHANNELS (MAX_EP93XX_DMA_M2P_CHANNELS + MAX_EP93XX_DMA_M2M_CHANNELS) + +/***************************************************************************** + * + * Max DMA buffer size + * + ****************************************************************************/ +#define DMA_MAX_BUFFER_BYTES 0xFFFF + +/***************************************************************************** + * + * typedefs + * + ****************************************************************************/ + +/***************************************************************************** + * + * All devices which can use a DMA channel + * + * NOTE: There exist two types of DMA channels, those that transfer + * between an internal peripheral and memory (M2P/P2M), and + * those that transfer between an external peripheral and memory (M2M). + * This becomes a bit confusing when you take into account the fact + * that the M2M channels can also transfer between two specific + * internal peripherals and memory. + * The first 20 enumerated devices use the first type of channel (M2P/ + * P2M). The last six enumerations are specific to the M2M channels. + * + ****************************************************************************/ +typedef enum { + /* + * Hardware device options for the 10 M2P/P2M DMA channels. + */ + DMATx_I2S1 = 0x00000000, /* TX peripheral ports can be allocated an */ + DMATx_I2S2 = 0x00000001, /* even numbered DMA channel. */ + DMATx_AAC1 = 0x00000002, + DMATx_AAC2 = 0x00000003, + DMATx_AAC3 = 0x00000004, + DMATx_I2S3 = 0x00000005, + DMATx_UART1 = 0x00000006, + DMATx_UART2 = 0x00000007, + DMATx_UART3 = 0x00000008, + DMATx_IRDA = 0x00000009, + DMARx_I2S1 = 0x0000000A, /* RX perhipheral ports can be allocated an */ + DMARx_I2S2 = 0x0000000B, /* odd numbered DMA channel. */ + DMARx_AAC1 = 0x0000000C, + DMARx_AAC2 = 0x0000000D, + DMARx_AAC3 = 0x0000000E, + DMARx_I2S3 = 0x0000000F, + DMARx_UART1 = 0x00000010, + DMARx_UART2 = 0x00000011, + DMARx_UART3 = 0x00000012, + DMARx_IRDA = 0x00000013, + + /* + * Device options for the 2 M2M DMA channels + */ + DMA_MEMORY = 0x00000014, + DMA_IDE = 0x00000015, + DMARx_SSP = 0x00000016, + DMATx_SSP = 0x00000017, + DMATx_EXT_DREQ = 0x00000018, + DMARx_EXT_DREQ = 0x00000019, + UNDEF = 0x0000001A +} ep93xx_dma_dev_t; + +/***************************************************************************** + * + * Enumerated type used as a parameter for a callback function. + * Indicates the type of interrupt. + * + ****************************************************************************/ +typedef enum { + /* + * Common interrupts + */ + STALL, + NFB, + + /* + * Specific to M2P channels + */ + CHERROR, + + /* + * Specific to M2M channels + */ + DONE, + UNDEF_INT +} ep93xx_dma_int_t; + +/***************************************************************************** + * + * Init flag bit defintions for M2P/P2M flags. + * + ****************************************************************************/ + +/* + * Channel error interrupt enable. + */ +#define CHANNEL_ERROR_INT_ENABLE 0x00000001 +/* + * Determines how the channel state machine behaves in the NEXT state and + * in receipt of a peripheral error. + * 0 -> NEXT -> ON (ignore the peripheral error.) + * 1 -> NEXT -> STALL (effectively disable the channel.) + */ +#define EP93XX_DMA_ABORT 0x00000002 +/* + * Ignore channel error interrupt. + */ +#define IGNORE_CHANNEL_ERROR 0x00000004 + +/***************************************************************************** + * + * Init flag bit defintions for M2M flags. + * + ****************************************************************************/ + +/* + * Destination address hold. This should be set for IDE write transfers + */ +#define DESTINATION_HOLD 0x0000001 +/* + * Source Address hold. This should be set for IDE read transfers + */ +#define SOURCE_HOLD 0x0000002 +/* + * Transfer mode. + * 00 - s/w initiated M2M transfer + * 01 - h/w initiated external peripheral transfer - memory to external + * peripheral/IDE/SSP. + * 10 - h/w initiated external peripheral transfer - external + * peripheral/IDE/SSP to memory. + * 11 - not used. + */ +#define TRANSFER_MODE_MASK 0x000000C +#define TRANSFER_MODE_SHIFT 2 +#define TRANSFER_MODE_SW 0x0000000 +#define TRANSFER_MODE_HW_M2P 0x0000004 +#define TRANSFER_MODE_HW_P2M 0x0000008 +/* + * Peripheral wait states count. Latency in HCLK cycles needed by the + * peripheral to de-assert its request line once the transfer is + * finished. + * + * IDE Operation Wait States + * -------------- ------------ + * IDE MDMA read 0 + * IDE MDMA write 0 + * IDE UDMA read 1 + * IDE UDMA write 2 + */ +#define WAIT_STATES_MASK 0x00007F0 +#define WAIT_STATES_SHIFT 4 +#define WS_IDE_MDMA_READ_WRITE 0 +#define WS_IDE_UDMA_READ 1 +#define WS_IDE_UDMA_WRITE 2 + +/***************************************************************************** + * + * Type definition for the callback function + * + ****************************************************************************/ +typedef void (*dma_callback) (ep93xx_dma_int_t dma_int, + ep93xx_dma_dev_t device, unsigned int user_data); + +/***************************************************************************** + * + * API function prototypes + * + ****************************************************************************/ +extern int ep93xx_dma_request(int *handle, const char *device_id, + ep93xx_dma_dev_t device); +extern int ep93xx_dma_free(int handle); +extern int ep93xx_dma_config(int handle, unsigned int flags_m2p, + unsigned int flags_m2m, + dma_callback callback, unsigned int user_data); +extern int ep93xx_dma_add_buffer(int handle, unsigned int source, + unsigned int dest, unsigned int size, + unsigned int last, unsigned int buf_id); +extern int ep93xx_dma_remove_buffer(int handle, unsigned int *buf_id); +extern int ep93xx_dma_start(int handle, unsigned int channels, + unsigned int *handles); +extern int ep93xx_dma_pause(int handle, unsigned int channels, + unsigned int *handles); +extern int ep93xx_dma_flush(int handle); +extern int ep93xx_dma_queue_full(int handle); +extern int ep93xx_dma_get_position(int handle, unsigned int * buf_id, + unsigned int * total, unsigned int * current_frac); +#endif /* _ASM_ARCH_DMA_H */ diff --git a/include/asm-arm/arch-ep93xx/entry-macro.S b/include/asm-arm/arch-ep93xx/entry-macro.S new file mode 100644 index 0000000..cab811e --- /dev/null +++ b/include/asm-arm/arch-ep93xx/entry-macro.S @@ -0,0 +1,39 @@ +/* + * include/asm-arm/arch-ep93xx/entry-macro.S + * + * Low-level IRQ helper macros for EP93XX-based platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqstat, =VIC0IRQSTATUS + ldr \irqstat, [\irqstat, #0] @ get masked status + + mov \irqnr, #0 +1001: tst \irqstat, #1 + bne 1003f + add \irqnr, \irqnr, #1 + mov \irqstat, \irqstat, lsr #1 + cmp \irqnr, #32 + bcc 1001b + /* EQ will be set if we reach 32 */ + + ldr \irqstat, =VIC1IRQSTATUS + ldr \irqstat, [\irqstat, #0] @ get masked status + +1002: tst \irqstat, #1 + bne 1003f + add \irqnr, \irqnr, #1 + mov \irqstat, \irqstat, lsr #1 + cmp \irqnr, #64 + bcc 1002b + /* EQ will be set if we reach 64 */ + +1003: + .endm diff --git a/include/asm-arm/arch-ep93xx/hardware.h b/include/asm-arm/arch-ep93xx/hardware.h new file mode 100644 index 0000000..f390858 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/hardware.h @@ -0,0 +1,60 @@ +/* + * File: linux/include/asm-arm/arch-ep93xx/hardware.h + * + * Copyright (C) 2003 Cirrus Logic, Inc + * + * Copyright (C) 1999 ARM Limited. + * + * 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 + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include +#include +#include + +/* + * When adding your regs-*.h file here, please be careful to not have any + * macros being doubly defined. You may need to comment out a section of + * regmap.h to prevent that. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +/* + * Here's a safe way for calculating jiffies that won't break if the + * value of HZ changes. + */ +#ifndef MSECS_TO_JIFFIES +#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000) +#endif + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-ep93xx/ide.h b/include/asm-arm/arch-ep93xx/ide.h new file mode 100644 index 0000000..7eb7faa --- /dev/null +++ b/include/asm-arm/arch-ep93xx/ide.h @@ -0,0 +1,235 @@ +/***************************************************************************** + * linux/include/asm-arm/arch-ep93xx/ide.h + * + * IDE definitions for the EP93XX architecture + * + * + * Copyright (c) 2003 Cirrus Logic, Inc., 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 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 + * + ****************************************************************************/ +#ifndef ASM_ARCH_IDE_H +#define ASM_ARCH_IDE_H +#include +#include +#include +#include + +/* + * Maximum number of IDE interfaces for this architecture is 1. + */ +#ifdef CONFIG_BLK_DEV_EP93XX +#undef MAX_HWIFS +#define MAX_HWIFS 1 +#endif +/* + * Default PIO mode used for setting up DMA commands + */ +#define DEFAULT_PIO_MODE 4 + +/* + * ATA Command Register addresses. + */ + +#define DATAREGISTER 0x00 +#define ERRORREGISTER 0x01 +#define FEATURESREGISTER 0x01 +#define SECTORCOUNTREGISTER 0x02 +#define SECTORNUMBERREGISTER 0x03 +#define CYLINDERLOWREGISTER 0x04 +#define CYLINDERHIGHREGISTER 0x05 +#define DEVICEHEADREGISTER 0x06 +#define COMMANDREGISTER 0x07 +#define STATUSREGISTER 0x07 + +/* + * ATA Control Register addresses. + */ +#define DEVICECONTROLREGISTER 0x06 +#define ALTERNATESTATUSREGISTER 0x06 + +/* + * ATA Register Bit Masks + */ +#define ATASRST 0x04 +#define ATAnIEN 0x02 +#define ATADEV 0x10 +#define ATAABRT 0x04 +#define ATABSY 0x80 +#define ATADRDY 0x40 +#define ATADRQ 0x08 +#define ATAERR 0x01 +#define ATADEVFAULT 0x20 +#define ATAWRITEFAULT 0x20 +#define ATASERVICE 0x10 +#define ATACORRECTED 0x04 +#define ATAINDEX 0x02 + +#ifdef CONFIG_BLK_DEV_IDEDMA_EP93XX + +#define EP93XX_DMA_TODEVICE 1 +#define EP93XX_DMA_FROMDEVICE 2 + +/**************************************************************************** + * + * Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + * + ****************************************************************************/ +static inline int +ep93xx_map_sg(struct scatterlist *sg, unsigned int entries, + unsigned int direction) +{ + unsigned int loop; + + for (loop = 0; loop < entries; loop++, sg++) { + consistent_sync(sg->__address, sg->length, direction); + sg->dma_address = virt_to_bus(sg->__address); + } + + return entries; +} + +#endif /* CONFIG_BLK_DEV_IDEDMA_EP93XX */ + +/***************************************************************************** + * + * Set up a hw structure for a specified data port, control port and IRQ. + * This should follow whatever the default interface uses. + * + ****************************************************************************/ +static __inline__ void +old_ide_init_hwif_ports(hw_regs_t * hw, int data_port, int ctrl_port, int *irq) +{ + unsigned long reg; + int i; + printk("ide_init_hwif_ports\n"); + printk("ide_init_hwif_ports(hw=%p data_port=%08x, ctrl_port=%08x \n", + hw, data_port, ctrl_port); + + /* + * Set up the IDE interface for PIO transfers, using the default PIO + * mode. + */ + ep93xx_ide_regs->IDECFG.Field.PIO = 1; + ep93xx_ide_regs->IDECFG.Field.MODE = DEFAULT_PIO_MODE; + ep93xx_ide_regs->IDECFG.Field.WST = 0; + + /* + * Enable the IDE interface. + */ + ep93xx_ide_regs->IDECFG.Field.IDEEN = 1; + + /* + * Set up the ide device command register offsets in the io_port array. + * This offset includes the register offset and the bit settings for + * CS0n and CS1n. + */ + reg = (unsigned long)data_port; + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = (reg << 2) + 2; + reg += 1; + + printk(" io_ports: %08lx\n", hw->io_ports[i]); + } + + /* + * Set up the register offset for the device control registers. + * This offset includes the register offset and the bit settings for + * CS0n and CS1n. + */ + reg = (unsigned long)ctrl_port; + hw->io_ports[IDE_CONTROL_OFFSET] = (reg << 2) + 1; + printk("-io_ports: %08lx\n", hw->io_ports[IDE_CONTROL_OFFSET]); + + if (irq) + *irq = 0; + +} + +extern void ep93xx_ide_init(struct hwif_s *hwif); + +/***************************************************************************** + * + * This registers the standard ports for this architecture with the IDE + * driver. + * + ****************************************************************************/ +static __inline__ void old_ide_init_default_hwifs(void) +{ + hw_regs_t hw; + + struct hwif_s *hwif; + unsigned int uiTemp; + + /* + * Make sure the GPIO on IDE bits in the DEVCFG register are not set. + */ + uiTemp = + readl(SYSCON_DEVCFG) & ~(SYSCON_DEVCFG_EonIDE | + SYSCON_DEVCFG_GonIDE | + SYSCON_DEVCFG_HonIDE); + + SysconSetLocked(SYSCON_DEVCFG, uiTemp); + + /* + * Initialize the IDE interface + */ + old_ide_init_hwif_ports(&hw, DATAREGISTER, DEVICECONTROLREGISTER, NULL); + + /* + * Get the interrupt. + */ + hw.irq = IRQ_EIDE; + + /* + * This is the dma channel number assigned to this IDE interface. Until + * dma is enabled for this interface, we set it to NO_DMA. + */ + hw.dma = NO_DMA; + + /* + * Kernels > 2.6.15-rcX crash when leaving this uninitialized + */ + hw.dev = NULL; + + /* + * Register the IDE interface, an ide_hwif_t pointer is passed in, + * which will get filled in with the hwif pointer for this interface. + */ + ide_register_hw(&hw, &hwif); + + /* + * Set up a pointer to the ep93xx ideproc function. + */ + ep93xx_ide_init(hwif); + + printk + ("Cirrus Logic EP93XX IDE initialization - driver version 1.0, 5/21/03. \n"); +} +#endif /* ASM_ARCH_IDE_H */ diff --git a/include/asm-arm/arch-ep93xx/io.h b/include/asm-arm/arch-ep93xx/io.h new file mode 100644 index 0000000..7e2e087 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/io.h @@ -0,0 +1,29 @@ +/* + * File: linux/include/asm-arm/arch-ep93xx/io.h + * + * Copyright (C) 1999 ARM Limited + * + * 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 + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) ((void __iomem *)(a)) +#define __mem_pci(a) (a) +#define __mem_isa(a) (a) + +#endif diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h new file mode 100644 index 0000000..7a58d27 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/irqs.h @@ -0,0 +1,150 @@ +/* + * File: linux/include/asm-arm/arch-ep93xx/irqs.h + * + * 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 + */ + +/* + * Linux IRQ interrupts definitions here. + * TBD not worth the effort to put duplicate bit defines in platform.h + * + * Current IRQ implementation + * + * 1. Current implementation does not support vectored + * interrupts. support for this feature may be + * added later. + * 2. FIQs are ignored. None are assigned. + * 3. All interrupts are assigned to IRQs. + * 5. IRQ numbers are same as interrupt bit numbers. + * + */ + +/* First two interrupt bit assignments are unused. */ +#define IRQ_RFU0 0 +#define IRQ_RFU1 1 + +#define IRQ_COMMRX 2 +#define IRQ_COMMTX 3 + +/* Renamed TCXOI to TIMERX for consistency */ +#define IRQ_TIMER1 4 +#define IRQ_TIMER2 5 + +#define IRQ_AAC 6 + +#define IRQ_DMAM2P0 7 +#define IRQ_DMAM2P1 8 +#define IRQ_DMAM2P2 9 +#define IRQ_DMAM2P3 10 +#define IRQ_DMAM2P4 11 +#define IRQ_DMAM2P5 12 +#define IRQ_DMAM2P6 13 +#define IRQ_DMAM2P7 14 +#define IRQ_DMAM2P8 15 +#define IRQ_DMAM2P9 16 + +#define IRQ_DMAM2M0 17 +#define IRQ_DMAM2M1 18 + +#define IRQ_GPIO0 19 +#define IRQ_GPIO1 20 +#define IRQ_GPIO2 21 +#define IRQ_GPIO3 22 + +#define IRQ_UARTRX1 23 +#define IRQ_UARTTX1 24 +#define IRQ_UARTRX2 25 +#define IRQ_UARTTX2 26 +#define IRQ_UARTRX3 27 +#define IRQ_UARTTX3 28 + +#define IRQ_KEY 29 +#define IRQ_TOUCH 30 +#define IRQ_GRAPHICS 31 + +/* TODO - this was IRQ_INTX, may need to make changes in code */ +#define IRQ_EXT0 32 +#define IRQ_EXT1 33 +#define IRQ_EXT2 34 + +#define IRQ_64HZ 35 +#define IRQ_WEINT 36 +#define IRQ_RTC 37 + +#define IRQ_IRDA 38 +#define IRQ_MAC 39 + +#define IRQ_EXT3 40 +#define IRQ_EIDE IRQ_EXT3 + +#define IRQ_PROG 41 +#define IRQ_1HZ 42 +#define IRQ_VSYNC 43 +#define IRQ_VIDEOFIFO 44 + +#define IRQ_SSPRX 45 +#define IRQ_SSPTX 46 + +#define IRQ_GPIO4 47 + +#define IRQ_GPIO5 48 +#define IRQ_GPIO6 49 +#define IRQ_GPIO7 50 + +#define IRQ_TIMER3 51 + +#define IRQ_UART1 52 +#define IRQ_SSP 53 + +#define IRQ_UART2 54 +#define IRQ_UART3 55 + +#define IRQ_USH 56 +#define IRQ_PME 57 +#define IRQ_DSP 58 +#define IRQ_GPIO 59 + +#define IRQ_RFU60 60 +#define IRQ_RFU61 61 +#define IRQ_RFU62 62 +#define IRQ_RFU63 63 + +#ifdef CONFIG_ARCH_EP93XX_GPIO_IRQ +#define IRQ_TO_BIT(irq) (1 << ((irq - NR_GLBL_IRQS) % 16)) + +#define NR_GLBL_IRQS 64 + +#define GPIO_IRQ0 64 +#define GPIO_IRQ1 65 +#define GPIO_IRQ2 66 +#define GPIO_IRQ3 67 +#define GPIO_IRQ4 68 +#define GPIO_IRQ5 69 +#define GPIO_IRQ6 70 +#define GPIO_IRQ7 71 +#define GPIO_IRQ8 72 +#define GPIO_IRQ9 73 +#define GPIO_IRQ10 74 +#define GPIO_IRQ11 75 +#define GPIO_IRQ12 76 +#define GPIO_IRQ13 77 +#define GPIO_IRQ14 78 +#define GPIO_IRQ15 79 + +#define IRQ_CHAINED_GPIO(x) (NR_GLBL_IRQS + x) +#define NR_IRQS IRQ_CHAINED_GPIO(16) /* with GPIO IRQs EP9315 has 80 IRQs */ +#else +#define NR_IRQS 64 /* without GPIO IRQs EP9315 has 64 IRQs */ +#endif diff --git a/include/asm-arm/arch-ep93xx/keyboard.h b/include/asm-arm/arch-ep93xx/keyboard.h new file mode 100644 index 0000000..685ff17 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/keyboard.h @@ -0,0 +1,54 @@ +/* + * linux/include/asm-arm/arch-integrator/keyboard.h + * + * Copyright (C) 2000-2001 Deep Blue Solutions Ltd. + * + * 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. + * + * 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 + * + * Keyboard driver definitions for the Integrator architecture + */ +#include + +/* Scancode mapping is as follows: + * + * Scancode = keycode if key down event + * Scancode = keycode|KBUP if key up event + * + * Valid keycodes are 1..0x7F and are defined by the table + * in keymap_dave.map. Keycode 0 is reserved to mean invalid. + * + * Keycodes are computed from scanned key matrix as follows: + */ + +#define KEYCODE( row, col) ( ((row)<<4) + (col) + 1) +#define KBUP 0x80 +#define NR_SCANCODES 128 /*TBD used? */ + +#ifdef CONFIG_EP93XX_KBD_SCANNED +void __init ep93xx_scan_kbd_hw_init(void); +#define kbd_init_hw() ep93xx_scan_kbd_hw_init() +#elif defined CONFIG_EP93XX_KBD_SPI +void __init EP93XXSpiKbdInit(void); +#define kbd_init_hw() EP93XXSpiKbdInit() +#elif defined CONFIG_EP93XX_KBD_USB +void __init EP93XXUSBKbdInit(void); +#define kbd_init_hw() EP93XXUSBKbdInit() +#endif + +#ifdef kbd_sysrq_xlate +#undef kbd_sysrq_xlate +#define kbd_sysrq_xlate (1) +#endif +#define kbd_disable_irq() disable_irq( IRQ_KEY) +#define kbd_enable_irq() enable_irq( IRQ_KEY) diff --git a/include/asm-arm/arch-ep93xx/mach-edb9302.h b/include/asm-arm/arch-ep93xx/mach-edb9302.h new file mode 100644 index 0000000..829883a --- /dev/null +++ b/include/asm-arm/arch-ep93xx/mach-edb9302.h @@ -0,0 +1,20 @@ +/* + * linux/include/asm-arm/arch-ep93xx/mach-edb9302.h + * + * Copyright 2004 Ray Lehtiniemi + * Copyright 2004 Siconix, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __ASM_ARCH_MACHEDB9302_H +#define __ASM_ARCH_MACHEDB9302_H + +#include + +extern struct ep93xx_ssp_slave ep93xx_ssp_flash; +extern struct ep93xx_ssp_slave ep93xx_ssp_codec; + +#endif diff --git a/include/asm-arm/arch-ep93xx/mach-ttml.h b/include/asm-arm/arch-ep93xx/mach-ttml.h new file mode 100644 index 0000000..665873d --- /dev/null +++ b/include/asm-arm/arch-ep93xx/mach-ttml.h @@ -0,0 +1,23 @@ +/* + * linux/include/asm-arm/arch-ep93xx/mach-ttml.h + * + * Copyright 2004 Ray Lehtiniemi + * Copyright 2004 Siconix, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __ASM_ARCH_MACHTTML_H +#define __ASM_ARCH_MACHTTML_H + +#include + +extern struct ep93xx_ssp_slave ep93xx_ssp_micro; +extern struct ep93xx_ssp_slave ep93xx_ssp_expansion; + +extern int ssp_do_ttml(struct ep93xx_ssp_slave *s, void *tx, int tlen, void *rx, + int rlen); + +#endif diff --git a/include/asm-arm/arch-ep93xx/memory.h b/include/asm-arm/arch-ep93xx/memory.h new file mode 100644 index 0000000..57e266e --- /dev/null +++ b/include/asm-arm/arch-ep93xx/memory.h @@ -0,0 +1,256 @@ +/* + * linux/include/asm-arm/arch-ep93xx/memory.h + * + * ****************************************************** + * * CONFUSED? Read Documentation/IO-mapping.txt * + * ****************************************************** + * + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2002-2003 Cirrus Logic Corp. + * + * 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 + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +/* + * For EP93xx, SDRAM can be discontiguous, in a set number of blocks + * of equal size and (usually) equal spacing. The 9301 spacing isn't equal. + * + * SDRAM_START is the physical address of the start of SDRAM. + * SDRAM_NUMBER_OF_BLOCKS = # of blocks of SDRAM. + * Each block is of size SDRAM_BLOCK_SIZE and starts at a boundary + * of SDRAM_BLOCK_START_BOUNDARY. + * + * So memory blocks are at: + * SDRAM_START + * SDRAM_START + SDRAM_BLOCK_START_BOUNDARY + * SDRAM_START + (SDRAM_BLOCK_START_BOUNDARY * 2) + * SDRAM_START + (SDRAM_BLOCK_START_BOUNDARY * 3) + * so on + */ + +#ifndef CONFIG_DISCONTIGMEM + +/* + * Single 32Meg block of physical memory physically located at 0 . + */ +#define SDRAM_START 0x00000000 +#define SDRAM_NUMBER_OF_BLOCKS 1 +#define SDRAM_BLOCK_SIZE 0x02000000 +#define SDRAM_BLOCK_START_BOUNDARY 0x00000000 + +#else /* CONFIG_DISCONTIGMEM */ + +#if defined(CONFIG_MACH_EDB9301) +/* + * 4 8Meg blocks at 0x0n000000, n={0145} + */ +#define SDRAM_START 0x00000000 +#define SDRAM_NUMBER_OF_BLOCKS 4 +#define SDRAM_BLOCK_SIZE 0x00800000 +#define SDRAM_BLOCK_START_BOUNDARY 0x01000000 +#endif + +#if defined(CONFIG_MACH_TTML) +#define SDRAM_START 0x00000000 +#define SDRAM_NUMBER_OF_BLOCKS 1 +#define SDRAM_BLOCK_SIZE 0x02000000 +#define SDRAM_BLOCK_START_BOUNDARY 0x02000000 +#endif + +#if defined(CONFIG_MACH_EDB9302) +/* + * 4 8Meg blocks at 0x0n000000, n={0145} + */ +#define SDRAM_START 0x00000000 +#define SDRAM_NUMBER_OF_BLOCKS 4 +#define SDRAM_BLOCK_SIZE 0x00800000 +#define SDRAM_BLOCK_START_BOUNDARY 0x01000000 +#endif + +#if defined(CONFIG_MACH_EDB9312) || defined(CONFIG_MACH_EDB9315) || defined(CONFIG_MACH_ADSSPHERE) +/* + * 2 32Meg blocks that are located physically at 0 and 64Meg. + */ +#define SDRAM_START 0x00000000 +#define SDRAM_NUMBER_OF_BLOCKS 2 +#define SDRAM_BLOCK_SIZE 0x02000000 +#define SDRAM_BLOCK_START_BOUNDARY 0x04000000 +#endif + +#if defined(CONFIG_MACH_DMA03) +/* + * 2 32Meg blocks that are located physically at 0 and 64Meg. + */ +#define SDRAM_START 0x00000000 +#define SDRAM_NUMBER_OF_BLOCKS 2 +#define SDRAM_BLOCK_SIZE 0x02000000 +#define SDRAM_BLOCK_START_BOUNDARY 0x04000000 +#endif + +#if defined(CONFIG_MACH_ACC) +/* + * 8 8Meg blocks that are located physically at 0xC0000000 + * total 64Meg. + */ +#define SDRAM_START 0xC0000000 +#define SDRAM_NUMBER_OF_BLOCKS 8 +#define SDRAM_BLOCK_SIZE 0x00800000 +#define SDRAM_BLOCK_START_BOUNDARY 0x01000000 +#endif + +#if defined(CONFIG_MACH_ZEFEERDZB) +/* + * 2 8Meg blocks + */ +#define SDRAM_START 0xD0000000 +#define SDRAM_NUMBER_OF_BLOCKS 2 +#define SDRAM_BLOCK_SIZE 0x00800000 +#define SDRAM_BLOCK_START_BOUNDARY 0x01000000 +#endif + +#if defined(CONFIG_MACH_ZEFEERDZQ) +/* + * 2 32Meg blocks + */ +#define SDRAM_START 0xD0000000 +#define SDRAM_NUMBER_OF_BLOCKS 2 +#define SDRAM_BLOCK_SIZE 0x02000000 +#define SDRAM_BLOCK_START_BOUNDARY 0x04000000 +#endif + +/* + * Here we are assuming EP93xx is configured to have two 32MB SDRAM + * areas with 32MB of empty space between them. So use 24 for the node + * max shift to get 64MB node sizes. + */ +#define NODE_MAX_MEM_SHIFT 26 +#define NODE_MAX_MEM_SIZE (1< DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define __virt_to_bus__is_a_macro +#define __virt_to_bus(x) __virt_to_phys(x) + +#define __bus_to_virt__is_a_macro +#define __bus_to_virt(x) __phys_to_virt(x) + +/* + * Note that this file is included by include/asm-arm/memory.h so + * the macros in this file have to play nice with those. + */ +#ifdef CONFIG_DISCONTIGMEM + +/* + * Given a kernel address, find the home node of the underlying memory. + */ +#define KVADDR_TO_NID(addr) \ + (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT) + +/* + * Given a page frame number, convert it to a node id. + */ +#define PFN_TO_NID(pfn) \ + (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT)) + +/* + * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory + * and returns the mem_map of that node. + */ +#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr))) + +#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn)) + +/* + * Given a kaddr, LOCAL_MAR_NR finds the owning node of the memory + * and returns the index corresponding to the appropriate page in the + * node's mem_map. + */ +#define LOCAL_MAP_NR(kaddr) \ + (((unsigned long)(kaddr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT) + +#endif /* CONFIG_DISCONTIGMEM */ + +#endif diff --git a/include/asm-arm/arch-ep93xx/param.h b/include/asm-arm/arch-ep93xx/param.h new file mode 100644 index 0000000..525face --- /dev/null +++ b/include/asm-arm/arch-ep93xx/param.h @@ -0,0 +1,21 @@ +/* + * linux/include/asm-arm/arch-integrator/param.h + * + * Copyright (C) 1999 ARM Limited + * + * 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 + */ + +/* #define HZ 100 */ diff --git a/include/asm-arm/arch-ep93xx/platform.h b/include/asm-arm/arch-ep93xx/platform.h new file mode 100644 index 0000000..d92833d --- /dev/null +++ b/include/asm-arm/arch-ep93xx/platform.h @@ -0,0 +1,43 @@ +/* + * linux/include/asm-arm/arch-ep93xx/platform.h + * + * Copyright (C) 2002-2003 Cirrus Logic, Inc. + * + * 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 + */ +#ifndef ASM_ARCH_PLATFORM_H +#define ASM_ARCH_PLATFORM_H + +/* + * Timer definitions + * + * Use timers 1, 2, and 3. Do not use timer 4. + * Timers run at 508 kHz. + */ + +/* + * These are useconds NOT ticks. + */ +#define mSEC_1 1000 +#define mSEC_5 (mSEC_1 * 5) +#define mSEC_10 (mSEC_1 * 10) +#define mSEC_25 (mSEC_1 * 25) +#define SEC_1 (mSEC_1 * 1000) + +#ifndef __ASSEMBLY__ +extern struct sys_timer ep93xx_timer; +#endif + +#endif diff --git a/include/asm-arm/arch-ep93xx/regmap.h b/include/asm-arm/arch-ep93xx/regmap.h new file mode 100644 index 0000000..7b3eeac --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regmap.h @@ -0,0 +1,1125 @@ +/* + * File: linux/include/asm-arm/arch-ep93xx/regmap.h + * + * Copyright (C) 2004 Ray Lehtiniemi + * Copyright (C) 2003 Cirrus Logic, Inc + * Copyright (C) 1999 ARM Limited. + * + * 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 + */ + +#ifndef __ASM_ARCH_REGMAP_H +#define __ASM_ARCH_REGMAP_H + +/* + * Here's the rules: + * - EP93xx register addresses in regmap.h are physical addresses. + * + * - io_p2v translates a physical address to a virtual one for the + * EP93xx's register space only. Don't use it for actual memory. + * + */ + +#define IO_BASE_VIRT 0xE0000000 /* Virtual address of IO */ +#define IO_BASE_PHYS 0x80000000 /* Physical address of IO */ + +/* + * The HW_REG macro assumes that the param is a virtual address + */ +#define HW_REG(reg) ((unsigned int volatile *)reg) + +/* + * Macro to get at IO space when running virtually. + * (Translates a physical address to a virtual address) + * First cast the pa to an unsigned int in case we are using this + * on a macro that is already cast as a pointer. + */ + +#define io_p2v(x) ((x) - (IO_BASE_PHYS - IO_BASE_VIRT)) +#define io_v2p(x) ((x) - (IO_BASE_VIRT - IO_BASE_PHYS)) + +/******************************************************************/ +/* EP93xx Memory Map and Register list */ +/******************************************************************/ +/* */ +/* 0000_0000 - 0000_ffff: Internal ROM/nSDCE3/nCS0 */ +/* 0001_0000 - 0fff_ffff: nSDCE3/nCS0 */ +/* 1000_0000 - 1fff_ffff: nCS1 */ +/* 2000_0000 - 2fff_ffff: nCS2 */ +/* 3000_0000 - 3fff_ffff: nCS3 */ +/* 4000_0000 - 4fff_ffff: Reserved */ +/* 5000_0000 - 5fff_ffff: Reserved */ +/* 6000_0000 - 6fff_ffff: nCS6 */ +/* 7000_0000 - 7fff_ffff: nCS7 */ +/* 8000_0000 - 800f_ffff: AHB Registers */ +/* 8010_0000 - 807f_ffff: Reserved */ +/* 8080_0000 - 8fff_ffff: APB Registers */ +/* 9000_0000 - bfff_ffff: Not Used */ +/* c000_0000 - cfff_ffff: nSDCE0 */ +/* d000_0000 - dfff_ffff: nSDCE1 */ +/* e000_0000 - efff_ffff: nSDCE2 */ +/* f000_0000 - ffff_ffff: nCS0/nSDCE3 */ +/* */ +/******************************************************************/ + +/******************************************************************/ +/* EP93xx AHB Blocks */ +/******************************************************************/ +/* */ +/* Start End Usage */ +/* 8000_0000 8000_FFFF: DMA */ +/* 8001_0000 8001_FFFF: Ethernet MAC */ +/* 8002_0000 8002_FFFF: USB Host */ +/* 8003_0000 8003_FFFF: Raster */ +/* 8004_0000 8004_FFFF: Reserved */ +/* 8005_0000 8005_FFFF: Reserved */ +/* 8006_0000 8006_FFFF: SDRAM */ +/* 8007_0000 8007_FFFF: Reserved */ +/* 8008_0000 8008_FFFF: SMC */ +/* 8009_0000 8009_FFFF: Boot ROM physical address */ +/* 800A_0000 800A_FFFF: IDE */ +/* 800B_0000 800B_FFFF: VIC1 */ +/* 800C_0000 800C_FFFF: VIC2 */ +/* 800D_0000 800F_FFFF: Reserved */ +/* */ +/******************************************************************/ + +#define EP93XX_AHB_BASE (IO_BASE_VIRT) + +/* 8000_0000 - 8000_ffff: DMA */ +#define DMA_OFFSET 0x000000 +#define DMA_BASE (EP93XX_AHB_BASE|DMA_OFFSET) +#define DMAMP_TX_0_CONTROL (DMA_BASE+0x0000) +#define DMAMP_TX_0_INTERRUPT (DMA_BASE+0x0004) +#define DMAMP_TX_0_PPALLOC (DMA_BASE+0x0008) +#define DMAMP_TX_0_STATUS (DMA_BASE+0x000C) +#define DMAMP_TX_0_REMAIN (DMA_BASE+0x0014) +#define DMAMP_TX_0_MAXCNT0 (DMA_BASE+0x0020) +#define DMAMP_TX_0_BASE0 (DMA_BASE+0x0024) +#define DMAMP_TX_0_CURRENT0 (DMA_BASE+0x0028) +#define DMAMP_TX_0_MAXCNT1 (DMA_BASE+0x0030) +#define DMAMP_TX_0_BASE1 (DMA_BASE+0x0034) +#define DMAMP_TX_0_CURRENT1 (DMA_BASE+0x0038) + +#define DMAMP_RX_1_CONTROL (DMA_BASE+0x0040) +#define DMAMP_RX_1_INTERRUPT (DMA_BASE+0x0044) +#define DMAMP_RX_1_PPALLOC (DMA_BASE+0x0048) +#define DMAMP_RX_1_STATUS (DMA_BASE+0x004C) +#define DMAMP_RX_1_REMAIN (DMA_BASE+0x0054) +#define DMAMP_RX_1_MAXCNT0 (DMA_BASE+0x0060) +#define DMAMP_RX_1_BASE0 (DMA_BASE+0x0064) +#define DMAMP_RX_1_CURRENT0 (DMA_BASE+0x0068) +#define DMAMP_RX_1_MAXCNT1 (DMA_BASE+0x0070) +#define DMAMP_RX_1_BASE1 (DMA_BASE+0x0074) +#define DMAMP_RX_1_CURRENT1 (DMA_BASE+0x0078) + +#define DMAMP_TX_2_CONTROL (DMA_BASE+0x0080) +#define DMAMP_TX_2_INTERRUPT (DMA_BASE+0x0084) +#define DMAMP_TX_2_PPALLOC (DMA_BASE+0x0088) +#define DMAMP_TX_2_STATUS (DMA_BASE+0x008C) +#define DMAMP_TX_2_REMAIN (DMA_BASE+0x0094) +#define DMAMP_TX_2_MAXCNT0 (DMA_BASE+0x00A0) +#define DMAMP_TX_2_BASE0 (DMA_BASE+0x00A4) +#define DMAMP_TX_2_CURRENT0 (DMA_BASE+0x00A8) +#define DMAMP_TX_2_MAXCNT1 (DMA_BASE+0x00B0) +#define DMAMP_TX_2_BASE1 (DMA_BASE+0x00B4) +#define DMAMP_TX_2_CURRENT1 (DMA_BASE+0x00B8) + +#define DMAMP_RX_3_CONTROL (DMA_BASE+0x00C0) +#define DMAMP_RX_3_INTERRUPT (DMA_BASE+0x00C4) +#define DMAMP_RX_3_PPALLOC (DMA_BASE+0x00C8) +#define DMAMP_RX_3_STATUS (DMA_BASE+0x00CC) +#define DMAMP_RX_3_REMAIN (DMA_BASE+0x00D4) +#define DMAMP_RX_3_MAXCNT0 (DMA_BASE+0x00E0) +#define DMAMP_RX_3_BASE0 (DMA_BASE+0x00E4) +#define DMAMP_RX_3_CURRENT0 (DMA_BASE+0x00E8) +#define DMAMP_RX_3_MAXCNT1 (DMA_BASE+0x00F0) +#define DMAMP_RX_3_BASE1 (DMA_BASE+0x00F4) +#define DMAMP_RX_3_CURRENT1 (DMA_BASE+0x00F8) + +#define DMAMM_0_CONTROL (DMA_BASE+0x0100) +#define DMAMM_0_INTERRUPT (DMA_BASE+0x0104) +#define DMAMM_0_STATUS (DMA_BASE+0x010C) +#define DMAMM_0_BCR0 (DMA_BASE+0x0110) +#define DMAMM_0_BCR1 (DMA_BASE+0x0114) +#define DMAMM_0_SAR_BASE0 (DMA_BASE+0x0118) +#define DMAMM_0_SAR_BASE1 (DMA_BASE+0x011C) +#define DMAMM_0_SAR_CURRENT0 (DMA_BASE+0x0124) +#define DMAMM_0_SAR_CURRENT1 (DMA_BASE+0x0128) +#define DMAMM_0_DAR_BASE0 (DMA_BASE+0x012C) +#define DMAMM_0_DAR_BASE1 (DMA_BASE+0x0130) +#define DMAMM_0_DAR_CURRENT0 (DMA_BASE+0x0134) +#define DMAMM_0_DAR_CURRENT1 (DMA_BASE+0x013C) + +#define DMAMM_1_CONTROL (DMA_BASE+0x0140) +#define DMAMM_1_INTERRUPT (DMA_BASE+0x0144) +#define DMAMM_1_STATUS (DMA_BASE+0x014C) +#define DMAMM_1_BCR0 (DMA_BASE+0x0150) +#define DMAMM_1_BCR1 (DMA_BASE+0x0154) +#define DMAMM_1_SAR_BASE0 (DMA_BASE+0x0158) +#define DMAMM_1_SAR_BASE1 (DMA_BASE+0x015C) +#define DMAMM_1_SAR_CURRENT0 (DMA_BASE+0x0164) +#define DMAMM_1_SAR_CURRENT1 (DMA_BASE+0x0168) +#define DMAMM_1_DAR_BASE0 (DMA_BASE+0x016C) +#define DMAMM_1_DAR_BASE1 (DMA_BASE+0x0170) +#define DMAMM_1_DAR_CURRENT0 (DMA_BASE+0x0174) +#define DMAMM_1_DAR_CURRENT1 (DMA_BASE+0x017C) + +#define DMAMP_RX_5_CONTROL (DMA_BASE+0x0200) +#define DMAMP_RX_5_INTERRUPT (DMA_BASE+0x0204) +#define DMAMP_RX_5_PPALLOC (DMA_BASE+0x0208) +#define DMAMP_RX_5_STATUS (DMA_BASE+0x020C) +#define DMAMP_RX_5_REMAIN (DMA_BASE+0x0214) +#define DMAMP_RX_5_MAXCNT0 (DMA_BASE+0x0220) +#define DMAMP_RX_5_BASE0 (DMA_BASE+0x0224) +#define DMAMP_RX_5_CURRENT0 (DMA_BASE+0x0228) +#define DMAMP_RX_5_MAXCNT1 (DMA_BASE+0x0230) +#define DMAMP_RX_5_BASE1 (DMA_BASE+0x0234) +#define DMAMP_RX_5_CURRENT1 (DMA_BASE+0x0238) + +#define DMAMP_TX_4_CONTROL (DMA_BASE+0x0240) +#define DMAMP_TX_4_INTERRUPT (DMA_BASE+0x0244) +#define DMAMP_TX_4_PPALLOC (DMA_BASE+0x0248) +#define DMAMP_TX_4_STATUS (DMA_BASE+0x024C) +#define DMAMP_TX_4_REMAIN (DMA_BASE+0x0254) +#define DMAMP_TX_4_MAXCNT0 (DMA_BASE+0x0260) +#define DMAMP_TX_4_BASE0 (DMA_BASE+0x0264) +#define DMAMP_TX_4_CURRENT0 (DMA_BASE+0x0268) +#define DMAMP_TX_4_MAXCNT1 (DMA_BASE+0x0270) +#define DMAMP_TX_4_BASE1 (DMA_BASE+0x0274) +#define DMAMP_TX_4_CURRENT1 (DMA_BASE+0x0278) + +#define DMAMP_RX_7_CONTROL (DMA_BASE+0x0280) +#define DMAMP_RX_7_INTERRUPT (DMA_BASE+0x0284) +#define DMAMP_RX_7_PPALLOC (DMA_BASE+0x0288) +#define DMAMP_RX_7_STATUS (DMA_BASE+0x028C) +#define DMAMP_RX_7_REMAIN (DMA_BASE+0x0294) +#define DMAMP_RX_7_MAXCNT0 (DMA_BASE+0x02A0) +#define DMAMP_RX_7_BASE0 (DMA_BASE+0x02A4) +#define DMAMP_RX_7_CURRENT0 (DMA_BASE+0x02A8) +#define DMAMP_RX_7_MAXCNT1 (DMA_BASE+0x02B0) +#define DMAMP_RX_7_BASE1 (DMA_BASE+0x02B4) +#define DMAMP_RX_7_CURRENT1 (DMA_BASE+0x02B8) + +#define DMAMP_TX_6_CONTROL (DMA_BASE+0x02C0) +#define DMAMP_TX_6_INTERRUPT (DMA_BASE+0x02C4) +#define DMAMP_TX_6_PPALLOC (DMA_BASE+0x02C8) +#define DMAMP_TX_6_STATUS (DMA_BASE+0x02CC) +#define DMAMP_TX_6_REMAIN (DMA_BASE+0x02D4) +#define DMAMP_TX_6_MAXCNT0 (DMA_BASE+0x02E0) +#define DMAMP_TX_6_BASE0 (DMA_BASE+0x02E4) +#define DMAMP_TX_6_CURRENT0 (DMA_BASE+0x02E8) +#define DMAMP_TX_6_MAXCNT1 (DMA_BASE+0x02F0) +#define DMAMP_TX_6_BASE1 (DMA_BASE+0x02F4) +#define DMAMP_TX_6_CURRENT1 (DMA_BASE+0x02F8) + +#define DMAMP_RX_9_CONTROL (DMA_BASE+0x0300) +#define DMAMP_RX_9_INTERRUPT (DMA_BASE+0x0304) +#define DMAMP_RX_9_PPALLOC (DMA_BASE+0x0308) +#define DMAMP_RX_9_STATUS (DMA_BASE+0x030C) +#define DMAMP_RX_9_REMAIN (DMA_BASE+0x0314) +#define DMAMP_RX_9_MAXCNT0 (DMA_BASE+0x0320) +#define DMAMP_RX_9_BASE0 (DMA_BASE+0x0324) +#define DMAMP_RX_9_CURRENT0 (DMA_BASE+0x0328) +#define DMAMP_RX_9_MAXCNT1 (DMA_BASE+0x0330) +#define DMAMP_RX_9_BASE1 (DMA_BASE+0x0334) +#define DMAMP_RX_9_CURRENT1 (DMA_BASE+0x0338) + +#define DMAMP_TX_8_CONTROL (DMA_BASE+0x0340) +#define DMAMP_TX_8_INTERRUPT (DMA_BASE+0x0344) +#define DMAMP_TX_8_PPALLOC (DMA_BASE+0x0348) +#define DMAMP_TX_8_STATUS (DMA_BASE+0x034C) +#define DMAMP_TX_8_REMAIN (DMA_BASE+0x0354) +#define DMAMP_TX_8_MAXCNT0 (DMA_BASE+0x0360) +#define DMAMP_TX_8_BASE0 (DMA_BASE+0x0364) +#define DMAMP_TX_8_CURRENT0 (DMA_BASE+0x0368) +#define DMAMP_TX_8_MAXCNT1 (DMA_BASE+0x0370) +#define DMAMP_TX_8_BASE1 (DMA_BASE+0x0374) +#define DMAMP_TX_8_CURRENT1 (DMA_BASE+0x0378) + +#define DMA_ARBITRATION (DMA_BASE+0x0380) +#define DMA_INTERRUPT (DMA_BASE+0x03C0) + +/* + * DMA Register Base addresses and Offsets + */ +#define DMA_M2P_TX_0_BASE DMAMP_TX_0_CONTROL +#define DMA_M2P_RX_1_BASE DMAMP_RX_1_CONTROL +#define DMA_M2P_TX_2_BASE DMAMP_TX_2_CONTROL +#define DMA_M2P_RX_3_BASE DMAMP_RX_3_CONTROL +#define DMA_M2M_0_BASE DMAMM_0_CONTROL +#define DMA_M2M_1_BASE DMAMM_1_CONTROL +#define DMA_M2P_RX_5_BASE DMAMP_RX_5_CONTROL +#define DMA_M2P_TX_4_BASE DMAMP_TX_4_CONTROL +#define DMA_M2P_RX_7_BASE DMAMP_RX_7_CONTROL +#define DMA_M2P_TX_6_BASE DMAMP_TX_6_CONTROL +#define DMA_M2P_RX_9_BASE DMAMP_RX_9_CONTROL +#define DMA_M2P_TX_8_BASE DMAMP_TX_8_CONTROL + +#define M2P_OFFSET_CONTROL 0x0000 +#define M2P_OFFSET_INTERRUPT 0x0004 +#define M2P_OFFSET_PPALLOC 0x0008 +#define M2P_OFFSET_STATUS 0x000C +#define M2P_OFFSET_REMAIN 0x0014 +#define M2P_OFFSET_MAXCNT0 0x0020 +#define M2P_OFFSET_BASE0 0x0024 +#define M2P_OFFSET_CURRENT0 0x0028 +#define M2P_OFFSET_MAXCNT1 0x0030 +#define M2P_OFFSET_BASE1 0x0034 +#define M2P_OFFSET_CURRENT1 0x0038 + +#define M2M_OFFSET_CONTROL 0x0000 +#define M2M_OFFSET_INTERRUPT 0x0004 +#define M2M_OFFSET_STATUS 0x000C +#define M2M_OFFSET_BCR0 0x0010 +#define M2M_OFFSET_BCR1 0x0014 +#define M2M_OFFSET_SAR_BASE0 0x0018 +#define M2M_OFFSET_SAR_BASE1 0x001C +#define M2M_OFFSET_SAR_CURRENT0 0x0024 +#define M2M_OFFSET_SAR_CURRENT1 0x0028 +#define M2M_OFFSET_DAR_BASE0 0x002C +#define M2M_OFFSET_DAR_BASE1 0x0030 +#define M2M_OFFSET_DAR_CURRENT0 0x0034 +#define M2M_OFFSET_DAR_CURRENT1 0x003C + +/*----------------------------------------------------------------*/ +/* 8001_0000 - 8001_ffff: Ether MAC */ +/*----------------------------------------------------------------*/ +#define MAC_OFFSET 0x010000 +#define MAC_BASE (EP93XX_AHB_BASE|MAC_OFFSET) + +#define MAC_RXCTL (MAC_BASE+0x00) +#define MAC_TXCTL (MAC_BASE+0x04) +#define MAC_TESTCTL (MAC_BASE+0x08) +#define MAC_MIICMD (MAC_BASE+0x10) +#define MAC_MIIDATA (MAC_BASE+0x14) +#define MAC_MIISTS (MAC_BASE+0x18) +#define MAC_SELFCTL (MAC_BASE+0x20) +#define MAC_INTEN (MAC_BASE+0x24) +#define MAC_INTSTSP (MAC_BASE+0x28) +#define MAC_INTSTSC (MAC_BASE+0x2C) +#define MAC_DIAGAD (MAC_BASE+0x38) +#define MAC_DIAGDATA (MAC_BASE+0x3C) +#define MAC_GT (MAC_BASE+0x40) +#define MAC_FCT (MAC_BASE+0x44) +#define MAC_FCF (MAC_BASE+0x48) +#define MAC_AFP (MAC_BASE+0x4C) +#define MAC_HASHTBL (MAC_BASE+0x50) +#define MAC_INDAD (MAC_BASE+0x50) +#define MAC_INDAD_UPPER (MAC_BASE+0x54) +#define MAC_GIINTSTS (MAC_BASE+0x60) +#define MAC_GIINTMSK (MAC_BASE+0x64) +#define MAC_GIINTROSTS (MAC_BASE+0x68) +#define MAC_GIINTFRC (MAC_BASE+0x6C) +#define MAC_TXCOLLCNT (MAC_BASE+0x70) +#define MAC_RXMISSCNT (MAC_BASE+0x74) +#define MAC_RXRUNTCNT (MAC_BASE+0x78) +#define MAC_BMCTL (MAC_BASE+0x80) +#define MAC_BMSTS (MAC_BASE+0x84) +#define MAC_RXBCA (MAC_BASE+0x88) +#define MAC_RXDQBADD (MAC_BASE+0x90) +#define MAC_RXDQBLEN (UINT16*)(MAC_BASE+0x94) +#define MAC_RXDQCURLEN (UINT16*)(MAC_BASE+0x96) +#define MAC_RXDCURADD (MAC_BASE+0x98) +#define MAC_RXDENQ (MAC_BASE+0x9C) +#define MAC_RXSTSQBADD (MAC_BASE+0xA0) +#define MAC_RXSTSQBLEN (UINT16*)(MAC_BASE+0xA4) +#define MAC_RXSTSQCURLEN (UINT16*)(MAC_BASE+0xA6) +#define MAC_RXSTSQCURADD (MAC_BASE+0xA8) +#define MAC_RXSTSENQ (MAC_BASE+0xAC) +#define MAC_TXDQBADD (MAC_BASE+0xB0) +#define MAC_TXDQBLEN (MAC_BASE+0xB4) +#define MAC_TXDQCURLEN (MAC_BASE+0xB6) +#define MAC_TXDQCURADD (MAC_BASE+0xB8) +#define MAC_TXDENQ (MAC_BASE+0xBC) +#define MAC_TXSTSQBADD (MAC_BASE+0xC0) +#define MAC_TXSTSQBLEN (MAC_BASE+0xC4) +#define MAC_TXSTSQCURLEN (MAC_BASE+0xC6) +#define MAC_TXSTSQCURADD (MAC_BASE+0xC8) +#define MAC_RXBUFTHRSHLD (MAC_BASE+0xD0) +#define MAC_TXBUFTHRSHLD (MAC_BASE+0xD4) +#define MAC_RXSTSTHRSHLD (MAC_BASE+0xD8) +#define MAC_TXSTSTHRSHLD (MAC_BASE+0xDC) +#define MAC_RXDTHRSHLD (MAC_BASE+0xE0) +#define MAC_TXDTHRSHLD (MAC_BASE+0xE4) +#define MAC_MAXFRMLEN (MAC_BASE+0xE8) +#define MAC_RXHDRLEN (MAC_BASE+0xEC) + +#define MAC_FIFO (MAC_BASE+0x4000) +#define MAC_FIFO_LEN 0xc000 + +/*----------------------------------------------------------------*/ +/* 8002_0000 - 8002_ffff: USB */ +/*----------------------------------------------------------------*/ +#define USB_OFFSET 0x020000 +#define USB_BASE (EP93XX_AHB_BASE|USB_OFFSET) + +#define HCREVISION (USB_BASE+0x00) +#define HCCONTROL (USB_BASE+0x04) +#define HCCOMMANDSTATUS (USB_BASE+0x08) +#define HCINTERRUPTSTATUS (USB_BASE+0x0C) +#define HCINTERRUPTENABLE (USB_BASE+0x10) +#define HCINTERRUPTDISABLE (USB_BASE+0x14) +#define HCHCCA (USB_BASE+0x18) +#define HCPERIODCURRENTED (USB_BASE+0x1C) +#define HCCONTROLHEADED (USB_BASE+0x20) +#define HCCONTROLCURRENTED (USB_BASE+0x24) +#define HCBULKHEADED (USB_BASE+0x28) +#define HCBULKCURRENTED (USB_BASE+0x2C) +#define HCDONEHEAD (USB_BASE+0x30) +#define HCFMINTERVAL (USB_BASE+0x34) +#define HCFMREMAINING (USB_BASE+0x38) +#define HCFMNUMBER (USB_BASE+0x3C) +#define HCPERIODICSTART (USB_BASE+0x40) +#define HCLSTHRESHOLD (USB_BASE+0x44) +#define HCRHDESCRIPTORA (USB_BASE+0x48) +#define HCRHDESCRIPTORB (USB_BASE+0x4C) +#define HCRHSTATUS (USB_BASE+0x50) +#define HCRHPORTSTATUS0 (USB_BASE+0x54) +#define HCRHPORTSTATUS1 (USB_BASE+0x58) /* not in 9301 */ +#define HCRHPORTSTATUS2 (USB_BASE+0x5C) + +/* additional non-OHCI registers for controlling the AHB-HCI interface */ +#define USBCTRL (USB_BASE+0x80) +#define USBHCISTS (USB_BASE+0x84) + +/* 8003_0000 - 8003_ffff: Raster */ +#define RASTER_OFFSET 0x030000 +#define RASTER_BASE (EP93XX_AHB_BASE|RASTER_OFFSET) +#define VLINESTOTAL (RASTER_BASE+0x00) +#define VSYNCSTRTSTOP (RASTER_BASE+0x04) +#define VACTIVESTRTSTOP (RASTER_BASE+0x08) +#define VCLKSTRTSTOP (RASTER_BASE+0x0C) +#define HCLKSTOTAL (RASTER_BASE+0x10) +#define HSYNCSTRTSTOP (RASTER_BASE+0x14) +#define HACTIVESTRTSTOP (RASTER_BASE+0x18) +#define HCLKSTRTSTOP (RASTER_BASE+0x1C) +#define BRIGHTNESS (RASTER_BASE+0x20) +#define VIDEOATTRIBS (RASTER_BASE+0x24) +#define VIDSCRNPAGE (RASTER_BASE+0x28) +#define VIDSCRNHPG (RASTER_BASE+0x2C) +#define SCRNLINES (RASTER_BASE+0x30) +#define LINELENGTH (RASTER_BASE+0x34) +#define VLINESTEP (RASTER_BASE+0x38) +#define LINECARRY (RASTER_BASE+0x3C) +#define BLINKRATE (RASTER_BASE+0x40) +#define BLINKMASK (RASTER_BASE+0x44) +#define BLINKPATTRN (RASTER_BASE+0x48) +#define PATTRNMASK (RASTER_BASE+0x4C) +#define BG_OFFSET (RASTER_BASE+0x50) +#define PIXELMODE (RASTER_BASE+0x54) +#define PARLLIFOUT (RASTER_BASE+0x58) +#define PARLLIFIN (RASTER_BASE+0x5C) +#define CURSOR_ADR_START (RASTER_BASE+0x60) +#define CURSOR_ADR_RESET (RASTER_BASE+0x64) +#define CURSORSIZE (RASTER_BASE+0x68) +#define CURSORCOLOR1 (RASTER_BASE+0x6C) +#define CURSORCOLOR2 (RASTER_BASE+0x70) +#define CURSORXYLOC (RASTER_BASE+0x74) +#define CURSOR_DHSCAN_LH_YLOC (RASTER_BASE+0x78) +#define REALITI_SWLOCK (RASTER_BASE+0x7C) +#define GS_LUT (RASTER_BASE+0x80) +#define REALITI_TCR (RASTER_BASE+0x100) +#define REALITI_TISRA (RASTER_BASE+0x104) +#define REALITI_TISRB (RASTER_BASE+0x108) +#define CURSOR_TISR (RASTER_BASE+0x10C) +#define REALITI_TOCRA (RASTER_BASE+0x110) +#define REALITI_TOCRB (RASTER_BASE+0x114) +#define FIFO_TOCRA (RASTER_BASE+0x118) +#define FIFO_TOCRB (RASTER_BASE+0x11C) +#define BLINK_TISR (RASTER_BASE+0x120) +#define DAC_TISRA (RASTER_BASE+0x124) +#define DAC_TISRB (RASTER_BASE+0x128) +#define SHIFT_TISR (RASTER_BASE+0x12C) +#define DACMUX_TOCRA (RASTER_BASE+0x130) +#define DACMUX_TOCRB (RASTER_BASE+0x134) +#define PELMUX_TOCR (RASTER_BASE+0x138) +#define VIDEO_TOCRA (RASTER_BASE+0x13C) +#define VIDEO_TOCRB (RASTER_BASE+0x140) +#define YCRCB_TOCR (RASTER_BASE+0x144) +#define CURSOR_TOCR (RASTER_BASE+0x148) +#define VIDEO_TOCRC (RASTER_BASE+0x14C) +#define SHIFT_TOCR (RASTER_BASE+0x150) +#define BLINK_TOCR (RASTER_BASE+0x154) +#define REALITI_TCER (RASTER_BASE+0x180) +#define SIGVAL (RASTER_BASE+0x200) +#define SIGCTL (RASTER_BASE+0x204) +#define VSIGSTRTSTOP (RASTER_BASE+0x208) +#define HSIGSTRTSTOP (RASTER_BASE+0x20C) +#define SIGCLR (RASTER_BASE+0x210) +#define ACRATE (RASTER_BASE+0x214) +#define LUTCONT (RASTER_BASE+0x218) +#define VBLANKSTRTSTOP (RASTER_BASE+0x228) +#define HBLANKSTRTSTOP (RASTER_BASE+0x22C) +#define LUT (RASTER_BASE+0x400) +#define CURSORBLINK1 (RASTER_BASE+0x21C) +#define CURSORBLINK2 (RASTER_BASE+0x220) +#define CURSORBLINK (RASTER_BASE+0x224) +#define EOLOFFSET (RASTER_BASE+0x230) +#define FIFOLEVEL (RASTER_BASE+0x234) +#define GS_LUT2 (RASTER_BASE+0x280) +#define GS_LUT3 (RASTER_BASE+0x300) +#define COLOR_LUT (RASTER_BASE+0x400) + +/* 8006_0000 - 8006_ffff: SDRAM */ +#define SDRAM_OFFSET 0x060000 +#define SDRAM_BASE (EP93XX_AHB_BASE|SDRAM_OFFSET) +#define SDRAMGLOBALCFG (SDRAM_BASE+0x04) +#define SDRAMREFRESHTIME (SDRAM_BASE+0x08) /* Refresh Timer */ +#define SDRAMBOOTSTATUS (SDRAM_BASE+0x0C) +#define SDRAMCFG0 (SDRAM_BASE+0x10) /* Configuration Register 0 (nSDCS0) */ +#define SDRAMCFG1 (SDRAM_BASE+0x14) /* Configuration Register 1 (nSDCS1) */ +#define SDRAMCFG2 (SDRAM_BASE+0x18) /* Configuration Register 2 (nSDCS2) */ +#define SDRAMCFG3 (SDRAM_BASE+0x1C) /* Configuration Register 3 (nSDCS3) */ + +/* 8008_0000 - 8008_ffff: SMC */ +#define SMC_OFFSET 0x080000 +#define SMC_BASE (EP93XX_AHB_BASE|SMC_OFFSET) +#define SMCBCR0 (SMC_BASE+0x00) /* 0x8008.0000 Bank config register 0 */ +#define SMCBCR1 (SMC_BASE+0x04) /* 0x8008.0004 Bank config register 1 */ +#define SMCBCR2 (SMC_BASE+0x08) /* 0x8008.0008 Bank config register 2 */ +#define SMCBCR3 (SMC_BASE+0x0C) /* 0x8008.000C Bank config register 3 */ +#define SMCBCR6 (SMC_BASE+0x18) /* 0x8008.0018 Bank config register 6 */ +#define SMCBCR7 (SMC_BASE+0x1C) /* 0x8008.001C Bank config register 7 */ +#define PC1ATTRIB (SMC_BASE+0x20) /* 0x8008.0020 PC1 Attribute Register */ +#define PC1COMMON (SMC_BASE+0x24) /* 0x8008.0024 PC1 Common Register */ +#define PC1IO (SMC_BASE+0x28) /* 0x8008.0028 PC1 IO Register */ +#define PC2ATTRIB (SMC_BASE+0x30) /* 0x8008.0030 PC2 Attribute Register */ +#define PC2COMMON (SMC_BASE+0x34) /* 0x8008.0034 PC2 Common Register */ +#define PC2IO (SMC_BASE+0x38) /* 0x8008.0038 PC2 IO Register */ +#define PCMCIACNT (SMC_BASE+0x40) /* 0x8008.0040 PCMCIA control register */ + +/* 8009_0000 - 8009_ffff: Boot ROM */ +#define BOOT_OFFSET 0x090000 +#define BOOT_BASE (EP93XX_AHB_BASE|BOOT_OFFSET) + +/* 800A_0000 - 800A_ffff: IDE Interface */ +#define IDE_OFFSET 0x0a0000 +#define IDE_BASE (EP93XX_AHB_BASE|IDE_OFFSET) +/*#define IDECR (IDE_BASE+0x00) + *#define IDECFG (IDE_BASE+0x04) + *#define IDEMDMAOP (IDE_BASE+0x08) + *#define IDEUDMAOP (IDE_BASE+0x0C) + *#define IDEDATAOUT (IDE_BASE+0x10) + *#define IDEDATAIN (IDE_BASE+0x14) + *#define IDEMDMADATAOUT (IDE_BASE+0x18) + *#define IDEMDMADATAIN (IDE_BASE+0x1C) + *#define IDEUDMADATAOUT (IDE_BASE+0x20) + *#define IDEUDMADATAIN (IDE_BASE+0x24) + *#define IDEUDMASTATUS (IDE_BASE+0x28) + *#define IDEUDMADEBUG (IDE_BASE+0x2C) + *#define IDEUDMAWFST (IDE_BASE+0x30) + *#define IDEUDMARFST (IDE_BASE+0x34) + */ + +/* 800B_0000 - 800B_FFFF: VIC 0 */ +#define VIC0_OFFSET 0x0B0000 +#define VIC0_BASE (EP93XX_AHB_BASE|VIC0_OFFSET) +#define VIC0 (VIC0_BASE+0x000) +#define VIC0IRQSTATUS (VIC0_BASE+0x000) /* R IRQ status register */ +#define VIC0FIQSTATUS (VIC0_BASE+0x004) /* R FIQ status register */ +#define VIC0RAWINTR (VIC0_BASE+0x008) /* R Raw interrupt status register */ +#define VIC0INTSELECT (VIC0_BASE+0x00C) /* R/W Interrupt select register */ +#define VIC0INTENABLE (VIC0_BASE+0x010) /* R/W Interrupt enable register */ +#define VIC0INTENCLEAR (VIC0_BASE+0x014) /* W Interrupt enable clear register */ +#define VIC0SOFTINT (VIC0_BASE+0x018) /* R/W Software interrupt register */ +#define VIC0SOFTINTCLEAR (VIC0_BASE+0x01C) /* R/W Software interrupt clear register */ +#define VIC0PROTECTION (VIC0_BASE+0x020) /* R/W Protection enable register */ +#define VIC0VECTADDR (VIC0_BASE+0x030) /* R/W Vector address register */ +#define VIC0DEFVECTADDR (VIC0_BASE+0x034) /* R/W Default vector address register */ +#define VIC0VECTADDR00 (VIC0_BASE+0x100) /* R/W Vector address 00 register */ +#define VIC0VECTADDR01 (VIC0_BASE+0x104) /* R/W Vector address 01 register */ +#define VIC0VECTADDR02 (VIC0_BASE+0x108) /* R/W Vector address 02 register */ +#define VIC0VECTADDR03 (VIC0_BASE+0x10C) /* R/W Vector address 03 register */ +#define VIC0VECTADDR04 (VIC0_BASE+0x110) /* R/W Vector address 04 register */ +#define VIC0VECTADDR05 (VIC0_BASE+0x114) /* R/W Vector address 05 register */ +#define VIC0VECTADDR06 (VIC0_BASE+0x118) /* R/W Vector address 06 register */ +#define VIC0VECTADDR07 (VIC0_BASE+0x11C) /* R/W Vector address 07 register */ +#define VIC0VECTADDR08 (VIC0_BASE+0x120) /* R/W Vector address 08 register */ +#define VIC0VECTADDR09 (VIC0_BASE+0x124) /* R/W Vector address 09 register */ +#define VIC0VECTADDR10 (VIC0_BASE+0x128) /* R/W Vector address 10 register */ +#define VIC0VECTADDR11 (VIC0_BASE+0x12C) /* R/W Vector address 11 register */ +#define VIC0VECTADDR12 (VIC0_BASE+0x130) /* R/W Vector address 12 register */ +#define VIC0VECTADDR13 (VIC0_BASE+0x134) /* R/W Vector address 13 register */ +#define VIC0VECTADDR14 (VIC0_BASE+0x138) /* R/W Vector address 14 register */ +#define VIC0VECTADDR15 (VIC0_BASE+0x13C) /* R/W Vector address 15 register */ +#define VIC0VECTCNTL00 (VIC0_BASE+0x200) /* R/W Vector control 00 register */ +#define VIC0VECTCNTL01 (VIC0_BASE+0x204) /* R/W Vector control 01 register */ +#define VIC0VECTCNTL02 (VIC0_BASE+0x208) /* R/W Vector control 02 register */ +#define VIC0VECTCNTL03 (VIC0_BASE+0x20C) /* R/W Vector control 03 register */ +#define VIC0VECTCNTL04 (VIC0_BASE+0x210) /* R/W Vector control 04 register */ +#define VIC0VECTCNTL05 (VIC0_BASE+0x214) /* R/W Vector control 05 register */ +#define VIC0VECTCNTL06 (VIC0_BASE+0x218) /* R/W Vector control 06 register */ +#define VIC0VECTCNTL07 (VIC0_BASE+0x21C) /* R/W Vector control 07 register */ +#define VIC0VECTCNTL08 (VIC0_BASE+0x220) /* R/W Vector control 08 register */ +#define VIC0VECTCNTL09 (VIC0_BASE+0x224) /* R/W Vector control 09 register */ +#define VIC0VECTCNTL10 (VIC0_BASE+0x228) /* R/W Vector control 10 register */ +#define VIC0VECTCNTL11 (VIC0_BASE+0x22C) /* R/W Vector control 11 register */ +#define VIC0VECTCNTL12 (VIC0_BASE+0x230) /* R/W Vector control 12 register */ +#define VIC0VECTCNTL13 (VIC0_BASE+0x234) /* R/W Vector control 13 register */ +#define VIC0VECTCNTL14 (VIC0_BASE+0x238) /* R/W Vector control 14 register */ +#define VIC0VECTCNTL15 (VIC0_BASE+0x23C) /* R/W Vector control 15 register */ +#define VIC0ITCR (VIC0_BASE+0x300) /* R/W Test control register */ +#define VIC0ITIP1 (VIC0_BASE+0x304) /* R Test input register (nVICIRQIN/nVICFIQIN) */ +#define VIC0ITIP2 (VIC0_BASE+0x308) /* R Test input register (VICVECTADDRIN) */ +#define VIC0ITOP1 (VIC0_BASE+0x30C) /* R Test output register (nVICIRQ/nVICFIQ) */ +#define VIC0ITOP2 (VIC0_BASE+0x310) /* R Test output register (VICVECTADDROUT) */ +#define VIC0PERIPHID0 (VIC0_BASE+0xFE0) /* R Peripheral ID register bits 7:0 */ +#define VIC0PERIPHID1 (VIC0_BASE+0xFE4) /* R Peripheral ID register bits 15:8 */ +#define VIC0PERIPHID2 (VIC0_BASE+0xFE8) /* R Peripheral ID register bits 23:16 */ +#define VIC0PERIPHID3 (VIC0_BASE+0xFEC) /* R Peripheral ID register bits 31:24 */ + +/* 800C_0000 - 800C_FFFF: VIC 1 */ +#define VIC1_OFFSET 0x0C0000 +#define VIC1_BASE (EP93XX_AHB_BASE|VIC1_OFFSET) +#define VIC1 (VIC1_BASE+0x000) +#define VIC1IRQSTATUS (VIC1_BASE+0x000) /* R IRQ status register */ +#define VIC1FIQSTATUS (VIC1_BASE+0x004) /* R FIQ status register */ +#define VIC1RAWINTR (VIC1_BASE+0x008) /* R Raw interrupt status register */ +#define VIC1INTSELECT (VIC1_BASE+0x00C) /* R/W Interrupt select register */ +#define VIC1INTENABLE (VIC1_BASE+0x010) /* R/W Interrupt enable register */ +#define VIC1INTENCLEAR (VIC1_BASE+0x014) /* W Interrupt enable clear register */ +#define VIC1SOFTINT (VIC1_BASE+0x018) /* R/W Software interrupt register */ +#define VIC1SOFTINTCLEAR (VIC1_BASE+0x01C) /* R/W Software interrupt clear register */ +#define VIC1PROTECTION (VIC1_BASE+0x020) /* R/W Protection enable register */ +#define VIC1VECTADDR (VIC1_BASE+0x030) /* R/W Vector address register */ +#define VIC1DEFVECTADDR (VIC1_BASE+0x034) /* R/W Default vector address register */ +#define VIC1VECTADDR00 (VIC1_BASE+0x100) /* R/W Vector address 00 register */ +#define VIC1VECTADDR01 (VIC1_BASE+0x104) /* R/W Vector address 01 register */ +#define VIC1VECTADDR02 (VIC1_BASE+0x108) /* R/W Vector address 02 register */ +#define VIC1VECTADDR03 (VIC1_BASE+0x10C) /* R/W Vector address 03 register */ +#define VIC1VECTADDR04 (VIC1_BASE+0x110) /* R/W Vector address 04 register */ +#define VIC1VECTADDR05 (VIC1_BASE+0x114) /* R/W Vector address 05 register */ +#define VIC1VECTADDR06 (VIC1_BASE+0x118) /* R/W Vector address 06 register */ +#define VIC1VECTADDR07 (VIC1_BASE+0x11C) /* R/W Vector address 07 register */ +#define VIC1VECTADDR08 (VIC1_BASE+0x120) /* R/W Vector address 08 register */ +#define VIC1VECTADDR09 (VIC1_BASE+0x124) /* R/W Vector address 09 register */ +#define VIC1VECTADDR10 (VIC1_BASE+0x128) /* R/W Vector address 10 register */ +#define VIC1VECTADDR11 (VIC1_BASE+0x12C) /* R/W Vector address 11 register */ +#define VIC1VECTADDR12 (VIC1_BASE+0x130) /* R/W Vector address 12 register */ +#define VIC1VECTADDR13 (VIC1_BASE+0x134) /* R/W Vector address 13 register */ +#define VIC1VECTADDR14 (VIC1_BASE+0x138) /* R/W Vector address 14 register */ +#define VIC1VECTADDR15 (VIC1_BASE+0x13C) /* R/W Vector address 15 register */ +#define VIC1VECTCNTL00 (VIC1_BASE+0x200) /* R/W Vector control 00 register */ +#define VIC1VECTCNTL01 (VIC1_BASE+0x204) /* R/W Vector control 01 register */ +#define VIC1VECTCNTL02 (VIC1_BASE+0x208) /* R/W Vector control 02 register */ +#define VIC1VECTCNTL03 (VIC1_BASE+0x20C) /* R/W Vector control 03 register */ +#define VIC1VECTCNTL04 (VIC1_BASE+0x210) /* R/W Vector control 04 register */ +#define VIC1VECTCNTL05 (VIC1_BASE+0x214) /* R/W Vector control 05 register */ +#define VIC1VECTCNTL06 (VIC1_BASE+0x218) /* R/W Vector control 06 register */ +#define VIC1VECTCNTL07 (VIC1_BASE+0x21C) /* R/W Vector control 07 register */ +#define VIC1VECTCNTL08 (VIC1_BASE+0x220) /* R/W Vector control 08 register */ +#define VIC1VECTCNTL09 (VIC1_BASE+0x224) /* R/W Vector control 09 register */ +#define VIC1VECTCNTL10 (VIC1_BASE+0x228) /* R/W Vector control 10 register */ +#define VIC1VECTCNTL11 (VIC1_BASE+0x22C) /* R/W Vector control 11 register */ +#define VIC1VECTCNTL12 (VIC1_BASE+0x230) /* R/W Vector control 12 register */ +#define VIC1VECTCNTL13 (VIC1_BASE+0x234) /* R/W Vector control 13 register */ +#define VIC1VECTCNTL14 (VIC1_BASE+0x238) /* R/W Vector control 14 register */ +#define VIC1VECTCNTL15 (VIC1_BASE+0x23C) /* R/W Vector control 15 register */ +#define VIC1ITCR (VIC1_BASE+0x300) /* R/W Test control register */ +#define VIC1ITIP1 (VIC1_BASE+0x304) /* R Test input register (nVICIRQIN/nVICFIQIN) */ +#define VIC1ITIP2 (VIC1_BASE+0x308) /* R Test input register (VICVECTADDRIN) */ +#define VIC1ITOP1 (VIC1_BASE+0x30C) /* R Test output register (nVICIRQ/nVICFIQ) */ +#define VIC1ITOP2 (VIC1_BASE+0x310) /* R Test output register (VICVECTADDROUT) */ +#define VIC1PERIPHID0 (VIC1_BASE+0xFE0) /* R Peripheral ID register bits 7:0 */ +#define VIC1PERIPHID1 (VIC1_BASE+0xFE4) /* R Peripheral ID register bits 15:8 */ +#define VIC1PERIPHID2 (VIC1_BASE+0xFE8) /* R Peripheral ID register bits 23:16 */ +#define VIC1PERIPHID3 (VIC1_BASE+0xFEC) /* R Peripheral ID register bits 31:24 */ + +/******************************************************************/ +/* EP93xx APB Blocks */ +/******************************************************************/ +/* */ +/* Start End Usage */ +/* 8080_0000 8080_FFFF: Reserved */ +/* 8081_0000 8081_FFFF: Timer */ +/* 8082_0000 8082_FFFF: I2S */ +/* 8083_0000 8083_FFFF: Security */ +/* 8084_0000 8084_FFFF: GPIO */ +/* 8085_0000 8085_FFFF: Reserved */ +/* 8086_0000 8086_FFFF: Reserved */ +/* 8087_0000 8087_FFFF: Reserved */ +/* 8088_0000 8088_FFFF: AC97 */ +/* 8089_0000 8089_FFFF: Reserved */ +/* 808A_0000 808A_FFFF: SPI */ +/* 808B_0000 808B_FFFF: IrDA */ +/* 808C_0000 808C_FFFF: UART1 */ +/* 808D_0000 808D_FFFF: UART2 */ +/* 808E_0000 808E_FFFF: UART3 */ +/* 808F_0000 808F_FFFF: Key Matrix */ +/* 8090_0000 8090_FFFF: Touch Screen */ +/* 8091_0000 8091_FFFF: PWM */ +/* 8092_0000 8092_FFFF: Real Time Clock */ +/* 8093_0000 8093_FFFF: Syscon */ +/* 8094_0000 8094_FFFF: Watchdog */ +/* 8095_0000 8FFF_FFFF: Reserved */ +/* */ +/******************************************************************/ + +#define EP93XX_APB_BASE (IO_BASE_VIRT | 0x00800000) + +/*----------------------------------------------------------------*/ +/* 8081_0000 - 8081_ffff: Timers */ +/*----------------------------------------------------------------*/ + +#define TIMERS_OFFSET 0x010000 +#define TIMERS_BASE (EP93XX_APB_BASE|TIMERS_OFFSET) + +#define TIMER1LOAD (TIMERS_BASE+0x00) +#define TIMER1VALUE (TIMERS_BASE+0x04) /* RO */ +#define TIMER1CONTROL (TIMERS_BASE+0x08) +#define TIMER1CLEAR (TIMERS_BASE+0x0C) /* WO */ + +#define TIMER2LOAD (TIMERS_BASE+0x20) +#define TIMER2VALUE (TIMERS_BASE+0x24) /* RO */ +#define TIMER2CONTROL (TIMERS_BASE+0x28) +#define TIMER2CLEAR (TIMERS_BASE+0x2C) /* WO */ + +#define TIMER3LOAD (TIMERS_BASE+0x80) +#define TIMER3VALUE (TIMERS_BASE+0x84) /* RO */ +#define TIMER3CONTROL (TIMERS_BASE+0x88) +#define TIMER3CLEAR (TIMERS_BASE+0x8C) /* WO */ + +#define TIMER4VALUELOW (TIMERS_BASE+0x60) +#define TIMER4VALUEHIGH (TIMERS_BASE+0x64) + +/* 8082_0000 - 8082_ffff: I2S */ +#define I2S_OFFSET 0x020000 +#define I2S_BASE (EP93XX_APB_BASE|I2S_OFFSET) + +#define I2STxClkCfg (I2S_BASE+0x00) /* 8082.0000 R/W Transmitter clock config register */ +#define I2SRxClkCfg (I2S_BASE+0x04) /* 8082.0004 R/W Receiver clock config register */ +#define I2SGlSts (I2S_BASE+0x08) /* 8082.0008 R/W SAI Global Status register. */ +#define I2SGlCtrl (I2S_BASE+0x0C) /* 8082.000C R/W SAI Global Control register */ + +#define I2STX0Lft (I2S_BASE+0x10) /* 8082.0010 R/W Left TX data reg for channel 0 */ +#define I2STX0Rt (I2S_BASE+0x14) /* 8082.0014 R/W Right TX data reg for channel 0 */ +#define I2STX1Lft (I2S_BASE+0x18) /* 8082.0018 R/W Left TX data reg for channel 1 */ +#define I2STX1Rt (I2S_BASE+0x1C) /* 8082.001C R/W Right TX data reg for channel 1 */ +#define I2STX2Lft (I2S_BASE+0x20) /* 8082.0020 R/W Left TX data reg for channel 2 */ +#define I2STX2Rt (I2S_BASE+0x24) /* 8082.0024 R/W Right TX data reg for channel 2 */ + +#define I2STXLinCtrlData (I2S_BASE+0x28) /* 8082.0028 R/W TX Line Control data register */ +#define I2STXCtrl (I2S_BASE+0x2C) /* 8082.002C R/W TX Control register */ +#define I2STXWrdLen (I2S_BASE+0x30) /* 8082.0030 R/W TX Word Length */ +#define I2STX0En (I2S_BASE+0x34) /* 8082.0034 R/W TX0 Channel Enable */ +#define I2STX1En (I2S_BASE+0x38) /* 8082.0038 R/W TX1 Channel Enable */ +#define I2STX2En (I2S_BASE+0x3C) /* 8082.003C R/W TX2 Channel Enable */ + +#define I2SRX0Lft (I2S_BASE+0x40) /* 8082.0040 R Left RX data reg for channel 0 */ +#define I2SRX0Rt (I2S_BASE+0x44) /* 8082.0044 R Right RX data reg for channel 0 */ +#define I2SRX1Lft (I2S_BASE+0x48) /* 8082.0048 R Left RX data reg for channel 1 */ +#define I2SRX1Rt (I2S_BASE+0x4C) /* 8082.004c R Right RX data reg for channel 1 */ +#define I2SRX2Lft (I2S_BASE+0x50) /* 8082.0050 R Left RX data reg for channel 2 */ +#define I2SRX2Rt (I2S_BASE+0x54) /* 8082.0054 R Right RX data reg for channel 2 */ + +#define I2SRXLinCtrlData (I2S_BASE+0x58) /* 8082.0058 R/W RX Line Control data register */ +#define I2SRXCtrl (I2S_BASE+0x5C) /* 8082.005C R/W RX Control register */ +#define I2SRXWrdLen (I2S_BASE+0x60) /* 8082.0060 R/W RX Word Length */ +#define I2SRX0En (I2S_BASE+0x64) /* 8082.0064 R/W RX0 Channel Enable */ +#define I2SRX1En (I2S_BASE+0x68) /* 8082.0068 R/W RX1 Channel Enable */ +#define I2SRX2En (I2S_BASE+0x6C) /* 8082.006C R/W RX2 Channel Enable */ + +/* 8083_0000 - 8083_ffff: Security Block */ +#define SECURITY_OFFSET 0x030000 +#define SECURITY_BASE (EP93XX_APB_BASE|SECURITY_OFFSET) +#define SECFLG (SECURITY_BASE+0x2400) +#define SECEN (SECURITY_BASE+0x2410) +#define UNIQID (SECURITY_BASE+0x2440) +#define UNIQCHK (SECURITY_BASE+0x2450) +#define UNIQVAL (SECURITY_BASE+0x2460) +#define CLINBOOT (SECURITY_BASE+0x2480) +#define CLINVADDR (SECURITY_BASE+0x2484) +#define CLSETSKRNL (SECURITY_BASE+0x2488) +#define CLSKRNL (SECURITY_BASE+0x248C) +#define ITTMP (SECURITY_BASE+0x2490) +#define ETBL1 (SECURITY_BASE+0x24A0) +#define ETCL1 (SECURITY_BASE+0x24A4) +#define ETAPL1 (SECURITY_BASE+0x24A8) +#define ETSPTREG1 (SECURITY_BASE+0x24B0) +#define ETSPTREG2 (SECURITY_BASE+0x24B4) +#define ETSPTREG3 (SECURITY_BASE+0x24B8) + +#define SECID1 (SECURITY_BASE+0x2500) +#define SECID2 (SECURITY_BASE+0x2504) +#define SECCHK1 (SECURITY_BASE+0x2520) +#define SECCHK2 (SECURITY_BASE+0x2524) +#define SECVAL1 (SECURITY_BASE+0x2540) +#define SECVAL2 (SECURITY_BASE+0x2544) + +#define UNIQID2 (SECURITY_BASE+0x2700) +#define UNIQID3 (SECURITY_BASE+0x2704) +#define UNIQID4 (SECURITY_BASE+0x2708) +#define UNIQID5 (SECURITY_BASE+0x270C) +#define UNIQCHK2 (SECURITY_BASE+0x2710) +#define USRFLG (SECURITY_BASE+0x2714) /* llandre tells me this is also a CPU model flag */ +#define UNIQVAL2 (SECURITY_BASE+0x2720) +#define UNIQVAL3 (SECURITY_BASE+0x2724) +#define UNIQVAL4 (SECURITY_BASE+0x2728) +#define TESTVAL (SECURITY_BASE+0x2744) +#define TESTCHK (SECURITY_BASE+0x2754) +#define ACHK1 (SECURITY_BASE+0x27A0) +#define ACHK2 (SECURITY_BASE+0x27A4) +#define PROCRESET (SECURITY_BASE+0x27A8) +#define TESTIDR (SECURITY_BASE+0x27AC) +#define AVAL1 (SECURITY_BASE+0x27B0) +#define AVAL2 (SECURITY_BASE+0x27B4) +#define AID1 (SECURITY_BASE+0x27C4) +#define AID2 (SECURITY_BASE+0x27C8) +#define ADYNREMAP (SECURITY_BASE+0x27D0) +#define ALTTMP (SECURITY_BASE+0x27D4) +#define PROCSIGN (SECURITY_BASE+0x27F0) + +#define ECLIDX (SECURITY_BASE+0x2800) +#define ECLINE0 (SECURITY_BASE+0x2810) +#define ECLINE1 (SECURITY_BASE+0x2814) +#define ECLINE2 (SECURITY_BASE+0x2818) +#define ECLINE3 (SECURITY_BASE+0x281C) +#define ECLINE4 (SECURITY_BASE+0x2820) +#define ECLINE5 (SECURITY_BASE+0x2824) +#define ECLINE6 (SECURITY_BASE+0x2828) +#define ECLINE7 (SECURITY_BASE+0x282C) +#define ETWIDX1 (SECURITY_BASE+0x2840) +#define ETWL1 (SECURITY_BASE+0x2844) +#define ETWIDX2 (SECURITY_BASE+0x2848) +#define ETWL2 (SECURITY_BASE+0x284C) + +#define ETSPT10 (SECURITY_BASE+0x4000) +#define ETSPT11 (SECURITY_BASE+0x4004) +#define ETSPT12 (SECURITY_BASE+0x4008) +#define ETSPT13 (SECURITY_BASE+0x400C) + +#define ETSPT2000 (SECURITY_BASE+0x6000) +#define ETSPT2020 (SECURITY_BASE+0x6020) +#define ETSPT2024 (SECURITY_BASE+0x6024) + +/* 8084_0000 - 8084_ffff: GPIO */ +#define GPIO_OFFSET 0x040000 +#define GPIO_BASE (EP93XX_APB_BASE|GPIO_OFFSET) +#define GPIO_PADR (GPIO_BASE+0x00) +#define GPIO_PBDR (GPIO_BASE+0x04) +#define GPIO_PCDR (GPIO_BASE+0x08) + +/* For support EP9301 - EP9302 arch */ + +#if !defined(CONFIG_ARCH_EP9301) && !defined (CONFIG_ARCH_EP9302) +#define GPIO_PDDR (GPIO_BASE+0x0C) +#endif + +#define GPIO_PADDR (GPIO_BASE+0x10) +#define GPIO_PBDDR (GPIO_BASE+0x14) +#define GPIO_PCDDR (GPIO_BASE+0x18) + +/* For support EP9301 - EP9302 arch */ + +#if !defined(CONFIG_ARCH_EP9301) && !defined (CONFIG_ARCH_EP9302) +#define GPIO_PDDDR (GPIO_BASE+0x1C) +#endif + +#define GPIO_PEDR (GPIO_BASE+0x20) +#define GPIO_PEDDR (GPIO_BASE+0x24) +#define GPIO_PFDR (GPIO_BASE+0x30) +#define GPIO_PFDDR (GPIO_BASE+0x34) +#define GPIO_PGDR (GPIO_BASE+0x38) +#define GPIO_PGDDR (GPIO_BASE+0x3C) +#define GPIO_PHDR (GPIO_BASE+0x40) +#define GPIO_PHDDR (GPIO_BASE+0x44) +#define GPIO_INTTYPE1 (GPIO_BASE+0x4C) +#define GPIO_INTTYPE2 (GPIO_BASE+0x50) +#define GPIO_FEOI (GPIO_BASE+0x54) /* WRITE ONLY - READ UNDEFINED */ +#define GPIO_INTEN (GPIO_BASE+0x58) +#define GPIO_INTSTATUS (GPIO_BASE+0x5C) +#define GPIO_RAWINTSTASUS (GPIO_BASE+0x60) +#define GPIO_FDB (GPIO_BASE+0x64) +#define GPIO_PAPINDR (GPIO_BASE+0x68) +#define GPIO_PBPINDR (GPIO_BASE+0x6C) +#define GPIO_PCPINDR (GPIO_BASE+0x70) +#define GPIO_PDPINDR (GPIO_BASE+0x74) +#define GPIO_PEPINDR (GPIO_BASE+0x78) +#define GPIO_PFPINDR (GPIO_BASE+0x7C) +#define GPIO_PGPINDR (GPIO_BASE+0x80) +#define GPIO_PHPINDR (GPIO_BASE+0x84) +#define GPIO_AINTTYPE1 (GPIO_BASE+0x90) +#define GPIO_AINTTYPE2 (GPIO_BASE+0x94) +#define GPIO_AEOI (GPIO_BASE+0x98) /* WRITE ONLY - READ UNDEFINED */ +#define GPIO_AINTEN (GPIO_BASE+0x9C) +#define GPIO_INTSTATUSA (GPIO_BASE+0xA0) +#define GPIO_RAWINTSTSTISA (GPIO_BASE+0xA4) +#define GPIO_ADB (GPIO_BASE+0xA8) +#define GPIO_BINTTYPE1 (GPIO_BASE+0xAC) +#define GPIO_BINTTYPE2 (GPIO_BASE+0xB0) +#define GPIO_BEOI (GPIO_BASE+0xB4) /* WRITE ONLY - READ UNDEFINED */ +#define GPIO_BINTEN (GPIO_BASE+0xB8) +#define GPIO_INTSTATUSB (GPIO_BASE+0xBC) +#define GPIO_RAWINTSTSTISB (GPIO_BASE+0xC0) +#define GPIO_BDB (GPIO_BASE+0xC4) +#define GPIO_EEDRIVE (GPIO_BASE+0xC8) +/*#define Reserved (GPIO_BASE+0xCC) */ +#define GPIO_TCR (GPIO_BASE+0xD0) /* Test Registers */ +#define GPIO_TISRA (GPIO_BASE+0xD4) /* Test Registers */ +#define GPIO_TISRB (GPIO_BASE+0xD8) /* Test Registers */ +#define GPIO_TISRC (GPIO_BASE+0xDC) /* Test Registers */ +#define GPIO_TISRD (GPIO_BASE+0xE0) /* Test Registers */ +#define GPIO_TISRE (GPIO_BASE+0xE4) /* Test Registers */ +#define GPIO_TISRF (GPIO_BASE+0xE8) /* Test Registers */ +#define GPIO_TISRG (GPIO_BASE+0xEC) /* Test Registers */ +#define GPIO_TISRH (GPIO_BASE+0xF0) /* Test Registers */ +#define GPIO_TCER (GPIO_BASE+0xF4) /* Test Registers */ + +/* 8088_0000 - 8088_ffff: Ac97 Controller (AAC) */ +#define AC97_OFFSET 0x080000 +#define AC97_BASE (EP93XX_APB_BASE|AC97_OFFSET) +#define AC97DR1 (AC97_BASE+0x00) /* 8088.0000 R/W Data read or written from/to FIFO1 */ +#define AC97RXCR1 (AC97_BASE+0x04) /* 8088.0004 R/W Control register for receive */ +#define AC97TXCR1 (AC97_BASE+0x08) /* 8088.0008 R/W Control register for transmit */ +#define AC97SR1 (AC97_BASE+0x0C) /* 8088.000C R Status register */ +#define AC97RISR1 (AC97_BASE+0x10) /* 8088.0010 R Raw interrupt status register */ +#define AC97ISR1 (AC97_BASE+0x14) /* 8088.0014 R Interrupt Status */ +#define AC97IE1 (AC97_BASE+0x18) /* 8088.0018 R/W Interrupt Enable */ +#define AC97DR2 (AC97_BASE+0x20) /* 8088.0020 R/W Data read or written from/to FIFO2 */ +#define AC97RXCR2 (AC97_BASE+0x24) /* 8088.0024 R/W Control register for receive */ +#define AC97TXCR2 (AC97_BASE+0x28) /* 8088.0028 R/W Control register for transmit */ +#define AC97SR2 (AC97_BASE+0x2C) /* 8088.002C R Status register */ +#define AC97RISR2 (AC97_BASE+0x30) /* 8088.0030 R Raw interrupt status register */ +#define AC97ISR2 (AC97_BASE+0x34) /* 8088.0034 R Interrupt Status */ +#define AC97IE2 (AC97_BASE+0x38) /* 8088.0038 R/W Interrupt Enable */ +#define AC97DR3 (AC97_BASE+0x40) /* 8088.0040 R/W Data read or written from/to FIFO3. */ +#define AC97RXCR3 (AC97_BASE+0x44) /* 8088.0044 R/W Control register for receive */ +#define AC97TXCR3 (AC97_BASE+0x48) /* 8088.0048 R/W Control register for transmit */ +#define AC97SR3 (AC97_BASE+0x4C) /* 8088.004C R Status register */ +#define AC97RISR3 (AC97_BASE+0x50) /* 8088.0050 R Raw interrupt status register */ +#define AC97ISR3 (AC97_BASE+0x54) /* 8088.0054 R Interrupt Status */ +#define AC97IE3 (AC97_BASE+0x58) /* 8088.0058 R/W Interrupt Enable */ +#define AC97DR4 (AC97_BASE+0x60) /* 8088.0060 R/W Data read or written from/to FIFO4. */ +#define AC97RXCR4 (AC97_BASE+0x64) /* 8088.0064 R/W Control register for receive */ +#define AC97TXCR4 (AC97_BASE+0x68) /* 8088.0068 R/W Control register for transmit */ +#define AC97SR4 (AC97_BASE+0x6C) /* 8088.006C R Status register */ +#define AC97RISR4 (AC97_BASE+0x70) /* 8088.0070 R Raw interrupt status register */ +#define AC97ISR4 (AC97_BASE+0x74) /* 8088.0074 R Interrupt Status */ +#define AC97IE4 (AC97_BASE+0x78) /* 8088.0078 R/W Interrupt Enable */ +#define AC97S1DATA (AC97_BASE+0x80) /* 8088.0080 R/W Data received/transmitted on SLOT1 */ +#define AC97S2DATA (AC97_BASE+0x84) /* 8088.0084 R/W Data received/transmitted on SLOT2 */ +#define AC97S12DATA (AC97_BASE+0x88) /* 8088.0088 R/W Data received/transmitted on SLOT12 */ +#define AC97RGIS (AC97_BASE+0x8C) /* 8088.008C R/W Raw Global interrupt status register */ +#define AC97GIS (AC97_BASE+0x90) /* 8088.0090 R Global interrupt status register */ +#define AC97IM (AC97_BASE+0x94) /* 8088.0094 R/W Interrupt mask register */ +#define AC97EOI (AC97_BASE+0x98) /* 8088.0098 W Interrupt clear register */ +#define AC97GCR (AC97_BASE+0x9C) /* 8088.009C R/W Main Control register */ +#define AC97RESET (AC97_BASE+0xA0) /* 8088.00A0 R/W RESET control register. */ +#define AC97SYNC (AC97_BASE+0xA4) /* 8088.00A4 R/W SYNC control register. */ +#define AC97GCIS (AC97_BASE+0xA8) /* 8088.00A8 R Global chan FIFO int status register */ + +/* 808A_0000 - 808A_ffff: SSP */ +#define SSP_OFFSET 0x0A0000 +#define SSP_BASE (EP93XX_APB_BASE|SSP_OFFSET) +#define SSPCR0 (SSP_BASE+0x00) +#define SSPCR1 (SSP_BASE+0x04) +#define SSPDR (SSP_BASE+0x08) +#define SSPSR (SSP_BASE+0x0c) +#define SSPCPSR (SSP_BASE+0x10) +#define SSPIIR (SSP_BASE+0x14) +#define SSPICR (SSP_BASE+0x14) + +/* 808B_0000 - 808B_ffff: IrDA */ +#define IRDA_OFFSET 0x0B0000 +#define IRDA_BASE (EP93XX_APB_BASE|IRDA_OFFSET) +#define IrEnable (IRDA_BASE+0x00) +#define IrCtrl (IRDA_BASE+0x04) +#define IrAdrMatchVal (IRDA_BASE+0x08) +#define IrFlag (IRDA_BASE+0x0C) +#define IrData (IRDA_BASE+0x10) +#define IrDataTail1 (IRDA_BASE+0x14) +#define IrDataTail2 (IRDA_BASE+0x18) +#define IrDataTail3 (IRDA_BASE+0x1c) +#define IrRIB (IRDA_BASE+0x20) +#define IrTR0 (IRDA_BASE+0x24) +#define IrDMACR (IRDA_BASE+0x28) +#define SIRTR0 (IRDA_BASE+0x30) +#define MISR (IRDA_BASE+0x80) +#define MIMR (IRDA_BASE+0x84) +#define MIIR (IRDA_BASE+0x88) +#define FISR (IRDA_BASE+0x180) +#define FIMR (IRDA_BASE+0x184) +#define FIIR (IRDA_BASE+0x188) + +/* 808C_0000 - 808C_ffff: UART1 */ +#define UART1_OFFSET 0x0C0000 +#define UART1_BASE (EP93XX_APB_BASE|UART1_OFFSET) +#define UART1DR (UART1_BASE+0x000) +#define UART1RSR (UART1_BASE+0x004) +#define UART1ECR (UART1_BASE+0x004) +#define UART1CR_H (UART1_BASE+0x008) +#define UART1CR_M (UART1_BASE+0x00C) +#define UART1CR_L (UART1_BASE+0x010) +#define UART1CR (UART1_BASE+0x014) +#define UART1FR (UART1_BASE+0x018) +#define UART1IIR (UART1_BASE+0x01C) +#define UART1ICR (UART1_BASE+0x01C) +#define UART1ILPR (UART1_BASE+0x020) +#define UART1DMACR (UART1_BASE+0x028) +#define UART1TMR (UART1_BASE+0x084) +#define UART1MCR (UART1_BASE+0x100) +#define UART1MSR (UART1_BASE+0x104) +#define UART1TCR (UART1_BASE+0x108) +#define UART1TISR (UART1_BASE+0x10C) +#define UART1TOCR (UART1_BASE+0x110) +#define HDLC1CR (UART1_BASE+0x20c) +#define HDLC1AMV (UART1_BASE+0x210) +#define HDLC1AMSK (UART1_BASE+0x214) +#define HDLC1RIB (UART1_BASE+0x218) +#define HDLC1SR (UART1_BASE+0x21c) + +/* 808d_0000 - 808d_ffff: UART2 */ +#define UART2_OFFSET 0x0D0000 +#define UART2_BASE (EP93XX_APB_BASE|UART2_OFFSET) +#define UART2DR (UART2_BASE+0x00) +#define UART2RSR (UART2_BASE+0x04) /* Read */ +#define UART2ECR (UART2_BASE+0x04) /* Write */ +#define UART2CR_H (UART2_BASE+0x08) +#define UART2CR_M (UART2_BASE+0x0C) +#define UART2CR_L (UART2_BASE+0x10) +#define UART2CR (UART2_BASE+0x14) +#define UART2FR (UART2_BASE+0x18) +#define UART2IIR (UART2_BASE+0x1C) /* Read */ +#define UART2ICR (UART2_BASE+0x1C) /* Write */ +#define UART2ILPR (UART2_BASE+0x20) +#define UART2DMACR (UART2_BASE+0x28) +#define UART2TMR (UART2_BASE+0x84) + +/* 808e_0000 - 808e_ffff: UART3 */ +#define UART3_OFFSET 0x0E0000 +#define UART3_BASE (EP93XX_APB_BASE|UART3_OFFSET) +#define UART3DR (UART3_BASE+0x00) +#define UART3RSR (UART3_BASE+0x04) /* Read */ +#define UART3ECR (UART3_BASE+0x04) /* Write */ +#define UART3CR_H (UART3_BASE+0x08) +#define UART3CR_M (UART3_BASE+0x0C) +#define UART3CR_L (UART3_BASE+0x10) +#define UART3CR (UART3_BASE+0x14) +#define UART3FR (UART3_BASE+0x18) +#define UART3IIR (UART3_BASE+0x1C) /* Read */ +#define UART3ICR (UART3_BASE+0x1C) /* Write */ +#define UART3ILPR (UART3_BASE+0x20) +#define UART3DMACR (UART3_BASE+0x28) +#define UART3TCR (UART3_BASE+0x80) +#define UART3TISR (UART3_BASE+0x88) +#define UART3TOCR (UART3_BASE+0x8C) +#define UART3TMR (UART3_BASE+0x84) +#define UART3MCR (UART3_BASE+0x100) /* Modem Control Reg */ +#define UART3MSR (UART3_BASE+0x104) /* Modem Status Reg */ +#define UART3HDLCCR (UART3_BASE+0x20C) /* HDLC Registers */ +#define UART3HDLCAMV (UART3_BASE+0x210) /* HDLC Registers */ +#define UART3HDLCAMSK (UART3_BASE+0x214) /* HDLC Registers */ +#define UART3HDLCCRIB (UART3_BASE+0x218) /* HDLC Registers */ +#define UART3HDLCSR (UART3_BASE+0x21C) /* HDLC Registers */ + +/* 808f_0000 - 808f_ffff: KEY Matrix */ +#define KEY_OFFSET 0x0F0000 +#define KEY_BASE (EP93XX_APB_BASE|KEY_OFFSET) +#define SCANINIT (KEY_BASE+0x00) +#define KEY_DIAG (KEY_BASE+0x04) +#define KEY_REG (KEY_BASE+0x08) +#define KEY_TCR (KEY_BASE+0x10) +#define KEY_TISR (KEY_BASE+0x14) +#define KEY_TOCR (KEY_BASE+0x18) + +/* 8090_0000 - 8090_ffff: Analog Resistive Touchscreen */ +#define TOUCH_OFFSET 0x100000 +#define TOUCH_BASE (EP93XX_APB_BASE|TOUCH_OFFSET) +#define TSSetup (TOUCH_BASE+0x00) /* R/W touchscreen controller setup control register. */ +#define TSXYMaxMin (TOUCH_BASE+0x04) /* R/W touchscreen controller max/min register. */ +#define TSXYResult (TOUCH_BASE+0x08) /* R touchscreen controller result register. */ +#define TSDischarge (TOUCH_BASE+0x0C) /* LOCKED R/W touchscreen Switch Matrix control register. */ +#define TSXSample (TOUCH_BASE+0x10) /* LOCKED R/W touchscreen Switch Matrix control register. */ +#define TSYSample (TOUCH_BASE+0x14) /* LOCKED R/W touchscreen Switch Matrix control register. */ +#define TSDirect (TOUCH_BASE+0x18) /* LOCKED R/W touchscreen Switch Matrix control register. */ +#define TSDetect (TOUCH_BASE+0x1C) /* LOCKED R/W touchscreen Switch Matrix control register. */ +#define TSSWLock (TOUCH_BASE+0x20) /* NA R/W touchscreen software lock register. */ +#define TSSetup2 (TOUCH_BASE+0x24) /* R/W touchscreen setup control register #2. */ + +/* 8091_0000 - 8091_ffff: PWM */ +#define PWM_OFFSET 0x110000 +#define PWM_BASE (EP93XX_APB_BASE|PWM_OFFSET) +#define PWM0_TC (PWM_BASE+0x00) /* 80910000 R/W PWM_0 Terminal Count */ +#define PWM0_DC (PWM_BASE+0x04) /* 80910004 R/W PWM_0 Duty Cycle */ +#define PWM0_EN (PWM_BASE+0x08) /* 80910008 R/W PWM_0 Enable */ +#define PWM0_INV (PWM_BASE+0x0C) /* 8091000C R/W PWM_0 Invert */ +#define PWM0_SYNC (PWM_BASE+0x10) /* 80910010 R/W PWM_0 Synchronous */ +#define PWM1_TC (PWM_BASE+0x20) /* 80910020 R/W PWM_1 Terminal Count */ +#define PWM1_DC (PWM_BASE+0x24) /* 80910024 R/W PWM_1 Duty Cycle */ +#define PWM1_EN (PWM_BASE+0x28) /* 80910028 R/W PWM_1 Enable */ +#define PWM1_INV (PWM_BASE+0x2C) /* 8091002C R/W PWM_1 Invert */ +#define PWM1_SYNC (PWM_BASE+0x30) /* 80910030 R/W PWM_1 Synchronous */ + +/* 8092_0000 - 8092_ffff: RTC */ +#define RTC_OFFSET 0x120000 +#define RTC_BASE (EP93XX_APB_BASE|RTC_OFFSET) +#define RTCDR (RTC_BASE+0x00) +#define RTCMR (RTC_BASE+0x04) +#define RTCSTAT (RTC_BASE+0x08) /* Read */ +#define RTCEOI (RTC_BASE+0x08) /* Write */ +#define RTCLR (RTC_BASE+0x0C) +#define RTCCR (RTC_BASE+0x10) +#define RTCSCOMP (RTC_BASE+0x108) + +/* 8093_0000 - 8093_ffff: CSC/Syscon PLL, clock control, & misc. stuff */ +#define SYSCON_OFFSET 0x130000 +#define SYSCON_BASE (EP93XX_APB_BASE|SYSCON_OFFSET) +#define SYSCON_PWRSR (SYSCON_BASE+0x0000) +#define SYSCON_PWRCNT (SYSCON_BASE+0x0004) +#define SYSCON_HALT (SYSCON_BASE+0x0008) +#define SYSCON_STBY (SYSCON_BASE+0x000c) +#define SYSCON_BLEOI (SYSCON_BASE+0x0010) +#define SYSCON_MCEOI (SYSCON_BASE+0x0014) +#define SYSCON_TEOI (SYSCON_BASE+0x0018) +#define SYSCON_STFCLR (SYSCON_BASE+0x001c) +#define SYSCON_CLKSET1 (SYSCON_BASE+0x0020) +#define SYSCON_CLKSET2 (SYSCON_BASE+0x0024) +#define SYSCON_RESV00 (SYSCON_BASE+0x0028) +#define SYSCON_RESV01 (SYSCON_BASE+0x002c) +#define SYSCON_RESV02 (SYSCON_BASE+0x0030) +#define SYSCON_RESV03 (SYSCON_BASE+0x0034) +#define SYSCON_RESV04 (SYSCON_BASE+0x0038) +#define SYSCON_RESV05 (SYSCON_BASE+0x003c) +#define SYSCON_SCRREG0 (SYSCON_BASE+0x0040) +#define SYSCON_SCRREG1 (SYSCON_BASE+0x0044) +#define SYSCON_CLKTEST (SYSCON_BASE+0x0048) +#define SYSCON_USBRESET (SYSCON_BASE+0x004c) +#define SYSCON_APBWAIT (SYSCON_BASE+0x0050) +#define SYSCON_BMAR (SYSCON_BASE+0x0054) +#define SYSCON_BOOTCLR (SYSCON_BASE+0x0058) +#define SYSCON_DEVCFG (SYSCON_BASE+0x0080) +#define SYSCON_VIDDIV (SYSCON_BASE+0x0084) +#define SYSCON_MIRDIV (SYSCON_BASE+0x0088) +#define SYSCON_I2SDIV (SYSCON_BASE+0x008C) +#define SYSCON_KTDIV (SYSCON_BASE+0x0090) +#define SYSCON_CHIPID (SYSCON_BASE+0x0094) +#define SYSCON_TSTCR (SYSCON_BASE+0x0098) +#define SYSCON_SYSCFG (SYSCON_BASE+0x009C) +#define SYSCON_SWLOCK (SYSCON_BASE+0x00C0) + +#define SYSCON_DEVCFG_KEYS 0x00000002 +#define SYSCON_DEVCFG_RasOnP3 0x00000010 +#define SYSCON_DEVCFG_GONK 0x08000000 + +#define SYSCON_KTDIV_KEN 0x00008000 + +/* 8094_0000 - 8094_ffff: Watchdog */ +#define WATCHDOG_OFFSET 0x140000 +#define WATCHDOG_BASE (EP93XX_APB_BASE|WATCHDOG_OFFSET) +#define WATCHDOG (WATCHDOG_BASE+0x00) +#define WDSTATUS (WATCHDOG_BASE+0x04) + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-ep93xx/regs_ac97.h b/include/asm-arm/arch-ep93xx/regs_ac97.h new file mode 100644 index 0000000..efe0015 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_ac97.h @@ -0,0 +1,168 @@ +/*============================================================================= + * FILE: regs_ac97.h + * + * DESCRIPTION: Ac'97 Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + *============================================================================= + */ +#ifndef _REGS_AC97_H_ +#define _REGS_AC97_H_ + +/* Bit definitionses */ +#define AC97ISR_RIS 8 +#define AC97ISR_TIS 4 +#define AC97ISR_RTIS 2 +#define AC97ISR_TCIS 1 + +#define AC97RGIS_SLOT1TXCOMPLETE 0x01 +#define AC97RGIS_SLOT2RXVALID 0x02 +#define AC97RGIS_GPIOTXCOMPLETE 0x04 +#define AC97RGIS_GPIOINTRX 0x08 +#define AC97RGIS_RWIS 0x10 +#define AC97RGIS_CODECREADY 0x20 +#define AC97RGIS_SLOT2TXCOMPLETE 0x40 + +#define AC97SR_RXFE 0x0001 +#define AC97SR_TXFE 0x0002 +#define AC97SR_RXFF 0x0004 +#define AC97SR_TXFF 0x0008 +#define AC97SR_TXBUSY 0x0010 +#define AC97SR_RXOE 0x0020 +#define AC97SR_TXUE 0x0040 + +#define AC97GSR_IFE 0x1 +#define AC97GSR_LOOP 0x2 +#define AC97GSR_OVERRIDECODECREADY 0x4 + +#define AC97RESET_TIMEDRESET 0x1 +#define AC97RESET_FORCEDRESET 0x2 +#define AC97RESET_EFORCER 0x4 + +#define AC97RXCR_REN 0x1 + +#define AC97TXCR_TEN 0x1 + +/* + * The Ac97 Codec registers, accessable through the Ac-link. + * These are not controller registers and are not memory mapped. + * Includes registers specific to CS4202 (Beavis). + */ +#define AC97_REG_OFFSET_MASK 0x0000007E + +#define AC97_00_RESET 0x00000000 +#define AC97_02_MASTER_VOL 0x00000002 +#define AC97_04_HEADPHONE_VOL 0x00000004 +#define AC97_06_MONO_VOL 0x00000006 +#define AC97_08_TONE 0x00000008 +#define AC97_0A_PC_BEEP_VOL 0x0000000A +#define AC97_0C_PHONE_VOL 0x0000000C +#define AC97_0E_MIC_VOL 0x0000000E +#define AC97_10_LINE_IN_VOL 0x00000010 +#define AC97_12_CD_VOL 0x00000012 +#define AC97_14_VIDEO_VOL 0x00000014 +#define AC97_16_AUX_VOL 0x00000016 +#define AC97_18_PCM_OUT_VOL 0x00000018 +#define AC97_1A_RECORD_SELECT 0x0000001A +#define AC97_1C_RECORD_GAIN 0x0000001C +#define AC97_1E_RESERVED_1E 0x0000001E +#define AC97_20_GENERAL_PURPOSE 0x00000020 +#define AC97_22_3D_CONTROL 0x00000022 +#define AC97_24_MODEM_RATE 0x00000024 +#define AC97_26_POWERDOWN 0x00000026 +#define AC97_28_EXT_AUDIO_ID 0x00000028 +#define AC97_2A_EXT_AUDIO_POWER 0x0000002A +#define AC97_2C_PCM_FRONT_DAC_RATE 0x0000002C +#define AC97_2E_PCM_SURR_DAC_RATE 0x0000002E +#define AC97_30_PCM_LFE_DAC_RATE 0x00000030 +#define AC97_32_PCM_LR_ADC_RATE 0x00000032 +#define AC97_34_MIC_ADC_RATE 0x00000034 +#define AC97_36_6CH_VOL_C_LFE 0x00000036 +#define AC97_38_6CH_VOL_SURROUND 0x00000038 +#define AC97_3A_SPDIF_CONTROL 0x0000003A +#define AC97_3C_EXT_MODEM_ID 0x0000003C +#define AC97_3E_EXT_MODEM_POWER 0x0000003E +#define AC97_40_LINE1_CODEC_RATE 0x00000040 +#define AC97_42_LINE2_CODEC_RATE 0x00000042 +#define AC97_44_HANDSET_CODEC_RATE 0x00000044 +#define AC97_46_LINE1_CODEC_LEVEL 0x00000046 +#define AC97_48_LINE2_CODEC_LEVEL 0x00000048 +#define AC97_4A_HANDSET_CODEC_LEVEL 0x0000004A +#define AC97_4C_GPIO_PIN_CONFIG 0x0000004C +#define AC97_4E_GPIO_PIN_TYPE 0x0000004E +#define AC97_50_GPIO_PIN_STICKY 0x00000050 +#define AC97_52_GPIO_PIN_WAKEUP 0x00000052 +#define AC97_54_GPIO_PIN_STATUS 0x00000054 +#define AC97_56_RESERVED 0x00000056 +#define AC97_58_RESERVED 0x00000058 +#define AC97_5A_CRYSTAL_REV_N_FAB_ID 0x0000005A +#define AC97_5C_TEST_AND_MISC_CTRL 0x0000005C +#define AC97_5E_AC_MODE 0x0000005E +#define AC97_60_MISC_CRYSTAL_CONTROL 0x00000060 +#define AC97_62_VENDOR_RESERVED 0x00000062 +#define AC97_64_DAC_SRC_PHASE_INCR 0x00000064 +#define AC97_66_ADC_SRC_PHASE_INCR 0x00000066 +#define AC97_68_RESERVED_68 0x00000068 +#define AC97_6A_SERIAL_PORT_CONTROL 0x0000006A +#define AC97_6C_VENDOR_RESERVED 0x0000006C +#define AC97_6E_VENDOR_RESERVED 0x0000006E +#define AC97_70_BDI_CONFIG 0x00000070 +#define AC97_72_BDI_WAKEUP 0x00000072 +#define AC97_74_VENDOR_RESERVED 0x00000074 +#define AC97_76_CAL_ADDRESS 0x00000076 +#define AC97_78_CAL_DATA 0x00000078 +#define AC97_7A_VENDOR_RESERVED 0x0000007A +#define AC97_7C_VENDOR_ID1 0x0000007C +#define AC97_7E_VENDOR_ID2 0x0000007E + +#ifndef __ASSEMBLY__ + +/* enum type for use with reg AC97_RECORD_SELECT */ +enum Ac97RecordSources { + RECORD_MIC = 0x0000, + RECORD_CD = 0x0101, + RECORD_VIDEO_IN = 0x0202, + RECORD_AUX_IN = 0x0303, + RECORD_LINE_IN = 0x0404, + RECORD_STEREO_MIX = 0x0505, + RECORD_MONO_MIX = 0x0606, + RECORD_PHONE_IN = 0x0707 +}; + +#endif /* __ASSEMBLY__ */ + +/* + * Sample rates supported directly in AC97_PCM_FRONT_DAC_RATE and + * AC97_PCM_LR_ADC_RATE. + */ +#define Ac97_Fs_8000 0x1f40 +#define Ac97_Fs_11025 0x2b11 +#define Ac97_Fs_16000 0x3e80 +#define Ac97_Fs_22050 0x5622 +#define Ac97_Fs_32000 0x7d00 +#define Ac97_Fs_44100 0xac44 +#define Ac97_Fs_48000 0xbb80 + +/* + * RSIZE and TSIZE in AC97RXCR and AC97TXCR + */ +#define Ac97_SIZE_20 2 +#define Ac97_SIZE_18 1 +#define Ac97_SIZE_16 0 +#define Ac97_SIZE_12 3 + +#endif /* _REGS_AC97_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_dma.h b/include/asm-arm/arch-ep93xx/regs_dma.h new file mode 100644 index 0000000..926965d --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_dma.h @@ -0,0 +1,269 @@ +/***************************************************************************** + * + * linux/include/asm-arm/arch-ep93xx/regs_dma.h + * + * Register definitions for the ep93xx dma channel registers. + * + * Copyright (C) 2003 Cirrus Logic + * + * 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 + * + ****************************************************************************/ +#ifndef _REGS_DMA_H_ +#define _REGS_DMA_H_ + +/***************************************************************************** + * 0x8000.0000 -> 0x8000.003C M2P Channel 0 Registers (Tx) + * 0x8000.0040 -> 0x8000.007C M2P Channel 1 Registers (Rx) + * 0x8000.0080 -> 0x8000.00BC M2P Channel 2 Registers (Tx) + * 0x8000.00C0 -> 0x8000.00FC M2P Channel 3 Registers (Rx) + * 0x8000.0100 -> 0x8000.013C M2M Channel 0 Registers + * 0x8000.0140 -> 0x8000.017C M2M Channel 1 Registers + * 0x8000.0180 -> 0x8000.01BC Not Used + * 0x8000.01C0 -> 0x8000.01FC Not Used + * 0x8000.0200 -> 0x8000.023C M2P Channel 5 Registers (Rx) + * 0x8000.0240 -> 0x8000.027C M2P Channel 4 Registers (Tx) + * 0x8000.0280 -> 0x8000.02BC M2P Channel 7 Registers (Rx) + * 0x8000.02C0 -> 0x8000.02FC M2P Channel 6 Registers (Tx) + * 0x8000.0300 -> 0x8000.033C M2P Channel 9 Registers (Rx) + * 0x8000.0340 -> 0x8000.037C M2P Channel 8 Registers (Tx) + * 0x8000.0380 DMA Channel Arbitration register + * 0x8000.03C0 DMA Global Interrupt register + * 0x8000.03C4 -> 0x8000.03FC Not Used + * + * + * Internal M2P/P2M Channel Register Map + * + * Offset Name Access Bits Reset Value + * 0x00 CONTROL R/W 6 0 + * 0x04 INTERRUPT R/W TC* 3 0 + * 0x08 PPALLOC R/W 4 channel dependant + * (see reg description) + * 0x0C STATUS RO 8 0 + * 0x10 reserved + * 0x14 REMAIN RO 16 0 + * 0X18 Reserved + * 0X1C Reserved + * 0x20 MAXCNT0 R/W 16 0 + * 0x24 BASE0 R/W 32 0 + * 0x28 CURRENT0 RO 32 0 + * 0x2C Reserved + * 0x30 MAXCNT1 R/W 16 0 + * 0x34 BASE1 R/W 32 0 + * 0X38 CURRENT1 RO 32 0 + * 0X3C Reserved + * + * M2M Channel Register Map + * Offset Name Access Bits Reset Value + * + * 0x00 CONTROL R/W 22 0 + * 0x04 INTERRUPT R/W TC* 3 0 + * 0x08 Reserved + * 0x0C STATUS R/W TC* 14 0 + * 0x10 BCR0 R/W 16 0 + * 0x14 BCR1 R/W 16 0 + * 0x18 SAR_BASE0 R/W 32 0 + * 0x1C SAR_BASE1 R/W 32 0 + * 0x20 Reserved + * 0x24 SAR_CURRENT0 RO 32 0 + * 0x28 SAR_CURRENT1 RO 32 0 + * 0x2C DAR_BASE0 R/W 32 0 + * 0x30 DAR_BASE1 R/W 32 0 + * 0x34 DAR_CURRENT0 RO 32 0 + * 0X38 Reserved + * 0X3C DAR_CURRENT1 RO 32 0 + * * Write this location once to clear the bit (see + * Interrupt/Status register description for which bits + * this rule applies to). + * + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* + * DMA Register Base addresses + */ +static unsigned int const DMAM2PChannelBase[10] = { + DMA_M2P_TX_0_BASE, + DMA_M2P_RX_1_BASE, + DMA_M2P_TX_2_BASE, + DMA_M2P_RX_3_BASE, + DMA_M2P_TX_4_BASE, + DMA_M2P_RX_5_BASE, + DMA_M2P_TX_6_BASE, + DMA_M2P_RX_7_BASE, + DMA_M2P_TX_8_BASE, + DMA_M2P_RX_9_BASE +}; + +static unsigned int const DMAM2MChannelBase[2] = { + DMA_M2M_0_BASE, + DMA_M2M_1_BASE +}; + +#endif /* __ASSEMBLY__ */ + +/*----------------------------------------------------------------------------------*/ +/* M2P Registers */ +/*----------------------------------------------------------------------------------*/ +/* + * M2P CONTROL register bit defines + */ +#define CONTROL_M2P_STALLINTEN 0x00000001 /* Enables the STALL interrupt */ +#define CONTROL_M2P_NFBINTEN 0x00000002 /* Enables the NFB interrupt */ +#define CONTROL_M2P_CHERRORINTEN 0x00000008 /* Enables the ChError interrupt */ +#define CONTROL_M2P_ENABLE 0x00000010 /* Enables the channel */ +#define CONTROL_M2P_ABRT 0x00000020 /* Determines how DMA behaves in */ + /* NEXT state with peripheral */ + /* error */ + /* 0: NEXT -> ON, ignore error */ + /* 1: NEXT -> STALL, disable ch. */ +#define CONTROL_M2P_ICE 0x00000040 /* Ignore Channel Error */ + +/* + * M2P INTERRUPT register bit defines + */ +#define INTERRUPT_M2P_STALLINT 0x00000001 /* Indicates channel stalled. */ +#define INTERRUPT_M2P_NFBINT 0x00000002 /* Indicates channel is hungry. */ +#define INTERRUPT_M2P_CHERRORINT 0x00000008 /* Peripheral detects error */ + +/* + * STATUS register bit defines + */ +#define STATUS_M2P_STALL 0x00000001 /* A '1' indicates channel is */ + /* stalled */ +#define STATUS_M2P_NFB 0x00000002 /* A '1' indicates channel has moved */ + /* from NEXT state to ON state, but */ + /* waiting for next buffer to be */ + /* programmed. */ +#define STATUS_M2P_CHERROR 0x00000008 /* Enables the ChError interrupt */ +#define STATUS_M2P_CURRENT_MASK 0x00000030 /* Current state of the FSM */ +#define STATUS_M2P_CURRENT_SHIFT 4 +#define STATUS_M2P_NEXTBUFFER 0x00000040 /* Informs the int handler after an */ + /* NFB int which pair of maxcnt and */ + /* base regs to update. */ +#define STATUS_M2P_BYTES_MASK 0x0000f800 /* number of valid DMA data */ +#define STATUS_M2P_BYTES_SHIFT 7 /* currently in */ + /* packer/unpacker */ + +#define STATUS_M2P_DMA_NO_BUF 0x00000000 +#define STATUS_M2P_DMA_BUF_ON 0x00000010 +#define STATUS_M2P_DMA_BUF_NEXT 0x00000020 + +/* + * Register masks to mask off reserved bits after reading register. + */ +#define M2P_MASK_PPALLOC 0x0000000f +#define M2P_MASK_REMAIN 0x0000ffff +#define M2P_MASK_MAXCNT0 0x0000ffff +#define M2P_MASK_BASE0 0xffffffff +#define M2P_MASK_CURRENT0 0xffffffff +#define M2P_MASK_MAXCNT1 0x0000ffff +#define M2P_MASK_BASE1 0xffffffff +#define M2P_MASK_CURRENT1 0xffffffff + +/*----------------------------------------------------------------------------------*/ +/* M2M Registers */ +/*----------------------------------------------------------------------------------*/ + +#define CONTROL_M2M_STALLINTEN 0x00000001 /* Enables the STALL interrupt */ +#define CONTROL_M2M_SCT 0x00000002 /* Source Copy Transfer. Setup a */ + /* block transfer from 1 memory source */ + /* location. */ +#define CONTROL_M2M_DONEINTEN 0x00000004 /* Enables the DONE interrupt which */ + /* indicates if the xfer completed */ + /* successfully */ +#define CONTROL_M2M_ENABLE 0x00000008 /* Enables the channel */ +#define CONTROL_M2M_START 0x00000010 /* Initiates the xfer. 'software trigger' */ +#define CONTROL_M2M_BWC_MASK 0x000001e0 /* Bandwidth control. Indicate number of */ +#define CONTROL_M2M_BWC_SHIFT 5 /* bytes in a transfer. */ +#define CONTROL_M2M_PW_MASK 0x00000600 /* Peripheral width. Used for xfers */ +#define CONTROL_M2M_PW_SHIFT 9 /* between memory and external peripheral. */ + /* 00: byte, 01: halfword, 10: word. */ +#define CONTROL_M2M_DAH 0x00000800 /* Destination Address Hold */ +#define CONTROL_M2M_SAH 0x00001000 /* Source Address Hold */ +#define CONTROL_M2M_TM_MASK 0x00006000 /* Transfer Mode. 00: sw triggered, */ +#define CONTROL_M2M_TM_SHIFT 13 /* 01: hw initiated M2P, 01: hw initiated P2M */ +#define CONTROL_M2M_ETDP_MASK 0x00018000 /* End-of-Transfer/Terminal Count pin */ +#define CONTROL_M2M_ETDP_SHIFT 15 /* direction and polarity. */ +#define CONTROL_M2M_DACKP 0x00020000 /* DMA acknowledge pin polarity */ + +#define CONTROL_M2M_DREQP_MASK 0x00180000 /* DMA request pin polarity. must be set */ +#define CONTROL_M2M_DREQP_SHIFT 19 /* before enable bit. */ +#define CONTROL_M2M_NFBINTEN 0x00200000 /* Enables generation of the NFB interrupt. */ +#define CONTROL_M2M_RSS_MASK 0x00c00000 /* Request source selection: */ +#define CONTROL_M2M_RSS_SHIFT 22 /* 000 - External DReq[0] */ + /* 001 - External DReq[1] */ + /* 01X - Internal SSPRx */ + /* 10X - Internal SSPTx */ + /* 11X - Internal IDE */ +#define CONTROL_M2M_NO_HDSK 0x01000000 /* No handshake. When set the peripheral doesn't */ + /* require the regular handshake protocal. Must */ + /* be set for SSP and IDE operations, optional */ + /* for external peripherals. */ +#define CONTROL_M2M_PWSC_MASK 0xfe000000 /* Peripheral wait states count. Gives the latency */ +#define CONTROL_M2M_PWSC_SHIFT 25 /* (in PCLK cycles) needed by the peripheral to */ + /* deassert its' request once the M2M xfer w/ DMA */ + /* is complete. */ + +/* + * M2M INTERRUPT register bit defines + */ +#define INTERRUPT_M2M_STALLINT 0x00000001 /* Stall interrupt indicates channel stalled. */ +#define INTERRUPT_M2M_DONEINT 0x00000002 /* Transaction done. */ +#define INTERRUPT_M2M_NFBINT 0x00000004 /* Next frame buffer interrupt indicates */ + /* channel requires a new buffer */ + +/* + * M2M STATUS register bit defines + */ +#define STATUS_M2M_STALL 0x00000001 /* A '1' indicates channel is stalled */ +#define STATUS_M2M_CURRENTSTATE_MASK 0x0000003e /* Indicates state of M2M Channel control */ +#define STATUS_M2M_CURRENTSTATE_SHIFT 1 /* FSM (0-2): */ + /* 000 - IDLE, 001 - STALL, 010 - MEM_RD, */ + /* 011 - MEM_WR, 100 - BWC_WAIT */ + /* and M2M buffer FSM (3-2): */ + /* 00 - NO_BUF, 01 - BUF_ON, 10 - BUF_NEXT */ +#define STATUS_M2M_DONE 0x00000040 /* Transfer completed successfully if 1. */ +#define STATUS_M2M_TCS_MASK 0x00000180 /* Terminal Count status. Indicates whether or */ +#define STATUS_M2M_TCS_SHIFT 7 /* or not the actual byte count reached */ + /* programmed limit for buffer descriptor */ +#define STATUS_M2M_EOTS_MASK 0x00000600 /* End-of-Transfer status for buffer */ +#define STATUS_M2M_EOTS_SHIFT 9 +#define STATUS_M2M_NFB 0x00000800 /* A '1' indicates channel has moved */ + /* from NEXT state to ON state, but the next */ + /* byte count reg for next buffer has not been */ + /* programmed yet. */ +#define STATUS_M2M_NB 0x00001000 /* NextBuffer status. Informs NFB service */ + /* routine, after NFB int, which pair of buffer */ + /* descriptor registers is free to update. */ +#define STATUS_M2M_DREQS 0x00002000 /* DREQ status. Reflects the status of the */ + /* synchronized external peripherals DMA */ + /* request signal. */ + +/* + * Register masks to mask off reserved bits after reading register. + */ +#define M2M_MASK_BCR0 0x0000ffff +#define M2M_MASK_BCR1 0x0000ffff +#define M2M_MASK_SAR_BASE0 0xffffffff +#define M2M_MASK_SAR_BASE1 0xffffffff +#define M2M_MASK_SAR_CURRENT0 0xffffffff +#define M2M_MASK_SAR_CURRENT1 0xffffffff +#define M2M_MASK_DAR_BASE0 0xffffffff +#define M2M_MASK_DAR_BASE1 0xffffffff +#define M2M_MASK_DAR_CURRENT0 0xffffffff +#define M2M_MASK_DAR_CURRENT1 0xffffffff + +#endif /* _REGS_DMA_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_gpio.h b/include/asm-arm/arch-ep93xx/regs_gpio.h new file mode 100644 index 0000000..12397be --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_gpio.h @@ -0,0 +1,31 @@ +/*======================================================================= + * + * FILE: regs_gpio.h + * + * DESCRIPTION: GPIO Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + *======================================================================= + */ +#ifndef _REGS_GPIO_H_ +#define _REGS_GPIO_H_ + +/* + * This file intentionally blank. + */ + +#endif /* _REGS_GPIO_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_hardcode.h b/include/asm-arm/arch-ep93xx/regs_hardcode.h new file mode 100644 index 0000000..ecbc512 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_hardcode.h @@ -0,0 +1,110 @@ +/* + * File: linux/include/asm-arm/arch-ep93xx/regs_hardcode.h + * + * Handle 'Must-be-zero' and 'Must-be-one' values for various + * registers on different flavours of the EP93xx family. + * + * Copyright (C) 2004 Ray Lehtiniemi + * + * 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 + */ + +#ifndef __ASM_ARCH_HARDCODE_H +#define __ASM_ARCH_HARDCODE_H + +#if defined(CONFIG_ARCH_EP9301) +#define ep93xx_SYSCON_DEVCFG(v) (((v) & ~0x0460c220) | 0x08000d00) +#define ep93xx_VIC0INTSELECT(v) (((v) & ~0xf8080000) | 0x00000000) +#define ep93xx_VIC1INTSELECT(v) (((v) & ~0x06879a04) | 0x00000000) +#define ep93xx_VIC0INTENABLE(v) (((v) & ~0xf8080000) | 0x00000000) +#define ep93xx_VIC1INTENABLE(v) (((v) & ~0x06879a04) | 0x00000000) +#define ep93xx_VIC0INTENCLEAR(v) (((v) & ~0xf8080000) | 0x00000000) +#define ep93xx_VIC1INTENCLEAR(v) (((v) & ~0x06879a04) | 0x00000000) +#define ep93xx_MAC_RXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_UART1MCR(v) (((v) & ~0x000000e0) | 0x00000000) +#define ep93xx_UART2TMR(v) (((v) & ~0x000000fd) | 0x00000000) +#define ep93xx_IrCtrl(v) (((v) & ~0x00000001) | 0x00000000) +#define ep93xx_RTCSCOMP(v) (((v) & ~0x00200000) | 0x00000000) + +/* cut'n'paste from 9301, verify this section... */ +#elif defined(CONFIG_ARCH_EP9302) +#define ep93xx_SYSCON_DEVCFG(v) (((v) & ~0x0460c220) | 0x08000d00) +#define ep93xx_VIC0INTSELECT(v) (((v) & ~0xf8080000) | 0x00000000) +#define ep93xx_VIC1INTSELECT(v) (((v) & ~0x06879a04) | 0x00000000) +#define ep93xx_VIC0INTENABLE(v) (((v) & ~0xf8080000) | 0x00000000) +#define ep93xx_VIC1INTENABLE(v) (((v) & ~0x06879a04) | 0x00000000) +#define ep93xx_VIC0INTENCLEAR(v) (((v) & ~0xf8080000) | 0x00000000) +#define ep93xx_VIC1INTENCLEAR(v) (((v) & ~0x06879a04) | 0x00000000) +#define ep93xx_MAC_RXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_UART1MCR(v) (((v) & ~0x000000e0) | 0x00000000) +#define ep93xx_UART2TMR(v) (((v) & ~0x000000fd) | 0x00000000) +#define ep93xx_IrCtrl(v) (((v) & ~0x00000001) | 0x00000000) +#define ep93xx_RTCSCOMP(v) (((v) & ~0x00200000) | 0x00000000) + +#elif defined(CONFIG_ARCH_EP9312) +#define ep93xx_SYSCON_DEVCFG(v) (((v) & ~0x00000020) | 0x00000000) +#define ep93xx_VIC0INTSELECT(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC1INTSELECT(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC0INTENABLE(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC1INTENABLE(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC0INTENCLEAR(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC1INTENCLEAR(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_PIXELMODE(v) (((v) & ~0x00010000) | 0x00000000) +#define ep93xx_MAC_RXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_UART1MCR(v) (((v) & ~0x000000e0) | 0x00000000) +#define ep93xx_UART2TMR(v) (((v) & ~0x000000fd) | 0x00000000) +#define ep93xx_UART3MCR(v) (((v) & ~0x000000e0) | 0x00000000) +#define ep93xx_IrCtrl(v) (((v) & ~0x00000001) | 0x00000000) +#define ep93xx_RTCSCOMP(v) (((v) & ~0x00200000) | 0x00000000) + +#elif defined(CONFIG_ARCH_EP9315) +#define ep93xx_SYSCON_DEVCFG(v) (((v) & ~0x00000020) | 0x00000000) +#define ep93xx_VIC0INTSELECT(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC1INTSELECT(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC0INTENABLE(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC1INTENABLE(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC0INTENCLEAR(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_VIC1INTENCLEAR(v) (((v) & ~0x00000000) | 0x00000000) +#define ep93xx_PIXELMODE(v) (((v) & ~0x00010000) | 0x00000000) +#define ep93xx_MAC_RXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXBUFTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXSTSTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_RXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_MAC_TXDTHRSHLD(v) (((v) & ~0x00030003) | 0x00000000) +#define ep93xx_UART1MCR(v) (((v) & ~0x000000e0) | 0x00000000) +#define ep93xx_UART2TMR(v) (((v) & ~0x000000fd) | 0x00000000) +#define ep93xx_UART3MCR(v) (((v) & ~0x000000e0) | 0x00000000) +#define ep93xx_IrCtrl(v) (((v) & ~0x00000001) | 0x00000000) +#define ep93xx_RTCSCOMP(v) (((v) & ~0x00200000) | 0x00000000) + +#endif + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-ep93xx/regs_i2s.h b/include/asm-arm/arch-ep93xx/regs_i2s.h new file mode 100644 index 0000000..2ca60df --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_i2s.h @@ -0,0 +1,91 @@ +/*============================================================================= + * + * FILE: reg_i2s.h + * + * DESCRIPTION: ep93xx I2S Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + * + *============================================================================= + */ +#ifndef _REG_I2S_H_ +#define _REG_I2S_H_ + +/* I2STXClkCfg bits */ +#define i2s_txcc_trls 0x00000001 +#define i2s_txcc_tckp 0x00000002 +#define i2s_txcc_trel 0x00000004 +#define i2s_txcc_mstr 0x00000008 +#define i2s_txcc_nbcg 0x00000010 + +#define i2s_txcc_bcr_32x 0x00000020 +#define i2s_txcc_bcr_64x 0x00000040 +#define i2s_txcc_bcr_128x 0x00000060 + +/* I2SRxClkCfg bits */ +#define i2s_rxcc_rrls 0x00000001 +#define i2s_rxcc_rckp 0x00000002 +#define i2s_rxcc_rrel 0x00000004 +#define i2s_rxcc_mstr 0x00000008 +#define i2s_rxcc_nbcg 0x00000010 + +#define i2s_rxcc_bcr_32x 0x00000020 +#define i2s_rxcc_bcr_64x 0x00000040 +#define i2s_rxcc_bcr_128x 0x00000060 + +/* I2SGlSts bits */ +#define TX0_UNDERFLOW 0x00000001 +#define TX1_UNDERFLOW 0x00000002 +#define TX2_UNDERFLOW 0x00000004 + +#define RX0_OVERFLOW 0x00000008 +#define RX1_OVERFLOW 0x00000010 +#define RX2_OVERFLOW 0x00000020 + +#define TX0_OVERFLOW 0x00000040 +#define TX1_OVERFLOW 0x00000080 +#define TX2_OVERFLOW 0x00000100 + +#define RX0_UNDERFLOW 0x00000200 +#define RX1_UNDERFLOW 0x00000400 +#define RX2_UNDERFLOW 0x00000800 + +#define TX0_FIFO_FULL 0x00001000 +#define TX0_FIFO_EMPTY 0x00002000 +#define TX0_FIFO_HALF_EMPTY 0x00004000 + +#define RX0_FIFO_FULL 0x00008000 +#define RX0_FIFO_EMPTY 0x00010000 +#define RX0_FIFO_HALF_FULL 0x00020000 + +#define TX1_FIFO_FULL 0x00040000 +#define TX1_FIFO_EMPTY 0x00080000 +#define TX1_FIFO_HALF_EMPTY 0x00100000 + +#define RX1_FIFO_FULL 0x00200000 +#define RX1_FIFO_EMPTY 0x00400000 +#define RX1_FIFO_HALF_FULL 0x00800000 + +#define TX2_FIFO_FULL 0x01000000 +#define TX2_FIFO_EMPTY 0x02000000 +#define TX2_FIFO_HALF_EMPTY 0x04000000 + +#define RX2_FIFO_FULL 0x08000000 +#define RX2_FIFO_EMPTY 0x10000000 +#define RX2_FIFO_HALF_FULL 0x20000000 + +#endif diff --git a/include/asm-arm/arch-ep93xx/regs_ide.h b/include/asm-arm/arch-ep93xx/regs_ide.h new file mode 100644 index 0000000..762ebfd --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_ide.h @@ -0,0 +1,250 @@ +/***************************************************************************** + * + * linux/include/asm-arm/arch-ep93xx/regs_ide.h + * + * Register definitions for the ep93xx ide registers. + * + * Copyright (C) 2003 Cirrus Logic + * + * 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 + + * + ****************************************************************************/ +#ifndef _REGS_IDE_H_ +#define _REGS_IDE_H_ + +#ifndef __ASSEMBLY__ + +/***************************************************************************** + * + * IDE register definitions + * + ****************************************************************************/ +typedef struct _ide_regs_s { + union { + unsigned int Value; + } IDECR; /* 00 */ + + union { + struct { + unsigned int IDEEN:1; /* IDE master enable */ + unsigned int PIO:1; /* Polled IO operation selection */ + unsigned int MDMA:1; /* Multiword DMA operation selection */ + unsigned int UDMA:1; /* Ultra DMA operation selection */ + unsigned int MODE:4; /* Speed mode number (0 - 4 for PIO, */ + /* 0 - 2 for MDMA, 0 - 4 for UDMA) */ + unsigned int WST:2; /* Wait State for Turn. Number of */ + /* HCLK cycles to hold the data bus */ + /* after */ + /* PIO write operation */ + unsigned int RAZ:22; /* read only always zero */ + } Field; + unsigned int Value; + } IDECFG; /* 04 */ + + union { + struct { + unsigned int MEN:1; /* Enable Multiword DMA operation. */ + /* 1 - start mdma, 0 - terminate */ + /* mdma operation by host. */ + unsigned int RWOP:1; /* Read or write operation selection: */ + /* 0 = read, 1 = write. */ + unsigned int RAZ:30; /* read only always zero */ + } Field; + unsigned int Value; + } IDEMDMAOP; /* 08 */ + + union { + struct { + unsigned int UEN:1; /* Enable Ultra DMA operation */ + /* 1 - start udma, 0 - terminate */ + /* udma operation by host. */ + unsigned int RWOP:1; /* Read or write operation selection: */ + /* 0 = read, 1 = write. */ + unsigned int RAZ:30; /* read only always zero */ + } Field; + unsigned int Value; + } IDEUDMAOP; /* 0C */ + + union { + unsigned int Value; + } IDEDATAOUT; /* 10 */ + + union { + unsigned int Value; + } IDEDATAIN; /* 14 */ + + union { + struct { + unsigned int IDEDD:32; /* IDE output data in the output buffer */ + /* in MDMA mode. This register should */ + /* only be written to by the DMA engine. */ + } Field; + unsigned int Value; + } IDEMDMADATAOUT; /* 18 */ + + union { + struct { + unsigned int IDEDD:32; /* IDE input data in the input buffer */ + /* in MDMA mode. */ + } Field; + unsigned int Value; + } IDEMDMADATAIN; /* 1C */ + + union { + struct { + unsigned int IDEDD:32; /* IDE output data at the tail of the */ + /* output buffer in UDMA mode. */ + } Field; + unsigned int Value; + } IDEUDMADATAOUT; /* 20 */ + + union { + struct { + unsigned int IDEDD:32; /* IDE input data at teh head of the */ + /* input buffer in UDMA mode. */ + } Field; + unsigned int Value; + } IDEUDMADATAIN; /* 24 */ + + union { + struct { + unsigned int CS0n:1; /* Chip select pin 0 status. Should */ + /* be driven to 1 (deasserted) in UDMA */ + unsigned int CS1n:1; /* Chip select pin 1 status. Should */ + /* be driven to 1 (deasserted) in UDMA */ + unsigned int DA:3; /* Device address status, should be */ + /* driven to 0 (deasserted) in UDMA */ + unsigned int HSHD:1; /* HSTROBE (during data out) status, */ + /* HDMARDYn (during data in) status, */ + /* driven by UDMA state machine. */ + unsigned int STOP:1; /* STOP (during data out) status, driven */ + /* by UDMA state machine. */ + unsigned int DM:1; /* DMACKn status, driven by UDMA state */ + /* machine. */ + unsigned int DDOE:1; /* DD bus output enable as controlled */ + /* by UDMA state machine. */ + unsigned int DMARQ:1; /* Synchronized version of DMARQ input */ + /* from device. */ + unsigned int DSDD:1; /* DSTROBE (during data in) and DDMARDYn */ + /* (during data out) status from device. */ + unsigned int RAZ1:5; /* reserved, always zero */ + unsigned int DMAIDE:1; /* DMA request signal from UDMA state */ + /* machine. */ + unsigned int INTIDE:1; /* INT line generated by UDMA state */ + /* machine. */ + unsigned int SBUSY:1; /* UDMA state machine busy, not in idle */ + /* state. */ + unsigned int RAZ2:5; /* Reserved, always zero. */ + unsigned int NDO:1; /* Error for data out not completed */ + unsigned int NDI:1; /* Error for data in not completed */ + unsigned int N4X:1; /* Error for data transferred not */ + /* multiples of 4 32 bit words. */ + unsigned int RAZ3:5; /* Reserved, always zero */ + } Field; + unsigned int Value; + } IDEUDMASTATUS; /* 28 */ + + union { + struct { + unsigned int RWOE:1; /* Reset UDMA write data out error. */ + unsigned int RWPTR:1; /* Reset UDMA write buffer ptr to 0. */ + unsigned int RWDR:1; /* Reset UDMA write DMA request. */ + unsigned int RROE:1; /* Reset UDMA read data in error. */ + unsigned int RRPTR:1; /* Reset UDMA read buffer ptr to 0. */ + unsigned int RRDR:1; /* Reset UDMA read DMA request. */ + unsigned int RAZ:26; /* reserved, always zero */ + } Field; + unsigned int Value; + } IDEUDMADEBUG; /* 2C */ + + union { + struct { + unsigned int HPTR:4; /* Head pointer in the write buffer */ + unsigned int TPTR:4; /* Tail pointer in the write buffer */ + unsigned int EMPTY:1; /* Write buffer empty status */ + unsigned int HOM:1; /* Half or more entries in write buffer */ + /* filled status */ + unsigned int NFULL:1; /* Write buffer near full status */ + unsigned int FULL:1; /* Write buffer full status */ + unsigned int RAZ:4; /* Reserved, always zero */ + unsigned int CRC:16; /* CRC result for data operation */ + /* TODO: is there a CRC? */ + } Field; + unsigned int Value; + } IDEUDMAWFST; /* 30 */ + + union { + struct { + unsigned int HPTR:4; /* Head pointer in the read buffer */ + unsigned int TPTR:4; /* Tail pointer in the read buffer */ + unsigned int EMPTY:1; /* Read buffer empty status */ + unsigned int HOM:1; /* Half or more entries in read buffer */ + /* filled status */ + unsigned int NFULL:1; /* Read buffer near full status */ + unsigned int FULL:1; /* Read buffer full status */ + unsigned int RAZ:4; /* Reserved, always zero */ + unsigned int CRC:16; /* CRC result for data operation */ + /* TODO: is there a CRC? */ + } Field; + unsigned int Value; + } IDEUDMARFST; /* 34 */ + +} IDEREGISTERS; + +/***************************************************************************** + * + * Global Register Anchor Definitions (these address values will change) + * + ****************************************************************************/ +#ifdef CONFIG_BLK_DEV_EP93XX +static volatile IDEREGISTERS *const ep93xx_ide_regs = + (IDEREGISTERS *) (IDE_BASE); +#endif + +#endif /* Not __ASSEMBLY__ */ + +#define IDECtrl HW_REG(io_p2v(0x800a0000)) +#define IDECfg HW_REG(io_p2v(0x800a0004)) +#define IDEMDMAOp HW_REG(io_p2v(0x800a0008)) +#define IDEUDMAOp HW_REG(io_p2v(0x800a000c)) +#define IDEDataOut HW_REG(io_p2v(0x800a0010)) +#define IDEDataIn HW_REG(io_p2v(0x800a0014)) +#define IDEMDMADataOut HW_REG(io_p2v(0x800a0018)) +#define IDEMDMADataIn HW_REG(io_p2v(0x800a001c)) +#define IDEUDMADataOut HW_REG(io_p2v(0x800a0020)) +#define IDEUDMADataIn HW_REG(io_p2v(0x800a0024)) +#define IDEUDMASts HW_REG(io_p2v(0x800a0028)) +#define IDEUDMADebug HW_REG(io_p2v(0x800a002c)) +#define IDEUDMAWrBufSts HW_REG(io_p2v(0x800a0030)) +#define IDEUDMARdBufSts HW_REG(io_p2v(0x800a0034)) + +/***************************************************************************** + * + * Bit definitions for use with assembly code for the ide control register. + * + ****************************************************************************/ +#define IDECtrl_CS0n 0x00000001 +#define IDECtrl_CS1n 0x00000002 +#define IDECtrl_DA_MASK 0x0000001c +#define IDECtrl_DA_SHIFT 2 +#define IDECtrl_DIORn 0x00000020 +#define IDECtrl_DIOWn 0x00000040 +#define IDECtrl_DASPn 0x00000080 +#define IDECtrl_DMARQ 0x00000100 +#define IDECtrl_INTRQ 0x00000200 +#define IDECtrl_IORDY 0x00000400 + +#endif /* _REGS_IDE_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_irda.h b/include/asm-arm/arch-ep93xx/regs_irda.h new file mode 100644 index 0000000..77edafa --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_irda.h @@ -0,0 +1,24 @@ +/*======================================================================= + * + * FILE: regs_irda.h + * + * DESCRIPTION: IrDA Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + *======================================================================= + */ +#ifndef _REGS_IRDA_H_ +#define _REGS_IRDA_H_ + +/* Bit definitions */ + +#define IrEnable_EN_NONE 0x00 +#define IrEnable_EN_SIR 0x01 +#define IrEnable_EN_MIR 0x02 +#define IrEnable_EN_FIR 0x03 +#define IrEnable_LBM 0x04 +#define IrEnable_MD 0x08 +#define IrEnable_FD 0x10 + +#endif /* _REGS_IRDA_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_pcmcia.h b/include/asm-arm/arch-ep93xx/regs_pcmcia.h new file mode 100644 index 0000000..6f731e7 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_pcmcia.h @@ -0,0 +1,72 @@ +/* + * linux/include/asm-arm/arch-ep93xx/regs-pcmcia.h + * + * Derived from: + * linux/include/asm-arm/arch-pxa/pxa-regs.h + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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. + */ + +/* + * Personal Computer Memory Card International Association (PCMCIA) sockets + * (from pxa-regs.h for compatibility) + */ +#ifndef _REGS_PCMCIA_H_ +#define _REGS_PCMCIA_H_ + +#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */ +#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */ +#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */ +#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */ +#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */ + +#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */ +#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */ +#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */ +#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */ + +#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */ +#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */ +#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */ +#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */ + + +#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ + (0x40000000 + (Nb)*PCMCIASp) +#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */ +#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ + (_PCMCIA (Nb) + 2*PCMCIAPrtSp) +#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ + (_PCMCIA (Nb) + 3*PCMCIAPrtSp) + +#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */ +#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */ +#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */ +#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */ + +#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */ +#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */ +#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */ +#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */ + +#define PCATTRIB(sock) ((sock ==0) ? (PC1ATTRIB) : (PC2ATTRIB)) +#define PCCOMMON(sock) ((sock ==0) ? (PC1COMMON) : (PC2COMMON)) +#define PCIO(sock) ((sock ==0) ? (PC1IO) : (PC2IO)) + +#define PC16BITSWIDE 0x80000000 + +#define PCMCIA_WRPROT 0x01 +#define PCMCIA_DETECT 0x06 +#define PCMCIA_BVD1 0x08 +#define PCMCIA_BVD2 0x10 +#define PCMCIA_VS_3V 0x20 +#define PCMCIA_READY 0x40 +#define PCMCIA_VS_XV 0x80 + +#endif /* _REGS_PCMCIA_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_raster.h b/include/asm-arm/arch-ep93xx/regs_raster.h new file mode 100644 index 0000000..bfab3ed --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_raster.h @@ -0,0 +1,279 @@ +/*============================================================================= + * + * FILE: regs_raster.h + * + * DESCRIPTION: ep93xx Raster Engine Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + * + *============================================================================= + */ +#ifndef _REGS_RASTER_H_ +#define _REGS_RASTER_H_ + +/* VLINESTOTAL Register Definitions */ +#define VLINESTOTAL_MASK 0x000007ff + +/* VSYNCSTRTSTOP Register Definitions */ +#define VSYNCSTRTSTOP_STRT_MASK 0x07ff0000 +#define VSYNCSTRTSTOP_STRT_SHIFT 0 +#define VSYNCSTRTSTOP_STOP_MASK 0x000007ff +#define VSYNCSTRTSTOP_STOP_SHIFT 16 + +/* VACTIVESTRTSTOP Register Definitions */ +#define VACTIVESTRTSTOP_STRT_MASK 0x07ff0000 +#define VACTIVESTRTSTOP_STRT_SHIFT 0 +#define VACTIVESTRTSTOP_STOP_MASK 0x000007ff +#define VACTIVESTRTSTOP_STOP_SHIFT 16 + +/* VCLKSTRTSTOP Register Definitions */ +#define VCLKSTRTSTOP_STRT_MASK 0x07ff0000 +#define VCLKSTRTSTOP_STRT_SHIFT 0 +#define VCLKSTRTSTOP_STOP_MASK 0x000007ff +#define VCLKSTRTSTOP_STOP_SHIFT 16 + +/* VBLANKSTRTSTOP Register Definitions */ +#define VBLANKSTRTSTOP_STRT_MASK 0x07ff0000 +#define VBLANKSTRTSTOP_STRT_SHIFT 0 +#define VBLANKSTRTSTOP_STOP_MASK 0x000007ff +#define VBLANKSTRTSTOP_STOP_SHIFT 16 + +/* HSYNCSTRTSTOP Register Definitions */ +#define HSYNCSTRTSTOP_STRT_MASK 0x07ff0000 +#define HSYNCSTRTSTOP_STRT_SHIFT 0 +#define HSYNCSTRTSTOP_STOP_MASK 0x000007ff +#define HSYNCSTRTSTOP_STOP_SHIFT 16 + +/* HACTIVESTRTSTOP Register Definitions */ +#define HACTIVESTRTSTOP_STRT_MASK 0x07ff0000 +#define HACTIVESTRTSTOP_STRT_SHIFT 0 +#define HACTIVESTRTSTOP_STOP_MASK 0x000007ff +#define HACTIVESTRTSTOP_STOP_SHIFT 16 + +/* HCLKSTRTSTOP Register Definitions */ +#define HCLKSTRTSTOP_STRT_MASK 0x07ff0000 +#define HCLKSTRTSTOP_STRT_SHIFT 0 +#define HCLKSTRTSTOP_STOP_MASK 0x000007ff +#define HCLKSTRTSTOP_STOP_SHIFT 16 + +/* BRIGHTNESS Register Definitions */ +#define BRIGHTNESS_MASK 0x0000ffff +#define BRIGHTNESS_CNT_MASK 0x000000ff +#define BRIGHTNESS_CNT_SHIFT 0 +#define BRIGHTNESS_CMP_MASK 0x0000ff00 +#define BRIGHTNESS_CMP_SHIFT 8 + +/* VIDEOATTRIBS Register Definitions */ +#define VIDEOATTRIBS_MASK 0x001fffff +#define VIDEOATTRIBS_EN 0x00000001 +#define VIDEOATTRIBS_PCLKEN 0x00000002 +#define VIDEOATTRIBS_SYNCEN 0x00000004 +#define VIDEOATTRIBS_DATAEN 0x00000008 +#define VIDEOATTRIBS_CSYNC 0x00000010 +#define VIDEOATTRIBS_VCPOL 0x00000020 +#define VIDEOATTRIBS_HSPOL 0x00000040 +#define VIDEOATTRIBS_BLKPOL 0x00000080 +#define VIDEOATTRIBS_INVCLK 0x00000100 +#define VIDEOATTRIBS_ACEN 0x00000200 +#define VIDEOATTRIBS_LCDEN 0x00000400 +#define VIDEOATTRIBS_RGBEN 0x00000800 +#define VIDEOATTRIBS_CCIREN 0x00001000 +#define VIDEOATTRIBS_PIFEN 0x00002000 +#define VIDEOATTRIBS_INTEN 0x00004000 +#define VIDEOATTRIBS_INT 0x00008000 +#define VIDEOATTRIBS_INTRLC 0x00010000 +#define VIDEOATTRIBS_EQUSER 0x00020000 +#define VIDEOATTRIBS_DHORZ 0x00040000 +#define VIDEOATTRIBS_DVERT 0x00080000 +#define VIDEOATTRIBS_BKPXD 0x00100000 + +#define VIDEOATTRIBS_SDSEL_MASK 0x00600000 +#define VIDEOATTRIBS_SDSEL_SHIFT 21 + +/* HBLANKSTRTSTOP Register Definitions */ +#define HBLANKSTRTSTOP_STRT_MASK 0x07ff0000 +#define HBLANKSTRTSTOP_STRT_SHIFT 0 +#define HBLANKSTRTSTOP_STOP_MASK 0x000007ff +#define HBLANKSTRTSTOP_STOP_SHIFT 16 + +/* LINECARRY Register Definitions */ +#define LINECARRY_LCARY_MASK 0x000007ff +#define LINECARRY_LCARY_SHIFT 0 + +/* BLINKRATE Register Definitons */ +#define BLINKRATE_MASK 0x000000ff + +/* BLINKMASK Register Definitons */ +#define BLINKMASK_MASK 0x00ffffff + +/* VIDSCRNPAGE Register Definitons */ +#define VIDSCRNPAGE_PAGE_MASK 0x0ffffffc + +/* VIDSCRNHPG Register Definitons */ +#define VIDSCRNHPG_MASK 0x0ffffffc + +/* SCRNLINES Register Definitons */ +#define SCRNLINES_MASK 0x000007ff + +/* LINELENGTH Register Definitons */ +#define LINELENGTH_MASK 0x000007ff + +/* VLINESTEP Register Definitons */ +#define VLINESTEP_MASK 0x00000fff + +/* REALITI_SWLOCK Register Definitons */ +#define REALITI_SWLOCK_MASK_WR 0xff +#define REALITI_SWLOCK_MASK_R 0x1 +#define REALITI_SWLOCK_VALUE 0xaa + +/* LUTCONT Register Definitions */ +#define LUTCONT_MASK 0x00000003 +#define LUTCONT_SWTCH 0x00000001 +#define LUTCONT_STAT 0x00000002 +#define LUTCONT_RAM0 0 +#define LUTCONT_RAM1 1 + +/* CURSORBLINK1 Register Definitions */ +#define CURSORBLINK1_MASK 0x00ffffff +/* CURSORBLINK2 Register Definitions */ +#define CURSORBLINK2_MASK 0x00ffffff + +/* CURSORBLINK Register Definitions */ +#define CURSORBLINK_MASK 0x000001ff +#define CURSORBLINK_RATE_MASK 0x000000ff +#define CURSORBLINK_RATE_SHIFT 0 +#define CURSORBLINK_EN 0x00000100 + +/* BLINKPATRN Register Definitions */ +#define BLINKPATRN_MASK 0x00ffffff + +/* PATRNMASK Register Definitions */ +#define PATRNMASK_MASK 0x00ffffff + +/* BG_OFFSET Register Definitions */ +#define BG_OFFSET_MASK 0x00ffffff + +/* PIXELMODE Register Definitions */ +#define PIXELMODE_P_MASK 0x00000007 +#define PIXELMODE_P_MUX_DISABLE 0x00000000 +#define PIXELMODE_P_4BPP 0x00000001 +#define PIXELMODE_P_8BPP 0x00000002 +#define PIXELMODE_P_16BPP 0x00000004 +#define PIXELMODE_P_24BPP 0x00000006 +#define PIXELMODE_P_32BPP 0x00000007 +#define PIXELMODE_P_SHIFT 0 + +#define PIXELMODE_S_MASK 0x00000038 +#define PIXELMODE_S_SHIFT 3 +#define PIXELMODE_S_1PPC 0x0 +#define PIXELMODE_S_1PPCMAPPED 0x1 +#define PIXELMODE_S_2PPC 0x2 +#define PIXELMODE_S_4PPC 0x3 +#define PIXELMODE_S_8PPC 0x4 +#define PIXELMODE_S_223PPC 0x5 +#define PIXELMODE_S_DS223PPC 0x6 +#define PIXELMODE_S_UNDEF 0x7 + +#define PIXELMODE_M_MASK 0x000003c0 +#define PIXELMODE_M_SHIFT 6 +#define PIXELMODE_M_NOBLINK 0 +#define PIXELMODE_M_ANDBLINK 1 +#define PIXELMODE_M_ORBLINK 2 +#define PIXELMODE_M_XORBLINK 3 +#define PIXELMODE_M_BGBLINK 4 +#define PIXELMODE_M_OFFSINGBLINK 5 +#define PIXELMODE_M_OFF888BLINK 6 +#define PIXELMODE_M_DIMBLINK 0xc +#define PIXELMODE_M_BRTBLINK 0xd +#define PIXELMODE_M_DIM888BLINK 0xe +#define PIXELMODE_M_BRT888BLINK 0xf + +#define PIXELMODE_C_MASK 0x00003c00 +#define PIXELMODE_C_SHIFT 10 +#define PIXELMODE_C_LUT 0 +#define PIXELMODE_C_888 4 +#define PIXELMODE_C_565 5 +#define PIXELMODE_C_555 6 +#define PIXELMODE_C_GSLUT 8 + +#define PIXELMODE_DSCAN 0x00004000 +#define PIXELMODE_TRBSW 0x00008000 +#define PIXELMODE_P13951 0x00010000 + +/*PARLLIFOUT Register Defintions */ +#define PARLLIFOUT_DAT_MASK 0x0000000f +#define PARLLIFOUT_DAT_SHIFT 0 +#define PARLLIFOUT_RD 0x00000010 + +/*PARLLIFIN Register Defintions */ +#define PARLLIFIN_DAT_MASK 0x0000000f +#define PARLLIFIN_DAT_SHIFT 0 +#define PARLLIFIN_CNT_MASK 0x000f0000 +#define PARLLIFIN_CNT_SHIFT 16 +#define PARLLIFIN_ESTRT_MASK 0x00f00000 +#define PARLLIFIN_ESTRT_SHIFT 20 + +/* CURSORADRSTART Register Defintions */ +#define CURSOR_ADR_START_MASK 0xfffffffc + +/* CURSORADRSTART Register Defintions */ +#define CURSOR_ADR_RESET_MASK 0xfffffffc + +/* CURSORCOLOR1 Register Definitions */ +#define CURSORCOLOR1_MASK 0x00ffffff +/* CURSORCOLOR2 Register Definitions */ +#define CURSORCOLOR2_MASK 0x00ffffff + +/* CURSORXYLOC Register Definitions */ +#define CURSORXYLOC_MASK 0x07ff87ff +#define CURSORXYLOC_XLOC_MASK 0x000007ff +#define CURSORXYLOC_XLOC_SHIFT 0 +#define CURSORXYLOC_CEN 0x00008000 +#define CURSORXYLOC_YLOC_MASK 0x07ff0000 +#define CURSORXYLOC_YLOC_SHIFT 16 + +/* CURSOR_DSCAN_LH_YLOC Register Definitions */ +#define CURSOR_DSCAN_LH_YLOC_MASK 0x000087ff + +#define CURSOR_DSCAN_LH_YLOC_YLOC_MASK 0x000007ff +#define CURSOR_DSCAN_LH_YLOC_YLOC_SHIFT 0 +#define CURSOR_DSCAN_LH_YLOC_CLHEN 0x00008000 + +/* CURSORSIZE Register Definitions */ +#define CURSORSIZE_MASK 0x0000ffff + +#define CURSORSIZE_CWID_MASK 0x00000003 +#define CURSORSIZE_CWID_SHIFT 0 +#define CURSORSIZE_CWID_1_WORD 0 +#define CURSORSIZE_CWID_2_WORD 1 +#define CURSORSIZE_CWID_3_WORD 2 +#define CURSORSIZE_CWID_4_WORD 3 + +#define CURSORSIZE_CLINS_MASK 0x000000fc +#define CURSORSIZE_CLINS_SHIFT 2 + +#define CURSORSIZE_CSTEP_MASK 0x00000300 +#define CURSORSIZE_CSTEP_SHIFT 8 +#define CURSORSIZE_CSTEP_1_WORD 0 +#define CURSORSIZE_CSTEP_2_WORD 1 +#define CURSORSIZE_CSTEP_3_WORD 2 +#define CURSORSIZE_CSTEP_4_WORD 3 + +#define CURSORSIZE_DLNS_MASK 0x0000fc00 +#define CURSORSIZE_DLNS_SHIFT 10 + +#endif diff --git a/include/asm-arm/arch-ep93xx/regs_spi.h b/include/asm-arm/arch-ep93xx/regs_spi.h new file mode 100644 index 0000000..a51d3dc --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_spi.h @@ -0,0 +1,76 @@ +/*======================================================================= + * + * FILE: regs_spi.h + * + * DESCRIPTION: SSP Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + *======================================================================= + */ + +#ifndef _REGS_SSP_H_ +#define _REGS_SSP_H_ + +/* Bits in SSPCR0 */ +#define SSPCR0_DSS_MASK 0x0000000f +#define SSPCR0_DSS_4BIT 0x00000003 +#define SSPCR0_DSS_5BIT 0x00000004 +#define SSPCR0_DSS_6BIT 0x00000005 +#define SSPCR0_DSS_7BIT 0x00000006 +#define SSPCR0_DSS_8BIT 0x00000007 +#define SSPCR0_DSS_9BIT 0x00000008 +#define SSPCR0_DSS_10BIT 0x00000009 +#define SSPCR0_DSS_11BIT 0x0000000a +#define SSPCR0_DSS_12BIT 0x0000000b +#define SSPCR0_DSS_13BIT 0x0000000c +#define SSPCR0_DSS_14BIT 0x0000000d +#define SSPCR0_DSS_15BIT 0x0000000e +#define SSPCR0_DSS_16BIT 0x0000000f + +/* Bits in SSPCR1 */ +#define SSPC1_RIE 0x00000001 +#define SSPC1_TIE 0x00000002 +#define SSPC1_RORIE 0x00000004 +#define SSPC1_LBM 0x00000008 +#define SSPC1_SSE 0x00000010 +#define SSPC1_MS 0x00000020 +#define SSPC1_SOD 0x00000040 + +#define SSPCR0_DSS_SHIFT 0 +#define SSPCR0_FRF_MASK 0x00000030 +#define SSPCR0_FRF_SHIFT 4 +#define SSPCR0_FRF_MOTOROLA (0 << SSPCR0_FRF_SHIFT) +#define SSPCR0_FRF_TI (1 << SSPCR0_FRF_SHIFT) +#define SSPCR0_FRF_NI (2 << SSPCR0_FRF_SHIFT) +#define SSPCR0_SPO 0x00000040 +#define SSPCR0_SPH 0x00000080 +#define SSPCR0_SCR_MASK 0x0000ff00 +#define SSPCR0_SCR_SHIFT 8 + +/* Bits in SSPSR */ +#define SSPSR_TFE 0x00000001 /* TX FIFO is empty */ +#define SSPSR_TNF 0x00000002 /* TX FIFO is not full */ +#define SSPSR_RNE 0x00000004 /* RX FIFO is not empty */ +#define SSPSR_RFF 0x00000008 /* RX FIFO is full */ +#define SSPSR_BSY 0x00000010 /* SSP is busy */ + +/* Bits in SSPIIR */ +#define SSPIIR_RIS 0x00000001 /* RX FIFO IRQ status */ +#define SSPIIR_TIS 0x00000002 /* TX FIFO is not full */ +#define SSPIIR_RORIS 0x00000004 /* RX FIFO is full */ + +#endif diff --git a/include/asm-arm/arch-ep93xx/regs_syscon.h b/include/asm-arm/arch-ep93xx/regs_syscon.h new file mode 100644 index 0000000..271cfcd --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_syscon.h @@ -0,0 +1,257 @@ +/*============================================================================= + * + * FILE: reg_syscon.h + * + * DESCRIPTION: ep93xx Syscon Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + * + *============================================================================= + */ +#ifndef _REGS_SYSCON_H_ +#define _REGS_SYSCON_H_ + +#ifndef __ASSEMBLY__ + +#define SysconSetLocked(registername,value) \ + { \ + writel( 0xAA, SYSCON_SWLOCK); \ + writel( value, registername); \ + } + +#endif /* Not __ASSEMBLY__ */ + +/* SYSCON_CLKSET1 */ +#define SYSCON_CLKSET1_PLL1_X2IPD_SHIFT 0 +#define SYSCON_CLKSET1_PLL1_X2IPD_MASK 0x0000001f +#define SYSCON_CLKSET1_PLL1_X2FBD2_SHIFT 5 +#define SYSCON_CLKSET1_PLL1_X2FBD2_MASK 0x000007e0 +#define SYSCON_CLKSET1_PLL1_X1FBD1_SHIFT 11 +#define SYSCON_CLKSET1_PLL1_X1FBD1_MASK 0x0000f800 +#define SYSCON_CLKSET1_PLL1_PS_SHIFT 16 +#define SYSCON_CLKSET1_PLL1_PS_MASK 0x00030000 +#define SYSCON_CLKSET1_PCLKDIV_SHIFT 18 +#define SYSCON_CLKSET1_PCLKDIV_MASK 0x000c0000 +#define SYSCON_CLKSET1_HCLKDIV_SHIFT 20 +#define SYSCON_CLKSET1_HCLKDIV_MASK 0x00700000 +#define SYSCON_CLKSET1_nBYP1 0x00800000 +#define SYSCON_CLKSET1_SMCROM 0x01000000 +#define SYSCON_CLKSET1_FCLKDIV_SHIFT 25 +#define SYSCON_CLKSET1_FCLKDIV_MASK 0x0e000000 + +#define SYSCON_CLKSET1_HSEL 0x00000001 +#define SYSCON_CLKSET1_PLL1_EXCLKSEL 0x00000002 + +#define SYSCON_CLKSET1_PLL1_P_MASK 0x0000007C +#define SYSCON_CLKSET1_PLL1_P_SHIFT 2 + +#define SYSCON_CLKSET1_PLL1_M1_MASK 0x00000780 +#define SYSCON_CLKSET1_PLL1_M1_SHIFT 7 +#define SYSCON_CLKSET1_PLL1_M2_MASK 0x0000F800 +#define SYSCON_CLKSET1_PLL1_M2_SHIFT 11 +#define SYSCON_CLKSET1_PLL1_PS_MASK 0x00030000 +#define SYSCON_CLKSET1_PLL1_PS_SHIFT 16 +#define SYSCON_CLKSET1_PCLK_DIV_MASK 0x000C0000 +#define SYSCON_CLKSET1_PCLK_DIV_SHIFT 18 +#define SYSCON_CLKSET1_HCLK_DIV_MASK 0x00700000 +#define SYSCON_CLKSET1_HCLK_DIV_SHIFT 20 +#define SYSCON_CLKSET1_SMCROM 0x01000000 +#define SYSCON_CLKSET1_FCLK_DIV_MASK 0x0E000000 +#define SYSCON_CLKSET1_FCLK_DIV_SHIFT 25 + +#define SYSCON_CLKSET2_PLL2_EN 0x00000001 +#define SYSCON_CLKSET2_PLL2EXCLKSEL 0x00000002 +#define SYSCON_CLKSET2_PLL2_P_MASK 0x0000007C +#define SYSCON_CLKSET2_PLL2_P_SHIFT 2 +#define SYSCON_CLKSET2_PLL2_M2_MASK 0x00000F80 +#define SYSCON_CLKSET2_PLL2_M2_SHIFT 7 +#define SYSCON_CLKSET2_PLL2_M1_MASK 0x0001F000 +#define SYSCON_CLKSET2_PLL2_M1 12 +#define SYSCON_CLKSET2_PLL2_PS_MASK 0x000C0000 +#define SYSCON_CLKSET2_PLL2_PS_SHIFT 18 +#define SYSCON_CLKSET2_USBDIV_MASK 0xF0000000 +#define SYSCON_CLKSET2_USBDIV_SHIFT 28 + +/* DEV_CFG Register Defines */ +#define SYSCON_DEVCFG_SHena 0x00000001 +#define SYSCON_DEVCFG_KEYS 0x00000002 +#define SYSCON_DEVCFG_ADCPD 0x00000004 +#define SYSCON_DEVCFG_RAS 0x00000008 +#define SYSCON_DEVCFG_RASonP3 0x00000010 +#define SYSCON_DEVCFG_TTIC 0x00000020 +#define SYSCON_DEVCFG_I2SonAC97 0x00000040 +#define SYSCON_DEVCFG_I2SonSSP 0x00000080 +#define SYSCON_DEVCFG_EonIDE 0x00000100 +#define SYSCON_DEVCFG_PonG 0x00000200 +#define SYSCON_DEVCFG_GonIDE 0x00000400 +#define SYSCON_DEVCFG_HonIDE 0x00000800 +#define SYSCON_DEVCFG_HC1CEN 0x00001000 +#define SYSCON_DEVCFG_HC1IN 0x00002000 +#define SYSCON_DEVCFG_HC3CEN 0x00004000 +#define SYSCON_DEVCFG_HC3IN 0x00008000 +#define SYSCON_DEVCFG_ADCEN 0x00010000 +#define SYSCON_DEVCFG_TIN 0x00020000 +#define SYSCON_DEVCFG_U1EN 0x00040000 +#define SYSCON_DEVCFG_EXVC 0x00080000 +#define SYSCON_DEVCFG_U2EN 0x00100000 +#define SYSCON_DEVCFG_A1onG 0x00200000 +#define SYSCON_DEVCFG_A2onG 0x00400000 +#define SYSCON_DEVCFG_CPENA 0x00800000 +#define SYSCON_DEVCFG_U3EN 0x01000000 +#define SYSCON_DEVCFG_MonG 0x02000000 +#define SYSCON_DEVCFG_TonG 0x04000000 +#define SYSCON_DEVCFG_GonK 0x08000000 +#define SYSCON_DEVCFG_IonU2 0x10000000 +#define SYSCON_DEVCFG_D0onG 0x20000000 +#define SYSCON_DEVCFG_D1onG 0x40000000 +#define SYSCON_DEVCFG_SWRST 0x80000000 + +/* VIDDIV Register Defines */ +#define SYSCON_VIDDIV_VDIV_MASK 0x0000007f +#define SYSCON_VIDDIV_VDIV_SHIFT 0 +#define SYSCON_VIDDIV_PDIV_MASK 0x00000300 +#define SYSCON_VIDDIV_PDIV_SHIFT 8 +#define SYSCON_VIDDIV_PSEL 0x00002000 +#define SYSCON_VIDDIV_ESEL 0x00004000 +#define SYSCON_VIDDIV_VENA 0x00008000 + +/* MIRDIV Register Defines */ +#define SYSCON_MIRDIV_MDIV_MASK 0x0000003f +#define SYSCON_MIRDIV_MDIV_SHIFT 0 +#define SYSCON_MIRDIV_PDIV_MASK 0x00000300 +#define SYSCON_MIRDIV_PDIV_SHIFT 8 +#define SYSCON_MIRDIV_PSEL 0x00002000 +#define SYSCON_MIRDIV_ESEL 0x00004000 +#define SYSCON_MIRDIV_MENA 0x00008000 + +/* I2SDIV Register Defines */ +#define SYSCON_I2SDIV_MDIV_MASK 0x0000007f +#define SYSCON_I2SDIV_MDIV_SHIFT 0 +#define SYSCON_I2SDIV_PDIV_MASK 0x00000300 +#define SYSCON_I2SDIV_PDIV_SHIFT 8 +#define SYSCON_I2SDIV_PSEL 0x00002000 +#define SYSCON_I2SDIV_ESEL 0x00004000 +#define SYSCON_I2SDIV_MENA 0x00008000 +#define SYSCON_I2SDIV_SDIV 0x00010000 +#define SYSCON_I2SDIV_LRDIV_MASK 0x00060000 +#define SYSCON_I2SDIV_LRDIV_SHIFT 17 +#define SYSCON_I2SDIV_SPOL 0x00080000 +#define SYSCON_I2SDIV_DROP 0x00100000 +#define SYSCON_I2SDIV_ORIDE 0x20000000 +#define SYSCON_I2SDIV_SLAVE 0x40000000 +#define SYSCON_I2SDIV_SENA 0x80000000 + +#define SYSCON_I2SDIV_PDIV_OFF 0x00000000 +#define SYSCON_I2SDIV_PDIV_2 0x00000100 +#define SYSCON_I2SDIV_PDIV_25 0x00000200 +#define SYSCON_I2SDIV_PDIV_3 0x00000300 + +#define SYSCON_I2SDIV_LRDIV_32 0x00000000 +#define SYSCON_I2SDIV_LRDIV_64 0x00020000 +#define SYSCON_I2SDIV_LRDIV_128 0x00040000 + +/* KTDIV Register Defines */ +#define SYSCON_KTDIV_KDIV 0x00000001 +#define SYSCON_KTDIV_KEN 0x00008000 +#define SYSCON_KTDIV_ADIV 0x00010000 +#define SYSCON_KTDIV_TSEN 0x80000000 + +/* CHIPID Register Defines */ +#define SYSCON_CHIPID_ID_MASK 0x0000ffff +#define SYSCON_CHIPID_ID_SHIFT 0 +#define SYSCON_CHIPID_PKID 0x00010000 +#define SYSCON_CHIPID_BND 0x00040000 +#define SYSCON_CHIPID_FAB_MASK 0x0e000000 +#define SYSCON_CHIPID_FAB_SHIFT 25 +#define SYSCON_CHIPID_REV_MASK 0xf0000000 +#define SYSCON_CHIPID_REV_SHIFT 28 + +/* TESTCR Register Defines */ +#define SYSCON_TESTCR_TMODE_MASK 0x000000ff +#define SYSCON_TESTCR_TMODE_SHIFT 0 +#define SYSCON_TESTCR_BONDO 0x00000100 +#define SYSCON_TESTCR_PACKO 0x00000800 +#define SYSCON_TESTCR_ETOM 0x00002000 +#define SYSCON_TESTCR_TOM 0x00004000 +#define SYSCON_TESTCR_OVR 0x00008000 +#define SYSCON_TESTCR_TonIDE 0x00010000 +#define SYSCON_TESTCR_RonG 0x00020000 + +/* SYSCFG Register Defines */ +#define SYSCON_SYSCFG_LCSn1 0x00000001 +#define SYSCON_SYSCFG_LCSn2 0x00000002 +#define SYSCON_SYSCFG_LCSn3 0x00000004 +#define SYSCON_SYSCFG_LEECK 0x00000008 +#define SYSCON_SYSCFG_LEEDA 0x00000010 +#define SYSCON_SYSCFG_LASDO 0x00000020 +#define SYSCON_SYSCFG_LCSn6 0x00000040 +#define SYSCON_SYSCFG_LCSn7 0x00000080 +#define SYSCON_SYSCFG_SBOOT 0x00000100 +#define SYSCON_SYSCFG_FAB_MASK 0x0e000000 +#define SYSCON_SYSCFG_FAB_SHIFT 25 +#define SYSCON_SYSCFG_REV_MASK 0xf0000000 +#define SYSCON_SYSCFG_REV_SHIFT 28 + +/* PWRSR Register Defines */ +#define SYSCON_PWRSR_CHIPMAN_MASK 0xFF000000 +#define SYSCON_PWRSR_CHIPMAN_SHIFT 24 +#define SYSCON_PWRSR_CHIPID_MASK 0x00FF0000 +#define SYSCON_PWRSR_CHIPID_SHIFT 16 +#define SYSCON_PWRSR_WDTFLG 0x00008000 +#define SYSCON_PWRSR_CLDFLG 0x00002000 +#define SYSCON_PWRSR_TEST_RESET 0x00001000 +#define SYSCON_PWRSR_RSTFLG 0x00000800 +#define SYSCON_PWRSR_SWRESET 0x00000400 +#define SYSCON_PWRSR_PLL2_LOCKREG 0x00000200 +#define SYSCON_PWRSR_PLL2_LOCK 0x00000100 +#define SYSCON_PWRSR_PLL1_LOCKREG 0x00000080 +#define SYSCON_PWRSR_PLL1_LOCK 0x00000040 +#define SYSCON_PWRSR_RTCDIV 0x0000003F + +/* PWRCNT Register Defines */ +#define SYSCON_PWRCNT_FIREN 0x80000000 +#define SYSCON_PWRCNT_UARTBAUD 0x20000000 +#define SYSCON_PWRCNT_USHEN 0x10000000 +#define SYSCON_PWRCNT_DMA_M2MCH1 0x08000000 +#define SYSCON_PWRCNT_DMA_M2MCH0 0x04000000 +#define SYSCON_PWRCNT_DMA_M2PCH8 0x02000000 +#define SYSCON_PWRCNT_DMA_M2PCH9 0x01000000 +#define SYSCON_PWRCNT_DMA_M2PCH6 0x00800000 +#define SYSCON_PWRCNT_DMA_M2PCH7 0x00400000 +#define SYSCON_PWRCNT_DMA_M2PCH4 0x00200000 +#define SYSCON_PWRCNT_DMA_M2PCH5 0x00100000 +#define SYSCON_PWRCNT_DMA_M2PCH2 0x00080000 +#define SYSCON_PWRCNT_DMA_M2PCH3 0x00040000 +#define SYSCON_PWRCNT_DMA_M2PCH0 0x00020000 +#define SYSCON_PWRCNT_DMA_M2PCH1 0x00010000 + +/* BMAR Register Defines */ +#define BMAR_PRIORD_00 0x00000000 +#define BMAR_PRIORD_01 0x00000001 +#define BMAR_PRIORD_02 0x00000002 +#define BMAR_PRIORD_03 0x00000003 +#define BMAR_PRI_CORE 0x00000008 +#define BMAR_DMA_ENIRQ 0x00000010 +#define BMAR_DMA_ENFIQ 0x00000020 +#define BMAR_USB_ENIRQ 0x00000040 +#define BMAR_USB_ENFIQ 0x00000080 +#define BMAR_MAC_ENIRQ 0x00000100 +#define BMAR_MAC_ENFIQ 0x00000200 +#define BMAR_GRAPHICS_ENIRQ 0x00000400 +#define BMAR_GRAPHICS_ENFIQ 0x00000800 + +#endif /* _REGS_SYSCON_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_touch.h b/include/asm-arm/arch-ep93xx/regs_touch.h new file mode 100644 index 0000000..aad8a99 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_touch.h @@ -0,0 +1,94 @@ +/*============================================================================= + * + * FILE: regs_touch.h + * + * DESCRIPTION: Analog Touchscreen Register Definition + * + * Copyright Cirrus Logic, 2001-2003 + * + * 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 + *============================================================================= + */ +#ifndef _REGS_TOUCH_H_ +#define _REGS_TOUCH_H_ + +/* + *----------------------------------------------------------------------------- + * Individual bit #defines + *----------------------------------------------------------------------------- + */ +#define TSSETUP_SDLY_MASK 0x000003FF +#define TSSETUP_SDLY_SHIFT 0 +#define TSSETUP_NSMP_4 0x00000000 +#define TSSETUP_NSMP_8 0x00000400 +#define TSSETUP_NSMP_16 0x00000800 +#define TSSETUP_NSMP_32 0x00000C00 +#define TSSETUP_NSMP_MASK 0x00000C00 +#define TSSETUP_DEV_4 0x00000000 +#define TSSETUP_DEV_8 0x00001000 +#define TSSETUP_DEV_12 0x00002000 +#define TSSETUP_DEV_16 0x00003000 +#define TSSETUP_DEV_24 0x00004000 +#define TSSETUP_DEV_32 0x00005000 +#define TSSETUP_DEV_64 0x00006000 +#define TSSETUP_DEV_128 0x00007000 +#define TSSETUP_ENABLE 0x00008000 +#define TSSETUP_DLY_MASK 0x03FF0000 +#define TSSETUP_DLY_SHIFT 16 +#define TSSETUP_TDTCT 0x80000000 + +#define TSMAXMIN_XMIN_MASK 0x000000FF +#define TSMAXMIN_XMIN_SHIFT 0 +#define TSMAXMIN_YMIN_MASK 0x0000FF00 +#define TSMAXMIN_YMIN_SHIFT 8 +#define TSMAXMIN_XMAX_MASK 0x00FF0000 +#define TSMAXMIN_XMAX_SHIFT 16 +#define TSMAXMIN_YMAX_MASK 0xFF000000 +#define TSMAXMIN_YMAX_SHIFT 24 + +#define TSXYRESULT_X_MASK 0x00000FFF +#define TSXYRESULT_X_SHIFT 0 +#define TSXYRESULT_AD_MASK 0x0000FFFF +#define TSXYRESULT_AD_SHIFT 0 +#define TSXYRESULT_Y_MASK 0x0FFF0000 +#define TSXYRESULT_Y_SHIFT 16 +#define TSXYRESULT_SDR 0x80000000 + +#define TSX_SAMPLE_MASK 0x00003FFF +#define TSX_SAMPLE_SHIFT 0x00 +#define TSY_SAMPLE_MASK 0x3FFF0000 +#define TSY_SAMPLE_SHIFT 0x10 + +#define TSSETUP2_TINT 0x00000001 +#define TSSETUP2_NICOR 0x00000002 +#define TSSETUP2_PINT 0x00000004 +#define TSSETUP2_PENSTS 0x00000008 +#define TSSETUP2_PINTEN 0x00000010 +#define TSSETUP2_DEVINT 0x00000020 +#define TSSETUP2_DINTEN 0x00000040 +#define TSSETUP2_DTMEN 0x00000080 +#define TSSETUP2_DISDEV 0x00000100 +#define TSSETUP2_NSIGND 0x00000200 +#define TSSETUP2_S28EN 0x00000400 +#define TSSETUP2_RINTEN 0x00000800 + +#define TSXYRESULT_SDR 0x80000000 + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +#endif /* _REGS_TOUCH_H_ */ diff --git a/include/asm-arm/arch-ep93xx/regs_uart.h b/include/asm-arm/arch-ep93xx/regs_uart.h new file mode 100644 index 0000000..cfadf4a --- /dev/null +++ b/include/asm-arm/arch-ep93xx/regs_uart.h @@ -0,0 +1,84 @@ +/* + * File: linux/include/asm-arm/arch-ep93xx/regs_uart.h + * + * Copyright (C) 2003 Cirrus Logic, Inc + * + * 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 + */ + +#ifndef _REGS_UART_H_ +#define _REGS_UART_H_ + +/* Bits in UARTRSR */ +#define UARTRSR_FE 0x00000001 /* Framing error */ +#define UARTRSR_PE 0x00000002 /* Parity error */ +#define UARTRSR_BE 0x00000004 /* Break error */ +#define UARTRSR_OE 0x00000008 /* Overrun error */ + +/* Bits in UARTCR - UART1CR, UART2CR, or UART3CR */ +#define UARTLCR_H_BRK 0x00000001 +#define UARTLCR_H_PEN 0x00000002 +#define UARTLCR_H_EPS 0x00000004 +#define UARTLCR_H_STP2 0x00000008 +#define UARTLCR_H_FEN 0x00000010 +#define UARTLCR_H_WLEN 0x00000060 +#define UARTLCR_H_WLEN_8_DATA 0x00000060 +#define UARTLCR_H_WLEN_7_DATA 0x00000040 +#define UARTLCR_H_WLEN_6_DATA 0x00000020 +#define UARTLCR_H_WLEN_5_DATA 0x00000000 + +/* Bits in UARTFR - UART1FR, UART2FR, or UART3FR */ +#define UARTFR_RSR_ERRORS 0x0000000F +#define UARTFR_CTS 0x00000001 +#define UARTFR_DSR 0x00000002 +#define UARTFR_DCD 0x00000004 +#define UARTFR_BUSY 0x00000008 +#define UARTFR_RXFE 0x00000010 +#define UARTFR_TXFF 0x00000020 +#define UARTFR_RXFF 0x00000040 +#define UARTFR_TXFE 0x00000080 + +/* Bits in UARTIIR */ +#define UARTIIR_MIS 0x00000001 +#define UARTIIR_RIS 0x00000002 +#define UARTIIR_TIS 0x00000004 +#define UARTIIR_RTIS 0x00000008 + +/* Bits in UARTCR */ +#define UARTCR_UARTE 0x00000001 +#define UARTCR_MSIE 0x00000008 +#define UARTCR_RIE 0x00000010 +#define UARTCR_TIE 0x00000020 +#define UARTCR_RTIE 0x00000040 +#define UARTCR_LBE 0x00000080 + +/* Bits in UARTMCR */ +#define UARTMCR_DTR 0x00000001 +#define UARTMCR_RTS 0x00000002 +#define UARTMCR_OUT1 0x00000004 +#define UARTMCR_OUT2 0x00000008 +#define UARTMCR_LOOP 0x00000010 + +/* Bits in UARTMSR */ +#define UARTMSR_DCTS 0x00000001 +#define UARTMSR_DDSR 0x00000002 +#define UARTMSR_TERI 0x00000004 +#define UARTMSR_DDCD 0x00000008 +#define UARTMSR_CTS 0x00000010 +#define UARTMSR_DSR 0x00000020 +#define UARTMSR_RI 0x00000040 +#define UARTMSR_DCD 0x00000080 + +#endif /* _REGS_UART_H_ */ diff --git a/include/asm-arm/arch-ep93xx/serial.h b/include/asm-arm/arch-ep93xx/serial.h new file mode 100644 index 0000000..06ab737 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/serial.h @@ -0,0 +1,49 @@ +/* + * linux/include/asm-arm/arch-integrator/serial.h + * + * Copyright (C) 1999 ARM Limited + * + * 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 + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +#include +#include + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD (1843200 / 16) + +#define _SER_IRQ0 IRQ_UARTINT0 +#define _SER_IRQ1 IRQ_UARTINT1 + +#define RS_TABLE_SIZE 2 + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + + /* UART CLK PORT IRQ FLAGS */ +#define STD_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS }, /* ttyS1 */ + +#define EXTRA_SERIAL_PORT_DEFNS + +#endif diff --git a/include/asm-arm/arch-ep93xx/ssp-cirrus.h b/include/asm-arm/arch-ep93xx/ssp-cirrus.h new file mode 100644 index 0000000..e29dc9d --- /dev/null +++ b/include/asm-arm/arch-ep93xx/ssp-cirrus.h @@ -0,0 +1,30 @@ +/* + * + * FILE: ssp.h + * + * DESCRIPTION: SSP Interface Driver Module implementation + * + * Copyright Cirrus Logic Corporation, 2001-2003. All rights reserved + * + */ +#ifndef _SSP_DRV_H_ +#define _SSP_DRV_H_ + +enum SSPDeviceType { + PS2_KEYBOARD = 0, + I2S_CODEC = 1, + SERIAL_FLASH = 2 +}; + +typedef void (*SSPDataCallback) (unsigned int Data); + +typedef struct _SSP_DRIVER_API { + int (*Open) (enum SSPDeviceType Device, SSPDataCallback Callback); + int (*Read) (int Handle, unsigned int Addr, unsigned int *pValue); + int (*Write) (int Handle, unsigned int Addr, unsigned int Value); + int (*Close) (int Handle); +} SSP_DRIVER_API; + +extern SSP_DRIVER_API *SSPDriver; + +#endif /* _SSP_DRV_H_ */ diff --git a/include/asm-arm/arch-ep93xx/ssp.h b/include/asm-arm/arch-ep93xx/ssp.h new file mode 100644 index 0000000..9102233 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/ssp.h @@ -0,0 +1,121 @@ +/* + * ssp.h + * + * Copyright (C) 2004 Ray Lehtiniemi, All Rights Reserved. + * Copyright (C) 2004 Siconix, Inc., 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. + */ + +#ifndef SSP_H +#define SSP_H + +#include +#include +#include + +struct ssp_master_ops; +struct ssp_slave; + +struct ssp_transfer { + + /* how many _bytes_ per unit of data */ + int size; + + /* how many units of data left to be clocked out */ + int len; + + /* how many units of data left to be clocked in */ + int rlen; + + /* buffer of units to shift out to slave */ + void *tx; + + /* buffer to hold units shifted in from slave */ + void *rx; + + /* signaled when complete */ + struct completion *c; +}; + +struct ssp_master { + + /* serialize access to the frontend */ + struct semaphore sem; + + /* synchronize the frontend and the backend */ + struct completion completion; + + /* the slave devices on this master */ + struct list_head slave; + + /* the active transfer on the bus */ + struct ssp_transfer transfer; + + /* methods for different master controllers */ + struct ssp_master_ops *ops; +}; + +struct ssp_master_ops { + + /* configure the master for accessing a particular slave */ + int (*configure) (struct ssp_slave *); + + /* enable the backend to start the transfer */ + int (*enable) (struct ssp_transfer *); + + /* disable the backend to stop the transfer */ + int (*disable) (void); +}; + +struct ssp_slave { + + /* our link in the masters list of slaves */ + struct list_head list; + + /* our master */ + struct ssp_master *master; +#if 0 + /* the upper level protocol spoken by the device */ + struct ssp_protocol *protocol; +#endif + /* the phase and polarity modes we support */ + unsigned long supported_modes; + + /* our maximum clock rate, in Hz */ + unsigned long max_clock_rate; + + /* our data unit size, in bits */ + int word_size; + + /* our data unit size, in bytes */ + int nbytes; + + /* assert or negate the chip select line for this device */ + void (*chip_select) (struct ssp_slave *, int); +}; + +/* manage the master-slave list */ +extern int ssp_add_slave(struct ssp_master *, struct ssp_slave *); +extern void ssp_remove_slave(struct ssp_master *, struct ssp_slave *); + +/* perform a single transaction */ +extern int ssp_do(struct ssp_slave *s, int len, void *tx, void *rx); + +/* perform each step of a transaction */ +extern int ssp_start(struct ssp_slave *s); /* grab master, blocking */ +extern int ssp_trystart(struct ssp_slave *s); /* grab master, non-blocking */ +extern void ssp_select(struct ssp_slave *s); /* assert CS */ +extern int ssp_post(struct ssp_slave *s, int len, void *tx, void *rx); /* start a transfer */ +extern int ssp_wait(struct ssp_slave *s); /* wait for completion */ + /*extern int ssp_disable (struct ssp_slave *s); *//* stop a transfer */ +extern void ssp_deselect(struct ssp_slave *s); /* negate CS */ +extern void ssp_finish(struct ssp_slave *s); /* release master */ + +/* module stuff */ +extern int ssp_init(void); +extern void ssp_exit(void); + +#endif diff --git a/include/asm-arm/arch-ep93xx/ssp2.h b/include/asm-arm/arch-ep93xx/ssp2.h new file mode 100644 index 0000000..93823a0 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/ssp2.h @@ -0,0 +1,29 @@ +/* + * ssp.h + * + * Copyright (C) 2004 Ray Lehtiniemi, All Rights Reserved. + * Copyright (C) 2004 Siconix, Inc., 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. + */ + +#ifndef SSP2_H +#define SSP2_H + +#include + +struct ep93xx_ssp_slave { + struct ssp_slave slave; + unsigned long cr0; + unsigned long cr1; + unsigned long cpsr; +}; + +extern struct ssp_master ep93xx_ssp_master; + +extern int ep93xx_ssp_init(void); +extern void ep93xx_ssp_exit(void); + +#endif diff --git a/include/asm-arm/arch-ep93xx/system.h b/include/asm-arm/arch-ep93xx/system.h new file mode 100644 index 0000000..1030210 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/system.h @@ -0,0 +1,68 @@ +/* + * linux/include/asm-arm/arch-ep93xx/system.h + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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 + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include +#include +#include + +static void arch_idle(void) +{ + unsigned long val = readl(SYSCON_DEVCFG); + val = ep93xx_SYSCON_DEVCFG(val | SYSCON_DEVCFG_SHena); + SysconSetLocked(SYSCON_DEVCFG, val); + readl(SYSCON_HALT); +} + +#if defined(CONFIG_MACH_TTML) + +#include +extern __inline__ void arch_reset(char mode) +{ + /* reboot using micro */ + unsigned char msg[4] = { 0xaa, 0x90, 0xa0, 0x65 }; + unsigned char reply[10]; + (void)ssp_do_ttml(&ep93xx_ssp_micro, msg, 4, reply, 10); + while (1) ; +} + +#else + +extern __inline__ void arch_reset(char mode) +{ +#if 1 + /* reboot using SW_RESET bit in devcfg register */ + unsigned long val = readl(SYSCON_DEVCFG); + SysconSetLocked(SYSCON_DEVCFG, + ep93xx_SYSCON_DEVCFG(val | SYSCON_DEVCFG_SWRST)); + SysconSetLocked(SYSCON_DEVCFG, + ep93xx_SYSCON_DEVCFG(val & ~SYSCON_DEVCFG_SWRST)); + +#else + /* reboot using 0.250 second onboard watchdog timeout */ + writel(0xaaaa, WATCHDOG); + while (1) ; +#endif +} +#endif + +#endif diff --git a/include/asm-arm/arch-ep93xx/timex.h b/include/asm-arm/arch-ep93xx/timex.h new file mode 100644 index 0000000..87a7628 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/timex.h @@ -0,0 +1,26 @@ +/* + * linux/include/asm-arm/arch-integrator/timex.h + * + * Integrator architecture timex specifications + * + * Copyright (C) 1999 ARM Limited + * + * 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 + */ + +/* + * ?? + */ +#define CLOCK_TICK_RATE (50000000 / 16) diff --git a/include/asm-arm/arch-ep93xx/uncompress.h b/include/asm-arm/arch-ep93xx/uncompress.h new file mode 100644 index 0000000..f76de3c --- /dev/null +++ b/include/asm-arm/arch-ep93xx/uncompress.h @@ -0,0 +1,91 @@ +/* + * linux/include/asm-arm/arch-ep93xx/uncompress.h + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#if defined(CONFIG_MACH_ZEFEERDZA) || defined(CONFIG_MACH_ZEFEERDZB) || \ + defined(CONFIG_MACH_ZEFEERDZG) || defined(CONFIG_MACH_ZEFEERDZN) || defined(CONFIG_MACH_ZEFEERDZQ) +# define BAUDRATE ((EP93XX_UART_CLK/(16 * 115200)) - 1) +#else +# define BAUDRATE ((EP93XX_UART_CLK/(16 * 57600)) - 1) +#endif + +#define HW_PREG(reg) ((unsigned int volatile *)(io_v2p(reg))) + +static void putstr(const char *s) +{ + while (*s) { + while (*HW_PREG(UART1FR) & UARTFR_TXFF) ; + + *HW_PREG(UART1DR) = *s; + + if (*s == '\n') { + while (*HW_PREG(UART1FR) & UARTFR_TXFF) ; + + *HW_PREG(UART1DR) = '\r'; + } + s++; + } + while (*HW_PREG(UART1FR) & UARTFR_BUSY) ; +} + +static void EnableUart(void) +{ + /* + * Ensure that the base clock to the UARTS is 14.7456Mhz + * and that UART1 is enabled. + */ + *HW_PREG(SYSCON_PWRCNT) = SYSCON_PWRCNT_UARTBAUD; + + *HW_PREG(SYSCON_SWLOCK) = 0xaa; + *HW_PREG(SYSCON_DEVCFG) = (*HW_PREG(SYSCON_DEVCFG)) | SYSCON_DEVCFG_U1EN; + + /* Disable the UARTS and clear out the old settings. */ + *HW_PREG(UART1MCR) = 0; + *HW_PREG(UART1CR) = 0; + *HW_PREG(UART1RSR) = 0; + *HW_PREG(UART1CR_L) = 0; + *HW_PREG(UART1CR_M) = 0; + *HW_PREG(UART1CR_H) = 0; + + /* Set the baud rate and framing */ + *HW_PREG(UART1CR_L) = (BAUDRATE & 0x0FF); + *HW_PREG(UART1CR_M) = ((BAUDRATE >> 8) & 0x0FF); + + /* 8 Data bits, No Parity, 1 Stop bit. */ + *HW_PREG(UART1CR_H) = (UARTLCR_H_WLEN_8_DATA | UARTLCR_H_FEN); + + /* Enable Uart */ + *HW_PREG(UART1CR) = UARTCR_UARTE; +} + +#if defined(CONFIG_MACH_ADSSPHERE) +#define arch_decomp_setup() +#else + +/* Called early before the UART is used for output by the compressed loader. */ +static void arch_decomp_setup(void) +{ + EnableUart(); +} +#endif + +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-ep93xx/vmalloc.h b/include/asm-arm/arch-ep93xx/vmalloc.h new file mode 100644 index 0000000..ec8f98d --- /dev/null +++ b/include/asm-arm/arch-ep93xx/vmalloc.h @@ -0,0 +1,32 @@ +/* + * linux/include/asm-arm/arch-integrator/vmalloc.h + * + * Copyright (C) 2000 Russell King. + * + * 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 + */ + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END (PAGE_OFFSET + 0x10000000) diff --git a/include/asm-arm/arch-ep93xx/zefeerevb.h b/include/asm-arm/arch-ep93xx/zefeerevb.h new file mode 100644 index 0000000..2cb3f84 --- /dev/null +++ b/include/asm-arm/arch-ep93xx/zefeerevb.h @@ -0,0 +1,51 @@ +/* + * linux/include/asm-arm/arch-ep93xx/platform.h + * + * Copyright (C) 2004 DAVE Srl + * + * 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 + */ +#ifndef ASM_ARCH_ZEFEEREVB_H +#define ASM_ARCH_ZEFEEREVB_H + +#ifdef CONFIG_MACH_ZEFEER_EVBL_107 +/* GPIO pins used to drive NAND chip mounted on old EVB */ +/* + nCE = EGPIO2 + CLE = EGPIO0 + ALE = EGPIO1 + R/B = EGPIO3 +*/ +# define NAND_EVB_nCE_GPIO_PIN (1 << 2) +# define NAND_EVB_CLE_GPIO_PIN (1 << 0) +# define NAND_EVB_ALE_GPIO_PIN (1 << 1) +# define NAND_EVB_RB_GPIO_PIN (1 << 3) +#else +/* GPIO pins used to drive NAND chip mounted on EVB */ +/* + nCE = EGPIO6 + CLE = EGPIO4 + ALE = EGPIO5 + R/B = EGPIO7 +*/ +# define NAND_EVB_nCE_GPIO_PIN (1 << 6) +# define NAND_EVB_CLE_GPIO_PIN (1 << 4) +# define NAND_EVB_ALE_GPIO_PIN (1 << 5) +# define NAND_EVB_RB_GPIO_PIN (1 << 7) +#endif + +#define ZEFEEREVB_NAND_PADDR 0x20000000 + +#endif /* ASM_ARCH_ZEFEEREVB_H */ diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h index 59975ee..755d9de 100644 --- a/include/asm-arm/irq.h +++ b/include/asm-arm/irq.h @@ -38,6 +38,12 @@ extern void enable_irq(unsigned int); #define IRQT_HIGH (__IRQT_HIGHLVL) #define IRQT_PROBE (1 << 4) +/* + * Flags for enable and disable debounce + */ +#define IRQT_DB ( 1 << 5 ) +#define IRQT_NOTDB ( 1 << 6 ) + int set_irq_type(unsigned int irq, unsigned int type); void disable_irq_wake(unsigned int irq); void enable_irq_wake(unsigned int irq); diff --git a/include/asm-arm/procinfo.h b/include/asm-arm/procinfo.h index a9c75b2..556e5d8 100644 --- a/include/asm-arm/procinfo.h +++ b/include/asm-arm/procinfo.h @@ -56,5 +56,6 @@ extern unsigned int elf_hwcap; #define HWCAP_VFP 64 #define HWCAP_EDSP 128 #define HWCAP_JAVA 256 +#define HWCAP_CRUNCH 512 #endif diff --git a/include/linux/can/oki_ml9620_ctrl.h b/include/linux/can/oki_ml9620_ctrl.h new file mode 100644 index 0000000..d2cfbea --- /dev/null +++ b/include/linux/can/oki_ml9620_ctrl.h @@ -0,0 +1,54 @@ +/* + * include/linux/can/oki_ml9620_ctrl.h + * + * OKI ML9620 CAN Controler driver + * + * Author: Manfred Gruber + * + * Copyright 2004 (c) Manfred Gruber + * Copyright 2004 (c) Contec Steuerungstechnik & Automation Ges.m.b.H + * Kufstein/Austria www.contec.at + * + * This driver was written for Contec hypercontrol Micro9 Board + * 1. CAN Controller is on Hypercontrol Micro9 CPU board + * 2. CAN Controller is on Hypercontrol Micro9 eval board + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef _OKI_ML9620_CTRL_H_ +#define _OKI_ML9620_CTRL_H_ + +#ifdef __KERNEL__ +struct can_msg { + unsigned short id; /* identifier */ + unsigned short dlc : 4; /* bitfield 4: data length code [0..8] */ + unsigned short rtr : 1; /* bitfield 1: rtr bit */ + unsigned short ext : 1; /* bitfield 1: extended ID */ + unsigned short pad : 10; /* workaround alignment issues: + FIXME: completely remove that bitfield junk */ + unsigned char data[8]; /* data bytes */ +}; +#endif + +#define CAN_STS_CNTRL_OFF 0 /*!< set CAN controller off */ +#define CAN_STS_CNTRL_ON 1 /*!< set CAN controller on */ +#define CAN_STS_CNTRL_SLEEP 2 /*!< set CAN controller sleep mode */ +#define CAN_STS_CNTRL_AWAKE 3 /*!< set CAN controller wake up */ +#define CAN_STS_NORMAL 0x00 /*!< CAN controller status normal */ +#define CAN_STS_RESET 0x01 /*!< CAN controller status reset */ +#define CAN_STS_WARNING 0x02 /*!< CAN controller status warning */ +#define CAN_STS_BUS_OFF 0x04 /*!< CAN controller status bus off */ +#define CAN_STS_SLEEPING 0x08 /*!< CAN controller status sleeping */ +#define CAN_STS_OVERRUN 0x10 /*!< CAN controller status overrun */ +#define CAN_STS_TXOK 0x20 /*!< CAN message transmitted */ + +#define COMMAND 0 +#define CONFIG 1 +#define SEND 2 +#define RECEIVE 3 +#define STATUS 4 + +#endif diff --git a/include/linux/input.h b/include/linux/input.h index 3c58233..8ea2247 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -414,6 +414,7 @@ struct input_absinfo { #define BTN_STYLUS2 0x14c #define BTN_TOOL_DOUBLETAP 0x14d #define BTN_TOOL_TRIPLETAP 0x14e +#define BTN_RAW 0x14f #define BTN_WHEEL 0x150 #define BTN_GEAR_DOWN 0x150 diff --git a/include/linux/irda.h b/include/linux/irda.h index 95dee17..3172c96 100644 --- a/include/linux/irda.h +++ b/include/linux/irda.h @@ -76,6 +76,7 @@ typedef enum { IRDA_MCP2120_DONGLE = 9, IRDA_ACT200L_DONGLE = 10, IRDA_MA600_DONGLE = 11, + IRDA_EP93XX_SIR = 12, } IRDA_DONGLE; /* Protocol types to be used for SOCK_DGRAM */ diff --git a/include/linux/sched.h b/include/linux/sched.h index b0ad6f3..2ee1652 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -883,6 +883,11 @@ extern void __put_task_struct(struct tas #define put_task_struct(tsk) \ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) +#ifdef CONFIG_EP93XX_CRUNCH +#define PF_USEDCRUNCH 0x00200000 /* introduced to preserve PF_USEDFPU + meaning across the architecture */ +#endif + /* * Per process flags */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index e3710d7..a1c9b53 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -124,6 +124,9 @@ /* Hilscher netx */ #define PORT_NETX 71 +/* Cirrus EP93xx family */ +#define PORT_EP93XX 65 + #ifdef __KERNEL__ #include diff --git a/include/linux/ttml.h b/include/linux/ttml.h new file mode 100644 index 0000000..2b0e327 --- /dev/null +++ b/include/linux/ttml.h @@ -0,0 +1,61 @@ +/* + * include/linux/ttml.h + * + * TTML TripDawg system devices. + * + * Copyright 2004, Ray Lehtiniemi + * Copyright 2004, Siconix, Inc + */ + +#ifndef __TTML_H +#define __TTML_H + +#define TTML_MAJOR MISC_MAJOR + +#define TTML_MINOR_LED 240 +#define TTML_MINOR_BUZZER 241 +#define TTML_MINOR_SPEEDO 242 +#define TTML_MINOR_GPIO 243 +#define TTML_MINOR_BUTTON 244 +#define TTML_MINOR_WD 245 + +#define MAX_TTML_MINORS 6 + +struct ttml_ioctl_led { + int blue; + int red; + int yellow; +}; + +struct ttml_ioctl_buzzer { + int buzzer1; +}; + +struct ttml_ioctl_speedo { + int instant; + int average; +}; + +struct ttml_ioctl_gpio { + int pto; + int ignition; + int spare; +}; + +struct ttml_ioctl_button { + int button1; + int portf; +}; + +#define TTML_IOCTL 't' + +#define TTML_GET_LED _IOR(TTML_IOCTL, 0, struct ttml_ioctl_led) +#define TTML_GET_BUZZER _IOR(TTML_IOCTL, 1, struct ttml_ioctl_buzzer) +#define TTML_GET_SPEEDO _IOR(TTML_IOCTL, 2, struct ttml_ioctl_speedo) +#define TTML_GET_GPIO _IOR(TTML_IOCTL, 3, struct ttml_ioctl_gpio) +#define TTML_GET_BUTTON _IOR(TTML_IOCTL, 4, struct ttml_ioctl_button) + +#define TTML_SET_LED _IOW(TTML_IOCTL, 16, struct ttml_ioctl_led) +#define TTML_SET_BUZZER _IOW(TTML_IOCTL, 17, struct ttml_ioctl_buzzer) + +#endif diff --git a/include/net/irda/ep93xx_irda.h b/include/net/irda/ep93xx_irda.h new file mode 100644 index 0000000..0ee919d --- /dev/null +++ b/include/net/irda/ep93xx_irda.h @@ -0,0 +1,261 @@ + /********************************************************************* + * + * Filename: ep93xx_irda.h + * Version: 0.2 + * Description: Header for the EP93xx SOC IrDA driver. + * Status: Experimental. + * + * Copyright 2003 Cirrus Logic, Inc. + * + * Based on the ali-ircc.c implementation: + * Author: Benjamin Kong + * Created at: 2000/10/16 03:46PM + * Modified at: 2001/1/3 02:55PM + * Modified by: Benjamin Kong + * + * Copyright (c) 2000 Benjamin Kong + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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: + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + ********************************************************************/ + +#ifndef EP93XX_IRDA_H +#define EP93XX_IRDA_H + +#include + +#include +#include +#include + +/* + * Number of DMA channels used + */ +#define DMA_COUNT 3 + +/* + * TX/RX window queues + */ +#define MAX_TX_WINDOW 7 +#define MAX_RX_WINDOW 7 + +struct ep93xx_chip { + char *name; + int iSIR_IRQ, iMFIR_IRQ; + ep93xx_dma_dev_t eSIR_DMATx; + ep93xx_dma_dev_t eMFIR_DMATx; + ep93xx_dma_dev_t eMFIR_DMARx; + int (*init) (struct ep93xx_chip * chip); +}; + +/* For storing entries in the status FIFO */ + +struct st_fifo_entry { + int status; + int len; +}; + +struct st_fifo { + struct st_fifo_entry entries[MAX_RX_WINDOW]; + int pending_bytes; + int head; + int tail; + int len; +}; + +struct frame_cb { + void *start; /* Start of frame in DMA mem */ + int len; /* Lenght of frame in DMA mem */ +}; + +struct tx_fifo { + struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ + int ptr; /* Currently being sent */ + int len; /* Length of queue */ + int free; /* Next free slot */ + void *tail; /* Next free start in DMA mem */ +}; + +/* Private data for each instance */ +struct ep93xx_irda_cb { + struct st_fifo st_fifo; /* Info about received frames */ + struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ + + struct net_device *netdev; /* Net device pointer */ + struct net_device_stats stats; /* Net device stats */ + + struct irlap_cb *irlap; /* The link layer we are binded with */ + struct qos_info qos; /* QoS capabilities for this device */ + + int iSIR_irq, iMFIR_irq; /* Interrupts used */ + + ep93xx_dma_dev_t ePorts[DMA_COUNT]; /* DMA port ids */ + + int iDMAh[DMA_COUNT]; /* handles for DMA channels */ + dma_addr_t rx_dmaphysh, tx_dmaphysh; + + int fifo_size; /* FIFO size */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + char *conv_buf; /* Buffer used for SIR conversion */ + + struct timeval stamp; /* ? */ + struct timeval now; /* ? */ + + spinlock_t lock; /* Used for serializing operations */ + + __u32 flags; /* Interface flags */ + + __u8 direction; /* TX/RX flag */ + + __u32 speed; /* Currently used speed */ + __u32 new_speed; /* New target tx/rx speed */ + + int index; /* Instance index */ + + int suspended; /* APM suspend flag */ + struct pm_dev *dev; /* Power Management device */ + +}; + +/* + * DMA array handle index meanings + */ +#define DMA_SIR_TX 0 +#define DMA_MFIR_TX 1 +#define DMA_MFIR_RX 2 + +/* + * Directional defines + */ +#define DIR_TX 0x01 +#define DIR_RX 0x02 +#define DIR_BOTH 0x03 + +/* + * Modes support flag defines. + */ +#define CLK_SIR 0x01 +#define CLK_MIR 0x02 +#define CLK_FIR 0x04 + +/* Name friendly bit defines for register accesses */ + +/* UART2/SIR */ +#define U2RSR_OvnErr 0x08 +#define U2RSR_BrkErr 0x04 +#define U2RSR_PtyErr 0x02 +#define U2RSR_FrmErr 0x01 + +#define U2CRH_WLen 0x60 +#define U2CRH_FEn 0x10 +#define U2CRH_Stp2 0x08 +#define U2CRH_EPS 0x04 +#define U2CRH_PEn 0x02 +#define U2CRH_Brk 0x01 + +#define U2CR_LoopBk 0x80 +#define U2CR_RxTO 0x40 +#define U2CR_TxIrq 0x20 +#define U2CR_RxIrq 0x10 +#define U2CR_MdmStsIrq 0x08 +#define U2CR_SIRLowPwr 0x04 +#define U2CR_SIR 0x02 +#define U2CR_UART 0x01 + +#define U2FR_TXFE 0x80 +#define U2FR_RXFF 0x40 +#define U2FR_TXFF 0x20 +#define U2FR_RXFE 0x10 +#define U2FR_BUSY 0x08 +#define U2FR_DCD 0x04 +#define U2FR_DSR 0x02 +#define U2FR_CTS 0x01 + +#define U2IICR_RXTOIRQ 0x08 +#define U2IICR_TXIRQ 0x04 +#define U2IICR_RXIRQ 0x02 +#define U2IICR_MDMIRQ 0x01 + +#define U2DMACR_DMAErr 0x04 +#define U2DMACR_TXDMA 0x02 +#define U2DMACR_RXDMA 0x01 + +#define IrENABLE_SIR 0x01 + +/* IrDA block - MIR/FIR */ +#define IrENABLE_FIR 0x03 +#define IrENABLE_MIR 0x02 + +#define IrCONTROL_RXRP 0x40 +#define IrCONTROL_TXRP 0x20 +#define IrCONTROL_RXON 0x10 +#define IrCONTROL_TXON 0x08 +#define IrCONTROL_TXUNDER 0x04 +#define IrCONTROL_MIRBR 0x02 + +#define IrFLAG_TXBUSY 0x200 +#define IrFLAG_RXINFRM 0x100 +#define IrFLAG_RXSYNC 0x80 +#define IrFLAG_EOF 0x40 +#define IrFLAG_WIDTHST 0x30 +#define IrFLAG_FIRFE 0x08 +#define IrFLAG_RXOR 0x04 +#define IrFLAG_CRCERR 0x02 +#define IrFLAG_RXABORT 0x01 + +#define IrRIB_ByteCt 0x7FF0 +#define IrRIB_BUFFE 0x08 +#define IrRIB_BUFOR 0x04 +#define IrRIB_BUFCRCERR 0x02 +#define IrRIB_BUFRXABORT 0x01 + +#define IrDMACR_DMAERR 0x04 +#define IrDMACR_DMATXE 0x02 +#define IrDMACR_DMARXE 0x01 + +#define MFISR_RXFL 0x40 +#define MFISR_RXIL 0x20 +#define MFISR_RXFC 0x10 +#define MFISR_RXFS 0x08 +#define MFISR_TXFABORT 0x04 +#define MFISR_TXFC 0x02 +#define MFISR_TXSR 0x01 + +#define MFIMR_RXFL 0x40 +#define MFIMR_RXIL 0x20 +#define MFIMR_RXFC 0x10 +#define MFIMR_RXFS 0x08 +#define MFIMR_TXABORT 0x04 +#define MFIMR_TXFC 0x02 +#define MFIMR_TXFS 0x01 + +#define MFIIR_RXFL 0x40 +#define MFIIR_RXIL 0x20 +#define MFIIR_RXFC 0x10 +#define MFIIR_RXFS 0x08 +#define MFIIR_TXABORT 0x04 +#define MFIIR_TXFC 0x02 +#define MFIIR_TXFS 0x01 + +#endif /* EP93XX_IRDA_H */ diff --git a/init/do_mounts.c b/init/do_mounts.c index b27c110..29d2d52 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -410,7 +410,9 @@ void __init prepare_namespace(void) root_device_name += 5; } - is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; + /* llandre */ + /* To retrieve ramdisk from MTD partition we must add major 31 as suggested by rmk */ + is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR || MAJOR(ROOT_DEV) == 31; if (initrd_load()) goto out; diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 88e52dc..cda016b 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -1004,6 +1004,26 @@ config SOUND_AEDSP16 to get more information about this driver and its configuration. + +config SOUND_EP93XX_AC97 + tristate "EP93xx AC97 Support" + depends on SOUND_OSS && ARCH_EP93XX + ---help--- + AC97 sound support for Cirrus EP93xx + +config SOUND_EP93XX_AC97_CODEC_CS4297 + bool "CS4297" + depends on SOUND_EP93XX_AC97 + help + Say Y here if you have CS4297 Codec. + +config SOUND_EP93XX_AUDIO_PIO + bool "EP93xx AC97 in PIO mode" + depends on SOUND_EP93XX_AC97 + ---help--- + Run EP93XX AC97 in PIO MODE. + !!! NOT TESTED !!! + config SC6600 bool "SC-6600 based audio cards (new Audio Excel DSP 16)" depends on SOUND_AEDSP16 diff --git a/sound/oss/Makefile b/sound/oss/Makefile index 9bf3ee5..c7c1927 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile @@ -91,6 +91,9 @@ obj-$(CONFIG_SOUND_EMU10K1) += emu10k1/ obj-$(CONFIG_SOUND_CS4281) += cs4281/ obj-$(CONFIG_DMASOUND) += dmasound/ +obj-$(CONFIG_SOUND_EP93XX_I2S) += ep93xx-audio.o ep93xx-i2s.o +obj-$(CONFIG_SOUND_EP93XX_AC97) += ep93xx-audio.o ep93xx-ac97.o + # Declare multi-part drivers. sound-objs := \ diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index fd25aca..c7c9a02 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c @@ -156,6 +156,8 @@ static const struct { {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops}, {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops}, {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops}, + {0x4352594d, "Cirrus Logic CS4201", &crystal_digital_ops}, + {0x43525973, "Cirrus Logic CS4202", &crystal_digital_ops}, {0x43585430, "CXT48", &default_ops, AC97_DELUDED_MODEM }, {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM }, {0x44543031, "Diamond Technology DT0893", &default_ops}, diff --git a/sound/oss/ep93xx-ac97.c b/sound/oss/ep93xx-ac97.c new file mode 100644 index 0000000..a967f19 --- /dev/null +++ b/sound/oss/ep93xx-ac97.c @@ -0,0 +1,1200 @@ +/* + * Glue audio driver for the Cirrus EP93xx Ac97 Controller + * + * Copyright (c) 2003 Cirrus Logic Corp. + * Copyright (c) 2000 Nicolas Pitre + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + * + * This file taken from h3600-uda1341.c + * The mixer code is from ac97_codec.c + * + * History: + * + * 2000-05-21 Nicolas Pitre Initial UDA1341 driver release. + * + * 2000-07-?? George France Bitsy support. + * + * 2000-12-13 Deborah Wallach Fixed power handling for iPAQ/h3600 + * + * 2001-06-03 Nicolas Pitre Made this file a separate module, based on + * the former sa1100-uda1341.c driver. + * + * 2001-07-13 Nicolas Pitre Fixes for all supported samplerates. + * + * 2003-04-04 adt Changes for Cirrus Logic EP93xx I2S + * + * 2003-04-25 adt Changes for Cirrus Logic EP93xx Ac97 + * + * 2005-05-11 Manfred Gruber Ported this from Cirrus Logic Virgo 1-4-3 release + * to Kernel 2.6.11.X + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ep93xx-audio.h" + +#undef DEBUG +//#define DEBUG 1 +#ifdef DEBUG +#define DPRINTK( x... ) printk( x ) +#else +#define DPRINTK( x... ) +#endif + +#define AUDIO_NAME "ep93xx_ac97" + +#ifdef CONFIG_SOUND_EP93XX_AC97_CODEC_CS4297 +#define AUDIO_SAMPLE_RATE_DEFAULT 48000 +#else +#define AUDIO_SAMPLE_RATE_DEFAULT 44100 +#endif + +/* original check is not good enough in case FOO is greater than + * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly + * SOUND_MIXER_NRDEVICES elements. + * before matching the given mixer against the bitmask in supported_mixers we + * check if mixer number exceeds maximum allowed size which is as mentioned + * above SOUND_MIXER_NRDEVICES */ +#define supported_mixer(FOO) \ + ( (FOO >= 0) && \ + (FOO < SOUND_MIXER_NRDEVICES) && \ + codec_supported_mixers & (1< ac97 quickly. */ +enum ac97_recsettings { + AC97_REC_MIC = 0, + AC97_REC_CD, + AC97_REC_VIDEO, + AC97_REC_AUX, + AC97_REC_LINE, + AC97_REC_STEREO, /* combination of all enabled outputs.. */ + AC97_REC_MONO, /*.. or the mono equivalent */ + AC97_REC_PHONE +}; + +static const unsigned int ac97_rm2oss[] = { + [AC97_REC_MIC] = SOUND_MIXER_MIC, + [AC97_REC_CD] = SOUND_MIXER_CD, + [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO, + [AC97_REC_AUX] = SOUND_MIXER_LINE1, + [AC97_REC_LINE] = SOUND_MIXER_LINE, + [AC97_REC_STEREO] = SOUND_MIXER_IGAIN, + [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN +}; + +/* indexed by bit position */ +static const unsigned int ac97_oss_rm[] = { + [SOUND_MIXER_MIC] = AC97_REC_MIC, + [SOUND_MIXER_CD] = AC97_REC_CD, + [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO, + [SOUND_MIXER_LINE1] = AC97_REC_AUX, + [SOUND_MIXER_LINE] = AC97_REC_LINE, + [SOUND_MIXER_IGAIN] = AC97_REC_STEREO, + [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE +}; + +static struct audio_stream_t ac97_output_stream0 = { + audio_num_channels:EP93XX_DEFAULT_NUM_CHANNELS, + audio_format:EP93XX_DEFAULT_FORMAT, + audio_stream_bitwidth:EP93XX_DEFAULT_BIT_WIDTH, + devicename:"Ac97_out", + dmachannel:{DMATx_AAC1, UNDEF, UNDEF}, + sample_rate:0, + hw_bit_width:16, + bCompactMode:1, +}; + +static struct audio_stream_t ac97_input_stream0 = { + audio_num_channels:EP93XX_DEFAULT_NUM_CHANNELS, + audio_format:EP93XX_DEFAULT_FORMAT, + audio_stream_bitwidth:EP93XX_DEFAULT_BIT_WIDTH, + devicename:"Ac97_in", + dmachannel:{DMARx_AAC1, UNDEF, UNDEF}, + sample_rate:0, + hw_bit_width:16, + bCompactMode:1, +}; + +static struct audio_hw_t ep93xx_ac97_hw = { + hw_enable:ep93xx_audio_enable, + hw_disable:ep93xx_audio_disable, + hw_clear_fifo:0, + client_ioctl:ep93xx_audio_ioctl, + + set_hw_serial_format:ep93xx_set_hw_format, + + txdmachannels:{DMATx_AAC1, DMATx_AAC2, DMATx_AAC3}, + rxdmachannels:{DMARx_AAC1, DMARx_AAC2, DMARx_AAC3}, + + MaxTxDmaChannels:3, + MaxRxDmaChannels:3, + + modcnt:0, +}; + +static struct audio_state_t ac97_audio_state0 = { + output_stream:&ac97_output_stream0, + input_stream:&ac97_input_stream0, + // KERNEL2.4 deleted internal sema intialisier, do it in function + hw:&ep93xx_ac97_hw, + wr_ref:0, + rd_ref:0, +}; + +/* + * peek + * + * Reads an AC97 codec register. Returns -1 if there was an error. + */ +static int peek(unsigned int uiAddress) +{ + unsigned int uiAC97RGIS, uiTemp; + + if (!ac_link_enabled) { + DPRINTK + ("ep93xx ac97 peek: attempt to peek before enabling ac-link.\n"); + return -1; + } + + /* + * Check to make sure that the address is aligned on a word boundary + * and is 7E or less. + */ + if (((uiAddress & 0x1) != 0) || (uiAddress > 0x007e)) { + return -1; + } + + /* + * How it is supposed to work is: + * - The ac97 controller sends out a read addr in slot 1. + * - In the next frame, the codec will echo that address back in slot 1 + * and send the data in slot 2. SLOT2RXVALID will be set to 1. + * + * Read until SLOT2RXVALID goes to 1. Reading the data in AC97S2DATA + * clears SLOT2RXVALID. + */ + + /* + * First, delay one frame in case of back to back peeks/pokes. + */ + mdelay(1); + + /* + * Write the address to AC97S1DATA, delay 1 frame, read the flags. + */ + outl(uiAddress, AC97S1DATA); + uiTemp = inl(AC97GCR); /* read to push write out the wrapper */ + + udelay(21 * 4); + uiAC97RGIS = inl(AC97RGIS); + + /* + * Return error if we timed out. + */ + if (((uiAC97RGIS & AC97RGIS_SLOT1TXCOMPLETE) == 0) && + ((uiAC97RGIS & AC97RGIS_SLOT2RXVALID) == 0)) { + DPRINTK("ep93xx-ac97 - peek failed reading reg 0x%02x.\n", + uiAddress); + return -1; + } + + return (inl(AC97S2DATA) & 0x000fffff); +} + +/* + * poke + * + * Writes an AC97 codec Register. Return -1 if error. + */ +static int poke(unsigned int uiAddress, unsigned int uiValue) +{ + unsigned int uiAC97RGIS, uiTemp; + + if (!ac_link_enabled) { + DPRINTK + ("ep93xx ac97 poke: attempt to poke before enabling ac-link.\n"); + return -1; + } + + /* + * Check to make sure that the address is align on a word boundary and + * is 7E or less. And that the value is a 16 bit value. + */ + if (((uiAddress & 0x1) != 0) || (uiAddress > 0x007e)) { + return -1; + } + + /* + * First, delay one frame in case of back to back peeks/pokes. + */ + mdelay(1); + + /* + * Write the data to AC97S2DATA, then the address to AC97S1DATA. + */ + outl(uiValue, AC97S2DATA); + outl(uiAddress, AC97S1DATA); + uiTemp = inl(AC97GCR); /* read to push writes out the wrapper */ + + /* + * Wait for the tx to complete, get status. + */ + udelay(42); + uiAC97RGIS = inl(AC97RGIS); + + /* + * Return error if we timed out. + */ + if (!(inl(AC97RGIS) & AC97RGIS_SLOT1TXCOMPLETE)) { + DPRINTK + ("ep93xx-ac97: poke failed writing reg 0x%02x value 0x%02x.\n", + uiAddress, uiValue); + return -1; + } + + return 0; +} + +/* + * When we get to the multichannel case the pre-fill and enable code + * will go to the dma driver's start routine. + */ +static void ep93xx_audio_enable(struct audio_stream_t *stream) +{ + unsigned int uiTemp; + + DPRINTK("ep93xx_audio_enable\n"); + + /* + * Enable the rx or tx channel + */ + if (stream->dmachannel[0] == DMATx_AAC1) { + uiTemp = inl(AC97TXCR1); + outl((uiTemp | AC97TXCR_TEN), AC97TXCR1); + uiTemp = inl(AC97TXCR1); +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO + outl(inl(AC97IE1) | AC97ISR_TIS, AC97IE1); +#endif + } + + if (stream->dmachannel[0] == DMARx_AAC1) { + uiTemp = inl(AC97RXCR1); + outl((uiTemp | AC97RXCR_REN), AC97RXCR1); + uiTemp = inl(AC97RXCR1); +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO + outl(inl(AC97IE1) | AC97ISR_RIS, AC97IE1); +#endif + } + //DPRINTK("ep93xx_audio_enable - EXIT\n"); +} + +static void ep93xx_audio_disable(struct audio_stream_t *stream) +{ + unsigned int uiControl, uiStatus; + + DPRINTK("ep93xx_audio_disable\n"); + + /* + * Disable the rx or tx channel + */ + if (stream->dmachannel[0] == DMATx_AAC1) { + uiControl = inl(AC97TXCR1); + if (uiControl & AC97TXCR_TEN) { +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO + outl(inl(AC97IE1) & ~AC97ISR_TIS, AC97IE1); +#else + /* + * Wait for fifo to empty. We've shut down the dma + * so that should happen soon. + */ + do { + uiStatus = inl(AC97SR1); + } while (((uiStatus & 0x82) == 0)); + //} while( ((uiStatus & 0x20)!=0) ;&& + //((uiStatus & 0x82)==0) ); +#endif + + outl((uiControl & ~AC97TXCR_TEN), AC97TXCR1); + uiControl = inl(AC97TXCR1); + } + } + + if (stream->dmachannel[0] == DMARx_AAC1) { +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO + outl(inl(AC97IE1) & ~AC97ISR_RIS, AC97IE1); +#endif + uiControl = inl(AC97RXCR1); + outl((uiControl & ~AC97RXCR_REN), AC97RXCR1); + uiControl = inl(AC97RXCR1); + } + //DPRINTK("ep93xx_audio_disable - EXIT\n"); +} + +/* + * ep93xx_setup_src + * + * Once the ac-link is up and all is good, we want to set the codec to a + * usable mode. + */ +static void ep93xx_setup_src(void) +{ + int iTemp; + + /* + * Set the VRA bit to enable the SRC. + */ + iTemp = peek(AC97_2A_EXT_AUDIO_POWER); + poke(AC97_2A_EXT_AUDIO_POWER, (iTemp | 0x1)); + + /* + * Set the DSRC/ASRC bits to enable the variable rate SRC. + */ + iTemp = peek(AC97_60_MISC_CRYSTAL_CONTROL); + poke(AC97_60_MISC_CRYSTAL_CONTROL, (iTemp | 0x0300)); +} + +/* + * ep93xx_set_samplerate + * + * lFrequency - Sample Rate in Hz + * bTx - 1 to set Tx sample rate + * bRx - 1 to set Rx sample rate + */ +static void ep93xx_set_samplerate(struct audio_stream_t *stream, + long lSampleRate) +{ +#ifndef CONFIG_SOUND_EP93XX_AC97_CODEC_CS4297 + unsigned short usDivider, usPhase; + + DPRINTK("ep93xx_set_samplerate - Fs = %d\n", (int)lSampleRate); + + if ((lSampleRate < 7200) || (lSampleRate > 48000)) { + DPRINTK("ep93xx_set_samplerate - invalid Fs = %d\n", + (int)lSampleRate); + return; + } + + /* + * Calculate divider and phase increment. + * + * divider = round( 0x1770000 / lSampleRate ) + * Note that usually rounding is done by adding 0.5 to a floating + * value and then truncating. To do this without using floating + * point, I multiply the fraction by two, do the division, then add one, + * then divide the whole by 2 and then truncate. + * Same effect, no floating point math. + * + * Ph incr = trunc( (0x1000000 / usDivider) + 1 ) + */ + + usDivider = (unsigned short)(((2 * 0x1770000 / lSampleRate) + 1) / 2); + + usPhase = (0x1000000 / usDivider) + 1; + + /* + * Write them in the registers. Spec says divider must be + * written after phase incr. + */ + if (stream->dmachannel[0] == DMATx_AAC1) { + poke(AC97_2C_PCM_FRONT_DAC_RATE, usDivider); + poke(AC97_64_DAC_SRC_PHASE_INCR, usPhase); + } + + if (stream->dmachannel[0] == DMARx_AAC1) { + + poke(AC97_32_PCM_LR_ADC_RATE, usDivider); + poke(AC97_66_ADC_SRC_PHASE_INCR, usPhase); + } + + DPRINTK("ep93xx_set_samplerate - phase = %d, divider = %d\n", + (unsigned int)usPhase, (unsigned int)usDivider); + + /* + * We sorta should report the actual samplerate back to the calling + * application. But some applications freak out if they don't get + * exactly what they asked for. So we fudge and tell them what + * they want to hear. + */ + stream->sample_rate = lSampleRate; + + DPRINTK("ep93xx_set_samplerate - EXIT\n"); +#else + stream->sample_rate = AUDIO_SAMPLE_RATE_DEFAULT; +#endif +} + +/* + * ep93xx_set_hw_format + * + * Sets up whether the controller is expecting 20 bit data in 32 bit words + * or 16 bit data compacted to have a stereo sample in each 32 bit word. + */ +static void ep93xx_set_hw_format(struct audio_stream_t *stream, long format) +{ + int bCompactMode, uiTemp, iWidth; + unsigned long ulRegValue; + + switch (format) { + /* + * Here's all the <=16 bit formats. We can squeeze both L and R + * into one 32 bit sample so use compact mode. + */ + case AFMT_U8: + case AFMT_S8: + case AFMT_S16_LE: + case AFMT_U16_LE: + bCompactMode = 1; + ulRegValue = 0x00008018; + iWidth = 16; + break; + + /* + * Add any other >16 bit formats here... + */ + case AFMT_S32_BLOCKED: + default: + bCompactMode = 0; + ulRegValue = 0x00004018; + iWidth = 20; + break; + } + + if (stream->dmachannel[0] == DMARx_AAC1) { + uiTemp = inl(AC97RXCR1); + if (ulRegValue != uiTemp) { + outl(ulRegValue, AC97RXCR1); + uiTemp = inl(AC97RXCR1); + } + stream->hw_bit_width = iWidth; + stream->bCompactMode = bCompactMode; + } + + if (stream->dmachannel[0] == DMATx_AAC1) { + uiTemp = inl(AC97TXCR1); + if (ulRegValue != uiTemp) { + outl(ulRegValue, AC97TXCR1); + uiTemp = inl(AC97TXCR1); + } + stream->hw_bit_width = iWidth; + stream->bCompactMode = bCompactMode; + } + +} + +/* + * ep93xx_init_ac97_controller + * + * This routine sets up the Ac'97 Controller. + */ +static void ep93xx_init_ac97_controller(void) +{ + unsigned int uiDEVCFG, uiTemp; + + DPRINTK("ep93xx_init_ac97_controller - enter\n"); + + /* + * Configure the multiplexed Ac'97 pins to be Ac97 not I2s. + * Configure the EGPIO4 and EGPIO6 to be GPIOS, not to be + * SDOUT's for the second and third I2S controller channels. + */ + uiDEVCFG = inl(SYSCON_DEVCFG); + + uiDEVCFG &= ~(SYSCON_DEVCFG_I2SonAC97 | + SYSCON_DEVCFG_A1onG | SYSCON_DEVCFG_A2onG); + + SysconSetLocked(SYSCON_DEVCFG, uiDEVCFG); + + /* + * Disable the AC97 controller internal loopback. + * Disable Override codec ready. + */ + outl(0, AC97GCR); + + /* + * Enable the AC97 Link. + */ + uiTemp = inl(AC97GCR); + outl((uiTemp | AC97GSR_IFE), AC97GCR); + uiTemp = inl(AC97GCR); /* read to push write out the wrapper */ + + /* + * Set the TIMEDRESET bit. Will cause a > 1uSec reset of the ac-link. + * This bit is self resetting. + */ + outl(AC97RESET_TIMEDRESET, AC97RESET); + uiTemp = inl(AC97GCR); /* read to push write out the wrapper */ + + /* + * Delay briefly, but let's not hog the processor. + */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(5); /* 50 mSec */ + + /* + * Read the AC97 status register to see if we've seen a CODECREADY + * signal from the AC97 codec. + */ + if (!(inl(AC97RGIS) & AC97RGIS_CODECREADY)) { + DPRINTK("ep93xx-ac97 - FAIL: CODECREADY still low!\n"); + return; + } + + /* + * Delay for a second, not hogging the processor + */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); /* 1 Sec */ + + /* + * Now the Ac-link is up. We can read and write codec registers. + */ + ac_link_enabled = 1; + + /* + * Set up the rx and tx channels + * Set the CM bit, data size=16 bits, enable tx slots 3 & 4. + */ + ep93xx_set_hw_format(&ac97_output_stream0, EP93XX_DEFAULT_FORMAT); + ep93xx_set_hw_format(&ac97_input_stream0, EP93XX_DEFAULT_FORMAT); + + DPRINTK("ep93xx-ac97 -- AC97RXCR1: %08x\n", inl(AC97RXCR1)); + DPRINTK("ep93xx-ac97 -- AC97TXCR1: %08x\n", inl(AC97TXCR1)); + + DPRINTK("ep93xx_init_ac97_controller - EXIT - success\n"); + +} + +/* + * ep93xx_init_ac97_codec + * + * Program up the external Ac97 codec. + * + */ +static void ep93xx_init_ac97_codec(void) +{ + DPRINTK("ep93xx_init_ac97_codec - enter\n"); + + ep93xx_setup_src(); + ep93xx_set_samplerate(&ac97_output_stream0, AUDIO_SAMPLE_RATE_DEFAULT); + ep93xx_set_samplerate(&ac97_input_stream0, AUDIO_SAMPLE_RATE_DEFAULT); + ep93xx_init_mixer(); + + DPRINTK("ep93xx_init_ac97_codec - EXIT\n"); + +} + +#ifdef DEBUG +static void ep93xx_dump_ac97_regs(void) +{ + int i; + unsigned int reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; + + DPRINTK("---------------------------------------------\n"); + DPRINTK(" : 0 2 4 6 8 A C E\n"); + + for (i = 0; i < 0x80; i += 0x10) { + reg0 = 0xffff & (unsigned int)peek(i); + reg1 = 0xffff & (unsigned int)peek(i + 0x2); + reg2 = 0xffff & (unsigned int)peek(i + 0x4); + reg3 = 0xffff & (unsigned int)peek(i + 0x6); + reg4 = 0xffff & (unsigned int)peek(i + 0x8); + reg5 = 0xffff & (unsigned int)peek(i + 0xa); + reg6 = 0xffff & (unsigned int)peek(i + 0xc); + reg7 = 0xffff & (unsigned int)peek(i + 0xe); + + DPRINTK(" %02x : %04x %04x %04x %04x %04x %04x %04x %04x\n", + i, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); + } +} +#endif + +static void ep93xx_set_volume(unsigned int oss_channel, unsigned int oss_val) { + unsigned int left, right; + u16 val = 0; + struct ac97_mixer_hw_t *mh = &ac97_hw[oss_channel]; + + if (!mh->scale) { + DPRINTK + ("ep93xx-ac97.c: ep93xx_set_volume - not a valid OSS channel\n"); + return; + } + + /* cleanse input a little */ + right = ((oss_val >> 8) & 0xff); + left = (oss_val & 0xff); + + if (right > 100) + right = 100; + if (left > 100) + left = 100; + + DPRINTK("ac97_codec: wrote OSS channel#%2d (ac97 reg 0x%02x), " + "l:%2d, r:%2d:", oss_channel, mh->offset, left, right); + + if (AC97_STEREO_MASK & (1 << oss_channel)) { + /* stereo mixers */ + if (oss_channel == SOUND_MIXER_IGAIN) { + right = ((100 - right) * (mh->scale - 1)) / 100; + left = ((100 - left) * (mh->scale - 1)) / 100; + if (right >= mh->scale) + right = mh->scale - 1; + if (left >= mh->scale) + left = mh->scale - 1; + right = (mh->scale - 1) - right; + left = (mh->scale - 1) - left; + val = (left << 8) | right; + } else { + if (left == 0 && right == 0) { + val = 0x8000; + } else { + right = ((100 - right) * (mh->scale - 1)) / 100; + left = ((100 - left) * (mh->scale - 1)) / 100; + if (right >= mh->scale) + right = mh->scale - 1; + if (left >= mh->scale) + left = mh->scale - 1; + val = (left << 8) | right; + } + } + } else if (left == 0) { + val = 0x8000; + } else if ((oss_channel == SOUND_MIXER_SPEAKER) || + (oss_channel == SOUND_MIXER_PHONEIN) || + (oss_channel == SOUND_MIXER_PHONEOUT)) { + left = ((100 - left) * (mh->scale - 1)) / 100; + if (left >= mh->scale) + left = mh->scale - 1; + val = left; + } else if (oss_channel == SOUND_MIXER_MIC) { + val = peek(mh->offset) & ~0x801f; + left = ((100 - left) * (mh->scale - 1)) / 100; + if (left >= mh->scale) + left = mh->scale - 1; + val |= left; + } + /* + * For bass and treble, the low bit is optional. Masking it + * lets us avoid the 0xf 'bypass'. + * Do a read, modify, write as we have two contols in one reg. + */ + else if (oss_channel == SOUND_MIXER_BASS) { + val = peek(mh->offset) & ~0x0f00; + left = ((100 - left) * (mh->scale - 1)) / 100; + if (left >= mh->scale) + left = mh->scale - 1; + val |= (left << 8) & 0x0e00; + } else if (oss_channel == SOUND_MIXER_TREBLE) { + val = peek(mh->offset) & ~0x000f; + left = ((100 - left) * (mh->scale - 1)) / 100; + if (left >= mh->scale) + left = mh->scale - 1; + val |= left & 0x000e; + } + + DPRINTK(" 0x%04x", val); + + poke(mh->offset, val); + +#ifdef DEBUG + val = peek(mh->offset); + DPRINTK(" (read back 0x%04x)\n", val); +#endif + + guiOSS_Volume[oss_channel] = oss_val; +} + +static void ep93xx_init_mixer(void) +{ + u16 cap; + int i; + + /* mixer masks */ + codec_supported_mixers = AC97_SUPPORTED_MASK; + + cap = peek(AC97_00_RESET); + if (!(cap & 0x04)) { + codec_supported_mixers &= + ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE); + } + if (!(cap & 0x10)) { + codec_supported_mixers &= ~SOUND_MASK_ALTPCM; + } + + /* + * Detect bit resolution of output volume controls by writing to the + * 6th bit (not unmuting yet) + */ + poke(AC97_02_MASTER_VOL, 0xa020); + if (peek(AC97_02_MASTER_VOL) != 0xa020) { + ac97_hw[SOUND_MIXER_VOLUME].scale = 32; + } + + poke(AC97_04_HEADPHONE_VOL, 0xa020); + if (peek(AC97_04_HEADPHONE_VOL) != 0xa020) { + ac97_hw[AC97_04_HEADPHONE_VOL].scale = 32; + } + + poke(AC97_06_MONO_VOL, 0x8020); + if (peek(AC97_06_MONO_VOL) != 0x8020) { + ac97_hw[AC97_06_MONO_VOL].scale = 32; + } + + /* initialize mixer channel volumes */ + for (i = 0; + (i < SOUND_MIXER_NRDEVICES) && (mixer_defaults[i].mixer != -1); + i++) { + if (!supported_mixer(mixer_defaults[i].mixer)) { + continue; + } + + ep93xx_set_volume(mixer_defaults[i].mixer, + mixer_defaults[i].value); + } + +} + +/* + * ac97_recmask_io + * + * Read or write the record source. + */ +static int ep93xx_read_recsource(void) +{ + unsigned int val; + + /* read it from the card */ + val = peek(AC97_1A_RECORD_SELECT); + + DPRINTK("ac97_codec: ac97 recmask to set to 0x%04x\n", val); + + return (1 << ac97_rm2oss[val & 0x07]); +} + +static int ep93xx_set_recsource(int mask) +{ + unsigned int val; + + /* Arg contains a bit for each recording source */ + if (mask == 0) { + return 0; + } + + mask &= AC97_RECORD_MASK; + + if (mask == 0) { + return -EINVAL; + } + + /* + * May have more than one bit set. So clear out currently selected + * record source value first (AC97 supports only 1 input) + */ + val = (1 << ac97_rm2oss[peek(AC97_1A_RECORD_SELECT) & 0x07]); + if (mask != val) + mask &= ~val; + + val = ffs(mask); + val = ac97_oss_rm[val - 1]; + val |= val << 8; /* set both channels */ + + DPRINTK("ac97_codec: setting ac97 recmask to 0x%04x\n", val); + + poke(AC97_1A_RECORD_SELECT, val); + + return 0; +} + +static int ep93xx_mixer_open(struct inode *inode, struct file *file) +{ + file->private_data = &ep93xx_ac97_hw; + return 0; +} + +static int ep93xx_mixer_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static int +ep93xx_mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) +{ + int val, nr; + + struct audio_hw_t *hw = (struct audio_hw_t *)file->private_data; + + DPRINTK("ep93xx_mixer_ioctl - enter. IOC_TYPE is %c \n", + _IOC_TYPE(cmd)); + + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, "CS4202", sizeof(info.id)); + strncpy(info.name, "Cirrus CS4202", sizeof(info.name)); + info.modify_counter = hw->modcnt; + if (copy_to_user((void *)arg, &info, sizeof(info))) { + return -EFAULT; + } + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, "CS4202", sizeof(info.id)); + strncpy(info.name, "Cirrus CS4202", sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) { + return -EFAULT; + } + return 0; + } + + if ((_IOC_TYPE(cmd) != 'M') || (_SIOC_SIZE(cmd) != sizeof(int))) + return -EINVAL; + + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + + nr = _IOC_NR(cmd); + + if (_SIOC_DIR(cmd) == _SIOC_READ) { + switch (nr) { + case SOUND_MIXER_RECSRC: + /* Read the current record source */ + val = ep93xx_read_recsource(); + break; + + case SOUND_MIXER_DEVMASK: + /* give them the supported mixers */ + val = codec_supported_mixers; + break; + + case SOUND_MIXER_RECMASK: + /* Arg contains a bit for each supported recording source */ + val = AC97_RECORD_MASK; + break; + + case SOUND_MIXER_STEREODEVS: + /* Mixer channels supporting stereo */ + val = AC97_STEREO_MASK; + break; + + case SOUND_MIXER_CAPS: + val = SOUND_CAP_EXCL_INPUT; + break; + + default: + if (!supported_mixer(nr)) + return -EINVAL; + + val = guiOSS_Volume[nr]; + break; + + } /* switch */ + + return put_user(val, (int *)arg); + } + + if (_SIOC_DIR(cmd) == (_SIOC_WRITE | _SIOC_READ)) { + if (get_user(val, (int *)arg)) + return -EFAULT; + + switch (nr) { + case SOUND_MIXER_RECSRC: + return ep93xx_set_recsource(val); + + default: + if (!supported_mixer(nr)) + return -EINVAL; + + ep93xx_set_volume(nr, val); + hw->modcnt++; + return 0; + } + } + + return -EINVAL; +} + +static struct file_operations ep93xx_mixer_fops = { + owner:THIS_MODULE, + llseek:no_llseek, + ioctl:ep93xx_mixer_ioctl, + open:ep93xx_mixer_open, + release:ep93xx_mixer_release, +}; + +/* + * Audio interface + */ +static void ep93xx_audio_init(void *dummy) +{ + DPRINTK("ep93xx_audio_init - enter\n"); + + /* + * Init the controller, enable the ac-link. + * Initialize the codec. + */ + ep93xx_init_ac97_controller(); + ep93xx_init_ac97_codec(); + +#ifdef DEBUG + ep93xx_dump_ac97_regs(); +#endif + + DPRINTK("ep93xx_audio_init - EXIT\n"); +} + +static int ep93xx_audio_ioctl(struct inode *inode, struct file *file, + uint cmd, ulong arg) +{ + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *os = state->output_stream; + struct audio_stream_t *is = state->input_stream; + long val; + int ret = 0; + + /* + * These are platform dependent ioctls which are not handled by the + * generic ep93xx-audio module. + */ + switch (cmd) { + case SNDCTL_DSP_SPEED: + + DPRINTK("ep93xx_audio_ioctl - SNDCTL_DSP_SPEED\n"); + + if (get_user(val, (int *)arg)) { + return -EFAULT; + } + + if ((file->f_mode & FMODE_WRITE) && (val != os->sample_rate)) { + ep93xx_set_samplerate(os, val); + } + if ((file->f_mode & FMODE_READ) && (val != is->sample_rate)) { + ep93xx_set_samplerate(is, val); + } + + return put_user(val, (long *)arg); + + case SOUND_PCM_READ_RATE: + DPRINTK("ep93xx_audio_ioctl - SOUND_PCM_READ_RATE\n"); + if (file->f_mode & FMODE_WRITE) { + return put_user(os->sample_rate, (long *)arg); + } + return put_user(is->sample_rate, (long *)arg); + + default: + DPRINTK("ep93xx_audio_ioctl-->ep93xx_mixer_ioctl\n"); + /* Maybe this is meant for the mixer (As per OSS Docs) */ + return ep93xx_mixer_ioctl(inode, file, cmd, arg); + } + + return ret; +} + +static int ep93xx_audio_open(struct inode *inode, struct file *file) +{ + DPRINTK("ep93xx_audio_open\n"); + return ep93xx_audio_attach(inode, file, &ac97_audio_state0); +} + +/* + * Missing fields of this structure will be patched with the call + * to ep93xx_audio_attach(). + */ +static struct file_operations ep93xx_audio_fops = { + open:ep93xx_audio_open, + owner:THIS_MODULE +}; + +static int audio_dev_id, mixer_dev_id; + +static int __init ep93xx_ac97_init(void) +{ + DPRINTK("ep93xx_ac97_init - enter\n"); + + // KERNEL2.4 + sema_init(&ac97_audio_state0.sem, 1); + + /* + * Enable audio early on, give the DAC time to come up. + */ + ep93xx_audio_init(0); + + /* + * Register devices using sound_core.c's devfs stuff + */ + audio_dev_id = register_sound_dsp(&ep93xx_audio_fops, -1); + if (audio_dev_id < 0) { + DPRINTK + (" ep93xx_ac97_init: register_sound_dsp failed for dsp.\n"); + return -ENODEV; + } + + mixer_dev_id = register_sound_mixer(&ep93xx_mixer_fops, -1); + if (mixer_dev_id < 0) { + DPRINTK + (" ep93xx_ac97_init: register_sound_dsp failed for mixer.\n"); + return -ENODEV; + } + + printk(KERN_INFO "EP93xx Ac97 audio support initialized.\n"); + return 0; +} + +static void __exit ep93xx_ac97_exit(void) +{ + unregister_sound_dsp(audio_dev_id); + unregister_sound_mixer(mixer_dev_id); +} + +module_init(ep93xx_ac97_init); +module_exit(ep93xx_ac97_exit); + +MODULE_DESCRIPTION("Audio driver for the Cirrus EP93xx Ac97 controller."); +MODULE_LICENSE("GPL"); +/* EXPORT_NO_SYMBOLS; */ diff --git a/sound/oss/ep93xx-audio.c b/sound/oss/ep93xx-audio.c new file mode 100644 index 0000000..7e00d6d --- /dev/null +++ b/sound/oss/ep93xx-audio.c @@ -0,0 +1,3821 @@ +/* + * ep93xx-audio.c + * + * Common audio handling for the Cirrus EP93xx processor. + * + * Copyright (c) 2003 Cirrus Logic Corp. + * Copyright (C) 2000, 2001 Nicolas Pitre + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + * + * Taken from sa1100-audio.c + * + * This module handles the generic buffering/DMA/mmap audio interface for + * codecs connected to the EP93xx chip. All features depending on specific + * hardware implementations like supported audio formats or samplerates are + * relegated to separate specific modules. + * + * + * History: + * + * 2000-05-21 Nicolas Pitre Initial release. + * + * 2000-06-10 Erik Bunce Add initial poll support. + * + * 2000-08-22 Nicolas Pitre Removed all DMA stuff. Now using the + * generic SA1100 DMA interface. + * + * 2000-11-30 Nicolas Pitre - Validation of opened instances; + * - Power handling at open/release time instead + * of driver load/unload; + * + * 2001-06-03 Nicolas Pitre Made this file a separate module, based on + * the former sa1100-uda1341.c driver. + * + * 2001-07-22 Nicolas Pitre - added mmap() and realtime support + * - corrected many details to better comply + * with the OSS API + * + * 2001-10-19 Nicolas Pitre - brought DMA registration processing + * into this module for better ressource + * management. This also fixes a bug + * with the suspend/resume logic. + * + * 2003-04-04 Adapted for EP93xx I2S/Ac97 audio. + * + * 2004-04-23 Added support for multiple stereo streams. + * + * 2005-05-11 Manfred Gruber - Ported this from Cirrus Logic Virgo 1-4-3 release + * to Kernel 2.6.11.X + */ + +#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 "ep93xx-audio.h" + +#undef DEBUG +//#define DEBUG 1 +#ifdef DEBUG +#define DPRINTK( fmt, arg... ) printk( fmt, ##arg ) +#else +#define DPRINTK( fmt, arg... ) +#endif + +/* Mostly just prints what ioctls got called */ +//#define DEBUG 1 +#ifdef DEBUG +#define DPRINTK_IOCTL( fmt, arg... ) printk( fmt, ##arg ) +#else +#define DPRINTK_IOCTL( fmt, arg... ) +#endif + +/* + * Experiencing gaps in your audio? Try upping the AUDIO_NBFRAGS_DEFAULT! + * Experiencing memory problems? Try lowering them. + * DMA memory space is precious and rare on ARM. + * + */ + +// +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO +#define AUDIO_NBFRAGS_DEFAULT 31 +#define AUDIO_FRAGSIZE_DEFAULT 65536 +#define AUDIO_NBFRAGS_MAX 31 +#else +#ifdef CONFIG_SOUND_EP93XX_AC97 +// Values changed from KERNEL2.4 +#define AUDIO_NBFRAGS_DEFAULT 4 +#define AUDIO_FRAGSIZE_DEFAULT 8192 // max is 65536 +#define AUDIO_NBFRAGS_MAX 4 +#else +#define AUDIO_NBFRAGS_DEFAULT 16 +#define AUDIO_FRAGSIZE_DEFAULT 32768 // max is 65536 +#define AUDIO_NBFRAGS_MAX 16 +#endif +#endif + +/* + * NEXT_BUF + * + * Translates to: + * stream->dma_buffer_index++; + * stream->dma_buffer_index %= stream->nbfrags; + * stream->dma_buffer = stream->buffers + stream->dma_buffer_index; + * + * So stream->dma_buffer always points to the stream->dma_buffer_index-nth element + * of stream->buffers. + */ +#define NEXT_BUF(_s_,_b_) { \ + (_s_)->_b_##_index++; \ + (_s_)->_b_##_index %= (_s_)->nbfrags; \ + (_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_index; } + +#define AUDIO_ACTIVE(state) ((state)->rd_ref || (state)->wr_ref) + +/* Function prototypes */ +static __inline__ int copy_to_user_with_conversion + (struct audio_state_t *state, + const char *to, const char *from, int toCount); + +static __inline__ int copy_from_user_with_conversion + (struct audio_state_t *state, + const char *to, const char *from, int toCount); + +static void audio_dma_start(struct audio_state_t *state, + struct audio_stream_t *stream); +static void audio_dma_pause(struct audio_state_t *state, + struct audio_stream_t *stream); +static void audio_prime_dma(struct audio_state_t *state, + struct audio_stream_t *stream); + +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO +#define DMA_ADD_BUFFER pio_add_buffer +#define DMA_CONFIG pio_config +#define DMA_FLUSH pio_flush +#define DMA_FREE pio_free +#define DMA_GET_POSITION pio_get_position +#define DMA_PAUSE pio_pause +#define DMA_REMOVE_BUFFER pio_remove_buffer +#define DMA_REQUEST pio_request +#define DMA_START pio_start +#else +#define DMA_ADD_BUFFER ep93xx_dma_add_buffer +#define DMA_CONFIG ep93xx_dma_config +#define DMA_FLUSH ep93xx_dma_flush +#define DMA_FREE ep93xx_dma_free +#define DMA_GET_POSITION ep93xx_dma_get_position +#define DMA_PAUSE ep93xx_dma_pause +#define DMA_REMOVE_BUFFER ep93xx_dma_remove_buffer +#define DMA_REQUEST ep93xx_dma_request +#define DMA_START ep93xx_dma_start +#endif + +#ifdef CONFIG_SOUND_EP93XX_AUDIO_PIO +/* + * The maximum number of buffers accepted by the PIO interface. + */ +#define PIO_MAX_BUFFERS 32 + +/* + * A convenienced macro to advance from one buffer to the next. + */ +#define PIO_NEXT(x) (((x) + 1) % PIO_MAX_BUFFERS) + +/* + * A structure to remember information about a buffer. + */ +struct pio_buffer { + unsigned int source; + unsigned int pos; + unsigned int size; + int buf_id; +}; + +/* + * A structure to remember information about a stream. + */ +struct pio_stream { + int assigned; + struct pio_buffer queue[PIO_MAX_BUFFERS]; + ep93xx_dma_dev_t device; + int first; + int cur; + int last; + int bytes; + int pause; + dma_callback callback; + unsigned int user_data; +}; + +/* + * The twelve streams that we can handle. + */ +static struct pio_stream pio_streams[12]; + +/* + * Reference counts for the two interrupt handlers. + */ +static int pio_irq_ref_count[2]; + +/* + * The registers that enable the three I2S transmitters. + */ +static const unsigned int i2s_txenable[3] = { + I2STX0En, + I2STX1En, + I2STX2En +}; + +/* + * The flag that indicates a FIFO full condition on the three I2S transmitters. + */ +static const unsigned int i2s_txflag[3] = { + TX0_FIFO_FULL, + TX1_FIFO_FULL, + TX2_FIFO_FULL +}; + +/* + * The register that contains the left channel data for the three I2S + * transmitters. + */ +static const unsigned int i2s_tx_lft[3] = { + I2STX0Lft, + I2STX1Lft, + I2STX2Lft +}; + +/* + * The register that contains the right channel data for the three I2S + * transmitters. + */ +static const unsigned int i2s_tx_rt[3] = { + I2STX0Rt, + I2STX1Rt, + I2STX2Rt +}; + +/* + * The registers that enable the three I2S receivers. + */ +static const unsigned int i2s_rxenable[3] = { + I2SRX0En, + I2SRX1En, + I2SRX2En +}; + +/* + * The flag that indicates a FIFO empty condition on the three I2S receivers. + */ +static const unsigned int i2s_rxflag[3] = { + RX0_FIFO_EMPTY, + RX1_FIFO_EMPTY, + RX2_FIFO_EMPTY +}; + +/* + * The register that contains the left channel data for the three I2S + * receivers. + */ +static const unsigned int i2s_rx_lft[3] = { + I2SRX0Lft, + I2SRX1Lft, + I2SRX2Lft +}; + +/* + * The register that contains the right channel data for the three I2S + * receivers. + */ +static const unsigned int i2s_rx_rt[3] = { + I2SRX0Rt, + I2SRX1Rt, + I2SRX2Rt +}; + +/* + * The registers that contain the status for the three AC'97 transceivers. + */ +static const unsigned int ac97_status[3] = { + AC97SR1, + AC97SR2, + AC97SR3 +}; + +/* + * The registers that contain the audio data for the three AC'97 transceivers. + */ +static const unsigned int ac97_data[3] = { + AC97DR1, + AC97DR2, + AC97DR3 +}; + +/* + * The registers that control the three AC'97 transmitters. + */ +static const unsigned int ac97_txctrl[3] = { + AC97TXCR1, + AC97TXCR2, + AC97TXCR3 +}; + +/* + * The registers that control the three AC'97 receivers. + */ +static const unsigned int ac97_rxctrl[3] = { + AC97RXCR1, + AC97RXCR2, + AC97RXCR3 +}; + +/* + * The descriptor for our FIQ handler. + */ +static struct fiq_handler fh = { NULL, "pio_audio", NULL, NULL }; + +/* + * Stack space for our FIQ handler. + */ +static unsigned char fiq_stack[1024]; + +/* + * References to the labels in the inline assembly. + */ +extern void i2s_fiq_begin; +extern void i2s_fiq_end; +extern void ac97_fiq_begin; +extern void ac97_fiq_end; + +/* + * The FIQ handler for I2S audio. This stub is copied into the vector area and + * simply calls the I2S interrupt handler. + */ +void pio_i2s_fiq_handler(void) +{ + __asm__ __volatile__("\n\ +i2s_fiq_begin:\n\ + stmdb r13!, {r0-r7, lr}\n\ + ldr r0, =pio_i2s_irq_handler\n\ + mov lr, pc\n\ + mov pc, r0\n\ + ldmia r13!, {r0-r7, lr}\n\ + subs pc, lr, #4\n\ + .ltorg\n\ +i2s_fiq_end:"); +} + +/* + * The FIQ handler for AC'97 audio. This stub is copied into the vector area + * and simply calls the AC'97 interrupt handler. + */ +void pio_ac97_fiq_handler(void) +{ + __asm__ __volatile__("\n\ +ac97_fiq_begin:\n\ + stmdb r13!, {r0-r7, lr}\n\ + ldr r0, =pio_ac97_irq_handler\n\ + mov lr, pc\n\ + mov pc, r0\n\ + ldmia r13!, {r0-r7, lr}\n\ + subs pc, lr, #4\n\ + .ltorg\n\ +ac97_fiq_end:"); +} + +/* + * The interrupt handler for I2S audio. + */ +static void pio_i2s_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pio_stream *p; + struct pio_buffer *b; + int idx; + + /* + * Increment the count of interrupts. + */ + kstat.irqs[smp_processor_id()][IRQ_SAI]++; + + /* + * Loop through the three transmitters. + */ + for (idx = 0; idx < 3; idx++) { + /* + * Do nothing if this transmitter is not enabled. + */ + if (!inl(i2s_txenable[idx])) + continue; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[idx]; + + /* + * Loop while the transmit FIFO is not full. + */ + while (!(inl(I2SGlSts) & i2s_txflag[idx])) { + /* + * If the stream is not assigned, is paused, or has no + * data, then write out silence. + */ + if (!p->assigned || p->pause || (p->cur == p->last)) { + outl(0, i2s_tx_lft[idx]); + outl(0, i2s_tx_rt[idx]); + } else { + /* + * Get a pointer to the current buffer. + */ + b = &p->queue[p->cur]; + + /* + * Write out the next sample. + */ + outl(*(unsigned long *)b->source, + i2s_tx_lft[idx]); + outl(*(unsigned long *)(b->source + 4), + i2s_tx_rt[idx]); + + /* + * Increment past the next sample. + */ + b->source += 8; + b->pos += 8; + + /* + * See if the buffer has been consumed. + */ + if (b->pos == b->size) { + /* + * Increment the count of bytes + * transmitted. + */ + p->bytes += b->size; + + /* + * Go to the next buffer. + */ + p->cur = PIO_NEXT(p->cur); + + /* + * Call the callback if there is one. + */ + if (p->callback) + p->callback(NFB, p->device, + p->user_data); + } + } + } + } + + /* + * Loop through the three receivers. + */ + for (idx = 0; idx < 3; idx++) { + /* + * Do nothing if this receiver is not enabled. + */ + if (!inl(i2s_rxenable[idx])) + continue; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[idx + 3]; + + /* + * Loop while the receive FIFO is not empty. + */ + while (!(inl(I2SGlSts) & i2s_rxflag[idx])) { + /* + * If the stream is not assigned, is paused, or has no + * buffer space, then throw away the data. + */ + if (!p->assigned || p->pause || (p->cur == p->last)) { + inl(i2s_rx_lft[idx]); + inl(i2s_rx_rt[idx]); + } else { + /* + * Get a pointer to the current buffer. + */ + b = &p->queue[p->cur]; + + /* + * Read in the next sample. + */ + *(unsigned long *)b->source = + inl(i2s_rx_lft[idx]); + *(unsigned long *)(b->source + 4) = + inl(i2s_rx_rt[idx]); + + /* + * Increment past the next sample. + */ + b->source += 8; + b->pos += 8; + + /* + * See if the buffer has been consumed. + */ + if (b->pos == b->size) { + /* + * Increment the count of bytes + * received. + */ + p->bytes += b->size; + + /* + * Go to the next buffer. + */ + p->cur = PIO_NEXT(p->cur); + + /* + * Call the callback if there is one. + */ + if (p->callback) + p->callback(NFB, p->device, + p->user_data); + } + } + } + } + + /* + * Clear any overrun or underrun conditions that may exist. + */ + outl(0, I2SGlSts); +} + +/* + * The interrupt handler for AC'97 audio. +*/ +static void pio_ac97_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pio_stream *p; + struct pio_buffer *b; + int idx, cm; + + /* + * Increment the count of interrupts. + */ + kstat.irqs[smp_processor_id()][IRQ_AAC]++; + + /* + * Loop through the three transmitters. + */ + for (idx = 0; idx < 3; idx++) { + /* + * Do nothing if this transmitter is not enabled. + */ + if (!(inl(ac97_txctrl[idx]) & AC97TXCR_TEN)) + continue; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[idx + 6]; + + /* + * See if this transmitter is in compact mode. + */ + cm = inl(ac97_txctrl[idx]) & AC97TXCR_CM; + + /* + * Loop while the transmit FIFO is not full. + */ + while (!(inl(ac97_status[idx]) & AC97SR_TXFF)) { + /* + * If the stream is not assigned, is paused, or has no + * data, then write out silence. + */ + if (!p->assigned || p->pause || (p->cur == p->last)) { + outl(0, ac97_data[idx]); + if (!cm) + outl(0, ac97_data[idx]); + } else { + /* + * Get a pointer to the current buffer. + */ + b = &p->queue[p->cur]; + + /* + * Write out the next sample. + */ + outl(*(unsigned long *)b->source, + ac97_data[idx]); + + /* + * Increment past the next sample. + */ + b->source += 4; + b->pos += 4; + + /* + * Write another sample if we are not in + * compact mode. + */ + if (!cm) { + outl(*(unsigned long *)b->source, + ac97_data[idx]); + b->source += 4; + b->pos += 4; + } + + /* + * See if the buffer has been consumed. + */ + if (b->pos == b->size) { + /* + * Increment the count of bytes + * transmitted. + */ + p->bytes += b->size; + + /* + * Go to the next buffer. + */ + p->cur = PIO_NEXT(p->cur); + + /* + * Call the callback if there is one. + */ + if (p->callback) + p->callback(NFB, p->device, + p->user_data); + } + } + } + } + + /* + * Loop through the three receivers. + */ + for (idx = 0; idx < 3; idx++) { + /* + * Do nothing if this receiver is not enabled. + */ + if (!(inl(ac97_rxctrl[idx]) & AC97RXCR_REN)) + continue; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[idx + 9]; + + /* + * See if this receiver is in compact mode. + */ + cm = inl(ac97_rxctrl[idx]) & AC97RXCR_CM; + + /* + * Loop while the receive FIFO is not empty. + */ + while (!(inl(ac97_status[idx]) & AC97SR_RXFE)) { + /* + * If the stream is not assigned, is paused, or has no + * buffer space, then throw away the data. + */ + if (!p->assigned || p->pause || (p->cur == p->last)) { + inl(ac97_data[idx]); + if (!cm) + inl(ac97_data[idx]); + } else { + /* + * Get a pointer to the current buffer. + */ + b = &p->queue[p->cur]; + + /* + * Read in the next sample. + */ + *(unsigned long *)b->source = + inl(ac97_data[idx]); + + /* + * Increment past the next sample. + */ + b->source += 4; + b->pos += 4; + + /* + * Read another sample if we are not in compact + * mode. + */ + if (!cm) { + *(unsigned long *)b->source = + inl(ac97_data[idx]); + b->source += 4; + b->pos += 4; + } + + /* + * See if the buffer has been consumed. + */ + if (b->pos == b->size) { + /* + * Increment the count of bytes + * received. + */ + p->bytes += b->size; + + /* + * Go to the next buffer. + */ + p->cur = PIO_NEXT(p->cur); + + /* + * Call the callback if there is one. + */ + if (p->callback) + p->callback(NFB, p->device, + p->user_data); + } + } + } + } +} + +/* + * Add a buffer to a PIO stream. + */ +static int +pio_add_buffer(int handle, unsigned int source, unsigned int dest, + unsigned int size, unsigned int last, unsigned int buf_id) +{ + struct pio_stream *p; + struct pio_buffer *b; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * Fail if there is not space for another buffer. + */ + if (PIO_NEXT(p->last) == p->first) + return -1; + + /* + * Get a pointer to the next buffer. + */ + b = &p->queue[p->last]; + + /* + * Save the information about this buffer. + */ + b->source = (unsigned int)phys_to_virt(source); + b->pos = 0; + b->size = size; + b->buf_id = buf_id; + + /* + * Increment the last pointer. + */ + p->last = PIO_NEXT(p->last); + + /* + * Success. + */ + return 0; +} + +/* + * Configure a PIO stream. + */ +static int +pio_config(int handle, unsigned int flags_m2p, unsigned int flags_m2m, + dma_callback callback, unsigned int user_data) +{ + struct pio_stream *p; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * This puts the stream into pause mode. + */ + p->pause = 1; + + /* + * Save the callback function information. + */ + p->callback = callback; + p->user_data = user_data; + + /* + * Success. + */ + return 0; +} + +/* + * Flush all data from a PIO stream. + */ +static int pio_flush(int handle) +{ + struct pio_stream *p; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * Disable interrupts. + */ + clf(); + + /* + * Blast all buffer information from this stream. + */ + p->first = 0; + p->cur = 0; + p->last = 0; + p->bytes = 0; + + /* + * Enable interrupts. + */ + stf(); + + /* + * Success. + */ + return 0; +} + +/* + * Free a PIO stream. + */ +static int pio_free(int handle) +{ + /* + * See if this is a I2S or AC'97 stream. + */ + if (handle < 6) { + /* + * Decrement the I2S reference count. + */ + pio_irq_ref_count[0]--; + + /* + * See if the reference count is now zero. + */ + if (pio_irq_ref_count[0] == 0) { + /* + * Make the I2S interrupt an IRQ instead of a FIQ. + */ + outl(inl(VIC1INTSELECT) & ~(1 << (IRQ_SAI - 32)), + VIC1INTSELECT); + + /* + * Disable I2S interrupts in the I2S block. + */ + outl(0, I2STXCtrl); + outl(0, I2SRXCtrl); + + /* + * Release the I2S interrupt. + */ + free_irq(IRQ_SAI, (void *)&pio_i2s_irq_handler); + + /* + * Release the FIQ. + */ + release_fiq(&fh); + } + } else { + /* + * Decrement the AC'97 reference count. + */ + pio_irq_ref_count[1]--; + + /* + * See if the reference count is now zero. + */ + if (pio_irq_ref_count[1] == 0) { + /* + * Make the AC'97 interrupt an IRQ instead of a FIQ. + */ + outl(inl(VIC0INTSELECT) & ~(1 << IRQ_AAC), + VIC0INTSELECT); + + /* + * Release the AC'97 interrupt. + */ + free_irq(IRQ_AAC, (void *)&pio_ac97_irq_handler); + + /* + * Release the FIQ. + */ + release_fiq(&fh); + } + } + + /* + * Mark this stream as unassigned. + */ + pio_streams[handle].assigned = 0; + + /* + * Success. + */ + return 0; +} + +/* + * Get the current position in a PIO stream. + */ +static int +pio_get_position(int handle, unsigned int *buf_id, unsigned int *total, + unsigned int *current_frac) +{ + struct pio_stream *p; + struct pio_buffer *b; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * Disable interrupts. + */ + clf(); + + /* + * Get a pointer to the current buffer. + */ + b = &p->queue[p->cur]; + + /* + * If the buffer is is being requested, then return it. + */ + if (buf_id) + *buf_id = b->buf_id; + + /* + * If the total bytes transferred is being requested, then return it. + */ + if (total) + *total = p->bytes; + + /* + * If the bytes transferred from the current buffer is being requested, + * then return it. + */ + if (current_frac) + *current_frac = b->size - b->pos; + + /* + * Enable interrupts. + */ + stf(); + + /* + * Success. + */ + return 0; +} + +/* + * Pause a PIO stream. + */ +static int pio_pause(int handle, unsigned int channels, unsigned int *handles) +{ + struct pio_stream *p; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * Pause the stream. + */ + p->pause = 1; + + /* + * Success. + */ + return 0; +} + +/* + * Remove a consumed buffer from a PIO stream. + */ +static int pio_remove_buffer(int handle, unsigned int *buf_id) +{ + struct pio_stream *p; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * Fail if there are not consumed buffers. + */ + if (p->first == p->cur) + return -1; + + /* + * Return the ID of the next fully consumed buffer. + */ + *buf_id = p->queue[p->first].buf_id; + + /* + * Increment the first pointer. + */ + p->first = PIO_NEXT(p->first); + + /* + * Success. + */ + return 0; +} + +/* + * Request a PIO stream. + */ +static int +pio_request(int *handle, const char *device_id, ep93xx_dma_dev_t device) +{ + struct pio_stream *p; + struct pt_regs regs; + int idx, error; + + /* + * Get the stream index from the DMA device we are emulating. + */ + switch (device) { + case DMATx_I2S1: + idx = 0; + break; + case DMATx_I2S2: + idx = 1; + break; + case DMATx_I2S3: + idx = 2; + break; + case DMARx_I2S1: + idx = 3; + break; + case DMARx_I2S2: + idx = 4; + break; + case DMARx_I2S3: + idx = 5; + break; + case DMATx_AAC1: + idx = 6; + break; + case DMATx_AAC2: + idx = 7; + break; + case DMATx_AAC3: + idx = 8; + break; + case DMARx_AAC1: + idx = 9; + break; + case DMARx_AAC2: + idx = 10; + break; + case DMARx_AAC3: + idx = 11; + break; + default: + return -ENODEV; + } + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[idx]; + + /* + * Fail if this stream is already assigned. + */ + if (p->assigned) + return -EBUSY; + + /* + * Initialize this stream. + */ + memset(p->queue, 0, sizeof(p->queue)); + p->device = device; + p->first = 0; + p->cur = 0; + p->last = 0; + p->bytes = 0; + p->pause = 0; + p->callback = 0; + p->user_data = 0; + + /* + * Mark this stream as assigned. + */ + p->assigned = 1; + + /* + * See if this is a I2S or AC'97 stream. + */ + if (idx < 6) { + /* + * If there is already a AC'97 stream in use, then do not allow + * I2S streams. + */ + if (pio_irq_ref_count[1]) + return -EBUSY; + + /* + * See if there is another I2S stream. + */ + if (pio_irq_ref_count[0] == 0) { + /* + * Claim the FIQ handler. + */ + if (claim_fiq(&fh)) + return -EBUSY; + + /* + * Request the I2S interrupt. + */ + error = request_irq(IRQ_SAI, pio_i2s_irq_handler, + SA_INTERRUPT, "i2s", + (void *)&pio_i2s_irq_handler); + if (error) { + release_fiq(&fh); + return error; + } + + /* + * Set the FIQ mode registers. + */ + regs.ARM_sp = (long)fiq_stack + sizeof(fiq_stack); + set_fiq_regs(®s); + + /* + * Set the FIQ handler. + */ + set_fiq_handler(&i2s_fiq_begin, + &i2s_fiq_end - &i2s_fiq_begin); + + /* + * Make the I2S interrupt a FIQ instead of an IRQ. + */ + outl(inl(VIC1INTSELECT) | (1 << (IRQ_SAI - 32)), + VIC1INTSELECT); + + /* + * Enable transmit half empty and receive half full + * interrupts in the I2S block. + */ + outl(2, I2STXCtrl); + outl(2, I2SRXCtrl); + } + + /* + * Increment the I2S interrupt reference count. + */ + pio_irq_ref_count[0]++; + } else { + /* + * If there is already a I2S stream in use, then do not allow + * AC'97 streams. + */ + if (pio_irq_ref_count[0]) + return -EBUSY; + + /* + * See if there is another AC'97 stream. + */ + if (pio_irq_ref_count[1] == 0) { + /* + * Claim the FIQ handler. + */ + if (claim_fiq(&fh)) + return -EBUSY; + + /* + * Request the AC'97 interrupt. + */ + error = request_irq(IRQ_AAC, pio_ac97_irq_handler, + SA_INTERRUPT, "ac-97", + (void *)&pio_ac97_irq_handler); + if (error) { + release_fiq(&fh); + return error; + } + + /* + * Set the FIQ mode registers. + */ + regs.ARM_sp = (long)fiq_stack + sizeof(fiq_stack); + set_fiq_regs(®s); + + /* + * Set the FIQ handler. + */ + set_fiq_handler(&ac97_fiq_begin, + &ac97_fiq_end - &ac97_fiq_begin); + + /* + * Make the AC'97 interrupt a FIQ instead of an IRQ. + */ + outl(inl(VIC0INTSELECT) | (1 << IRQ_AAC), + VIC0INTSELECT); + } + + /* + * Increment the AC'97 interrupt reference count. + */ + pio_irq_ref_count[1]++; + } + + /* + * Return a handle to this stream. + */ + *handle = idx; + + /* + * Success. + */ + return 0; +} + +/* + * Start a PIO stream. + */ +static int pio_start(int handle, unsigned int channels, unsigned int *handles) +{ + struct pio_stream *p; + + /* + * Get a pointer to this stream's structure. + */ + p = &pio_streams[handle]; + + /* + * Start the stream. + */ + p->pause = 0; + + /* + * Success. + */ + return 0; +} +#endif + +/* + * calculate_dma2usr_ratio_etc() + * + * For audio playback, we convert samples of arbitrary format to be 32 bit + * for our hardware. We're scaling a user buffer to a dma buffer. So when + * report byte counts, we scale them acording to the ratio of DMA sample + * size to user buffer sample size. When we report # of DMA fragments, + * we don't scale that. So: + * - The fragment size the app sees = (stream->fragsize/stream->dma2usr_ratio) + * - The # of fragments the app sees = stream->nbfrags + * + * User sample type can be stereo/mono/8/16/32 bit. + * DMA sample type will be either CM (compact mode) where two 16 bit + * samples together in a 32 bit word become a stereo sample or non-CM + * where each channel gets a 32 bit word. + * + * Any time usr sample type changes, we need to call this function. + * + * Also adjust the size and number of dma fragments if sample size changed. + * + * Input format Input sample Output sample size ratio (out:in) + * bits channels size (bytes) CM non-CM CM non-CM + * 8 mono 1 4 8 4:1 8:1 + * 8 stereo 2 4 8 2:1 4:1 + * 16 mono 2 4 8 2:1 4:1 + * 16 stereo 4 4 8 1:1 2:1 + * + * 24 mono 3 4 8 X 8:3 not a real case + * 24 stereo 6 4 8 X 8:6 not a real case + * 32 mono 4 4 8 X 2:1 + * 32 stereo 8 4 8 X 1:1 + * + */ +static void calculate_dma2usr_ratio_etc(struct audio_stream_t *stream) +{ + unsigned int dma_sample_size, user_sample_size; + + if (stream->bCompactMode) + dma_sample_size = 4; /* each stereo sample is 2 * 16 bits */ + else + dma_sample_size = 8; /* each stereo sample is 2 * 32 bits */ + + if (stream->audio_num_channels != 1) { + // If stereo 16 bit, user sample is 4 bytes. + // If stereo 8 bit, user sample is 2 bytes. + user_sample_size = stream->audio_stream_bitwidth / 4; + } else { + // If mono 16 bit, user sample is 2 bytes. + // If mono 8 bit, user sample is 1 bytes. + user_sample_size = stream->audio_stream_bitwidth / 8; + } + + /* + * dma2usr_ratio = (4 or 8) / (4, 2, or 1) = 8, 4, 2, or 1 + */ + stream->dma2usr_ratio = dma_sample_size / user_sample_size; + + DPRINTK(" samplesize: dma %d user %d dma/usr ratio %d\n", + dma_sample_size, user_sample_size, stream->dma2usr_ratio); + DPRINTK + (" requested: fragsize %d num frags %d total bytes %d total samples %d\n", + stream->requested_fragsize, stream->requested_nbfrags, + stream->requested_fragsize * stream->requested_nbfrags, + (stream->requested_fragsize * stream->requested_nbfrags) / + user_sample_size); + DPRINTK + (" usr : fragsize %d num frags %d total bytes %d total samples %d\n", + (stream->fragsize / stream->dma2usr_ratio), stream->nbfrags, + stream->fragsize * stream->nbfrags / stream->dma2usr_ratio, + (stream->fragsize * stream->nbfrags) / (stream->dma2usr_ratio * + user_sample_size)); + DPRINTK + (" dma: fragsize %d num frags %d total bytes %d total samples %d\n", + stream->fragsize, stream->nbfrags, + stream->fragsize * stream->nbfrags, + (stream->fragsize * stream->nbfrags) / dma_sample_size); + +} + +/* + * audio_deallocate_buffers + * + * This function frees all buffers + */ +static void audio_deallocate_buffers(struct audio_state_t *state, + struct audio_stream_t *stream) +{ + int frag, i; + + DPRINTK("EP93xx - audio_deallocate_buffers\n"); + + /* ensure DMA won't run anymore */ + audio_dma_pause(state, stream); + stream->active = 0; + stream->stopped = 0; + + for (i = 0; i < stream->NumDmaChannels; i++) + DMA_FLUSH(stream->dmahandles[i]); + + if (stream->buffers) { + for (frag = 0; frag < stream->nbfrags; frag++) { + if (!stream->buffers[frag].master) { + continue; + } + // KERNEL2.4 + //consistent_free(stream->buffers[frag].start, + // stream->buffers[frag].master, + // stream->buffers[frag].dma_addr); + dma_free_coherent(NULL, stream->buffers[frag].master, + stream->buffers[frag].start, + stream->buffers[frag].dma_addr); + + } + + /* + * Free the space allocated to the array of dma_buffer structs. + */ + kfree(stream->buffers); + stream->buffers = NULL; + } + + stream->buffered_bytes_to_play = 0; + stream->dma_buffer_index = 0; + stream->dma_buffer = NULL; + stream->bytecount = 0; + stream->getptrCount = 0; + stream->fragcount = 0; + + DPRINTK("EP93xx - audio_deallocate_buffers - EXIT\n"); +} + +/* + * audio_allocate_buffers + * + * This function allocates the buffer structure array and buffer data space + * according to the current number of fragments and fragment size. + * Note that the output_stream and input_stream structs are allocated + * in ep93xx-ac97.c or ep93xx-i2s.c. + */ +static int audio_allocate_buffers(struct audio_state_t *state, + struct audio_stream_t *stream) +{ + int frag; + int dmasize = 0; + char *dmabuf = NULL; + dma_addr_t dmaphys = 0; + int buf_num = 0; + + if (stream->buffers) + return -EBUSY; + + DPRINTK("EP93xx audio_allocate_buffers\n"); + + /* + * Allocate space for the array of struct audio_buf_t structs. + */ + stream->buffers = (struct audio_buf_t *) + kmalloc(sizeof(struct audio_buf_t) * stream->nbfrags, GFP_KERNEL); + + if (!stream->buffers) { + DPRINTK("ep93xx-audio: unable to allocate audio memory\n "); + audio_deallocate_buffers(state, stream); + return -ENOMEM; + } + + /* + * If the audio app hasn't requested a specific fragsize and nbfrags, + * we stay with our default. + */ + if ((stream->requested_fragsize != 0) + && (stream->requested_nbfrags != 0)) { + /* + * Adjust the fragsize to take into account how big actual samples in + * the dma buffer are. Max dma buf size is 64K. + */ + stream->fragsize = + stream->requested_fragsize * stream->dma2usr_ratio; + } + + if (stream->fragsize > 65536) + stream->fragsize = 65536; + if (stream->fragsize < 8192) + stream->fragsize = 8192; + + /* + * Adjust num of frags so we have as many samples of buffer as were requested + * even if the fragment size changed. + */ + if ((stream->requested_fragsize != 0) + && (stream->requested_nbfrags != 0)) { + stream->nbfrags = + (stream->requested_fragsize * stream->requested_nbfrags * + stream->dma2usr_ratio) + / stream->fragsize; + } + + if (stream->nbfrags < 2) + stream->nbfrags = 2; + if (stream->nbfrags > AUDIO_NBFRAGS_MAX) + stream->nbfrags = AUDIO_NBFRAGS_MAX; + + memset(stream->buffers, 0, + sizeof(struct audio_buf_t) * stream->nbfrags); + + /* + * Let's allocate non-cached memory for DMA buffers. + * We try to allocate all memory at once. + * If this fails (a common reason is memory fragmentation), + * then we allocate more smaller buffers. + */ + for (frag = 0; frag < stream->nbfrags; frag++) { + struct audio_buf_t *dma_buffer = &stream->buffers[frag]; + + if (!dmasize) { + /* + * First try to allocate enough for all the frags that + * don't yet have memory allocated. + */ + dmasize = (stream->nbfrags - frag) * stream->fragsize; + do { + // GRM + //dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA, + // dmasize, &dmaphys); + dmabuf = dma_alloc_coherent(NULL, + dmasize, &dmaphys, + GFP_KERNEL | + GFP_DMA); + + /* + * If that fails, try to allocate a chunk of memory + * that is one less fragment is size. + */ + if (!dmabuf) + dmasize -= stream->fragsize; + + /* + * Keep trying but the minimum we'll attempt is one + * fragment. If we can't even get that, give up. + */ + } while (!dmabuf && dmasize); + + /* + * If we do fail to allocate enough for all the frags, + * deallocate whatever we did get and quit. + */ + if (!dmabuf) { + DPRINTK + ("ep93xx-audio: unable to allocate audio memory\n "); + audio_deallocate_buffers(state, stream); + return -ENOMEM; + } + + DPRINTK + ("EP93xx allocated %d bytes: dmabuf=0x%08x dmaphys=0x%08x\n", + dmasize, (int)dmabuf, (int)dmaphys); + + /* + * Success! Save the size of this chunk to use when we deallocate it. + */ + dma_buffer->master = dmasize; + memzero(dmabuf, dmasize); + } + + /* + * Save the start address of the dma_buffer fragment. + * We know the size of the fragment is fragsize. + */ + dma_buffer->start = dmabuf; + dma_buffer->dma_addr = dmaphys; + dma_buffer->stream = stream; + dma_buffer->size = 0; + dma_buffer->sent = 0; + dma_buffer->num = buf_num++; + + dma_buffer->owner = 0; + + /* + * Now if we only allocated the minimal one frag of space, the + * dmasize will be ==0 after this subtraction so it will allocate more + * for the next frag. Otherwise, the next time(s) thru this for loop + * will dole out frag sized pieces of this big master chunk. + */ + dmabuf += stream->fragsize; + dmaphys += stream->fragsize; + dmasize -= stream->fragsize; + } + + /* + * Initialize the stream. + */ + stream->buffered_bytes_to_play = 0; + stream->dma_buffer_index = 0; /* Init the current buffer index. */ + stream->dma_buffer = &stream->buffers[0]; /* Point dma_buffer to the current buffer struct. */ + stream->bytecount = 0; + stream->getptrCount = 0; + stream->fragcount = 0; + + DPRINTK("EP93xx audio_allocate_buffers -- exit SUCCESS\n"); + return 0; + +} + +/* + * audio_reset_buffers + * + * This function stops and flushes the dma, gets all buffers back + * from the DMA driver and resets them ready to be used again. + */ +static void audio_reset_buffers(struct audio_state_t *state, + struct audio_stream_t *stream) +{ + int frag, i; + + audio_dma_pause(state, stream); + stream->active = 0; + stream->stopped = 0; + + for (i = 0; i < stream->NumDmaChannels; i++) + DMA_FLUSH(stream->dmahandles[i]); + + if (stream->buffers) { + for (frag = 0; frag < stream->nbfrags; frag++) { + struct audio_buf_t *dma_buffer = &stream->buffers[frag]; + dma_buffer->size = 0; + dma_buffer->sent = 0; + dma_buffer->owner = 0; + } + } + + stream->buffered_bytes_to_play = 0; + stream->bytecount = 0; + stream->getptrCount = 0; + stream->fragcount = 0; +} + +/* + * DMA callback functions + */ +static void audio_dma_tx_callback + (ep93xx_dma_int_t DMAInt, ep93xx_dma_dev_t device, unsigned int user_data) { + unsigned int buf_id; + int handle, i; + + struct audio_state_t *state = (struct audio_state_t *)user_data; + struct audio_stream_t *stream = state->output_stream; + + /* DPRINTK( "audio_dma_tx_callback - %s\n", stream->devicename ); */ + + /* + * Get the DMA handle that corresponds to the dma channel + * that needs servicing. A multichannel audio stream will + * have a DMA handle for each stereo pair that it uses. + */ + for (i = 0; + (i < stream->NumDmaChannels) && (stream->dmachannel[i] != device); + i++) ; + handle = stream->dmahandles[i]; + + if (stream->mapped) { + /* + * If we are mapped, get one dma buffer back and recycle it. + */ + if (DMA_REMOVE_BUFFER(handle, &buf_id) >= 0) { + struct audio_buf_t *dma_buffer = + (struct audio_buf_t *)buf_id; + + /* DPRINTK( "audio_dma_tx_callback - got dma buffer index=%d\n", buf_id); */ + + /* Accounting */ + stream->buffered_bytes_to_play -= dma_buffer->size; + + /* bytecount and fragcount will overflow */ + stream->bytecount += dma_buffer->size; + if (stream->bytecount < 0) + stream->bytecount = 0; + + stream->fragcount++; + if (stream->fragcount < 0) + stream->fragcount = 0; + + dma_buffer->size = 0; + + /* Recycle dma buffer */ + dma_buffer->size = stream->fragsize; + + DMA_ADD_BUFFER(handle, /* dma instance */ + (unsigned int)dma_buffer->dma_addr, /* source */ + 0, /* dest */ + stream->fragsize, /* size */ + 0, /* is the last chunk? */ + (unsigned int)dma_buffer); /* buf id */ + + dma_buffer->sent = 1; + } + } else { + /* + * Get all buffers that are free'ed back and clear their semephores. + */ + while (DMA_REMOVE_BUFFER(handle, &buf_id) >= 0) { + struct audio_buf_t *dma_buffer = + (struct audio_buf_t *)buf_id; + + /* DPRINTK( "audio_dma_tx_callback - got dma buffer index=%d\n", buf_id); */ + + /* Accounting */ + stream->buffered_bytes_to_play -= dma_buffer->size; + + stream->bytecount += dma_buffer->size; + if (stream->bytecount < 0) + stream->bytecount = 0; + + stream->fragcount++; + if (stream->fragcount < 0) + stream->fragcount = 0; + + dma_buffer->size = 0; + dma_buffer->sent = 0; + + /* + * Release the semaphore on this dma_buffer. + * If write is waiting on this dma_buffer then it can go + * ahead and fill it and send it to the dma. + */ + dma_buffer->owner = 0; + } + } + + /* And any process polling on write. */ + wake_up(&stream->wq); +} + +static void audio_dma_rx_callback + (ep93xx_dma_int_t DMAInt, ep93xx_dma_dev_t device, unsigned int user_data) { + unsigned int buf_id; + int handle, i; + + struct audio_state_t *state = (struct audio_state_t *)user_data; + struct audio_stream_t *stream = state->input_stream; + + //DPRINTK("audio_dma_rx_callback\n"); + + /* + * Get the DMA handle that corresponds to the dma channel + * that needs servicing. A multichannel audio stream will + * have a DMA handle for each stereo pair that it uses. + */ + for (i = 0; + (i < stream->NumDmaChannels) && (stream->dmachannel[i] != device); + i++) ; + handle = stream->dmahandles[i]; + + /* + * Keep removing and recycling buffers as long as there are buffers + * to remove. + */ + while (!DMA_REMOVE_BUFFER(handle, &buf_id)) { + struct audio_buf_t *dma_buffer = (struct audio_buf_t *)buf_id; + + /* Accounting */ + stream->bytecount += stream->fragsize; + if (stream->bytecount < 0) + stream->bytecount = 0; + + stream->fragcount++; + if (stream->fragcount < 0) + stream->fragcount = 0; + + /* Recycle dma buffer */ + if (stream->mapped) { + DMA_ADD_BUFFER(handle, /* dma instance */ + (unsigned int)dma_buffer->dma_addr, /* source */ + 0, /* dest */ + stream->fragsize, /* size */ + 0, /* is the last chunk? */ + (unsigned int)dma_buffer); /* buf id */ + } else { + dma_buffer->size = stream->fragsize; + dma_buffer->owner = 0; + } + + /* And any process polling on write. */ + wake_up(&stream->wq); + } +} + +/* + * audio_sync + * + * Wait until the last byte written to this device has been played. + */ +static int audio_sync(struct file *file) +{ + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *stream = state->output_stream; + struct audio_buf_t *dma_buffer; + int buf_wait_index; + + DPRINTK("audio_sync - enter\n"); + + if (!(file->f_mode & FMODE_WRITE) || !stream->buffers || stream->mapped) { + DPRINTK("audio_sync - exit immediately.\n"); + return 0; + } + + /* + * Send current dma buffer if it contains data and hasn't been sent. + */ + dma_buffer = stream->dma_buffer; + + if (dma_buffer->size && !dma_buffer->sent) { + DPRINTK("audio_sync -- SENDING BUFFER index=%d size=%d\n", + stream->dma_buffer_index, dma_buffer->size); + + while (dma_buffer->owner == 1) + schedule(); + dma_buffer->owner = 1; + DMA_ADD_BUFFER(stream->dmahandles[0], /* dma instance */ + (unsigned int)dma_buffer->dma_addr, /* source */ + 0, /* dest */ + dma_buffer->size, /* size */ + 0, /* is the last chunk? */ + (unsigned int)dma_buffer); /* dma_buffer id */ + dma_buffer->sent = 1; + NEXT_BUF(stream, dma_buffer); + } + + /* + * Let's wait for the last dma buffer we sent i.e. the one before the + * current dma_buffer_index. When we acquire the semaphore, this means either: + * - DMA on the buffer completed or + * - the buffer was already free thus nothing else to sync. + */ + buf_wait_index = + ((stream->nbfrags + stream->dma_buffer_index - + 1) % stream->nbfrags); + dma_buffer = stream->buffers + buf_wait_index; + + DPRINTK("audio_sync - waiting on down_interruptible\n"); + while (dma_buffer->owner == 1) { + if (signal_pending(current)) + return -ERESTARTSYS; + schedule(); + } + + DPRINTK("audio_sync - EXIT\n"); + return 0; +} + +//static int iWriteCount = 0; + +/* + * Need to convert to 32 bit stereo format: + * 16 bit signed + * 16 bit unsigned + * 8 bit signed + * 8 bit unsigned + */ +static int audio_write + (struct file *file, + const char *user_buffer, size_t src_count, loff_t * ppos) { + const char *user_buffer_start = user_buffer; + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *stream = state->output_stream; + unsigned int dma_xfer_count, src_xfer_count, expanded_count; + int ret = 0; +// int i,j; + + /* DPRINTK_IOCTL( "EP93xx - audio_write: count=%d\n", src_count ); */ + + // KERNEL2.4 + /*if (ppos != &file->f_pos) + return -ESPIPE; */ + + if (stream->mapped) + return -ENXIO; + + if (!access_ok(VERIFY_READ, user_buffer, src_count)) { + DPRINTK("access_ok failed for audio_write!!!!\n"); + return -EFAULT; + } + + /* + * Allocate dma buffers if we haven't already done so. + */ + if (!stream->buffers && audio_allocate_buffers(state, stream)) + return -ENOMEM; + +// if( iWriteCount > 40 ) +// { +// for( i=0; i<4 ; i++ ) +// { +// for( j=0; j<8 ; j++ ) +// { +// printk("%02x ", user_buffer[(i*8)+j] ); +// } +// printk("\n"); +// } +// iWriteCount = 0; +// } +// iWriteCount++; + + /* + * Stay in this loop until we have copied all of the file + * into user memory. + */ + while (src_count > 0) { + struct audio_buf_t *dma_buffer = stream->dma_buffer; + + /* Wait for a dma buffer to become free */ + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + if (dma_buffer->owner != 0) + break; + } else { + while (dma_buffer->owner == 1) { + if (signal_pending(current)) + return -ERESTARTSYS; + schedule(); + } + } + + /* + * Feed the current dma buffer (stream->dma_buffer) + * This involves expanding sample size from the user_buffer + * to be 32 bit stereo for our dma. + */ + + /* + * How much space is left in the current dma buffer? + * + * dma_xfer_count is # of bytes placed into the dma buffer + * where each sample is 8 bytes (4 bytes left, 4 bytes right) + * because that's what the I2S is set up for - 32 bit samples. + */ + dma_xfer_count = stream->fragsize - dma_buffer->size; + + /* + * user_buffer is src_count (bytes) of whatever format. + * How big will src_count be when sample size is expanded + * to 32 bit samples for our hardware? + */ + expanded_count = src_count * stream->dma2usr_ratio; + + /* + * See if we can fit all the remaining user_buffer in + * the current dma buffer... + */ + if (dma_xfer_count > expanded_count) + dma_xfer_count = expanded_count; + + //DPRINTK( "EP93xx - audio_write: %d to dma_buffer # %d\n", dma_xfer_count, stream->dma_buffer_index ); + + src_xfer_count = copy_from_user_with_conversion(state, + dma_buffer-> + start + + dma_buffer-> + size, + user_buffer, + dma_xfer_count); + if (src_xfer_count <= 0) + return -EFAULT; + + /* + * Increment dma buffer pointer. + */ + dma_buffer->size += dma_xfer_count; + + /* + * Increment user_buffer pointer. + * Decrement the user_buffer size count. + */ + user_buffer += src_xfer_count; + src_count -= src_xfer_count; + + /* + * If we haven't already started the DMA start it. + * But don't start it if we are waiting on a trigger. + */ + if (!stream->active && !stream->stopped) { + stream->active = 1; + audio_dma_start(state, stream); + } + + /* + * Note that we've 'downed' the semiphore for this buffer. But the + * dma driver doesn't know about it until we've added it to the DMA + * driver's buffer queue. So let's do that now. + */ + dma_buffer->owner = 1; + DMA_ADD_BUFFER(stream->dmahandles[0], /* dma instance */ + (unsigned int)dma_buffer->dma_addr, /* source */ + 0, /* dest */ + dma_buffer->size, /* size */ + 0, /* is the last chunk? */ + (unsigned int)dma_buffer); /* buf id */ + + /* + * Note that we added a buffer to play for the benefit of calculating + * ODELAY. + */ + stream->buffered_bytes_to_play += dma_buffer->size; + + /* + * Indicate that the dma buffer has been sent. Not the same as the + * buffer's semiphore. + */ + dma_buffer->sent = 1; + + NEXT_BUF(stream, dma_buffer); + } + + /* + * Return the number of bytes transferred. + */ + if ((int)user_buffer - (int)user_buffer_start) + ret = (int)user_buffer - (int)user_buffer_start; + +/* DPRINTK( "EP93xx - audio_write: return=%d\n", ret );*/ + return ret; +} + +/* + * audio_dma_start + * + * Our Ac97 has a specific start order that it likes. Enable the + * Ac97 channel AFTER enabling DMA. Our I2S is not so picky. + */ +void audio_dma_start(struct audio_state_t *state, struct audio_stream_t *stream) +{ + DMA_START(stream->dmahandles[0], + stream->NumDmaChannels, stream->dmahandles); + + if (state->hw->hw_enable) + state->hw->hw_enable(stream); + +} + +/* + * audio_dma_pause + */ +void audio_dma_pause(struct audio_state_t *state, struct audio_stream_t *stream) +{ + DPRINTK("audio_dma_pause - enter\n"); + + DMA_PAUSE(stream->dmahandles[0], + stream->NumDmaChannels, stream->dmahandles); + + if (state->hw->hw_disable) + state->hw->hw_disable(stream); + + if (state->hw->hw_clear_fifo) + state->hw->hw_clear_fifo(stream); + + DPRINTK("audio_dma_pause - EXIT\n"); +} + +static void audio_prime_dma(struct audio_state_t *state, + struct audio_stream_t *stream) +{ + int i; + + DPRINTK("audio_prime_dma\n"); + + /* + * If we haven't already started the DMA start it. + * But don't start it if we are waiting on a trigger. + */ + if (!stream->active && !stream->stopped) { + stream->active = 1; + audio_dma_start(state, stream); + } + + for (i = 0; i < stream->nbfrags; i++) { + struct audio_buf_t *dma_buffer = stream->dma_buffer; + + dma_buffer->owner = 1; + DMA_ADD_BUFFER(stream->dmahandles[0], /* dma instance */ + (unsigned int)dma_buffer->dma_addr, /* source */ + 0, /* dest */ + stream->fragsize, /* size */ + 0, /* is the last chunk? */ + (unsigned int)dma_buffer); /* buf id */ + NEXT_BUF(stream, dma_buffer); + } +} + +/* + * audio_read + * + * Audio capture function. + */ +static int audio_read + (struct file *file, char *user_buffer, size_t count, loff_t * ppos) { + char *user_buffer_start = user_buffer; + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *stream = state->input_stream; + unsigned int user_buffer_xfer_count = 0, dma_buffer_xfer_count = 0; + int ret = 0; + + DPRINTK("EP93xx - audio_read: count=%d\n", count); + + // KERNEL2.4 + /*if (ppos != &file->f_pos) + return -ESPIPE; */ + + if (stream->mapped) + return -ENXIO; + + if (!access_ok(VERIFY_WRITE, user_buffer, count)) { + DPRINTK("access_ok failed for audio_read!!!!\n"); + return -EFAULT; + } + + if (!stream->active) { + if (!stream->buffers && audio_allocate_buffers(state, stream)) + return -ENOMEM; + + audio_prime_dma(state, stream); + } + + while (count > 0) { + /* + * Get the current buffer. + */ + struct audio_buf_t *dma_buffer = stream->dma_buffer; + + /* + * Wait for a dma buffer to become full + */ + if (file->f_flags & O_NONBLOCK) { + //DPRINTK("file->f_flags & O_NONBLOCK\n"); + ret = -EAGAIN; + if (dma_buffer->owner != 0) + break; + } else { + while (dma_buffer->owner == 1) { + if (signal_pending(current)) + return -ERESTARTSYS; + schedule(); + } + } + + /* + * If this is the first buffer captured, + * dump the first 8 samples of the dma buffer. + */ + if (stream->bFirstCaptureBuffer) { + dma_buffer->size -= 64; + stream->bFirstCaptureBuffer = 0; + } + + /* + * How much user buffer would a whole DMA buffer fill? + */ + user_buffer_xfer_count = + dma_buffer->size / stream->dma2usr_ratio; + + if (user_buffer_xfer_count > count) + user_buffer_xfer_count = count; + + dma_buffer_xfer_count = + user_buffer_xfer_count * stream->dma2usr_ratio; + + DPRINTK("dma_buffer: start=0x%08x fragsz=%d size=%d\n", + (int)dma_buffer->start, (int)stream->fragsize, + dma_buffer->size); + + DPRINTK + ("user_buffer=0x%08x from=0x%08x user_count=%d dma_count=%d\n", + (int)user_buffer, + (int)dma_buffer->start + stream->fragsize - + dma_buffer->size, user_buffer_xfer_count, + dma_buffer_xfer_count); + + if (copy_to_user_with_conversion(state, + user_buffer, + dma_buffer->start + + stream->fragsize - + dma_buffer->size, + user_buffer_xfer_count) <= 0) + return -EFAULT; + + dma_buffer->size -= dma_buffer_xfer_count; + + user_buffer += user_buffer_xfer_count; + count -= user_buffer_xfer_count; + + /* + * Grab data from the current dma buffer + */ + //DPRINTK("Read: read %d bytes from %d. dmabufsize=%d. count=%d\n", + // user_buffer_xfer_count, stream->dma_buffer_index, + // dma_buffer->size, count); + + /* + * If there's still data in this buffer to be read, release + * the semiphore and don't give it back yet. We may come back + * and read from it in a minute when the app calls for another read. + */ + if (dma_buffer->size > 0) + break; + + /* Make current dma buffer available for DMA again */ + dma_buffer->owner = 1; + DMA_ADD_BUFFER(stream->dmahandles[0], /* dma instance */ + (unsigned int)dma_buffer->dma_addr, /* source */ + 0, /* dest */ + stream->fragsize, /* size */ + 0, /* the last chunk? */ + (unsigned int)dma_buffer); /* buf id */ + + NEXT_BUF(stream, dma_buffer); + } + + if ((int)user_buffer - (int)user_buffer_start) + ret = (int)user_buffer - (int)user_buffer_start; + + //DPRINTK("EP93xx - audio_read: return=%d\n", ret); + + return ret; +} + +static int audio_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *stream = 0; + unsigned long size, vma_addr; + int i, ret; + + if (vma->vm_pgoff != 0) + return -EINVAL; + + if (vma->vm_flags & VM_WRITE) { + if (!state->wr_ref) + return -EINVAL; + + stream = state->output_stream; + } else if (vma->vm_flags & VM_READ) { + if (!state->rd_ref) + return -EINVAL; + + stream = state->input_stream; + } else { + return -EINVAL; + } + + if (stream->mapped) + return -EINVAL; + + size = vma->vm_end - vma->vm_start; + + if (size != stream->fragsize * stream->nbfrags) + return -EINVAL; + + if (!stream->buffers && audio_allocate_buffers(state, stream)) + return -ENOMEM; + + vma_addr = vma->vm_start; + + for (i = 0; i < stream->nbfrags; i++) { + struct audio_buf_t *dma_buffer = &stream->buffers[i]; + + if (!dma_buffer->master) { + continue; + } + // KERNEL2.4 + //ret = remap_page_range(vma_addr, dma_buffer->dma_addr, dma_buffer->master, vma->vm_page_prot); + ret = + remap_pfn_range(vma, vma_addr, dma_buffer->dma_addr, + dma_buffer->master, vma->vm_page_prot); + + if (ret) + return ret; + + vma_addr += dma_buffer->master; + } + + stream->mapped = 1; + + return 0; +} + +static unsigned int audio_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *is = state->input_stream; + struct audio_stream_t *os = state->output_stream; + unsigned int mask = 0; + int i; + + DPRINTK("EP93xx - audio_poll(): mode=%s%s\n", + (file->f_mode & FMODE_READ) ? "r" : "", + (file->f_mode & FMODE_WRITE) ? "w" : ""); + + if (file->f_mode & FMODE_READ) { + /* Start audio input if not already active */ + if (!is->active) { + if (!is->buffers && audio_allocate_buffers(state, is)) + return -ENOMEM; + + audio_prime_dma(state, is); + } + + poll_wait(file, &is->wq, wait); + } + + if (file->f_mode & FMODE_WRITE) { + if (!os->buffers && audio_allocate_buffers(state, os)) + return -ENOMEM; + + poll_wait(file, &os->wq, wait); + } + + if (file->f_mode & FMODE_READ) { + if (is->mapped) { + /* + * if the buffer is mapped assume we care that there are + * more bytes available than when we last asked using + * SNDCTL_DSP_GETxPTR + */ + if (is->bytecount != is->getptrCount) + mask |= POLLIN | POLLRDNORM; + } else { + for (i = 0; i < is->nbfrags; i++) { + if (is->buffers[i].owner != 0) { + mask |= POLLIN | POLLRDNORM; + break; + } + } + } + } + + if (file->f_mode & FMODE_WRITE) { + if (os->mapped) { + if (os->bytecount != os->getptrCount) + mask |= POLLOUT | POLLWRNORM; + } else { + for (i = 0; i < os->nbfrags; i++) { + if (os->buffers[i].owner != 0) { + mask |= POLLOUT | POLLWRNORM; + break; + } + } + } + } + + DPRINTK("EP93xx - audio_poll() returned mask of %s%s\n", + (mask & POLLIN) ? "r" : "", (mask & POLLOUT) ? "w" : ""); + + return mask; +} + +/* + * audio_set_fragments + * + * Used to process SNDCTL_DSP_SETFRAGMENT. + * + * Argument is 0xMMMMSSSS where: + * MMMM sets number of fragments. + * SSSS sets dma fragment (dma_buffer) size. size = 2^SSSS bytes + */ +static int audio_set_fragments(struct audio_state_t *state, + struct audio_stream_t *stream, int val) +{ + if (stream->active) + return -EBUSY; + + stream->requested_fragsize = 1 << (val & 0x000ffff); + stream->requested_nbfrags = (val >> 16) & 0x7FFF; + + return 0; +} + +static void print_audio_format(long format) +{ + switch (format) { + case AFMT_U8: + DPRINTK_IOCTL("AFMT_U8\n"); + break; + + case AFMT_S8: + DPRINTK_IOCTL("AFMT_S8\n"); + break; + + case AFMT_S32_BLOCKED: + DPRINTK_IOCTL("AFMT_S32_BLOCKED\n"); + break; + + case AFMT_S16_LE: + DPRINTK_IOCTL("AFMT_S16_LE\n"); + break; + + case AFMT_S16_BE: + DPRINTK_IOCTL("AFMT_S16_BE\n"); + break; + + case AFMT_U16_LE: + DPRINTK_IOCTL("AFMT_U16_LE\n"); + break; + + case AFMT_U16_BE: + default: + DPRINTK_IOCTL("AFMT_U16_BE\n"); + break; + } +} + +/* + * We convert to 24 bit samples that occupy 32 bits each. + * Formats we support: + * + * AFMT_U8 + * AFMT_S16_LE Little endian signed 16 + * AFMT_S8 + * AFMT_U16_LE Little endian U16 + * AFMT_S32_BLOCKED 32 bit little endian format, taken from the rme96xx driver. + * + */ +static long audio_set_format(struct audio_stream_t *stream, long val) +{ + DPRINTK_IOCTL("audio_set_format enter. Format requested (%d) ", + (int)val); + print_audio_format(val); + + switch (val) { + case AFMT_QUERY: + break; + + case AFMT_U8: + stream->audio_format = val; + stream->audio_stream_bitwidth = 8; + break; + + case AFMT_S8: + stream->audio_format = val; + stream->audio_stream_bitwidth = 8; + break; + + case AFMT_S32_BLOCKED: + stream->audio_format = val; + stream->audio_stream_bitwidth = 32; + break; + + case AFMT_S16_LE: + case AFMT_S16_BE: + stream->audio_format = AFMT_S16_LE; + stream->audio_stream_bitwidth = 16; + break; + + case AFMT_U16_LE: + case AFMT_U16_BE: + default: + stream->audio_format = AFMT_U16_LE; + stream->audio_stream_bitwidth = 16; + break; + } + + DPRINTK_IOCTL("audio_set_format EXIT format set to be (%d) ", + (int)stream->audio_format); + print_audio_format((long)stream->audio_format); + + return stream->audio_format; +} + +static __inline__ unsigned long copy_to_user_U16_LE_CM + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + unsigned short *user_ptr = (unsigned short *)to; /* 16 bit user buffer */ + short *dma_ptr = (short *)from; + short right, left; + + /* + * Compact mode - left is the lower 16 bits. right is the upper 16 bits. + */ + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + right = *dma_ptr++; + left = *dma_ptr++; + __put_user(left ^ 0x8000, user_ptr++); + __put_user(right ^ 0x8000, user_ptr++); + to_count -= 4; + } + } else { + while (to_count > 0) { + dma_ptr++; /* skip right channel sample */ + left = *dma_ptr++; + __put_user(left ^ 0x8000, user_ptr++); + to_count -= 2; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_U16_LE + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + short *user_ptr = (short *)to; /* 16 bit user buffer */ + int *dma_ptr = (int *)from; /* 32 bit dma buffer */ + + int shift = state->input_stream->hw_bit_width - 16; + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + __put_user(((short)((*dma_ptr++) >> shift)) ^ 0x8000, + user_ptr++); + __put_user(((short)((*dma_ptr++) >> shift)) ^ 0x8000, + user_ptr++); + to_count -= 4; + } + } else { + while (to_count > 0) { + __put_user(((short)((*dma_ptr++) >> shift)) ^ 0x8000, + user_ptr++); + dma_ptr++; /* skip right channel sample */ + to_count -= 2; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_S16_LE_CM + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + short *user_ptr = (short *)to; /* 16 bit user buffer */ + short *dma_ptr = (short *)from; + short left, right; + + /* + * Compact mode - left is the lower 16 bits. right is the upper 16 bits. + */ + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + right = *dma_ptr++; + left = *dma_ptr++; + __put_user(left, user_ptr++); + __put_user(right, user_ptr++); + to_count -= 4; + } + } else { + while (to_count > 0) { + dma_ptr++; /* skip right sample */ + left = *dma_ptr++; + __put_user(left, user_ptr++); + to_count -= 2; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_S16_LE + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + short *user_ptr = (short *)to; /* 16 bit user buffer */ + int *dma_ptr = (int *)from; /* 32 bit dma buffer */ + + int shift = state->input_stream->hw_bit_width - 16; + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + __put_user((short)((*dma_ptr++) >> shift), user_ptr++); + __put_user((short)((*dma_ptr++) >> shift), user_ptr++); + to_count -= 4; + } + } else { + while (to_count > 0) { + __put_user((short)((*dma_ptr++) >> shift), user_ptr++); + dma_ptr++; /* skip right channel sample */ + to_count -= 2; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_S8_CM + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + char *user_ptr = (char *)to; /* 8 bit user buffer */ + unsigned short *dma_ptr = (unsigned short *)from; /* 16 bit dma buffer */ + char right, left; + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + right = ((char)(*dma_ptr++ >> 8)); + left = ((char)(*dma_ptr++ >> 8)); + __put_user(left, user_ptr++); + __put_user(right, user_ptr++); + to_count -= 2; + } + } else { + while (to_count > 0) { + dma_ptr++; /* skip right channel sample */ + left = ((char)(*dma_ptr++ >> 8)); + __put_user(left, user_ptr++); + to_count--; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_S8 + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + char *user_ptr = (char *)to; /* 8 bit user buffer */ + int *dma_ptr = (int *)from; /* 32 bit dma buffer */ + + int shift = state->input_stream->hw_bit_width - 8; + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + __put_user((char)((*dma_ptr++) >> shift), user_ptr++); + __put_user((char)((*dma_ptr++) >> shift), user_ptr++); + to_count -= 2; + } + } else { + while (to_count > 0) { + __put_user((char)((*dma_ptr++) >> shift), user_ptr++); + dma_ptr++; /* skip right channel sample */ + to_count--; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_U8_CM + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + char *user_ptr = (char *)to; /* 8 bit user buffer */ + unsigned short *dma_ptr = (unsigned short *)from; /* 16 bit dma buffer */ + char right, left; + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + right = ((char)(*dma_ptr++ >> 8)) ^ 0x80; + left = ((char)(*dma_ptr++ >> 8)) ^ 0x80; + __put_user(left, user_ptr++); + __put_user(right, user_ptr++); + to_count -= 2; + } + } else { + while (to_count > 0) { + dma_ptr++; /* skip right channel sample */ + left = ((char)(*dma_ptr++ >> 8)) ^ 0x80; + __put_user(left, user_ptr++); + to_count--; + } + } + + return total_to_count; +} + +static __inline__ unsigned long copy_to_user_U8 + (struct audio_state_t *state, + const char *to, const char *from, unsigned long to_count) { + int total_to_count = to_count; + char *user_ptr = (char *)to; /* 8 bit user buffer */ + int *dma_ptr = (int *)from; /* 32 bit dma buffer */ + + int shift = state->input_stream->hw_bit_width - 8; + + if (state->input_stream->audio_num_channels != 1) { + while (to_count > 0) { + __put_user(((char)((*dma_ptr++) >> shift)) ^ 0x80, + user_ptr++); + __put_user(((char)((*dma_ptr++) >> shift)) ^ 0x80, + user_ptr++); + to_count -= 2; + } + } else { + while (to_count > 0) { + __put_user(((char)((*dma_ptr++) >> shift)) ^ 0x80, + user_ptr++); + dma_ptr++; /* skip right channel sample */ + to_count--; + } + } + + return total_to_count; +} + +/* + * Returns negative for error + * Returns # of bytes transferred out of the from buffer + * for success. + */ +static __inline__ int copy_to_user_with_conversion + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + int ret = 0; + + if (toCount == 0) { + DPRINTK("copy_to_user_with_conversion - nothing to copy!\n"); + } + + /* + * Compact Mode means that each 32 bit word has both the + * left and right sample in it. + */ + if (state->input_stream->bCompactMode) { + switch (state->input_stream->audio_format) { + case AFMT_U8: + ret = copy_to_user_U8_CM(state, to, from, toCount); + break; + + case AFMT_S16_LE: + ret = copy_to_user_S16_LE_CM(state, to, from, toCount); + break; + + case AFMT_S8: + ret = copy_to_user_S8_CM(state, to, from, toCount); + break; + + case AFMT_U16_LE: + ret = copy_to_user_U16_LE_CM(state, to, from, toCount); + break; + + case AFMT_S32_BLOCKED: + default: + break; + } + } else { + switch (state->input_stream->audio_format) { + case AFMT_U8: + ret = copy_to_user_U8(state, to, from, toCount); + break; + + case AFMT_S16_LE: + ret = copy_to_user_S16_LE(state, to, from, toCount); + break; + + case AFMT_S8: + ret = copy_to_user_S8(state, to, from, toCount); + break; + + case AFMT_U16_LE: + ret = copy_to_user_U16_LE(state, to, from, toCount); + break; + + case AFMT_S32_BLOCKED: + default: + __copy_to_user((char *)to, from, toCount); + ret = toCount; + break; + } + } + + return ret; +} + +static __inline__ int copy_from_user_U16_LE_CM + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + unsigned short *dma_buffer = (unsigned short *)to; + unsigned short *user_buffer = (unsigned short *)from; + unsigned short data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + + /* + * Compact mode - left is the lower 16 bits. right is the upper 16 bits. + */ + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = data ^ 0x8000; + __get_user(data, user_buffer++); + *dma_buffer++ = data ^ 0x8000; + toCount -= 4; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + data = data ^ 0x8000; + *dma_buffer++ = data; + *dma_buffer++ = data; + toCount -= 4; + } + } + + /* + * Each mono or stereo 16 bit sample going in results + * in one stereo 32 bit sample going out. So + * mono = (2 bytes in)/(4 bytes out) + * stereo = (4 bytes in)/(4 bytes out) + */ + if (mono) { + return toCount0 / 2; + } + + return toCount0; +} + +static __inline__ int copy_from_user_U16_LE + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + int *dma_buffer = (int *)to; + int val; + unsigned short *user_buffer = (unsigned short *)from; + unsigned short data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + int shift = state->output_stream->hw_bit_width - 16; + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = ((unsigned int)data ^ 0x8000) << shift; + __get_user(data, user_buffer++); + *dma_buffer++ = ((unsigned int)data ^ 0x8000) << shift; + toCount -= 8; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + val = ((unsigned int)data ^ 0x8000) << shift; + *dma_buffer++ = val; + *dma_buffer++ = val; + toCount -= 8; + } + } + + /* + * Each mono or stereo 16 bit sample going in results + * in a two 32 bit (left & right) samples going out. So + * mono = (2 bytes in)/(8 bytes out) + * stereo = (4 bytes in)/(8 bytes out) + */ + if (mono) + return toCount0 / 4; + + return toCount0 / 2; +} + +static __inline__ int copy_from_user_S16_LE_CM + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + short *dma_buffer = (short *)to; + unsigned short *user_buffer = (unsigned short *)from; + unsigned short data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + + /* + * Compact mode - left is the lower 16 bits. right is the upper 16 bits. + */ + + if (!mono) { + __copy_from_user((char *)to, from, toCount); + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = data; + *dma_buffer++ = data; + toCount -= 4; + } + } + + /* + * Each mono or stereo 16 bit sample going in results + * in one stereo 32 bit sample going out. So + * mono = (2 bytes in)/(4 bytes out) + * stereo = (4 bytes in)/(4 bytes out) + */ + if (mono) + return toCount0 / 2; + + return toCount0; +} + +static __inline__ int copy_from_user_S16_LE + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + int *dma_buffer = (int *)to; + int val; + unsigned short *user_buffer = (unsigned short *)from; + unsigned short data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + int shift = state->output_stream->hw_bit_width - 16; + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = (unsigned int)data << shift; + __get_user(data, user_buffer++); + *dma_buffer++ = (unsigned int)data << shift; + toCount -= 8; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + val = (unsigned int)data << shift; + *dma_buffer++ = val; + *dma_buffer++ = val; + toCount -= 8; + } + } + + /* + * Each mono or stereo 16 bit sample going in results + * in a two 32 bit samples (left & right) going out. So + * mono = (2 bytes in)/(8 bytes out) + * stereo = (4 bytes in)/(8 bytes out) + */ + if (mono) + return toCount0 / 4; + + return toCount0 / 2; +} + +static __inline__ int copy_from_user_S8_CM + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + short *dma_buffer = (short *)to; + short val; + unsigned char *user_buffer = (unsigned char *)from; + unsigned char data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + + /* + * Compact mode - left is the lower 16 bits. right is the upper 16 bits. + */ + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = (unsigned short)data << 8; + __get_user(data, user_buffer++); + *dma_buffer++ = (unsigned short)data << 8; + toCount -= 4; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + val = (unsigned short)data << 8; + *dma_buffer++ = val; + *dma_buffer++ = val; + toCount -= 4; + } + } + + /* + * Each mono or stereo 8 bit sample going in results + * in one stereo 32 bit sample going out. So + * mono = (1 byte in)/(4 bytes out) + * stereo = (2 bytes in)/(4 bytes out) + */ + if (mono) + return toCount0 / 4; + + return toCount0 / 2; +} + +static __inline__ int copy_from_user_S8 + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + int *dma_buffer = (int *)to; + int val; + unsigned char *user_buffer = (unsigned char *)from; + unsigned char data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + int shift = state->output_stream->hw_bit_width - 8; + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = (unsigned int)data << shift; + __get_user(data, user_buffer++); + *dma_buffer++ = (unsigned int)data << shift; + toCount -= 8; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + val = (unsigned int)data << shift; + *dma_buffer++ = val; + *dma_buffer++ = val; + toCount -= 8; + } + } + + /* + * Each mono or stereo 8 bit sample going in results + * in a two 32 bit samples (left & right) going out. So + * mono = (1 byte in)/(8 bytes out) + * stereo = (2 bytes in)/(8 bytes out) + */ + if (mono) + return toCount0 / 8; + + return toCount0 / 4; +} + +static __inline__ int copy_from_user_U8_CM + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + unsigned short *dma_buffer = (unsigned short *)to; + unsigned short val; + unsigned char *user_buffer = (unsigned char *)from; + unsigned char data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = ((unsigned short)data ^ 0x80) << 8; + __get_user(data, user_buffer++); + *dma_buffer++ = ((unsigned short)data ^ 0x80) << 8; + toCount -= 4; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + val = ((unsigned short)data ^ 0x80) << 8; + *dma_buffer++ = val; + *dma_buffer++ = val; + toCount -= 4; + } + } + + /* + * Each mono or stereo 8 bit sample going in results + * in one stereo 32 bit sample going out. So + * mono = (1 byte in)/(4 bytes out) + * stereo = (2 bytes in)/(4 bytes out) + */ + if (mono) + return toCount0 / 4; + + return toCount0 / 2; +} + +static __inline__ int copy_from_user_U8 + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + unsigned int *dma_buffer = (unsigned int *)to; + unsigned int val; + unsigned char *user_buffer = (unsigned char *)from; + unsigned char data; + + int toCount0 = toCount; + int mono = (state->output_stream->audio_num_channels == 1); + int shift = state->output_stream->hw_bit_width - 8; + + if (!mono) { + while (toCount > 0) { + __get_user(data, user_buffer++); + *dma_buffer++ = ((unsigned int)data ^ 0x80) << shift; + __get_user(data, user_buffer++); + *dma_buffer++ = ((unsigned int)data ^ 0x80) << shift; + toCount -= 8; + } + } else { + while (toCount > 0) { + __get_user(data, user_buffer++); + val = ((unsigned int)data ^ 0x80) << shift; + *dma_buffer++ = val; + *dma_buffer++ = val; + toCount -= 8; + } + } + + /* + * Each mono or stereo 8 bit sample going in results + * in a two 32 bit samples (left & right) going out. So + * mono = (1 byte in)/(8 bytes out) + * stereo = (2 bytes in)/(8 bytes out) + */ + if (mono) + return toCount0 / 8; + + return toCount0 / 4; +} + +/* + * Returns negative for error + * Returns # of bytes transferred out of the from buffer + * for success. + */ +static __inline__ int copy_from_user_with_conversion + (struct audio_state_t *state, + const char *to, const char *from, int toCount) { + int ret = 0; + + if (toCount == 0) { + DPRINTK("copy_from_user_with_conversion - nothing to copy!\n"); + } + + /* + * Compact Mode means that each 32 bit word has both the + * left and right sample in it. + */ + if (state->output_stream->bCompactMode) { + switch (state->output_stream->audio_format) { + case AFMT_U8: + ret = copy_from_user_U8_CM(state, to, from, toCount); + break; + + case AFMT_S16_LE: + ret = + copy_from_user_S16_LE_CM(state, to, from, toCount); + break; + + case AFMT_S8: + ret = copy_from_user_S8_CM(state, to, from, toCount); + break; + + case AFMT_U16_LE: + ret = + copy_from_user_U16_LE_CM(state, to, from, toCount); + break; + + case AFMT_S32_BLOCKED: + default: + break; + } + } else { + switch (state->output_stream->audio_format) { + case AFMT_U8: + ret = copy_from_user_U8(state, to, from, toCount); + break; + + case AFMT_S16_LE: + ret = copy_from_user_S16_LE(state, to, from, toCount); + break; + + case AFMT_S8: + ret = copy_from_user_S8(state, to, from, toCount); + break; + + case AFMT_U16_LE: + ret = copy_from_user_U16_LE(state, to, from, toCount); + break; + + case AFMT_S32_BLOCKED: + default: + __copy_from_user((char *)to, from, toCount); + ret = toCount; + break; + } + } + + return ret; +} + +static int audio_ioctl(struct inode *inode, struct file *file, + uint cmd, ulong arg) +{ + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + struct audio_stream_t *os = state->output_stream; + struct audio_stream_t *is = state->input_stream; + long val = 0; + + switch (cmd) { + case SNDCTL_DSP_STEREO: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_STEREO\n"); + if (get_user(val, (int *)arg) || (val > 1) || (val < 0)) + return -EFAULT; + + if (file->f_mode & FMODE_WRITE) { + if (os->audio_num_channels != (val + 1)) { + os->audio_num_channels = val + 1; + calculate_dma2usr_ratio_etc(os); + } + } + + if (file->f_mode & FMODE_READ) { + if (is->audio_num_channels != (val + 1)) { + is->audio_num_channels = val + 1; + calculate_dma2usr_ratio_etc(is); + } + } + + return put_user(val, (long *)arg); + + case SNDCTL_DSP_CHANNELS: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_CHANNELS\n"); + if (get_user(val, (int *)arg) || (val > 2) || (val < 0)) + return -EFAULT; + + // Calling with value of 0 is a query. + if (val == 0) { + if (file->f_mode & FMODE_WRITE) + val = os->audio_num_channels; + else + val = is->audio_num_channels; + } else { + if (file->f_mode & FMODE_WRITE) { + if (os->audio_num_channels != val) { + os->audio_num_channels = val; + calculate_dma2usr_ratio_etc(os); + } + } + if (file->f_mode & FMODE_READ) { + if (is->audio_num_channels != val) { + is->audio_num_channels = val; + calculate_dma2usr_ratio_etc(is); + } + } + } + + return put_user(val, (long *)arg); + + case SOUND_PCM_READ_CHANNELS: + DPRINTK_IOCTL("audio_ioctl - SOUND_PCM_READ_CHANNELS\n"); + if (file->f_mode & FMODE_WRITE) + val = os->audio_num_channels; + else + val = is->audio_num_channels; + return put_user(val, (long *)arg); + + case SNDCTL_DSP_SETFMT: + { + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETFMT\n"); + + if (get_user(val, (int *)arg)) + return -EFAULT; + + if (val != AFMT_QUERY) { + if ((file->f_mode & FMODE_WRITE) + && (val != os->audio_format)) { + audio_set_format(os, val); + calculate_dma2usr_ratio_etc(os); + if (state->hw->set_hw_serial_format) + state->hw-> + set_hw_serial_format(os, + val); + } + if ((file->f_mode & FMODE_READ) + && (val != is->audio_format)) { + audio_set_format(is, val); + calculate_dma2usr_ratio_etc(is); + if (state->hw->set_hw_serial_format) + state->hw-> + set_hw_serial_format(is, + val); + } + } + + if (file->f_mode & FMODE_WRITE) + return put_user(os->audio_format, (long *)arg); + return put_user(is->audio_format, (long *)arg); + } + + case SNDCTL_DSP_GETFMTS: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETFMTS\n"); + return put_user((AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE), + (long *)arg); + + case OSS_GETVERSION: + DPRINTK_IOCTL("audio_ioctl - OSS_GETVERSION\n"); + return put_user(SOUND_VERSION, (int *)arg); + + case SNDCTL_DSP_GETBLKSIZE: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETBLKSIZE\n"); + if (file->f_mode & FMODE_WRITE) + return put_user(os->fragsize, (int *)arg); + return put_user(is->fragsize, (int *)arg); + + case SNDCTL_DSP_GETCAPS: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETCAPS\n"); + val = DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP; + if (is && os) + val |= DSP_CAP_DUPLEX; + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETFRAGMENT: + { + int ret; + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETFRAGMENT\n"); + if (get_user(val, (long *)arg)) + return -EFAULT; + + if (file->f_mode & FMODE_READ) { + ret = audio_set_fragments(state, is, val); + if (ret < 0) + return ret; + } + + if (file->f_mode & FMODE_WRITE) { + ret = audio_set_fragments(state, os, val); + if (ret < 0) + return ret; + } + + return 0; + } + + case SNDCTL_DSP_SYNC: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SYNC\n"); + return audio_sync(file); + + case SNDCTL_DSP_SETDUPLEX: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETDUPLEX\n"); + return 0; + + case SNDCTL_DSP_POST: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_POST\n"); + return 0; + + case SNDCTL_DSP_GETTRIGGER: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETTRIGGER\n"); + val = 0; + + if (file->f_mode & FMODE_READ && is->active && !is->stopped) + val |= PCM_ENABLE_INPUT; + + if (file->f_mode & FMODE_WRITE && os->active && !os->stopped) + val |= PCM_ENABLE_OUTPUT; + + return put_user(val, (int *)arg); + + case SNDCTL_DSP_SETTRIGGER: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETTRIGGER\n"); + if (get_user(val, (int *)arg)) + return -EFAULT; + + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!is->active) { + if (!is->buffers + && audio_allocate_buffers(state, + is)) + return -ENOMEM; + audio_prime_dma(state, is); + } + + if (is->stopped) { + is->stopped = 0; + os->active = 1; + audio_dma_start(state, is); + } + } else { + audio_dma_pause(state, is); + is->stopped = 1; + is->active = 0; + } + } + + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!os->active) { + if (!os->buffers + && audio_allocate_buffers(state, + os)) + return -ENOMEM; + + if (os->mapped) + audio_prime_dma(state, os); + } + + if (os->stopped) { + os->stopped = 0; + os->active = 1; + audio_dma_start(state, os); + } + } else { + audio_dma_pause(state, os); + os->stopped = 1; + os->active = 0; + } + } + return 0; + + case SNDCTL_DSP_GETOPTR: + case SNDCTL_DSP_GETIPTR: + { + count_info inf = { 0, }; + struct audio_stream_t *stream = + (cmd == SNDCTL_DSP_GETOPTR) ? os : is; + int bytecount, fragcount, buf_num = 0; + unsigned int current_frac, buf_id; + // KERNEL2.4 SNIP + unsigned long flags; + unsigned int total = 0; + // KERNEL2.4 SNAP + + DPRINTK_IOCTL + ("audio_ioctl - called SNDCTL_DSP_GETOPTR.\n"); + + if ((stream == is && !(file->f_mode & FMODE_READ)) || + (stream == os && !(file->f_mode & FMODE_WRITE))) + return -EINVAL; + + if (!stream->active) + return copy_to_user((void *)arg, &inf, + sizeof(inf)); + + // KERNEL2.4 + //save_flags_cli(flags); + local_irq_save(flags); + + // KERNEL2.4 + //DMA_GET_POSITION( stream->dmahandles[0], &buf_id, 0, + // ¤t_frac ); + DMA_GET_POSITION(stream->dmahandles[0], &buf_id, &total, + ¤t_frac); + + /* + * Out of a set of nbfrags buffers, which one is the current one? + */ + if (buf_id) + buf_num = ((struct audio_buf_t *)buf_id)->num; + + /* + * The ep93xx-audio ISRs keep track of bytecount and fragcount. + * This bytecount isn't cleared except when the driver is opened + * or when it overflows. + */ + bytecount = stream->bytecount; + + /* so poll can tell if it changes */ + stream->getptrCount = stream->bytecount; + + /* + * Return the number of fragment transitions counted in our dma ISR + * since the previous call to this ioctl, then clear that counter. + */ + fragcount = stream->fragcount; + stream->fragcount = 0; + + // KERNEL2.4 + //restore_flags(flags); + local_irq_restore(flags); + + /* + * When reporting position to user app, scale byte counts and the + * ptr to reflect the difference in sample size between dma samples + * and user samples. But don't scale the # of fragments. + */ + inf.blocks = fragcount; + inf.bytes = + (bytecount + current_frac) / stream->dma2usr_ratio; + inf.ptr = + ((buf_num * stream->fragsize) + + current_frac) / stream->dma2usr_ratio; + + return copy_to_user((void *)arg, &inf, sizeof(inf)); + } + + case SNDCTL_DSP_GETODELAY: + { + int buffered_bytes_left, count; + //unsigned int current_frac; + // KERNEL2.4 SNIP + unsigned int current_frac = 0; + unsigned long flags; + unsigned int total = 0, buf_id = 0; + // KERNEL2.4SNAP + + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + + DPRINTK_IOCTL + ("audio_ioctl - called SNDCTL_DSP_GETODELAY.\n"); + + // KERNEL2.4 + //save_flags_cli(flags); + local_irq_save(flags); + + // KERNEL2.4 + //DMA_GET_POSITION( os->dmahandles[0], 0, 0, ¤t_frac ); + DMA_GET_POSITION(os->dmahandles[0], &buf_id, &total, + ¤t_frac); + + buffered_bytes_left = os->buffered_bytes_to_play; + + // KERNEL2.4 + //restore_flags(flags); + local_irq_restore(flags); + + count = + (buffered_bytes_left - + current_frac) / os->dma2usr_ratio; + + return put_user(count, (int *)arg); + } + + case SNDCTL_DSP_GETOSPACE: + { + /* + * It looks like this code is assuming that nobody + * is writing the device while calling this ioctl + * which may be a reasonable assumption. I hope. + * Maybe. + */ + audio_buf_info inf = { 0, }; + int i; + + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETOSPACE\n"); + + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!os->buffers && audio_allocate_buffers(state, os)) + return -ENOMEM; + + for (i = 0; i < os->nbfrags; i++) { + /* + * If the semaphore is 1, the buffer is available. + */ + if (os->buffers[i].owner != 0) { + if (os->buffers[i].size == 0) + inf.fragments++; + + inf.bytes += + os->fragsize - os->buffers[i].size; + } + } + + inf.fragsize = os->fragsize / os->dma2usr_ratio; + inf.fragstotal = os->nbfrags; + inf.bytes = inf.bytes / os->dma2usr_ratio; + + return copy_to_user((void *)arg, &inf, sizeof(inf)); + } + + case SNDCTL_DSP_GETISPACE: + { + audio_buf_info inf = { 0, }; + int i; + + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETISPACE\n"); + + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!is->buffers && audio_allocate_buffers(state, is)) + return -ENOMEM; + + for (i = 0; i < is->nbfrags; i++) { + if (is->buffers[i].owner != 0) { + if (is->buffers[i].size == is->fragsize) + inf.fragments++; + + inf.bytes += is->buffers[i].size; + } + } + + inf.fragsize = is->fragsize / is->dma2usr_ratio; + inf.fragstotal = is->nbfrags; + inf.bytes = inf.bytes / is->dma2usr_ratio; + + return copy_to_user((void *)arg, &inf, sizeof(inf)); + } + + case SNDCTL_DSP_NONBLOCK: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_NONBLOCK\n"); + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_RESET: + DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_RESET\n"); + if (file->f_mode & FMODE_READ) + audio_reset_buffers(state, is); + if (file->f_mode & FMODE_WRITE) + audio_reset_buffers(state, os); + return 0; + + default: + /* + * Let the client of this module handle the + * non generic ioctls + */ + return state->hw->client_ioctl(inode, file, cmd, arg); + } + + return 0; +} + +static int audio_release(struct inode *inode, struct file *file) +{ + struct audio_state_t *state = + (struct audio_state_t *)file->private_data; + int i; + + DPRINTK("EP93xx - audio_release -- enter. Write=%d Read=%d\n", + ((file->f_mode & FMODE_WRITE) != 0), + ((file->f_mode & FMODE_READ) != 0)); + + down(&state->sem); + + if (file->f_mode & FMODE_READ) { + audio_deallocate_buffers(state, state->input_stream); + + for (i = 0; i < state->input_stream->NumDmaChannels; i++) + DMA_FREE(state->input_stream->dmahandles[i]); + + state->rd_ref = 0; + } + + if (file->f_mode & FMODE_WRITE) { + /* + * Wait for all our buffers to play. + */ + audio_sync(file); + + /* + * audio_deallocate_buffers will pause and flush the dma + * then deallocate the buffers. + */ + audio_deallocate_buffers(state, state->output_stream); + for (i = 0; i < state->output_stream->NumDmaChannels; i++) + DMA_FREE(state->output_stream->dmahandles[i]); + + state->wr_ref = 0; + } + + up(&state->sem); + + DPRINTK("EP93xx - audio_release -- EXIT\n"); + + return 0; +} + +/* + * ep93xx_clear_stream_struct + * + * Initialize stuff or at least clear it to zero for a stream structure. + */ +static void ep93xx_clear_stream_struct(struct audio_stream_t *stream) +{ + + stream->dmahandles[0] = 0; /* handles for dma driver instances */ + stream->dmahandles[1] = 0; /* handles for dma driver instances */ + stream->dmahandles[2] = 0; /* handles for dma driver instances */ + stream->NumDmaChannels = 0; /* 1, 2, or 3 DMA channels */ + stream->TX_dma_ch_bitfield = 0; /* which dma channels used for strm */ + stream->RX_dma_ch_bitfield = 0; /* which dma channels used for strm */ + stream->buffers = 0; /* array of audio buffer structures */ + stream->dma_buffer = 0; /* current buffer used by read/write */ + stream->dma_buffer_index = 0; /* index for the pointer above... */ + stream->fragsize = AUDIO_FRAGSIZE_DEFAULT; /* fragment i.e. buffer size */ + stream->nbfrags = AUDIO_NBFRAGS_DEFAULT; /* nbr of fragments i.e. buffers */ + stream->requested_fragsize = 0; /* This is ignored if 0 */ + stream->requested_nbfrags = 0; /* This is ignored if 0 */ + stream->bytecount = 0; /* nbr of processed bytes */ + stream->getptrCount = 0; /* value of bytecount last time */ + /* anyone asked via GETxPTR */ + stream->fragcount = 0; /* nbr of fragment transitions */ + stream->mapped = 0; /* mmap()'ed buffers */ + stream->active = 0; /* actually in progress */ + stream->stopped = 0; /* might be active but stopped */ + stream->bFirstCaptureBuffer = 1; /* flag meaning there is junk in rx fifo */ + stream->buffered_bytes_to_play = 0; + + calculate_dma2usr_ratio_etc(stream); +} + +/* + * ep93xx_audio_attach + * + * Initialize the state structure for read or write. Allocate dma channels. + * Currently each s is a stereo s (one dma channel). + * + */ +int ep93xx_audio_attach + (struct inode *inode, struct file *file, struct audio_state_t *state) { + int err, i; + struct audio_stream_t *os = state->output_stream; + struct audio_stream_t *is = state->input_stream; + + DPRINTK("ep93xx_audio_attach -- enter. Write=%d Read=%d\n", + ((file->f_mode & FMODE_WRITE) != 0), + ((file->f_mode & FMODE_READ) != 0)); + + down(&state->sem); + + /* access control */ + if (((file->f_mode & FMODE_WRITE) && !os) || + ((file->f_mode & FMODE_READ) && !is)) { + up(&state->sem); + return -ENODEV; + } + + if (((file->f_mode & FMODE_WRITE) && state->wr_ref) || + ((file->f_mode & FMODE_READ) && state->rd_ref)) { + up(&state->sem); + return -EBUSY; + } + + /* + * Request DMA channels + */ + if (file->f_mode & FMODE_WRITE) { + DPRINTK("ep93xx_audio_attach -- FMODE_WRITE\n"); + + state->wr_ref = 1; + + ep93xx_clear_stream_struct(os); + + err = DMA_REQUEST(&os->dmahandles[0], + os->devicename, os->dmachannel[0]); + if (err) { + up(&state->sem); + DPRINTK + ("ep93xx_audio_attach -- EXIT ERROR dma request failed\n"); + return err; + } + + err = DMA_CONFIG(os->dmahandles[0], + IGNORE_CHANNEL_ERROR, + 0, audio_dma_tx_callback, (unsigned int)state); + if (err) { + DMA_FREE(os->dmahandles[0]); + up(&state->sem); + DPRINTK + ("ep93xx_audio_attach -- EXIT ERROR dma config failed\n"); + return err; + } + + /* + * Assuming each audio stream is mono or stereo. + */ + os->NumDmaChannels = 1; + + /* + * Automatically set up the bit field of dma channels used for + * this stream. + */ + for (i = 0; (i < state->hw->MaxTxDmaChannels); i++) { + if (os->dmachannel[i] == state->hw->txdmachannels[0]) + os->TX_dma_ch_bitfield |= 1; + + if (os->dmachannel[i] == state->hw->txdmachannels[1]) + os->TX_dma_ch_bitfield |= 2; + + if (os->dmachannel[i] == state->hw->txdmachannels[2]) + os->TX_dma_ch_bitfield |= 4; + } + + DPRINTK("DMA Tx channel bitfield = %x\n", + os->TX_dma_ch_bitfield); + + if (state->hw->hw_clear_fifo) + state->hw->hw_clear_fifo(os); + + init_waitqueue_head(&os->wq); + } + + if (file->f_mode & FMODE_READ) { + state->rd_ref = 1; + + ep93xx_clear_stream_struct(is); + + err = DMA_REQUEST(&is->dmahandles[0], + is->devicename, is->dmachannel[0]); + if (err) { + up(&state->sem); + DPRINTK + ("ep93xx_audio_attach -- EXIT ERROR dma request failed\n"); + return err; + } + + err = DMA_CONFIG(is->dmahandles[0], + IGNORE_CHANNEL_ERROR, + 0, audio_dma_rx_callback, (unsigned int)state); + if (err) { + DMA_FREE(is->dmahandles[0]); + up(&state->sem); + DPRINTK + ("ep93xx_audio_attach -- EXIT ERROR dma config failed\n"); + return err; + } + + is->NumDmaChannels = 1; + + /* + * Automatically set up the bit field of dma channels used for + * this stream. + */ + for (i = 0; (i < state->hw->MaxRxDmaChannels); i++) { + if (is->dmachannel[i] == state->hw->rxdmachannels[0]) + is->RX_dma_ch_bitfield |= 1; + + if (is->dmachannel[i] == state->hw->rxdmachannels[1]) + is->RX_dma_ch_bitfield |= 2; + + if (is->dmachannel[i] == state->hw->rxdmachannels[2]) + is->RX_dma_ch_bitfield |= 4; + } + + DPRINTK("DMA Rx channel bitfield = %x\n", + is->RX_dma_ch_bitfield); + + init_waitqueue_head(&is->wq); + } + + /* + * Fill out the rest of the file_operations struct. + */ + file->private_data = state; + file->f_op->release = audio_release; + file->f_op->write = audio_write; + file->f_op->read = audio_read; + file->f_op->mmap = audio_mmap; + file->f_op->poll = audio_poll; + file->f_op->ioctl = audio_ioctl; + file->f_op->llseek = no_llseek; + + up(&state->sem); + + DPRINTK("ep93xx_audio_attach -- EXIT\n"); + + return 0; +} + +EXPORT_SYMBOL(ep93xx_audio_attach); + +MODULE_DESCRIPTION("Common audio handling for the Cirrus EP93xx processor"); +MODULE_LICENSE("GPL"); diff --git a/sound/oss/ep93xx-audio.h b/sound/oss/ep93xx-audio.h new file mode 100644 index 0000000..04a0581 --- /dev/null +++ b/sound/oss/ep93xx-audio.h @@ -0,0 +1,149 @@ +/* + * ep93xx-audio.h + * + * Common audio handling for the Cirrus Logic EP93xx + * + * Copyright (c) 2003 Cirrus Logic Corp. + * Copyright (c) 2000 Nicolas Pitre + * + * Taken from sa1100-audio.h + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ + +/* + * Getting this from the rme96xx driver. Has same numerical value + * as AC3. Hmmmm. + */ +#ifndef AFMT_S32_BLOCKED +#define AFMT_S32_BLOCKED 0x0000400 +#endif + +#define EP93XX_DEFAULT_NUM_CHANNELS 2 +#define EP93XX_DEFAULT_FORMAT AFMT_S16_LE +#define EP93XX_DEFAULT_BIT_WIDTH 16 + +/* + * Buffer Management + */ + +struct audio_buf_t { + + int size; /* buffer size */ + int sent; /* indicates that dma has the dma_buffer */ + char *start; /* points to actual buffer */ + dma_addr_t dma_addr; /* physical buffer address */ + int owner; + struct semaphore sem; /* down before touching the buffer */ + int master; /* owner for buffer allocation, */ + /* contains size when true */ + int num; /* which out of nbfrags buffers is this? */ + struct audio_stream_t *stream; /* owning stream */ + +}; + +#define MAX_DEVICE_NAME 20 + +struct audio_stream_t { + + /* dma stuff */ + int dmahandles[3]; /* handles for dma driver instances */ + char devicename[MAX_DEVICE_NAME]; /* string - name of device */ + int NumDmaChannels; /* 1, 2, or 3 DMA channels */ + ep93xx_dma_dev_t dmachannel[3]; /* dma channel numbers */ + + struct audio_buf_t *buffers; /* array of audio buffer structures */ + struct audio_buf_t *dma_buffer; /* current buffer used by read/write */ + u_int dma_buffer_index; /* index for the pointer above... */ + + u_int fragsize; /* fragment i.e. buffer size */ + u_int nbfrags; /* nbr of fragments i.e. buffers */ + u_int requested_fragsize; + u_int requested_nbfrags; + + int bytecount; /* nbr of processed bytes */ + int getptrCount; /* value of bytecount last time */ + /* anyone asked via GETxPTR */ + int fragcount; /* nbr of fragment transitions */ + wait_queue_head_t wq; /* for poll */ + int mapped:1; /* mmap()'ed buffers */ + int active:1; /* actually in progress */ + int stopped:1; /* might be active but stopped */ + u_int TX_dma_ch_bitfield; /* bit0 = txdma1, bit1= txdma2, etc */ + u_int RX_dma_ch_bitfield; /* bit0 = rxdma1, bit1= rxdma2, etc */ + int bFirstCaptureBuffer; /* flag meaning there is junk in rx fifo */ + + /* + * Data about the file format that we are configured to play. + */ + long audio_num_channels; /* Range: 1 to 6 */ + long audio_format; + long audio_stream_bitwidth; /* Range: 8, 16, 24, 32 */ + + long sample_rate; /* Fs in Hz. */ + + /* + * Data about how the audio controller and codec are set up. + */ + int hw_bit_width; /* width of dac or adc */ + int bCompactMode; /* set if 32bits == a stereo sample */ + + /* + * dma2usr_ratio = dma sample size (8 or 4 bytes) / usr sample size (8,4,2,1) + */ + int dma2usr_ratio; + + /* + * This provides a way of determining audio playback position that will not + * overflow. This is (size of buffers written) - (buffers we've gotten back) + */ + int buffered_bytes_to_play; + +}; + +/* + * No matter how many streams are going, we are using one hardware device. + * This struct describes that hardware. + */ +struct audio_hw_t { + + ep93xx_dma_dev_t txdmachannels[3]; /* all dma channels available for */ + ep93xx_dma_dev_t rxdmachannels[3]; /* this audio ctrlr */ + + int MaxTxDmaChannels; /* number of tx and rx channels */ + int MaxRxDmaChannels; /* number of tx and rx channels */ + + /* + * Pointers to init, shutdown, and ioctl functions. + */ + void (*hw_enable) (struct audio_stream_t * stream); + void (*hw_disable) (struct audio_stream_t * stream); + void (*hw_clear_fifo) (struct audio_stream_t * stream); + int (*client_ioctl) (struct inode *, struct file *, uint, ulong); + void (*set_hw_serial_format) (struct audio_stream_t *, long); + + unsigned int modcnt; /* count the # of volume writes */ + +}; + +/* + * State structure for one instance + */ +struct audio_state_t { + struct audio_stream_t *output_stream; + struct audio_stream_t *input_stream; + + struct audio_hw_t *hw; /* hw info */ + + int rd_ref:1; /* open reference for recording */ + int wr_ref:1; /* open reference for playback */ + + struct semaphore sem; /* to protect against races in attach() */ + +}; + +/* + * Functions exported by this module + */ +extern int ep93xx_audio_attach(struct inode *inode, struct file *file, + struct audio_state_t *state);