diff options
Diffstat (limited to 'recipes/linux/linux-2.6.31/ben-nanonote/files.patch')
-rw-r--r-- | recipes/linux/linux-2.6.31/ben-nanonote/files.patch | 20506 |
1 files changed, 0 insertions, 20506 deletions
diff --git a/recipes/linux/linux-2.6.31/ben-nanonote/files.patch b/recipes/linux/linux-2.6.31/ben-nanonote/files.patch deleted file mode 100644 index 3d274cbe25..0000000000 --- a/recipes/linux/linux-2.6.31/ben-nanonote/files.patch +++ /dev/null @@ -1,20506 +0,0 @@ -diff -ruN linux-2.6.31-vanilla/arch/mips/boot/compressed/Makefile linux-2.6.31/arch/mips/boot/compressed/Makefile ---- linux-2.6.31-vanilla/arch/mips/boot/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/compressed/Makefile 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,42 @@ -+#
-+# linux/arch/mips/boot/compressed/Makefile
-+#
-+# create a compressed zImage from the original vmlinux
-+#
-+
-+targets := zImage vmlinuz vmlinux.bin.gz head.o misc.o piggy.o dummy.o
-+
-+OBJS := $(obj)/head.o $(obj)/misc.o
-+
-+LD_ARGS := -T $(obj)/ld.script -Ttext 0x80600000 -Bstatic
-+OBJCOPY_ARGS := -O elf32-tradlittlemips
-+
-+ENTRY := $(obj)/../tools/entry
-+FILESIZE := $(obj)/../tools/filesize
-+
-+drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options
-+strip-flags = $(addprefix --remove-section=,$(drop-sections))
-+
-+
-+$(obj)/vmlinux.bin.gz: vmlinux
-+ rm -f $(obj)/vmlinux.bin.gz
-+ $(OBJCOPY) -O binary $(strip-flags) vmlinux $(obj)/vmlinux.bin
-+ gzip -v9f $(obj)/vmlinux.bin
-+
-+$(obj)/head.o: $(obj)/head.S $(obj)/vmlinux.bin.gz vmlinux
-+ $(CC) $(KBUILD_AFLAGS) \
-+ -DIMAGESIZE=$(shell sh $(FILESIZE) $(obj)/vmlinux.bin.gz) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) vmlinux ) \
-+ -DLOADADDR=$(loadaddr) \
-+ -c -o $(obj)/head.o $<
-+
-+$(obj)/vmlinuz: $(OBJS) $(obj)/ld.script $(obj)/vmlinux.bin.gz $(obj)/dummy.o
-+ $(OBJCOPY) \
-+ --add-section=.image=$(obj)/vmlinux.bin.gz \
-+ --set-section-flags=.image=contents,alloc,load,readonly,data \
-+ $(obj)/dummy.o $(obj)/piggy.o
-+ $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/piggy.o
-+ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap
-+
-+zImage: $(obj)/vmlinuz
-+ $(OBJCOPY) -O binary $(obj)/vmlinuz $(obj)/zImage
-diff -ruN linux-2.6.31-vanilla/arch/mips/boot/compressed/dummy.c linux-2.6.31/arch/mips/boot/compressed/dummy.c ---- linux-2.6.31-vanilla/arch/mips/boot/compressed/dummy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/compressed/dummy.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,4 @@ -+int main(void) -+{ -+ return 0; -+} -diff -ruN linux-2.6.31-vanilla/arch/mips/boot/compressed/head.S linux-2.6.31/arch/mips/boot/compressed/head.S ---- linux-2.6.31-vanilla/arch/mips/boot/compressed/head.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/compressed/head.S 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,85 @@ -+/* -+ * linux/arch/mips/boot/compressed/head.S -+ * -+ * Copyright (C) 2005-2008 Ingenic Semiconductor Inc. -+ */ -+ -+#include <asm/asm.h> -+#include <asm/cacheops.h> -+#include <asm/cachectl.h> -+#include <asm/regdef.h> -+ -+#define IndexInvalidate_I 0x00 -+#define IndexWriteBack_D 0x01 -+ -+ .set noreorder -+ LEAF(startup) -+startup: -+ move s0, a0 /* Save the boot loader transfered args */ -+ move s1, a1 -+ move s2, a2 -+ move s3, a3 -+ -+ la a0, _edata -+ la a1, _end -+1: sw zero, 0(a0) /* Clear BSS section */ -+ bne a1, a0, 1b -+ addu a0, 4 -+ -+ la sp, (.stack + 8192) -+ -+ la a0, __image_begin -+ la a1, IMAGESIZE -+ la a2, LOADADDR -+ la ra, 1f -+ la k0, decompress_kernel -+ jr k0 -+ nop -+1: -+ -+ move a0, s0 -+ move a1, s1 -+ move a2, s2 -+ move a3, s3 -+ li k0, KERNEL_ENTRY -+ jr k0 -+ nop -+2: -+ b 32 -+ END(startup) -+ -+ -+ LEAF(flushcaches) -+ la t0, 1f -+ la t1, 0xa0000000 -+ or t0, t0, t1 -+ jr t0 -+ nop -+1: -+ li k0, 0x80000000 # start address -+ li k1, 0x80004000 # end address (16KB I-Cache) -+ subu k1, 128 -+ -+2: -+ .set mips3 -+ cache IndexWriteBack_D, 0(k0) -+ cache IndexWriteBack_D, 32(k0) -+ cache IndexWriteBack_D, 64(k0) -+ cache IndexWriteBack_D, 96(k0) -+ cache IndexInvalidate_I, 0(k0) -+ cache IndexInvalidate_I, 32(k0) -+ cache IndexInvalidate_I, 64(k0) -+ cache IndexInvalidate_I, 96(k0) -+ .set mips0 -+ -+ bne k0, k1, 2b -+ addu k0, k0, 128 -+ la t0, 3f -+ jr t0 -+ nop -+3: -+ jr ra -+ nop -+ END(flushcaches) -+ -+ .comm .stack,4096*2,4 -diff -ruN linux-2.6.31-vanilla/arch/mips/boot/compressed/ld.script linux-2.6.31/arch/mips/boot/compressed/ld.script ---- linux-2.6.31-vanilla/arch/mips/boot/compressed/ld.script 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/compressed/ld.script 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,151 @@ -+OUTPUT_ARCH(mips) -+ENTRY(startup) -+SECTIONS -+{ -+ /* Read-only sections, merged into text segment: */ -+ -+ .init : { *(.init) } =0 -+ .text : -+ { -+ _ftext = . ; -+ *(.text) -+ *(.rodata) -+ *(.rodata1) -+ /* .gnu.warning sections are handled specially by elf32.em. */ -+ *(.gnu.warning) -+ } =0 -+ .kstrtab : { *(.kstrtab) } -+ -+ . = ALIGN(16); /* Exception table */ -+ __start___ex_table = .; -+ __ex_table : { *(__ex_table) } -+ __stop___ex_table = .; -+ -+ __start___dbe_table = .; /* Exception table for data bus errors */ -+ __dbe_table : { *(__dbe_table) } -+ __stop___dbe_table = .; -+ -+ __start___ksymtab = .; /* Kernel symbol table */ -+ __ksymtab : { *(__ksymtab) } -+ __stop___ksymtab = .; -+ -+ _etext = .; -+ -+ . = ALIGN(8192); -+ .data.init_task : { *(.data.init_task) } -+ -+ /* Startup code */ -+ . = ALIGN(4096); -+ __init_begin = .; -+ .text.init : { *(.text.init) } -+ .data.init : { *(.data.init) } -+ . = ALIGN(16); -+ __setup_start = .; -+ .setup.init : { *(.setup.init) } -+ __setup_end = .; -+ __initcall_start = .; -+ .initcall.init : { *(.initcall.init) } -+ __initcall_end = .; -+ . = ALIGN(4096); /* Align double page for init_task_union */ -+ __init_end = .; -+ -+ . = ALIGN(4096); -+ .data.page_aligned : { *(.data.idt) } -+ -+ . = ALIGN(32); -+ .data.cacheline_aligned : { *(.data.cacheline_aligned) } -+ -+ .fini : { *(.fini) } =0 -+ .reginfo : { *(.reginfo) } -+ /* Adjust the address for the data segment. We want to adjust up to -+ the same address within the page on the next page up. It would -+ be more correct to do this: -+ . = .; -+ The current expression does not correctly handle the case of a -+ text segment ending precisely at the end of a page; it causes the -+ data segment to skip a page. The above expression does not have -+ this problem, but it will currently (2/95) cause BFD to allocate -+ a single segment, combining both text and data, for this case. -+ This will prevent the text segment from being shared among -+ multiple executions of the program; I think that is more -+ important than losing a page of the virtual address space (note -+ that no actual memory is lost; the page which is skipped can not -+ be referenced). */ -+ . = .; -+ .data : -+ { -+ _fdata = . ; -+ *(.data) -+ -+ /* Put the compressed image here, so bss is on the end. */ -+ __image_begin = .; -+ *(.image) -+ __image_end = .; -+ /* Align the initial ramdisk image (INITRD) on page boundaries. */ -+ . = ALIGN(4096); -+ __ramdisk_begin = .; -+ *(.initrd) -+ __ramdisk_end = .; -+ . = ALIGN(4096); -+ -+ CONSTRUCTORS -+ } -+ .data1 : { *(.data1) } -+ _gp = . + 0x8000; -+ .lit8 : { *(.lit8) } -+ .lit4 : { *(.lit4) } -+ .ctors : { *(.ctors) } -+ .dtors : { *(.dtors) } -+ .got : { *(.got.plt) *(.got) } -+ .dynamic : { *(.dynamic) } -+ /* We want the small data sections together, so single-instruction offsets -+ can access them all, and initialized data all before uninitialized, so -+ we can shorten the on-disk segment size. */ -+ .sdata : { *(.sdata) } -+ . = ALIGN(4); -+ _edata = .; -+ PROVIDE (edata = .); -+ -+ __bss_start = .; -+ _fbss = .; -+ .sbss : { *(.sbss) *(.scommon) } -+ .bss : -+ { -+ *(.dynbss) -+ *(.bss) -+ *(COMMON) -+ . = ALIGN(4); -+ _end = . ; -+ PROVIDE (end = .); -+ } -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : -+ { -+ *(.text.exit) -+ *(.data.exit) -+ *(.exitcall.exit) -+ } -+ -+ /* This is the MIPS specific mdebug section. */ -+ .mdebug : { *(.mdebug) } -+ /* These are needed for ELF backends which have not yet been -+ converted to the new style linker. */ -+ .stab 0 : { *(.stab) } -+ .stabstr 0 : { *(.stabstr) } -+ /* DWARF debug sections. -+ Symbols in the .debug DWARF section are relative to the beginning of the -+ section so we begin .debug at 0. It's not clear yet what needs to happen -+ for the others. */ -+ .debug 0 : { *(.debug) } -+ .debug_srcinfo 0 : { *(.debug_srcinfo) } -+ .debug_aranges 0 : { *(.debug_aranges) } -+ .debug_pubnames 0 : { *(.debug_pubnames) } -+ .debug_sfnames 0 : { *(.debug_sfnames) } -+ .line 0 : { *(.line) } -+ /* These must appear regardless of . */ -+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } -+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } -+ .comment : { *(.comment) } -+ .note : { *(.note) } -+} -diff -ruN linux-2.6.31-vanilla/arch/mips/boot/compressed/misc.c linux-2.6.31/arch/mips/boot/compressed/misc.c ---- linux-2.6.31-vanilla/arch/mips/boot/compressed/misc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/compressed/misc.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,242 @@ -+/* -+ * linux/arch/mips/boot/compressed/misc.c -+ * -+ * This is a collection of several routines from gzip-1.0.3 -+ * adapted for Linux. -+ * -+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 -+ * -+ * Adapted for JZSOC by Peter Wei, 2008 -+ * -+ */ -+ -+#define size_t int -+#define NULL 0 -+ -+/* -+ * gzip declarations -+ */ -+ -+#define OF(args) args -+#define STATIC static -+ -+#undef memset -+#undef memcpy -+#define memzero(s, n) memset ((s), 0, (n)) -+ -+typedef unsigned char uch; -+typedef unsigned short ush; -+typedef unsigned long ulg; -+ -+#define WSIZE 0x8000 /* Window size must be at least 32k, */ -+ /* and a power of two */ -+ -+static uch *inbuf; /* input buffer */ -+static uch window[WSIZE]; /* Sliding window buffer */ -+ -+static unsigned insize = 0; /* valid bytes in inbuf */ -+static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ -+static unsigned outcnt = 0; /* bytes in output buffer */ -+ -+/* gzip flag byte */ -+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ -+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -+#define COMMENT 0x10 /* bit 4 set: file comment present */ -+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -+#define RESERVED 0xC0 /* bit 6,7: reserved */ -+ -+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) -+ -+/* Diagnostic functions */ -+#ifdef DEBUG -+# define Assert(cond,msg) {if(!(cond)) error(msg);} -+# define Trace(x) fprintf x -+# define Tracev(x) {if (verbose) fprintf x ;} -+# define Tracevv(x) {if (verbose>1) fprintf x ;} -+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -+#else -+# define Assert(cond,msg) -+# define Trace(x) -+# define Tracev(x) -+# define Tracevv(x) -+# define Tracec(c,x) -+# define Tracecv(c,x) -+#endif -+ -+static int fill_inbuf(void); -+static void flush_window(void); -+static void error(char *m); -+static void gzip_mark(void **); -+static void gzip_release(void **); -+ -+void* memset(void* s, int c, size_t n); -+void* memcpy(void* __dest, __const void* __src, size_t __n); -+ -+extern void flushcaches(void); /* defined in head.S */ -+ -+char *input_data; -+int input_len; -+ -+static long bytes_out = 0; -+static uch *output_data; -+static unsigned long output_ptr = 0; -+ -+ -+static void *malloc(int size); -+static void free(void *where); -+static void error(char *m); -+static void gzip_mark(void **); -+static void gzip_release(void **); -+ -+static void puts(const char *str) -+{ -+} -+ -+extern unsigned char _end[]; -+static unsigned long free_mem_ptr; -+static unsigned long free_mem_end_ptr; -+ -+#define HEAP_SIZE 0x10000 -+ -+#include "../../../../lib/inflate.c" -+ -+static void *malloc(int size) -+{ -+ void *p; -+ -+ if (size <0) error("Malloc error\n"); -+ if (free_mem_ptr == 0) error("Memory error\n"); -+ -+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ -+ -+ p = (void *)free_mem_ptr; -+ free_mem_ptr += size; -+ -+ if (free_mem_ptr >= free_mem_end_ptr) -+ error("\nOut of memory\n"); -+ -+ return p; -+} -+ -+static void free(void *where) -+{ /* Don't care */ -+} -+ -+static void gzip_mark(void **ptr) -+{ -+ *ptr = (void *) free_mem_ptr; -+} -+ -+static void gzip_release(void **ptr) -+{ -+ free_mem_ptr = (long) *ptr; -+} -+ -+void* memset(void* s, int c, size_t n) -+{ -+ int i; -+ char *ss = (char*)s; -+ -+ for (i=0;i<n;i++) ss[i] = c; -+ return s; -+} -+ -+void* memcpy(void* __dest, __const void* __src, size_t __n) -+{ -+ int i = 0; -+ unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; -+ -+ for (i = __n >> 3; i > 0; i--) { -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ } -+ -+ if (__n & 1 << 2) { -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ *d++ = *s++; -+ } -+ -+ if (__n & 1 << 1) { -+ *d++ = *s++; -+ *d++ = *s++; -+ } -+ -+ if (__n & 1) -+ *d++ = *s++; -+ -+ return __dest; -+} -+ -+/* =========================================================================== -+ * Fill the input buffer. This is called only when the buffer is empty -+ * and at least one byte is really needed. -+ */ -+static int fill_inbuf(void) -+{ -+ if (insize != 0) { -+ error("ran out of input data\n"); -+ } -+ -+ inbuf = input_data; -+ insize = input_len; -+ inptr = 1; -+ return inbuf[0]; -+} -+ -+/* =========================================================================== -+ * Write the output window window[0..outcnt-1] and update crc and bytes_out. -+ * (Used for the decompressed data only.) -+ */ -+static void flush_window(void) -+{ -+ ulg c = crc; /* temporary variable */ -+ unsigned n; -+ uch *in, *out, ch; -+ -+ in = window; -+ out = &output_data[output_ptr]; -+ for (n = 0; n < outcnt; n++) { -+ ch = *out++ = *in++; -+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); -+ } -+ crc = c; -+ bytes_out += (ulg)outcnt; -+ output_ptr += (ulg)outcnt; -+ outcnt = 0; -+} -+ -+static void error(char *x) -+{ -+ puts("\n\n"); -+ puts(x); -+ puts("\n\n -- System halted"); -+ -+ while(1); /* Halt */ -+} -+ -+void decompress_kernel(unsigned int imageaddr, unsigned int imagesize, unsigned int loadaddr) -+{ -+ input_data = (char *)imageaddr; -+ input_len = imagesize; -+ output_ptr = 0; -+ output_data = (uch *)loadaddr; -+ free_mem_ptr = (unsigned long)_end; -+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; -+ -+ makecrc(); -+ puts("Uncompressing Linux..."); -+ gunzip(); -+ flushcaches(); -+ puts("Ok, booting the kernel."); -+} -diff -ruN linux-2.6.31-vanilla/arch/mips/boot/tools/entry linux-2.6.31/arch/mips/boot/tools/entry ---- linux-2.6.31-vanilla/arch/mips/boot/tools/entry 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/tools/entry 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,12 @@ -+#!/bin/sh -+ -+# grab the kernel_entry address from the vmlinux elf image -+entry=`$1 $2 | grep kernel_entry` -+ -+fs=`echo $entry | grep ffffffff` # check toolchain output -+ -+if [ -n "$fs" ]; then -+ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'` -+else -+ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'` -+fi -diff -ruN linux-2.6.31-vanilla/arch/mips/boot/tools/filesize linux-2.6.31/arch/mips/boot/tools/filesize ---- linux-2.6.31-vanilla/arch/mips/boot/tools/filesize 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/boot/tools/filesize 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,7 @@ -+#!/bin/sh -+HOSTNAME=`uname` -+if [ "$HOSTNAME" = "Linux" ]; then -+echo `ls -l $1 | awk '{print $5}'` -+else -+echo `ls -l $1 | awk '{print $6}'` -+fi -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/jzsoc.h linux-2.6.31/arch/mips/include/asm/jzsoc.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/jzsoc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/jzsoc.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,26 @@ -+/* -+ * linux/include/asm-mips/jzsoc.h -+ * -+ * Ingenic's JZXXXX SoC common include. -+ * -+ * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc. -+ * -+ * Author: <jlwei@ingenic.cn> -+ * -+ * 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 __ASM_JZSOC_H__ -+#define __ASM_JZSOC_H__ -+ -+/* -+ * SoC include -+ */ -+ -+#ifdef CONFIG_SOC_JZ4740 -+#include <asm/mach-jz4740/jz4740.h> -+#endif -+ -+#endif /* __ASM_JZSOC_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-dipper.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-dipper.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-dipper.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-dipper.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,69 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/board-dipper.h -+ * -+ * JZ4725-based (16bit) Dipper board ver 1.x definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4725_DIPPER_H__ -+#define __ASM_JZ4725_DIPPER_H__ -+ -+/*====================================================================== -+ * Frequencies of on-board oscillators -+ */ -+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */ -+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */ -+ -+/*====================================================================== -+ * GPIO JZ4725 -+ */ -+#define GPIO_SD_VCC_EN_N 85 /* GPC21 */ -+#define GPIO_SD_CD_N 91 /* GPC27 */ -+#define GPIO_SD_WP 112 /* GPD16 */ -+#define GPIO_USB_DETE 124 /* GPD28 */ -+#define GPIO_DC_DETE_N 103 /* GPD7 */ -+#define GPIO_CHARG_STAT_N 86 /* GPC22 */ -+#define GPIO_DISP_OFF_N 118 /* GPD22 */ -+ -+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE -+ -+/*====================================================================== -+ * MMC/SD -+ */ -+ -+#define MSC_WP_PIN GPIO_SD_WP -+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N -+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N) -+ -+#define __msc_init_io() \ -+do { \ -+ __gpio_as_output(GPIO_SD_VCC_EN_N); \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+} while (0) -+ -+#define __msc_enable_power() \ -+do { \ -+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_disable_power() \ -+do { \ -+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_card_detected(s) \ -+({ \ -+ int detected = 1; \ -+ if (__gpio_get_pin(GPIO_SD_CD_N)) \ -+ detected = 0; \ -+ detected; \ -+}) -+ -+#endif /* __ASM_JZ4740_DIPPER_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-leo.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-leo.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-leo.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-leo.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,56 @@ -+#ifndef __ASM_JZ4740_LEO_H__ -+#define __ASM_JZ4740_LEO_H__ -+ -+/* -+ * Define your board specific codes here !!! -+ */ -+ -+/*====================================================================== -+ * Frequencies of on-board oscillators -+ */ -+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */ -+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */ -+ -+ -+/*====================================================================== -+ * GPIO -+ */ -+#define GPIO_DISP_OFF_N 100 -+#define GPIO_SD_VCC_EN_N 119 -+#define GPIO_SD_CD_N 120 -+#define GPIO_SD_WP 111 -+ -+/*====================================================================== -+ * MMC/SD -+ */ -+ -+#define MSC_WP_PIN GPIO_SD_WP -+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N -+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N) -+ -+#define __msc_init_io() \ -+do { \ -+ __gpio_as_output(GPIO_SD_VCC_EN_N); \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+} while (0) -+ -+#define __msc_enable_power() \ -+do { \ -+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_disable_power() \ -+do { \ -+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_card_detected(s) \ -+({ \ -+ int detected = 1; \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+ if (__gpio_get_pin(GPIO_SD_CD_N)) \ -+ detected = 0; \ -+ detected; \ -+}) -+ -+#endif /* __ASM_JZ4740_BOARD_LEO_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-lyra.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-lyra.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-lyra.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-lyra.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,70 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/board-lyra.h -+ * -+ * JZ4740-based LYRA board ver 2.x definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4740_LYRA_H__ -+#define __ASM_JZ4740_LYRA_H__ -+ -+/*====================================================================== -+ * Frequencies of on-board oscillators -+ */ -+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */ -+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */ -+ -+ -+/*====================================================================== -+ * GPIO -+ */ -+#define GPIO_SD_VCC_EN_N 113 /* GPD17 */ -+#define GPIO_SD_CD_N 110 /* GPD14 */ -+#define GPIO_SD_WP 112 /* GPD16 */ -+#define GPIO_USB_DETE 102 /* GPD6 */ -+#define GPIO_DC_DETE_N 103 /* GPD7 */ -+#define GPIO_CHARG_STAT_N 111 /* GPD15 */ -+#define GPIO_DISP_OFF_N 118 /* GPD22 */ -+#define GPIO_LED_EN 124 /* GPD28 */ -+ -+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE -+/*====================================================================== -+ * MMC/SD -+ */ -+ -+#define MSC_WP_PIN GPIO_SD_WP -+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N -+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N) -+ -+#define __msc_init_io() \ -+do { \ -+ __gpio_as_output(GPIO_SD_VCC_EN_N); \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+} while (0) -+ -+#define __msc_enable_power() \ -+do { \ -+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_disable_power() \ -+do { \ -+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_card_detected(s) \ -+({ \ -+ int detected = 1; \ -+ if (!(__gpio_get_pin(GPIO_SD_CD_N))) \ -+ detected = 0; \ -+ detected; \ -+}) -+ -+#endif /* __ASM_JZ4740_LYRA_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-pavo.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-pavo.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-pavo.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-pavo.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,70 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/board-pavo.h -+ * -+ * JZ4730-based PAVO board ver 2.x definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4740_PAVO_H__ -+#define __ASM_JZ4740_PAVO_H__ -+ -+/*====================================================================== -+ * Frequencies of on-board oscillators -+ */ -+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */ -+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */ -+ -+ -+/*====================================================================== -+ * GPIO -+ */ -+#define GPIO_SD_VCC_EN_N 113 /* GPD17 */ -+#define GPIO_SD_CD_N 110 /* GPD14 */ -+#define GPIO_SD_WP 112 /* GPD16 */ -+#define GPIO_USB_DETE 102 /* GPD6 */ -+#define GPIO_DC_DETE_N 103 /* GPD7 */ -+#define GPIO_CHARG_STAT_N 111 /* GPD15 */ -+#define GPIO_DISP_OFF_N 118 /* GPD22 */ -+#define GPIO_LED_EN 124 /* GPD28 */ -+ -+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE -+/*====================================================================== -+ * MMC/SD -+ */ -+ -+#define MSC_WP_PIN GPIO_SD_WP -+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N -+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N) -+ -+#define __msc_init_io() \ -+do { \ -+ __gpio_as_output(GPIO_SD_VCC_EN_N); \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+} while (0) -+ -+#define __msc_enable_power() \ -+do { \ -+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_disable_power() \ -+do { \ -+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_card_detected(s) \ -+({ \ -+ int detected = 1; \ -+ if (__gpio_get_pin(GPIO_SD_CD_N)) \ -+ detected = 0; \ -+ detected; \ -+}) -+ -+#endif /* __ASM_JZ4740_PAVO_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-qi_lb60.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-qi_lb60.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-qi_lb60.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-qi_lb60.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (c) 2009 Qi Hardware Inc., -+ * Author: Xiangfu Liu <xiangfu@qi-hardware.com> -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __ASM_JZ4740_QI_LB60_H__ -+#define __ASM_JZ4740_QI_LB60_H__ -+ -+#include <linux/gpio.h> -+/* -+ * Frequencies of on-board oscillators -+ */ -+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */ -+#define JZ_EXTAL_RTC 32768 /* RTC extal freq: 32.768 KHz */ -+ -+/* -+ * GPIO -+ */ -+#define GPIO_DC_DETE_N JZ_GPIO_PORTC(26) -+#define GPIO_CHARG_STAT_N JZ_GPIO_PORTC(27) -+#define GPIO_LED_EN JZ_GPIO_PORTC(28) -+#define GPIO_LCD_CS JZ_GPIO_PORTC(21) -+#define GPIO_DISP_OFF_N JZ_GPIO_PORTD(21) -+#define GPIO_PWM JZ_GPIO_PORTD(27) -+#define GPIO_WAKEUP_N JZ_GPIO_PORTD(29) -+ -+#define GPIO_AMP_EN JZ_GPIO_PORTD(4) -+ -+#define GPIO_SD_CD_N JZ_GPIO_PORTD(0) -+#define GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(2) -+#define GPIO_SD_WP JZ_GPIO_PORTD(16) -+ -+#define GPIO_USB_DETE JZ_GPIO_PORTD(28) -+#define GPIO_BUZZ_PWM JZ_GPIO_PORTD(27) -+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE -+ -+#define GPIO_AUDIO_POP JZ_GPIO_PORTB(29) -+#define GPIO_COB_TEST JZ_GPIO_PORTB(30) -+ -+#define GPIO_KEYOUT_BASE JZ_GPIO_PORTC(10) -+#define GPIO_KEYIN_BASE JZ_GPIO_PORTD(18) -+#define GPIO_KEYIN_8 JZ_GPIO_PORTD(26) -+ -+/* -+ * MMC/SD -+ */ -+#define MSC_WP_PIN GPIO_SD_WP -+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N -+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N) -+ -+#define __msc_init_io() \ -+do { \ -+ __gpio_as_output(GPIO_SD_VCC_EN_N); \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+} while (0) -+ -+#define __msc_enable_power() \ -+do { \ -+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_disable_power() \ -+do { \ -+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_card_detected(s) \ -+({ \ -+ int detected = 1; \ -+ if (!__gpio_get_pin(GPIO_SD_CD_N)) \ -+ detected = 0; \ -+ detected; \ -+}) -+ -+#endif /* __ASM_JZ4740_QI_LB60_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-virgo.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-virgo.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/board-virgo.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/board-virgo.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,67 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/board-virgo.h -+ * -+ * JZ4720-based VIRGO board ver 1.x definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4720_VIRGO_H__ -+#define __ASM_JZ4720_VIRGO_H__ -+ -+/*====================================================================== -+ * Frequencies of on-board oscillators -+ */ -+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */ -+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */ -+ -+/*====================================================================== -+ * GPIO VIRGO(JZ4720) -+ */ -+#define GPIO_SD_VCC_EN_N 115 /* GPD19 */ -+#define GPIO_SD_CD_N 116 /* GPD20 */ -+#define GPIO_USB_DETE 114 /* GPD18 */ -+#define GPIO_DC_DETE_N 120 /* GPD24 */ -+#define GPIO_DISP_OFF_N 118 /* GPD22 */ -+#define GPIO_LED_EN 117 /* GPD21 */ -+ -+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE -+ -+/*====================================================================== -+ * MMC/SD -+ */ -+ -+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N -+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N) -+ -+#define __msc_init_io() \ -+do { \ -+ __gpio_as_output(GPIO_SD_VCC_EN_N); \ -+ __gpio_as_input(GPIO_SD_CD_N); \ -+} while (0) -+ -+#define __msc_enable_power() \ -+do { \ -+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_disable_power() \ -+do { \ -+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ -+} while (0) -+ -+#define __msc_card_detected(s) \ -+({ \ -+ int detected = 1; \ -+ if (__gpio_get_pin(GPIO_SD_CD_N)) \ -+ detected = 0; \ -+ detected; \ -+}) -+ -+#endif /* __ASM_JZ4720_VIRGO_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/clock.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/clock.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/clock.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/clock.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,175 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/clock.h -+ * -+ * JZ4740 clocks definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4740_CLOCK_H__ -+#define __ASM_JZ4740_CLOCK_H__ -+ -+#ifndef JZ_EXTAL -+//#define JZ_EXTAL 3686400 /* 3.6864 MHz */ -+#define JZ_EXTAL 12000000 /* 3.6864 MHz */ -+#endif -+#ifndef JZ_EXTAL2 -+#define JZ_EXTAL2 32768 /* 32.768 KHz */ -+#endif -+ -+/* -+ * JZ4740 clocks structure -+ */ -+typedef struct { -+ unsigned int cclk; /* CPU clock */ -+ unsigned int hclk; /* System bus clock */ -+ unsigned int pclk; /* Peripheral bus clock */ -+ unsigned int mclk; /* Flash/SRAM/SDRAM clock */ -+ unsigned int lcdclk; /* LCDC module clock */ -+ unsigned int pixclk; /* LCD pixel clock */ -+ unsigned int i2sclk; /* AIC module clock */ -+ unsigned int usbclk; /* USB module clock */ -+ unsigned int mscclk; /* MSC module clock */ -+ unsigned int extalclk; /* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */ -+ unsigned int rtcclk; /* RTC clock for CPM,INTC,RTC,TCU,WDT */ -+} jz_clocks_t; -+ -+extern jz_clocks_t jz_clocks; -+ -+ -+/* PLL output frequency */ -+static __inline__ unsigned int __cpm_get_pllout(void) -+{ -+ unsigned long m, n, no, pllout; -+ unsigned long cppcr = REG_CPM_CPPCR; -+ unsigned long od[4] = {1, 2, 2, 4}; -+ if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) { -+ m = __cpm_get_pllm() + 2; -+ n = __cpm_get_plln() + 2; -+ no = od[__cpm_get_pllod()]; -+ pllout = ((JZ_EXTAL) / (n * no)) * m; -+ } else -+ pllout = JZ_EXTAL; -+ return pllout; -+} -+ -+/* PLL output frequency for MSC/I2S/LCD/USB */ -+static __inline__ unsigned int __cpm_get_pllout2(void) -+{ -+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) -+ return __cpm_get_pllout(); -+ else -+ return __cpm_get_pllout()/2; -+} -+ -+/* CPU core clock */ -+static __inline__ unsigned int __cpm_get_cclk(void) -+{ -+ int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ -+ return __cpm_get_pllout() / div[__cpm_get_cdiv()]; -+} -+ -+/* AHB system bus clock */ -+static __inline__ unsigned int __cpm_get_hclk(void) -+{ -+ int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ -+ return __cpm_get_pllout() / div[__cpm_get_hdiv()]; -+} -+ -+/* Memory bus clock */ -+static __inline__ unsigned int __cpm_get_mclk(void) -+{ -+ int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ -+ return __cpm_get_pllout() / div[__cpm_get_mdiv()]; -+} -+ -+/* APB peripheral bus clock */ -+static __inline__ unsigned int __cpm_get_pclk(void) -+{ -+ int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ -+ return __cpm_get_pllout() / div[__cpm_get_pdiv()]; -+} -+ -+/* LCDC module clock */ -+static __inline__ unsigned int __cpm_get_lcdclk(void) -+{ -+ return __cpm_get_pllout2() / (__cpm_get_ldiv() + 1); -+} -+ -+/* LCD pixel clock */ -+static __inline__ unsigned int __cpm_get_pixclk(void) -+{ -+ return __cpm_get_pllout2() / (__cpm_get_pixdiv() + 1); -+} -+ -+/* I2S clock */ -+static __inline__ unsigned int __cpm_get_i2sclk(void) -+{ -+ if (REG_CPM_CPCCR & CPM_CPCCR_I2CS) { -+ return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1); -+ } -+ else { -+ return JZ_EXTAL; -+ } -+} -+ -+/* USB clock */ -+static __inline__ unsigned int __cpm_get_usbclk(void) -+{ -+ if (REG_CPM_CPCCR & CPM_CPCCR_UCS) { -+ return __cpm_get_pllout2() / (__cpm_get_udiv() + 1); -+ } -+ else { -+ return JZ_EXTAL; -+ } -+} -+ -+/* MSC clock */ -+static __inline__ unsigned int __cpm_get_mscclk(void) -+{ -+ return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1); -+} -+ -+/* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */ -+static __inline__ unsigned int __cpm_get_extalclk(void) -+{ -+ return JZ_EXTAL; -+} -+ -+/* RTC clock for CPM,INTC,RTC,TCU,WDT */ -+static __inline__ unsigned int __cpm_get_rtcclk(void) -+{ -+ return JZ_EXTAL2; -+} -+ -+/* -+ * Output 24MHz for SD and 16MHz for MMC. -+ */ -+static inline void __cpm_select_msc_clk(int sd) -+{ -+ unsigned int pllout2 = __cpm_get_pllout2(); -+ unsigned int div = 0; -+ -+ if (sd) { -+ div = pllout2 / 24000000; -+ } -+ else { -+ div = pllout2 / 16000000; -+ } -+ -+ REG_CPM_MSCCDR = div - 1; -+} -+ -+int jz_init_clocks(unsigned long ext_rate); -+ -+#endif /* __ASM_JZ4740_CLOCK_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/dma.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/dma.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/dma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/dma.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,265 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/dma.h -+ * -+ * JZ4740 DMA definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4740_DMA_H__ -+#define __ASM_JZ4740_DMA_H__ -+ -+#include <linux/interrupt.h> -+#include <asm/io.h> /* need byte IO */ -+#include <linux/spinlock.h> /* And spinlocks */ -+#include <linux/delay.h> -+#include <asm/system.h> -+ -+/* -+ * Descriptor structure for JZ4740 DMA engine -+ * Note: this structure must always be aligned to a 16-bytes boundary. -+ */ -+ -+typedef struct { -+ volatile u32 dcmd; /* DCMD value for the current transfer */ -+ volatile u32 dsadr; /* DSAR value for the current transfer */ -+ volatile u32 dtadr; /* DTAR value for the current transfer */ -+ volatile u32 ddadr; /* Points to the next descriptor + transfer count */ -+} jz_dma_desc; -+ -+ -+/* DMA Device ID's follow */ -+enum { -+ DMA_ID_UART0_TX = 0, -+ DMA_ID_UART0_RX, -+ DMA_ID_SSI_TX, -+ DMA_ID_SSI_RX, -+ DMA_ID_AIC_TX, -+ DMA_ID_AIC_RX, -+ DMA_ID_MSC_TX, -+ DMA_ID_MSC_RX, -+ DMA_ID_TCU_OVERFLOW, -+ DMA_ID_AUTO, -+ DMA_ID_RAW_SET, -+ DMA_ID_MAX -+}; -+ -+/* DMA modes, simulated by sw */ -+#define DMA_MODE_READ 0x0 /* I/O to memory, no autoinit, increment, single mode */ -+#define DMA_MODE_WRITE 0x1 /* memory to I/O, no autoinit, increment, single mode */ -+#define DMA_AUTOINIT 0x2 -+#define DMA_MODE_MASK 0x3 -+ -+struct jz_dma_chan { -+ int dev_id; /* DMA ID: this channel is allocated if >=0, free otherwise */ -+ unsigned int io; /* DMA channel number */ -+ const char *dev_str; /* string describes the DMA channel */ -+ int irq; /* DMA irq number */ -+ void *irq_dev; /* DMA private device structure */ -+ unsigned int fifo_addr; /* physical fifo address of the requested device */ -+ unsigned int cntl; /* DMA controll */ -+ unsigned int mode; /* DMA configuration */ -+ unsigned int source; /* DMA request source */ -+}; -+ -+extern struct jz_dma_chan jz_dma_table[]; -+ -+ -+#define DMA_8BIT_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_8BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_8BIT_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \ -+ DMAC_DCMD_DS_8BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_16BIT_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_16BIT_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_16 | \ -+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_32BIT_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_32BIT_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_16BYTE_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_16BYTE_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \ -+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_32BYTE_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_32BYTE_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \ -+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_AIC_32_16BYTE_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_AIC_32_16BYTE_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \ -+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_AIC_16BIT_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \ -+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_AIC_16BIT_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \ -+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_AIC_16BYTE_RX_CMD \ -+ DMAC_DCMD_DAI | \ -+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \ -+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN -+ -+#define DMA_AIC_16BYTE_TX_CMD \ -+ DMAC_DCMD_SAI | \ -+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \ -+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN -+ -+extern int jz_request_dma(int dev_id, -+ const char *dev_str, -+ irqreturn_t (*irqhandler)(int, void *), -+ unsigned long irqflags, -+ void *irq_dev_id); -+extern void jz_free_dma(unsigned int dmanr); -+ -+extern int jz_dma_read_proc(char *buf, char **start, off_t fpos, -+ int length, int *eof, void *data); -+extern void dump_jz_dma_channel(unsigned int dmanr); -+ -+extern void enable_dma(unsigned int dmanr); -+extern void disable_dma(unsigned int dmanr); -+extern void set_dma_addr(unsigned int dmanr, unsigned int phyaddr); -+extern void set_dma_count(unsigned int dmanr, unsigned int bytecnt); -+extern void set_dma_mode(unsigned int dmanr, unsigned int mode); -+extern void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt); -+extern void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt); -+extern unsigned int get_dma_residue(unsigned int dmanr); -+ -+extern spinlock_t dma_spin_lock; -+ -+static __inline__ unsigned long claim_dma_lock(void) -+{ -+ unsigned long flags; -+ spin_lock_irqsave(&dma_spin_lock, flags); -+ return flags; -+} -+ -+static __inline__ void release_dma_lock(unsigned long flags) -+{ -+ spin_unlock_irqrestore(&dma_spin_lock, flags); -+} -+ -+/* Clear the 'DMA Pointer Flip Flop'. -+ * Write 0 for LSB/MSB, 1 for MSB/LSB access. -+ */ -+#define clear_dma_ff(channel) -+ -+static __inline__ struct jz_dma_chan *get_dma_chan(unsigned int dmanr) -+{ -+ if (dmanr > MAX_DMA_NUM -+ || jz_dma_table[dmanr].dev_id < 0) -+ return NULL; -+ return &jz_dma_table[dmanr]; -+} -+ -+static __inline__ int dma_halted(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return 1; -+ return __dmac_channel_transmit_halt_detected(dmanr) ? 1 : 0; -+} -+ -+static __inline__ unsigned int get_dma_mode(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return 0; -+ return chan->mode; -+} -+ -+static __inline__ void clear_dma_done(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return; -+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); -+} -+ -+static __inline__ void clear_dma_halt(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return; -+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT); -+ REG_DMAC_DMACR &= ~(DMAC_DMACR_HLT); -+} -+ -+static __inline__ void clear_dma_flag(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return; -+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); -+ REG_DMAC_DMACR &= ~(DMAC_DMACR_HLT | DMAC_DMACR_AR); -+} -+ -+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) -+{ -+} -+ -+static __inline__ unsigned int get_dma_done_status(unsigned int dmanr) -+{ -+ unsigned long dccsr; -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return 0; -+ dccsr = REG_DMAC_DCCSR(chan->io); -+ return dccsr & (DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); -+} -+ -+static __inline__ int get_dma_done_irq(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return -1; -+ return chan->irq; -+} -+ -+#endif /* __ASM_JZ4740_DMA_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/gpio.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/gpio.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/gpio.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,386 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ7420/JZ4740 GPIO pin definitions -+ * -+ * 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. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _JZ_GPIO_H -+#define _JZ_GPIO_H -+ -+#include <linux/types.h> -+ -+enum jz_gpio_function { -+ JZ_GPIO_FUNC_NONE, -+ JZ_GPIO_FUNC1, -+ JZ_GPIO_FUNC2, -+ JZ_GPIO_FUNC3, -+}; -+ -+ -+/* -+ Usually a driver for a SoC component has to request several gpio pins and -+ configure them as funcion pins. -+ jz_gpio_bulk_request can be used to ease this process. -+ Usually one would do something like: -+ -+ const static struct jz_gpio_bulk_request i2c_pins[] = { -+ JZ_GPIO_BULK_PIN(I2C_SDA), -+ JZ_GPIO_BULK_PIN(I2C_SCK), -+ }; -+ -+ inside the probe function: -+ -+ ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins)); -+ if (ret) { -+ ... -+ -+ inside the remove function: -+ -+ jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins)); -+ -+ -+*/ -+struct jz_gpio_bulk_request { -+ int gpio; -+ const char *name; -+ enum jz_gpio_function function; -+}; -+ -+#define JZ_GPIO_BULK_PIN(pin) { \ -+ .gpio = JZ_GPIO_ ## pin, \ -+ .name = #pin, \ -+ .function = JZ_GPIO_FUNC_ ## pin \ -+} -+ -+int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num); -+void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num); -+void jz_gpio_enable_pullup(unsigned gpio); -+void jz_gpio_disable_pullup(unsigned gpio); -+int jz_gpio_set_function(int gpio, enum jz_gpio_function function); -+ -+#include <asm/mach-generic/gpio.h> -+ -+#define JZ_GPIO_PORTA(x) (x + 32 * 0) -+#define JZ_GPIO_PORTB(x) (x + 32 * 1) -+#define JZ_GPIO_PORTC(x) (x + 32 * 2) -+#define JZ_GPIO_PORTD(x) (x + 32 * 3) -+ -+/* Port A function pins */ -+#define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0) -+#define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1) -+#define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2) -+#define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3) -+#define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4) -+#define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5) -+#define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6) -+#define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7) -+#define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8) -+#define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9) -+#define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10) -+#define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11) -+#define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12) -+#define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13) -+#define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14) -+#define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15) -+#define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16) -+#define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17) -+#define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18) -+#define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19) -+#define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20) -+#define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21) -+#define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22) -+#define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23) -+#define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24) -+#define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25) -+#define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26) -+#define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27) -+#define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28) -+#define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29) -+#define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30) -+#define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31) -+ -+#define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1 -+ -+/* Port B function pins */ -+#define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0) -+#define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1) -+#define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2) -+#define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3) -+#define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4) -+#define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5) -+#define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6) -+#define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7) -+#define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8) -+#define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9) -+#define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10) -+#define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11) -+#define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12) -+#define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13) -+#define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14) -+#define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15) -+#define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16) -+#define JZ_GPIO_MEM_CLS JZ_GPIO_PORTB(17) -+#define JZ_GPIO_MEM_SPL JZ_GPIO_PORTB(18) -+#define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19) -+#define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20) -+#define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21) -+#define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22) -+#define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23) -+#define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24) -+#define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25) -+#define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26) -+#define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27) -+#define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28) -+#define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29) -+#define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30) -+#define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31) -+ -+#define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CLS JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_SPL JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1 -+ -+ -+#define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17) -+#define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18) -+ -+#define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2 -+ -+/* Port C function pins */ -+#define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0) -+#define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1) -+#define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2) -+#define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3) -+#define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4) -+#define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5) -+#define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6) -+#define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7) -+#define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8) -+#define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9) -+#define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10) -+#define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11) -+#define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12) -+#define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13) -+#define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14) -+#define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15) -+#define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16) -+#define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17) -+#define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18) -+#define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19) -+#define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20) -+#define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21) -+#define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22) -+#define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23) -+#define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24) -+#define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25) -+#define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26) -+#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27) -+#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28) -+#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29) -+ -+#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1 -+ -+ -+#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22) -+#define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23) -+ -+#define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2 -+ -+/* Port D function pins */ -+#define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0) -+#define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1) -+#define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2) -+#define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3) -+#define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4) -+#define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5) -+#define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6) -+#define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7) -+#define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8) -+#define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9) -+#define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10) -+#define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11) -+#define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12) -+#define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13) -+#define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14) -+#define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15) -+#define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16) -+#define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17) -+#define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18) -+#define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19) -+#define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20) -+#define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21) -+#define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22) -+#define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23) -+#define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24) -+#define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25) -+#define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26) -+#define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27) -+#define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28) -+#define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30) -+#define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31) -+ -+#define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC1 -+#define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC1 -+ -+#define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18) -+#define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19) -+#define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20) -+#define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21) -+#define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22) -+#define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23) -+#define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24) -+#define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25) -+#define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26) -+#define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27) -+#define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28) -+#define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30) -+#define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31) -+ -+#define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2 -+#define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2 -+ -+#define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30) -+#define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31) -+ -+#define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3 -+#define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3 -+ -+#endif -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/jz4740.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/jz4740.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/jz4740.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/jz4740.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,60 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/jz4740.h -+ * -+ * JZ4740 common definition. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 __ASM_JZ4740_H__ -+#define __ASM_JZ4740_H__ -+ -+#include <asm/mach-jz4740/regs.h> -+#include <asm/mach-jz4740/ops.h> -+#include <asm/mach-jz4740/dma.h> -+#include <asm/mach-jz4740/misc.h> -+ -+/*------------------------------------------------------------------ -+ * Platform definitions -+ */ -+#ifdef CONFIG_JZ4740_PAVO -+#include <asm/mach-jz4740/board-pavo.h> -+#endif -+ -+#ifdef CONFIG_JZ4740_LEO -+#include <asm/mach-jz4740/board-leo.h> -+#endif -+ -+#ifdef CONFIG_JZ4740_LYRA -+#include <asm/mach-jz4740/board-lyra.h> -+#endif -+ -+#ifdef CONFIG_JZ4725_DIPPER -+#include <asm/mach-jz4740/board-dipper.h> -+#endif -+ -+#ifdef CONFIG_JZ4720_VIRGO -+#include <asm/mach-jz4740/board-virgo.h> -+#endif -+ -+#ifdef CONFIG_JZ4740_QI_LB60 -+#include <asm/mach-jz4740/board-qi_lb60.h> -+#endif -+ -+/* Add other platform definition here ... */ -+ -+ -+/*------------------------------------------------------------------ -+ * Follows are related to platform definitions -+ */ -+ -+#include <asm/mach-jz4740/clock.h> -+#include <asm/mach-jz4740/serial.h> -+ -+#endif /* __ASM_JZ4740_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/misc.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/misc.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/misc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/misc.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,43 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/misc.h -+ * -+ * Ingenic's JZ4740 common include. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <yliu@ingenic.cn> -+ * -+ * 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 __ASM_JZ4740_MISC_H__ -+#define __ASM_JZ4740_MISC_H__ -+ -+/*========================================================== -+ * I2C -+ *===========================================================*/ -+ -+#define I2C_EEPROM_DEV 0xA /* b'1010 */ -+#define I2C_RTC_DEV 0xD /* b'1101 */ -+#define DIMM0_SPD_ADDR 0 -+#define DIMM1_SPD_ADDR 1 -+#define DIMM2_SPD_ADDR 2 -+#define DIMM3_SPD_ADDR 3 -+#define JZ_HCI_ADDR 7 -+ -+#define DIMM_SPD_LEN 128 -+#define JZ_HCI_LEN 512 /* 4K bits E2PROM */ -+#define I2C_RTC_LEN 16 -+#define HCI_MAC_OFFSET 64 -+ -+extern void i2c_open(void); -+extern void i2c_close(void); -+extern void i2c_setclk(unsigned int i2cclk); -+extern int i2c_read(unsigned char device, unsigned char *buf, -+ unsigned char address, int count); -+extern int i2c_write(unsigned char device, unsigned char *buf, -+ unsigned char address, int count); -+ -+#endif /* __ASM_JZ4740_MISC_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/ops.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/ops.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/ops.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/ops.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,2224 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/ops.h -+ * -+ * Ingenic's JZ4740 common include. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <yliu@ingenic.cn> -+ * -+ * 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 __JZ4740_OPS_H__ -+#define __JZ4740_OPS_H__ -+ -+/* -+ * Definition of Module Operations -+ */ -+ -+/*************************************************************************** -+ * GPIO -+ ***************************************************************************/ -+ -+//------------------------------------------------------ -+// GPIO Pins Description -+// -+// PORT 0: -+// -+// PIN/BIT N FUNC0 FUNC1 -+// 0 D0 - -+// 1 D1 - -+// 2 D2 - -+// 3 D3 - -+// 4 D4 - -+// 5 D5 - -+// 6 D6 - -+// 7 D7 - -+// 8 D8 - -+// 9 D9 - -+// 10 D10 - -+// 11 D11 - -+// 12 D12 - -+// 13 D13 - -+// 14 D14 - -+// 15 D15 - -+// 16 D16 - -+// 17 D17 - -+// 18 D18 - -+// 19 D19 - -+// 20 D20 - -+// 21 D21 - -+// 22 D22 - -+// 23 D23 - -+// 24 D24 - -+// 25 D25 - -+// 26 D26 - -+// 27 D27 - -+// 28 D28 - -+// 29 D29 - -+// 30 D30 - -+// 31 D31 - -+// -+//------------------------------------------------------ -+// PORT 1: -+// -+// PIN/BIT N FUNC0 FUNC1 -+// 0 A0 - -+// 1 A1 - -+// 2 A2 - -+// 3 A3 - -+// 4 A4 - -+// 5 A5 - -+// 6 A6 - -+// 7 A7 - -+// 8 A8 - -+// 9 A9 - -+// 10 A10 - -+// 11 A11 - -+// 12 A12 - -+// 13 A13 - -+// 14 A14 - -+// 15 A15/CL - -+// 16 A16/AL - -+// 17 LCD_CLS A21 -+// 18 LCD_SPL A22 -+// 19 DCS# - -+// 20 RAS# - -+// 21 CAS# - -+// 22 RDWE#/BUFD# - -+// 23 CKE - -+// 24 CKO - -+// 25 CS1# - -+// 26 CS2# - -+// 27 CS3# - -+// 28 CS4# - -+// 29 RD# - -+// 30 WR# - -+// 31 WE0# - -+// -+// Note: PIN15&16 are CL&AL when connecting to NAND flash. -+//------------------------------------------------------ -+// PORT 2: -+// -+// PIN/BIT N FUNC0 FUNC1 -+// 0 LCD_D0 - -+// 1 LCD_D1 - -+// 2 LCD_D2 - -+// 3 LCD_D3 - -+// 4 LCD_D4 - -+// 5 LCD_D5 - -+// 6 LCD_D6 - -+// 7 LCD_D7 - -+// 8 LCD_D8 - -+// 9 LCD_D9 - -+// 10 LCD_D10 - -+// 11 LCD_D11 - -+// 12 LCD_D12 - -+// 13 LCD_D13 - -+// 14 LCD_D14 - -+// 15 LCD_D15 - -+// 16 LCD_D16 - -+// 17 LCD_D17 - -+// 18 LCD_PCLK - -+// 19 LCD_HSYNC - -+// 20 LCD_VSYNC - -+// 21 LCD_DE - -+// 22 LCD_PS A19 -+// 23 LCD_REV A20 -+// 24 WE1# - -+// 25 WE2# - -+// 26 WE3# - -+// 27 WAIT# - -+// 28 FRE# - -+// 29 FWE# - -+// 30(NOTE:FRB#) - - -+// 31 - - -+// -+// NOTE(1): PIN30 is used for FRB# when connecting to NAND flash. -+//------------------------------------------------------ -+// PORT 3: -+// -+// PIN/BIT N FUNC0 FUNC1 -+// 0 CIM_D0 - -+// 1 CIM_D1 - -+// 2 CIM_D2 - -+// 3 CIM_D3 - -+// 4 CIM_D4 - -+// 5 CIM_D5 - -+// 6 CIM_D6 - -+// 7 CIM_D7 - -+// 8 MSC_CMD - -+// 9 MSC_CLK - -+// 10 MSC_D0 - -+// 11 MSC_D1 - -+// 12 MSC_D2 - -+// 13 MSC_D3 - -+// 14 CIM_MCLK - -+// 15 CIM_PCLK - -+// 16 CIM_VSYNC - -+// 17 CIM_HSYNC - -+// 18 SSI_CLK SCLK_RSTN -+// 19 SSI_CE0# BIT_CLK(AIC) -+// 20 SSI_DT SDATA_OUT(AIC) -+// 21 SSI_DR SDATA_IN(AIC) -+// 22 SSI_CE1#&GPC SYNC(AIC) -+// 23 PWM0 I2C_SDA -+// 24 PWM1 I2C_SCK -+// 25 PWM2 UART0_TxD -+// 26 PWM3 UART0_RxD -+// 27 PWM4 A17 -+// 28 PWM5 A18 -+// 29 - - -+// 30 PWM6 UART0_CTS/UART1_RxD -+// 31 PWM7 UART0_RTS/UART1_TxD -+// -+////////////////////////////////////////////////////////// -+ -+/* -+ * p is the port number (0,1,2,3) -+ * o is the pin offset (0-31) inside the port -+ * n is the absolute number of a pin (0-127), regardless of the port -+ */ -+ -+//------------------------------------------- -+// Function Pins Mode -+ -+#define __gpio_as_func0(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXFUNS(p) = (1 << o); \ -+ REG_GPIO_PXSELC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_as_func1(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXFUNS(p) = (1 << o); \ -+ REG_GPIO_PXSELS(p) = (1 << o); \ -+} while (0) -+ -+/* -+ * D0 ~ D31, A0 ~ A16, DCS#, RAS#, CAS#, CKE#, -+ * RDWE#, CKO#, WE0#, WE1#, WE2#, WE3# -+ */ -+#define __gpio_as_sdram_32bit() \ -+do { \ -+ REG_GPIO_PXFUNS(0) = 0xffffffff; \ -+ REG_GPIO_PXSELC(0) = 0xffffffff; \ -+ REG_GPIO_PXPES(0) = 0xffffffff; \ -+ REG_GPIO_PXFUNS(1) = 0x81f9ffff; \ -+ REG_GPIO_PXSELC(1) = 0x81f9ffff; \ -+ REG_GPIO_PXPES(1) = 0x81f9ffff; \ -+ REG_GPIO_PXFUNS(2) = 0x07000000; \ -+ REG_GPIO_PXSELC(2) = 0x07000000; \ -+ REG_GPIO_PXPES(2) = 0x07000000; \ -+} while (0) -+ -+/* -+ * D0 ~ D15, A0 ~ A16, DCS#, RAS#, CAS#, CKE#, -+ * RDWE#, CKO#, WE0#, WE1# -+ */ -+#define __gpio_as_sdram_16bit() \ -+do { \ -+ REG_GPIO_PXFUNS(0) = 0x5442bfaa; \ -+ REG_GPIO_PXSELC(0) = 0x5442bfaa; \ -+ REG_GPIO_PXPES(0) = 0x5442bfaa; \ -+ REG_GPIO_PXFUNS(1) = 0x81f9ffff; \ -+ REG_GPIO_PXSELC(1) = 0x81f9ffff; \ -+ REG_GPIO_PXPES(1) = 0x81f9ffff; \ -+ REG_GPIO_PXFUNS(2) = 0x01000000; \ -+ REG_GPIO_PXSELC(2) = 0x01000000; \ -+ REG_GPIO_PXPES(2) = 0x01000000; \ -+} while (0) -+ -+/* -+ * CS1#, CLE, ALE, FRE#, FWE#, FRB#, RDWE#/BUFD# -+ */ -+#define __gpio_as_nand() \ -+do { \ -+ REG_GPIO_PXFUNS(1) = 0x02018000; \ -+ REG_GPIO_PXSELC(1) = 0x02018000; \ -+ REG_GPIO_PXPES(1) = 0x02018000; \ -+ REG_GPIO_PXFUNS(2) = 0x30000000; \ -+ REG_GPIO_PXSELC(2) = 0x30000000; \ -+ REG_GPIO_PXPES(2) = 0x30000000; \ -+ REG_GPIO_PXFUNC(2) = 0x40000000; \ -+ REG_GPIO_PXSELC(2) = 0x40000000; \ -+ REG_GPIO_PXDIRC(2) = 0x40000000; \ -+ REG_GPIO_PXPES(2) = 0x40000000; \ -+ REG_GPIO_PXFUNS(1) = 0x00400000; \ -+ REG_GPIO_PXSELC(1) = 0x00400000; \ -+} while (0) -+ -+/* -+ * CS4#, RD#, WR#, WAIT#, A0 ~ A22, D0 ~ D7 -+ */ -+#define __gpio_as_nor_8bit() \ -+do { \ -+ REG_GPIO_PXFUNS(0) = 0x000000ff; \ -+ REG_GPIO_PXSELC(0) = 0x000000ff; \ -+ REG_GPIO_PXPES(0) = 0x000000ff; \ -+ REG_GPIO_PXFUNS(1) = 0x7041ffff; \ -+ REG_GPIO_PXSELC(1) = 0x7041ffff; \ -+ REG_GPIO_PXPES(1) = 0x7041ffff; \ -+ REG_GPIO_PXFUNS(1) = 0x00060000; \ -+ REG_GPIO_PXSELS(1) = 0x00060000; \ -+ REG_GPIO_PXPES(1) = 0x00060000; \ -+ REG_GPIO_PXFUNS(2) = 0x08000000; \ -+ REG_GPIO_PXSELC(2) = 0x08000000; \ -+ REG_GPIO_PXPES(2) = 0x08000000; \ -+ REG_GPIO_PXFUNS(2) = 0x00c00000; \ -+ REG_GPIO_PXSELS(2) = 0x00c00000; \ -+ REG_GPIO_PXPES(2) = 0x00c00000; \ -+ REG_GPIO_PXFUNS(3) = 0x18000000; \ -+ REG_GPIO_PXSELS(3) = 0x18000000; \ -+ REG_GPIO_PXPES(3) = 0x18000000; \ -+} while (0) -+ -+/* -+ * CS4#, RD#, WR#, WAIT#, A0 ~ A22, D0 ~ D15 -+ */ -+#define __gpio_as_nor_16bit() \ -+do { \ -+ REG_GPIO_PXFUNS(0) = 0x0000ffff; \ -+ REG_GPIO_PXSELC(0) = 0x0000ffff; \ -+ REG_GPIO_PXPES(0) = 0x0000ffff; \ -+ REG_GPIO_PXFUNS(1) = 0x7041ffff; \ -+ REG_GPIO_PXSELC(1) = 0x7041ffff; \ -+ REG_GPIO_PXPES(1) = 0x7041ffff; \ -+ REG_GPIO_PXFUNS(1) = 0x00060000; \ -+ REG_GPIO_PXSELS(1) = 0x00060000; \ -+ REG_GPIO_PXPES(1) = 0x00060000; \ -+ REG_GPIO_PXFUNS(2) = 0x08000000; \ -+ REG_GPIO_PXSELC(2) = 0x08000000; \ -+ REG_GPIO_PXPES(2) = 0x08000000; \ -+ REG_GPIO_PXFUNS(2) = 0x00c00000; \ -+ REG_GPIO_PXSELS(2) = 0x00c00000; \ -+ REG_GPIO_PXPES(2) = 0x00c00000; \ -+ REG_GPIO_PXFUNS(3) = 0x18000000; \ -+ REG_GPIO_PXSELS(3) = 0x18000000; \ -+ REG_GPIO_PXPES(3) = 0x18000000; \ -+} while (0) -+ -+/* -+ * UART0_TxD, UART_RxD0 -+ */ -+#define __gpio_as_uart0() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x06000000; \ -+ REG_GPIO_PXSELS(3) = 0x06000000; \ -+ REG_GPIO_PXPES(3) = 0x06000000; \ -+} while (0) -+ -+/* -+ * UART0_CTS, UART0_RTS -+ */ -+#define __gpio_as_ctsrts() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0xc0000000; \ -+ REG_GPIO_PXSELS(3) = 0xc0000000; \ -+ REG_GPIO_PXTRGC(3) = 0xc0000000; \ -+ REG_GPIO_PXPES(3) = 0xc0000000; \ -+} while (0) -+ -+/* -+ * UART1_TxD, UART1_RxD1 -+ */ -+#define __gpio_as_uart1() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0xc0000000; \ -+ REG_GPIO_PXSELC(3) = 0xc0000000; \ -+ REG_GPIO_PXTRGS(3) = 0xc0000000; \ -+ REG_GPIO_PXPES(3) = 0xc0000000; \ -+} while (0) -+ -+/* -+ * LCD_D0~LCD_D15, LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE -+ */ -+#define __gpio_as_lcd_16bit() \ -+do { \ -+ REG_GPIO_PXFUNS(2) = 0x003cffff; \ -+ REG_GPIO_PXSELC(2) = 0x003cffff; \ -+ REG_GPIO_PXPES(2) = 0x003cffff; \ -+} while (0) -+ -+/* -+ * LCD_D0~LCD_D17, LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE -+ */ -+#define __gpio_as_lcd_18bit() \ -+do { \ -+ REG_GPIO_PXFUNS(2) = 0x003fffff; \ -+ REG_GPIO_PXSELC(2) = 0x003fffff; \ -+ REG_GPIO_PXPES(2) = 0x003fffff; \ -+} while (0) -+ -+/* -+ * LCD_PS, LCD_REV, LCD_CLS, LCD_SPL -+ */ -+#define __gpio_as_lcd_special() \ -+do { \ -+ REG_GPIO_PXFUNS(1) = 0x00060000; \ -+ REG_GPIO_PXSELC(1) = 0x00060000; \ -+ REG_GPIO_PXPES(1) = 0x00060000; \ -+ REG_GPIO_PXFUNS(2) = 0x00c00000; \ -+ REG_GPIO_PXSELC(2) = 0x00c00000; \ -+ REG_GPIO_PXPES(2) = 0x00c00000; \ -+} while (0) -+ -+/* LCD_D0~LCD_D7, SLCD_RS, SLCD_CS */ -+#define __gpio_as_slcd_8bit() \ -+do { \ -+ REG_GPIO_PXFUNS(2) = 0x001800ff; \ -+ REG_GPIO_PXSELC(2) = 0x001800ff; \ -+} while (0) -+ -+/* LCD_D0~LCD_D7, SLCD_RS, SLCD_CS */ -+#define __gpio_as_slcd_9bit() \ -+do { \ -+ REG_GPIO_PXFUNS(2) = 0x001801ff; \ -+ REG_GPIO_PXSELC(2) = 0x001801ff; \ -+} while (0) -+ -+/* LCD_D0~LCD_D15, SLCD_RS, SLCD_CS */ -+#define __gpio_as_slcd_16bit() \ -+do { \ -+ REG_GPIO_PXFUNS(2) = 0x0018ffff; \ -+ REG_GPIO_PXSELC(2) = 0x0018ffff; \ -+} while (0) -+ -+/* LCD_D0~LCD_D17, SLCD_RS, SLCD_CS */ -+#define __gpio_as_slcd_18bit() \ -+do { \ -+ REG_GPIO_PXFUNS(2) = 0x001bffff; \ -+ REG_GPIO_PXSELC(2) = 0x001bffff; \ -+} while (0) -+ -+/* -+ * CIM_D0~CIM_D7, CIM_MCLK, CIM_PCLK, CIM_VSYNC, CIM_HSYNC -+ */ -+#define __gpio_as_cim() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x0003c0ff; \ -+ REG_GPIO_PXSELC(3) = 0x0003c0ff; \ -+ REG_GPIO_PXPES(3) = 0x0003c0ff; \ -+} while (0) -+ -+/* -+ * SDATA_OUT, SDATA_IN, BIT_CLK, SYNC, SCLK_RESET -+ */ -+#define __gpio_as_aic() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x007c0000; \ -+ REG_GPIO_PXSELS(3) = 0x007c0000; \ -+ REG_GPIO_PXPES(3) = 0x007c0000; \ -+} while (0) -+ -+/* -+ * MSC_CMD, MSC_CLK, MSC_D0 ~ MSC_D3 -+ */ -+#define __gpio_as_msc() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x00003f00; \ -+ REG_GPIO_PXSELC(3) = 0x00003f00; \ -+ REG_GPIO_PXPES(3) = 0x00003f00; \ -+} while (0) -+ -+/* -+ * SSI_CS0, SSI_CLK, SSI_DT, SSI_DR -+ */ -+#define __gpio_as_ssi() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x003c0000; \ -+ REG_GPIO_PXSELC(3) = 0x003c0000; \ -+ REG_GPIO_PXPES(3) = 0x003c0000; \ -+} while (0) -+ -+/* -+ * I2C_SCK, I2C_SDA -+ */ -+#define __gpio_as_i2c() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x01800000; \ -+ REG_GPIO_PXSELS(3) = 0x01800000; \ -+ REG_GPIO_PXPES(3) = 0x01800000; \ -+} while (0) -+ -+/* -+ * PWM0 -+ */ -+#define __gpio_as_pwm0() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x00800000; \ -+ REG_GPIO_PXSELC(3) = 0x00800000; \ -+ REG_GPIO_PXPES(3) = 0x00800000; \ -+} while (0) -+ -+/* -+ * PWM1 -+ */ -+#define __gpio_as_pwm1() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x01000000; \ -+ REG_GPIO_PXSELC(3) = 0x01000000; \ -+ REG_GPIO_PXPES(3) = 0x01000000; \ -+} while (0) -+ -+/* -+ * PWM2 -+ */ -+#define __gpio_as_pwm2() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x02000000; \ -+ REG_GPIO_PXSELC(3) = 0x02000000; \ -+ REG_GPIO_PXPES(3) = 0x02000000; \ -+} while (0) -+ -+/* -+ * PWM3 -+ */ -+#define __gpio_as_pwm3() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x04000000; \ -+ REG_GPIO_PXSELC(3) = 0x04000000; \ -+ REG_GPIO_PXPES(3) = 0x04000000; \ -+} while (0) -+ -+/* -+ * PWM4 -+ */ -+#define __gpio_as_pwm4() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x08000000; \ -+ REG_GPIO_PXSELC(3) = 0x08000000; \ -+ REG_GPIO_PXPES(3) = 0x08000000; \ -+} while (0) -+ -+/* -+ * PWM5 -+ */ -+#define __gpio_as_pwm5() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x10000000; \ -+ REG_GPIO_PXSELC(3) = 0x10000000; \ -+ REG_GPIO_PXPES(3) = 0x10000000; \ -+} while (0) -+ -+/* -+ * PWM6 -+ */ -+#define __gpio_as_pwm6() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x40000000; \ -+ REG_GPIO_PXSELC(3) = 0x40000000; \ -+ REG_GPIO_PXPES(3) = 0x40000000; \ -+} while (0) -+ -+/* -+ * PWM7 -+ */ -+#define __gpio_as_pwm7() \ -+do { \ -+ REG_GPIO_PXFUNS(3) = 0x80000000; \ -+ REG_GPIO_PXSELC(3) = 0x80000000; \ -+ REG_GPIO_PXPES(3) = 0x80000000; \ -+} while (0) -+ -+/* -+ * n = 0 ~ 7 -+ */ -+#define __gpio_as_pwm(n) __gpio_as_pwm##n() -+ -+//------------------------------------------- -+// GPIO or Interrupt Mode -+ -+#define __gpio_get_port(p) (REG_GPIO_PXPIN(p)) -+ -+#define __gpio_port_as_output(p, o) \ -+do { \ -+ REG_GPIO_PXFUNC(p) = (1 << (o)); \ -+ REG_GPIO_PXSELC(p) = (1 << (o)); \ -+ REG_GPIO_PXDIRS(p) = (1 << (o)); \ -+} while (0) -+ -+#define __gpio_port_as_input(p, o) \ -+do { \ -+ REG_GPIO_PXFUNC(p) = (1 << (o)); \ -+ REG_GPIO_PXSELC(p) = (1 << (o)); \ -+ REG_GPIO_PXDIRC(p) = (1 << (o)); \ -+} while (0) -+ -+#define __gpio_as_output(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ __gpio_port_as_output(p, o); \ -+} while (0) -+ -+#define __gpio_as_input(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ __gpio_port_as_input(p, o); \ -+} while (0) -+ -+#define __gpio_set_pin(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXDATS(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_clear_pin(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXDATC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_get_pin(n) \ -+({ \ -+ unsigned int p, o, v; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ if (__gpio_get_port(p) & (1 << o)) \ -+ v = 1; \ -+ else \ -+ v = 0; \ -+ v; \ -+}) -+ -+#define __gpio_as_irq_high_level(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXIMS(p) = (1 << o); \ -+ REG_GPIO_PXTRGC(p) = (1 << o); \ -+ REG_GPIO_PXFUNC(p) = (1 << o); \ -+ REG_GPIO_PXSELS(p) = (1 << o); \ -+ REG_GPIO_PXDIRS(p) = (1 << o); \ -+ REG_GPIO_PXFLGC(p) = (1 << o); \ -+ REG_GPIO_PXIMC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_as_irq_low_level(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXIMS(p) = (1 << o); \ -+ REG_GPIO_PXTRGC(p) = (1 << o); \ -+ REG_GPIO_PXFUNC(p) = (1 << o); \ -+ REG_GPIO_PXSELS(p) = (1 << o); \ -+ REG_GPIO_PXDIRC(p) = (1 << o); \ -+ REG_GPIO_PXFLGC(p) = (1 << o); \ -+ REG_GPIO_PXIMC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_as_irq_rise_edge(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXIMS(p) = (1 << o); \ -+ REG_GPIO_PXTRGS(p) = (1 << o); \ -+ REG_GPIO_PXFUNC(p) = (1 << o); \ -+ REG_GPIO_PXSELS(p) = (1 << o); \ -+ REG_GPIO_PXDIRS(p) = (1 << o); \ -+ REG_GPIO_PXFLGC(p) = (1 << o); \ -+ REG_GPIO_PXIMC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_as_irq_fall_edge(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXIMS(p) = (1 << o); \ -+ REG_GPIO_PXTRGS(p) = (1 << o); \ -+ REG_GPIO_PXFUNC(p) = (1 << o); \ -+ REG_GPIO_PXSELS(p) = (1 << o); \ -+ REG_GPIO_PXDIRC(p) = (1 << o); \ -+ REG_GPIO_PXFLGC(p) = (1 << o); \ -+ REG_GPIO_PXIMC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_mask_irq(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXIMS(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_unmask_irq(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXIMC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_ack_irq(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXFLGC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_get_irq() \ -+({ \ -+ unsigned int p, i, tmp, v = 0; \ -+ for (p = 3; p >= 0; p--) { \ -+ tmp = REG_GPIO_PXFLG(p); \ -+ for (i = 0; i < 32; i++) \ -+ if (tmp & (1 << i)) \ -+ v = (32*p + i); \ -+ } \ -+ v; \ -+}) -+ -+#define __gpio_group_irq(n) \ -+({ \ -+ register int tmp, i; \ -+ tmp = REG_GPIO_PXFLG((n)); \ -+ for (i=31;i>=0;i--) \ -+ if (tmp & (1 << i)) \ -+ break; \ -+ i; \ -+}) -+ -+#define __gpio_enable_pull(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXPEC(p) = (1 << o); \ -+} while (0) -+ -+#define __gpio_disable_pull(n) \ -+do { \ -+ unsigned int p, o; \ -+ p = (n) / 32; \ -+ o = (n) % 32; \ -+ REG_GPIO_PXPES(p) = (1 << o); \ -+} while (0) -+ -+ -+/*************************************************************************** -+ * CPM -+ ***************************************************************************/ -+#define __cpm_get_pllm() \ -+ ((REG_CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT) -+#define __cpm_get_plln() \ -+ ((REG_CPM_CPPCR & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT) -+#define __cpm_get_pllod() \ -+ ((REG_CPM_CPPCR & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT) -+ -+#define __cpm_get_cdiv() \ -+ ((REG_CPM_CPCCR & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT) -+#define __cpm_get_hdiv() \ -+ ((REG_CPM_CPCCR & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT) -+#define __cpm_get_pdiv() \ -+ ((REG_CPM_CPCCR & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT) -+#define __cpm_get_mdiv() \ -+ ((REG_CPM_CPCCR & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT) -+#define __cpm_get_ldiv() \ -+ ((REG_CPM_CPCCR & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT) -+#define __cpm_get_udiv() \ -+ ((REG_CPM_CPCCR & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT) -+#define __cpm_get_i2sdiv() \ -+ ((REG_CPM_I2SCDR & CPM_I2SCDR_I2SDIV_MASK) >> CPM_I2SCDR_I2SDIV_BIT) -+#define __cpm_get_pixdiv() \ -+ ((REG_CPM_LPCDR & CPM_LPCDR_PIXDIV_MASK) >> CPM_LPCDR_PIXDIV_BIT) -+#define __cpm_get_mscdiv() \ -+ ((REG_CPM_MSCCDR & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT) -+#define __cpm_get_uhcdiv() \ -+ ((REG_CPM_UHCCDR & CPM_UHCCDR_UHCDIV_MASK) >> CPM_UHCCDR_UHCDIV_BIT) -+#define __cpm_get_ssidiv() \ -+ ((REG_CPM_SSICCDR & CPM_SSICDR_SSICDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT) -+ -+#define __cpm_set_cdiv(v) \ -+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | ((v) << (CPM_CPCCR_CDIV_BIT))) -+#define __cpm_set_hdiv(v) \ -+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | ((v) << (CPM_CPCCR_HDIV_BIT))) -+#define __cpm_set_pdiv(v) \ -+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | ((v) << (CPM_CPCCR_PDIV_BIT))) -+#define __cpm_set_mdiv(v) \ -+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | ((v) << (CPM_CPCCR_MDIV_BIT))) -+#define __cpm_set_ldiv(v) \ -+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT))) -+#define __cpm_set_udiv(v) \ -+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | ((v) << (CPM_CPCCR_UDIV_BIT))) -+#define __cpm_set_i2sdiv(v) \ -+ (REG_CPM_I2SCDR = (REG_CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | ((v) << (CPM_I2SCDR_I2SDIV_BIT))) -+#define __cpm_set_pixdiv(v) \ -+ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT))) -+#define __cpm_set_mscdiv(v) \ -+ (REG_CPM_MSCCDR = (REG_CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | ((v) << (CPM_MSCCDR_MSCDIV_BIT))) -+#define __cpm_set_uhcdiv(v) \ -+ (REG_CPM_UHCCDR = (REG_CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | ((v) << (CPM_UHCCDR_UHCDIV_BIT))) -+#define __cpm_ssiclk_select_exclk() \ -+ (REG_CPM_SSICDR &= ~CPM_SSICDR_SCS) -+#define __cpm_ssiclk_select_pllout() \ -+ (REG_CPM_SSICDR |= CPM_SSICDR_SCS) -+#define __cpm_set_ssidiv(v) \ -+ (REG_CPM_SSICDR = (REG_CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT))) -+ -+#define __cpm_select_i2sclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_I2CS) -+#define __cpm_select_i2sclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_I2CS) -+#define __cpm_enable_cko() (REG_CPM_CPCCR |= CPM_CPCCR_CLKOEN) -+#define __cpm_select_usbclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_UCS) -+#define __cpm_select_usbclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_UCS) -+#define __cpm_enable_pll_change() (REG_CPM_CPCCR |= CPM_CPCCR_CE) -+#define __cpm_pllout_direct() (REG_CPM_CPCCR |= CPM_CPCCR_PCS) -+#define __cpm_pllout_div2() (REG_CPM_CPCCR &= ~CPM_CPCCR_PCS) -+ -+#define __cpm_pll_is_on() (REG_CPM_CPPCR & CPM_CPPCR_PLLS) -+#define __cpm_pll_bypass() (REG_CPM_CPPCR |= CPM_CPPCR_PLLBP) -+#define __cpm_pll_enable() (REG_CPM_CPPCR |= CPM_CPPCR_PLLEN) -+ -+#define __cpm_get_cclk_doze_duty() \ -+ ((REG_CPM_LCR & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT) -+#define __cpm_set_cclk_doze_duty(v) \ -+ (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_DOZE_DUTY_MASK) | ((v) << (CPM_LCR_DOZE_DUTY_BIT))) -+ -+#define __cpm_doze_mode() (REG_CPM_LCR |= CPM_LCR_DOZE_ON) -+#define __cpm_idle_mode() \ -+ (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_IDLE) -+#define __cpm_sleep_mode() \ -+ (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP) -+ -+#define __cpm_stop_all() (REG_CPM_CLKGR = 0x7fff) -+#define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1) -+#define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC) -+#define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU) -+#define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC) -+#define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC) -+#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) -+#define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM) -+#define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC) -+#define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC) -+#define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1) -+#define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2) -+#define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI) -+#define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C) -+#define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC) -+#define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU) -+#define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0) -+ -+#define __cpm_start_all() (REG_CPM_CLKGR = 0x0) -+#define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1) -+#define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC) -+#define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU) -+#define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC) -+#define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC) -+#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) -+#define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM) -+#define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC) -+#define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC) -+#define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1) -+#define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2) -+#define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI) -+#define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C) -+#define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC) -+#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) -+#define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0) -+ -+#define __cpm_get_o1st() \ -+ ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT) -+#define __cpm_set_o1st(v) \ -+ (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT))) -+#define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND) -+#define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE) -+ -+ -+/*************************************************************************** -+ * TCU -+ ***************************************************************************/ -+// where 'n' is the TCU channel -+#define __tcu_select_extalclk(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_EXT_EN) -+#define __tcu_select_rtcclk(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_RTC_EN) -+#define __tcu_select_pclk(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_PCK_EN) -+ -+#define __tcu_select_clk_div1(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE1) -+#define __tcu_select_clk_div4(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE4) -+#define __tcu_select_clk_div16(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE16) -+#define __tcu_select_clk_div64(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE64) -+#define __tcu_select_clk_div256(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE256) -+#define __tcu_select_clk_div1024(n) \ -+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE1024) -+ -+#define __tcu_enable_pwm_output(n) ( REG_TCU_TCSR((n)) |= TCU_TCSR_PWM_EN ) -+#define __tcu_disable_pwm_output(n) ( REG_TCU_TCSR((n)) &= ~TCU_TCSR_PWM_EN ) -+ -+#define __tcu_init_pwm_output_high(n) ( REG_TCU_TCSR((n)) |= TCU_TCSR_PWM_INITL_HIGH ) -+#define __tcu_init_pwm_output_low(n) ( REG_TCU_TCSR((n)) &= ~TCU_TCSR_PWM_INITL_HIGH ) -+ -+#define __tcu_set_pwm_output_shutdown_graceful(n) ( REG_TCU_TCSR((n)) &= ~TCU_TCSR_PWM_SD ) -+#define __tcu_set_pwm_output_shutdown_abrupt(n) ( REG_TCU_TCSR((n)) |= TCU_TCSR_PWM_SD ) -+ -+#define __tcu_start_counter(n) ( REG_TCU_TESR |= (1 << (n)) ) -+#define __tcu_stop_counter(n) ( REG_TCU_TECR |= (1 << (n)) ) -+ -+#define __tcu_half_match_flag(n) ( REG_TCU_TFR & (1 << ((n) + 16)) ) -+#define __tcu_full_match_flag(n) ( REG_TCU_TFR & (1 << (n)) ) -+#define __tcu_set_half_match_flag(n) ( REG_TCU_TFSR = (1 << ((n) + 16)) ) -+#define __tcu_set_full_match_flag(n) ( REG_TCU_TFSR = (1 << (n)) ) -+#define __tcu_clear_half_match_flag(n) ( REG_TCU_TFCR = (1 << ((n) + 16)) ) -+#define __tcu_clear_full_match_flag(n) ( REG_TCU_TFCR = (1 << (n)) ) -+#define __tcu_mask_half_match_irq(n) ( REG_TCU_TMSR = (1 << ((n) + 16)) ) -+#define __tcu_mask_full_match_irq(n) ( REG_TCU_TMSR = (1 << (n)) ) -+#define __tcu_unmask_half_match_irq(n) ( REG_TCU_TMCR = (1 << ((n) + 16)) ) -+#define __tcu_unmask_full_match_irq(n) ( REG_TCU_TMCR = (1 << (n)) ) -+ -+#define __tcu_wdt_clock_stopped() ( REG_TCU_TSR & TCU_TSSR_WDTSC ) -+#define __tcu_timer_clock_stopped(n) ( REG_TCU_TSR & (1 << (n)) ) -+ -+#define __tcu_start_wdt_clock() ( REG_TCU_TSCR = TCU_TSSR_WDTSC ) -+#define __tcu_start_timer_clock(n) ( REG_TCU_TSCR = (1 << (n)) ) -+ -+#define __tcu_stop_wdt_clock() ( REG_TCU_TSSR = TCU_TSSR_WDTSC ) -+#define __tcu_stop_timer_clock(n) ( REG_TCU_TSSR = (1 << (n)) ) -+ -+#define __tcu_get_count(n) ( REG_TCU_TCNT((n)) ) -+#define __tcu_set_count(n,v) ( REG_TCU_TCNT((n)) = (v) ) -+#define __tcu_set_full_data(n,v) ( REG_TCU_TDFR((n)) = (v) ) -+#define __tcu_set_half_data(n,v) ( REG_TCU_TDHR((n)) = (v) ) -+ -+ -+/*************************************************************************** -+ * WDT -+ ***************************************************************************/ -+#define __wdt_start() ( REG_WDT_TCER |= WDT_TCER_TCEN ) -+#define __wdt_stop() ( REG_WDT_TCER &= ~WDT_TCER_TCEN ) -+#define __wdt_set_count(v) ( REG_WDT_TCNT = (v) ) -+#define __wdt_set_data(v) ( REG_WDT_TDR = (v) ) -+ -+#define __wdt_select_extalclk() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_EXT_EN) -+#define __wdt_select_rtcclk() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_RTC_EN) -+#define __wdt_select_pclk() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_PCK_EN) -+ -+#define __wdt_select_clk_div1() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE1) -+#define __wdt_select_clk_div4() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE4) -+#define __wdt_select_clk_div16() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE16) -+#define __wdt_select_clk_div64() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE64) -+#define __wdt_select_clk_div256() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE256) -+#define __wdt_select_clk_div1024() \ -+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE1024) -+ -+ -+/*************************************************************************** -+ * UART -+ ***************************************************************************/ -+ -+#define __uart_enable(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) |= UARTFCR_UUE | UARTFCR_FE ) -+#define __uart_disable(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) = ~UARTFCR_UUE ) -+ -+#define __uart_enable_transmit_irq(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_TIE ) -+#define __uart_disable_transmit_irq(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~UARTIER_TIE ) -+ -+#define __uart_enable_receive_irq(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE ) -+#define __uart_disable_receive_irq(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~(UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE) ) -+ -+#define __uart_enable_loopback(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) |= UARTMCR_LOOP ) -+#define __uart_disable_loopback(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) &= ~UARTMCR_LOOP ) -+ -+#define __uart_set_8n1(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) = UARTLCR_WLEN_8 ) -+ -+#define __uart_set_baud(n, devclk, baud) \ -+ do { \ -+ REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) |= UARTLCR_DLAB; \ -+ REG8(UART_BASE + UART_OFF*(n) + OFF_DLLR) = (devclk / 16 / baud) & 0xff; \ -+ REG8(UART_BASE + UART_OFF*(n) + OFF_DLHR) = ((devclk / 16 / baud) >> 8) & 0xff; \ -+ REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) &= ~UARTLCR_DLAB; \ -+ } while (0) -+ -+#define __uart_parity_error(n) \ -+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_PER) != 0 ) -+ -+#define __uart_clear_errors(n) \ -+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) &= ~(UARTLSR_ORER | UARTLSR_BRK | UARTLSR_FER | UARTLSR_PER | UARTLSR_RFER) ) -+ -+#define __uart_transmit_fifo_empty(n) \ -+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TDRQ) != 0 ) -+ -+#define __uart_transmit_end(n) \ -+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TEMT) != 0 ) -+ -+#define __uart_transmit_char(n, ch) \ -+ REG8(UART_BASE + UART_OFF*(n) + OFF_TDR) = (ch) -+ -+#define __uart_receive_fifo_full(n) \ -+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 ) -+ -+#define __uart_receive_ready(n) \ -+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 ) -+ -+#define __uart_receive_char(n) \ -+ REG8(UART_BASE + UART_OFF*(n) + OFF_RDR) -+ -+#define __uart_disable_irda() \ -+ ( REG8(IRDA_BASE + OFF_SIRCR) &= ~(SIRCR_TSIRE | SIRCR_RSIRE) ) -+#define __uart_enable_irda() \ -+ /* Tx high pulse as 0, Rx low pulse as 0 */ \ -+ ( REG8(IRDA_BASE + OFF_SIRCR) = SIRCR_TSIRE | SIRCR_RSIRE | SIRCR_RXPL | SIRCR_TPWS ) -+ -+ -+/*************************************************************************** -+ * DMAC -+ ***************************************************************************/ -+ -+/* n is the DMA channel (0 - 5) */ -+ -+#define __dmac_enable_module() \ -+ ( REG_DMAC_DMACR |= DMAC_DMACR_DMAE | DMAC_DMACR_PR_RR ) -+#define __dmac_disable_module() \ -+ ( REG_DMAC_DMACR &= ~DMAC_DMACR_DMAE ) -+ -+/* p=0,1,2,3 */ -+#define __dmac_set_priority(p) \ -+do { \ -+ REG_DMAC_DMACR &= ~DMAC_DMACR_PR_MASK; \ -+ REG_DMAC_DMACR |= ((p) << DMAC_DMACR_PR_BIT); \ -+} while (0) -+ -+#define __dmac_test_halt_error() ( REG_DMAC_DMACR & DMAC_DMACR_HLT ) -+#define __dmac_test_addr_error() ( REG_DMAC_DMACR & DMAC_DMACR_AR ) -+ -+#define __dmac_enable_descriptor(n) \ -+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_NDES ) -+#define __dmac_disable_descriptor(n) \ -+ ( REG_DMAC_DCCSR((n)) |= DMAC_DCCSR_NDES ) -+ -+#define __dmac_enable_channel(n) \ -+ ( REG_DMAC_DCCSR((n)) |= DMAC_DCCSR_EN ) -+#define __dmac_disable_channel(n) \ -+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_EN ) -+#define __dmac_channel_enabled(n) \ -+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_EN ) -+ -+#define __dmac_channel_enable_irq(n) \ -+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_TIE ) -+#define __dmac_channel_disable_irq(n) \ -+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_TIE ) -+ -+#define __dmac_channel_transmit_halt_detected(n) \ -+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_HLT ) -+#define __dmac_channel_transmit_end_detected(n) \ -+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_TT ) -+#define __dmac_channel_address_error_detected(n) \ -+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_AR ) -+#define __dmac_channel_count_terminated_detected(n) \ -+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_CT ) -+#define __dmac_channel_descriptor_invalid_detected(n) \ -+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_INV ) -+ -+#define __dmac_channel_clear_transmit_halt(n) \ -+ ( REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_HLT ) -+#define __dmac_channel_clear_transmit_end(n) \ -+ ( REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_TT ) -+#define __dmac_channel_clear_address_error(n) \ -+ ( REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_AR ) -+#define __dmac_channel_clear_count_terminated(n) \ -+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_CT ) -+#define __dmac_channel_clear_descriptor_invalid(n) \ -+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_INV ) -+ -+#define __dmac_channel_set_single_mode(n) \ -+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_TM ) -+#define __dmac_channel_set_block_mode(n) \ -+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_TM ) -+ -+#define __dmac_channel_set_transfer_unit_32bit(n) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BIT; \ -+} while (0) -+ -+#define __dmac_channel_set_transfer_unit_16bit(n) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BIT; \ -+} while (0) -+ -+#define __dmac_channel_set_transfer_unit_8bit(n) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_8BIT; \ -+} while (0) -+ -+#define __dmac_channel_set_transfer_unit_16byte(n) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BYTE; \ -+} while (0) -+ -+#define __dmac_channel_set_transfer_unit_32byte(n) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BYTE; \ -+} while (0) -+ -+/* w=8,16,32 */ -+#define __dmac_channel_set_dest_port_width(n,w) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DWDH_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DWDH_##w; \ -+} while (0) -+ -+/* w=8,16,32 */ -+#define __dmac_channel_set_src_port_width(n,w) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_SWDH_MASK; \ -+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_SWDH_##w; \ -+} while (0) -+ -+/* v=0-15 */ -+#define __dmac_channel_set_rdil(n,v) \ -+do { \ -+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_RDIL_MASK; \ -+ REG_DMAC_DCMD((n) |= ((v) << DMAC_DCMD_RDIL_BIT); \ -+} while (0) -+ -+#define __dmac_channel_dest_addr_fixed(n) \ -+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DAI ) -+#define __dmac_channel_dest_addr_increment(n) \ -+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_DAI ) -+ -+#define __dmac_channel_src_addr_fixed(n) \ -+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_SAI ) -+#define __dmac_channel_src_addr_increment(n) \ -+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_SAI ) -+ -+#define __dmac_channel_set_doorbell(n) \ -+ ( REG_DMAC_DMADBSR = (1 << (n)) ) -+ -+#define __dmac_channel_irq_detected(n) ( REG_DMAC_DMAIPR & (1 << (n)) ) -+#define __dmac_channel_ack_irq(n) ( REG_DMAC_DMAIPR &= ~(1 << (n)) ) -+ -+static __inline__ int __dmac_get_irq(void) -+{ -+ int i; -+ for (i = 0; i < MAX_DMA_NUM; i++) -+ if (__dmac_channel_irq_detected(i)) -+ return i; -+ return -1; -+} -+ -+ -+/*************************************************************************** -+ * AIC (AC'97 & I2S Controller) -+ ***************************************************************************/ -+ -+#define __aic_enable() ( REG_AIC_FR |= AIC_FR_ENB ) -+#define __aic_disable() ( REG_AIC_FR &= ~AIC_FR_ENB ) -+ -+#define __aic_select_ac97() ( REG_AIC_FR &= ~AIC_FR_AUSEL ) -+#define __aic_select_i2s() ( REG_AIC_FR |= AIC_FR_AUSEL ) -+ -+#define __aic_play_zero() ( REG_AIC_FR &= ~AIC_FR_LSMP ) -+#define __aic_play_lastsample() ( REG_AIC_FR |= AIC_FR_LSMP ) -+ -+#define __i2s_as_master() ( REG_AIC_FR |= AIC_FR_BCKD | AIC_FR_SYNCD ) -+#define __i2s_as_slave() ( REG_AIC_FR &= ~(AIC_FR_BCKD | AIC_FR_SYNCD) ) -+#define __aic_reset_status() ( REG_AIC_FR & AIC_FR_RST ) -+ -+#define __aic_reset() \ -+do { \ -+ REG_AIC_FR |= AIC_FR_RST; \ -+} while(0) -+ -+ -+#define __aic_set_transmit_trigger(n) \ -+do { \ -+ REG_AIC_FR &= ~AIC_FR_TFTH_MASK; \ -+ REG_AIC_FR |= ((n) << AIC_FR_TFTH_BIT); \ -+} while(0) -+ -+#define __aic_set_receive_trigger(n) \ -+do { \ -+ REG_AIC_FR &= ~AIC_FR_RFTH_MASK; \ -+ REG_AIC_FR |= ((n) << AIC_FR_RFTH_BIT); \ -+} while(0) -+ -+#define __aic_enable_record() ( REG_AIC_CR |= AIC_CR_EREC ) -+#define __aic_disable_record() ( REG_AIC_CR &= ~AIC_CR_EREC ) -+#define __aic_enable_replay() ( REG_AIC_CR |= AIC_CR_ERPL ) -+#define __aic_disable_replay() ( REG_AIC_CR &= ~AIC_CR_ERPL ) -+#define __aic_enable_loopback() ( REG_AIC_CR |= AIC_CR_ENLBF ) -+#define __aic_disable_loopback() ( REG_AIC_CR &= ~AIC_CR_ENLBF ) -+ -+#define __aic_flush_fifo() ( REG_AIC_CR |= AIC_CR_FLUSH ) -+#define __aic_unflush_fifo() ( REG_AIC_CR &= ~AIC_CR_FLUSH ) -+ -+#define __aic_enable_transmit_intr() \ -+ ( REG_AIC_CR |= (AIC_CR_ETFS | AIC_CR_ETUR) ) -+#define __aic_disable_transmit_intr() \ -+ ( REG_AIC_CR &= ~(AIC_CR_ETFS | AIC_CR_ETUR) ) -+#define __aic_enable_receive_intr() \ -+ ( REG_AIC_CR |= (AIC_CR_ERFS | AIC_CR_EROR) ) -+#define __aic_disable_receive_intr() \ -+ ( REG_AIC_CR &= ~(AIC_CR_ERFS | AIC_CR_EROR) ) -+ -+#define __aic_enable_transmit_dma() ( REG_AIC_CR |= AIC_CR_TDMS ) -+#define __aic_disable_transmit_dma() ( REG_AIC_CR &= ~AIC_CR_TDMS ) -+#define __aic_enable_receive_dma() ( REG_AIC_CR |= AIC_CR_RDMS ) -+#define __aic_disable_receive_dma() ( REG_AIC_CR &= ~AIC_CR_RDMS ) -+ -+#define __aic_enable_mono2stereo() ( REG_AIC_CR |= AIC_CR_M2S ) -+#define __aic_disable_mono2stereo() ( REG_AIC_CR &= ~AIC_CR_M2S ) -+#define __aic_enable_byteswap() ( REG_AIC_CR |= AIC_CR_ENDSW ) -+#define __aic_disable_byteswap() ( REG_AIC_CR &= ~AIC_CR_ENDSW ) -+#define __aic_enable_unsignadj() ( REG_AIC_CR |= AIC_CR_AVSTSU ) -+#define __aic_disable_unsignadj() ( REG_AIC_CR &= ~AIC_CR_AVSTSU ) -+ -+#define AC97_PCM_XS_L_FRONT AIC_ACCR1_XS_SLOT3 -+#define AC97_PCM_XS_R_FRONT AIC_ACCR1_XS_SLOT4 -+#define AC97_PCM_XS_CENTER AIC_ACCR1_XS_SLOT6 -+#define AC97_PCM_XS_L_SURR AIC_ACCR1_XS_SLOT7 -+#define AC97_PCM_XS_R_SURR AIC_ACCR1_XS_SLOT8 -+#define AC97_PCM_XS_LFE AIC_ACCR1_XS_SLOT9 -+ -+#define AC97_PCM_RS_L_FRONT AIC_ACCR1_RS_SLOT3 -+#define AC97_PCM_RS_R_FRONT AIC_ACCR1_RS_SLOT4 -+#define AC97_PCM_RS_CENTER AIC_ACCR1_RS_SLOT6 -+#define AC97_PCM_RS_L_SURR AIC_ACCR1_RS_SLOT7 -+#define AC97_PCM_RS_R_SURR AIC_ACCR1_RS_SLOT8 -+#define AC97_PCM_RS_LFE AIC_ACCR1_RS_SLOT9 -+ -+#define __ac97_set_xs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK ) -+#define __ac97_set_xs_mono() \ -+do { \ -+ REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \ -+ REG_AIC_ACCR1 |= AC97_PCM_XS_R_FRONT; \ -+} while(0) -+#define __ac97_set_xs_stereo() \ -+do { \ -+ REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \ -+ REG_AIC_ACCR1 |= AC97_PCM_XS_L_FRONT | AC97_PCM_XS_R_FRONT; \ -+} while(0) -+ -+/* In fact, only stereo is support now. */ -+#define __ac97_set_rs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK ) -+#define __ac97_set_rs_mono() \ -+do { \ -+ REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \ -+ REG_AIC_ACCR1 |= AC97_PCM_RS_R_FRONT; \ -+} while(0) -+#define __ac97_set_rs_stereo() \ -+do { \ -+ REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \ -+ REG_AIC_ACCR1 |= AC97_PCM_RS_L_FRONT | AC97_PCM_RS_R_FRONT; \ -+} while(0) -+ -+#define __ac97_warm_reset_codec() \ -+ do { \ -+ REG_AIC_ACCR2 |= AIC_ACCR2_SA; \ -+ REG_AIC_ACCR2 |= AIC_ACCR2_SS; \ -+ udelay(2); \ -+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SS; \ -+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SA; \ -+ } while (0) -+ -+#define __ac97_cold_reset_codec() \ -+ do { \ -+ REG_AIC_ACCR2 |= AIC_ACCR2_SR; \ -+ udelay(2); \ -+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SR; \ -+ } while (0) -+ -+/* n=8,16,18,20 */ -+#define __ac97_set_iass(n) \ -+ ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_IASS_MASK) | AIC_ACCR2_IASS_##n##BIT ) -+#define __ac97_set_oass(n) \ -+ ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_OASS_MASK) | AIC_ACCR2_OASS_##n##BIT ) -+ -+#define __i2s_select_i2s() ( REG_AIC_I2SCR &= ~AIC_I2SCR_AMSL ) -+#define __i2s_select_msbjustified() ( REG_AIC_I2SCR |= AIC_I2SCR_AMSL ) -+ -+/* n=8,16,18,20,24 */ -+/*#define __i2s_set_sample_size(n) \ -+ ( REG_AIC_I2SCR |= (REG_AIC_I2SCR & ~AIC_I2SCR_WL_MASK) | AIC_I2SCR_WL_##n##BIT )*/ -+ -+#define __i2s_set_oss_sample_size(n) \ -+ ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_OSS_MASK) | AIC_CR_OSS_##n##BIT ) -+#define __i2s_set_iss_sample_size(n) \ -+ ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_ISS_MASK) | AIC_CR_ISS_##n##BIT ) -+ -+#define __i2s_stop_bitclk() ( REG_AIC_I2SCR |= AIC_I2SCR_STPBK ) -+#define __i2s_start_bitclk() ( REG_AIC_I2SCR &= ~AIC_I2SCR_STPBK ) -+ -+#define __aic_transmit_request() ( REG_AIC_SR & AIC_SR_TFS ) -+#define __aic_receive_request() ( REG_AIC_SR & AIC_SR_RFS ) -+#define __aic_transmit_underrun() ( REG_AIC_SR & AIC_SR_TUR ) -+#define __aic_receive_overrun() ( REG_AIC_SR & AIC_SR_ROR ) -+ -+#define __aic_clear_errors() ( REG_AIC_SR &= ~(AIC_SR_TUR | AIC_SR_ROR) ) -+ -+#define __aic_get_transmit_resident() \ -+ ( (REG_AIC_SR & AIC_SR_TFL_MASK) >> AIC_SR_TFL_BIT ) -+#define __aic_get_receive_count() \ -+ ( (REG_AIC_SR & AIC_SR_RFL_MASK) >> AIC_SR_RFL_BIT ) -+ -+#define __ac97_command_transmitted() ( REG_AIC_ACSR & AIC_ACSR_CADT ) -+#define __ac97_status_received() ( REG_AIC_ACSR & AIC_ACSR_SADR ) -+#define __ac97_status_receive_timeout() ( REG_AIC_ACSR & AIC_ACSR_RSTO ) -+#define __ac97_codec_is_low_power_mode() ( REG_AIC_ACSR & AIC_ACSR_CLPM ) -+#define __ac97_codec_is_ready() ( REG_AIC_ACSR & AIC_ACSR_CRDY ) -+#define __ac97_slot_error_detected() ( REG_AIC_ACSR & AIC_ACSR_SLTERR ) -+#define __ac97_clear_slot_error() ( REG_AIC_ACSR &= ~AIC_ACSR_SLTERR ) -+ -+#define __i2s_is_busy() ( REG_AIC_I2SSR & AIC_I2SSR_BSY ) -+ -+#define CODEC_READ_CMD (1 << 19) -+#define CODEC_WRITE_CMD (0 << 19) -+#define CODEC_REG_INDEX_BIT 12 -+#define CODEC_REG_INDEX_MASK (0x7f << CODEC_REG_INDEX_BIT) /* 18:12 */ -+#define CODEC_REG_DATA_BIT 4 -+#define CODEC_REG_DATA_MASK (0x0ffff << 4) /* 19:4 */ -+ -+#define __ac97_out_rcmd_addr(reg) \ -+do { \ -+ REG_AIC_ACCAR = CODEC_READ_CMD | ((reg) << CODEC_REG_INDEX_BIT); \ -+} while (0) -+ -+#define __ac97_out_wcmd_addr(reg) \ -+do { \ -+ REG_AIC_ACCAR = CODEC_WRITE_CMD | ((reg) << CODEC_REG_INDEX_BIT); \ -+} while (0) -+ -+#define __ac97_out_data(value) \ -+do { \ -+ REG_AIC_ACCDR = ((value) << CODEC_REG_DATA_BIT); \ -+} while (0) -+ -+#define __ac97_in_data() \ -+ ( (REG_AIC_ACSDR & CODEC_REG_DATA_MASK) >> CODEC_REG_DATA_BIT ) -+ -+#define __ac97_in_status_addr() \ -+ ( (REG_AIC_ACSAR & CODEC_REG_INDEX_MASK) >> CODEC_REG_INDEX_BIT ) -+ -+#define __i2s_set_sample_rate(i2sclk, sync) \ -+ ( REG_AIC_I2SDIV = ((i2sclk) / (4*64)) / (sync) ) -+ -+#define __aic_write_tfifo(v) ( REG_AIC_DR = (v) ) -+#define __aic_read_rfifo() ( REG_AIC_DR ) -+ -+#define __aic_internal_codec() ( REG_AIC_FR |= AIC_FR_ICDC ) -+#define __aic_external_codec() ( REG_AIC_FR &= ~AIC_FR_ICDC ) -+ -+// -+// Define next ops for AC97 compatible -+// -+ -+#define AC97_ACSR AIC_ACSR -+ -+#define __ac97_enable() __aic_enable(); __aic_select_ac97() -+#define __ac97_disable() __aic_disable() -+#define __ac97_reset() __aic_reset() -+ -+#define __ac97_set_transmit_trigger(n) __aic_set_transmit_trigger(n) -+#define __ac97_set_receive_trigger(n) __aic_set_receive_trigger(n) -+ -+#define __ac97_enable_record() __aic_enable_record() -+#define __ac97_disable_record() __aic_disable_record() -+#define __ac97_enable_replay() __aic_enable_replay() -+#define __ac97_disable_replay() __aic_disable_replay() -+#define __ac97_enable_loopback() __aic_enable_loopback() -+#define __ac97_disable_loopback() __aic_disable_loopback() -+ -+#define __ac97_enable_transmit_dma() __aic_enable_transmit_dma() -+#define __ac97_disable_transmit_dma() __aic_disable_transmit_dma() -+#define __ac97_enable_receive_dma() __aic_enable_receive_dma() -+#define __ac97_disable_receive_dma() __aic_disable_receive_dma() -+ -+#define __ac97_transmit_request() __aic_transmit_request() -+#define __ac97_receive_request() __aic_receive_request() -+#define __ac97_transmit_underrun() __aic_transmit_underrun() -+#define __ac97_receive_overrun() __aic_receive_overrun() -+ -+#define __ac97_clear_errors() __aic_clear_errors() -+ -+#define __ac97_get_transmit_resident() __aic_get_transmit_resident() -+#define __ac97_get_receive_count() __aic_get_receive_count() -+ -+#define __ac97_enable_transmit_intr() __aic_enable_transmit_intr() -+#define __ac97_disable_transmit_intr() __aic_disable_transmit_intr() -+#define __ac97_enable_receive_intr() __aic_enable_receive_intr() -+#define __ac97_disable_receive_intr() __aic_disable_receive_intr() -+ -+#define __ac97_write_tfifo(v) __aic_write_tfifo(v) -+#define __ac97_read_rfifo() __aic_read_rfifo() -+ -+// -+// Define next ops for I2S compatible -+// -+ -+#define I2S_ACSR AIC_I2SSR -+ -+#define __i2s_enable() __aic_enable(); __aic_select_i2s() -+#define __i2s_disable() __aic_disable() -+#define __i2s_reset() __aic_reset() -+ -+#define __i2s_set_transmit_trigger(n) __aic_set_transmit_trigger(n) -+#define __i2s_set_receive_trigger(n) __aic_set_receive_trigger(n) -+ -+#define __i2s_enable_record() __aic_enable_record() -+#define __i2s_disable_record() __aic_disable_record() -+#define __i2s_enable_replay() __aic_enable_replay() -+#define __i2s_disable_replay() __aic_disable_replay() -+#define __i2s_enable_loopback() __aic_enable_loopback() -+#define __i2s_disable_loopback() __aic_disable_loopback() -+ -+#define __i2s_enable_transmit_dma() __aic_enable_transmit_dma() -+#define __i2s_disable_transmit_dma() __aic_disable_transmit_dma() -+#define __i2s_enable_receive_dma() __aic_enable_receive_dma() -+#define __i2s_disable_receive_dma() __aic_disable_receive_dma() -+ -+#define __i2s_transmit_request() __aic_transmit_request() -+#define __i2s_receive_request() __aic_receive_request() -+#define __i2s_transmit_underrun() __aic_transmit_underrun() -+#define __i2s_receive_overrun() __aic_receive_overrun() -+ -+#define __i2s_clear_errors() __aic_clear_errors() -+ -+#define __i2s_get_transmit_resident() __aic_get_transmit_resident() -+#define __i2s_get_receive_count() __aic_get_receive_count() -+ -+#define __i2s_enable_transmit_intr() __aic_enable_transmit_intr() -+#define __i2s_disable_transmit_intr() __aic_disable_transmit_intr() -+#define __i2s_enable_receive_intr() __aic_enable_receive_intr() -+#define __i2s_disable_receive_intr() __aic_disable_receive_intr() -+ -+#define __i2s_write_tfifo(v) __aic_write_tfifo(v) -+#define __i2s_read_rfifo() __aic_read_rfifo() -+ -+#define __i2s_reset_codec() \ -+ do { \ -+ } while (0) -+ -+ -+/*************************************************************************** -+ * ICDC -+ ***************************************************************************/ -+#define __i2s_internal_codec() __aic_internal_codec() -+#define __i2s_external_codec() __aic_external_codec() -+ -+/*************************************************************************** -+ * INTC -+ ***************************************************************************/ -+#define __intc_unmask_irq(n) ( REG_INTC_IMCR = (1 << (n)) ) -+#define __intc_mask_irq(n) ( REG_INTC_IMSR = (1 << (n)) ) -+#define __intc_ack_irq(n) ( REG_INTC_IPR = (1 << (n)) ) -+ -+ -+/*************************************************************************** -+ * I2C -+ ***************************************************************************/ -+ -+#define __i2c_enable() ( REG_I2C_CR |= I2C_CR_I2CE ) -+#define __i2c_disable() ( REG_I2C_CR &= ~I2C_CR_I2CE ) -+ -+#define __i2c_send_start() ( REG_I2C_CR |= I2C_CR_STA ) -+#define __i2c_send_stop() ( REG_I2C_CR |= I2C_CR_STO ) -+#define __i2c_send_ack() ( REG_I2C_CR &= ~I2C_CR_AC ) -+#define __i2c_send_nack() ( REG_I2C_CR |= I2C_CR_AC ) -+ -+#define __i2c_set_drf() ( REG_I2C_SR |= I2C_SR_DRF ) -+#define __i2c_clear_drf() ( REG_I2C_SR &= ~I2C_SR_DRF ) -+#define __i2c_check_drf() ( REG_I2C_SR & I2C_SR_DRF ) -+ -+#define __i2c_received_ack() ( !(REG_I2C_SR & I2C_SR_ACKF) ) -+#define __i2c_is_busy() ( REG_I2C_SR & I2C_SR_BUSY ) -+#define __i2c_transmit_ended() ( REG_I2C_SR & I2C_SR_TEND ) -+ -+#define __i2c_set_clk(dev_clk, i2c_clk) \ -+ ( REG_I2C_GR = (dev_clk) / (16*(i2c_clk)) - 1 ) -+ -+#define __i2c_read() ( REG_I2C_DR ) -+#define __i2c_write(val) ( REG_I2C_DR = (val) ) -+ -+ -+/*************************************************************************** -+ * MSC -+ ***************************************************************************/ -+ -+#define __msc_start_op() \ -+ ( REG_MSC_STRPCL = MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START ) -+ -+#define __msc_set_resto(to) ( REG_MSC_RESTO = to ) -+#define __msc_set_rdto(to) ( REG_MSC_RDTO = to ) -+#define __msc_set_cmd(cmd) ( REG_MSC_CMD = cmd ) -+#define __msc_set_arg(arg) ( REG_MSC_ARG = arg ) -+#define __msc_set_nob(nob) ( REG_MSC_NOB = nob ) -+#define __msc_get_nob() ( REG_MSC_NOB ) -+#define __msc_set_blklen(len) ( REG_MSC_BLKLEN = len ) -+#define __msc_set_cmdat(cmdat) ( REG_MSC_CMDAT = cmdat ) -+#define __msc_set_cmdat_ioabort() ( REG_MSC_CMDAT |= MSC_CMDAT_IO_ABORT ) -+#define __msc_clear_cmdat_ioabort() ( REG_MSC_CMDAT &= ~MSC_CMDAT_IO_ABORT ) -+ -+#define __msc_set_cmdat_bus_width1() \ -+do { \ -+ REG_MSC_CMDAT &= ~MSC_CMDAT_BUS_WIDTH_MASK; \ -+ REG_MSC_CMDAT |= MSC_CMDAT_BUS_WIDTH_1BIT; \ -+} while(0) -+ -+#define __msc_set_cmdat_bus_width4() \ -+do { \ -+ REG_MSC_CMDAT &= ~MSC_CMDAT_BUS_WIDTH_MASK; \ -+ REG_MSC_CMDAT |= MSC_CMDAT_BUS_WIDTH_4BIT; \ -+} while(0) -+ -+#define __msc_set_cmdat_dma_en() ( REG_MSC_CMDAT |= MSC_CMDAT_DMA_EN ) -+#define __msc_set_cmdat_init() ( REG_MSC_CMDAT |= MSC_CMDAT_INIT ) -+#define __msc_set_cmdat_busy() ( REG_MSC_CMDAT |= MSC_CMDAT_BUSY ) -+#define __msc_set_cmdat_stream() ( REG_MSC_CMDAT |= MSC_CMDAT_STREAM_BLOCK ) -+#define __msc_set_cmdat_block() ( REG_MSC_CMDAT &= ~MSC_CMDAT_STREAM_BLOCK ) -+#define __msc_set_cmdat_read() ( REG_MSC_CMDAT &= ~MSC_CMDAT_WRITE_READ ) -+#define __msc_set_cmdat_write() ( REG_MSC_CMDAT |= MSC_CMDAT_WRITE_READ ) -+#define __msc_set_cmdat_data_en() ( REG_MSC_CMDAT |= MSC_CMDAT_DATA_EN ) -+ -+/* r is MSC_CMDAT_RESPONSE_FORMAT_Rx or MSC_CMDAT_RESPONSE_FORMAT_NONE */ -+#define __msc_set_cmdat_res_format(r) \ -+do { \ -+ REG_MSC_CMDAT &= ~MSC_CMDAT_RESPONSE_FORMAT_MASK; \ -+ REG_MSC_CMDAT |= (r); \ -+} while(0) -+ -+#define __msc_clear_cmdat() \ -+ REG_MSC_CMDAT &= ~( MSC_CMDAT_IO_ABORT | MSC_CMDAT_DMA_EN | MSC_CMDAT_INIT| \ -+ MSC_CMDAT_BUSY | MSC_CMDAT_STREAM_BLOCK | MSC_CMDAT_WRITE_READ | \ -+ MSC_CMDAT_DATA_EN | MSC_CMDAT_RESPONSE_FORMAT_MASK ) -+ -+#define __msc_get_imask() ( REG_MSC_IMASK ) -+#define __msc_mask_all_intrs() ( REG_MSC_IMASK = 0xff ) -+#define __msc_unmask_all_intrs() ( REG_MSC_IMASK = 0x00 ) -+#define __msc_mask_rd() ( REG_MSC_IMASK |= MSC_IMASK_RXFIFO_RD_REQ ) -+#define __msc_unmask_rd() ( REG_MSC_IMASK &= ~MSC_IMASK_RXFIFO_RD_REQ ) -+#define __msc_mask_wr() ( REG_MSC_IMASK |= MSC_IMASK_TXFIFO_WR_REQ ) -+#define __msc_unmask_wr() ( REG_MSC_IMASK &= ~MSC_IMASK_TXFIFO_WR_REQ ) -+#define __msc_mask_endcmdres() ( REG_MSC_IMASK |= MSC_IMASK_END_CMD_RES ) -+#define __msc_unmask_endcmdres() ( REG_MSC_IMASK &= ~MSC_IMASK_END_CMD_RES ) -+#define __msc_mask_datatrandone() ( REG_MSC_IMASK |= MSC_IMASK_DATA_TRAN_DONE ) -+#define __msc_unmask_datatrandone() ( REG_MSC_IMASK &= ~MSC_IMASK_DATA_TRAN_DONE ) -+#define __msc_mask_prgdone() ( REG_MSC_IMASK |= MSC_IMASK_PRG_DONE ) -+#define __msc_unmask_prgdone() ( REG_MSC_IMASK &= ~MSC_IMASK_PRG_DONE ) -+ -+/* n=0,1,2,3,4,5,6,7 */ -+#define __msc_set_clkrt(n) \ -+do { \ -+ REG_MSC_CLKRT = n; \ -+} while(0) -+ -+#define __msc_get_ireg() ( REG_MSC_IREG ) -+#define __msc_ireg_rd() ( REG_MSC_IREG & MSC_IREG_RXFIFO_RD_REQ ) -+#define __msc_ireg_wr() ( REG_MSC_IREG & MSC_IREG_TXFIFO_WR_REQ ) -+#define __msc_ireg_end_cmd_res() ( REG_MSC_IREG & MSC_IREG_END_CMD_RES ) -+#define __msc_ireg_data_tran_done() ( REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE ) -+#define __msc_ireg_prg_done() ( REG_MSC_IREG & MSC_IREG_PRG_DONE ) -+#define __msc_ireg_clear_end_cmd_res() ( REG_MSC_IREG = MSC_IREG_END_CMD_RES ) -+#define __msc_ireg_clear_data_tran_done() ( REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE ) -+#define __msc_ireg_clear_prg_done() ( REG_MSC_IREG = MSC_IREG_PRG_DONE ) -+ -+#define __msc_get_stat() ( REG_MSC_STAT ) -+#define __msc_stat_not_end_cmd_res() ( (REG_MSC_STAT & MSC_STAT_END_CMD_RES) == 0) -+#define __msc_stat_crc_err() \ -+ ( REG_MSC_STAT & (MSC_STAT_CRC_RES_ERR | MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR_YES) ) -+#define __msc_stat_res_crc_err() ( REG_MSC_STAT & MSC_STAT_CRC_RES_ERR ) -+#define __msc_stat_rd_crc_err() ( REG_MSC_STAT & MSC_STAT_CRC_READ_ERROR ) -+#define __msc_stat_wr_crc_err() ( REG_MSC_STAT & MSC_STAT_CRC_WRITE_ERROR_YES ) -+#define __msc_stat_resto_err() ( REG_MSC_STAT & MSC_STAT_TIME_OUT_RES ) -+#define __msc_stat_rdto_err() ( REG_MSC_STAT & MSC_STAT_TIME_OUT_READ ) -+ -+#define __msc_rd_resfifo() ( REG_MSC_RES ) -+#define __msc_rd_rxfifo() ( REG_MSC_RXFIFO ) -+#define __msc_wr_txfifo(v) ( REG_MSC_TXFIFO = v ) -+ -+#define __msc_reset() \ -+do { \ -+ REG_MSC_STRPCL = MSC_STRPCL_RESET; \ -+ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \ -+} while (0) -+ -+#define __msc_start_clk() \ -+do { \ -+ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START; \ -+} while (0) -+ -+#define __msc_stop_clk() \ -+do { \ -+ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; \ -+} while (0) -+ -+#define MMC_CLK 19169200 -+#define SD_CLK 24576000 -+ -+/* msc_clk should little than pclk and little than clk retrieve from card */ -+#define __msc_calc_clk_divisor(type,dev_clk,msc_clk,lv) \ -+do { \ -+ unsigned int rate, pclk, i; \ -+ pclk = dev_clk; \ -+ rate = type?SD_CLK:MMC_CLK; \ -+ if (msc_clk && msc_clk < pclk) \ -+ pclk = msc_clk; \ -+ i = 0; \ -+ while (pclk < rate) \ -+ { \ -+ i ++; \ -+ rate >>= 1; \ -+ } \ -+ lv = i; \ -+} while(0) -+ -+/* divide rate to little than or equal to 400kHz */ -+#define __msc_calc_slow_clk_divisor(type, lv) \ -+do { \ -+ unsigned int rate, i; \ -+ rate = (type?SD_CLK:MMC_CLK)/1000/400; \ -+ i = 0; \ -+ while (rate > 0) \ -+ { \ -+ rate >>= 1; \ -+ i ++; \ -+ } \ -+ lv = i; \ -+} while(0) -+ -+ -+/*************************************************************************** -+ * SSI -+ ***************************************************************************/ -+ -+#define __ssi_enable() ( REG_SSI_CR0 |= SSI_CR0_SSIE ) -+#define __ssi_disable() ( REG_SSI_CR0 &= ~SSI_CR0_SSIE ) -+#define __ssi_select_ce() ( REG_SSI_CR0 &= ~SSI_CR0_FSEL ) -+ -+#define __ssi_normal_mode() ( REG_SSI_ITR &= ~SSI_ITR_IVLTM_MASK ) -+ -+#define __ssi_select_ce2() \ -+do { \ -+ REG_SSI_CR0 |= SSI_CR0_FSEL; \ -+ REG_SSI_CR1 &= ~SSI_CR1_MULTS; \ -+} while (0) -+ -+#define __ssi_select_gpc() \ -+do { \ -+ REG_SSI_CR0 &= ~SSI_CR0_FSEL; \ -+ REG_SSI_CR1 |= SSI_CR1_MULTS; \ -+} while (0) -+ -+#define __ssi_enable_tx_intr() \ -+ ( REG_SSI_CR0 |= SSI_CR0_TIE | SSI_CR0_TEIE ) -+ -+#define __ssi_disable_tx_intr() \ -+ ( REG_SSI_CR0 &= ~(SSI_CR0_TIE | SSI_CR0_TEIE) ) -+ -+#define __ssi_enable_rx_intr() \ -+ ( REG_SSI_CR0 |= SSI_CR0_RIE | SSI_CR0_REIE ) -+ -+#define __ssi_disable_rx_intr() \ -+ ( REG_SSI_CR0 &= ~(SSI_CR0_RIE | SSI_CR0_REIE) ) -+ -+#define __ssi_enable_txfifo_half_empty_intr() \ -+ ( REG_SSI_CR0 |= SSI_CR0_TIE ) -+#define __ssi_disable_txfifo_half_empty_intr() \ -+ ( REG_SSI_CR0 &= ~SSI_CR0_TIE ) -+#define __ssi_enable_tx_error_intr() \ -+ ( REG_SSI_CR0 |= SSI_CR0_TEIE ) -+#define __ssi_disable_tx_error_intr() \ -+ ( REG_SSI_CR0 &= ~SSI_CR0_TEIE ) -+ -+#define __ssi_enable_rxfifo_half_full_intr() \ -+ ( REG_SSI_CR0 |= SSI_CR0_RIE ) -+#define __ssi_disable_rxfifo_half_full_intr() \ -+ ( REG_SSI_CR0 &= ~SSI_CR0_RIE ) -+#define __ssi_enable_rx_error_intr() \ -+ ( REG_SSI_CR0 |= SSI_CR0_REIE ) -+#define __ssi_disable_rx_error_intr() \ -+ ( REG_SSI_CR0 &= ~SSI_CR0_REIE ) -+ -+#define __ssi_enable_loopback() ( REG_SSI_CR0 |= SSI_CR0_LOOP ) -+#define __ssi_disable_loopback() ( REG_SSI_CR0 &= ~SSI_CR0_LOOP ) -+ -+#define __ssi_enable_receive() ( REG_SSI_CR0 &= ~SSI_CR0_DISREV ) -+#define __ssi_disable_receive() ( REG_SSI_CR0 |= SSI_CR0_DISREV ) -+ -+#define __ssi_finish_receive() \ -+ ( REG_SSI_CR0 |= (SSI_CR0_RFINE | SSI_CR0_RFINC) ) -+ -+#define __ssi_disable_recvfinish() \ -+ ( REG_SSI_CR0 &= ~(SSI_CR0_RFINE | SSI_CR0_RFINC) ) -+ -+#define __ssi_flush_txfifo() ( REG_SSI_CR0 |= SSI_CR0_TFLUSH ) -+#define __ssi_flush_rxfifo() ( REG_SSI_CR0 |= SSI_CR0_RFLUSH ) -+ -+#define __ssi_flush_fifo() \ -+ ( REG_SSI_CR0 |= SSI_CR0_TFLUSH | SSI_CR0_RFLUSH ) -+ -+#define __ssi_finish_transmit() ( REG_SSI_CR1 &= ~SSI_CR1_UNFIN ) -+#define __ssi_wait_transmit() ( REG_SSI_CR1 |= SSI_CR1_UNFIN ) -+ -+#define __ssi_spi_format() \ -+do { \ -+ REG_SSI_CR1 &= ~SSI_CR1_FMAT_MASK; \ -+ REG_SSI_CR1 |= SSI_CR1_FMAT_SPI; \ -+ REG_SSI_CR1 &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK);\ -+ REG_SSI_CR1 |= (SSI_CR1_TFVCK_1 | SSI_CR1_TCKFI_1); \ -+} while (0) -+ -+/* TI's SSP format, must clear SSI_CR1.UNFIN */ -+#define __ssi_ssp_format() \ -+do { \ -+ REG_SSI_CR1 &= ~(SSI_CR1_FMAT_MASK | SSI_CR1_UNFIN); \ -+ REG_SSI_CR1 |= SSI_CR1_FMAT_SSP; \ -+} while (0) -+ -+/* National's Microwire format, must clear SSI_CR0.RFINE, and set max delay */ -+#define __ssi_microwire_format() \ -+do { \ -+ REG_SSI_CR1 &= ~SSI_CR1_FMAT_MASK; \ -+ REG_SSI_CR1 |= SSI_CR1_FMAT_MW1; \ -+ REG_SSI_CR1 &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK);\ -+ REG_SSI_CR1 |= (SSI_CR1_TFVCK_3 | SSI_CR1_TCKFI_3); \ -+ REG_SSI_CR0 &= ~SSI_CR0_RFINE; \ -+} while (0) -+ -+/* CE# level (FRMHL), CE# in interval time (ITFRM), -+ clock phase and polarity (PHA POL), -+ interval time (SSIITR), interval characters/frame (SSIICR) */ -+ -+ /* frmhl,endian,mcom,flen,pha,pol MASK */ -+#define SSICR1_MISC_MASK \ -+ ( SSI_CR1_FRMHL_MASK | SSI_CR1_LFST | SSI_CR1_MCOM_MASK \ -+ | SSI_CR1_FLEN_MASK | SSI_CR1_PHA | SSI_CR1_POL ) \ -+ -+#define __ssi_spi_set_misc(frmhl,endian,flen,mcom,pha,pol) \ -+do { \ -+ REG_SSI_CR1 &= ~SSICR1_MISC_MASK; \ -+ REG_SSI_CR1 |= ((frmhl) << 30) | ((endian) << 25) | \ -+ (((mcom) - 1) << 12) | (((flen) - 2) << 4) | \ -+ ((pha) << 1) | (pol); \ -+} while(0) -+ -+/* Transfer with MSB or LSB first */ -+#define __ssi_set_msb() ( REG_SSI_CR1 &= ~SSI_CR1_LFST ) -+#define __ssi_set_lsb() ( REG_SSI_CR1 |= SSI_CR1_LFST ) -+ -+#define __ssi_set_frame_length(n) \ -+ REG_SSI_CR1 = (REG_SSI_CR1 & ~SSI_CR1_FLEN_MASK) | (((n) - 2) << 4) -+ -+/* n = 1 - 16 */ -+#define __ssi_set_microwire_command_length(n) \ -+ ( REG_SSI_CR1 = ((REG_SSI_CR1 & ~SSI_CR1_MCOM_MASK) | SSI_CR1_MCOM_##n##BIT) ) -+ -+/* Set the clock phase for SPI */ -+#define __ssi_set_spi_clock_phase(n) \ -+ ( REG_SSI_CR1 = ((REG_SSI_CR1 & ~SSI_CR1_PHA) | ((n&0x1)<< 1))) -+ -+/* Set the clock polarity for SPI */ -+#define __ssi_set_spi_clock_polarity(n) \ -+ ( REG_SSI_CR1 = ((REG_SSI_CR1 & ~SSI_CR1_POL) | (n&0x1)) ) -+ -+/* n = ix8 */ -+#define __ssi_set_tx_trigger(n) \ -+do { \ -+ REG_SSI_CR1 &= ~SSI_CR1_TTRG_MASK; \ -+ REG_SSI_CR1 |= (n/8)<<SSI_CR1_TTRG_BIT; \ -+} while (0) -+ -+/* n = ix8 */ -+#define __ssi_set_rx_trigger(n) \ -+do { \ -+ REG_SSI_CR1 &= ~SSI_CR1_RTRG_MASK; \ -+ REG_SSI_CR1 |= (n/8)<<SSI_CR1_RTRG_BIT; \ -+} while (0) -+ -+#define __ssi_get_txfifo_count() \ -+ ( (REG_SSI_SR & SSI_SR_TFIFONUM_MASK) >> SSI_SR_TFIFONUM_BIT ) -+ -+#define __ssi_get_rxfifo_count() \ -+ ( (REG_SSI_SR & SSI_SR_RFIFONUM_MASK) >> SSI_SR_RFIFONUM_BIT ) -+ -+#define __ssi_transfer_end() ( REG_SSI_SR & SSI_SR_END ) -+#define __ssi_is_busy() ( REG_SSI_SR & SSI_SR_BUSY ) -+ -+#define __ssi_txfifo_full() ( REG_SSI_SR & SSI_SR_TFF ) -+#define __ssi_rxfifo_empty() ( REG_SSI_SR & SSI_SR_RFE ) -+#define __ssi_rxfifo_half_full() ( REG_SSI_SR & SSI_SR_RFHF ) -+#define __ssi_txfifo_half_empty() ( REG_SSI_SR & SSI_SR_TFHE ) -+#define __ssi_underrun() ( REG_SSI_SR & SSI_SR_UNDR ) -+#define __ssi_overrun() ( REG_SSI_SR & SSI_SR_OVER ) -+#define __ssi_clear_underrun() ( REG_SSI_SR = ~SSI_SR_UNDR ) -+#define __ssi_clear_overrun() ( REG_SSI_SR = ~SSI_SR_OVER ) -+#define __ssi_clear_errors() \ -+ ( REG_SSI_SR &= ~(SSI_SR_UNDR | SSI_SR_OVER) ) -+ -+ -+#define __ssi_set_clk(dev_clk, ssi_clk) \ -+ ( REG_SSI_GR = (dev_clk) / (2*(ssi_clk)) - 1 ) -+ -+#define __ssi_receive_data() REG_SSI_DR -+#define __ssi_transmit_data(v) ( REG_SSI_DR = (v) ) -+ -+ -+/*************************************************************************** -+ * CIM -+ ***************************************************************************/ -+ -+#define __cim_enable() ( REG_CIM_CTRL |= CIM_CTRL_ENA ) -+#define __cim_disable() ( REG_CIM_CTRL &= ~CIM_CTRL_ENA ) -+ -+#define __cim_input_data_inverse() ( REG_CIM_CFG |= CIM_CFG_INV_DAT ) -+#define __cim_input_data_normal() ( REG_CIM_CFG &= ~CIM_CFG_INV_DAT ) -+ -+#define __cim_vsync_active_low() ( REG_CIM_CFG |= CIM_CFG_VSP ) -+#define __cim_vsync_active_high() ( REG_CIM_CFG &= ~CIM_CFG_VSP ) -+ -+#define __cim_hsync_active_low() ( REG_CIM_CFG |= CIM_CFG_HSP ) -+#define __cim_hsync_active_high() ( REG_CIM_CFG &= ~CIM_CFG_HSP ) -+ -+#define __cim_sample_data_at_pclk_falling_edge() \ -+ ( REG_CIM_CFG |= CIM_CFG_PCP ) -+#define __cim_sample_data_at_pclk_rising_edge() \ -+ ( REG_CIM_CFG &= ~CIM_CFG_PCP ) -+ -+#define __cim_enable_dummy_zero() ( REG_CIM_CFG |= CIM_CFG_DUMMY_ZERO ) -+#define __cim_disable_dummy_zero() ( REG_CIM_CFG &= ~CIM_CFG_DUMMY_ZERO ) -+ -+#define __cim_select_external_vsync() ( REG_CIM_CFG |= CIM_CFG_EXT_VSYNC ) -+#define __cim_select_internal_vsync() ( REG_CIM_CFG &= ~CIM_CFG_EXT_VSYNC ) -+ -+/* n=0-7 */ -+#define __cim_set_data_packing_mode(n) \ -+do { \ -+ REG_CIM_CFG &= ~CIM_CFG_PACK_MASK; \ -+ REG_CIM_CFG |= (CIM_CFG_PACK_##n); \ -+} while (0) -+ -+#define __cim_enable_ccir656_progressive_mode() \ -+do { \ -+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \ -+ REG_CIM_CFG |= CIM_CFG_DSM_CPM; \ -+} while (0) -+ -+#define __cim_enable_ccir656_interlace_mode() \ -+do { \ -+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \ -+ REG_CIM_CFG |= CIM_CFG_DSM_CIM; \ -+} while (0) -+ -+#define __cim_enable_gated_clock_mode() \ -+do { \ -+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \ -+ REG_CIM_CFG |= CIM_CFG_DSM_GCM; \ -+} while (0) -+ -+#define __cim_enable_nongated_clock_mode() \ -+do { \ -+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \ -+ REG_CIM_CFG |= CIM_CFG_DSM_NGCM; \ -+} while (0) -+ -+/* sclk:system bus clock -+ * mclk: CIM master clock -+ */ -+#define __cim_set_master_clk(sclk, mclk) \ -+do { \ -+ REG_CIM_CTRL &= ~CIM_CTRL_MCLKDIV_MASK; \ -+ REG_CIM_CTRL |= (((sclk)/(mclk) - 1) << CIM_CTRL_MCLKDIV_BIT); \ -+} while (0) -+ -+#define __cim_enable_sof_intr() \ -+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_SOFM ) -+#define __cim_disable_sof_intr() \ -+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_SOFM ) -+ -+#define __cim_enable_eof_intr() \ -+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_EOFM ) -+#define __cim_disable_eof_intr() \ -+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EOFM ) -+ -+#define __cim_enable_stop_intr() \ -+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_STOPM ) -+#define __cim_disable_stop_intr() \ -+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_STOPM ) -+ -+#define __cim_enable_trig_intr() \ -+ ( REG_CIM_CTRL |= CIM_CTRL_RXF_TRIGM ) -+#define __cim_disable_trig_intr() \ -+ ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_TRIGM ) -+ -+#define __cim_enable_rxfifo_overflow_intr() \ -+ ( REG_CIM_CTRL |= CIM_CTRL_RXF_OFM ) -+#define __cim_disable_rxfifo_overflow_intr() \ -+ ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_OFM ) -+ -+/* n=1-16 */ -+#define __cim_set_frame_rate(n) \ -+do { \ -+ REG_CIM_CTRL &= ~CIM_CTRL_FRC_MASK; \ -+ REG_CIM_CTRL |= CIM_CTRL_FRC_##n; \ -+} while (0) -+ -+#define __cim_enable_dma() ( REG_CIM_CTRL |= CIM_CTRL_DMA_EN ) -+#define __cim_disable_dma() ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EN ) -+ -+#define __cim_reset_rxfifo() ( REG_CIM_CTRL |= CIM_CTRL_RXF_RST ) -+#define __cim_unreset_rxfifo() ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_RST ) -+ -+/* n=4,8,12,16,20,24,28,32 */ -+#define __cim_set_rxfifo_trigger(n) \ -+do { \ -+ REG_CIM_CTRL &= ~CIM_CTRL_RXF_TRIG_MASK; \ -+ REG_CIM_CTRL |= CIM_CTRL_RXF_TRIG_##n; \ -+} while (0) -+ -+#define __cim_clear_state() ( REG_CIM_STATE = 0 ) -+ -+#define __cim_disable_done() ( REG_CIM_STATE & CIM_STATE_VDD ) -+#define __cim_rxfifo_empty() ( REG_CIM_STATE & CIM_STATE_RXF_EMPTY ) -+#define __cim_rxfifo_reach_trigger() ( REG_CIM_STATE & CIM_STATE_RXF_TRIG ) -+#define __cim_rxfifo_overflow() ( REG_CIM_STATE & CIM_STATE_RXF_OF ) -+#define __cim_clear_rxfifo_overflow() ( REG_CIM_STATE &= ~CIM_STATE_RXF_OF ) -+#define __cim_dma_stop() ( REG_CIM_STATE & CIM_STATE_DMA_STOP ) -+#define __cim_dma_eof() ( REG_CIM_STATE & CIM_STATE_DMA_EOF ) -+#define __cim_dma_sof() ( REG_CIM_STATE & CIM_STATE_DMA_SOF ) -+ -+#define __cim_get_iid() ( REG_CIM_IID ) -+#define __cim_get_image_data() ( REG_CIM_RXFIFO ) -+#define __cim_get_dam_cmd() ( REG_CIM_CMD ) -+ -+#define __cim_set_da(a) ( REG_CIM_DA = (a) ) -+ -+/*************************************************************************** -+ * LCD -+ ***************************************************************************/ -+#define __lcd_as_smart_lcd() ( REG_LCD_CFG |= (1<<LCD_CFG_LCDPIN_BIT) ) -+#define __lcd_as_general_lcd() ( REG_LCD_CFG &= ~(1<<LCD_CFG_LCDPIN_BIT) ) -+ -+#define __lcd_set_dis() ( REG_LCD_CTRL |= LCD_CTRL_DIS ) -+#define __lcd_clr_dis() ( REG_LCD_CTRL &= ~LCD_CTRL_DIS ) -+ -+#define __lcd_set_ena() ( REG_LCD_CTRL |= LCD_CTRL_ENA ) -+#define __lcd_clr_ena() ( REG_LCD_CTRL &= ~LCD_CTRL_ENA ) -+ -+/* n=1,2,4,8,16 */ -+#define __lcd_set_bpp(n) \ -+ ( REG_LCD_CTRL = (REG_LCD_CTRL & ~LCD_CTRL_BPP_MASK) | LCD_CTRL_BPP_##n ) -+ -+/* n=4,8,16 */ -+#define __lcd_set_burst_length(n) \ -+do { \ -+ REG_LCD_CTRL &= ~LCD_CTRL_BST_MASK; \ -+ REG_LCD_CTRL |= LCD_CTRL_BST_n##; \ -+} while (0) -+ -+#define __lcd_select_rgb565() ( REG_LCD_CTRL &= ~LCD_CTRL_RGB555 ) -+#define __lcd_select_rgb555() ( REG_LCD_CTRL |= LCD_CTRL_RGB555 ) -+ -+#define __lcd_set_ofup() ( REG_LCD_CTRL |= LCD_CTRL_OFUP ) -+#define __lcd_clr_ofup() ( REG_LCD_CTRL &= ~LCD_CTRL_OFUP ) -+ -+/* n=2,4,16 */ -+#define __lcd_set_stn_frc(n) \ -+do { \ -+ REG_LCD_CTRL &= ~LCD_CTRL_FRC_MASK; \ -+ REG_LCD_CTRL |= LCD_CTRL_FRC_n##; \ -+} while (0) -+ -+ -+#define __lcd_pixel_endian_little() ( REG_LCD_CTRL |= LCD_CTRL_PEDN ) -+#define __lcd_pixel_endian_big() ( REG_LCD_CTRL &= ~LCD_CTRL_PEDN ) -+ -+#define __lcd_reverse_byte_endian() ( REG_LCD_CTRL |= LCD_CTRL_BEDN ) -+#define __lcd_normal_byte_endian() ( REG_LCD_CTRL &= ~LCD_CTRL_BEDN ) -+ -+#define __lcd_enable_eof_intr() ( REG_LCD_CTRL |= LCD_CTRL_EOFM ) -+#define __lcd_disable_eof_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_EOFM ) -+ -+#define __lcd_enable_sof_intr() ( REG_LCD_CTRL |= LCD_CTRL_SOFM ) -+#define __lcd_disable_sof_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_SOFM ) -+ -+#define __lcd_enable_ofu_intr() ( REG_LCD_CTRL |= LCD_CTRL_OFUM ) -+#define __lcd_disable_ofu_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_OFUM ) -+ -+#define __lcd_enable_ifu0_intr() ( REG_LCD_CTRL |= LCD_CTRL_IFUM0 ) -+#define __lcd_disable_ifu0_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_IFUM0 ) -+ -+#define __lcd_enable_ifu1_intr() ( REG_LCD_CTRL |= LCD_CTRL_IFUM1 ) -+#define __lcd_disable_ifu1_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_IFUM1 ) -+ -+#define __lcd_enable_ldd_intr() ( REG_LCD_CTRL |= LCD_CTRL_LDDM ) -+#define __lcd_disable_ldd_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_LDDM ) -+ -+#define __lcd_enable_qd_intr() ( REG_LCD_CTRL |= LCD_CTRL_QDM ) -+#define __lcd_disable_qd_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_QDM ) -+ -+ -+/* LCD status register indication */ -+ -+#define __lcd_quick_disable_done() ( REG_LCD_STATE & LCD_STATE_QD ) -+#define __lcd_disable_done() ( REG_LCD_STATE & LCD_STATE_LDD ) -+#define __lcd_infifo0_underrun() ( REG_LCD_STATE & LCD_STATE_IFU0 ) -+#define __lcd_infifo1_underrun() ( REG_LCD_STATE & LCD_STATE_IFU1 ) -+#define __lcd_outfifo_underrun() ( REG_LCD_STATE & LCD_STATE_OFU ) -+#define __lcd_start_of_frame() ( REG_LCD_STATE & LCD_STATE_SOF ) -+#define __lcd_end_of_frame() ( REG_LCD_STATE & LCD_STATE_EOF ) -+ -+#define __lcd_clr_outfifounderrun() ( REG_LCD_STATE &= ~LCD_STATE_OFU ) -+#define __lcd_clr_sof() ( REG_LCD_STATE &= ~LCD_STATE_SOF ) -+#define __lcd_clr_eof() ( REG_LCD_STATE &= ~LCD_STATE_EOF ) -+ -+#define __lcd_panel_white() ( REG_LCD_CFG |= LCD_CFG_WHITE ) -+#define __lcd_panel_black() ( REG_LCD_CFG &= ~LCD_CFG_WHITE ) -+ -+/* n=1,2,4,8 for single mono-STN -+ * n=4,8 for dual mono-STN -+ */ -+#define __lcd_set_panel_datawidth(n) \ -+do { \ -+ REG_LCD_CFG &= ~LCD_CFG_PDW_MASK; \ -+ REG_LCD_CFG |= LCD_CFG_PDW_n##; \ -+} while (0) -+ -+/* m=LCD_CFG_MODE_GENERUIC_TFT_xxx */ -+#define __lcd_set_panel_mode(m) \ -+do { \ -+ REG_LCD_CFG &= ~LCD_CFG_MODE_MASK; \ -+ REG_LCD_CFG |= (m); \ -+} while(0) -+ -+/* n = 0-255 */ -+#define __lcd_disable_ac_bias() ( REG_LCD_IO = 0xff ) -+#define __lcd_set_ac_bias(n) \ -+do { \ -+ REG_LCD_IO &= ~LCD_IO_ACB_MASK; \ -+ REG_LCD_IO |= ((n) << LCD_IO_ACB_BIT); \ -+} while(0) -+ -+#define __lcd_io_set_dir() ( REG_LCD_IO |= LCD_IO_DIR ) -+#define __lcd_io_clr_dir() ( REG_LCD_IO &= ~LCD_IO_DIR ) -+ -+#define __lcd_io_set_dep() ( REG_LCD_IO |= LCD_IO_DEP ) -+#define __lcd_io_clr_dep() ( REG_LCD_IO &= ~LCD_IO_DEP ) -+ -+#define __lcd_io_set_vsp() ( REG_LCD_IO |= LCD_IO_VSP ) -+#define __lcd_io_clr_vsp() ( REG_LCD_IO &= ~LCD_IO_VSP ) -+ -+#define __lcd_io_set_hsp() ( REG_LCD_IO |= LCD_IO_HSP ) -+#define __lcd_io_clr_hsp() ( REG_LCD_IO &= ~LCD_IO_HSP ) -+ -+#define __lcd_io_set_pcp() ( REG_LCD_IO |= LCD_IO_PCP ) -+#define __lcd_io_clr_pcp() ( REG_LCD_IO &= ~LCD_IO_PCP ) -+ -+#define __lcd_vsync_get_vps() \ -+ ( (REG_LCD_VSYNC & LCD_VSYNC_VPS_MASK) >> LCD_VSYNC_VPS_BIT ) -+ -+#define __lcd_vsync_get_vpe() \ -+ ( (REG_LCD_VSYNC & LCD_VSYNC_VPE_MASK) >> LCD_VSYNC_VPE_BIT ) -+#define __lcd_vsync_set_vpe(n) \ -+do { \ -+ REG_LCD_VSYNC &= ~LCD_VSYNC_VPE_MASK; \ -+ REG_LCD_VSYNC |= (n) << LCD_VSYNC_VPE_BIT; \ -+} while (0) -+ -+#define __lcd_hsync_get_hps() \ -+ ( (REG_LCD_HSYNC & LCD_HSYNC_HPS_MASK) >> LCD_HSYNC_HPS_BIT ) -+#define __lcd_hsync_set_hps(n) \ -+do { \ -+ REG_LCD_HSYNC &= ~LCD_HSYNC_HPS_MASK; \ -+ REG_LCD_HSYNC |= (n) << LCD_HSYNC_HPS_BIT; \ -+} while (0) -+ -+#define __lcd_hsync_get_hpe() \ -+ ( (REG_LCD_HSYNC & LCD_HSYNC_HPE_MASK) >> LCD_VSYNC_HPE_BIT ) -+#define __lcd_hsync_set_hpe(n) \ -+do { \ -+ REG_LCD_HSYNC &= ~LCD_HSYNC_HPE_MASK; \ -+ REG_LCD_HSYNC |= (n) << LCD_HSYNC_HPE_BIT; \ -+} while (0) -+ -+#define __lcd_vat_get_ht() \ -+ ( (REG_LCD_VAT & LCD_VAT_HT_MASK) >> LCD_VAT_HT_BIT ) -+#define __lcd_vat_set_ht(n) \ -+do { \ -+ REG_LCD_VAT &= ~LCD_VAT_HT_MASK; \ -+ REG_LCD_VAT |= (n) << LCD_VAT_HT_BIT; \ -+} while (0) -+ -+#define __lcd_vat_get_vt() \ -+ ( (REG_LCD_VAT & LCD_VAT_VT_MASK) >> LCD_VAT_VT_BIT ) -+#define __lcd_vat_set_vt(n) \ -+do { \ -+ REG_LCD_VAT &= ~LCD_VAT_VT_MASK; \ -+ REG_LCD_VAT |= (n) << LCD_VAT_VT_BIT; \ -+} while (0) -+ -+#define __lcd_dah_get_hds() \ -+ ( (REG_LCD_DAH & LCD_DAH_HDS_MASK) >> LCD_DAH_HDS_BIT ) -+#define __lcd_dah_set_hds(n) \ -+do { \ -+ REG_LCD_DAH &= ~LCD_DAH_HDS_MASK; \ -+ REG_LCD_DAH |= (n) << LCD_DAH_HDS_BIT; \ -+} while (0) -+ -+#define __lcd_dah_get_hde() \ -+ ( (REG_LCD_DAH & LCD_DAH_HDE_MASK) >> LCD_DAH_HDE_BIT ) -+#define __lcd_dah_set_hde(n) \ -+do { \ -+ REG_LCD_DAH &= ~LCD_DAH_HDE_MASK; \ -+ REG_LCD_DAH |= (n) << LCD_DAH_HDE_BIT; \ -+} while (0) -+ -+#define __lcd_dav_get_vds() \ -+ ( (REG_LCD_DAV & LCD_DAV_VDS_MASK) >> LCD_DAV_VDS_BIT ) -+#define __lcd_dav_set_vds(n) \ -+do { \ -+ REG_LCD_DAV &= ~LCD_DAV_VDS_MASK; \ -+ REG_LCD_DAV |= (n) << LCD_DAV_VDS_BIT; \ -+} while (0) -+ -+#define __lcd_dav_get_vde() \ -+ ( (REG_LCD_DAV & LCD_DAV_VDE_MASK) >> LCD_DAV_VDE_BIT ) -+#define __lcd_dav_set_vde(n) \ -+do { \ -+ REG_LCD_DAV &= ~LCD_DAV_VDE_MASK; \ -+ REG_LCD_DAV |= (n) << LCD_DAV_VDE_BIT; \ -+} while (0) -+ -+#define __lcd_cmd0_set_sofint() ( REG_LCD_CMD0 |= LCD_CMD_SOFINT ) -+#define __lcd_cmd0_clr_sofint() ( REG_LCD_CMD0 &= ~LCD_CMD_SOFINT ) -+#define __lcd_cmd1_set_sofint() ( REG_LCD_CMD1 |= LCD_CMD_SOFINT ) -+#define __lcd_cmd1_clr_sofint() ( REG_LCD_CMD1 &= ~LCD_CMD_SOFINT ) -+ -+#define __lcd_cmd0_set_eofint() ( REG_LCD_CMD0 |= LCD_CMD_EOFINT ) -+#define __lcd_cmd0_clr_eofint() ( REG_LCD_CMD0 &= ~LCD_CMD_EOFINT ) -+#define __lcd_cmd1_set_eofint() ( REG_LCD_CMD1 |= LCD_CMD_EOFINT ) -+#define __lcd_cmd1_clr_eofint() ( REG_LCD_CMD1 &= ~LCD_CMD_EOFINT ) -+ -+#define __lcd_cmd0_set_pal() ( REG_LCD_CMD0 |= LCD_CMD_PAL ) -+#define __lcd_cmd0_clr_pal() ( REG_LCD_CMD0 &= ~LCD_CMD_PAL ) -+ -+#define __lcd_cmd0_get_len() \ -+ ( (REG_LCD_CMD0 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT ) -+#define __lcd_cmd1_get_len() \ -+ ( (REG_LCD_CMD1 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT ) -+ -+/******************************************************* -+ * SMART LCD -+ *******************************************************/ -+ -+#define __slcd_dma_enable() (REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN) -+#define __slcd_dma_disable() \ -+do {\ -+ while (REG_SLCD_STATE & SLCD_STATE_BUSY); \ -+ REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN; \ -+} while(0) -+ -+/******************************************************* -+ * SMART LCD -+ *******************************************************/ -+ -+#define __slcd_dma_enable() (REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN) -+#define __slcd_dma_disable() \ -+do {\ -+ while (REG_SLCD_STATE & SLCD_STATE_BUSY); \ -+ REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN; \ -+} while(0) -+ -+/*************************************************************************** -+ * RTC ops -+ ***************************************************************************/ -+ -+#define __rtc_write_ready() ( (REG_RTC_RCR & RTC_RCR_WRDY) >> RTC_RCR_WRDY_BIT ) -+#define __rtc_enabled() ( REG_RTC_RCR |= RTC_RCR_RTCE ) -+#define __rtc_disabled() ( REG_RTC_RCR &= ~RTC_RCR_RTCE ) -+#define __rtc_enable_alarm() ( REG_RTC_RCR |= RTC_RCR_AE ) -+#define __rtc_disable_alarm() ( REG_RTC_RCR &= ~RTC_RCR_AE ) -+#define __rtc_enable_alarm_irq() ( REG_RTC_RCR |= RTC_RCR_AIE ) -+#define __rtc_disable_alarm_irq() ( REG_RTC_RCR &= ~RTC_RCR_AIE ) -+#define __rtc_enable_1Hz_irq() ( REG_RTC_RCR |= RTC_RCR_1HZIE ) -+#define __rtc_disable_1Hz_irq() ( REG_RTC_RCR &= ~RTC_RCR_1HZIE ) -+ -+#define __rtc_get_1Hz_flag() ( (REG_RTC_RCR >> RTC_RCR_1HZ_BIT) & 0x1 ) -+#define __rtc_clear_1Hz_flag() ( REG_RTC_RCR &= ~RTC_RCR_1HZ ) -+#define __rtc_get_alarm_flag() ( (REG_RTC_RCR >> RTC_RCR_AF_BIT) & 0x1 ) -+#define __rtc_clear_alarm_flag() ( REG_RTC_RCR &= ~RTC_RCR_AF ) -+ -+#define __rtc_get_second() ( REG_RTC_RSR ) -+#define __rtc_set_second(v) ( REG_RTC_RSR = v ) -+ -+#define __rtc_get_alarm_second() ( REG_RTC_RSAR ) -+#define __rtc_set_alarm_second(v) ( REG_RTC_RSAR = v ) -+ -+#define __rtc_RGR_is_locked() ( (REG_RTC_RGR >> RTC_RGR_LOCK) ) -+#define __rtc_lock_RGR() ( REG_RTC_RGR |= RTC_RGR_LOCK ) -+#define __rtc_unlock_RGR() ( REG_RTC_RGR &= ~RTC_RGR_LOCK ) -+#define __rtc_get_adjc_val() ( (REG_RTC_RGR & RTC_RGR_ADJC_MASK) >> RTC_RGR_ADJC_BIT ) -+#define __rtc_set_adjc_val(v) \ -+ ( REG_RTC_RGR = ( (REG_RTC_RGR & ~RTC_RGR_ADJC_MASK) | (v << RTC_RGR_ADJC_BIT) )) -+#define __rtc_get_nc1Hz_val() ( (REG_RTC_RGR & RTC_RGR_NC1HZ_MASK) >> RTC_RGR_NC1HZ_BIT ) -+#define __rtc_set_nc1Hz_val(v) \ -+ ( REG_RTC_RGR = ( (REG_RTC_RGR & ~RTC_RGR_NC1HZ_MASK) | (v << RTC_RGR_NC1HZ_BIT) )) -+ -+#define __rtc_power_down() ( REG_RTC_HCR |= RTC_HCR_PD ) -+ -+#define __rtc_get_hwfcr_val() ( REG_RTC_HWFCR & RTC_HWFCR_MASK ) -+#define __rtc_set_hwfcr_val(v) ( REG_RTC_HWFCR = (v) & RTC_HWFCR_MASK ) -+#define __rtc_get_hrcr_val() ( REG_RTC_HRCR & RTC_HRCR_MASK ) -+#define __rtc_set_hrcr_val(v) ( REG_RTC_HRCR = (v) & RTC_HRCR_MASK ) -+ -+#define __rtc_enable_alarm_wakeup() ( REG_RTC_HWCR |= RTC_HWCR_EALM ) -+#define __rtc_disable_alarm_wakeup() ( REG_RTC_HWCR &= ~RTC_HWCR_EALM ) -+ -+#define __rtc_status_hib_reset_occur() ( (REG_RTC_HWRSR >> RTC_HWRSR_HR) & 0x1 ) -+#define __rtc_status_ppr_reset_occur() ( (REG_RTC_HWRSR >> RTC_HWRSR_PPR) & 0x1 ) -+#define __rtc_status_wakeup_pin_waken_up() ( (REG_RTC_HWRSR >> RTC_HWRSR_PIN) & 0x1 ) -+#define __rtc_status_alarm_waken_up() ( (REG_RTC_HWRSR >> RTC_HWRSR_ALM) & 0x1 ) -+#define __rtc_clear_hib_stat_all() ( REG_RTC_HWRSR = 0 ) -+ -+#define __rtc_get_scratch_pattern() (REG_RTC_HSPR) -+#define __rtc_set_scratch_pattern(n) (REG_RTC_HSPR = n ) -+ -+ -+ -+#endif /* __JZ4740_OPS_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/platform.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/platform.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/platform.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,19 @@ -+ -+#ifndef __JZ4740_PLATFORM_H -+#define __JZ4740_PLATFORM_H -+ -+#include <linux/platform_device.h> -+ -+extern struct platform_device jz4740_usb_ohci_device; -+extern struct platform_device jz4740_usb_gdt_device; -+extern struct platform_device jz4740_mmc_device; -+extern struct platform_device jz4740_rtc_device; -+extern struct platform_device jz4740_i2c_device; -+extern struct platform_device jz4740_nand_device; -+extern struct platform_device jz4740_framebuffer_device; -+extern struct platform_device jz4740_i2s_device; -+extern struct platform_device jz4740_codec_device; -+extern struct platform_device jz4740_adc_device; -+extern struct platform_device jz4740_battery_device; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/regs.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/regs.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/regs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/regs.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,2397 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/regs.h -+ * -+ * Ingenic's JZ4740 common include. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <yliu@ingenic.cn> -+ * -+ * 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 __JZ4740_REGS_H__ -+#define __JZ4740_REGS_H__ -+ -+#if defined(__ASSEMBLY__) || defined(__LANGUAGE_ASSEMBLY) -+#define REG8(addr) (addr) -+#define REG16(addr) (addr) -+#define REG32(addr) (addr) -+#else -+#define REG8(addr) *((volatile unsigned char *)(addr)) -+#define REG16(addr) *((volatile unsigned short *)(addr)) -+#define REG32(addr) *((volatile unsigned int *)(addr)) -+#endif -+ -+/* -+ * Define the module base addresses -+ */ -+#define CPM_BASE 0xB0000000 -+#define INTC_BASE 0xB0001000 -+#define TCU_BASE 0xB0002000 -+#define WDT_BASE 0xB0002000 -+#define RTC_BASE 0xB0003000 -+#define GPIO_BASE 0xB0010000 -+#define AIC_BASE 0xB0020000 -+#define ICDC_BASE 0xB0020000 -+#define MSC_BASE 0xB0021000 -+#define UART0_BASE 0xB0030000 -+#define UART1_BASE 0xB0031000 -+#define I2C_BASE 0xB0042000 -+#define SSI_BASE 0xB0043000 -+#define SADC_BASE 0xB0070000 -+#define EMC_BASE 0xB3010000 -+#define DMAC_BASE 0xB3020000 -+#define UHC_BASE 0xB3030000 -+#define UDC_BASE 0xB3040000 -+#define LCD_BASE 0xB3050000 -+#define SLCD_BASE 0xB3050000 -+#define CIM_BASE 0xB3060000 -+#define IPU_BASE 0xB3080000 -+#define ETH_BASE 0xB3100000 -+ -+ -+/************************************************************************* -+ * INTC (Interrupt Controller) -+ *************************************************************************/ -+#define INTC_ISR (INTC_BASE + 0x00) -+#define INTC_IMR (INTC_BASE + 0x04) -+#define INTC_IMSR (INTC_BASE + 0x08) -+#define INTC_IMCR (INTC_BASE + 0x0c) -+#define INTC_IPR (INTC_BASE + 0x10) -+ -+#define REG_INTC_ISR REG32(INTC_ISR) -+#define REG_INTC_IMR REG32(INTC_IMR) -+#define REG_INTC_IMSR REG32(INTC_IMSR) -+#define REG_INTC_IMCR REG32(INTC_IMCR) -+#define REG_INTC_IPR REG32(INTC_IPR) -+ -+// 1st-level interrupts -+#define JZ_IRQ_BASE 8 -+#define JZ_IRQ(x) (JZ_IRQ_BASE + (x)) -+#define JZ_IRQ_I2C JZ_IRQ(1) -+#define JZ_IRQ_UHC JZ_IRQ(3) -+#define JZ_IRQ_UART1 JZ_IRQ(8) -+#define JZ_IRQ_UART0 JZ_IRQ(9) -+#define JZ_IRQ_SADC JZ_IRQ(12) -+#define JZ_IRQ_MSC JZ_IRQ(14) -+#define JZ_IRQ_RTC JZ_IRQ(15) -+#define JZ_IRQ_SSI JZ_IRQ(16) -+#define JZ_IRQ_CIM JZ_IRQ(17) -+#define JZ_IRQ_AIC JZ_IRQ(18) -+#define JZ_IRQ_ETH JZ_IRQ(19) -+#define JZ_IRQ_DMAC JZ_IRQ(20) -+#define JZ_IRQ_TCU2 JZ_IRQ(21) -+#define JZ_IRQ_TCU1 JZ_IRQ(22) -+#define JZ_IRQ_TCU0 JZ_IRQ(23) -+#define JZ_IRQ_UDC JZ_IRQ(24) -+#define JZ_IRQ_GPIO3 JZ_IRQ(25) -+#define JZ_IRQ_GPIO2 JZ_IRQ(26) -+#define JZ_IRQ_GPIO1 JZ_IRQ(27) -+#define JZ_IRQ_GPIO0 JZ_IRQ(28) -+#define JZ_IRQ_IPU JZ_IRQ(29) -+#define JZ_IRQ_LCD JZ_IRQ(30) -+ -+/* 2nd-level interrupts */ -+#define JZ_IRQ_DMA(x) ((x) + JZ_IRQ(32)) /* 32 to 37 for DMAC channel 0 to 5 */ -+#define IRQ_GPIO_0 JZ_IRQ(48) /* 48 to 175 for GPIO pin 0 to 127 */ -+ -+#define JZ_IRQ_INTC_GPIO(x) (JZ_IRQ_GPIO0 - (x)) -+#define JZ_IRQ_GPIO(x) (IRQ_GPIO_0 + (x)) -+ -+#define NUM_DMA 6 -+#define NUM_GPIO 128 -+/************************************************************************* -+ * RTC -+ *************************************************************************/ -+#define RTC_RCR (RTC_BASE + 0x00) /* RTC Control Register */ -+#define RTC_RSR (RTC_BASE + 0x04) /* RTC Second Register */ -+#define RTC_RSAR (RTC_BASE + 0x08) /* RTC Second Alarm Register */ -+#define RTC_RGR (RTC_BASE + 0x0c) /* RTC Regulator Register */ -+ -+#define RTC_HCR (RTC_BASE + 0x20) /* Hibernate Control Register */ -+#define RTC_HWFCR (RTC_BASE + 0x24) /* Hibernate Wakeup Filter Counter Reg */ -+#define RTC_HRCR (RTC_BASE + 0x28) /* Hibernate Reset Counter Register */ -+#define RTC_HWCR (RTC_BASE + 0x2c) /* Hibernate Wakeup Control Register */ -+#define RTC_HWRSR (RTC_BASE + 0x30) /* Hibernate Wakeup Status Register */ -+#define RTC_HSPR (RTC_BASE + 0x34) /* Hibernate Scratch Pattern Register */ -+ -+#define REG_RTC_RCR REG32(RTC_RCR) -+#define REG_RTC_RSR REG32(RTC_RSR) -+#define REG_RTC_RSAR REG32(RTC_RSAR) -+#define REG_RTC_RGR REG32(RTC_RGR) -+#define REG_RTC_HCR REG32(RTC_HCR) -+#define REG_RTC_HWFCR REG32(RTC_HWFCR) -+#define REG_RTC_HRCR REG32(RTC_HRCR) -+#define REG_RTC_HWCR REG32(RTC_HWCR) -+#define REG_RTC_HWRSR REG32(RTC_HWRSR) -+#define REG_RTC_HSPR REG32(RTC_HSPR) -+ -+/* RTC Control Register */ -+#define RTC_RCR_WRDY_BIT 7 -+#define RTC_RCR_WRDY (1 << 7) /* Write Ready Flag */ -+#define RTC_RCR_1HZ_BIT 6 -+#define RTC_RCR_1HZ (1 << RTC_RCR_1HZ_BIT) /* 1Hz Flag */ -+#define RTC_RCR_1HZIE (1 << 5) /* 1Hz Interrupt Enable */ -+#define RTC_RCR_AF_BIT 4 -+#define RTC_RCR_AF (1 << RTC_RCR_AF_BIT) /* Alarm Flag */ -+#define RTC_RCR_AIE (1 << 3) /* Alarm Interrupt Enable */ -+#define RTC_RCR_AE (1 << 2) /* Alarm Enable */ -+#define RTC_RCR_RTCE (1 << 0) /* RTC Enable */ -+ -+/* RTC Regulator Register */ -+#define RTC_RGR_LOCK (1 << 31) /* Lock Bit */ -+#define RTC_RGR_ADJC_BIT 16 -+#define RTC_RGR_ADJC_MASK (0x3ff << RTC_RGR_ADJC_BIT) -+#define RTC_RGR_NC1HZ_BIT 0 -+#define RTC_RGR_NC1HZ_MASK (0xffff << RTC_RGR_NC1HZ_BIT) -+ -+/* Hibernate Control Register */ -+#define RTC_HCR_PD (1 << 0) /* Power Down */ -+ -+/* Hibernate Wakeup Filter Counter Register */ -+#define RTC_HWFCR_BIT 5 -+#define RTC_HWFCR_MASK (0x7ff << RTC_HWFCR_BIT) -+ -+/* Hibernate Reset Counter Register */ -+#define RTC_HRCR_BIT 5 -+#define RTC_HRCR_MASK (0x7f << RTC_HRCR_BIT) -+ -+/* Hibernate Wakeup Control Register */ -+#define RTC_HWCR_EALM (1 << 0) /* RTC alarm wakeup enable */ -+ -+/* Hibernate Wakeup Status Register */ -+#define RTC_HWRSR_HR (1 << 5) /* Hibernate reset */ -+#define RTC_HWRSR_PPR (1 << 4) /* PPR reset */ -+#define RTC_HWRSR_PIN (1 << 1) /* Wakeup pin status bit */ -+#define RTC_HWRSR_ALM (1 << 0) /* RTC alarm status bit */ -+ -+ -+/************************************************************************* -+ * CPM (Clock reset and Power control Management) -+ *************************************************************************/ -+#define CPM_CPCCR (CPM_BASE+0x00) -+#define CPM_CPPCR (CPM_BASE+0x10) -+#define CPM_I2SCDR (CPM_BASE+0x60) -+#define CPM_LPCDR (CPM_BASE+0x64) -+#define CPM_MSCCDR (CPM_BASE+0x68) -+#define CPM_UHCCDR (CPM_BASE+0x6C) -+#define CPM_SSICDR (CPM_BASE+0x74) -+ -+#define CPM_LCR (CPM_BASE+0x04) -+#define CPM_CLKGR (CPM_BASE+0x20) -+#define CPM_SCR (CPM_BASE+0x24) -+ -+#define CPM_HCR (CPM_BASE+0x30) -+#define CPM_HWFCR (CPM_BASE+0x34) -+#define CPM_HRCR (CPM_BASE+0x38) -+#define CPM_HWCR (CPM_BASE+0x3c) -+#define CPM_HWSR (CPM_BASE+0x40) -+#define CPM_HSPR (CPM_BASE+0x44) -+ -+#define CPM_RSR (CPM_BASE+0x08) -+ -+ -+#define REG_CPM_CPCCR REG32(CPM_CPCCR) -+#define REG_CPM_CPPCR REG32(CPM_CPPCR) -+#define REG_CPM_I2SCDR REG32(CPM_I2SCDR) -+#define REG_CPM_LPCDR REG32(CPM_LPCDR) -+#define REG_CPM_MSCCDR REG32(CPM_MSCCDR) -+#define REG_CPM_UHCCDR REG32(CPM_UHCCDR) -+#define REG_CPM_SSICDR REG32(CPM_SSICDR) -+ -+#define REG_CPM_LCR REG32(CPM_LCR) -+#define REG_CPM_CLKGR REG32(CPM_CLKGR) -+#define REG_CPM_SCR REG32(CPM_SCR) -+#define REG_CPM_HCR REG32(CPM_HCR) -+#define REG_CPM_HWFCR REG32(CPM_HWFCR) -+#define REG_CPM_HRCR REG32(CPM_HRCR) -+#define REG_CPM_HWCR REG32(CPM_HWCR) -+#define REG_CPM_HWSR REG32(CPM_HWSR) -+#define REG_CPM_HSPR REG32(CPM_HSPR) -+ -+#define REG_CPM_RSR REG32(CPM_RSR) -+ -+ -+/* Clock Control Register */ -+#define CPM_CPCCR_I2CS (1 << 31) -+#define CPM_CPCCR_CLKOEN (1 << 30) -+#define CPM_CPCCR_UCS (1 << 29) -+#define CPM_CPCCR_UDIV_BIT 23 -+#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT) -+#define CPM_CPCCR_CE (1 << 22) -+#define CPM_CPCCR_PCS (1 << 21) -+#define CPM_CPCCR_LDIV_BIT 16 -+#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT) -+#define CPM_CPCCR_MDIV_BIT 12 -+#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT) -+#define CPM_CPCCR_PDIV_BIT 8 -+#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT) -+#define CPM_CPCCR_HDIV_BIT 4 -+#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT) -+#define CPM_CPCCR_CDIV_BIT 0 -+#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT) -+ -+/* I2S Clock Divider Register */ -+#define CPM_I2SCDR_I2SDIV_BIT 0 -+#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT) -+ -+/* LCD Pixel Clock Divider Register */ -+#define CPM_LPCDR_PIXDIV_BIT 0 -+#define CPM_LPCDR_PIXDIV_MASK (0x7ff << CPM_LPCDR_PIXDIV_BIT) -+ -+/* MSC Clock Divider Register */ -+#define CPM_MSCCDR_MSCDIV_BIT 0 -+#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT) -+ -+/* UHC Clock Divider Register */ -+#define CPM_UHCCDR_UHCDIV_BIT 0 -+#define CPM_UHCCDR_UHCDIV_MASK (0xf << CPM_UHCCDR_UHCDIV_BIT) -+ -+/* SSI Clock Divider Register */ -+#define CPM_SSICDR_SCS (1<<31) /* SSI clock source selection, 0:EXCLK, 1: PLL */ -+#define CPM_SSICDR_SSIDIV_BIT 0 -+#define CPM_SSICDR_SSIDIV_MASK (0xf << CPM_SSICDR_SSIDIV_BIT) -+ -+/* PLL Control Register */ -+#define CPM_CPPCR_PLLM_BIT 23 -+#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT) -+#define CPM_CPPCR_PLLN_BIT 18 -+#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT) -+#define CPM_CPPCR_PLLOD_BIT 16 -+#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT) -+#define CPM_CPPCR_PLLS (1 << 10) -+#define CPM_CPPCR_PLLBP (1 << 9) -+#define CPM_CPPCR_PLLEN (1 << 8) -+#define CPM_CPPCR_PLLST_BIT 0 -+#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT) -+ -+/* Low Power Control Register */ -+#define CPM_LCR_DOZE_DUTY_BIT 3 -+#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT) -+#define CPM_LCR_DOZE_ON (1 << 2) -+#define CPM_LCR_LPM_BIT 0 -+#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT) -+ #define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT) -+ #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) -+ -+/* Clock Gate Register */ -+#define CPM_CLKGR_UART1 (1 << 15) -+#define CPM_CLKGR_UHC (1 << 14) -+#define CPM_CLKGR_IPU (1 << 13) -+#define CPM_CLKGR_DMAC (1 << 12) -+#define CPM_CLKGR_UDC (1 << 11) -+#define CPM_CLKGR_LCD (1 << 10) -+#define CPM_CLKGR_CIM (1 << 9) -+#define CPM_CLKGR_SADC (1 << 8) -+#define CPM_CLKGR_MSC (1 << 7) -+#define CPM_CLKGR_AIC1 (1 << 6) -+#define CPM_CLKGR_AIC2 (1 << 5) -+#define CPM_CLKGR_SSI (1 << 4) -+#define CPM_CLKGR_I2C (1 << 3) -+#define CPM_CLKGR_RTC (1 << 2) -+#define CPM_CLKGR_TCU (1 << 1) -+#define CPM_CLKGR_UART0 (1 << 0) -+ -+/* Sleep Control Register */ -+#define CPM_SCR_O1ST_BIT 8 -+#define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT) -+#define CPM_SCR_USBPHY_ENABLE (1 << 6) -+#define CPM_SCR_OSC_ENABLE (1 << 4) -+ -+/* Hibernate Control Register */ -+#define CPM_HCR_PD (1 << 0) -+ -+/* Wakeup Filter Counter Register in Hibernate Mode */ -+#define CPM_HWFCR_TIME_BIT 0 -+#define CPM_HWFCR_TIME_MASK (0x3ff << CPM_HWFCR_TIME_BIT) -+ -+/* Reset Counter Register in Hibernate Mode */ -+#define CPM_HRCR_TIME_BIT 0 -+#define CPM_HRCR_TIME_MASK (0x7f << CPM_HRCR_TIME_BIT) -+ -+/* Wakeup Control Register in Hibernate Mode */ -+#define CPM_HWCR_WLE_LOW (0 << 2) -+#define CPM_HWCR_WLE_HIGH (1 << 2) -+#define CPM_HWCR_PIN_WAKEUP (1 << 1) -+#define CPM_HWCR_RTC_WAKEUP (1 << 0) -+ -+/* Wakeup Status Register in Hibernate Mode */ -+#define CPM_HWSR_WSR_PIN (1 << 1) -+#define CPM_HWSR_WSR_RTC (1 << 0) -+ -+/* Reset Status Register */ -+#define CPM_RSR_HR (1 << 2) -+#define CPM_RSR_WR (1 << 1) -+#define CPM_RSR_PR (1 << 0) -+ -+ -+/************************************************************************* -+ * TCU (Timer Counter Unit) -+ *************************************************************************/ -+#define TCU_TSR (TCU_BASE + 0x1C) /* Timer Stop Register */ -+#define TCU_TSSR (TCU_BASE + 0x2C) /* Timer Stop Set Register */ -+#define TCU_TSCR (TCU_BASE + 0x3C) /* Timer Stop Clear Register */ -+#define TCU_TER (TCU_BASE + 0x10) /* Timer Counter Enable Register */ -+#define TCU_TESR (TCU_BASE + 0x14) /* Timer Counter Enable Set Register */ -+#define TCU_TECR (TCU_BASE + 0x18) /* Timer Counter Enable Clear Register */ -+#define TCU_TFR (TCU_BASE + 0x20) /* Timer Flag Register */ -+#define TCU_TFSR (TCU_BASE + 0x24) /* Timer Flag Set Register */ -+#define TCU_TFCR (TCU_BASE + 0x28) /* Timer Flag Clear Register */ -+#define TCU_TMR (TCU_BASE + 0x30) /* Timer Mask Register */ -+#define TCU_TMSR (TCU_BASE + 0x34) /* Timer Mask Set Register */ -+#define TCU_TMCR (TCU_BASE + 0x38) /* Timer Mask Clear Register */ -+#define TCU_TDFR0 (TCU_BASE + 0x40) /* Timer Data Full Register */ -+#define TCU_TDHR0 (TCU_BASE + 0x44) /* Timer Data Half Register */ -+#define TCU_TCNT0 (TCU_BASE + 0x48) /* Timer Counter Register */ -+#define TCU_TCSR0 (TCU_BASE + 0x4C) /* Timer Control Register */ -+#define TCU_TDFR1 (TCU_BASE + 0x50) -+#define TCU_TDHR1 (TCU_BASE + 0x54) -+#define TCU_TCNT1 (TCU_BASE + 0x58) -+#define TCU_TCSR1 (TCU_BASE + 0x5C) -+#define TCU_TDFR2 (TCU_BASE + 0x60) -+#define TCU_TDHR2 (TCU_BASE + 0x64) -+#define TCU_TCNT2 (TCU_BASE + 0x68) -+#define TCU_TCSR2 (TCU_BASE + 0x6C) -+#define TCU_TDFR3 (TCU_BASE + 0x70) -+#define TCU_TDHR3 (TCU_BASE + 0x74) -+#define TCU_TCNT3 (TCU_BASE + 0x78) -+#define TCU_TCSR3 (TCU_BASE + 0x7C) -+#define TCU_TDFR4 (TCU_BASE + 0x80) -+#define TCU_TDHR4 (TCU_BASE + 0x84) -+#define TCU_TCNT4 (TCU_BASE + 0x88) -+#define TCU_TCSR4 (TCU_BASE + 0x8C) -+#define TCU_TDFR5 (TCU_BASE + 0x90) -+#define TCU_TDHR5 (TCU_BASE + 0x94) -+#define TCU_TCNT5 (TCU_BASE + 0x98) -+#define TCU_TCSR5 (TCU_BASE + 0x9C) -+ -+#define REG_TCU_TSR REG32(TCU_TSR) -+#define REG_TCU_TSSR REG32(TCU_TSSR) -+#define REG_TCU_TSCR REG32(TCU_TSCR) -+#define REG_TCU_TER REG8(TCU_TER) -+#define REG_TCU_TESR REG8(TCU_TESR) -+#define REG_TCU_TECR REG8(TCU_TECR) -+#define REG_TCU_TFR REG32(TCU_TFR) -+#define REG_TCU_TFSR REG32(TCU_TFSR) -+#define REG_TCU_TFCR REG32(TCU_TFCR) -+#define REG_TCU_TMR REG32(TCU_TMR) -+#define REG_TCU_TMSR REG32(TCU_TMSR) -+#define REG_TCU_TMCR REG32(TCU_TMCR) -+#define REG_TCU_TDFR0 REG16(TCU_TDFR0) -+#define REG_TCU_TDHR0 REG16(TCU_TDHR0) -+#define REG_TCU_TCNT0 REG16(TCU_TCNT0) -+#define REG_TCU_TCSR0 REG16(TCU_TCSR0) -+#define REG_TCU_TDFR1 REG16(TCU_TDFR1) -+#define REG_TCU_TDHR1 REG16(TCU_TDHR1) -+#define REG_TCU_TCNT1 REG16(TCU_TCNT1) -+#define REG_TCU_TCSR1 REG16(TCU_TCSR1) -+#define REG_TCU_TDFR2 REG16(TCU_TDFR2) -+#define REG_TCU_TDHR2 REG16(TCU_TDHR2) -+#define REG_TCU_TCNT2 REG16(TCU_TCNT2) -+#define REG_TCU_TCSR2 REG16(TCU_TCSR2) -+#define REG_TCU_TDFR3 REG16(TCU_TDFR3) -+#define REG_TCU_TDHR3 REG16(TCU_TDHR3) -+#define REG_TCU_TCNT3 REG16(TCU_TCNT3) -+#define REG_TCU_TCSR3 REG16(TCU_TCSR3) -+#define REG_TCU_TDFR4 REG16(TCU_TDFR4) -+#define REG_TCU_TDHR4 REG16(TCU_TDHR4) -+#define REG_TCU_TCNT4 REG16(TCU_TCNT4) -+#define REG_TCU_TCSR4 REG16(TCU_TCSR4) -+ -+// n = 0,1,2,3,4,5 -+#define TCU_TDFR(n) (TCU_BASE + (0x40 + (n)*0x10)) /* Timer Data Full Reg */ -+#define TCU_TDHR(n) (TCU_BASE + (0x44 + (n)*0x10)) /* Timer Data Half Reg */ -+#define TCU_TCNT(n) (TCU_BASE + (0x48 + (n)*0x10)) /* Timer Counter Reg */ -+#define TCU_TCSR(n) (TCU_BASE + (0x4C + (n)*0x10)) /* Timer Control Reg */ -+ -+#define REG_TCU_TDFR(n) REG16(TCU_TDFR((n))) -+#define REG_TCU_TDHR(n) REG16(TCU_TDHR((n))) -+#define REG_TCU_TCNT(n) REG16(TCU_TCNT((n))) -+#define REG_TCU_TCSR(n) REG16(TCU_TCSR((n))) -+ -+// Register definitions -+#define TCU_TCSR_PWM_SD (1 << 9) -+#define TCU_TCSR_PWM_INITL_HIGH (1 << 8) -+#define TCU_TCSR_PWM_EN (1 << 7) -+#define TCU_TCSR_PRESCALE_BIT 3 -+#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT) -+ #define TCU_TCSR_PRESCALE1 (0x0 << TCU_TCSR_PRESCALE_BIT) -+ #define TCU_TCSR_PRESCALE4 (0x1 << TCU_TCSR_PRESCALE_BIT) -+ #define TCU_TCSR_PRESCALE16 (0x2 << TCU_TCSR_PRESCALE_BIT) -+ #define TCU_TCSR_PRESCALE64 (0x3 << TCU_TCSR_PRESCALE_BIT) -+ #define TCU_TCSR_PRESCALE256 (0x4 << TCU_TCSR_PRESCALE_BIT) -+ #define TCU_TCSR_PRESCALE1024 (0x5 << TCU_TCSR_PRESCALE_BIT) -+#define TCU_TCSR_EXT_EN (1 << 2) -+#define TCU_TCSR_RTC_EN (1 << 1) -+#define TCU_TCSR_PCK_EN (1 << 0) -+ -+#define TCU_TER_TCEN5 (1 << 5) -+#define TCU_TER_TCEN4 (1 << 4) -+#define TCU_TER_TCEN3 (1 << 3) -+#define TCU_TER_TCEN2 (1 << 2) -+#define TCU_TER_TCEN1 (1 << 1) -+#define TCU_TER_TCEN0 (1 << 0) -+ -+#define TCU_TESR_TCST5 (1 << 5) -+#define TCU_TESR_TCST4 (1 << 4) -+#define TCU_TESR_TCST3 (1 << 3) -+#define TCU_TESR_TCST2 (1 << 2) -+#define TCU_TESR_TCST1 (1 << 1) -+#define TCU_TESR_TCST0 (1 << 0) -+ -+#define TCU_TECR_TCCL5 (1 << 5) -+#define TCU_TECR_TCCL4 (1 << 4) -+#define TCU_TECR_TCCL3 (1 << 3) -+#define TCU_TECR_TCCL2 (1 << 2) -+#define TCU_TECR_TCCL1 (1 << 1) -+#define TCU_TECR_TCCL0 (1 << 0) -+ -+#define TCU_TFR_HFLAG5 (1 << 21) -+#define TCU_TFR_HFLAG4 (1 << 20) -+#define TCU_TFR_HFLAG3 (1 << 19) -+#define TCU_TFR_HFLAG2 (1 << 18) -+#define TCU_TFR_HFLAG1 (1 << 17) -+#define TCU_TFR_HFLAG0 (1 << 16) -+#define TCU_TFR_FFLAG5 (1 << 5) -+#define TCU_TFR_FFLAG4 (1 << 4) -+#define TCU_TFR_FFLAG3 (1 << 3) -+#define TCU_TFR_FFLAG2 (1 << 2) -+#define TCU_TFR_FFLAG1 (1 << 1) -+#define TCU_TFR_FFLAG0 (1 << 0) -+ -+#define TCU_TFSR_HFLAG5 (1 << 21) -+#define TCU_TFSR_HFLAG4 (1 << 20) -+#define TCU_TFSR_HFLAG3 (1 << 19) -+#define TCU_TFSR_HFLAG2 (1 << 18) -+#define TCU_TFSR_HFLAG1 (1 << 17) -+#define TCU_TFSR_HFLAG0 (1 << 16) -+#define TCU_TFSR_FFLAG5 (1 << 5) -+#define TCU_TFSR_FFLAG4 (1 << 4) -+#define TCU_TFSR_FFLAG3 (1 << 3) -+#define TCU_TFSR_FFLAG2 (1 << 2) -+#define TCU_TFSR_FFLAG1 (1 << 1) -+#define TCU_TFSR_FFLAG0 (1 << 0) -+ -+#define TCU_TFCR_HFLAG5 (1 << 21) -+#define TCU_TFCR_HFLAG4 (1 << 20) -+#define TCU_TFCR_HFLAG3 (1 << 19) -+#define TCU_TFCR_HFLAG2 (1 << 18) -+#define TCU_TFCR_HFLAG1 (1 << 17) -+#define TCU_TFCR_HFLAG0 (1 << 16) -+#define TCU_TFCR_FFLAG5 (1 << 5) -+#define TCU_TFCR_FFLAG4 (1 << 4) -+#define TCU_TFCR_FFLAG3 (1 << 3) -+#define TCU_TFCR_FFLAG2 (1 << 2) -+#define TCU_TFCR_FFLAG1 (1 << 1) -+#define TCU_TFCR_FFLAG0 (1 << 0) -+ -+#define TCU_TMR_HMASK5 (1 << 21) -+#define TCU_TMR_HMASK4 (1 << 20) -+#define TCU_TMR_HMASK3 (1 << 19) -+#define TCU_TMR_HMASK2 (1 << 18) -+#define TCU_TMR_HMASK1 (1 << 17) -+#define TCU_TMR_HMASK0 (1 << 16) -+#define TCU_TMR_FMASK5 (1 << 5) -+#define TCU_TMR_FMASK4 (1 << 4) -+#define TCU_TMR_FMASK3 (1 << 3) -+#define TCU_TMR_FMASK2 (1 << 2) -+#define TCU_TMR_FMASK1 (1 << 1) -+#define TCU_TMR_FMASK0 (1 << 0) -+ -+#define TCU_TMSR_HMST5 (1 << 21) -+#define TCU_TMSR_HMST4 (1 << 20) -+#define TCU_TMSR_HMST3 (1 << 19) -+#define TCU_TMSR_HMST2 (1 << 18) -+#define TCU_TMSR_HMST1 (1 << 17) -+#define TCU_TMSR_HMST0 (1 << 16) -+#define TCU_TMSR_FMST5 (1 << 5) -+#define TCU_TMSR_FMST4 (1 << 4) -+#define TCU_TMSR_FMST3 (1 << 3) -+#define TCU_TMSR_FMST2 (1 << 2) -+#define TCU_TMSR_FMST1 (1 << 1) -+#define TCU_TMSR_FMST0 (1 << 0) -+ -+#define TCU_TMCR_HMCL5 (1 << 21) -+#define TCU_TMCR_HMCL4 (1 << 20) -+#define TCU_TMCR_HMCL3 (1 << 19) -+#define TCU_TMCR_HMCL2 (1 << 18) -+#define TCU_TMCR_HMCL1 (1 << 17) -+#define TCU_TMCR_HMCL0 (1 << 16) -+#define TCU_TMCR_FMCL5 (1 << 5) -+#define TCU_TMCR_FMCL4 (1 << 4) -+#define TCU_TMCR_FMCL3 (1 << 3) -+#define TCU_TMCR_FMCL2 (1 << 2) -+#define TCU_TMCR_FMCL1 (1 << 1) -+#define TCU_TMCR_FMCL0 (1 << 0) -+ -+#define TCU_TSR_WDTS (1 << 16) -+#define TCU_TSR_STOP5 (1 << 5) -+#define TCU_TSR_STOP4 (1 << 4) -+#define TCU_TSR_STOP3 (1 << 3) -+#define TCU_TSR_STOP2 (1 << 2) -+#define TCU_TSR_STOP1 (1 << 1) -+#define TCU_TSR_STOP0 (1 << 0) -+ -+#define TCU_TSSR_WDTSS (1 << 16) -+#define TCU_TSSR_STPS5 (1 << 5) -+#define TCU_TSSR_STPS4 (1 << 4) -+#define TCU_TSSR_STPS3 (1 << 3) -+#define TCU_TSSR_STPS2 (1 << 2) -+#define TCU_TSSR_STPS1 (1 << 1) -+#define TCU_TSSR_STPS0 (1 << 0) -+ -+#define TCU_TSSR_WDTSC (1 << 16) -+#define TCU_TSSR_STPC5 (1 << 5) -+#define TCU_TSSR_STPC4 (1 << 4) -+#define TCU_TSSR_STPC3 (1 << 3) -+#define TCU_TSSR_STPC2 (1 << 2) -+#define TCU_TSSR_STPC1 (1 << 1) -+#define TCU_TSSR_STPC0 (1 << 0) -+ -+ -+/************************************************************************* -+ * WDT (WatchDog Timer) -+ *************************************************************************/ -+#define WDT_TDR (WDT_BASE + 0x00) -+#define WDT_TCER (WDT_BASE + 0x04) -+#define WDT_TCNT (WDT_BASE + 0x08) -+#define WDT_TCSR (WDT_BASE + 0x0C) -+ -+#define REG_WDT_TDR REG16(WDT_TDR) -+#define REG_WDT_TCER REG8(WDT_TCER) -+#define REG_WDT_TCNT REG16(WDT_TCNT) -+#define REG_WDT_TCSR REG16(WDT_TCSR) -+ -+// Register definition -+#define WDT_TCSR_PRESCALE_BIT 3 -+#define WDT_TCSR_PRESCALE_MASK (0x7 << WDT_TCSR_PRESCALE_BIT) -+ #define WDT_TCSR_PRESCALE1 (0x0 << WDT_TCSR_PRESCALE_BIT) -+ #define WDT_TCSR_PRESCALE4 (0x1 << WDT_TCSR_PRESCALE_BIT) -+ #define WDT_TCSR_PRESCALE16 (0x2 << WDT_TCSR_PRESCALE_BIT) -+ #define WDT_TCSR_PRESCALE64 (0x3 << WDT_TCSR_PRESCALE_BIT) -+ #define WDT_TCSR_PRESCALE256 (0x4 << WDT_TCSR_PRESCALE_BIT) -+ #define WDT_TCSR_PRESCALE1024 (0x5 << WDT_TCSR_PRESCALE_BIT) -+#define WDT_TCSR_EXT_EN (1 << 2) -+#define WDT_TCSR_RTC_EN (1 << 1) -+#define WDT_TCSR_PCK_EN (1 << 0) -+ -+#define WDT_TCER_TCEN (1 << 0) -+ -+ -+/************************************************************************* -+ * DMAC (DMA Controller) -+ *************************************************************************/ -+ -+#define MAX_DMA_NUM 6 /* max 6 channels */ -+ -+#define DMAC_DSAR(n) (DMAC_BASE + (0x00 + (n) * 0x20)) /* DMA source address */ -+#define DMAC_DTAR(n) (DMAC_BASE + (0x04 + (n) * 0x20)) /* DMA target address */ -+#define DMAC_DTCR(n) (DMAC_BASE + (0x08 + (n) * 0x20)) /* DMA transfer count */ -+#define DMAC_DRSR(n) (DMAC_BASE + (0x0c + (n) * 0x20)) /* DMA request source */ -+#define DMAC_DCCSR(n) (DMAC_BASE + (0x10 + (n) * 0x20)) /* DMA control/status */ -+#define DMAC_DCMD(n) (DMAC_BASE + (0x14 + (n) * 0x20)) /* DMA command */ -+#define DMAC_DDA(n) (DMAC_BASE + (0x18 + (n) * 0x20)) /* DMA descriptor address */ -+#define DMAC_DMACR (DMAC_BASE + 0x0300) /* DMA control register */ -+#define DMAC_DMAIPR (DMAC_BASE + 0x0304) /* DMA interrupt pending */ -+#define DMAC_DMADBR (DMAC_BASE + 0x0308) /* DMA doorbell */ -+#define DMAC_DMADBSR (DMAC_BASE + 0x030C) /* DMA doorbell set */ -+ -+// channel 0 -+#define DMAC_DSAR0 DMAC_DSAR(0) -+#define DMAC_DTAR0 DMAC_DTAR(0) -+#define DMAC_DTCR0 DMAC_DTCR(0) -+#define DMAC_DRSR0 DMAC_DRSR(0) -+#define DMAC_DCCSR0 DMAC_DCCSR(0) -+#define DMAC_DCMD0 DMAC_DCMD(0) -+#define DMAC_DDA0 DMAC_DDA(0) -+ -+// channel 1 -+#define DMAC_DSAR1 DMAC_DSAR(1) -+#define DMAC_DTAR1 DMAC_DTAR(1) -+#define DMAC_DTCR1 DMAC_DTCR(1) -+#define DMAC_DRSR1 DMAC_DRSR(1) -+#define DMAC_DCCSR1 DMAC_DCCSR(1) -+#define DMAC_DCMD1 DMAC_DCMD(1) -+#define DMAC_DDA1 DMAC_DDA(1) -+ -+// channel 2 -+#define DMAC_DSAR2 DMAC_DSAR(2) -+#define DMAC_DTAR2 DMAC_DTAR(2) -+#define DMAC_DTCR2 DMAC_DTCR(2) -+#define DMAC_DRSR2 DMAC_DRSR(2) -+#define DMAC_DCCSR2 DMAC_DCCSR(2) -+#define DMAC_DCMD2 DMAC_DCMD(2) -+#define DMAC_DDA2 DMAC_DDA(2) -+ -+// channel 3 -+#define DMAC_DSAR3 DMAC_DSAR(3) -+#define DMAC_DTAR3 DMAC_DTAR(3) -+#define DMAC_DTCR3 DMAC_DTCR(3) -+#define DMAC_DRSR3 DMAC_DRSR(3) -+#define DMAC_DCCSR3 DMAC_DCCSR(3) -+#define DMAC_DCMD3 DMAC_DCMD(3) -+#define DMAC_DDA3 DMAC_DDA(3) -+ -+// channel 4 -+#define DMAC_DSAR4 DMAC_DSAR(4) -+#define DMAC_DTAR4 DMAC_DTAR(4) -+#define DMAC_DTCR4 DMAC_DTCR(4) -+#define DMAC_DRSR4 DMAC_DRSR(4) -+#define DMAC_DCCSR4 DMAC_DCCSR(4) -+#define DMAC_DCMD4 DMAC_DCMD(4) -+#define DMAC_DDA4 DMAC_DDA(4) -+ -+// channel 5 -+#define DMAC_DSAR5 DMAC_DSAR(5) -+#define DMAC_DTAR5 DMAC_DTAR(5) -+#define DMAC_DTCR5 DMAC_DTCR(5) -+#define DMAC_DRSR5 DMAC_DRSR(5) -+#define DMAC_DCCSR5 DMAC_DCCSR(5) -+#define DMAC_DCMD5 DMAC_DCMD(5) -+#define DMAC_DDA5 DMAC_DDA(5) -+ -+#define REG_DMAC_DSAR(n) REG32(DMAC_DSAR((n))) -+#define REG_DMAC_DTAR(n) REG32(DMAC_DTAR((n))) -+#define REG_DMAC_DTCR(n) REG32(DMAC_DTCR((n))) -+#define REG_DMAC_DRSR(n) REG32(DMAC_DRSR((n))) -+#define REG_DMAC_DCCSR(n) REG32(DMAC_DCCSR((n))) -+#define REG_DMAC_DCMD(n) REG32(DMAC_DCMD((n))) -+#define REG_DMAC_DDA(n) REG32(DMAC_DDA((n))) -+#define REG_DMAC_DMACR REG32(DMAC_DMACR) -+#define REG_DMAC_DMAIPR REG32(DMAC_DMAIPR) -+#define REG_DMAC_DMADBR REG32(DMAC_DMADBR) -+#define REG_DMAC_DMADBSR REG32(DMAC_DMADBSR) -+ -+// DMA request source register -+#define DMAC_DRSR_RS_BIT 0 -+#define DMAC_DRSR_RS_MASK (0x1f << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_UART0OUT (20 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_UART0IN (21 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_SSIOUT (22 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_SSIIN (23 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_AICOUT (24 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_AICIN (25 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_MSCOUT (26 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_MSCIN (27 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_TCU (28 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_SADC (29 << DMAC_DRSR_RS_BIT) -+ #define DMAC_DRSR_RS_SLCD (30 << DMAC_DRSR_RS_BIT) -+ -+// DMA channel control/status register -+#define DMAC_DCCSR_NDES (1 << 31) /* descriptor (0) or not (1) ? */ -+#define DMAC_DCCSR_CDOA_BIT 16 /* copy of DMA offset address */ -+#define DMAC_DCCSR_CDOA_MASK (0xff << DMAC_DCCSR_CDOA_BIT) -+#define DMAC_DCCSR_INV (1 << 6) /* descriptor invalid */ -+#define DMAC_DCCSR_AR (1 << 4) /* address error */ -+#define DMAC_DCCSR_TT (1 << 3) /* transfer terminated */ -+#define DMAC_DCCSR_HLT (1 << 2) /* DMA halted */ -+#define DMAC_DCCSR_CT (1 << 1) /* count terminated */ -+#define DMAC_DCCSR_EN (1 << 0) /* channel enable bit */ -+ -+// DMA channel command register -+#define DMAC_DCMD_SAI (1 << 23) /* source address increment */ -+#define DMAC_DCMD_DAI (1 << 22) /* dest address increment */ -+#define DMAC_DCMD_RDIL_BIT 16 /* request detection interval length */ -+#define DMAC_DCMD_RDIL_MASK (0x0f << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_IGN (0 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_2 (1 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_4 (2 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_8 (3 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_12 (4 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_16 (5 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_20 (6 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_24 (7 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_28 (8 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_32 (9 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_48 (10 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_60 (11 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_64 (12 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_124 (13 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_128 (14 << DMAC_DCMD_RDIL_BIT) -+ #define DMAC_DCMD_RDIL_200 (15 << DMAC_DCMD_RDIL_BIT) -+#define DMAC_DCMD_SWDH_BIT 14 /* source port width */ -+#define DMAC_DCMD_SWDH_MASK (0x03 << DMAC_DCMD_SWDH_BIT) -+ #define DMAC_DCMD_SWDH_32 (0 << DMAC_DCMD_SWDH_BIT) -+ #define DMAC_DCMD_SWDH_8 (1 << DMAC_DCMD_SWDH_BIT) -+ #define DMAC_DCMD_SWDH_16 (2 << DMAC_DCMD_SWDH_BIT) -+#define DMAC_DCMD_DWDH_BIT 12 /* dest port width */ -+#define DMAC_DCMD_DWDH_MASK (0x03 << DMAC_DCMD_DWDH_BIT) -+ #define DMAC_DCMD_DWDH_32 (0 << DMAC_DCMD_DWDH_BIT) -+ #define DMAC_DCMD_DWDH_8 (1 << DMAC_DCMD_DWDH_BIT) -+ #define DMAC_DCMD_DWDH_16 (2 << DMAC_DCMD_DWDH_BIT) -+#define DMAC_DCMD_DS_BIT 8 /* transfer data size of a data unit */ -+#define DMAC_DCMD_DS_MASK (0x07 << DMAC_DCMD_DS_BIT) -+ #define DMAC_DCMD_DS_32BIT (0 << DMAC_DCMD_DS_BIT) -+ #define DMAC_DCMD_DS_8BIT (1 << DMAC_DCMD_DS_BIT) -+ #define DMAC_DCMD_DS_16BIT (2 << DMAC_DCMD_DS_BIT) -+ #define DMAC_DCMD_DS_16BYTE (3 << DMAC_DCMD_DS_BIT) -+ #define DMAC_DCMD_DS_32BYTE (4 << DMAC_DCMD_DS_BIT) -+#define DMAC_DCMD_TM (1 << 7) /* transfer mode: 0-single 1-block */ -+#define DMAC_DCMD_DES_V (1 << 4) /* descriptor valid flag */ -+#define DMAC_DCMD_DES_VM (1 << 3) /* descriptor valid mask: 1:support V-bit */ -+#define DMAC_DCMD_DES_VIE (1 << 2) /* DMA valid error interrupt enable */ -+#define DMAC_DCMD_TIE (1 << 1) /* DMA transfer interrupt enable */ -+#define DMAC_DCMD_LINK (1 << 0) /* descriptor link enable */ -+ -+// DMA descriptor address register -+#define DMAC_DDA_BASE_BIT 12 /* descriptor base address */ -+#define DMAC_DDA_BASE_MASK (0x0fffff << DMAC_DDA_BASE_BIT) -+#define DMAC_DDA_OFFSET_BIT 4 /* descriptor offset address */ -+#define DMAC_DDA_OFFSET_MASK (0x0ff << DMAC_DDA_OFFSET_BIT) -+ -+// DMA control register -+#define DMAC_DMACR_PR_BIT 8 /* channel priority mode */ -+#define DMAC_DMACR_PR_MASK (0x03 << DMAC_DMACR_PR_BIT) -+ #define DMAC_DMACR_PR_012345 (0 << DMAC_DMACR_PR_BIT) -+ #define DMAC_DMACR_PR_023145 (1 << DMAC_DMACR_PR_BIT) -+ #define DMAC_DMACR_PR_201345 (2 << DMAC_DMACR_PR_BIT) -+ #define DMAC_DMACR_PR_RR (3 << DMAC_DMACR_PR_BIT) /* round robin */ -+#define DMAC_DMACR_HLT (1 << 3) /* DMA halt flag */ -+#define DMAC_DMACR_AR (1 << 2) /* address error flag */ -+#define DMAC_DMACR_DMAE (1 << 0) /* DMA enable bit */ -+ -+// DMA doorbell register -+#define DMAC_DMADBR_DB5 (1 << 5) /* doorbell for channel 5 */ -+#define DMAC_DMADBR_DB4 (1 << 5) /* doorbell for channel 4 */ -+#define DMAC_DMADBR_DB3 (1 << 5) /* doorbell for channel 3 */ -+#define DMAC_DMADBR_DB2 (1 << 5) /* doorbell for channel 2 */ -+#define DMAC_DMADBR_DB1 (1 << 5) /* doorbell for channel 1 */ -+#define DMAC_DMADBR_DB0 (1 << 5) /* doorbell for channel 0 */ -+ -+// DMA doorbell set register -+#define DMAC_DMADBSR_DBS5 (1 << 5) /* enable doorbell for channel 5 */ -+#define DMAC_DMADBSR_DBS4 (1 << 5) /* enable doorbell for channel 4 */ -+#define DMAC_DMADBSR_DBS3 (1 << 5) /* enable doorbell for channel 3 */ -+#define DMAC_DMADBSR_DBS2 (1 << 5) /* enable doorbell for channel 2 */ -+#define DMAC_DMADBSR_DBS1 (1 << 5) /* enable doorbell for channel 1 */ -+#define DMAC_DMADBSR_DBS0 (1 << 5) /* enable doorbell for channel 0 */ -+ -+// DMA interrupt pending register -+#define DMAC_DMAIPR_CIRQ5 (1 << 5) /* irq pending status for channel 5 */ -+#define DMAC_DMAIPR_CIRQ4 (1 << 4) /* irq pending status for channel 4 */ -+#define DMAC_DMAIPR_CIRQ3 (1 << 3) /* irq pending status for channel 3 */ -+#define DMAC_DMAIPR_CIRQ2 (1 << 2) /* irq pending status for channel 2 */ -+#define DMAC_DMAIPR_CIRQ1 (1 << 1) /* irq pending status for channel 1 */ -+#define DMAC_DMAIPR_CIRQ0 (1 << 0) /* irq pending status for channel 0 */ -+ -+ -+/************************************************************************* -+ * GPIO (General-Purpose I/O Ports) -+ *************************************************************************/ -+#define MAX_GPIO_NUM 128 -+ -+//n = 0,1,2,3 -+#define GPIO_PXPIN(n) (GPIO_BASE + (0x00 + (n)*0x100)) /* PIN Level Register */ -+#define GPIO_PXDAT(n) (GPIO_BASE + (0x10 + (n)*0x100)) /* Port Data Register */ -+#define GPIO_PXDATS(n) (GPIO_BASE + (0x14 + (n)*0x100)) /* Port Data Set Register */ -+#define GPIO_PXDATC(n) (GPIO_BASE + (0x18 + (n)*0x100)) /* Port Data Clear Register */ -+#define GPIO_PXIM(n) (GPIO_BASE + (0x20 + (n)*0x100)) /* Interrupt Mask Register */ -+#define GPIO_PXIMS(n) (GPIO_BASE + (0x24 + (n)*0x100)) /* Interrupt Mask Set Reg */ -+#define GPIO_PXIMC(n) (GPIO_BASE + (0x28 + (n)*0x100)) /* Interrupt Mask Clear Reg */ -+#define GPIO_PXPE(n) (GPIO_BASE + (0x30 + (n)*0x100)) /* Pull Enable Register */ -+#define GPIO_PXPES(n) (GPIO_BASE + (0x34 + (n)*0x100)) /* Pull Enable Set Reg. */ -+#define GPIO_PXPEC(n) (GPIO_BASE + (0x38 + (n)*0x100)) /* Pull Enable Clear Reg. */ -+#define GPIO_PXFUN(n) (GPIO_BASE + (0x40 + (n)*0x100)) /* Function Register */ -+#define GPIO_PXFUNS(n) (GPIO_BASE + (0x44 + (n)*0x100)) /* Function Set Register */ -+#define GPIO_PXFUNC(n) (GPIO_BASE + (0x48 + (n)*0x100)) /* Function Clear Register */ -+#define GPIO_PXSEL(n) (GPIO_BASE + (0x50 + (n)*0x100)) /* Select Register */ -+#define GPIO_PXSELS(n) (GPIO_BASE + (0x54 + (n)*0x100)) /* Select Set Register */ -+#define GPIO_PXSELC(n) (GPIO_BASE + (0x58 + (n)*0x100)) /* Select Clear Register */ -+#define GPIO_PXDIR(n) (GPIO_BASE + (0x60 + (n)*0x100)) /* Direction Register */ -+#define GPIO_PXDIRS(n) (GPIO_BASE + (0x64 + (n)*0x100)) /* Direction Set Register */ -+#define GPIO_PXDIRC(n) (GPIO_BASE + (0x68 + (n)*0x100)) /* Direction Clear Register */ -+#define GPIO_PXTRG(n) (GPIO_BASE + (0x70 + (n)*0x100)) /* Trigger Register */ -+#define GPIO_PXTRGS(n) (GPIO_BASE + (0x74 + (n)*0x100)) /* Trigger Set Register */ -+#define GPIO_PXTRGC(n) (GPIO_BASE + (0x78 + (n)*0x100)) /* Trigger Set Register */ -+#define GPIO_PXFLG(n) (GPIO_BASE + (0x80 + (n)*0x100)) /* Port Flag Register */ -+#define GPIO_PXFLGC(n) (GPIO_BASE + (0x14 + (n)*0x100)) /* Port Flag Clear Register */ -+ -+#define REG_GPIO_PXPIN(n) REG32(GPIO_PXPIN((n))) /* PIN level */ -+#define REG_GPIO_PXDAT(n) REG32(GPIO_PXDAT((n))) /* 1: interrupt pending */ -+#define REG_GPIO_PXDATS(n) REG32(GPIO_PXDATS((n))) -+#define REG_GPIO_PXDATC(n) REG32(GPIO_PXDATC((n))) -+#define REG_GPIO_PXIM(n) REG32(GPIO_PXIM((n))) /* 1: mask pin interrupt */ -+#define REG_GPIO_PXIMS(n) REG32(GPIO_PXIMS((n))) -+#define REG_GPIO_PXIMC(n) REG32(GPIO_PXIMC((n))) -+#define REG_GPIO_PXPE(n) REG32(GPIO_PXPE((n))) /* 1: disable pull up/down */ -+#define REG_GPIO_PXPES(n) REG32(GPIO_PXPES((n))) -+#define REG_GPIO_PXPEC(n) REG32(GPIO_PXPEC((n))) -+#define REG_GPIO_PXFUN(n) REG32(GPIO_PXFUN((n))) /* 0:GPIO or intr, 1:FUNC */ -+#define REG_GPIO_PXFUNS(n) REG32(GPIO_PXFUNS((n))) -+#define REG_GPIO_PXFUNC(n) REG32(GPIO_PXFUNC((n))) -+#define REG_GPIO_PXSEL(n) REG32(GPIO_PXSEL((n))) /* 0:GPIO/Fun0,1:intr/fun1*/ -+#define REG_GPIO_PXSELS(n) REG32(GPIO_PXSELS((n))) -+#define REG_GPIO_PXSELC(n) REG32(GPIO_PXSELC((n))) -+#define REG_GPIO_PXDIR(n) REG32(GPIO_PXDIR((n))) /* 0:input/low-level-trig/falling-edge-trig, 1:output/high-level-trig/rising-edge-trig */ -+#define REG_GPIO_PXDIRS(n) REG32(GPIO_PXDIRS((n))) -+#define REG_GPIO_PXDIRC(n) REG32(GPIO_PXDIRC((n))) -+#define REG_GPIO_PXTRG(n) REG32(GPIO_PXTRG((n))) /* 0:level-trigger, 1:edge-trigger */ -+#define REG_GPIO_PXTRGS(n) REG32(GPIO_PXTRGS((n))) -+#define REG_GPIO_PXTRGC(n) REG32(GPIO_PXTRGC((n))) -+#define REG_GPIO_PXFLG(n) REG32(GPIO_PXFLG((n))) /* interrupt flag */ -+#define REG_GPIO_PXFLGC(n) REG32(GPIO_PXFLGC((n))) /* interrupt flag */ -+ -+ -+/************************************************************************* -+ * UART -+ *************************************************************************/ -+ -+#define IRDA_BASE UART0_BASE -+#define UART_BASE UART0_BASE -+#define UART_OFF 0x1000 -+ -+/* Register Offset */ -+#define OFF_RDR (0x00) /* R 8b H'xx */ -+#define OFF_TDR (0x00) /* W 8b H'xx */ -+#define OFF_DLLR (0x00) /* RW 8b H'00 */ -+#define OFF_DLHR (0x04) /* RW 8b H'00 */ -+#define OFF_IER (0x04) /* RW 8b H'00 */ -+#define OFF_ISR (0x08) /* R 8b H'01 */ -+#define OFF_FCR (0x08) /* W 8b H'00 */ -+#define OFF_LCR (0x0C) /* RW 8b H'00 */ -+#define OFF_MCR (0x10) /* RW 8b H'00 */ -+#define OFF_LSR (0x14) /* R 8b H'00 */ -+#define OFF_MSR (0x18) /* R 8b H'00 */ -+#define OFF_SPR (0x1C) /* RW 8b H'00 */ -+#define OFF_SIRCR (0x20) /* RW 8b H'00, UART0 */ -+#define OFF_UMR (0x24) /* RW 8b H'00, UART M Register */ -+#define OFF_UACR (0x28) /* RW 8b H'00, UART Add Cycle Register */ -+ -+/* Register Address */ -+#define UART0_RDR (UART0_BASE + OFF_RDR) -+#define UART0_TDR (UART0_BASE + OFF_TDR) -+#define UART0_DLLR (UART0_BASE + OFF_DLLR) -+#define UART0_DLHR (UART0_BASE + OFF_DLHR) -+#define UART0_IER (UART0_BASE + OFF_IER) -+#define UART0_ISR (UART0_BASE + OFF_ISR) -+#define UART0_FCR (UART0_BASE + OFF_FCR) -+#define UART0_LCR (UART0_BASE + OFF_LCR) -+#define UART0_MCR (UART0_BASE + OFF_MCR) -+#define UART0_LSR (UART0_BASE + OFF_LSR) -+#define UART0_MSR (UART0_BASE + OFF_MSR) -+#define UART0_SPR (UART0_BASE + OFF_SPR) -+#define UART0_SIRCR (UART0_BASE + OFF_SIRCR) -+#define UART0_UMR (UART0_BASE + OFF_UMR) -+#define UART0_UACR (UART0_BASE + OFF_UACR) -+ -+/* -+ * Define macros for UARTIER -+ * UART Interrupt Enable Register -+ */ -+#define UARTIER_RIE (1 << 0) /* 0: receive fifo full interrupt disable */ -+#define UARTIER_TIE (1 << 1) /* 0: transmit fifo empty interrupt disable */ -+#define UARTIER_RLIE (1 << 2) /* 0: receive line status interrupt disable */ -+#define UARTIER_MIE (1 << 3) /* 0: modem status interrupt disable */ -+#define UARTIER_RTIE (1 << 4) /* 0: receive timeout interrupt disable */ -+ -+/* -+ * Define macros for UARTISR -+ * UART Interrupt Status Register -+ */ -+#define UARTISR_IP (1 << 0) /* 0: interrupt is pending 1: no interrupt */ -+#define UARTISR_IID (7 << 1) /* Source of Interrupt */ -+#define UARTISR_IID_MSI (0 << 1) /* Modem status interrupt */ -+#define UARTISR_IID_THRI (1 << 1) /* Transmitter holding register empty */ -+#define UARTISR_IID_RDI (2 << 1) /* Receiver data interrupt */ -+#define UARTISR_IID_RLSI (3 << 1) /* Receiver line status interrupt */ -+#define UARTISR_IID_RTO (6 << 1) /* Receive timeout */ -+#define UARTISR_FFMS (3 << 6) /* FIFO mode select, set when UARTFCR.FE is set to 1 */ -+#define UARTISR_FFMS_NO_FIFO (0 << 6) -+#define UARTISR_FFMS_FIFO_MODE (3 << 6) -+ -+/* -+ * Define macros for UARTFCR -+ * UART FIFO Control Register -+ */ -+#define UARTFCR_FE (1 << 0) /* 0: non-FIFO mode 1: FIFO mode */ -+#define UARTFCR_RFLS (1 << 1) /* write 1 to flush receive FIFO */ -+#define UARTFCR_TFLS (1 << 2) /* write 1 to flush transmit FIFO */ -+#define UARTFCR_DMS (1 << 3) /* 0: disable DMA mode */ -+#define UARTFCR_UUE (1 << 4) /* 0: disable UART */ -+#define UARTFCR_RTRG (3 << 6) /* Receive FIFO Data Trigger */ -+#define UARTFCR_RTRG_1 (0 << 6) -+#define UARTFCR_RTRG_4 (1 << 6) -+#define UARTFCR_RTRG_8 (2 << 6) -+#define UARTFCR_RTRG_15 (3 << 6) -+ -+/* -+ * Define macros for UARTLCR -+ * UART Line Control Register -+ */ -+#define UARTLCR_WLEN (3 << 0) /* word length */ -+#define UARTLCR_WLEN_5 (0 << 0) -+#define UARTLCR_WLEN_6 (1 << 0) -+#define UARTLCR_WLEN_7 (2 << 0) -+#define UARTLCR_WLEN_8 (3 << 0) -+#define UARTLCR_STOP (1 << 2) /* 0: 1 stop bit when word length is 5,6,7,8 -+ 1: 1.5 stop bits when 5; 2 stop bits when 6,7,8 */ -+#define UARTLCR_STOP1 (0 << 2) -+#define UARTLCR_STOP2 (1 << 2) -+#define UARTLCR_PE (1 << 3) /* 0: parity disable */ -+#define UARTLCR_PROE (1 << 4) /* 0: even parity 1: odd parity */ -+#define UARTLCR_SPAR (1 << 5) /* 0: sticky parity disable */ -+#define UARTLCR_SBRK (1 << 6) /* write 0 normal, write 1 send break */ -+#define UARTLCR_DLAB (1 << 7) /* 0: access UARTRDR/TDR/IER 1: access UARTDLLR/DLHR */ -+ -+/* -+ * Define macros for UARTLSR -+ * UART Line Status Register -+ */ -+#define UARTLSR_DR (1 << 0) /* 0: receive FIFO is empty 1: receive data is ready */ -+#define UARTLSR_ORER (1 << 1) /* 0: no overrun error */ -+#define UARTLSR_PER (1 << 2) /* 0: no parity error */ -+#define UARTLSR_FER (1 << 3) /* 0; no framing error */ -+#define UARTLSR_BRK (1 << 4) /* 0: no break detected 1: receive a break signal */ -+#define UARTLSR_TDRQ (1 << 5) /* 1: transmit FIFO half "empty" */ -+#define UARTLSR_TEMT (1 << 6) /* 1: transmit FIFO and shift registers empty */ -+#define UARTLSR_RFER (1 << 7) /* 0: no receive error 1: receive error in FIFO mode */ -+ -+/* -+ * Define macros for UARTMCR -+ * UART Modem Control Register -+ */ -+#define UARTMCR_RTS (1 << 1) /* 0: RTS_ output high, 1: RTS_ output low */ -+#define UARTMCR_LOOP (1 << 4) /* 0: normal 1: loopback mode */ -+#define UARTMCR_MCE (1 << 7) /* 0: modem function is disable */ -+ -+/* -+ * Define macros for UARTMSR -+ * UART Modem Status Register -+ */ -+#define UARTMSR_CCTS (1 << 0) /* 1: a change on CTS_ pin */ -+#define UARTMSR_CTS (1 << 4) /* 0: CTS_ pin is high */ -+ -+/* -+ * Define macros for SIRCR -+ * Slow IrDA Control Register -+ */ -+#define SIRCR_TSIRE (1 << 0) /* 0: transmitter is in UART mode 1: SIR mode */ -+#define SIRCR_RSIRE (1 << 1) /* 0: receiver is in UART mode 1: SIR mode */ -+#define SIRCR_TPWS (1 << 2) /* 0: transmit 0 pulse width is 3/16 of bit length -+ 1: 0 pulse width is 1.6us for 115.2Kbps */ -+#define SIRCR_TDPL (1 << 3) /* 0: encoder generates a positive pulse for 0 */ -+#define SIRCR_RDPL (1 << 4) /* 0: decoder interprets positive pulse as 0 */ -+ -+ -+/************************************************************************* -+ * AIC (AC97/I2S Controller) -+ *************************************************************************/ -+#define AIC_FR (AIC_BASE + 0x000) -+#define AIC_CR (AIC_BASE + 0x004) -+#define AIC_ACCR1 (AIC_BASE + 0x008) -+#define AIC_ACCR2 (AIC_BASE + 0x00C) -+#define AIC_I2SCR (AIC_BASE + 0x010) -+#define AIC_SR (AIC_BASE + 0x014) -+#define AIC_ACSR (AIC_BASE + 0x018) -+#define AIC_I2SSR (AIC_BASE + 0x01C) -+#define AIC_ACCAR (AIC_BASE + 0x020) -+#define AIC_ACCDR (AIC_BASE + 0x024) -+#define AIC_ACSAR (AIC_BASE + 0x028) -+#define AIC_ACSDR (AIC_BASE + 0x02C) -+#define AIC_I2SDIV (AIC_BASE + 0x030) -+#define AIC_DR (AIC_BASE + 0x034) -+ -+#define REG_AIC_FR REG32(AIC_FR) -+#define REG_AIC_CR REG32(AIC_CR) -+#define REG_AIC_ACCR1 REG32(AIC_ACCR1) -+#define REG_AIC_ACCR2 REG32(AIC_ACCR2) -+#define REG_AIC_I2SCR REG32(AIC_I2SCR) -+#define REG_AIC_SR REG32(AIC_SR) -+#define REG_AIC_ACSR REG32(AIC_ACSR) -+#define REG_AIC_I2SSR REG32(AIC_I2SSR) -+#define REG_AIC_ACCAR REG32(AIC_ACCAR) -+#define REG_AIC_ACCDR REG32(AIC_ACCDR) -+#define REG_AIC_ACSAR REG32(AIC_ACSAR) -+#define REG_AIC_ACSDR REG32(AIC_ACSDR) -+#define REG_AIC_I2SDIV REG32(AIC_I2SDIV) -+#define REG_AIC_DR REG32(AIC_DR) -+ -+/* AIC Controller Configuration Register (AIC_FR) */ -+ -+#define AIC_FR_RFTH_BIT 12 /* Receive FIFO Threshold */ -+#define AIC_FR_RFTH_MASK (0xf << AIC_FR_RFTH_BIT) -+#define AIC_FR_TFTH_BIT 8 /* Transmit FIFO Threshold */ -+#define AIC_FR_TFTH_MASK (0xf << AIC_FR_TFTH_BIT) -+#define AIC_FR_LSMP (1 << 6) /* Play Zero sample or last sample */ -+#define AIC_FR_ICDC (1 << 5) /* External(0) or Internal CODEC(1) */ -+#define AIC_FR_AUSEL (1 << 4) /* AC97(0) or I2S/MSB-justified(1) */ -+#define AIC_FR_RST (1 << 3) /* AIC registers reset */ -+#define AIC_FR_BCKD (1 << 2) /* I2S BIT_CLK direction, 0:input,1:output */ -+#define AIC_FR_SYNCD (1 << 1) /* I2S SYNC direction, 0:input,1:output */ -+#define AIC_FR_ENB (1 << 0) /* AIC enable bit */ -+ -+/* AIC Controller Common Control Register (AIC_CR) */ -+ -+#define AIC_CR_OSS_BIT 19 /* Output Sample Size from memory (AIC V2 only) */ -+#define AIC_CR_OSS_MASK (0x7 << AIC_CR_OSS_BIT) -+ #define AIC_CR_OSS_8BIT (0x0 << AIC_CR_OSS_BIT) -+ #define AIC_CR_OSS_16BIT (0x1 << AIC_CR_OSS_BIT) -+ #define AIC_CR_OSS_18BIT (0x2 << AIC_CR_OSS_BIT) -+ #define AIC_CR_OSS_20BIT (0x3 << AIC_CR_OSS_BIT) -+ #define AIC_CR_OSS_24BIT (0x4 << AIC_CR_OSS_BIT) -+#define AIC_CR_ISS_BIT 16 /* Input Sample Size from memory (AIC V2 only) */ -+#define AIC_CR_ISS_MASK (0x7 << AIC_CR_ISS_BIT) -+ #define AIC_CR_ISS_8BIT (0x0 << AIC_CR_ISS_BIT) -+ #define AIC_CR_ISS_16BIT (0x1 << AIC_CR_ISS_BIT) -+ #define AIC_CR_ISS_18BIT (0x2 << AIC_CR_ISS_BIT) -+ #define AIC_CR_ISS_20BIT (0x3 << AIC_CR_ISS_BIT) -+ #define AIC_CR_ISS_24BIT (0x4 << AIC_CR_ISS_BIT) -+#define AIC_CR_RDMS (1 << 15) /* Receive DMA enable */ -+#define AIC_CR_TDMS (1 << 14) /* Transmit DMA enable */ -+#define AIC_CR_M2S (1 << 11) /* Mono to Stereo enable */ -+#define AIC_CR_ENDSW (1 << 10) /* Endian switch enable */ -+#define AIC_CR_AVSTSU (1 << 9) /* Signed <-> Unsigned toggle enable */ -+#define AIC_CR_FLUSH (1 << 8) /* Flush FIFO */ -+#define AIC_CR_EROR (1 << 6) /* Enable ROR interrupt */ -+#define AIC_CR_ETUR (1 << 5) /* Enable TUR interrupt */ -+#define AIC_CR_ERFS (1 << 4) /* Enable RFS interrupt */ -+#define AIC_CR_ETFS (1 << 3) /* Enable TFS interrupt */ -+#define AIC_CR_ENLBF (1 << 2) /* Enable Loopback Function */ -+#define AIC_CR_ERPL (1 << 1) /* Enable Playback Function */ -+#define AIC_CR_EREC (1 << 0) /* Enable Record Function */ -+ -+/* AIC Controller AC-link Control Register 1 (AIC_ACCR1) */ -+ -+#define AIC_ACCR1_RS_BIT 16 /* Receive Valid Slots */ -+#define AIC_ACCR1_RS_MASK (0x3ff << AIC_ACCR1_RS_BIT) -+ #define AIC_ACCR1_RS_SLOT12 (1 << 25) /* Slot 12 valid bit */ -+ #define AIC_ACCR1_RS_SLOT11 (1 << 24) /* Slot 11 valid bit */ -+ #define AIC_ACCR1_RS_SLOT10 (1 << 23) /* Slot 10 valid bit */ -+ #define AIC_ACCR1_RS_SLOT9 (1 << 22) /* Slot 9 valid bit, LFE */ -+ #define AIC_ACCR1_RS_SLOT8 (1 << 21) /* Slot 8 valid bit, Surround Right */ -+ #define AIC_ACCR1_RS_SLOT7 (1 << 20) /* Slot 7 valid bit, Surround Left */ -+ #define AIC_ACCR1_RS_SLOT6 (1 << 19) /* Slot 6 valid bit, PCM Center */ -+ #define AIC_ACCR1_RS_SLOT5 (1 << 18) /* Slot 5 valid bit */ -+ #define AIC_ACCR1_RS_SLOT4 (1 << 17) /* Slot 4 valid bit, PCM Right */ -+ #define AIC_ACCR1_RS_SLOT3 (1 << 16) /* Slot 3 valid bit, PCM Left */ -+#define AIC_ACCR1_XS_BIT 0 /* Transmit Valid Slots */ -+#define AIC_ACCR1_XS_MASK (0x3ff << AIC_ACCR1_XS_BIT) -+ #define AIC_ACCR1_XS_SLOT12 (1 << 9) /* Slot 12 valid bit */ -+ #define AIC_ACCR1_XS_SLOT11 (1 << 8) /* Slot 11 valid bit */ -+ #define AIC_ACCR1_XS_SLOT10 (1 << 7) /* Slot 10 valid bit */ -+ #define AIC_ACCR1_XS_SLOT9 (1 << 6) /* Slot 9 valid bit, LFE */ -+ #define AIC_ACCR1_XS_SLOT8 (1 << 5) /* Slot 8 valid bit, Surround Right */ -+ #define AIC_ACCR1_XS_SLOT7 (1 << 4) /* Slot 7 valid bit, Surround Left */ -+ #define AIC_ACCR1_XS_SLOT6 (1 << 3) /* Slot 6 valid bit, PCM Center */ -+ #define AIC_ACCR1_XS_SLOT5 (1 << 2) /* Slot 5 valid bit */ -+ #define AIC_ACCR1_XS_SLOT4 (1 << 1) /* Slot 4 valid bit, PCM Right */ -+ #define AIC_ACCR1_XS_SLOT3 (1 << 0) /* Slot 3 valid bit, PCM Left */ -+ -+/* AIC Controller AC-link Control Register 2 (AIC_ACCR2) */ -+ -+#define AIC_ACCR2_ERSTO (1 << 18) /* Enable RSTO interrupt */ -+#define AIC_ACCR2_ESADR (1 << 17) /* Enable SADR interrupt */ -+#define AIC_ACCR2_ECADT (1 << 16) /* Enable CADT interrupt */ -+#define AIC_ACCR2_OASS_BIT 8 /* Output Sample Size for AC-link */ -+#define AIC_ACCR2_OASS_MASK (0x3 << AIC_ACCR2_OASS_BIT) -+ #define AIC_ACCR2_OASS_20BIT (0 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 20-bit */ -+ #define AIC_ACCR2_OASS_18BIT (1 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 18-bit */ -+ #define AIC_ACCR2_OASS_16BIT (2 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 16-bit */ -+ #define AIC_ACCR2_OASS_8BIT (3 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 8-bit */ -+#define AIC_ACCR2_IASS_BIT 6 /* Output Sample Size for AC-link */ -+#define AIC_ACCR2_IASS_MASK (0x3 << AIC_ACCR2_IASS_BIT) -+ #define AIC_ACCR2_IASS_20BIT (0 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 20-bit */ -+ #define AIC_ACCR2_IASS_18BIT (1 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 18-bit */ -+ #define AIC_ACCR2_IASS_16BIT (2 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 16-bit */ -+ #define AIC_ACCR2_IASS_8BIT (3 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 8-bit */ -+#define AIC_ACCR2_SO (1 << 3) /* SDATA_OUT output value */ -+#define AIC_ACCR2_SR (1 << 2) /* RESET# pin level */ -+#define AIC_ACCR2_SS (1 << 1) /* SYNC pin level */ -+#define AIC_ACCR2_SA (1 << 0) /* SYNC and SDATA_OUT alternation */ -+ -+/* AIC Controller I2S/MSB-justified Control Register (AIC_I2SCR) */ -+ -+#define AIC_I2SCR_STPBK (1 << 12) /* Stop BIT_CLK for I2S/MSB-justified */ -+#define AIC_I2SCR_WL_BIT 1 /* Input/Output Sample Size for I2S/MSB-justified */ -+#define AIC_I2SCR_WL_MASK (0x7 << AIC_I2SCR_WL_BIT) -+ #define AIC_I2SCR_WL_24BIT (0 << AIC_I2SCR_WL_BIT) /* Word Length is 24 bit */ -+ #define AIC_I2SCR_WL_20BIT (1 << AIC_I2SCR_WL_BIT) /* Word Length is 20 bit */ -+ #define AIC_I2SCR_WL_18BIT (2 << AIC_I2SCR_WL_BIT) /* Word Length is 18 bit */ -+ #define AIC_I2SCR_WL_16BIT (3 << AIC_I2SCR_WL_BIT) /* Word Length is 16 bit */ -+ #define AIC_I2SCR_WL_8BIT (4 << AIC_I2SCR_WL_BIT) /* Word Length is 8 bit */ -+#define AIC_I2SCR_AMSL (1 << 0) /* 0:I2S, 1:MSB-justified */ -+ -+/* AIC Controller FIFO Status Register (AIC_SR) */ -+ -+#define AIC_SR_RFL_BIT 24 /* Receive FIFO Level */ -+#define AIC_SR_RFL_MASK (0x3f << AIC_SR_RFL_BIT) -+#define AIC_SR_TFL_BIT 8 /* Transmit FIFO level */ -+#define AIC_SR_TFL_MASK (0x3f << AIC_SR_TFL_BIT) -+#define AIC_SR_ROR (1 << 6) /* Receive FIFO Overrun */ -+#define AIC_SR_TUR (1 << 5) /* Transmit FIFO Underrun */ -+#define AIC_SR_RFS (1 << 4) /* Receive FIFO Service Request */ -+#define AIC_SR_TFS (1 << 3) /* Transmit FIFO Service Request */ -+ -+/* AIC Controller AC-link Status Register (AIC_ACSR) */ -+ -+#define AIC_ACSR_SLTERR (1 << 21) /* Slot Error Flag */ -+#define AIC_ACSR_CRDY (1 << 20) /* External CODEC Ready Flag */ -+#define AIC_ACSR_CLPM (1 << 19) /* External CODEC low power mode flag */ -+#define AIC_ACSR_RSTO (1 << 18) /* External CODEC regs read status timeout */ -+#define AIC_ACSR_SADR (1 << 17) /* External CODEC regs status addr and data received */ -+#define AIC_ACSR_CADT (1 << 16) /* Command Address and Data Transmitted */ -+ -+/* AIC Controller I2S/MSB-justified Status Register (AIC_I2SSR) */ -+ -+#define AIC_I2SSR_BSY (1 << 2) /* AIC Busy in I2S/MSB-justified format */ -+ -+/* AIC Controller AC97 codec Command Address Register (AIC_ACCAR) */ -+ -+#define AIC_ACCAR_CAR_BIT 0 -+#define AIC_ACCAR_CAR_MASK (0xfffff << AIC_ACCAR_CAR_BIT) -+ -+/* AIC Controller AC97 codec Command Data Register (AIC_ACCDR) */ -+ -+#define AIC_ACCDR_CDR_BIT 0 -+#define AIC_ACCDR_CDR_MASK (0xfffff << AIC_ACCDR_CDR_BIT) -+ -+/* AIC Controller AC97 codec Status Address Register (AIC_ACSAR) */ -+ -+#define AIC_ACSAR_SAR_BIT 0 -+#define AIC_ACSAR_SAR_MASK (0xfffff << AIC_ACSAR_SAR_BIT) -+ -+/* AIC Controller AC97 codec Status Data Register (AIC_ACSDR) */ -+ -+#define AIC_ACSDR_SDR_BIT 0 -+#define AIC_ACSDR_SDR_MASK (0xfffff << AIC_ACSDR_SDR_BIT) -+ -+/* AIC Controller I2S/MSB-justified Clock Divider Register (AIC_I2SDIV) */ -+ -+#define AIC_I2SDIV_DIV_BIT 0 -+#define AIC_I2SDIV_DIV_MASK (0x7f << AIC_I2SDIV_DIV_BIT) -+ #define AIC_I2SDIV_BITCLK_3072KHZ (0x0C << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 3.072MHz */ -+ #define AIC_I2SDIV_BITCLK_2836KHZ (0x0D << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 2.836MHz */ -+ #define AIC_I2SDIV_BITCLK_1418KHZ (0x1A << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 1.418MHz */ -+ #define AIC_I2SDIV_BITCLK_1024KHZ (0x24 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 1.024MHz */ -+ #define AIC_I2SDIV_BITCLK_7089KHZ (0x34 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 708.92KHz */ -+ #define AIC_I2SDIV_BITCLK_512KHZ (0x48 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 512.00KHz */ -+ -+ -+/************************************************************************* -+ * ICDC (Internal CODEC) -+ *************************************************************************/ -+#define ICDC_CR (ICDC_BASE + 0x0400) /* ICDC Control Register */ -+#define ICDC_APWAIT (ICDC_BASE + 0x0404) /* Anti-Pop WAIT Stage Timing Control Register */ -+#define ICDC_APPRE (ICDC_BASE + 0x0408) /* Anti-Pop HPEN-PRE Stage Timing Control Register */ -+#define ICDC_APHPEN (ICDC_BASE + 0x040C) /* Anti-Pop HPEN Stage Timing Control Register */ -+#define ICDC_APSR (ICDC_BASE + 0x0410) /* Anti-Pop Status Register */ -+#define ICDC_CDCCR1 (ICDC_BASE + 0x0080) -+#define ICDC_CDCCR2 (ICDC_BASE + 0x0084) -+ -+#define REG_ICDC_CR REG32(ICDC_CR) -+#define REG_ICDC_APWAIT REG32(ICDC_APWAIT) -+#define REG_ICDC_APPRE REG32(ICDC_APPRE) -+#define REG_ICDC_APHPEN REG32(ICDC_APHPEN) -+#define REG_ICDC_APSR REG32(ICDC_APSR) -+#define REG_ICDC_CDCCR1 REG32(ICDC_CDCCR1) -+#define REG_ICDC_CDCCR2 REG32(ICDC_CDCCR2) -+ -+/* ICDC Control Register */ -+#define ICDC_CR_LINVOL_BIT 24 /* LINE Input Volume Gain: GAIN=LINVOL*1.5-34.5 */ -+#define ICDC_CR_LINVOL_MASK (0x1f << ICDC_CR_LINVOL_BIT) -+#define ICDC_CR_ASRATE_BIT 20 /* Audio Sample Rate */ -+#define ICDC_CR_ASRATE_MASK (0x0f << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_8000 (0x0 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_11025 (0x1 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_12000 (0x2 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_16000 (0x3 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_22050 (0x4 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_24000 (0x5 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_32000 (0x6 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_44100 (0x7 << ICDC_CR_ASRATE_BIT) -+ #define ICDC_CR_ASRATE_48000 (0x8 << ICDC_CR_ASRATE_BIT) -+#define ICDC_CR_MICBG_BIT 18 /* MIC Boost Gain */ -+#define ICDC_CR_MICBG_MASK (0x3 << ICDC_CR_MICBG_BIT) -+ #define ICDC_CR_MICBG_0DB (0x0 << ICDC_CR_MICBG_BIT) -+ #define ICDC_CR_MICBG_6DB (0x1 << ICDC_CR_MICBG_BIT) -+ #define ICDC_CR_MICBG_12DB (0x2 << ICDC_CR_MICBG_BIT) -+ #define ICDC_CR_MICBG_20DB (0x3 << ICDC_CR_MICBG_BIT) -+#define ICDC_CR_HPVOL_BIT 16 /* Headphone Volume Gain */ -+#define ICDC_CR_HPVOL_MASK (0x3 << ICDC_CR_HPVOL_BIT) -+ #define ICDC_CR_HPVOL_0DB (0x0 << ICDC_CR_HPVOL_BIT) -+ #define ICDC_CR_HPVOL_2DB (0x1 << ICDC_CR_HPVOL_BIT) -+ #define ICDC_CR_HPVOL_4DB (0x2 << ICDC_CR_HPVOL_BIT) -+ #define ICDC_CR_HPVOL_6DB (0x3 << ICDC_CR_HPVOL_BIT) -+#define ICDC_CR_ELINEIN (1 << 13) /* Enable LINE Input */ -+#define ICDC_CR_EMIC (1 << 12) /* Enable MIC Input */ -+#define ICDC_CR_SW1ON (1 << 11) /* Switch 1 in CODEC is on */ -+#define ICDC_CR_EADC (1 << 10) /* Enable ADC */ -+#define ICDC_CR_SW2ON (1 << 9) /* Switch 2 in CODEC is on */ -+#define ICDC_CR_EDAC (1 << 8) /* Enable DAC */ -+#define ICDC_CR_HPMUTE (1 << 5) /* Headphone Mute */ -+#define ICDC_CR_HPTON (1 << 4) /* Headphone Amplifier Trun On */ -+#define ICDC_CR_HPTOFF (1 << 3) /* Headphone Amplifier Trun Off */ -+#define ICDC_CR_TAAP (1 << 2) /* Turn Around of the Anti-Pop Procedure */ -+#define ICDC_CR_EAP (1 << 1) /* Enable Anti-Pop Procedure */ -+#define ICDC_CR_SUSPD (1 << 0) /* CODEC Suspend */ -+ -+/* Anti-Pop WAIT Stage Timing Control Register */ -+#define ICDC_APWAIT_WAITSN_BIT 0 -+#define ICDC_APWAIT_WAITSN_MASK (0x7ff << ICDC_APWAIT_WAITSN_BIT) -+ -+/* Anti-Pop HPEN-PRE Stage Timing Control Register */ -+#define ICDC_APPRE_PRESN_BIT 0 -+#define ICDC_APPRE_PRESN_MASK (0x1ff << ICDC_APPRE_PRESN_BIT) -+ -+/* Anti-Pop HPEN Stage Timing Control Register */ -+#define ICDC_APHPEN_HPENSN_BIT 0 -+#define ICDC_APHPEN_HPENSN_MASK (0x3fff << ICDC_APHPEN_HPENSN_BIT) -+ -+/* Anti-Pop Status Register */ -+#define ICDC_SR_HPST_BIT 14 /* Headphone Amplifier State */ -+#define ICDC_SR_HPST_MASK (0x7 << ICDC_SR_HPST_BIT) -+#define ICDC_SR_HPST_HP_OFF (0x0 << ICDC_SR_HPST_BIT) /* HP amplifier is off */ -+#define ICDC_SR_HPST_TON_WAIT (0x1 << ICDC_SR_HPST_BIT) /* wait state in turn-on */ -+ #define ICDC_SR_HPST_TON_PRE (0x2 << ICDC_SR_HPST_BIT) /* pre-enable state in turn-on */ -+#define ICDC_SR_HPST_TON_HPEN (0x3 << ICDC_SR_HPST_BIT) /* HP enable state in turn-on */ -+ #define ICDC_SR_HPST_TOFF_HPEN (0x4 << ICDC_SR_HPST_BIT) /* HP enable state in turn-off */ -+ #define ICDC_SR_HPST_TOFF_PRE (0x5 << ICDC_SR_HPST_BIT) /* pre-enable state in turn-off */ -+ #define ICDC_SR_HPST_TOFF_WAIT (0x6 << ICDC_SR_HPST_BIT) /* wait state in turn-off */ -+ #define ICDC_SR_HPST_HP_ON (0x7 << ICDC_SR_HPST_BIT) /* HP amplifier is on */ -+#define ICDC_SR_SNCNT_BIT 0 /* Sample Number Counter */ -+#define ICDC_SR_SNCNT_MASK (0x3fff << ICDC_SR_SNCNT_BIT) -+ -+ -+/************************************************************************* -+ * I2C -+ *************************************************************************/ -+#define I2C_DR (I2C_BASE + 0x000) -+#define I2C_CR (I2C_BASE + 0x004) -+#define I2C_SR (I2C_BASE + 0x008) -+#define I2C_GR (I2C_BASE + 0x00C) -+ -+#define REG_I2C_DR REG8(I2C_DR) -+#define REG_I2C_CR REG8(I2C_CR) -+#define REG_I2C_SR REG8(I2C_SR) -+#define REG_I2C_GR REG16(I2C_GR) -+ -+/* I2C Control Register (I2C_CR) */ -+ -+#define I2C_CR_IEN (1 << 4) -+#define I2C_CR_STA (1 << 3) -+#define I2C_CR_STO (1 << 2) -+#define I2C_CR_AC (1 << 1) -+#define I2C_CR_I2CE (1 << 0) -+ -+/* I2C Status Register (I2C_SR) */ -+ -+#define I2C_SR_STX (1 << 4) -+#define I2C_SR_BUSY (1 << 3) -+#define I2C_SR_TEND (1 << 2) -+#define I2C_SR_DRF (1 << 1) -+#define I2C_SR_ACKF (1 << 0) -+ -+ -+/************************************************************************* -+ * SSI -+ *************************************************************************/ -+#define SSI_DR (SSI_BASE + 0x000) -+#define SSI_CR0 (SSI_BASE + 0x004) -+#define SSI_CR1 (SSI_BASE + 0x008) -+#define SSI_SR (SSI_BASE + 0x00C) -+#define SSI_ITR (SSI_BASE + 0x010) -+#define SSI_ICR (SSI_BASE + 0x014) -+#define SSI_GR (SSI_BASE + 0x018) -+ -+#define REG_SSI_DR REG32(SSI_DR) -+#define REG_SSI_CR0 REG16(SSI_CR0) -+#define REG_SSI_CR1 REG32(SSI_CR1) -+#define REG_SSI_SR REG32(SSI_SR) -+#define REG_SSI_ITR REG16(SSI_ITR) -+#define REG_SSI_ICR REG8(SSI_ICR) -+#define REG_SSI_GR REG16(SSI_GR) -+ -+/* SSI Data Register (SSI_DR) */ -+ -+#define SSI_DR_GPC_BIT 0 -+#define SSI_DR_GPC_MASK (0x1ff << SSI_DR_GPC_BIT) -+ -+/* SSI Control Register 0 (SSI_CR0) */ -+ -+#define SSI_CR0_SSIE (1 << 15) -+#define SSI_CR0_TIE (1 << 14) -+#define SSI_CR0_RIE (1 << 13) -+#define SSI_CR0_TEIE (1 << 12) -+#define SSI_CR0_REIE (1 << 11) -+#define SSI_CR0_LOOP (1 << 10) -+#define SSI_CR0_RFINE (1 << 9) -+#define SSI_CR0_RFINC (1 << 8) -+#define SSI_CR0_FSEL (1 << 6) -+#define SSI_CR0_TFLUSH (1 << 2) -+#define SSI_CR0_RFLUSH (1 << 1) -+#define SSI_CR0_DISREV (1 << 0) -+ -+/* SSI Control Register 1 (SSI_CR1) */ -+ -+#define SSI_CR1_FRMHL_BIT 30 -+#define SSI_CR1_FRMHL_MASK (0x3 << SSI_CR1_FRMHL_BIT) -+ #define SSI_CR1_FRMHL_CELOW_CE2LOW (0 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is low valid and SSI_CE2_ is low valid */ -+ #define SSI_CR1_FRMHL_CEHIGH_CE2LOW (1 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is high valid and SSI_CE2_ is low valid */ -+ #define SSI_CR1_FRMHL_CELOW_CE2HIGH (2 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is low valid and SSI_CE2_ is high valid */ -+ #define SSI_CR1_FRMHL_CEHIGH_CE2HIGH (3 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is high valid and SSI_CE2_ is high valid */ -+#define SSI_CR1_TFVCK_BIT 28 -+#define SSI_CR1_TFVCK_MASK (0x3 << SSI_CR1_TFVCK_BIT) -+ #define SSI_CR1_TFVCK_0 (0 << SSI_CR1_TFVCK_BIT) -+ #define SSI_CR1_TFVCK_1 (1 << SSI_CR1_TFVCK_BIT) -+ #define SSI_CR1_TFVCK_2 (2 << SSI_CR1_TFVCK_BIT) -+ #define SSI_CR1_TFVCK_3 (3 << SSI_CR1_TFVCK_BIT) -+#define SSI_CR1_TCKFI_BIT 26 -+#define SSI_CR1_TCKFI_MASK (0x3 << SSI_CR1_TCKFI_BIT) -+ #define SSI_CR1_TCKFI_0 (0 << SSI_CR1_TCKFI_BIT) -+ #define SSI_CR1_TCKFI_1 (1 << SSI_CR1_TCKFI_BIT) -+ #define SSI_CR1_TCKFI_2 (2 << SSI_CR1_TCKFI_BIT) -+ #define SSI_CR1_TCKFI_3 (3 << SSI_CR1_TCKFI_BIT) -+#define SSI_CR1_LFST (1 << 25) -+#define SSI_CR1_ITFRM (1 << 24) -+#define SSI_CR1_UNFIN (1 << 23) -+#define SSI_CR1_MULTS (1 << 22) -+#define SSI_CR1_FMAT_BIT 20 -+#define SSI_CR1_FMAT_MASK (0x3 << SSI_CR1_FMAT_BIT) -+ #define SSI_CR1_FMAT_SPI (0 << SSI_CR1_FMAT_BIT) /* Motorola¡¯s SPI format */ -+ #define SSI_CR1_FMAT_SSP (1 << SSI_CR1_FMAT_BIT) /* TI's SSP format */ -+ #define SSI_CR1_FMAT_MW1 (2 << SSI_CR1_FMAT_BIT) /* National Microwire 1 format */ -+ #define SSI_CR1_FMAT_MW2 (3 << SSI_CR1_FMAT_BIT) /* National Microwire 2 format */ -+#define SSI_CR1_TTRG_BIT 16 -+#define SSI_CR1_TTRG_MASK (0xf << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_1 (0 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_8 (1 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_16 (2 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_24 (3 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_32 (4 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_40 (5 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_48 (6 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_56 (7 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_64 (8 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_72 (9 << SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_80 (10<< SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_88 (11<< SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_96 (12<< SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_104 (13<< SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_112 (14<< SSI_CR1_TTRG_BIT) -+ #define SSI_CR1_TTRG_120 (15<< SSI_CR1_TTRG_BIT) -+#define SSI_CR1_MCOM_BIT 12 -+#define SSI_CR1_MCOM_MASK (0xf << SSI_CR1_MCOM_BIT) -+ #define SSI_CR1_MCOM_1BIT (0x0 << SSI_CR1_MCOM_BIT) /* 1-bit command selected */ -+ #define SSI_CR1_MCOM_2BIT (0x1 << SSI_CR1_MCOM_BIT) /* 2-bit command selected */ -+ #define SSI_CR1_MCOM_3BIT (0x2 << SSI_CR1_MCOM_BIT) /* 3-bit command selected */ -+ #define SSI_CR1_MCOM_4BIT (0x3 << SSI_CR1_MCOM_BIT) /* 4-bit command selected */ -+ #define SSI_CR1_MCOM_5BIT (0x4 << SSI_CR1_MCOM_BIT) /* 5-bit command selected */ -+ #define SSI_CR1_MCOM_6BIT (0x5 << SSI_CR1_MCOM_BIT) /* 6-bit command selected */ -+ #define SSI_CR1_MCOM_7BIT (0x6 << SSI_CR1_MCOM_BIT) /* 7-bit command selected */ -+ #define SSI_CR1_MCOM_8BIT (0x7 << SSI_CR1_MCOM_BIT) /* 8-bit command selected */ -+ #define SSI_CR1_MCOM_9BIT (0x8 << SSI_CR1_MCOM_BIT) /* 9-bit command selected */ -+ #define SSI_CR1_MCOM_10BIT (0x9 << SSI_CR1_MCOM_BIT) /* 10-bit command selected */ -+ #define SSI_CR1_MCOM_11BIT (0xA << SSI_CR1_MCOM_BIT) /* 11-bit command selected */ -+ #define SSI_CR1_MCOM_12BIT (0xB << SSI_CR1_MCOM_BIT) /* 12-bit command selected */ -+ #define SSI_CR1_MCOM_13BIT (0xC << SSI_CR1_MCOM_BIT) /* 13-bit command selected */ -+ #define SSI_CR1_MCOM_14BIT (0xD << SSI_CR1_MCOM_BIT) /* 14-bit command selected */ -+ #define SSI_CR1_MCOM_15BIT (0xE << SSI_CR1_MCOM_BIT) /* 15-bit command selected */ -+ #define SSI_CR1_MCOM_16BIT (0xF << SSI_CR1_MCOM_BIT) /* 16-bit command selected */ -+#define SSI_CR1_RTRG_BIT 8 -+#define SSI_CR1_RTRG_MASK (0xf << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_1 (0 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_8 (1 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_16 (2 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_24 (3 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_32 (4 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_40 (5 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_48 (6 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_56 (7 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_64 (8 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_72 (9 << SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_80 (10<< SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_88 (11<< SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_96 (12<< SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_104 (13<< SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_112 (14<< SSI_CR1_RTRG_BIT) -+ #define SSI_CR1_RTRG_120 (15<< SSI_CR1_RTRG_BIT) -+#define SSI_CR1_FLEN_BIT 4 -+#define SSI_CR1_FLEN_MASK (0xf << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_2BIT (0x0 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_3BIT (0x1 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_4BIT (0x2 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_5BIT (0x3 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_6BIT (0x4 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_7BIT (0x5 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_8BIT (0x6 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_9BIT (0x7 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_10BIT (0x8 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_11BIT (0x9 << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_12BIT (0xA << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_13BIT (0xB << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_14BIT (0xC << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_15BIT (0xD << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_16BIT (0xE << SSI_CR1_FLEN_BIT) -+ #define SSI_CR1_FLEN_17BIT (0xF << SSI_CR1_FLEN_BIT) -+#define SSI_CR1_PHA (1 << 1) -+#define SSI_CR1_POL (1 << 0) -+ -+/* SSI Status Register (SSI_SR) */ -+ -+#define SSI_SR_TFIFONUM_BIT 16 -+#define SSI_SR_TFIFONUM_MASK (0xff << SSI_SR_TFIFONUM_BIT) -+#define SSI_SR_RFIFONUM_BIT 8 -+#define SSI_SR_RFIFONUM_MASK (0xff << SSI_SR_RFIFONUM_BIT) -+#define SSI_SR_END (1 << 7) -+#define SSI_SR_BUSY (1 << 6) -+#define SSI_SR_TFF (1 << 5) -+#define SSI_SR_RFE (1 << 4) -+#define SSI_SR_TFHE (1 << 3) -+#define SSI_SR_RFHF (1 << 2) -+#define SSI_SR_UNDR (1 << 1) -+#define SSI_SR_OVER (1 << 0) -+ -+/* SSI Interval Time Control Register (SSI_ITR) */ -+ -+#define SSI_ITR_CNTCLK (1 << 15) -+#define SSI_ITR_IVLTM_BIT 0 -+#define SSI_ITR_IVLTM_MASK (0x7fff << SSI_ITR_IVLTM_BIT) -+ -+ -+/************************************************************************* -+ * MSC -+ *************************************************************************/ -+#define MSC_STRPCL (MSC_BASE + 0x000) -+#define MSC_STAT (MSC_BASE + 0x004) -+#define MSC_CLKRT (MSC_BASE + 0x008) -+#define MSC_CMDAT (MSC_BASE + 0x00C) -+#define MSC_RESTO (MSC_BASE + 0x010) -+#define MSC_RDTO (MSC_BASE + 0x014) -+#define MSC_BLKLEN (MSC_BASE + 0x018) -+#define MSC_NOB (MSC_BASE + 0x01C) -+#define MSC_SNOB (MSC_BASE + 0x020) -+#define MSC_IMASK (MSC_BASE + 0x024) -+#define MSC_IREG (MSC_BASE + 0x028) -+#define MSC_CMD (MSC_BASE + 0x02C) -+#define MSC_ARG (MSC_BASE + 0x030) -+#define MSC_RES (MSC_BASE + 0x034) -+#define MSC_RXFIFO (MSC_BASE + 0x038) -+#define MSC_TXFIFO (MSC_BASE + 0x03C) -+ -+#define REG_MSC_STRPCL REG16(MSC_STRPCL) -+#define REG_MSC_STAT REG32(MSC_STAT) -+#define REG_MSC_CLKRT REG16(MSC_CLKRT) -+#define REG_MSC_CMDAT REG32(MSC_CMDAT) -+#define REG_MSC_RESTO REG16(MSC_RESTO) -+#define REG_MSC_RDTO REG16(MSC_RDTO) -+#define REG_MSC_BLKLEN REG16(MSC_BLKLEN) -+#define REG_MSC_NOB REG16(MSC_NOB) -+#define REG_MSC_SNOB REG16(MSC_SNOB) -+#define REG_MSC_IMASK REG16(MSC_IMASK) -+#define REG_MSC_IREG REG16(MSC_IREG) -+#define REG_MSC_CMD REG8(MSC_CMD) -+#define REG_MSC_ARG REG32(MSC_ARG) -+#define REG_MSC_RES REG16(MSC_RES) -+#define REG_MSC_RXFIFO REG32(MSC_RXFIFO) -+#define REG_MSC_TXFIFO REG32(MSC_TXFIFO) -+ -+/* MSC Clock and Control Register (MSC_STRPCL) */ -+ -+#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7) -+#define MSC_STRPCL_EXIT_TRANSFER (1 << 6) -+#define MSC_STRPCL_START_READWAIT (1 << 5) -+#define MSC_STRPCL_STOP_READWAIT (1 << 4) -+#define MSC_STRPCL_RESET (1 << 3) -+#define MSC_STRPCL_START_OP (1 << 2) -+#define MSC_STRPCL_CLOCK_CONTROL_BIT 0 -+#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT) -+ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */ -+ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */ -+ -+/* MSC Status Register (MSC_STAT) */ -+ -+#define MSC_STAT_IS_RESETTING (1 << 15) -+#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14) -+#define MSC_STAT_PRG_DONE (1 << 13) -+#define MSC_STAT_DATA_TRAN_DONE (1 << 12) -+#define MSC_STAT_END_CMD_RES (1 << 11) -+#define MSC_STAT_DATA_FIFO_AFULL (1 << 10) -+#define MSC_STAT_IS_READWAIT (1 << 9) -+#define MSC_STAT_CLK_EN (1 << 8) -+#define MSC_STAT_DATA_FIFO_FULL (1 << 7) -+#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6) -+#define MSC_STAT_CRC_RES_ERR (1 << 5) -+#define MSC_STAT_CRC_READ_ERROR (1 << 4) -+#define MSC_STAT_CRC_WRITE_ERROR_BIT 2 -+#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT) -+ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */ -+ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */ -+ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */ -+#define MSC_STAT_TIME_OUT_RES (1 << 1) -+#define MSC_STAT_TIME_OUT_READ (1 << 0) -+ -+/* MSC Bus Clock Control Register (MSC_CLKRT) */ -+ -+#define MSC_CLKRT_CLK_RATE_BIT 0 -+#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT) -+ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */ -+ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */ -+ -+/* MSC Command Sequence Control Register (MSC_CMDAT) */ -+ -+#define MSC_CMDAT_IO_ABORT (1 << 11) -+#define MSC_CMDAT_BUS_WIDTH_BIT 9 -+#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) -+ #define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) /* 1-bit data bus */ -+ #define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) /* 4-bit data bus */ -+ #define CMDAT_BUS_WIDTH1 (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) -+ #define CMDAT_BUS_WIDTH4 (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) -+#define MSC_CMDAT_DMA_EN (1 << 8) -+#define MSC_CMDAT_INIT (1 << 7) -+#define MSC_CMDAT_BUSY (1 << 6) -+#define MSC_CMDAT_STREAM_BLOCK (1 << 5) -+#define MSC_CMDAT_WRITE (1 << 4) -+#define MSC_CMDAT_READ (0 << 4) -+#define MSC_CMDAT_DATA_EN (1 << 3) -+#define MSC_CMDAT_RESPONSE_BIT 0 -+#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT) -+ #define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) /* No response */ -+ #define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) /* Format R1 and R1b */ -+ #define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) /* Format R2 */ -+ #define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) /* Format R3 */ -+ #define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) /* Format R4 */ -+ #define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) /* Format R5 */ -+ #define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) /* Format R6 */ -+ -+#define CMDAT_DMA_EN (1 << 8) -+#define CMDAT_INIT (1 << 7) -+#define CMDAT_BUSY (1 << 6) -+#define CMDAT_STREAM (1 << 5) -+#define CMDAT_WRITE (1 << 4) -+#define CMDAT_DATA_EN (1 << 3) -+ -+/* MSC Interrupts Mask Register (MSC_IMASK) */ -+ -+#define MSC_IMASK_SDIO (1 << 7) -+#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6) -+#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5) -+#define MSC_IMASK_END_CMD_RES (1 << 2) -+#define MSC_IMASK_PRG_DONE (1 << 1) -+#define MSC_IMASK_DATA_TRAN_DONE (1 << 0) -+ -+ -+/* MSC Interrupts Status Register (MSC_IREG) */ -+ -+#define MSC_IREG_SDIO (1 << 7) -+#define MSC_IREG_TXFIFO_WR_REQ (1 << 6) -+#define MSC_IREG_RXFIFO_RD_REQ (1 << 5) -+#define MSC_IREG_END_CMD_RES (1 << 2) -+#define MSC_IREG_PRG_DONE (1 << 1) -+#define MSC_IREG_DATA_TRAN_DONE (1 << 0) -+ -+ -+/************************************************************************* -+ * EMC (External Memory Controller) -+ *************************************************************************/ -+#define EMC_SMCR0 (EMC_BASE + 0x10) /* Static Memory Control Register 0 */ -+#define EMC_SMCR1 (EMC_BASE + 0x14) /* Static Memory Control Register 1 */ -+#define EMC_SMCR2 (EMC_BASE + 0x18) /* Static Memory Control Register 2 */ -+#define EMC_SMCR3 (EMC_BASE + 0x1c) /* Static Memory Control Register 3 */ -+#define EMC_SMCR4 (EMC_BASE + 0x20) /* Static Memory Control Register 4 */ -+#define EMC_SACR0 (EMC_BASE + 0x30) /* Static Memory Bank 0 Addr Config Reg */ -+#define EMC_SACR1 (EMC_BASE + 0x34) /* Static Memory Bank 1 Addr Config Reg */ -+#define EMC_SACR2 (EMC_BASE + 0x38) /* Static Memory Bank 2 Addr Config Reg */ -+#define EMC_SACR3 (EMC_BASE + 0x3c) /* Static Memory Bank 3 Addr Config Reg */ -+#define EMC_SACR4 (EMC_BASE + 0x40) /* Static Memory Bank 4 Addr Config Reg */ -+ -+#define EMC_NFCSR (EMC_BASE + 0x050) /* NAND Flash Control/Status Register */ -+#define EMC_NFECR (EMC_BASE + 0x100) /* NAND Flash ECC Control Register */ -+#define EMC_NFECC (EMC_BASE + 0x104) /* NAND Flash ECC Data Register */ -+#define EMC_NFPAR0 (EMC_BASE + 0x108) /* NAND Flash RS Parity 0 Register */ -+#define EMC_NFPAR1 (EMC_BASE + 0x10c) /* NAND Flash RS Parity 1 Register */ -+#define EMC_NFPAR2 (EMC_BASE + 0x110) /* NAND Flash RS Parity 2 Register */ -+#define EMC_NFINTS (EMC_BASE + 0x114) /* NAND Flash Interrupt Status Register */ -+#define EMC_NFINTE (EMC_BASE + 0x118) /* NAND Flash Interrupt Enable Register */ -+#define EMC_NFERR0 (EMC_BASE + 0x11c) /* NAND Flash RS Error Report 0 Register */ -+#define EMC_NFERR1 (EMC_BASE + 0x120) /* NAND Flash RS Error Report 1 Register */ -+#define EMC_NFERR2 (EMC_BASE + 0x124) /* NAND Flash RS Error Report 2 Register */ -+#define EMC_NFERR3 (EMC_BASE + 0x128) /* NAND Flash RS Error Report 3 Register */ -+ -+#define EMC_DMCR (EMC_BASE + 0x80) /* DRAM Control Register */ -+#define EMC_RTCSR (EMC_BASE + 0x84) /* Refresh Time Control/Status Register */ -+#define EMC_RTCNT (EMC_BASE + 0x88) /* Refresh Timer Counter */ -+#define EMC_RTCOR (EMC_BASE + 0x8c) /* Refresh Time Constant Register */ -+#define EMC_DMAR0 (EMC_BASE + 0x90) /* SDRAM Bank 0 Addr Config Register */ -+#define EMC_SDMR0 (EMC_BASE + 0xa000) /* Mode Register of SDRAM bank 0 */ -+ -+ -+#define REG_EMC_SMCR0 REG32(EMC_SMCR0) -+#define REG_EMC_SMCR1 REG32(EMC_SMCR1) -+#define REG_EMC_SMCR2 REG32(EMC_SMCR2) -+#define REG_EMC_SMCR3 REG32(EMC_SMCR3) -+#define REG_EMC_SMCR4 REG32(EMC_SMCR4) -+#define REG_EMC_SACR0 REG32(EMC_SACR0) -+#define REG_EMC_SACR1 REG32(EMC_SACR1) -+#define REG_EMC_SACR2 REG32(EMC_SACR2) -+#define REG_EMC_SACR3 REG32(EMC_SACR3) -+#define REG_EMC_SACR4 REG32(EMC_SACR4) -+ -+#define REG_EMC_NFCSR REG32(EMC_NFCSR) -+#define REG_EMC_NFECR REG32(EMC_NFECR) -+#define REG_EMC_NFECC REG32(EMC_NFECC) -+#define REG_EMC_NFPAR0 REG32(EMC_NFPAR0) -+#define REG_EMC_NFPAR1 REG32(EMC_NFPAR1) -+#define REG_EMC_NFPAR2 REG32(EMC_NFPAR2) -+#define REG_EMC_NFINTS REG32(EMC_NFINTS) -+#define REG_EMC_NFINTE REG32(EMC_NFINTE) -+#define REG_EMC_NFERR0 REG32(EMC_NFERR0) -+#define REG_EMC_NFERR1 REG32(EMC_NFERR1) -+#define REG_EMC_NFERR2 REG32(EMC_NFERR2) -+#define REG_EMC_NFERR3 REG32(EMC_NFERR3) -+ -+#define REG_EMC_DMCR REG32(EMC_DMCR) -+#define REG_EMC_RTCSR REG16(EMC_RTCSR) -+#define REG_EMC_RTCNT REG16(EMC_RTCNT) -+#define REG_EMC_RTCOR REG16(EMC_RTCOR) -+#define REG_EMC_DMAR0 REG32(EMC_DMAR0) -+ -+/* Static Memory Control Register */ -+#define EMC_SMCR_STRV_BIT 24 -+#define EMC_SMCR_STRV_MASK (0x0f << EMC_SMCR_STRV_BIT) -+#define EMC_SMCR_TAW_BIT 20 -+#define EMC_SMCR_TAW_MASK (0x0f << EMC_SMCR_TAW_BIT) -+#define EMC_SMCR_TBP_BIT 16 -+#define EMC_SMCR_TBP_MASK (0x0f << EMC_SMCR_TBP_BIT) -+#define EMC_SMCR_TAH_BIT 12 -+#define EMC_SMCR_TAH_MASK (0x07 << EMC_SMCR_TAH_BIT) -+#define EMC_SMCR_TAS_BIT 8 -+#define EMC_SMCR_TAS_MASK (0x07 << EMC_SMCR_TAS_BIT) -+#define EMC_SMCR_BW_BIT 6 -+#define EMC_SMCR_BW_MASK (0x03 << EMC_SMCR_BW_BIT) -+ #define EMC_SMCR_BW_8BIT (0 << EMC_SMCR_BW_BIT) -+ #define EMC_SMCR_BW_16BIT (1 << EMC_SMCR_BW_BIT) -+ #define EMC_SMCR_BW_32BIT (2 << EMC_SMCR_BW_BIT) -+#define EMC_SMCR_BCM (1 << 3) -+#define EMC_SMCR_BL_BIT 1 -+#define EMC_SMCR_BL_MASK (0x03 << EMC_SMCR_BL_BIT) -+ #define EMC_SMCR_BL_4 (0 << EMC_SMCR_BL_BIT) -+ #define EMC_SMCR_BL_8 (1 << EMC_SMCR_BL_BIT) -+ #define EMC_SMCR_BL_16 (2 << EMC_SMCR_BL_BIT) -+ #define EMC_SMCR_BL_32 (3 << EMC_SMCR_BL_BIT) -+#define EMC_SMCR_SMT (1 << 0) -+ -+/* Static Memory Bank Addr Config Reg */ -+#define EMC_SACR_BASE_BIT 8 -+#define EMC_SACR_BASE_MASK (0xff << EMC_SACR_BASE_BIT) -+#define EMC_SACR_MASK_BIT 0 -+#define EMC_SACR_MASK_MASK (0xff << EMC_SACR_MASK_BIT) -+ -+/* NAND Flash Control/Status Register */ -+#define EMC_NFCSR_NFCE4 (1 << 7) /* NAND Flash Enable */ -+#define EMC_NFCSR_NFE4 (1 << 6) /* NAND Flash FCE# Assertion Enable */ -+#define EMC_NFCSR_NFCE3 (1 << 5) -+#define EMC_NFCSR_NFE3 (1 << 4) -+#define EMC_NFCSR_NFCE2 (1 << 3) -+#define EMC_NFCSR_NFE2 (1 << 2) -+#define EMC_NFCSR_NFCE1 (1 << 1) -+#define EMC_NFCSR_NFE1 (1 << 0) -+ -+/* NAND Flash ECC Control Register */ -+#define EMC_NFECR_PRDY (1 << 4) /* Parity Ready */ -+#define EMC_NFECR_RS_DECODING (0 << 3) /* RS is in decoding phase */ -+#define EMC_NFECR_RS_ENCODING (1 << 3) /* RS is in encoding phase */ -+#define EMC_NFECR_HAMMING (0 << 2) /* Select HAMMING Correction Algorithm */ -+#define EMC_NFECR_RS (1 << 2) /* Select RS Correction Algorithm */ -+#define EMC_NFECR_ERST (1 << 1) /* ECC Reset */ -+#define EMC_NFECR_ECCE (1 << 0) /* ECC Enable */ -+ -+/* NAND Flash ECC Data Register */ -+#define EMC_NFECC_ECC2_BIT 16 -+#define EMC_NFECC_ECC2_MASK (0xff << EMC_NFECC_ECC2_BIT) -+#define EMC_NFECC_ECC1_BIT 8 -+#define EMC_NFECC_ECC1_MASK (0xff << EMC_NFECC_ECC1_BIT) -+#define EMC_NFECC_ECC0_BIT 0 -+#define EMC_NFECC_ECC0_MASK (0xff << EMC_NFECC_ECC0_BIT) -+ -+/* NAND Flash Interrupt Status Register */ -+#define EMC_NFINTS_ERRCNT_BIT 29 /* Error Count */ -+#define EMC_NFINTS_ERRCNT_MASK (0x7 << EMC_NFINTS_ERRCNT_BIT) -+#define EMC_NFINTS_PADF (1 << 4) /* Padding Finished */ -+#define EMC_NFINTS_DECF (1 << 3) /* Decoding Finished */ -+#define EMC_NFINTS_ENCF (1 << 2) /* Encoding Finished */ -+#define EMC_NFINTS_UNCOR (1 << 1) /* Uncorrectable Error Occurred */ -+#define EMC_NFINTS_ERR (1 << 0) /* Error Occurred */ -+ -+/* NAND Flash Interrupt Enable Register */ -+#define EMC_NFINTE_PADFE (1 << 4) /* Padding Finished Interrupt Enable */ -+#define EMC_NFINTE_DECFE (1 << 3) /* Decoding Finished Interrupt Enable */ -+#define EMC_NFINTE_ENCFE (1 << 2) /* Encoding Finished Interrupt Enable */ -+#define EMC_NFINTE_UNCORE (1 << 1) /* Uncorrectable Error Occurred Intr Enable */ -+#define EMC_NFINTE_ERRE (1 << 0) /* Error Occurred Interrupt */ -+ -+/* NAND Flash RS Error Report Register */ -+#define EMC_NFERR_INDEX_BIT 16 /* Error Symbol Index */ -+#define EMC_NFERR_INDEX_MASK (0x1ff << EMC_NFERR_INDEX_BIT) -+#define EMC_NFERR_MASK_BIT 0 /* Error Symbol Value */ -+#define EMC_NFERR_MASK_MASK (0x1ff << EMC_NFERR_MASK_BIT) -+ -+ -+/* DRAM Control Register */ -+#define EMC_DMCR_BW_BIT 31 -+#define EMC_DMCR_BW (1 << EMC_DMCR_BW_BIT) -+#define EMC_DMCR_CA_BIT 26 -+#define EMC_DMCR_CA_MASK (0x07 << EMC_DMCR_CA_BIT) -+ #define EMC_DMCR_CA_8 (0 << EMC_DMCR_CA_BIT) -+ #define EMC_DMCR_CA_9 (1 << EMC_DMCR_CA_BIT) -+ #define EMC_DMCR_CA_10 (2 << EMC_DMCR_CA_BIT) -+ #define EMC_DMCR_CA_11 (3 << EMC_DMCR_CA_BIT) -+ #define EMC_DMCR_CA_12 (4 << EMC_DMCR_CA_BIT) -+#define EMC_DMCR_RMODE (1 << 25) -+#define EMC_DMCR_RFSH (1 << 24) -+#define EMC_DMCR_MRSET (1 << 23) -+#define EMC_DMCR_RA_BIT 20 -+#define EMC_DMCR_RA_MASK (0x03 << EMC_DMCR_RA_BIT) -+ #define EMC_DMCR_RA_11 (0 << EMC_DMCR_RA_BIT) -+ #define EMC_DMCR_RA_12 (1 << EMC_DMCR_RA_BIT) -+ #define EMC_DMCR_RA_13 (2 << EMC_DMCR_RA_BIT) -+#define EMC_DMCR_BA_BIT 19 -+#define EMC_DMCR_BA (1 << EMC_DMCR_BA_BIT) -+#define EMC_DMCR_PDM (1 << 18) -+#define EMC_DMCR_EPIN (1 << 17) -+#define EMC_DMCR_TRAS_BIT 13 -+#define EMC_DMCR_TRAS_MASK (0x07 << EMC_DMCR_TRAS_BIT) -+#define EMC_DMCR_RCD_BIT 11 -+#define EMC_DMCR_RCD_MASK (0x03 << EMC_DMCR_RCD_BIT) -+#define EMC_DMCR_TPC_BIT 8 -+#define EMC_DMCR_TPC_MASK (0x07 << EMC_DMCR_TPC_BIT) -+#define EMC_DMCR_TRWL_BIT 5 -+#define EMC_DMCR_TRWL_MASK (0x03 << EMC_DMCR_TRWL_BIT) -+#define EMC_DMCR_TRC_BIT 2 -+#define EMC_DMCR_TRC_MASK (0x07 << EMC_DMCR_TRC_BIT) -+#define EMC_DMCR_TCL_BIT 0 -+#define EMC_DMCR_TCL_MASK (0x03 << EMC_DMCR_TCL_BIT) -+ -+/* Refresh Time Control/Status Register */ -+#define EMC_RTCSR_CMF (1 << 7) -+#define EMC_RTCSR_CKS_BIT 0 -+#define EMC_RTCSR_CKS_MASK (0x07 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_DISABLE (0 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_4 (1 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_16 (2 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_64 (3 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_256 (4 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_1024 (5 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_2048 (6 << EMC_RTCSR_CKS_BIT) -+ #define EMC_RTCSR_CKS_4096 (7 << EMC_RTCSR_CKS_BIT) -+ -+/* SDRAM Bank Address Configuration Register */ -+#define EMC_DMAR_BASE_BIT 8 -+#define EMC_DMAR_BASE_MASK (0xff << EMC_DMAR_BASE_BIT) -+#define EMC_DMAR_MASK_BIT 0 -+#define EMC_DMAR_MASK_MASK (0xff << EMC_DMAR_MASK_BIT) -+ -+/* Mode Register of SDRAM bank 0 */ -+#define EMC_SDMR_BM (1 << 9) /* Write Burst Mode */ -+#define EMC_SDMR_OM_BIT 7 /* Operating Mode */ -+#define EMC_SDMR_OM_MASK (3 << EMC_SDMR_OM_BIT) -+ #define EMC_SDMR_OM_NORMAL (0 << EMC_SDMR_OM_BIT) -+#define EMC_SDMR_CAS_BIT 4 /* CAS Latency */ -+#define EMC_SDMR_CAS_MASK (7 << EMC_SDMR_CAS_BIT) -+ #define EMC_SDMR_CAS_1 (1 << EMC_SDMR_CAS_BIT) -+ #define EMC_SDMR_CAS_2 (2 << EMC_SDMR_CAS_BIT) -+ #define EMC_SDMR_CAS_3 (3 << EMC_SDMR_CAS_BIT) -+#define EMC_SDMR_BT_BIT 3 /* Burst Type */ -+#define EMC_SDMR_BT_MASK (1 << EMC_SDMR_BT_BIT) -+ #define EMC_SDMR_BT_SEQ (0 << EMC_SDMR_BT_BIT) /* Sequential */ -+ #define EMC_SDMR_BT_INT (1 << EMC_SDMR_BT_BIT) /* Interleave */ -+#define EMC_SDMR_BL_BIT 0 /* Burst Length */ -+#define EMC_SDMR_BL_MASK (7 << EMC_SDMR_BL_BIT) -+ #define EMC_SDMR_BL_1 (0 << EMC_SDMR_BL_BIT) -+ #define EMC_SDMR_BL_2 (1 << EMC_SDMR_BL_BIT) -+ #define EMC_SDMR_BL_4 (2 << EMC_SDMR_BL_BIT) -+ #define EMC_SDMR_BL_8 (3 << EMC_SDMR_BL_BIT) -+ -+#define EMC_SDMR_CAS2_16BIT \ -+ (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2) -+#define EMC_SDMR_CAS2_32BIT \ -+ (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4) -+#define EMC_SDMR_CAS3_16BIT \ -+ (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2) -+#define EMC_SDMR_CAS3_32BIT \ -+ (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4) -+ -+ -+/************************************************************************* -+ * CIM -+ *************************************************************************/ -+#define CIM_CFG (CIM_BASE + 0x0000) -+#define CIM_CTRL (CIM_BASE + 0x0004) -+#define CIM_STATE (CIM_BASE + 0x0008) -+#define CIM_IID (CIM_BASE + 0x000C) -+#define CIM_RXFIFO (CIM_BASE + 0x0010) -+#define CIM_DA (CIM_BASE + 0x0020) -+#define CIM_FA (CIM_BASE + 0x0024) -+#define CIM_FID (CIM_BASE + 0x0028) -+#define CIM_CMD (CIM_BASE + 0x002C) -+ -+#define REG_CIM_CFG REG32(CIM_CFG) -+#define REG_CIM_CTRL REG32(CIM_CTRL) -+#define REG_CIM_STATE REG32(CIM_STATE) -+#define REG_CIM_IID REG32(CIM_IID) -+#define REG_CIM_RXFIFO REG32(CIM_RXFIFO) -+#define REG_CIM_DA REG32(CIM_DA) -+#define REG_CIM_FA REG32(CIM_FA) -+#define REG_CIM_FID REG32(CIM_FID) -+#define REG_CIM_CMD REG32(CIM_CMD) -+ -+/* CIM Configuration Register (CIM_CFG) */ -+ -+#define CIM_CFG_INV_DAT (1 << 15) -+#define CIM_CFG_VSP (1 << 14) -+#define CIM_CFG_HSP (1 << 13) -+#define CIM_CFG_PCP (1 << 12) -+#define CIM_CFG_DUMMY_ZERO (1 << 9) -+#define CIM_CFG_EXT_VSYNC (1 << 8) -+#define CIM_CFG_PACK_BIT 4 -+#define CIM_CFG_PACK_MASK (0x7 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_0 (0 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_1 (1 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_2 (2 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_3 (3 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_4 (4 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_5 (5 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_6 (6 << CIM_CFG_PACK_BIT) -+ #define CIM_CFG_PACK_7 (7 << CIM_CFG_PACK_BIT) -+#define CIM_CFG_DSM_BIT 0 -+#define CIM_CFG_DSM_MASK (0x3 << CIM_CFG_DSM_BIT) -+ #define CIM_CFG_DSM_CPM (0 << CIM_CFG_DSM_BIT) /* CCIR656 Progressive Mode */ -+ #define CIM_CFG_DSM_CIM (1 << CIM_CFG_DSM_BIT) /* CCIR656 Interlace Mode */ -+ #define CIM_CFG_DSM_GCM (2 << CIM_CFG_DSM_BIT) /* Gated Clock Mode */ -+ #define CIM_CFG_DSM_NGCM (3 << CIM_CFG_DSM_BIT) /* Non-Gated Clock Mode */ -+ -+/* CIM Control Register (CIM_CTRL) */ -+ -+#define CIM_CTRL_MCLKDIV_BIT 24 -+#define CIM_CTRL_MCLKDIV_MASK (0xff << CIM_CTRL_MCLKDIV_BIT) -+#define CIM_CTRL_FRC_BIT 16 -+#define CIM_CTRL_FRC_MASK (0xf << CIM_CTRL_FRC_BIT) -+ #define CIM_CTRL_FRC_1 (0x0 << CIM_CTRL_FRC_BIT) /* Sample every frame */ -+ #define CIM_CTRL_FRC_2 (0x1 << CIM_CTRL_FRC_BIT) /* Sample 1/2 frame */ -+ #define CIM_CTRL_FRC_3 (0x2 << CIM_CTRL_FRC_BIT) /* Sample 1/3 frame */ -+ #define CIM_CTRL_FRC_4 (0x3 << CIM_CTRL_FRC_BIT) /* Sample 1/4 frame */ -+ #define CIM_CTRL_FRC_5 (0x4 << CIM_CTRL_FRC_BIT) /* Sample 1/5 frame */ -+ #define CIM_CTRL_FRC_6 (0x5 << CIM_CTRL_FRC_BIT) /* Sample 1/6 frame */ -+ #define CIM_CTRL_FRC_7 (0x6 << CIM_CTRL_FRC_BIT) /* Sample 1/7 frame */ -+ #define CIM_CTRL_FRC_8 (0x7 << CIM_CTRL_FRC_BIT) /* Sample 1/8 frame */ -+ #define CIM_CTRL_FRC_9 (0x8 << CIM_CTRL_FRC_BIT) /* Sample 1/9 frame */ -+ #define CIM_CTRL_FRC_10 (0x9 << CIM_CTRL_FRC_BIT) /* Sample 1/10 frame */ -+ #define CIM_CTRL_FRC_11 (0xA << CIM_CTRL_FRC_BIT) /* Sample 1/11 frame */ -+ #define CIM_CTRL_FRC_12 (0xB << CIM_CTRL_FRC_BIT) /* Sample 1/12 frame */ -+ #define CIM_CTRL_FRC_13 (0xC << CIM_CTRL_FRC_BIT) /* Sample 1/13 frame */ -+ #define CIM_CTRL_FRC_14 (0xD << CIM_CTRL_FRC_BIT) /* Sample 1/14 frame */ -+ #define CIM_CTRL_FRC_15 (0xE << CIM_CTRL_FRC_BIT) /* Sample 1/15 frame */ -+ #define CIM_CTRL_FRC_16 (0xF << CIM_CTRL_FRC_BIT) /* Sample 1/16 frame */ -+#define CIM_CTRL_VDDM (1 << 13) -+#define CIM_CTRL_DMA_SOFM (1 << 12) -+#define CIM_CTRL_DMA_EOFM (1 << 11) -+#define CIM_CTRL_DMA_STOPM (1 << 10) -+#define CIM_CTRL_RXF_TRIGM (1 << 9) -+#define CIM_CTRL_RXF_OFM (1 << 8) -+#define CIM_CTRL_RXF_TRIG_BIT 4 -+#define CIM_CTRL_RXF_TRIG_MASK (0x7 << CIM_CTRL_RXF_TRIG_BIT) -+ #define CIM_CTRL_RXF_TRIG_4 (0 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 4 */ -+ #define CIM_CTRL_RXF_TRIG_8 (1 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 8 */ -+ #define CIM_CTRL_RXF_TRIG_12 (2 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 12 */ -+ #define CIM_CTRL_RXF_TRIG_16 (3 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 16 */ -+ #define CIM_CTRL_RXF_TRIG_20 (4 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 20 */ -+ #define CIM_CTRL_RXF_TRIG_24 (5 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 24 */ -+ #define CIM_CTRL_RXF_TRIG_28 (6 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 28 */ -+ #define CIM_CTRL_RXF_TRIG_32 (7 << CIM_CTRL_RXF_TRIG_BIT) /* RXFIFO Trigger Value is 32 */ -+#define CIM_CTRL_DMA_EN (1 << 2) -+#define CIM_CTRL_RXF_RST (1 << 1) -+#define CIM_CTRL_ENA (1 << 0) -+ -+/* CIM State Register (CIM_STATE) */ -+ -+#define CIM_STATE_DMA_SOF (1 << 6) -+#define CIM_STATE_DMA_EOF (1 << 5) -+#define CIM_STATE_DMA_STOP (1 << 4) -+#define CIM_STATE_RXF_OF (1 << 3) -+#define CIM_STATE_RXF_TRIG (1 << 2) -+#define CIM_STATE_RXF_EMPTY (1 << 1) -+#define CIM_STATE_VDD (1 << 0) -+ -+/* CIM DMA Command Register (CIM_CMD) */ -+ -+#define CIM_CMD_SOFINT (1 << 31) -+#define CIM_CMD_EOFINT (1 << 30) -+#define CIM_CMD_STOP (1 << 28) -+#define CIM_CMD_LEN_BIT 0 -+#define CIM_CMD_LEN_MASK (0xffffff << CIM_CMD_LEN_BIT) -+ -+ -+/************************************************************************* -+ * SADC (Smart A/D Controller) -+ *************************************************************************/ -+ -+#define SADC_ENA (SADC_BASE + 0x00) /* ADC Enable Register */ -+#define SADC_CFG (SADC_BASE + 0x04) /* ADC Configure Register */ -+#define SADC_CTRL (SADC_BASE + 0x08) /* ADC Control Register */ -+#define SADC_STATE (SADC_BASE + 0x0C) /* ADC Status Register*/ -+#define SADC_SAMETIME (SADC_BASE + 0x10) /* ADC Same Point Time Register */ -+#define SADC_WAITTIME (SADC_BASE + 0x14) /* ADC Wait Time Register */ -+#define SADC_TSDAT (SADC_BASE + 0x18) /* ADC Touch Screen Data Register */ -+#define SADC_BATDAT (SADC_BASE + 0x1C) /* ADC PBAT Data Register */ -+#define SADC_SADDAT (SADC_BASE + 0x20) /* ADC SADCIN Data Register */ -+ -+#define REG_SADC_ENA REG8(SADC_ENA) -+#define REG_SADC_CFG REG32(SADC_CFG) -+#define REG_SADC_CTRL REG8(SADC_CTRL) -+#define REG_SADC_STATE REG8(SADC_STATE) -+#define REG_SADC_SAMETIME REG16(SADC_SAMETIME) -+#define REG_SADC_WAITTIME REG16(SADC_WAITTIME) -+#define REG_SADC_TSDAT REG32(SADC_TSDAT) -+#define REG_SADC_BATDAT REG16(SADC_BATDAT) -+#define REG_SADC_SADDAT REG16(SADC_SADDAT) -+ -+/* ADC Enable Register */ -+#define SADC_ENA_ADEN (1 << 7) /* Touch Screen Enable */ -+#define SADC_ENA_TSEN (1 << 2) /* Touch Screen Enable */ -+#define SADC_ENA_PBATEN (1 << 1) /* PBAT Enable */ -+#define SADC_ENA_SADCINEN (1 << 0) /* SADCIN Enable */ -+ -+/* ADC Configure Register */ -+#define SADC_CFG_EXIN (1 << 30) -+#define SADC_CFG_CLKOUT_NUM_BIT 16 -+#define SADC_CFG_CLKOUT_NUM_MASK (0x7 << SADC_CFG_CLKOUT_NUM_BIT) -+#define SADC_CFG_TS_DMA (1 << 15) /* Touch Screen DMA Enable */ -+#define SADC_CFG_XYZ_BIT 13 /* XYZ selection */ -+#define SADC_CFG_XYZ_MASK (0x3 << SADC_CFG_XYZ_BIT) -+ #define SADC_CFG_XY (0 << SADC_CFG_XYZ_BIT) -+ #define SADC_CFG_XYZ (1 << SADC_CFG_XYZ_BIT) -+ #define SADC_CFG_XYZ1Z2 (2 << SADC_CFG_XYZ_BIT) -+#define SADC_CFG_SNUM_BIT 10 /* Sample Number */ -+#define SADC_CFG_SNUM_MASK (0x7 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_1 (0x0 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_2 (0x1 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_3 (0x2 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_4 (0x3 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_5 (0x4 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_6 (0x5 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_8 (0x6 << SADC_CFG_SNUM_BIT) -+ #define SADC_CFG_SNUM_9 (0x7 << SADC_CFG_SNUM_BIT) -+#define SADC_CFG_CLKDIV_BIT 5 /* AD Converter frequency clock divider */ -+#define SADC_CFG_CLKDIV_MASK (0x1f << SADC_CFG_CLKDIV_BIT) -+#define SADC_CFG_PBAT_HIGH (0 << 4) /* PBAT >= 2.5V */ -+#define SADC_CFG_PBAT_LOW (1 << 4) /* PBAT < 2.5V */ -+#define SADC_CFG_CMD_BIT 0 /* ADC Command */ -+#define SADC_CFG_CMD_MASK (0xf << SADC_CFG_CMD_BIT) -+ #define SADC_CFG_CMD_X_SE (0x0 << SADC_CFG_CMD_BIT) /* X Single-End */ -+ #define SADC_CFG_CMD_Y_SE (0x1 << SADC_CFG_CMD_BIT) /* Y Single-End */ -+ #define SADC_CFG_CMD_X_DIFF (0x2 << SADC_CFG_CMD_BIT) /* X Differential */ -+ #define SADC_CFG_CMD_Y_DIFF (0x3 << SADC_CFG_CMD_BIT) /* Y Differential */ -+ #define SADC_CFG_CMD_Z1_DIFF (0x4 << SADC_CFG_CMD_BIT) /* Z1 Differential */ -+ #define SADC_CFG_CMD_Z2_DIFF (0x5 << SADC_CFG_CMD_BIT) /* Z2 Differential */ -+ #define SADC_CFG_CMD_Z3_DIFF (0x6 << SADC_CFG_CMD_BIT) /* Z3 Differential */ -+ #define SADC_CFG_CMD_Z4_DIFF (0x7 << SADC_CFG_CMD_BIT) /* Z4 Differential */ -+ #define SADC_CFG_CMD_TP_SE (0x8 << SADC_CFG_CMD_BIT) /* Touch Pressure */ -+ #define SADC_CFG_CMD_PBATH_SE (0x9 << SADC_CFG_CMD_BIT) /* PBAT >= 2.5V */ -+ #define SADC_CFG_CMD_PBATL_SE (0xa << SADC_CFG_CMD_BIT) /* PBAT < 2.5V */ -+ #define SADC_CFG_CMD_SADCIN_SE (0xb << SADC_CFG_CMD_BIT) /* Measure SADCIN */ -+ #define SADC_CFG_CMD_INT_PEN (0xc << SADC_CFG_CMD_BIT) /* INT_PEN Enable */ -+ -+/* ADC Control Register */ -+#define SADC_CTRL_PENDM (1 << 4) /* Pen Down Interrupt Mask */ -+#define SADC_CTRL_PENUM (1 << 3) /* Pen Up Interrupt Mask */ -+#define SADC_CTRL_TSRDYM (1 << 2) /* Touch Screen Data Ready Interrupt Mask */ -+#define SADC_CTRL_PBATRDYM (1 << 1) /* PBAT Data Ready Interrupt Mask */ -+#define SADC_CTRL_SRDYM (1 << 0) /* SADCIN Data Ready Interrupt Mask */ -+ -+/* ADC Status Register */ -+#define SADC_STATE_TSBUSY (1 << 7) /* TS A/D is working */ -+#define SADC_STATE_PBATBUSY (1 << 6) /* PBAT A/D is working */ -+#define SADC_STATE_SBUSY (1 << 5) /* SADCIN A/D is working */ -+#define SADC_STATE_PEND (1 << 4) /* Pen Down Interrupt Flag */ -+#define SADC_STATE_PENU (1 << 3) /* Pen Up Interrupt Flag */ -+#define SADC_STATE_TSRDY (1 << 2) /* Touch Screen Data Ready Interrupt Flag */ -+#define SADC_STATE_PBATRDY (1 << 1) /* PBAT Data Ready Interrupt Flag */ -+#define SADC_STATE_SRDY (1 << 0) /* SADCIN Data Ready Interrupt Flag */ -+ -+/* ADC Touch Screen Data Register */ -+#define SADC_TSDAT_DATA0_BIT 0 -+#define SADC_TSDAT_DATA0_MASK (0xfff << SADC_TSDAT_DATA0_BIT) -+#define SADC_TSDAT_TYPE0 (1 << 15) -+#define SADC_TSDAT_DATA1_BIT 16 -+#define SADC_TSDAT_DATA1_MASK (0xfff << SADC_TSDAT_DATA1_BIT) -+#define SADC_TSDAT_TYPE1 (1 << 31) -+ -+ -+/************************************************************************* -+ * SLCD (Smart LCD Controller) -+ *************************************************************************/ -+ -+#define SLCD_CFG (SLCD_BASE + 0xA0) /* SLCD Configure Register */ -+#define SLCD_CTRL (SLCD_BASE + 0xA4) /* SLCD Control Register */ -+#define SLCD_STATE (SLCD_BASE + 0xA8) /* SLCD Status Register */ -+#define SLCD_DATA (SLCD_BASE + 0xAC) /* SLCD Data Register */ -+#define SLCD_FIFO (SLCD_BASE + 0xB0) /* SLCD FIFO Register */ -+ -+#define REG_SLCD_CFG REG32(SLCD_CFG) -+#define REG_SLCD_CTRL REG8(SLCD_CTRL) -+#define REG_SLCD_STATE REG8(SLCD_STATE) -+#define REG_SLCD_DATA REG32(SLCD_DATA) -+#define REG_SLCD_FIFO REG32(SLCD_FIFO) -+ -+/* SLCD Configure Register */ -+#define SLCD_CFG_BURST_BIT 14 -+#define SLCD_CFG_BURST_MASK (0x3 << SLCD_CFG_BURST_BIT) -+ #define SLCD_CFG_BURST_4_WORD (0 << SLCD_CFG_BURST_BIT) -+ #define SLCD_CFG_BURST_8_WORD (1 << SLCD_CFG_BURST_BIT) -+#define SLCD_CFG_DWIDTH_BIT 10 -+#define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT) -+ #define SLCD_CFG_DWIDTH_18 (0 << SLCD_CFG_DWIDTH_BIT) -+ #define SLCD_CFG_DWIDTH_16 (1 << SLCD_CFG_DWIDTH_BIT) -+ #define SLCD_CFG_DWIDTH_8_x3 (2 << SLCD_CFG_DWIDTH_BIT) -+ #define SLCD_CFG_DWIDTH_8_x2 (3 << SLCD_CFG_DWIDTH_BIT) -+ #define SLCD_CFG_DWIDTH_8_x1 (4 << SLCD_CFG_DWIDTH_BIT) -+ #define SLCD_CFG_DWIDTH_9_x2 (7 << SLCD_CFG_DWIDTH_BIT) -+#define SLCD_CFG_CWIDTH_16BIT (0 << 8) -+#define SLCD_CFG_CWIDTH_8BIT (1 << 8) -+#define SLCD_CFG_CWIDTH_18BIT (2 << 8) -+#define SLCD_CFG_CS_ACTIVE_LOW (0 << 4) -+#define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4) -+#define SLCD_CFG_RS_CMD_LOW (0 << 3) -+#define SLCD_CFG_RS_CMD_HIGH (1 << 3) -+#define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1) -+#define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1) -+#define SLCD_CFG_TYPE_PARALLEL (0 << 0) -+#define SLCD_CFG_TYPE_SERIAL (1 << 0) -+ -+/* SLCD Control Register */ -+#define SLCD_CTRL_DMA_EN (1 << 0) -+ -+/* SLCD Status Register */ -+#define SLCD_STATE_BUSY (1 << 0) -+ -+/* SLCD Data Register */ -+#define SLCD_DATA_RS_DATA (0 << 31) -+#define SLCD_DATA_RS_COMMAND (1 << 31) -+ -+/* SLCD FIFO Register */ -+#define SLCD_FIFO_RS_DATA (0 << 31) -+#define SLCD_FIFO_RS_COMMAND (1 << 31) -+ -+ -+/************************************************************************* -+ * LCD (LCD Controller) -+ *************************************************************************/ -+#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */ -+#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */ -+#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */ -+#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */ -+#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */ -+#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */ -+#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */ -+#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */ -+#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */ -+#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */ -+#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */ -+#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */ -+#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */ -+#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */ -+#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */ -+#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */ -+#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */ -+#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */ -+#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */ -+#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */ -+#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */ -+ -+#define REG_LCD_CFG REG32(LCD_CFG) -+#define REG_LCD_VSYNC REG32(LCD_VSYNC) -+#define REG_LCD_HSYNC REG32(LCD_HSYNC) -+#define REG_LCD_VAT REG32(LCD_VAT) -+#define REG_LCD_DAH REG32(LCD_DAH) -+#define REG_LCD_DAV REG32(LCD_DAV) -+#define REG_LCD_PS REG32(LCD_PS) -+#define REG_LCD_CLS REG32(LCD_CLS) -+#define REG_LCD_SPL REG32(LCD_SPL) -+#define REG_LCD_REV REG32(LCD_REV) -+#define REG_LCD_CTRL REG32(LCD_CTRL) -+#define REG_LCD_STATE REG32(LCD_STATE) -+#define REG_LCD_IID REG32(LCD_IID) -+#define REG_LCD_DA0 REG32(LCD_DA0) -+#define REG_LCD_SA0 REG32(LCD_SA0) -+#define REG_LCD_FID0 REG32(LCD_FID0) -+#define REG_LCD_CMD0 REG32(LCD_CMD0) -+#define REG_LCD_DA1 REG32(LCD_DA1) -+#define REG_LCD_SA1 REG32(LCD_SA1) -+#define REG_LCD_FID1 REG32(LCD_FID1) -+#define REG_LCD_CMD1 REG32(LCD_CMD1) -+ -+/* LCD Configure Register */ -+#define LCD_CFG_LCDPIN_BIT 31 /* LCD pins selection */ -+#define LCD_CFG_LCDPIN_MASK (0x1 << LCD_CFG_LCDPIN_BIT) -+ #define LCD_CFG_LCDPIN_LCD (0x0 << LCD_CFG_LCDPIN_BIT) -+ #define LCD_CFG_LCDPIN_SLCD (0x1 << LCD_CFG_LCDPIN_BIT) -+#define LCD_CFG_PSM (1 << 23) /* PS signal mode */ -+#define LCD_CFG_CLSM (1 << 22) /* CLS signal mode */ -+#define LCD_CFG_SPLM (1 << 21) /* SPL signal mode */ -+#define LCD_CFG_REVM (1 << 20) /* REV signal mode */ -+#define LCD_CFG_HSYNM (1 << 19) /* HSYNC signal mode */ -+#define LCD_CFG_PCLKM (1 << 18) /* PCLK signal mode */ -+#define LCD_CFG_INVDAT (1 << 17) /* Inverse output data */ -+#define LCD_CFG_SYNDIR_IN (1 << 16) /* VSYNC&HSYNC direction */ -+#define LCD_CFG_PSP (1 << 15) /* PS pin reset state */ -+#define LCD_CFG_CLSP (1 << 14) /* CLS pin reset state */ -+#define LCD_CFG_SPLP (1 << 13) /* SPL pin reset state */ -+#define LCD_CFG_REVP (1 << 12) /* REV pin reset state */ -+#define LCD_CFG_HSP (1 << 11) /* HSYNC pority:0-active high,1-active low */ -+#define LCD_CFG_PCP (1 << 10) /* PCLK pority:0-rising,1-falling */ -+#define LCD_CFG_DEP (1 << 9) /* DE pority:0-active high,1-active low */ -+#define LCD_CFG_VSP (1 << 8) /* VSYNC pority:0-rising,1-falling */ -+#define LCD_CFG_PDW_BIT 4 /* STN pins utilization */ -+#define LCD_CFG_PDW_MASK (0x3 << LCD_DEV_PDW_BIT) -+#define LCD_CFG_PDW_1 (0 << LCD_CFG_PDW_BIT) /* LCD_D[0] */ -+ #define LCD_CFG_PDW_2 (1 << LCD_CFG_PDW_BIT) /* LCD_D[0:1] */ -+ #define LCD_CFG_PDW_4 (2 << LCD_CFG_PDW_BIT) /* LCD_D[0:3]/LCD_D[8:11] */ -+ #define LCD_CFG_PDW_8 (3 << LCD_CFG_PDW_BIT) /* LCD_D[0:7]/LCD_D[8:15] */ -+#define LCD_CFG_MODE_BIT 0 /* Display Device Mode Select */ -+#define LCD_CFG_MODE_MASK (0x0f << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_CFG_MODE_BIT) /* 16,18 bit TFT */ -+ #define LCD_CFG_MODE_SPECIAL_TFT_1 (1 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_SPECIAL_TFT_2 (2 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_SPECIAL_TFT_3 (3 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_INTER_CCIR656 (6 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_SERIAL_TFT (12 << LCD_CFG_MODE_BIT) -+ /* JZ47XX defines */ -+ #define LCD_CFG_MODE_SHARP_HR (1 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_CASIO_TFT (2 << LCD_CFG_MODE_BIT) -+ #define LCD_CFG_MODE_SAMSUNG_ALPHA (3 << LCD_CFG_MODE_BIT) -+ -+ -+ -+/* Vertical Synchronize Register */ -+#define LCD_VSYNC_VPS_BIT 16 /* VSYNC pulse start in line clock, fixed to 0 */ -+#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT) -+#define LCD_VSYNC_VPE_BIT 0 /* VSYNC pulse end in line clock */ -+#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT) -+ -+/* Horizontal Synchronize Register */ -+#define LCD_HSYNC_HPS_BIT 16 /* HSYNC pulse start position in dot clock */ -+#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT) -+#define LCD_HSYNC_HPE_BIT 0 /* HSYNC pulse end position in dot clock */ -+#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT) -+ -+/* Virtual Area Setting Register */ -+#define LCD_VAT_HT_BIT 16 /* Horizontal Total size in dot clock */ -+#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT) -+#define LCD_VAT_VT_BIT 0 /* Vertical Total size in dot clock */ -+#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT) -+ -+/* Display Area Horizontal Start/End Point Register */ -+#define LCD_DAH_HDS_BIT 16 /* Horizontal display area start in dot clock */ -+#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT) -+#define LCD_DAH_HDE_BIT 0 /* Horizontal display area end in dot clock */ -+#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT) -+ -+/* Display Area Vertical Start/End Point Register */ -+#define LCD_DAV_VDS_BIT 16 /* Vertical display area start in line clock */ -+#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT) -+#define LCD_DAV_VDE_BIT 0 /* Vertical display area end in line clock */ -+#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT) -+ -+/* PS Signal Setting */ -+#define LCD_PS_PSS_BIT 16 /* PS signal start position in dot clock */ -+#define LCD_PS_PSS_MASK (0xffff << LCD_PS_PSS_BIT) -+#define LCD_PS_PSE_BIT 0 /* PS signal end position in dot clock */ -+#define LCD_PS_PSE_MASK (0xffff << LCD_PS_PSE_BIT) -+ -+/* CLS Signal Setting */ -+#define LCD_CLS_CLSS_BIT 16 /* CLS signal start position in dot clock */ -+#define LCD_CLS_CLSS_MASK (0xffff << LCD_CLS_CLSS_BIT) -+#define LCD_CLS_CLSE_BIT 0 /* CLS signal end position in dot clock */ -+#define LCD_CLS_CLSE_MASK (0xffff << LCD_CLS_CLSE_BIT) -+ -+/* SPL Signal Setting */ -+#define LCD_SPL_SPLS_BIT 16 /* SPL signal start position in dot clock */ -+#define LCD_SPL_SPLS_MASK (0xffff << LCD_SPL_SPLS_BIT) -+#define LCD_SPL_SPLE_BIT 0 /* SPL signal end position in dot clock */ -+#define LCD_SPL_SPLE_MASK (0xffff << LCD_SPL_SPLE_BIT) -+ -+/* REV Signal Setting */ -+#define LCD_REV_REVS_BIT 16 /* REV signal start position in dot clock */ -+#define LCD_REV_REVS_MASK (0xffff << LCD_REV_REVS_BIT) -+ -+/* LCD Control Register */ -+#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */ -+#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT) -+ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */ -+ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */ -+ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */ -+#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode */ -+#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode */ -+#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */ -+#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */ -+#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT) -+ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */ -+ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */ -+ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */ -+#define LCD_CTRL_PDD_BIT 16 /* Load Palette Delay Counter */ -+#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT) -+#define LCD_CTRL_EOFM (1 << 13) /* EOF interrupt mask */ -+#define LCD_CTRL_SOFM (1 << 12) /* SOF interrupt mask */ -+#define LCD_CTRL_OFUM (1 << 11) /* Output FIFO underrun interrupt mask */ -+#define LCD_CTRL_IFUM0 (1 << 10) /* Input FIFO 0 underrun interrupt mask */ -+#define LCD_CTRL_IFUM1 (1 << 9) /* Input FIFO 1 underrun interrupt mask */ -+#define LCD_CTRL_LDDM (1 << 8) /* LCD disable done interrupt mask */ -+#define LCD_CTRL_QDM (1 << 7) /* LCD quick disable done interrupt mask */ -+#define LCD_CTRL_BEDN (1 << 6) /* Endian selection */ -+#define LCD_CTRL_PEDN (1 << 5) /* Endian in byte:0-msb first, 1-lsb first */ -+#define LCD_CTRL_DIS (1 << 4) /* Disable indicate bit */ -+#define LCD_CTRL_ENA (1 << 3) /* LCD enable bit */ -+#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */ -+#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT) -+ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */ -+ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */ -+ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */ -+ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */ -+ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */ -+ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */ -+ -+/* LCD Status Register */ -+#define LCD_STATE_QD (1 << 7) /* Quick Disable Done */ -+#define LCD_STATE_EOF (1 << 5) /* EOF Flag */ -+#define LCD_STATE_SOF (1 << 4) /* SOF Flag */ -+#define LCD_STATE_OFU (1 << 3) /* Output FIFO Underrun */ -+#define LCD_STATE_IFU0 (1 << 2) /* Input FIFO 0 Underrun */ -+#define LCD_STATE_IFU1 (1 << 1) /* Input FIFO 1 Underrun */ -+#define LCD_STATE_LDD (1 << 0) /* LCD Disabled */ -+ -+/* DMA Command Register */ -+#define LCD_CMD_SOFINT (1 << 31) -+#define LCD_CMD_EOFINT (1 << 30) -+#define LCD_CMD_PAL (1 << 28) -+#define LCD_CMD_LEN_BIT 0 -+#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT) -+ -+ -+/************************************************************************* -+ * USB Device -+ *************************************************************************/ -+#define USB_BASE UDC_BASE -+ -+#define USB_REG_FADDR (USB_BASE + 0x00) /* Function Address 8-bit */ -+#define USB_REG_POWER (USB_BASE + 0x01) /* Power Managemetn 8-bit */ -+#define USB_REG_INTRIN (USB_BASE + 0x02) /* Interrupt IN 16-bit */ -+#define USB_REG_INTROUT (USB_BASE + 0x04) /* Interrupt OUT 16-bit */ -+#define USB_REG_INTRINE (USB_BASE + 0x06) /* Intr IN enable 16-bit */ -+#define USB_REG_INTROUTE (USB_BASE + 0x08) /* Intr OUT enable 16-bit */ -+#define USB_REG_INTRUSB (USB_BASE + 0x0a) /* Interrupt USB 8-bit */ -+#define USB_REG_INTRUSBE (USB_BASE + 0x0b) /* Interrupt USB Enable 8-bit */ -+#define USB_REG_FRAME (USB_BASE + 0x0c) /* Frame number 16-bit */ -+#define USB_REG_INDEX (USB_BASE + 0x0e) /* Index register 8-bit */ -+#define USB_REG_TESTMODE (USB_BASE + 0x0f) /* USB test mode 8-bit */ -+ -+#define USB_REG_CSR0 (USB_BASE + 0x12) /* EP0 CSR 8-bit */ -+#define USB_REG_INMAXP (USB_BASE + 0x10) /* EP1-2 IN Max Pkt Size 16-bit */ -+#define USB_REG_INCSR (USB_BASE + 0x12) /* EP1-2 IN CSR LSB 8/16bit */ -+#define USB_REG_INCSRH (USB_BASE + 0x13) /* EP1-2 IN CSR MSB 8-bit */ -+#define USB_REG_OUTMAXP (USB_BASE + 0x14) /* EP1 OUT Max Pkt Size 16-bit */ -+#define USB_REG_OUTCSR (USB_BASE + 0x16) /* EP1 OUT CSR LSB 8/16bit */ -+#define USB_REG_OUTCSRH (USB_BASE + 0x17) /* EP1 OUT CSR MSB 8-bit */ -+#define USB_REG_OUTCOUNT (USB_BASE + 0x18) /* bytes in EP0/1 OUT FIFO 16-bit */ -+ -+#define USB_FIFO_EP0 (USB_BASE + 0x20) -+#define USB_FIFO_EP1 (USB_BASE + 0x24) -+#define USB_FIFO_EP2 (USB_BASE + 0x28) -+ -+#define USB_REG_EPINFO (USB_BASE + 0x78) /* Endpoint information */ -+#define USB_REG_RAMINFO (USB_BASE + 0x79) /* RAM information */ -+ -+#define USB_REG_INTR (USB_BASE + 0x200) /* DMA pending interrupts */ -+#define USB_REG_CNTL1 (USB_BASE + 0x204) /* DMA channel 1 control */ -+#define USB_REG_ADDR1 (USB_BASE + 0x208) /* DMA channel 1 AHB memory addr */ -+#define USB_REG_COUNT1 (USB_BASE + 0x20c) /* DMA channel 1 byte count */ -+#define USB_REG_CNTL2 (USB_BASE + 0x214) /* DMA channel 2 control */ -+#define USB_REG_ADDR2 (USB_BASE + 0x218) /* DMA channel 2 AHB memory addr */ -+#define USB_REG_COUNT2 (USB_BASE + 0x21c) /* DMA channel 2 byte count */ -+ -+ -+/* Power register bit masks */ -+#define USB_POWER_SUSPENDM 0x01 -+#define USB_POWER_RESUME 0x04 -+#define USB_POWER_HSMODE 0x10 -+#define USB_POWER_HSENAB 0x20 -+#define USB_POWER_SOFTCONN 0x40 -+ -+/* Interrupt register bit masks */ -+#define USB_INTR_SUSPEND 0x01 -+#define USB_INTR_RESUME 0x02 -+#define USB_INTR_RESET 0x04 -+ -+#define USB_INTR_EP0 0x0001 -+#define USB_INTR_INEP1 0x0002 -+#define USB_INTR_INEP2 0x0004 -+#define USB_INTR_OUTEP1 0x0002 -+ -+/* CSR0 bit masks */ -+#define USB_CSR0_OUTPKTRDY 0x01 -+#define USB_CSR0_INPKTRDY 0x02 -+#define USB_CSR0_SENTSTALL 0x04 -+#define USB_CSR0_DATAEND 0x08 -+#define USB_CSR0_SETUPEND 0x10 -+#define USB_CSR0_SENDSTALL 0x20 -+#define USB_CSR0_SVDOUTPKTRDY 0x40 -+#define USB_CSR0_SVDSETUPEND 0x80 -+ -+/* Endpoint CSR register bits */ -+#define USB_INCSRH_AUTOSET 0x80 -+#define USB_INCSRH_ISO 0x40 -+#define USB_INCSRH_MODE 0x20 -+#define USB_INCSRH_DMAREQENAB 0x10 -+#define USB_INCSRH_DMAREQMODE 0x04 -+#define USB_INCSR_CDT 0x40 -+#define USB_INCSR_SENTSTALL 0x20 -+#define USB_INCSR_SENDSTALL 0x10 -+#define USB_INCSR_FF 0x08 -+#define USB_INCSR_UNDERRUN 0x04 -+#define USB_INCSR_FFNOTEMPT 0x02 -+#define USB_INCSR_INPKTRDY 0x01 -+#define USB_OUTCSRH_AUTOCLR 0x80 -+#define USB_OUTCSRH_ISO 0x40 -+#define USB_OUTCSRH_DMAREQENAB 0x20 -+#define USB_OUTCSRH_DNYT 0x10 -+#define USB_OUTCSRH_DMAREQMODE 0x08 -+#define USB_OUTCSR_CDT 0x80 -+#define USB_OUTCSR_SENTSTALL 0x40 -+#define USB_OUTCSR_SENDSTALL 0x20 -+#define USB_OUTCSR_FF 0x10 -+#define USB_OUTCSR_DATAERR 0x08 -+#define USB_OUTCSR_OVERRUN 0x04 -+#define USB_OUTCSR_FFFULL 0x02 -+#define USB_OUTCSR_OUTPKTRDY 0x01 -+ -+/* Testmode register bits */ -+#define USB_TEST_SE0NAK 0x01 -+#define USB_TEST_J 0x02 -+#define USB_TEST_K 0x04 -+#define USB_TEST_PACKET 0x08 -+ -+/* DMA control bits */ -+#define USB_CNTL_ENA 0x01 -+#define USB_CNTL_DIR_IN 0x02 -+#define USB_CNTL_MODE_1 0x04 -+#define USB_CNTL_INTR_EN 0x08 -+#define USB_CNTL_EP(n) ((n) << 4) -+#define USB_CNTL_BURST_0 (0 << 9) -+#define USB_CNTL_BURST_4 (1 << 9) -+#define USB_CNTL_BURST_8 (2 << 9) -+#define USB_CNTL_BURST_16 (3 << 9) -+ -+#endif /* __JZ4740_REGS_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/serial.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/serial.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/serial.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/serial.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,30 @@ -+/* -+ * linux/include/asm-mips/mach-jz4740/serial.h -+ * -+ * Ingenic's JZ4740 common include. -+ * -+ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. -+ * -+ * Author: <yliu@ingenic.cn> -+ * -+ * 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 __ASM_BOARD_SERIAL_H__ -+#define __ASM_BOARD_SERIAL_H__ -+ -+#ifndef CONFIG_SERIAL_MANY_PORTS -+#undef RS_TABLE_SIZE -+#define RS_TABLE_SIZE 1 -+#endif -+ -+#define JZ_BASE_BAUD (12000000/16) -+ -+#define JZ_SERIAL_PORT_DEFNS \ -+ { .baud_base = JZ_BASE_BAUD, .irq = IRQ_UART0, \ -+ .flags = STD_COM_FLAGS, .iomem_base = (u8 *)UART0_BASE, \ -+ .iomem_reg_shift = 2, .io_type = SERIAL_IO_MEM }, -+ -+#endif /* __ASM_BORAD_SERIAL_H__ */ -diff -ruN linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/war.h linux-2.6.31/arch/mips/include/asm/mach-jz4740/war.h ---- linux-2.6.31-vanilla/arch/mips/include/asm/mach-jz4740/war.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/include/asm/mach-jz4740/war.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> -+ */ -+#ifndef __ASM_MIPS_MACH_JZ4740_WAR_H -+#define __ASM_MIPS_MACH_JZ4740_WAR_H -+ -+#define R4600_V1_INDEX_ICACHEOP_WAR 0 -+#define R4600_V1_HIT_CACHEOP_WAR 0 -+#define R4600_V2_HIT_CACHEOP_WAR 0 -+#define R5432_CP0_INTERRUPT_WAR 0 -+#define BCM1250_M3_WAR 0 -+#define SIBYTE_1956_WAR 0 -+#define MIPS4K_ICACHE_REFILL_WAR 0 -+#define MIPS_CACHE_SYNC_WAR 0 -+#define TX49XX_ICACHE_INDEX_INV_WAR 0 -+#define RM9000_CDEX_SMP_WAR 0 -+#define ICACHE_REFILLS_WORKAROUND_WAR 0 -+#define R10000_LLSC_WAR 0 -+#define MIPS34K_MISSED_ITLB_WAR 0 -+ -+#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */ -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/Kconfig linux-2.6.31/arch/mips/jz4740/Kconfig ---- linux-2.6.31-vanilla/arch/mips/jz4740/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/Kconfig 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,29 @@ -+choice -+ prompt "Machine type" -+ depends on MACH_JZ -+ default JZ4740_QI_LB60 -+ -+config JZ4740_QI_LB60 -+ bool "Qi Hardware Ben NanoNote" -+ select DMA_NONCOHERENT -+ select SOC_JZ4740 -+ -+endchoice -+ -+config SOC_JZ4740 -+ bool -+ select JZSOC -+ select GENERIC_GPIO -+ select ARCH_REQUIRE_GPIOLIB -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select IRQ_CPU -+ -+config JZSOC -+ bool -+ select JZRISC -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ -+config JZRISC -+ bool -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/Makefile linux-2.6.31/arch/mips/jz4740/Makefile ---- linux-2.6.31-vanilla/arch/mips/jz4740/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/Makefile 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,27 @@ -+# -+# Makefile for the Ingenic JZ4740. -+# -+ -+# Object file lists. -+ -+obj-y += prom.o irq.o time.o reset.o setup.o dma.o \ -+ gpio.o clock.o platform.o -+ -+obj-$(CONFIG_PROC_FS) += proc.o -+ -+# board specific support -+ -+obj-$(CONFIG_JZ4740_PAVO) += board-pavo.o -+obj-$(CONFIG_JZ4740_LEO) += board-leo.o -+obj-$(CONFIG_JZ4740_LYRA) += board-lyra.o -+obj-$(CONFIG_JZ4725_DIPPER) += board-dipper.o -+obj-$(CONFIG_JZ4720_VIRGO) += board-virgo.o -+obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o -+ -+# PM support -+ -+obj-$(CONFIG_PM) +=pm.o -+ -+# CPU Frequency scaling support -+ -+obj-$(CONFIG_CPU_FREQ_JZ) +=cpufreq.o -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/board-qi_lb60.c linux-2.6.31/arch/mips/jz4740/board-qi_lb60.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/board-qi_lb60.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/board-qi_lb60.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,389 @@ -+/* -+ * linux/arch/mips/jz4740/board-qi_lb60.c -+ * -+ * QI_LB60 setup routines. -+ * -+ * Copyright (c) 2009 Qi Hardware inc., -+ * Author: Xiangfu Liu <xiangfu@qi-hardware.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 3 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/gpio.h> -+ -+#include <asm/mach-jz4740/board-qi_lb60.h> -+#include <asm/mach-jz4740/platform.h> -+ -+#include <linux/input.h> -+#include <linux/gpio_keys.h> -+#include <linux/mtd/jz4740_nand.h> -+#include <linux/jz4740_fb.h> -+#include <linux/input/matrix_keypad.h> -+#include <linux/mtd/jz4740_nand.h> -+#include <linux/spi/spi.h> -+#include <linux/spi/spi_gpio.h> -+#include <linux/power_supply.h> -+#include <linux/power/jz4740-battery.h> -+ -+ -+/* NAND */ -+static struct nand_ecclayout qi_lb60_ecclayout_1gb = { -+ .eccbytes = 36, -+ .eccpos = { -+ 6, 7, 8, 9, 10, 11, 12, 13, -+ 14, 15, 16, 17, 18, 19, 20, 21, -+ 22, 23, 24, 25, 26, 27, 28, 29, -+ 30, 31, 32, 33, 34, 35, 36, 37, -+ 38, 39, 40, 41}, -+ .oobfree = { -+ {.offset = 2, -+ .length = 4}, -+ {.offset = 42, -+ .length = 22}} -+}; -+ -+static struct mtd_partition qi_lb60_partitions_1gb[] = { -+ { .name = "NAND BOOT partition", -+ .offset = 0 * 0x100000, -+ .size = 4 * 0x100000, -+ }, -+ { .name = "NAND KERNEL partition", -+ .offset = 4 * 0x100000, -+ .size = 4 * 0x100000, -+ }, -+ { .name = "NAND ROOTFS partition", -+ .offset = 8 * 0x100000, -+ .size = 504 * 0x100000, -+ }, -+ { .name = "NAND DATA partition", -+ .offset = 512 * 0x100000, -+ .size = 512 * 0x100000, -+ }, -+}; -+ -+static struct nand_ecclayout qi_lb60_ecclayout_2gb = { -+ .eccbytes = 72, -+ .eccpos = { -+ 12, 13, 14, 15, 16, 17, 18, 19, -+ 20, 21, 22, 23, 24, 25, 26, 27, -+ 28, 29, 30, 31, 32, 33, 34, 35, -+ 36, 37, 38, 39, 40, 41, 42, 43, -+ 44, 45, 46, 47, 48, 49, 50, 51, -+ 52, 53, 54, 55, 56, 57, 58, 59, -+ 60, 61, 62, 63, 64, 65, 66, 67, -+ 68, 69, 70, 71, 72, 73, 74, 75, -+ 76, 77, 78, 79, 80, 81, 82, 83}, -+ .oobfree = { -+ {.offset = 2, -+ .length = 10}, -+ {.offset = 84, -+ .length = 44}} -+}; -+ -+static struct mtd_partition qi_lb60_partitions_2gb[] = { -+ { .name = "NAND BOOT partition", -+ .offset = 0 * 0x100000, -+ .size = 4 * 0x100000, -+ }, -+ { .name = "NAND KERNEL partition", -+ .offset = 4 * 0x100000, -+ .size = 4 * 0x100000, -+ }, -+ { .name = "NAND ROOTFS partition", -+ .offset = 8 * 0x100000, -+ .size = 504 * 0x100000, -+ }, -+ { .name = "NAND DATA partition", -+ .offset = 512 * 0x100000, -+ .size = (512 + 1024) * 0x100000, -+ }, -+}; -+ -+static void qi_lb60_nand_ident(struct platform_device *pdev, -+ struct nand_chip *chip, -+ struct mtd_partition **partitions, -+ int *num_partitions) -+{ -+ if (chip->page_shift == 12) { -+ chip->ecc.layout = &qi_lb60_ecclayout_2gb; -+ *partitions = qi_lb60_partitions_2gb; -+ *num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb); -+ } else { -+ chip->ecc.layout = &qi_lb60_ecclayout_1gb; -+ *partitions = qi_lb60_partitions_1gb; -+ *num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb); -+ } -+} -+ -+static struct jz_nand_platform_data qi_lb60_nand_pdata = { -+ .ident_callback = qi_lb60_nand_ident, -+ .busy_gpio = 94, -+}; -+ -+ -+/* Keyboard*/ -+ -+/* #define KEEP_UART_ALIVE -+ * don't define this. the keyboard and keyboard both work -+ */ -+ -+#define KEY_QI_QI KEY_F13 -+#define KEY_QI_UPRED KEY_RIGHTSHIFT -+#define KEY_QI_VOLUP KEY_F15 -+#define KEY_QI_VOLDOWN KEY_F16 -+#define KEY_QI_FN KEY_RIGHTCTRL -+ -+static const uint32_t qi_lb60_keymap[] = { -+ KEY(0, 0, KEY_F1), /* S2 */ -+ KEY(0, 1, KEY_F2), /* S3 */ -+ KEY(0, 2, KEY_F3), /* S4 */ -+ KEY(0, 3, KEY_F4), /* S5 */ -+ KEY(0, 4, KEY_F5), /* S6 */ -+ KEY(0, 5, KEY_F6), /* S7 */ -+ KEY(0, 6, KEY_F7), /* S8 */ -+ -+ KEY(1, 0, KEY_Q), /* S10 */ -+ KEY(1, 1, KEY_W), /* S11 */ -+ KEY(1, 2, KEY_E), /* S12 */ -+ KEY(1, 3, KEY_R), /* S13 */ -+ KEY(1, 4, KEY_T), /* S14 */ -+ KEY(1, 5, KEY_Y), /* S15 */ -+ KEY(1, 6, KEY_U), /* S16 */ -+ KEY(1, 7, KEY_I), /* S17 */ -+ KEY(2, 0, KEY_A), /* S18 */ -+ KEY(2, 1, KEY_S), /* S19 */ -+ KEY(2, 2, KEY_D), /* S20 */ -+ KEY(2, 3, KEY_F), /* S21 */ -+ KEY(2, 4, KEY_G), /* S22 */ -+ KEY(2, 5, KEY_H), /* S23 */ -+ KEY(2, 6, KEY_J), /* S24 */ -+ KEY(2, 7, KEY_K), /* S25 */ -+ KEY(3, 0, KEY_ESC), /* S26 */ -+ KEY(3, 1, KEY_Z), /* S27 */ -+ KEY(3, 2, KEY_X), /* S28 */ -+ KEY(3, 3, KEY_C), /* S29 */ -+ KEY(3, 4, KEY_V), /* S30 */ -+ KEY(3, 5, KEY_B), /* S31 */ -+ KEY(3, 6, KEY_N), /* S32 */ -+ KEY(3, 7, KEY_M), /* S33 */ -+ KEY(4, 0, KEY_TAB), /* S34 */ -+ KEY(4, 1, KEY_CAPSLOCK), /* S35 */ -+ KEY(4, 2, KEY_BACKSLASH), /* S36 */ -+ KEY(4, 3, KEY_APOSTROPHE), /* S37 */ -+ KEY(4, 4, KEY_COMMA), /* S38 */ -+ KEY(4, 5, KEY_DOT), /* S39 */ -+ KEY(4, 6, KEY_SLASH), /* S40 */ -+ KEY(4, 7, KEY_UP), /* S41 */ -+ KEY(5, 0, KEY_O), /* S42 */ -+ KEY(5, 1, KEY_L), /* S43 */ -+ KEY(5, 2, KEY_EQUAL), /* S44 */ -+ KEY(5, 3, KEY_QI_UPRED), /* S45 */ -+ KEY(5, 4, KEY_SPACE), /* S46 */ -+ KEY(5, 5, KEY_QI_QI), /* S47 */ -+ KEY(5, 6, KEY_LEFTCTRL), /* S48 */ -+ KEY(5, 7, KEY_LEFT), /* S49 */ -+ KEY(6, 0, KEY_F8), /* S50 */ -+ KEY(6, 1, KEY_P), /* S51 */ -+ KEY(6, 2, KEY_BACKSPACE),/* S52 */ -+ KEY(6, 3, KEY_ENTER), /* S53 */ -+ KEY(6, 4, KEY_QI_VOLUP), /* S54 */ -+ KEY(6, 5, KEY_QI_VOLDOWN), /* S55 */ -+ KEY(6, 6, KEY_DOWN), /* S56 */ -+ KEY(6, 7, KEY_RIGHT), /* S57 */ -+ -+#ifndef KEEP_UART_ALIVE -+ KEY(7, 0, KEY_LEFTSHIFT), /* S58 */ -+ KEY(7, 1, KEY_LEFTALT), /* S59 */ -+ KEY(7, 2, KEY_QI_FN), /* S60 */ -+#endif -+}; -+ -+static const struct matrix_keymap_data qi_lb60_keymap_data = { -+ .keymap = qi_lb60_keymap, -+ .keymap_size = ARRAY_SIZE(qi_lb60_keymap), -+}; -+ -+static const unsigned int qi_lb60_keypad_cols[] = { -+ 74, 75, 76, 77, 78, 79, 80, 81, -+}; -+ -+static const unsigned int qi_lb60_keypad_rows[] = { -+ 114, 115, 116, 117, 118, 119, 120, -+#ifndef KEEP_UART_ALIVE -+ 122, -+#endif -+}; -+ -+static struct matrix_keypad_platform_data qi_lb60_pdata = { -+ .keymap_data = &qi_lb60_keymap_data, -+ .col_gpios = qi_lb60_keypad_cols, -+ .row_gpios = qi_lb60_keypad_rows, -+ .num_col_gpios = ARRAY_SIZE(qi_lb60_keypad_cols), -+ .num_row_gpios = ARRAY_SIZE(qi_lb60_keypad_rows), -+ .col_scan_delay_us = 10, -+ .debounce_ms = 10, -+ .wakeup = 1, -+ .active_low = 1, -+}; -+ -+static struct platform_device qi_lb60_keypad = { -+ .name = "matrix-keypad", -+ .id = -1, -+ .dev = { -+ .platform_data = &qi_lb60_pdata, -+ }, -+}; -+ -+/* Display */ -+static struct fb_videomode qi_lb60_video_modes[] = { -+ { -+ .name = "320x240", -+ .xres = 320, -+ .yres = 240, -+ .pixclock = 700000, -+ .left_margin = 140, -+ .right_margin = 273, -+ .upper_margin = 20, -+ .lower_margin = 2, -+ .hsync_len = 1, -+ .vsync_len = 1, -+ .sync = 0, -+ .vmode = FB_VMODE_NONINTERLACED, -+ }, -+}; -+ -+static struct jz4740_fb_platform_data qi_lb60_fb_pdata = { -+ .width = 60, -+ .height = 45, -+ .num_modes = ARRAY_SIZE(qi_lb60_video_modes), -+ .modes = qi_lb60_video_modes, -+ .bpp = 24, -+ .lcd_type = JZ_LCD_TYPE_8BIT_SERIAL, -+}; -+ -+ -+struct spi_gpio_platform_data spigpio_platform_data = { -+ .sck = JZ_GPIO_PORTC(23), -+ .mosi = JZ_GPIO_PORTC(22), -+ .miso = JZ_GPIO_PORTC(22), -+ .num_chipselect = 1, -+}; -+ -+static struct platform_device spigpio_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &spigpio_platform_data, -+ }, -+}; -+ -+static struct spi_board_info qi_lb60_spi_board_info[] = { -+ { -+ .modalias = "gpm940b0", -+ .controller_data = (void*)JZ_GPIO_PORTC(21), -+ .chip_select = 0, -+ .bus_num = 1, -+ .max_speed_hz = 30 * 1000, -+ }, -+}; -+ -+/* Battery */ -+static struct jz_batt_info qi_lb60_battery_pdata = { -+ .dc_dect_gpio = GPIO_DC_DETE_N, -+ .usb_dect_gpio = GPIO_USB_DETE, -+ .charg_stat_gpio = GPIO_CHARG_STAT_N, -+ -+ .min_voltag = 3600000, -+ .max_voltag = 4200000, -+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO, -+}; -+ -+/* GPIO Key: power */ -+static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = { -+ [0] = { -+ .code = KEY_POWER, -+ .gpio = GPIO_WAKEUP_N, -+ .active_low = 1, -+ .desc = "Power", -+ .wakeup = 1, -+ }, -+}; -+ -+static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = { -+ .nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons), -+ .buttons = qi_lb60_gpio_keys_buttons, -+}; -+ -+static struct platform_device qi_lb60_gpio_keys = { -+ .name = "gpio-keys", -+ .id = -1, -+ .dev = { -+ .platform_data = &qi_lb60_gpio_keys_data, -+ } -+}; -+/* -+static struct jz_mmc_platform_data jz_mmc_pdata = { -+ .card_detect_gpio = JZ_GPIO_PORTD(0), -+ .read_only_gpio = JZ_GPIO_PORTD(16), -+ .power_gpio = JZ_GPIO_PORTD(2), -+};*/ -+ -+static struct platform_device *jz_platform_devices[] __initdata = { -+ &jz4740_usb_ohci_device, -+ &jz4740_usb_gdt_device, -+ &jz4740_mmc_device, -+ &jz4740_nand_device, -+ &qi_lb60_keypad, -+ &spigpio_device, -+ &jz4740_framebuffer_device, -+ &jz4740_i2s_device, -+ &jz4740_codec_device, -+ &jz4740_rtc_device, -+ &jz4740_adc_device, -+ &jz4740_battery_device, -+ &qi_lb60_gpio_keys, -+}; -+ -+static void __init board_gpio_setup(void) -+{ -+ /* We only need to enable/disable pullup here for pins used in generic -+ * drivers. Everything else is done by the drivers themselfs. */ -+ jz_gpio_disable_pullup(GPIO_SD_VCC_EN_N); -+ jz_gpio_disable_pullup(GPIO_SD_CD_N); -+ jz_gpio_disable_pullup(GPIO_SD_WP); -+} -+ -+static int __init qi_lb60_init_platform_devices(void) -+{ -+ jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata; -+ jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata; -+ jz4740_battery_device.dev.platform_data = &qi_lb60_battery_pdata; -+ -+ spi_register_board_info(qi_lb60_spi_board_info, -+ ARRAY_SIZE(qi_lb60_spi_board_info)); -+ -+ return platform_add_devices(jz_platform_devices, -+ ARRAY_SIZE(jz_platform_devices)); -+ -+} -+extern int jz_gpiolib_init(void); -+ -+static int __init qi_lb60_board_setup(void) -+{ -+ printk("Qi Hardware JZ4740 QI_LB60 setup\n"); -+ if (jz_gpiolib_init()) -+ panic("Failed to initalize jz gpio\n"); -+ -+ board_gpio_setup(); -+ -+ if (qi_lb60_init_platform_devices()) -+ panic("Failed to initalize platform devices\n"); -+ -+ return 0; -+} -+ -+arch_initcall(qi_lb60_board_setup); -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/clock.c linux-2.6.31/arch/mips/jz4740/clock.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/clock.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/clock.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,777 @@ -+ -+#include <linux/kernel.h> -+#include <linux/errno.h> -+#include <linux/clk.h> -+#include <linux/spinlock.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/list.h> -+#include <linux/err.h> -+ -+#define JZ_REG_CLOCK_CTRL 0x00 -+#define JZ_REG_CLOCK_PLL 0x10 -+#define JZ_REG_CLOCK_GATE 0x20 -+#define JZ_REG_CLOCK_I2S 0x60 -+#define JZ_REG_CLOCK_LCD 0x64 -+#define JZ_REG_CLOCK_MMC 0x68 -+#define JZ_REG_CLOCK_UHC 0x6C -+#define JZ_REG_CLOCK_SPI 0x74 -+ -+#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31) -+#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30) -+#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29) -+#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000 -+#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22) -+#define JZ_CLOCK_CTRL_PLL_HALF BIT(21) -+#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000 -+#define JZ_CLOCK_CTRL_UDIV_OFFSET 23 -+#define JZ_CLOCK_CTRL_LDIV_OFFSET 16 -+#define JZ_CLOCK_CTRL_MDIV_OFFSET 12 -+#define JZ_CLOCK_CTRL_PDIV_OFFSET 8 -+#define JZ_CLOCK_CTRL_HDIV_OFFSET 4 -+#define JZ_CLOCK_CTRL_CDIV_OFFSET 0 -+ -+#define JZ_CLOCK_GATE_UART0 BIT(0) -+#define JZ_CLOCK_GATE_TCU BIT(1) -+#define JZ_CLOCK_GATE_RTC BIT(2) -+#define JZ_CLOCK_GATE_I2C BIT(3) -+#define JZ_CLOCK_GATE_SPI BIT(4) -+#define JZ_CLOCK_GATE_AIC_PCLK BIT(5) -+#define JZ_CLOCK_GATE_AIC BIT(6) -+#define JZ_CLOCK_GATE_MMC BIT(7) -+#define JZ_CLOCK_GATE_ADC BIT(8) -+#define JZ_CLOCK_GATE_CIM BIT(9) -+#define JZ_CLOCK_GATE_LCD BIT(10) -+#define JZ_CLOCK_GATE_UDC BIT(11) -+#define JZ_CLOCK_GATE_DMAC BIT(12) -+#define JZ_CLOCK_GATE_IPU BIT(13) -+#define JZ_CLOCK_GATE_UHC BIT(14) -+#define JZ_CLOCK_GATE_UART1 BIT(15) -+ -+#define JZ_CLOCK_I2S_DIV_MASK 0x01ff -+ -+#define JZ_CLOCK_LCD_DIV_MASK 0x01ff -+ -+#define JZ_CLOCK_MMC_DIV_MASK 0x001f -+ -+#define JZ_CLOCK_UHC_DIV_MASK 0x000f -+ -+#define JZ_CLOCK_SPI_SRC_PLL BIT(31) -+#define JZ_CLOCK_SPI_DIV_MASK 0x000f -+ -+#define JZ_CLOCK_PLL_M_MASK 0x01ff -+#define JZ_CLOCK_PLL_N_MASK 0x001f -+#define JZ_CLOCK_PLL_OD_MASK 0x0003 -+#define JZ_CLOCK_PLL_STABLE BIT(10) -+#define JZ_CLOCK_PLL_BYPASS BIT(9) -+#define JZ_CLOCK_PLL_ENABLED BIT(8) -+#define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f -+#define JZ_CLOCK_PLL_M_OFFSET 23 -+#define JZ_CLOCK_PLL_N_OFFSET 18 -+#define JZ_CLOCK_PLL_OD_OFFSET 16 -+ -+static void __iomem *jz_clock_base; -+spinlock_t jz_clock_lock; -+static LIST_HEAD(jz_clocks); -+ -+struct clk { -+ const char *name; -+ struct clk* parent; -+ -+ uint32_t gate_bit; -+ -+ unsigned long (*get_rate)(struct clk* clk); -+ unsigned long (*round_rate)(struct clk *clk, unsigned long rate); -+ int (*set_rate)(struct clk* clk, unsigned long rate); -+ int (*enable)(struct clk* clk); -+ int (*disable)(struct clk* clk); -+ -+ int (*set_parent)(struct clk* clk, struct clk *parent); -+ struct list_head list; -+}; -+ -+struct main_clk { -+ struct clk clk; -+ uint32_t div_offset; -+}; -+ -+struct divided_clk { -+ struct clk clk; -+ uint32_t reg; -+ uint32_t mask; -+}; -+ -+struct static_clk { -+ struct clk clk; -+ unsigned long rate; -+}; -+ -+static uint32_t jz_clk_reg_read(int reg) -+{ -+ return readl(jz_clock_base + reg); -+} -+ -+static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask) -+{ -+ uint32_t val2; -+ -+ spin_lock(&jz_clock_lock); -+ val2 = readl(jz_clock_base + reg); -+ val2 &= ~mask; -+ val2 |= val; -+ writel(val2, jz_clock_base + reg); -+ spin_unlock(&jz_clock_lock); -+} -+ -+static void jz_clk_reg_set_bits(int reg, uint32_t mask) -+{ -+ uint32_t val; -+ -+ spin_lock(&jz_clock_lock); -+ val = readl(jz_clock_base + reg); -+ val |= mask; -+ writel(val, jz_clock_base + reg); -+ spin_unlock(&jz_clock_lock); -+} -+ -+static void jz_clk_reg_clear_bits(int reg, uint32_t mask) -+{ -+ uint32_t val; -+ -+ spin_lock(&jz_clock_lock); -+ val = readl(jz_clock_base + reg); -+ val &= ~mask; -+ writel(val, jz_clock_base + reg); -+ spin_unlock(&jz_clock_lock); -+} -+ -+static int jz_clk_enable_gating(struct clk *clk) -+{ -+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit); -+ return 0; -+} -+ -+static int jz_clk_disable_gating(struct clk *clk) -+{ -+ jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit); -+ return 0; -+} -+ -+static unsigned long jz_clk_static_get_rate(struct clk *clk) -+{ -+ return ((struct static_clk*)clk)->rate; -+} -+ -+static int jz_clk_ko_enable(struct clk* clk) -+{ -+ jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE); -+ return 0; -+} -+ -+static int jz_clk_ko_disable(struct clk* clk) -+{ -+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE); -+ return 0; -+} -+ -+ -+static const int pllno[] = {1, 2, 2, 4}; -+ -+static unsigned long jz_clk_pll_get_rate(struct clk *clk) -+{ -+ uint32_t val; -+ int m; -+ int n; -+ int od; -+ -+ val = jz_clk_reg_read(JZ_REG_CLOCK_PLL); -+ -+ if (val & JZ_CLOCK_PLL_BYPASS) -+ return clk_get_rate(clk->parent); -+ -+ m = ((val >> 23) & 0x1ff) + 2; -+ n = ((val >> 18) & 0x1f) + 2; -+ od = (val >> 16) & 0x3; -+ -+ return clk_get_rate(clk->parent) * (m / n) / pllno[od]; -+} -+ -+static unsigned long jz_clk_pll_half_get_rate(struct clk *clk) -+{ -+ uint32_t reg; -+ -+ reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL); -+ if (reg & JZ_CLOCK_CTRL_PLL_HALF) -+ return jz_clk_pll_get_rate(NULL) >> 1; -+ return jz_clk_pll_get_rate(NULL); -+} -+ -+ -+ -+static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ -+static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate) -+{ -+ unsigned long parent_rate = jz_clk_pll_get_rate(NULL); -+ int div; -+ -+ div = parent_rate / rate; -+ if (div > 32) -+ return parent_rate / 32; -+ else if (div < 1) -+ return parent_rate; -+ -+ div &= (0x3 << (ffs(div) - 1)); -+ -+ return parent_rate / div; -+} -+ -+static unsigned long jz_clk_main_get_rate(struct clk *clk) { -+ struct main_clk *mclk = (struct main_clk*)clk; -+ uint32_t div; -+ -+ div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL); -+ -+ div >>= mclk->div_offset; -+ div &= 0xf; -+ -+ if (div >= ARRAY_SIZE(jz_clk_main_divs)) -+ div = ARRAY_SIZE(jz_clk_main_divs) - 1; -+ -+ return jz_clk_pll_get_rate(NULL) / jz_clk_main_divs[div]; -+} -+ -+static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate) -+{ -+ struct main_clk *mclk = (struct main_clk*)clk; -+ int i; -+ int div; -+ unsigned long parent_rate = jz_clk_pll_get_rate(NULL); -+ -+ rate = jz_clk_main_round_rate(clk, rate); -+ -+ div = parent_rate / rate; -+ -+ i = (ffs(div) - 1) << 1; -+ if (i > 0 && !(div & BIT(i-1))) -+ i -= 1; -+ -+ jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset, -+ 0xf << mclk->div_offset); -+ -+ return 0; -+} -+ -+ -+static struct static_clk jz_clk_ext = { -+ .clk = { -+ .name = "ext", -+ .get_rate = jz_clk_static_get_rate, -+ }, -+}; -+ -+static struct clk jz_clk_pll = { -+ .name = "pll", -+ .parent = &jz_clk_ext.clk, -+ .get_rate = jz_clk_pll_get_rate, -+}; -+ -+static struct clk jz_clk_pll_half = { -+ .name = "pll half", -+ .parent = &jz_clk_pll, -+ .get_rate = jz_clk_pll_half_get_rate, -+}; -+ -+static struct main_clk jz_clk_cpu = { -+ .clk = { -+ .name = "cclk", -+ .parent = &jz_clk_pll, -+ .get_rate = jz_clk_main_get_rate, -+ .set_rate = jz_clk_main_set_rate, -+ .round_rate = jz_clk_main_round_rate, -+ }, -+ .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET, -+}; -+ -+static struct main_clk jz_clk_memory = { -+ .clk = { -+ .name = "mclk", -+ .parent = &jz_clk_pll, -+ .get_rate = jz_clk_main_get_rate, -+ .set_rate = jz_clk_main_set_rate, -+ .round_rate = jz_clk_main_round_rate, -+ }, -+ .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET, -+}; -+ -+static struct main_clk jz_clk_high_speed_peripheral = { -+ .clk = { -+ .name = "hclk", -+ .parent = &jz_clk_pll, -+ .get_rate = jz_clk_main_get_rate, -+ .set_rate = jz_clk_main_set_rate, -+ .round_rate = jz_clk_main_round_rate, -+ }, -+ .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET, -+}; -+ -+ -+static struct main_clk jz_clk_low_speed_peripheral = { -+ .clk = { -+ .name = "pclk", -+ .parent = &jz_clk_pll, -+ .get_rate = jz_clk_main_get_rate, -+ .set_rate = jz_clk_main_set_rate, -+ }, -+ .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET, -+}; -+ -+static struct clk jz_clk_ko = { -+ .name = "cko", -+ .parent = &jz_clk_memory.clk, -+ .enable = jz_clk_ko_enable, -+ .disable = jz_clk_ko_disable, -+}; -+ -+static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent) -+{ -+ if (parent == &jz_clk_pll) -+ jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI); -+ else if(parent == &jz_clk_ext.clk) -+ jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI); -+ else -+ return -EINVAL; -+ -+ clk->parent = parent; -+ -+ return 0; -+} -+ -+static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent) -+{ -+ if (parent == &jz_clk_pll_half) -+ jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL); -+ else if(parent == &jz_clk_ext.clk) -+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL); -+ else -+ return -EINVAL; -+ -+ clk->parent = parent; -+ -+ return 0; -+} -+ -+static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent) -+{ -+ if (parent == &jz_clk_pll_half) -+ jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL); -+ else if(parent == &jz_clk_ext.clk) -+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL); -+ else -+ return -EINVAL; -+ -+ clk->parent = parent; -+ -+ return 0; -+} -+ -+static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate) -+{ -+ int div; -+ -+ if (clk->parent == &jz_clk_ext.clk) -+ return -EINVAL; -+ -+ div = clk_get_rate(clk->parent) / rate - 1; -+ -+ if (div < 0) -+ div = 0; -+ else if (div > 63) -+ div = 63; -+ -+ jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET, -+ JZ_CLOCK_CTRL_UDIV_MASK); -+ return 0; -+} -+ -+static unsigned long jz_clk_udc_get_rate(struct clk *clk) -+{ -+ int div; -+ -+ if (clk->parent == &jz_clk_ext.clk) -+ return clk_get_rate(clk->parent); -+ -+ div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK); -+ div >>= JZ_CLOCK_CTRL_UDIV_OFFSET; -+ div += 1; -+ -+ return clk_get_rate(clk->parent) / div; -+} -+ -+static unsigned long jz_clk_divided_get_rate(struct clk *clk) -+{ -+ struct divided_clk *dclk = (struct divided_clk*)clk; -+ int div; -+ -+ if (clk->parent == &jz_clk_ext.clk) -+ return clk_get_rate(clk->parent); -+ -+ div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1; -+ -+ return clk_get_rate(clk->parent) / div; -+} -+ -+static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate) -+{ -+ struct divided_clk *dclk = (struct divided_clk*)clk; -+ int div; -+ -+ if (clk->parent == &jz_clk_ext.clk) -+ return -EINVAL; -+ -+ div = clk_get_rate(clk->parent) / rate - 1; -+ -+ if (div < 0) -+ div = 0; -+ else if(div > dclk->mask) -+ div = dclk->mask; -+ -+ jz_clk_reg_write_mask(dclk->reg, div, dclk->mask); -+ -+ return 0; -+} -+ -+static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ int div; -+ unsigned long parent_rate = jz_clk_pll_half_get_rate(NULL); -+ -+ if (rate > 150000000) -+ return 150000000; -+ -+ div = parent_rate / rate; -+ if (div < 1) -+ div = 1; -+ else if(div > 32) -+ div = 32; -+ -+ return parent_rate / div; -+} -+ -+static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ int div; -+ -+ if (rate > 150000000) -+ return -EINVAL; -+ -+ div = jz_clk_pll_half_get_rate(NULL) / rate - 1; -+ if (div < 0) -+ div = 0; -+ else if(div > 31) -+ div = 31; -+ -+ jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET, -+ JZ_CLOCK_CTRL_LDIV_MASK); -+} -+ -+static unsigned long jz_clk_ldclk_get_rate(struct clk *clk) -+{ -+ int div; -+ -+ div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK; -+ div >>= JZ_CLOCK_CTRL_LDIV_OFFSET; -+ -+ return jz_clk_pll_half_get_rate(NULL) / (div + 1); -+} -+ -+static struct clk jz_clk_ld = { -+ .name = "lcd", -+ .parent = &jz_clk_pll_half, -+ .set_rate = jz_clk_ldclk_set_rate, -+ .get_rate = jz_clk_ldclk_get_rate, -+ .round_rate = jz_clk_ldclk_round_rate, -+}; -+ -+static struct divided_clk jz_clk_lp = { -+ .clk = { -+ .name = "lcd_pclk", -+ .parent = &jz_clk_pll_half, -+ }, -+ .reg = JZ_REG_CLOCK_LCD, -+ .mask = JZ_CLOCK_LCD_DIV_MASK, -+}; -+ -+static struct clk jz_clk_cim_mclk = { -+ .name = "cim_mclk", -+ .parent = &jz_clk_high_speed_peripheral.clk, -+}; -+ -+static struct static_clk jz_clk_cim_pclk = { -+ .clk = { -+ .name = "cim_pclk", -+ .gate_bit = JZ_CLOCK_GATE_CIM, -+ .get_rate = jz_clk_static_get_rate, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+ }, -+}; -+ -+static struct divided_clk jz_clk_i2s = { -+ .clk = { -+ .name = "i2s", -+ .parent = &jz_clk_ext.clk, -+ .gate_bit = JZ_CLOCK_GATE_AIC, -+ .set_parent = jz_clk_i2s_set_parent, -+ .set_rate = jz_clk_divided_set_rate, -+ .get_rate = jz_clk_divided_get_rate, -+ }, -+ .reg = JZ_REG_CLOCK_I2S, -+ .mask = JZ_CLOCK_I2S_DIV_MASK, -+}; -+ -+static struct divided_clk jz_clk_mmc = { -+ .clk = { -+ .name = "mmc", -+ .parent = &jz_clk_pll_half, -+ .gate_bit = JZ_CLOCK_GATE_MMC, -+ .set_rate = jz_clk_divided_set_rate, -+ .get_rate = jz_clk_divided_get_rate, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+ }, -+ .reg = JZ_REG_CLOCK_MMC, -+ .mask = JZ_CLOCK_MMC_DIV_MASK, -+}; -+ -+static struct divided_clk jz_clk_uhc = { -+ .clk = { -+ .name = "uhc", -+ .parent = &jz_clk_pll_half, -+ .gate_bit = JZ_CLOCK_GATE_UHC, -+ .set_rate = jz_clk_divided_set_rate, -+ .get_rate = jz_clk_divided_get_rate, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+ }, -+ .reg = JZ_REG_CLOCK_UHC, -+ .mask = JZ_CLOCK_UHC_DIV_MASK, -+}; -+ -+static struct clk jz_clk_udc = { -+ .name = "udc", -+ .parent = &jz_clk_ext.clk, -+ .set_parent = jz_clk_udc_set_parent, -+ .set_rate = jz_clk_udc_set_rate, -+ .get_rate = jz_clk_udc_get_rate, -+}; -+ -+static struct divided_clk jz_clk_spi = { -+ .clk = { -+ .name = "spi", -+ .parent = &jz_clk_ext.clk, -+ .gate_bit = JZ_CLOCK_GATE_SPI, -+ .set_rate = jz_clk_divided_set_rate, -+ .get_rate = jz_clk_divided_get_rate, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+ .set_parent = jz_clk_spi_set_parent, -+ }, -+ .reg = JZ_REG_CLOCK_SPI, -+ .mask = JZ_CLOCK_SPI_DIV_MASK, -+}; -+ -+static struct clk jz_clk_uart0 = { -+ .name = "uart0", -+ .parent = &jz_clk_ext.clk, -+ .gate_bit = JZ_CLOCK_GATE_UART0, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+}; -+ -+static struct clk jz_clk_uart1 = { -+ .name = "uart1", -+ .parent = &jz_clk_ext.clk, -+ .gate_bit = JZ_CLOCK_GATE_UART1, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+}; -+ -+static struct clk jz_clk_dma = { -+ .name = "dma", -+ .parent = &jz_clk_high_speed_peripheral.clk, -+ .gate_bit = JZ_CLOCK_GATE_UART0, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+}; -+ -+static struct clk jz_clk_ipu = { -+ .name = "ipu", -+ .parent = &jz_clk_high_speed_peripheral.clk, -+ .gate_bit = JZ_CLOCK_GATE_IPU, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+}; -+ -+static struct clk jz_clk_adc = { -+ .name = "adc", -+ .parent = &jz_clk_ext.clk, -+ .gate_bit = JZ_CLOCK_GATE_ADC, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+}; -+ -+static struct clk jz_clk_i2c = { -+ .name = "i2c", -+ .parent = &jz_clk_ext.clk, -+ .gate_bit = JZ_CLOCK_GATE_I2C, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+}; -+ -+static struct static_clk jz_clk_rtc = { -+ .clk = { -+ .name = "rtc", -+ .gate_bit = JZ_CLOCK_GATE_RTC, -+ .enable = jz_clk_enable_gating, -+ .disable = jz_clk_disable_gating, -+ }, -+ .rate = 32768, -+}; -+ -+int clk_enable(struct clk *clk) -+{ -+ if (!clk->enable) -+ return -EINVAL; -+ -+ return clk->enable(clk); -+} -+EXPORT_SYMBOL_GPL(clk_enable); -+ -+void clk_disable(struct clk *clk) -+{ -+ if (clk->disable) -+ clk->disable(clk); -+} -+EXPORT_SYMBOL_GPL(clk_disable); -+ -+unsigned long clk_get_rate(struct clk *clk) -+{ -+ if (clk->get_rate) -+ return clk->get_rate(clk); -+ if (clk->parent) -+ return clk_get_rate(clk->parent); -+ -+ return -EINVAL; -+} -+EXPORT_SYMBOL_GPL(clk_get_rate); -+ -+int clk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ if (!clk->set_rate) -+ return -EINVAL; -+ return clk->set_rate(clk, rate); -+} -+EXPORT_SYMBOL_GPL(clk_set_rate); -+ -+long clk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ if (clk->round_rate) -+ return clk->round_rate(clk, rate); -+ -+ return -EINVAL; -+} -+EXPORT_SYMBOL_GPL(clk_round_rate); -+ -+int clk_set_parent(struct clk *clk, struct clk *parent) -+{ -+ int ret; -+ -+ if (!clk->set_parent) -+ return -EINVAL; -+ -+ clk->disable(clk); -+ ret = clk->set_parent(clk, parent); -+ clk->enable(clk); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(clk_set_parent); -+ -+ -+struct clk *clk_get(struct device *dev, const char *name) -+{ -+ struct clk *clk; -+ -+ list_for_each_entry(clk, &jz_clocks, list) { -+ if (strcmp(clk->name, name)) -+ return clk; -+ } -+ return ERR_PTR(-ENOENT); -+} -+EXPORT_SYMBOL_GPL(clk_get); -+ -+void clk_put(struct clk *clk) -+{ -+} -+EXPORT_SYMBOL_GPL(clk_put); -+ -+inline static void clk_add(struct clk *clk) -+{ -+ list_add_tail(&clk->list, &jz_clocks); -+} -+ -+static void clk_register_clks(void) -+{ -+ clk_add(&jz_clk_ext.clk); -+ clk_add(&jz_clk_pll); -+ clk_add(&jz_clk_pll_half); -+ clk_add(&jz_clk_cpu.clk); -+ clk_add(&jz_clk_high_speed_peripheral.clk); -+ clk_add(&jz_clk_low_speed_peripheral.clk); -+ clk_add(&jz_clk_ko); -+ clk_add(&jz_clk_ld); -+ clk_add(&jz_clk_lp.clk); -+ clk_add(&jz_clk_cim_mclk); -+ clk_add(&jz_clk_cim_pclk.clk); -+ clk_add(&jz_clk_i2s.clk); -+ clk_add(&jz_clk_mmc.clk); -+ clk_add(&jz_clk_uhc.clk); -+ clk_add(&jz_clk_udc); -+ clk_add(&jz_clk_uart0); -+ clk_add(&jz_clk_uart1); -+ clk_add(&jz_clk_dma); -+ clk_add(&jz_clk_ipu); -+ clk_add(&jz_clk_adc); -+ clk_add(&jz_clk_i2c); -+ clk_add(&jz_clk_rtc.clk); -+} -+ -+int jz_init_clocks(unsigned long ext_rate) -+{ -+ uint32_t val; -+ -+ jz_clock_base = ioremap(0x10000000, 0x100); -+ if (!jz_clock_base) -+ return -EBUSY; -+ -+ jz_clk_ext.rate = ext_rate; -+ -+ val = jz_clk_reg_read(JZ_REG_CLOCK_SPI); -+ -+ if (val & JZ_CLOCK_SPI_SRC_PLL) -+ jz_clk_spi.clk.parent = &jz_clk_pll_half; -+ -+ val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL); -+ -+ if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL) -+ jz_clk_i2s.clk.parent = &jz_clk_pll_half; -+ -+ if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL) -+ jz_clk_udc.parent = &jz_clk_pll_half; -+ -+ clk_register_clks(); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(jz_init_clocks); -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/cpufreq.c linux-2.6.31/arch/mips/jz4740/cpufreq.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/cpufreq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/cpufreq.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,602 @@ -+/* -+ * linux/arch/mips/jz4740/cpufreq.c -+ * -+ * cpufreq driver for JZ4740 -+ * -+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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 <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+ -+#include <linux/cpufreq.h> -+ -+#include <asm/jzsoc.h> -+#include <asm/processor.h> -+ -+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ -+ "cpufreq-jz4740", msg) -+ -+#undef CHANGE_PLL -+ -+#define PLL_UNCHANGED 0 -+#define PLL_GOES_UP 1 -+#define PLL_GOES_DOWN 2 -+ -+#define PLL_WAIT_500NS (500*(__cpm_get_cclk()/1000000000)) -+ -+/* Saved the boot-time parameters */ -+static struct { -+ /* SDRAM parameters */ -+ unsigned int mclk; /* memory clock, KHz */ -+ unsigned int tras; /* RAS pulse width, cycles of mclk */ -+ unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */ -+ unsigned int tpc; /* RAS Precharge time, cycles of mclk */ -+ unsigned int trwl; /* Write Precharge Time, cycles of mclk */ -+ unsigned int trc; /* RAS Cycle Time, cycles of mclk */ -+ unsigned int rtcor; /* Refresh Time Constant */ -+ unsigned int sdram_initialized; -+ -+ /* LCD parameters */ -+ unsigned int lcd_clk; /* LCD clock, Hz */ -+ unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */ -+ unsigned int lcd_clks_initialized; -+} boot_config; -+ -+struct jz4740_freq_percpu_info { -+ struct cpufreq_frequency_table table[7]; -+}; -+ -+static struct jz4740_freq_percpu_info jz4740_freq_table; -+ -+/* -+ * This contains the registers value for an operating point. -+ * If only part of a register needs to change then there is -+ * a mask value for that register. -+ * When going to a new operating point the current register -+ * value is ANDed with the ~mask and ORed with the new value. -+ */ -+struct dpm_regs { -+ u32 cpccr; /* Clock Freq Control Register */ -+ u32 cpccr_mask; /* Clock Freq Control Register mask */ -+ u32 cppcr; /* PLL1 Control Register */ -+ u32 cppcr_mask; /* PLL1 Control Register mask */ -+ u32 pll_up_flag; /* New PLL freq is higher than current or not */ -+}; -+ -+extern jz_clocks_t jz_clocks; -+ -+static void jz_update_clocks(void) -+{ -+ /* Next clocks must be updated if we have changed -+ * the PLL or divisors. -+ */ -+ jz_clocks.cclk = __cpm_get_cclk(); -+ jz_clocks.hclk = __cpm_get_hclk(); -+ jz_clocks.mclk = __cpm_get_mclk(); -+ jz_clocks.pclk = __cpm_get_pclk(); -+ jz_clocks.lcdclk = __cpm_get_lcdclk(); -+ jz_clocks.pixclk = __cpm_get_pixclk(); -+ jz_clocks.i2sclk = __cpm_get_i2sclk(); -+ jz_clocks.usbclk = __cpm_get_usbclk(); -+ jz_clocks.mscclk = __cpm_get_mscclk(); -+} -+ -+static void -+jz_init_boot_config(void) -+{ -+ if (!boot_config.lcd_clks_initialized) { -+ /* the first time to scale pll */ -+ boot_config.lcd_clk = __cpm_get_lcdclk(); -+ boot_config.lcdpix_clk = __cpm_get_pixclk(); -+ boot_config.lcd_clks_initialized = 1; -+ } -+ -+ if (!boot_config.sdram_initialized) { -+ /* the first time to scale frequencies */ -+ unsigned int dmcr, rtcor; -+ unsigned int tras, rcd, tpc, trwl, trc; -+ -+ dmcr = REG_EMC_DMCR; -+ rtcor = REG_EMC_RTCOR; -+ -+ tras = (dmcr >> 13) & 0x7; -+ rcd = (dmcr >> 11) & 0x3; -+ tpc = (dmcr >> 8) & 0x7; -+ trwl = (dmcr >> 5) & 0x3; -+ trc = (dmcr >> 2) & 0x7; -+ -+ boot_config.mclk = __cpm_get_mclk() / 1000; -+ boot_config.tras = tras + 4; -+ boot_config.rcd = rcd + 1; -+ boot_config.tpc = tpc + 1; -+ boot_config.trwl = trwl + 1; -+ boot_config.trc = trc * 2 + 1; -+ boot_config.rtcor = rtcor; -+ -+ boot_config.sdram_initialized = 1; -+ } -+} -+ -+static void jz_update_dram_rtcor(unsigned int new_mclk) -+{ -+ unsigned int rtcor; -+ -+ new_mclk /= 1000; -+ rtcor = boot_config.rtcor * new_mclk / boot_config.mclk; -+ rtcor--; -+ -+ if (rtcor < 1) rtcor = 1; -+ if (rtcor > 255) rtcor = 255; -+ -+ REG_EMC_RTCOR = rtcor; -+ REG_EMC_RTCNT = rtcor; -+} -+ -+static void jz_update_dram_dmcr(unsigned int new_mclk) -+{ -+ unsigned int dmcr; -+ unsigned int tras, rcd, tpc, trwl, trc; -+ unsigned int valid_time, new_time; /* ns */ -+ -+ new_mclk /= 1000; -+ tras = boot_config.tras * new_mclk / boot_config.mclk; -+ rcd = boot_config.rcd * new_mclk / boot_config.mclk; -+ tpc = boot_config.tpc * new_mclk / boot_config.mclk; -+ trwl = boot_config.trwl * new_mclk / boot_config.mclk; -+ trc = boot_config.trc * new_mclk / boot_config.mclk; -+ -+ /* Validation checking */ -+ valid_time = (boot_config.tras * 1000000) / boot_config.mclk; -+ new_time = (tras * 1000000) / new_mclk; -+ if (new_time < valid_time) tras += 1; -+ -+ valid_time = (boot_config.rcd * 1000000) / boot_config.mclk; -+ new_time = (rcd * 1000000) / new_mclk; -+ if (new_time < valid_time) rcd += 1; -+ -+ valid_time = (boot_config.tpc * 1000000) / boot_config.mclk; -+ new_time = (tpc * 1000000) / new_mclk; -+ if (new_time < valid_time) tpc += 1; -+ -+ valid_time = (boot_config.trwl * 1000000) / boot_config.mclk; -+ new_time = (trwl * 1000000) / new_mclk; -+ if (new_time < valid_time) trwl += 1; -+ -+ valid_time = (boot_config.trc * 1000000) / boot_config.mclk; -+ new_time = (trc * 1000000) / new_mclk; -+ if (new_time < valid_time) trc += 2; -+ -+ tras = (tras < 4) ? 4: tras; -+ tras = (tras > 11) ? 11: tras; -+ tras -= 4; -+ -+ rcd = (rcd < 1) ? 1: rcd; -+ rcd = (rcd > 4) ? 4: rcd; -+ rcd -= 1; -+ -+ tpc = (tpc < 1) ? 1: tpc; -+ tpc = (tpc > 8) ? 8: tpc; -+ tpc -= 1; -+ -+ trwl = (trwl < 1) ? 1: trwl; -+ trwl = (trwl > 4) ? 4: trwl; -+ trwl -= 1; -+ -+ trc = (trc < 1) ? 1: trc; -+ trc = (trc > 15) ? 15: trc; -+ trc /= 2; -+ -+ dmcr = REG_EMC_DMCR; -+ -+ dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK); -+ dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT)); -+ -+ REG_EMC_DMCR = dmcr; -+} -+ -+static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk) -+{ -+ /* No risk, no fun: run with interrupts on! */ -+ if (new_mclk > cur_mclk) { -+ /* We're going FASTER, so first update TRAS, RCD, TPC, TRWL -+ * and TRC of DMCR before changing the frequency. -+ */ -+ jz_update_dram_dmcr(new_mclk); -+ } else { -+ /* We're going SLOWER: first update RTCOR value -+ * before changing the frequency. -+ */ -+ jz_update_dram_rtcor(new_mclk); -+ } -+} -+ -+static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk) -+{ -+ /* No risk, no fun: run with interrupts on! */ -+ if (new_mclk > cur_mclk) { -+ /* We're going FASTER, so update RTCOR -+ * after changing the frequency -+ */ -+ jz_update_dram_rtcor(new_mclk); -+ } else { -+ /* We're going SLOWER: so update TRAS, RCD, TPC, TRWL -+ * and TRC of DMCR after changing the frequency. -+ */ -+ jz_update_dram_dmcr(new_mclk); -+ } -+} -+ -+static void jz_scale_divisors(struct dpm_regs *regs) -+{ -+ unsigned int cpccr; -+ unsigned int cur_mclk, new_mclk; -+ int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ unsigned int tmp = 0, wait = PLL_WAIT_500NS; -+ -+ cpccr = REG_CPM_CPCCR; -+ cpccr &= ~((unsigned long)regs->cpccr_mask); -+ cpccr |= regs->cpccr; -+ cpccr |= CPM_CPCCR_CE; /* update immediately */ -+ -+ cur_mclk = __cpm_get_mclk(); -+ new_mclk = __cpm_get_pllout() / div[(cpccr & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; -+ -+ /* Update some DRAM parameters before changing frequency */ -+ jz_update_dram_prev(cur_mclk, new_mclk); -+ -+ /* update register to change the clocks. -+ * align this code to a cache line. -+ */ -+ __asm__ __volatile__( -+ ".set noreorder\n\t" -+ ".align 5\n" -+ "sw %1,0(%0)\n\t" -+ "li %3,0\n\t" -+ "1:\n\t" -+ "bne %3,%2,1b\n\t" -+ "addi %3, 1\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ ".set reorder\n\t" -+ : -+ : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); -+ -+ /* Update some other DRAM parameters after changing frequency */ -+ jz_update_dram_post(cur_mclk, new_mclk); -+} -+ -+#ifdef CHANGE_PLL -+/* Maintain the LCD clock and pixel clock */ -+static void jz_scale_lcd_divisors(struct dpm_regs *regs) -+{ -+ unsigned int new_pll, new_lcd_div, new_lcdpix_div; -+ unsigned int cpccr; -+ unsigned int tmp = 0, wait = PLL_WAIT_500NS; -+ -+ if (!boot_config.lcd_clks_initialized) return; -+ -+ new_pll = __cpm_get_pllout(); -+ new_lcd_div = new_pll / boot_config.lcd_clk; -+ new_lcdpix_div = new_pll / boot_config.lcdpix_clk; -+ -+ if (new_lcd_div < 1) -+ new_lcd_div = 1; -+ if (new_lcd_div > 16) -+ new_lcd_div = 16; -+ -+ if (new_lcdpix_div < 1) -+ new_lcdpix_div = 1; -+ if (new_lcdpix_div > 512) -+ new_lcdpix_div = 512; -+ -+// REG_CPM_CPCCR2 = new_lcdpix_div - 1; -+ -+ cpccr = REG_CPM_CPCCR; -+ cpccr &= ~CPM_CPCCR_LDIV_MASK; -+ cpccr |= ((new_lcd_div - 1) << CPM_CPCCR_LDIV_BIT); -+ cpccr |= CPM_CPCCR_CE; /* update immediately */ -+ -+ /* update register to change the clocks. -+ * align this code to a cache line. -+ */ -+ __asm__ __volatile__( -+ ".set noreorder\n\t" -+ ".align 5\n" -+ "sw %1,0(%0)\n\t" -+ "li %3,0\n\t" -+ "1:\n\t" -+ "bne %3,%2,1b\n\t" -+ "addi %3, 1\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ ".set reorder\n\t" -+ : -+ : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); -+} -+ -+static void jz_scale_pll(struct dpm_regs *regs) -+{ -+ unsigned int cppcr; -+ unsigned int cur_mclk, new_mclk, new_pll; -+ int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ int od[] = {1, 2, 2, 4}; -+ -+ cppcr = REG_CPM_CPPCR; -+ cppcr &= ~(regs->cppcr_mask | CPM_CPPCR_PLLS | CPM_CPPCR_PLLEN | CPM_CPPCR_PLLST_MASK); -+ regs->cppcr &= ~CPM_CPPCR_PLLEN; -+ cppcr |= (regs->cppcr | 0xff); -+ -+ /* Update some DRAM parameters before changing frequency */ -+ new_pll = JZ_EXTAL * ((cppcr>>23)+2) / ((((cppcr>>18)&0x1f)+2) * od[(cppcr>>16)&0x03]); -+ cur_mclk = __cpm_get_mclk(); -+ new_mclk = new_pll / div[(REG_CPM_CPCCR>>CPM_CPCCR_MDIV_BIT) & 0xf]; -+ -+ /* -+ * Update some SDRAM parameters -+ */ -+ jz_update_dram_prev(cur_mclk, new_mclk); -+ -+ /* -+ * Update PLL, align code to cache line. -+ */ -+ cppcr |= CPM_CPPCR_PLLEN; -+ __asm__ __volatile__( -+ ".set noreorder\n\t" -+ ".align 5\n" -+ "sw %1,0(%0)\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ ".set reorder\n\t" -+ : -+ : "r" (CPM_CPPCR), "r" (cppcr)); -+ -+ /* Update some other DRAM parameters after changing frequency */ -+ jz_update_dram_post(cur_mclk, new_mclk); -+} -+#endif -+ -+static void jz4740_transition(struct dpm_regs *regs) -+{ -+ /* -+ * Get and save some boot-time conditions. -+ */ -+ jz_init_boot_config(); -+ -+#ifdef CHANGE_PLL -+ /* -+ * Disable LCD before scaling pll. -+ * LCD and LCD pixel clocks should not be changed even if the PLL -+ * output frequency has been changed. -+ */ -+ REG_LCD_CTRL &= ~LCD_CTRL_ENA; -+ -+ /* -+ * Stop module clocks before scaling PLL -+ */ -+ __cpm_stop_eth(); -+ __cpm_stop_aic(1); -+ __cpm_stop_aic(2); -+#endif -+ -+ /* ... add more as necessary */ -+ -+ if (regs->pll_up_flag == PLL_GOES_UP) { -+ /* the pll frequency is going up, so change dividors first */ -+ jz_scale_divisors(regs); -+#ifdef CHANGE_PLL -+ jz_scale_pll(regs); -+#endif -+ } -+ else if (regs->pll_up_flag == PLL_GOES_DOWN) { -+ /* the pll frequency is going down, so change pll first */ -+#ifdef CHANGE_PLL -+ jz_scale_pll(regs); -+#endif -+ jz_scale_divisors(regs); -+ } -+ else { -+ /* the pll frequency is unchanged, so change divisors only */ -+ jz_scale_divisors(regs); -+ } -+ -+#ifdef CHANGE_PLL -+ /* -+ * Restart module clocks before scaling PLL -+ */ -+ __cpm_start_eth(); -+ __cpm_start_aic(1); -+ __cpm_start_aic(2); -+ -+ /* ... add more as necessary */ -+ -+ /* Scale the LCD divisors after scaling pll */ -+ if (regs->pll_up_flag != PLL_UNCHANGED) { -+ jz_scale_lcd_divisors(regs); -+ } -+ -+ /* Enable LCD controller */ -+ REG_LCD_CTRL &= ~LCD_CTRL_DIS; -+ REG_LCD_CTRL |= LCD_CTRL_ENA; -+#endif -+ -+ /* Update system clocks */ -+ jz_update_clocks(); -+} -+ -+extern unsigned int idle_times; -+static unsigned int jz4740_freq_get(unsigned int cpu) -+{ -+ return (__cpm_get_cclk() / 1000); -+} -+ -+static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs) -+{ -+ int n2FR[33] = { -+ 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, -+ 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, -+ 9 -+ }; -+ int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */ -+ unsigned int div_of_cclk, new_freq, i; -+ -+ regs->pll_up_flag = PLL_UNCHANGED; -+ regs->cpccr_mask = CPM_CPCCR_CDIV_MASK | CPM_CPCCR_HDIV_MASK | CPM_CPCCR_PDIV_MASK | CPM_CPCCR_MDIV_MASK; -+ -+ new_freq = jz4740_freq_table.table[index].frequency; -+ -+ do { -+ div_of_cclk = __cpm_get_pllout() / (1000 * new_freq); -+ } while (div_of_cclk==0); -+ -+ if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) { -+ for(i = 1; i<4; i++) { -+ div[i] = 3; -+ } -+ } else { -+ for(i = 1; i<4; i++) { -+ div[i] = 2; -+ } -+ } -+ -+ for(i = 0; i<4; i++) { -+ div[i] *= div_of_cclk; -+ } -+ -+ dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]); -+ -+ regs->cpccr = -+ (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | -+ (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | -+ (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | -+ (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT); -+ -+ return div_of_cclk; -+} -+ -+static void jz4740_set_cpu_divider_index(unsigned int cpu, unsigned int index) -+{ -+ unsigned long divisor, old_divisor; -+ struct cpufreq_freqs freqs; -+ struct dpm_regs regs; -+ -+ old_divisor = __cpm_get_pllout() / __cpm_get_cclk(); -+ divisor = index_to_divisor(index, ®s); -+ -+ freqs.old = __cpm_get_cclk() / 1000; -+ freqs.new = __cpm_get_pllout() / (1000 * divisor); -+ freqs.cpu = cpu; -+ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+ if (old_divisor != divisor) -+ jz4740_transition(®s); -+ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+} -+ -+static int jz4740_freq_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ unsigned int new_index = 0; -+ -+ if (cpufreq_frequency_table_target(policy, -+ &jz4740_freq_table.table[0], -+ target_freq, relation, &new_index)) -+ return -EINVAL; -+ -+ jz4740_set_cpu_divider_index(policy->cpu, new_index); -+ -+ dprintk("new frequency is %d KHz (REG_CPM_CPCCR:0x%x)\n", __cpm_get_cclk() / 1000, REG_CPM_CPCCR); -+ -+ return 0; -+} -+ -+static int jz4740_freq_verify(struct cpufreq_policy *policy) -+{ -+ return cpufreq_frequency_table_verify(policy, -+ &jz4740_freq_table.table[0]); -+} -+ -+static int __init jz4740_cpufreq_driver_init(struct cpufreq_policy *policy) -+{ -+ -+ struct cpufreq_frequency_table *table = &jz4740_freq_table.table[0]; -+ unsigned int MAX_FREQ; -+ -+ dprintk(KERN_INFO "Jz4740 cpufreq driver\n"); -+ -+ if (policy->cpu != 0) -+ return -EINVAL; -+ -+ policy->cur = MAX_FREQ = __cpm_get_cclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */ -+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; -+ -+ policy->cpuinfo.min_freq = MAX_FREQ/8; -+ policy->cpuinfo.max_freq = MAX_FREQ; -+ policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */ -+ -+ table[0].index = 0; -+ table[0].frequency = MAX_FREQ/8; -+ table[1].index = 1; -+ table[1].frequency = MAX_FREQ/6; -+ table[2].index = 2; -+ table[2].frequency = MAX_FREQ/4; -+ table[3].index = 3; -+ table[3].frequency = MAX_FREQ/3; -+ table[4].index = 4; -+ table[4].frequency = MAX_FREQ/2; -+ table[5].index = 5; -+ table[5].frequency = MAX_FREQ; -+ table[6].index = 6; -+ table[6].frequency = CPUFREQ_TABLE_END; -+ -+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS -+ cpufreq_frequency_table_get_attr(table, policy->cpu); /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */ -+#endif -+ -+ return cpufreq_frequency_table_cpuinfo(policy, table); -+} -+ -+static struct cpufreq_driver cpufreq_jz4740_driver = { -+// .flags = CPUFREQ_STICKY, -+ .init = jz4740_cpufreq_driver_init, -+ .verify = jz4740_freq_verify, -+ .target = jz4740_freq_target, -+ .get = jz4740_freq_get, -+ .name = "jz4740", -+}; -+ -+static int __init jz4740_cpufreq_init(void) -+{ -+ return cpufreq_register_driver(&cpufreq_jz4740_driver); -+} -+ -+static void __exit jz4740_cpufreq_exit(void) -+{ -+ cpufreq_unregister_driver(&cpufreq_jz4740_driver); -+} -+ -+module_init(jz4740_cpufreq_init); -+module_exit(jz4740_cpufreq_exit); -+ -+MODULE_AUTHOR("Regen <lhhuang@ingenic.cn>"); -+MODULE_DESCRIPTION("cpufreq driver for Jz4740"); -+MODULE_LICENSE("GPL"); -+ -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/dma.c linux-2.6.31/arch/mips/jz4740/dma.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/dma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/dma.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,922 @@ -+/* -+ * linux/arch/mips/jz4740/dma.c -+ * -+ * Support functions for the JZ4740 internal DMA channels. -+ * No-descriptor transfer only. -+ * Descriptor transfer should also call jz_request_dma() to get a free -+ * channel and call jz_free_dma() to free the channel. And driver should -+ * build the DMA descriptor and setup the DMA channel by itself. -+ * -+ * Copyright (C) 2006 Ingenic Semiconductor 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/errno.h> -+#include <linux/sched.h> -+#include <linux/spinlock.h> -+#include <linux/string.h> -+#include <linux/delay.h> -+#include <linux/interrupt.h> -+#include <linux/soundcard.h> -+ -+#include <asm/system.h> -+#include <asm/addrspace.h> -+#include <asm/jzsoc.h> -+ -+#define JZ_REG_DMA_SRC_ADDR(x) ((x) * 0x20 + 0x00) -+#define JZ_REG_DMA_DEST_ADDR(x) ((x) * 0x20 + 0x04) -+#define JZ_REG_DMA_COUNT(x) ((x) * 0x20 + 0x08) -+#define JZ_REG_DMA_TYPE(x) ((x) * 0x20 + 0x0c) -+#define JZ_REG_DMA_STATUS(x) ((x) * 0x20 + 0x10) -+#define JZ_REG_DMA_CMD(x) ((x) * 0x20 + 0x14) -+#define JZ_REG_DMA_DESC_ADDR(x) ((x) * 0x20 + 0x18) -+#define JZ_REG_DMA_CTRL 0x300 -+#define JZ_REG_DMA_IRQ 0x304 -+#define JZ_REG_DMA_DOORBELL 0x308 -+#define JZ_REG_DMA_DOORBELL_SET 0x30C -+ -+#define JZ_DMA_STATUS_NO_DESC BIT(31) -+#define JZ_DMA_STATUS_CDOA_MASK (0xff << 16) -+#define JZ_DMA_STATUS_INV_DESC BIT(6) -+#define JZ_DMA_STATUS_ADDR_ERROR BIT(4) -+#define JZ_DMA_STATUS_TERMINATE_TRANSFER BIT(3) -+#define JZ_DMA_STATUS_HALT BIT(2) -+#define JZ_DMA_STATUS_CT BIT(1) -+#define JZ_DMA_STATUS_ENABLE BIT(0) -+ -+#define JZ_DMA_CMD_SAI BIT(23) -+#define JZ_DMA_CMD_DAI BIT(22) -+#define JZ_DMA_CMD_RDIL_MASK (0xf << 16) -+#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14) -+#define JZ_DMA_CMD_DEST_WIDTH_MASK (0x3 << 12) -+#define JZ_DMA_CMD_TRANSFER_SIZE_MASK (0x7 << 8) -+#define JZ_DMA_CMD_BLOCK_MODE BIT(7) -+#define JZ_DMA_CMD_VALID BIT(4) -+#define JZ_DMA_CMD_VALID_MODE BIT(3) -+#define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2) -+#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1) -+#define JZ_DMA_CMD_LINK BIT(0) -+ -+ -+static void __iomem *jz_dma_base; -+static spinlock_t jz_dma_lock; -+ -+static inline uint32_t jz_dma_read(size_t reg) -+{ -+ return readl(jz_dma_base + reg); -+} -+ -+static inline void jz_dma_write(size_t reg, uint32_t val) -+{ -+ writel(val, jz_dma_base + reg); -+} -+ -+ -+ -+/* -+ * A note on resource allocation: -+ * -+ * All drivers needing DMA channels, should allocate and release them -+ * through the public routines `jz_request_dma()' and `jz_free_dma()'. -+ * -+ * In order to avoid problems, all processes should allocate resources in -+ * the same sequence and release them in the reverse order. -+ * -+ * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. -+ * When releasing them, first release the IRQ, then release the DMA. The -+ * main reason for this order is that, if you are requesting the DMA buffer -+ * done interrupt, you won't know the irq number until the DMA channel is -+ * returned from jz_request_dma(). -+ */ -+ -+struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = { -+ {dev_id:-1,}, -+ {dev_id:-1,}, -+ {dev_id:-1,}, -+ {dev_id:-1,}, -+ {dev_id:-1,}, -+ {dev_id:-1,}, -+}; -+ -+// Device FIFO addresses and default DMA modes -+static const struct { -+ unsigned int fifo_addr; -+ unsigned int dma_mode; -+ unsigned int dma_source; -+} dma_dev_table[DMA_ID_MAX] = { -+ {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT}, -+ {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN}, -+ {CPHYSADDR(SSI_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSIOUT}, -+ {CPHYSADDR(SSI_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSIIN}, -+ {CPHYSADDR(AIC_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT}, -+ {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN}, -+ {CPHYSADDR(MSC_TXFIFO), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSCOUT}, -+ {CPHYSADDR(MSC_RXFIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSCIN}, -+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU}, -+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO}, -+ {}, -+}; -+ -+ -+int jz_dma_read_proc(char *buf, char **start, off_t fpos, -+ int length, int *eof, void *data) -+{ -+ int i, len = 0; -+ struct jz_dma_chan *chan; -+ -+ for (i = 0; i < MAX_DMA_NUM; i++) { -+ if ((chan = get_dma_chan(i)) != NULL) { -+ len += sprintf(buf + len, "%2d: %s\n", -+ i, chan->dev_str); -+ } -+ } -+ -+ if (fpos >= len) { -+ *start = buf; -+ *eof = 1; -+ return 0; -+ } -+ *start = buf + fpos; -+ if ((len -= fpos) > length) -+ return length; -+ *eof = 1; -+ return len; -+} -+ -+ -+void dump_jz_dma_channel(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan; -+ -+ if (dmanr > MAX_DMA_NUM) -+ return; -+ chan = &jz_dma_table[dmanr]; -+ -+ printk("DMA%d Registers:\n", dmanr); -+ printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR); -+ printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr)); -+ printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr)); -+ printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr)); -+ printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr)); -+ printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr)); -+ printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr)); -+ printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr)); -+ printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR); -+} -+ -+ -+/** -+ * jz_request_dma - dynamically allcate an idle DMA channel to return -+ * @dev_id: the specified dma device id or DMA_ID_RAW_SET -+ * @dev_str: the specified dma device string name -+ * @irqhandler: the irq handler, or NULL -+ * @irqflags: the irq handler flags -+ * @irq_dev_id: the irq handler device id for shared irq -+ * -+ * Finds a free channel, and binds the requested device to it. -+ * Returns the allocated channel number, or negative on error. -+ * Requests the DMA done IRQ if irqhandler != NULL. -+ * -+*/ -+/*int jz_request_dma(int dev_id, const char *dev_str, -+ void (*irqhandler)(int, void *, struct pt_regs *), -+ unsigned long irqflags, -+ void *irq_dev_id) -+*/ -+ -+int jz_request_dma(int dev_id, const char *dev_str, -+ irqreturn_t (*irqhandler)(int, void *), -+ unsigned long irqflags, -+ void *irq_dev_id) -+{ -+ struct jz_dma_chan *chan; -+ int i, ret; -+ -+ if (dev_id < 0 || dev_id >= DMA_ID_MAX) -+ return -EINVAL; -+ -+ for (i = 0; i < MAX_DMA_NUM; i++) { -+ if (jz_dma_table[i].dev_id < 0) -+ break; -+ } -+ if (i == MAX_DMA_NUM) /* no free channel */ -+ return -ENODEV; -+ -+ /* we got a free channel */ -+ chan = &jz_dma_table[i]; -+ -+ if (irqhandler) { -+ chan->irq = JZ_IRQ_DMA(i); // allocate irq number -+ chan->irq_dev = irq_dev_id; -+ if ((ret = request_irq(chan->irq, irqhandler, irqflags, -+ dev_str, chan->irq_dev))) { -+ chan->irq = -1; -+ chan->irq_dev = NULL; -+ return ret; -+ } -+ } else { -+ chan->irq = -1; -+ chan->irq_dev = NULL; -+ } -+ -+ // fill it in -+ chan->io = i; -+ chan->dev_id = dev_id; -+ chan->dev_str = dev_str; -+ chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; -+ chan->mode = dma_dev_table[dev_id].dma_mode; -+ chan->source = dma_dev_table[dev_id].dma_source; -+ -+ return i; -+} -+ -+void jz_free_dma(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) { -+ printk("Trying to free DMA%d\n", dmanr); -+ return; -+ } -+ -+ disable_dma(dmanr); -+ if (chan->irq) -+ free_irq(chan->irq, chan->irq_dev); -+ -+ chan->irq = -1; -+ chan->irq_dev = NULL; -+ chan->dev_id = -1; -+} -+ -+void jz_set_dma_dest_width(int dmanr, int nbit) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ chan->mode &= ~DMAC_DCMD_DWDH_MASK; -+ switch (nbit) { -+ case 8: -+ chan->mode |= DMAC_DCMD_DWDH_8; -+ break; -+ case 16: -+ chan->mode |= DMAC_DCMD_DWDH_16; -+ break; -+ case 32: -+ chan->mode |= DMAC_DCMD_DWDH_32; -+ break; -+ } -+} -+ -+void jz_set_dma_src_width(int dmanr, int nbit) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ chan->mode &= ~DMAC_DCMD_SWDH_MASK; -+ switch (nbit) { -+ case 8: -+ chan->mode |= DMAC_DCMD_SWDH_8; -+ break; -+ case 16: -+ chan->mode |= DMAC_DCMD_SWDH_16; -+ break; -+ case 32: -+ chan->mode |= DMAC_DCMD_SWDH_32; -+ break; -+ } -+} -+ -+void jz_set_dma_block_size(int dmanr, int nbyte) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ chan->mode &= ~DMAC_DCMD_DS_MASK; -+ switch (nbyte) { -+ case 1: -+ chan->mode |= DMAC_DCMD_DS_8BIT; -+ break; -+ case 2: -+ chan->mode |= DMAC_DCMD_DS_16BIT; -+ break; -+ case 4: -+ chan->mode |= DMAC_DCMD_DS_32BIT; -+ break; -+ case 16: -+ chan->mode |= DMAC_DCMD_DS_16BYTE; -+ break; -+ case 32: -+ chan->mode |= DMAC_DCMD_DS_32BYTE; -+ break; -+ } -+} -+ -+unsigned int jz_get_dma_command(int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ return chan->mode; -+} -+ -+/** -+ * jz_set_dma_mode - do the raw settings for the specified DMA channel -+ * @dmanr: the specified DMA channel -+ * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE -+ * @dma_mode: dma raw mode -+ * @dma_source: dma raw request source -+ * @fifo_addr: dma raw device fifo address -+ * -+ * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call -+ * jz_set_dma_mode() rather than set_dma_mode() if you work with -+ * and external request dma device. -+ * -+ * NOTE: Don not dynamically allocate dma channel if one external request -+ * dma device will occupy this channel. -+*/ -+int jz_set_dma_mode(unsigned int dmanr, unsigned int mode, -+ unsigned int dma_mode, unsigned int dma_source, -+ unsigned int fifo_addr) -+{ -+ int dev_id, i; -+ struct jz_dma_chan *chan; -+ -+ if (dmanr > MAX_DMA_NUM) -+ return -ENODEV; -+ -+ for (i = 0; i < MAX_DMA_NUM; i++) { -+ if (jz_dma_table[i].dev_id < 0) -+ break; -+ } -+ if (i == MAX_DMA_NUM) -+ return -ENODEV; -+ -+ chan = &jz_dma_table[dmanr]; -+ dev_id = chan->dev_id; -+ if (dev_id > 0) { -+ printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n", -+ __FUNCTION__, dmanr); -+ return -ENODEV; -+ } -+ -+ /* clone it from the dynamically allocated. */ -+ if (i != dmanr) { -+ chan->irq = jz_dma_table[i].irq; -+ chan->irq_dev = jz_dma_table[i].irq_dev; -+ chan->dev_str = jz_dma_table[i].dev_str; -+ jz_dma_table[i].irq = 0; -+ jz_dma_table[i].irq_dev = NULL; -+ jz_dma_table[i].dev_id = -1; -+ } -+ chan->dev_id = DMA_ID_RAW_SET; -+ chan->io = dmanr; -+ chan->fifo_addr = fifo_addr; -+ chan->mode = dma_mode; -+ chan->source = dma_source; -+ -+ set_dma_mode(dmanr, dma_mode); -+ -+ return dmanr; -+} -+ -+void enable_dma(unsigned int dmanr) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); -+ REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */ -+ __dmac_enable_channel(dmanr); -+ if (chan->irq) -+ __dmac_channel_enable_irq(dmanr); -+} -+ -+#define DMA_DISABLE_POLL 0x10000 -+ -+void disable_dma(unsigned int dmanr) -+{ -+ int i; -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ if (!__dmac_channel_enabled(dmanr)) -+ return; -+ -+ for (i = 0; i < DMA_DISABLE_POLL; i++) -+ if (__dmac_channel_transmit_end_detected(dmanr)) -+ break; -+#if 0 -+ if (i == DMA_DISABLE_POLL) -+ printk(KERN_INFO "disable_dma: poll expired!\n"); -+#endif -+ -+ __dmac_disable_channel(dmanr); -+ if (chan->irq) -+ __dmac_channel_disable_irq(dmanr); -+} -+ -+/* Note: DMA_MODE_MASK is simulated by sw */ -+void set_dma_mode(unsigned int dmanr, unsigned int mode) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); -+ mode &= DMA_MODE_MASK; -+ if (mode == DMA_MODE_READ) { -+ chan->mode |= DMAC_DCMD_DAI; -+ chan->mode &= ~DMAC_DCMD_SAI; -+ } else if (mode == DMA_MODE_WRITE) { -+ chan->mode |= DMAC_DCMD_SAI; -+ chan->mode &= ~DMAC_DCMD_DAI; -+ } else { -+ printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); -+ } -+ jz_dma_write(JZ_REG_DMA_CMD(chan->io), chan->mode & ~DMA_MODE_MASK); -+ jz_dma_write(JZ_REG_DMA_TYPE(chan->io), chan->source); -+} -+ -+void set_dma_addr(unsigned int dmanr, unsigned int phyaddr) -+{ -+ unsigned int mode; -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ mode = chan->mode & DMA_MODE_MASK; -+ if (mode == DMA_MODE_READ) { -+ jz_dma_write(JZ_REG_DMA_SRC_ADDR(chan->io), chan->fifo_addr); -+ jz_dma_write(JZ_REG_DMA_DEST_ADDR(chan->io), phyaddr); -+ } else if (mode == DMA_MODE_WRITE) { -+ jz_dma_write(JZ_REG_DMA_SRC_ADDR(chan->io), phyaddr); -+ jz_dma_write(JZ_REG_DMA_DEST_ADDR(chan->io), chan->fifo_addr); -+ } else -+ printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n"); -+} -+ -+void set_dma_count(unsigned int dmanr, unsigned int bytecnt) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ int dma_ds[] = {4, 1, 2, 16, 32}; -+ unsigned int ds; -+ -+ if (!chan) -+ return; -+ -+ ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; -+ -+ jz_dma_write(JZ_REG_DMA_COUNT(chan->io), bytecnt / dma_ds[ds]); -+} -+ -+unsigned int get_dma_residue(unsigned int dmanr) -+{ -+ unsigned int count, ds; -+ int dma_ds[] = {4, 1, 2, 16, 32}; -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ if (!chan) -+ return 0; -+ -+ ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; -+ count = jz_dma_read(JZ_REG_DMA_COUNT(chan->io)); -+ count = count * dma_ds[ds]; -+ -+ return count; -+} -+ -+void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ switch (audio_fmt) { -+ case AFMT_U8: -+ /* burst mode : 32BIT */ -+ break; -+ case AFMT_S16_LE: -+ /* burst mode : 16BYTE */ -+ if (mode == DMA_MODE_READ) { -+ chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ; -+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); -+ mode &= DMA_MODE_MASK; -+ chan->mode |= DMAC_DCMD_DAI; -+ chan->mode &= ~DMAC_DCMD_SAI; -+ } else if (mode == DMA_MODE_WRITE) { -+ chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE; -+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); -+ mode &= DMA_MODE_MASK; -+ chan->mode |= DMAC_DCMD_SAI; -+ chan->mode &= ~DMAC_DCMD_DAI; -+ } else -+ printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); -+ -+ jz_dma_write(JZ_REG_DMA_CMD(chan->io), chan->mode & ~DMA_MODE_MASK); -+ jz_dma_write(JZ_REG_DMA_TYPE(chan->io), chan->source); -+ break; -+ } -+} -+ -+void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) -+{ -+ struct jz_dma_chan *chan = get_dma_chan(dmanr); -+ -+ if (!chan) -+ return; -+ -+ switch (audio_fmt) { -+ case 8: -+ /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ -+ break; -+ case 16: -+ /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ -+ if (mode == DMA_MODE_READ) { -+ chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ; -+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); -+ mode &= DMA_MODE_MASK; -+ chan->mode |= DMAC_DCMD_DAI; -+ chan->mode &= ~DMAC_DCMD_SAI; -+ } else if (mode == DMA_MODE_WRITE) { -+ chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; -+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); -+ mode &= DMA_MODE_MASK; -+ chan->mode |= DMAC_DCMD_SAI; -+ chan->mode &= ~DMAC_DCMD_DAI; -+ } else { -+ printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); -+ } -+ -+ jz_dma_write(JZ_REG_DMA_CMD(chan->io), chan->mode & ~DMA_MODE_MASK); -+ jz_dma_write(JZ_REG_DMA_TYPE(chan->io), chan->source); -+ -+ break; -+ } -+} -+ -+#undef JZ4740_DMAC_TEST_ENABLE -+ -+#ifdef JZ4740_DMAC_TEST_ENABLE -+ -+/* -+ * DMA test: external address <--> external address -+ */ -+#define TEST_DMA_SIZE 16*1024 -+ -+static jz_dma_desc *dma_desc; -+ -+static int dma_chan; -+static dma_addr_t dma_desc_phys_addr; -+static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr; -+ -+static int dma_check_result(void *src, void *dst, int size) -+{ -+ unsigned int addr1, addr2, i, err = 0; -+ -+ addr1 = (unsigned int)src; -+ addr2 = (unsigned int)dst; -+ -+ for (i = 0; i < size; i += 4) { -+ if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) { -+ err++; -+ printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2); -+ } -+ addr1 += 4; -+ addr2 += 4; -+ } -+ printk("check DMA result err=%d\n", err); -+ return err; -+} -+ -+static void jz4740_dma_irq(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ printk("jz4740_dma_irq %d\n", irq); -+ -+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ -+ -+ if (__dmac_channel_transmit_halt_detected(dma_chan)) { -+ printk("DMA HALT\n"); -+ __dmac_channel_clear_transmit_halt(dma_chan); -+ } -+ -+ if (__dmac_channel_address_error_detected(dma_chan)) { -+ printk("DMA ADDR ERROR\n"); -+ __dmac_channel_clear_address_error(dma_chan); -+ } -+ -+ if (__dmac_channel_descriptor_invalid_detected(dma_chan)) { -+ printk("DMA DESC INVALID\n"); -+ __dmac_channel_clear_descriptor_invalid(dma_chan); -+ } -+ -+ if (__dmac_channel_count_terminated_detected(dma_chan)) { -+ printk("DMA CT\n"); -+ __dmac_channel_clear_count_terminated(dma_chan); -+ } -+ -+ if (__dmac_channel_transmit_end_detected(dma_chan)) { -+ printk("DMA TT\n"); -+ __dmac_channel_clear_transmit_end(dma_chan); -+ dump_jz_dma_channel(dma_chan); -+ dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE); -+ } -+ -+ /* free buffers */ -+ printk("free DMA buffers\n"); -+ free_pages(dma_src_addr, 2); -+ free_pages(dma_dst_addr, 2); -+ -+ if (dma_desc) -+ free_pages((unsigned int)dma_desc, 0); -+ -+ /* free dma */ -+ jz_free_dma(dma_chan); -+} -+ -+void dma_nodesc_test(void) -+{ -+ unsigned int addr, i; -+ -+ printk("dma_nodesc_test\n"); -+ -+ /* Request DMA channel and setup irq handler */ -+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4740_dma_irq, -+ SA_INTERRUPT, NULL); -+ if (dma_chan < 0) { -+ printk("Setup irq failed\n"); -+ return; -+ } -+ -+ printk("Requested DMA channel = %d\n", dma_chan); -+ -+ /* Allocate DMA buffers */ -+ dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ -+ dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ -+ -+ dma_src_phys_addr = CPHYSADDR(dma_src_addr); -+ dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); -+ -+ printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); -+ -+ /* Prepare data for source buffer */ -+ addr = (unsigned int)dma_src_addr; -+ for (i = 0; i < TEST_DMA_SIZE; i += 4) { -+ *(volatile unsigned int *)addr = addr; -+ addr += 4; -+ } -+ dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); -+ -+ /* Init target buffer */ -+ memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); -+ dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); -+ -+ /* Init DMA module */ -+ printk("Starting DMA\n"); -+ REG_DMAC_DMACR = 0; -+ REG_DMAC_DCCSR(dma_chan) = 0; -+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; -+ REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; -+ REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; -+ REG_DMAC_DTCR(dma_chan) = 512; -+ REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE; -+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; -+ REG_DMAC_DMACR = DMAC_DMACR_DMAE; /* global DMA enable bit */ -+ -+ printk("DMA started. IMR=%08x\n", REG_INTC_IMR); -+} -+ -+void dma_desc_test(void) -+{ -+ unsigned int next, addr, i; -+ static jz_dma_desc *desc; -+ -+ printk("dma_desc_test\n"); -+ -+ /* Request DMA channel and setup irq handler */ -+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4740_dma_irq, -+ SA_INTERRUPT, NULL); -+ if (dma_chan < 0) { -+ printk("Setup irq failed\n"); -+ return; -+ } -+ -+ printk("Requested DMA channel = %d\n", dma_chan); -+ -+ /* Allocate DMA buffers */ -+ dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ -+ dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ -+ -+ dma_src_phys_addr = CPHYSADDR(dma_src_addr); -+ dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); -+ -+ printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); -+ -+ /* Prepare data for source buffer */ -+ addr = (unsigned int)dma_src_addr; -+ for (i = 0; i < TEST_DMA_SIZE; i += 4) { -+ *(volatile unsigned int *)addr = addr; -+ addr += 4; -+ } -+ dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); -+ -+ /* Init target buffer */ -+ memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); -+ dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); -+ -+ /* Allocate DMA descriptors */ -+ dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0); -+ dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc); -+ -+ printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr); -+ -+ /* Setup DMA descriptors */ -+ desc = dma_desc; -+ next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4; -+ -+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TM | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; -+ desc->dsadr = dma_src_phys_addr; /* DMA source address */ -+ desc->dtadr = dma_dst_phys_addr; /* DMA target address */ -+ desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */ -+ -+ desc++; -+ next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4; -+ -+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; -+ desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */ -+ desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */ -+ desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ -+ -+ desc++; -+ next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4; -+ -+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; -+ desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */ -+ desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */ -+ desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ -+ -+ desc++; -+ next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4; -+ -+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE; -+ desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */ -+ desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */ -+ desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */ -+ -+ dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc))); -+ -+ /* Setup DMA descriptor address */ -+ REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr; -+ -+ /* Setup request source */ -+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; -+ -+ /* Setup DMA channel control/status register */ -+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */ -+ -+ /* Enable DMA */ -+ REG_DMAC_DMACR = DMAC_DMACR_DMAE; -+ -+ /* DMA doorbell set -- start DMA now ... */ -+ REG_DMAC_DMADBSR = 1 << dma_chan; -+ -+ printk("DMA started. IMR=%08x\n", REG_INTC_IMR); -+} -+ -+#endif -+ -+static void jz_dma_irq_demux_handler(unsigned int irq, struct irq_desc *desc) -+{ -+ int i; -+ uint32_t pending; -+ -+ pending = jz_dma_read(JZ_REG_DMA_IRQ); -+ -+ for (i = 0; i < 6; ++i) { -+ if (pending & BIT(i)) -+ generic_handle_irq(JZ_IRQ_DMA(i)); -+ } -+} -+ -+#define IRQ_TO_DMA(irq) ((irq) - JZ_IRQ_DMA(0)) -+ -+static void dma_irq_unmask(unsigned int irq) -+{ -+ unsigned long flags; -+ uint32_t mask; -+ unsigned int chan; -+ -+ chan = IRQ_TO_DMA(irq); -+ -+ spin_lock_irqsave(&jz_dma_lock, flags); -+ -+ mask = jz_dma_read(JZ_REG_DMA_CMD(chan)); -+ mask |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE; -+ jz_dma_write(JZ_REG_DMA_CMD(chan), mask); -+ -+ spin_unlock_irqrestore(&jz_dma_lock, flags); -+} -+ -+static void dma_irq_mask(unsigned int irq) -+{ -+ unsigned long flags; -+ uint32_t mask; -+ unsigned int chan; -+ -+ chan = IRQ_TO_DMA(irq); -+ -+ spin_lock_irqsave(&jz_dma_lock, flags); -+ -+ mask = jz_dma_read(JZ_REG_DMA_CMD(chan)); -+ mask &= ~JZ_DMA_CMD_TRANSFER_IRQ_ENABLE; -+ jz_dma_write(JZ_REG_DMA_CMD(chan), mask); -+ -+ spin_unlock_irqrestore(&jz_dma_lock, flags); -+} -+ -+static void dma_irq_ack(unsigned int irq) -+{ -+ unsigned long flags; -+ uint32_t pending; -+ -+ spin_lock_irqsave(&jz_dma_lock, flags); -+ -+ pending = jz_dma_read(JZ_REG_DMA_IRQ); -+ pending &= ~BIT(irq); -+ jz_dma_write(JZ_REG_DMA_IRQ, pending); -+ -+ spin_unlock_irqrestore(&jz_dma_lock, flags); -+} -+ -+static void dma_irq_end(unsigned int irq) -+{ -+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { -+ dma_irq_unmask(irq); -+ } -+} -+ -+static struct irq_chip dma_irq_type = { -+ .name = "DMA", -+ .unmask = dma_irq_unmask, -+ .mask = dma_irq_mask, -+ .ack = dma_irq_ack, -+ .end = dma_irq_end, -+}; -+ -+static int jz_dma_init(void) -+{ -+ int i; -+ -+ jz_dma_base = ioremap(CPHYSADDR(DMAC_BASE), 0x400); -+ -+ if (!jz_dma_base) -+ return -EBUSY; -+ -+ spin_lock_init(&jz_dma_lock); -+ -+ set_irq_chained_handler(JZ_IRQ_DMAC, jz_dma_irq_demux_handler); -+ -+ for (i = 0; i < NUM_DMA; i++) { -+ dma_irq_mask(JZ_IRQ_DMA(i)); -+ set_irq_chip_and_handler(JZ_IRQ_DMA(i), &dma_irq_type, handle_level_irq); -+ } -+ -+ return 0; -+} -+arch_initcall(jz_dma_init); -+ -+//EXPORT_SYMBOL_NOVERS(jz_dma_table); -+EXPORT_SYMBOL(jz_dma_table); -+EXPORT_SYMBOL(jz_request_dma); -+EXPORT_SYMBOL(jz_free_dma); -+EXPORT_SYMBOL(jz_set_dma_src_width); -+EXPORT_SYMBOL(jz_set_dma_dest_width); -+EXPORT_SYMBOL(jz_set_dma_block_size); -+EXPORT_SYMBOL(jz_set_dma_mode); -+EXPORT_SYMBOL(set_dma_mode); -+EXPORT_SYMBOL(jz_set_oss_dma); -+EXPORT_SYMBOL(jz_set_alsa_dma); -+EXPORT_SYMBOL(set_dma_addr); -+EXPORT_SYMBOL(set_dma_count); -+EXPORT_SYMBOL(get_dma_residue); -+EXPORT_SYMBOL(enable_dma); -+EXPORT_SYMBOL(disable_dma); -+EXPORT_SYMBOL(dump_jz_dma_channel); -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/gpio.c linux-2.6.31/arch/mips/jz4740/gpio.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/gpio.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,438 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ74xx platform GPIO support -+ * -+ * 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. -+ * -+ * 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 <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/spinlock.h> -+ -+#include <linux/io.h> -+#include <linux/gpio.h> -+#include <linux/delay.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/bitops.h> -+ -+#include <asm/mach-jz4740/regs.h> -+ -+#define JZ_GPIO_BASE_A (32*0) -+#define JZ_GPIO_BASE_B (32*1) -+#define JZ_GPIO_BASE_C (32*2) -+#define JZ_GPIO_BASE_D (32*3) -+ -+#define JZ_GPIO_NUM_A 32 -+#define JZ_GPIO_NUM_B 32 -+#define JZ_GPIO_NUM_C 31 -+#define JZ_GPIO_NUM_D 32 -+ -+#define JZ_IRQ_GPIO_BASE_A JZ_IRQ_GPIO(0) + JZ_GPIO_BASE_A -+#define JZ_IRQ_GPIO_BASE_B JZ_IRQ_GPIO(0) + JZ_GPIO_BASE_B -+#define JZ_IRQ_GPIO_BASE_C JZ_IRQ_GPIO(0) + JZ_GPIO_BASE_C -+#define JZ_IRQ_GPIO_BASE_D JZ_IRQ_GPIO(0) + JZ_GPIO_BASE_D -+ -+#define JZ_IRQ_GPIO_A(num) (num < JZ_GPIO_NUM_A ? JZ_IRQ_GPIO_BASE_A + num : -EINVAL) -+#define JZ_IRQ_GPIO_B(num) (num < JZ_GPIO_NUM_B ? JZ_IRQ_GPIO_BASE_B + num : -EINVAL) -+#define JZ_IRQ_GPIO_C(num) (num < JZ_GPIO_NUM_C ? JZ_IRQ_GPIO_BASE_C + num : -EINVAL) -+#define JZ_IRQ_GPIO_D(num) (num < JZ_GPIO_NUM_D ? JZ_IRQ_GPIO_BASE_D + num : -EINVAL) -+ -+ -+#define CHIP_TO_REG(chip, reg) (jz_gpio_base + (((chip)->base) << 3) + reg) -+#define CHIP_TO_PIN_REG(chip) CHIP_TO_REG(chip, 0x00) -+#define CHIP_TO_DATA_REG(chip) CHIP_TO_REG(chip, 0x10) -+#define CHIP_TO_DATA_SET_REG(chip) CHIP_TO_REG(chip, 0x14) -+#define CHIP_TO_DATA_CLEAR_REG(chip) CHIP_TO_REG(chip, 0x18) -+#define CHIP_TO_PULL_REG(chip) CHIP_TO_REG(chip, 0x30) -+#define CHIP_TO_PULL_SET_REG(chip) CHIP_TO_REG(chip, 0x34) -+#define CHIP_TO_PULL_CLEAR_REG(chip) CHIP_TO_REG(chip, 0x38) -+#define CHIP_TO_DATA_SELECT_REG(chip) CHIP_TO_REG(chip, 0x50) -+#define CHIP_TO_DATA_SELECT_SET_REG(chip) CHIP_TO_REG(chip, 0x54) -+#define CHIP_TO_DATA_SELECT_CLEAR_REG(chip) CHIP_TO_REG(chip, 0x58) -+#define CHIP_TO_DIRECION_REG(chip) CHIP_TO_REG(chip, 0x60) -+#define CHIP_TO_DIRECTION_SET_REG(chip) CHIP_TO_REG(chip, 0x64) -+#define CHIP_TO_DIRECTION_CLEAR_REG(chip) CHIP_TO_REG(chip, 0x68) -+ -+#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f) -+ -+#define GPIO_TO_REG(gpio, reg) (jz_gpio_base + ((gpio >> 5) << 8) + reg) -+#define GPIO_TO_MASK_REG(gpio) GPIO_TO_REG(gpio, 0x20) -+#define GPIO_TO_MASK_SET_REG(gpio) GPIO_TO_REG(gpio, 0x24) -+#define GPIO_TO_MASK_CLEAR_REG(gpio) GPIO_TO_REG(gpio, 0x28) -+#define GPIO_TO_PULL_REG(gpio) GPIO_TO_REG(gpio, 0x30) -+#define GPIO_TO_PULL_SET_REG(gpio) GPIO_TO_REG(gpio, 0x34) -+#define GPIO_TO_PULL_CLEAR_REG(gpio) GPIO_TO_REG(gpio, 0x38) -+#define GPIO_TO_FUNC_REG(gpio) GPIO_TO_REG(gpio, 0x40) -+#define GPIO_TO_FUNC_SET_REG(gpio) GPIO_TO_REG(gpio, 0x44) -+#define GPIO_TO_FUNC_CLEAR_REG(gpio) GPIO_TO_REG(gpio, 0x48) -+#define GPIO_TO_SEL_REG(gpio) GPIO_TO_REG(gpio, 0x50) -+#define GPIO_TO_SEL_SET_REG(gpio) GPIO_TO_REG(gpio, 0x54) -+#define GPIO_TO_SEL_CLEAR_REG(gpio) GPIO_TO_REG(gpio, 0x58) -+#define GPIO_TO_TRIGGER_REG(gpio) GPIO_TO_REG(gpio, 0x70) -+#define GPIO_TO_TRIGGER_SET_REG(gpio) GPIO_TO_REG(gpio, 0x74) -+#define GPIO_TO_TRIGGER_CLEAR_REG(gpio) GPIO_TO_REG(gpio, 0x78) -+ -+ -+ -+static void __iomem *jz_gpio_base; -+static spinlock_t jz_gpio_lock; -+ -+struct jz_gpio_chip { -+ unsigned int irq; -+ unsigned int irq_base; -+ uint32_t wakeup; -+ uint32_t saved[4]; -+ struct gpio_chip gpio_chip; -+ struct irq_chip irq_chip; -+ uint32_t edge_trigger_both; -+}; -+ -+static struct jz_gpio_chip *jz_irq_to_chip(unsigned int irq) -+{ -+ return get_irq_chip_data(irq); -+} -+ -+int jz_gpio_set_function(int gpio, enum jz_gpio_function function) -+{ -+ if (function == JZ_GPIO_FUNC_NONE) { -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_FUNC_CLEAR_REG(gpio)); -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_SEL_CLEAR_REG(gpio)); -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_TRIGGER_CLEAR_REG(gpio)); -+ } else { -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_FUNC_SET_REG(gpio)); -+ switch (function) { -+ case JZ_GPIO_FUNC1: -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_SEL_CLEAR_REG(gpio)); -+ break; -+ case JZ_GPIO_FUNC3: -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_TRIGGER_SET_REG(gpio)); -+ case JZ_GPIO_FUNC2: /* Falltrough */ -+ writew(GPIO_TO_BIT(gpio), GPIO_TO_SEL_SET_REG(gpio)); -+ break; -+ default: -+ BUG(); -+ break; -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(jz_gpio_set_function); -+ -+int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num) -+{ -+ size_t i; -+ int ret; -+ -+ for (i = 0; i < num; ++i, ++request) { -+ ret = gpio_request(request->gpio, request->name); -+ if (ret) -+ goto err; -+ jz_gpio_set_function(request->gpio, request->function); -+ } -+ -+ return 0; -+err: -+ for (--request; i > 0; --i, --request) -+ gpio_free(request->gpio); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(jz_gpio_bulk_request); -+ -+void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num) -+{ -+ size_t i; -+ -+ for (i = 0; i < num; ++i, ++request) { -+ gpio_free(request->gpio); -+ jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE); -+ } -+ -+} -+EXPORT_SYMBOL_GPL(jz_gpio_bulk_free); -+ -+void jz_gpio_enable_pullup(unsigned gpio) -+{ -+ writel(GPIO_TO_BIT(gpio), GPIO_TO_PULL_CLEAR_REG(gpio)); -+} -+EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup); -+ -+void jz_gpio_disable_pullup(unsigned gpio) -+{ -+ writel(GPIO_TO_BIT(gpio), GPIO_TO_PULL_SET_REG(gpio)); -+} -+EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup); -+ -+static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio) -+{ -+ return !!(readl(CHIP_TO_PIN_REG(chip)) & BIT(gpio)); -+} -+ -+static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) -+{ -+ uint32_t __iomem *reg = CHIP_TO_DATA_SET_REG(chip) + ((!value) << 2); -+ writel(BIT(gpio), reg); -+} -+ -+static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) -+{ -+ writel(BIT(gpio), CHIP_TO_DIRECTION_SET_REG(chip)); -+ jz_gpio_set_value(chip, gpio, value); -+ -+ return 0; -+} -+ -+static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) -+{ -+ writel(BIT(gpio), CHIP_TO_DIRECTION_CLEAR_REG(chip)); -+ -+ return 0; -+} -+ -+ -+#define IRQ_TO_GPIO(irq) (irq - JZ_IRQ_GPIO(0)) -+#define IRQ_TO_BIT(irq) BIT(IRQ_TO_GPIO(irq) & 0x1f) -+ -+ -+#define IRQ_TO_REG(irq, reg) GPIO_TO_REG(IRQ_TO_GPIO(irq), reg) -+#define IRQ_TO_PIN_REG(irq) IRQ_TO_REG(irq, 0x00) -+#define IRQ_TO_MASK_REG(irq) IRQ_TO_REG(irq, 0x20) -+#define IRQ_TO_MASK_SET_REG(irq) IRQ_TO_REG(irq, 0x24) -+#define IRQ_TO_MASK_CLEAR_REG(irq) IRQ_TO_REG(irq, 0x28) -+#define IRQ_TO_SELECT_REG(irq) IRQ_TO_REG(irq, 0x50) -+#define IRQ_TO_SELECT_SET_REG(irq) IRQ_TO_REG(irq, 0x54) -+#define IRQ_TO_SELECT_CLEAR_REG(irq) IRQ_TO_REG(irq, 0x58) -+#define IRQ_TO_DIRECTION_REG(irq) IRQ_TO_REG(irq, 0x60) -+#define IRQ_TO_DIRECTION_SET_REG(irq) IRQ_TO_REG(irq, 0x64) -+#define IRQ_TO_DIRECTION_CLEAR_REG(irq) IRQ_TO_REG(irq, 0x68) -+#define IRQ_TO_TRIGGER_REG(irq) IRQ_TO_REG(irq, 0x70) -+#define IRQ_TO_TRIGGER_SET_REG(irq) IRQ_TO_REG(irq, 0x74) -+#define IRQ_TO_TRIGGER_CLEAR_REG(irq) IRQ_TO_REG(irq, 0x78) -+#define IRQ_TO_FLAG_REG(irq) IRQ_TO_REG(irq, 0x80) -+#define IRQ_TO_FLAG_CLEAR_REG(irq) IRQ_TO_REG(irq, 0x14) -+ -+ -+static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) -+{ -+ uint32_t flag; -+ unsigned int gpio_irq; -+ unsigned int gpio_bank; -+ struct jz_gpio_chip *chip = get_irq_desc_data(desc); -+ -+ gpio_bank = JZ_IRQ_GPIO0 - irq; -+ -+ flag = readl(jz_gpio_base + (gpio_bank << 8) + 0x80); -+ -+ gpio_irq = ffs(flag) - 1; -+ -+ if (chip->edge_trigger_both & BIT(gpio_irq)) { -+ uint32_t value = readl(CHIP_TO_PIN_REG(&chip->gpio_chip)); -+ if (value & BIT(gpio_irq)) { -+ writel(BIT(gpio_irq), -+ CHIP_TO_DIRECTION_CLEAR_REG(&chip->gpio_chip)); -+ } else { -+ writel(BIT(gpio_irq), -+ CHIP_TO_DIRECTION_SET_REG(&chip->gpio_chip)); -+ } -+ } -+ -+ -+ gpio_irq += (gpio_bank << 5) + JZ_IRQ_GPIO(0); -+ -+ -+ generic_handle_irq(gpio_irq); -+}; -+ -+/* TODO: Check if function is gpio */ -+static unsigned int jz_gpio_irq_startup(unsigned int irq) -+{ -+ writel(IRQ_TO_BIT(irq), IRQ_TO_SELECT_SET_REG(irq)); -+ spin_lock(&jz_gpio_lock); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_MASK_CLEAR_REG(irq)); -+ spin_unlock(&jz_gpio_lock); -+ return 0; -+} -+ -+static void jz_gpio_irq_shutdown(unsigned int irq) -+{ -+ spin_lock(&jz_gpio_lock); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_MASK_SET_REG(irq)); -+ spin_unlock(&jz_gpio_lock); -+ /* Set direction to input */ -+ writel(IRQ_TO_BIT(irq), IRQ_TO_DIRECTION_CLEAR_REG(irq)); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_SELECT_CLEAR_REG(irq)); -+} -+ -+static void jz_gpio_irq_mask(unsigned int irq) -+{ -+ writel(IRQ_TO_BIT(irq), IRQ_TO_MASK_SET_REG(irq)); -+}; -+ -+static void jz_gpio_irq_unmask(unsigned int irq) -+{ -+ writel(IRQ_TO_BIT(irq), IRQ_TO_MASK_CLEAR_REG(irq)); -+}; -+ -+static void jz_gpio_irq_ack(unsigned int irq) -+{ -+ writel(IRQ_TO_BIT(irq), IRQ_TO_FLAG_CLEAR_REG(irq)); -+}; -+ -+static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) -+{ -+ uint32_t mask; -+ struct jz_gpio_chip *chip = jz_irq_to_chip(irq); -+ spin_lock(&jz_gpio_lock); -+ -+ mask = readl(IRQ_TO_MASK_REG(irq)); -+ -+ writel(IRQ_TO_BIT(irq), IRQ_TO_MASK_CLEAR_REG(irq)); -+ if (flow_type == IRQ_TYPE_EDGE_BOTH) { -+ uint32_t value = readl(IRQ_TO_PIN_REG(irq)); -+ if (value & IRQ_TO_BIT(irq)) -+ flow_type = IRQ_TYPE_EDGE_FALLING; -+ else -+ flow_type = IRQ_TYPE_EDGE_RISING; -+ chip->edge_trigger_both |= IRQ_TO_BIT(irq); -+ } else { -+ chip->edge_trigger_both &= ~IRQ_TO_BIT(irq); -+ } -+ -+ switch(flow_type) { -+ case IRQ_TYPE_EDGE_RISING: -+ writel(IRQ_TO_BIT(irq), IRQ_TO_DIRECTION_SET_REG(irq)); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_TRIGGER_SET_REG(irq)); -+ break; -+ case IRQ_TYPE_EDGE_FALLING: -+ writel(IRQ_TO_BIT(irq), IRQ_TO_DIRECTION_CLEAR_REG(irq)); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_TRIGGER_SET_REG(irq)); -+ break; -+ case IRQ_TYPE_LEVEL_HIGH: -+ writel(IRQ_TO_BIT(irq), IRQ_TO_DIRECTION_SET_REG(irq)); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_TRIGGER_CLEAR_REG(irq)); -+ break; -+ case IRQ_TYPE_LEVEL_LOW: -+ writel(IRQ_TO_BIT(irq), IRQ_TO_DIRECTION_CLEAR_REG(irq)); -+ writel(IRQ_TO_BIT(irq), IRQ_TO_TRIGGER_CLEAR_REG(irq)); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ writel(mask, IRQ_TO_MASK_SET_REG(irq)); -+ -+ spin_unlock(&jz_gpio_lock); -+ -+ return 0; -+} -+ -+static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on) -+{ -+ struct jz_gpio_chip *chip = jz_irq_to_chip(irq); -+ if (on) { -+ chip->wakeup |= IRQ_TO_BIT(irq); -+ } else { -+ chip->wakeup &= ~IRQ_TO_BIT(irq); -+ } -+ set_irq_wake(chip->irq, on); -+ return 0; -+} -+ -+int gpio_to_irq(unsigned gpio) -+{ -+ return JZ_IRQ_GPIO(0) + gpio; -+} -+EXPORT_SYMBOL_GPL(gpio_to_irq); -+ -+int irq_to_gpio(unsigned gpio) -+{ -+ return IRQ_TO_GPIO(gpio); -+} -+EXPORT_SYMBOL_GPL(irq_to_gpio); -+ -+#define JZ_GPIO_CHIP(_bank) { \ -+ .irq_base = JZ_IRQ_GPIO_BASE_ ## _bank, \ -+ .gpio_chip = { \ -+ .label = "Bank " # _bank, \ -+ .owner = THIS_MODULE, \ -+ .set = jz_gpio_set_value, \ -+ .get = jz_gpio_get_value, \ -+ .direction_output = jz_gpio_direction_output, \ -+ .direction_input = jz_gpio_direction_input, \ -+ .base = JZ_GPIO_BASE_ ## _bank, \ -+ .ngpio = JZ_GPIO_NUM_ ## _bank, \ -+ }, \ -+ .irq_chip = { \ -+ .name = "GPIO Bank " # _bank, \ -+ .mask = jz_gpio_irq_mask, \ -+ .unmask = jz_gpio_irq_unmask, \ -+ .ack = jz_gpio_irq_ack, \ -+ .startup = jz_gpio_irq_startup, \ -+ .shutdown = jz_gpio_irq_shutdown, \ -+ .set_type = jz_gpio_irq_set_type, \ -+ .set_wake = jz_gpio_irq_set_wake, \ -+ }, \ -+} -+ -+static struct jz_gpio_chip jz_gpio_chips[] = { -+ JZ_GPIO_CHIP(A), -+ JZ_GPIO_CHIP(B), -+ JZ_GPIO_CHIP(C), -+ JZ_GPIO_CHIP(D), -+}; -+ -+int __init jz_gpiolib_init(void) -+{ -+ struct jz_gpio_chip *chip = jz_gpio_chips; -+ int i, irq; -+ -+ jz_gpio_base = ioremap(0x10010000, 0x400); -+ -+ for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) { -+ gpiochip_add(&chip->gpio_chip); -+ chip->irq = JZ_IRQ_INTC_GPIO(i); -+ set_irq_data(chip->irq, chip); -+ set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler); -+ for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; -+ ++irq) { -+ set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq); -+ set_irq_chip_data(irq, chip); -+ } -+ } -+ -+ printk("JZ GPIO initalized\n"); -+ -+ return 0; -+} -+ -+void jz_gpiolib_suspend(void) -+{ -+ struct jz_gpio_chip *chip = jz_gpio_chips; -+ int i, gpio; -+ for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) { -+ gpio = chip->gpio_chip.base; -+ chip->saved[0] = readl(GPIO_TO_MASK_REG(gpio)); -+ writel(~(chip->wakeup), GPIO_TO_MASK_SET_REG(gpio)); -+ } -+} -+ -+/* TODO: Use sysdev */ -+void jz_gpiolib_resume(void) -+{ -+ struct jz_gpio_chip *chip = jz_gpio_chips; -+ int i, gpio; -+ for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) { -+ writel(~(chip->saved[0]), GPIO_TO_MASK_CLEAR_REG(chip->gpio_chip.base)); -+ } -+} -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/irq.c linux-2.6.31/arch/mips/jz4740/irq.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/irq.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,148 @@ -+/* -+ * linux/arch/mips/jz4740/irq.c -+ * -+ * JZ4740 interrupt routines. -+ * -+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. -+ * Author: <lhhuang@ingenic.cn> -+ * -+ * 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. -+ */ -+#include <linux/errno.h> -+#include <linux/init.h> -+#include <linux/irq.h> -+#include <linux/kernel_stat.h> -+#include <linux/module.h> -+#include <linux/signal.h> -+#include <linux/sched.h> -+#include <linux/types.h> -+#include <linux/interrupt.h> -+#include <linux/ioport.h> -+#include <linux/timex.h> -+#include <linux/slab.h> -+#include <linux/random.h> -+#include <linux/delay.h> -+#include <linux/bitops.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/io.h> -+#include <asm/mipsregs.h> -+#include <asm/system.h> -+#include <asm/jzsoc.h> -+#include <asm/mach-generic/irq.h> -+#include <asm/irq_cpu.h> -+ -+static void __iomem *jz_intc_base; -+static uint32_t jz_intc_wakeup; -+static uint32_t jz_intc_saved; -+ -+#define JZ_REG_BASE_INTC 0x10001000 -+ -+#define JZ_REG_INTC_STATUS 0x00 -+#define JZ_REG_INTC_MASK 0x04 -+#define JZ_REG_INTC_SET_MASK 0x08 -+#define JZ_REG_INTC_CLEAR_MASK 0x0c -+#define JZ_REG_INTC_PENDING 0x10 -+ -+#define IRQ_BIT(x) BIT((x) - JZ_IRQ_BASE) -+ -+static void intc_irq_unmask(unsigned int irq) -+{ -+ writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); -+} -+ -+static void intc_irq_mask(unsigned int irq) -+{ -+ writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK); -+} -+ -+static void intc_irq_ack(unsigned int irq) -+{ -+ writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_PENDING); -+} -+ -+static void intc_irq_end(unsigned int irq) -+{ -+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { -+ intc_irq_unmask(irq); -+ } -+} -+ -+static int intc_irq_set_wake(unsigned int irq, unsigned int on) -+{ -+ if (on) -+ jz_intc_wakeup |= IRQ_BIT(irq); -+ else -+ jz_intc_wakeup &= ~IRQ_BIT(irq); -+ -+ return 0; -+} -+ -+static struct irq_chip intc_irq_type = { -+ .name = "INTC", -+ .mask = intc_irq_mask, -+ .unmask = intc_irq_unmask, -+ .ack = intc_irq_ack, -+ .end = intc_irq_end, -+ .set_wake = intc_irq_set_wake, -+}; -+ -+static irqreturn_t jz4740_cascade(int irq, void *data) -+{ -+ uint32_t irq_reg; -+ irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING); -+ -+ if (irq_reg) { -+ generic_handle_irq(ffs(irq_reg) - 1 + JZ_IRQ_BASE); -+ return IRQ_HANDLED; -+ } -+ -+ return 0; -+} -+ -+static struct irqaction jz4740_cascade_action = { -+ .handler = jz4740_cascade, -+ .name = "JZ4740 cascade interrupt" -+}; -+ -+void __init arch_init_irq(void) -+{ -+ int i; -+ mips_cpu_irq_init(); -+ -+ jz_intc_base = ioremap(JZ_REG_BASE_INTC, 0x14); -+ -+ for (i = JZ_IRQ_BASE; i < JZ_IRQ_BASE + 32; i++) { -+ intc_irq_mask(i); -+ set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); -+ } -+ -+ setup_irq(2, &jz4740_cascade_action); -+} -+ -+asmlinkage void plat_irq_dispatch(void) -+{ -+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; -+ if (pending & STATUSF_IP2) -+ jz4740_cascade(2, NULL); -+ else if(pending & STATUSF_IP3) -+ do_IRQ(3); -+ else -+ spurious_interrupt(); -+} -+ -+/* TODO: Use sysdev */ -+void jz4740_intc_suspend(void) -+{ -+ jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK); -+ printk("intc wakeup: %d\n", jz_intc_wakeup); -+ writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK); -+} -+ -+void jz4740_intc_resume(void) -+{ -+ writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK); -+} -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/platform.c linux-2.6.31/arch/mips/jz4740/platform.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/platform.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/platform.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,240 @@ -+/* -+ * Platform device support for Jz4740 SoC. -+ * -+ * Copyright 2007, <yliu@ingenic.cn> -+ * -+ * 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 <linux/device.h> -+#include <linux/platform_device.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/resource.h> -+ -+#include <asm/mach-jz4740/platform.h> -+#include <asm/jzsoc.h> -+ -+/* OHCI (USB full speed host controller) */ -+static struct resource jz4740_usb_ohci_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(UHC_BASE), -+ .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = JZ_IRQ_UHC, -+ .end = JZ_IRQ_UHC, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+/* The dmamask must be set for OHCI to work */ -+static u64 ohci_dmamask = ~(u32)0; -+ -+struct platform_device jz4740_usb_ohci_device = { -+ .name = "jz-ohci", -+ .id = 0, -+ .dev = { -+ .dma_mask = &ohci_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources), -+ .resource = jz4740_usb_ohci_resources, -+}; -+ -+/* UDC (USB gadget controller) */ -+static struct resource jz4740_usb_gdt_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(UDC_BASE), -+ .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = JZ_IRQ_UDC, -+ .end = JZ_IRQ_UDC, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 jz4740_udc_dmamask = ~(u32)0; -+ -+struct platform_device jz4740_usb_gdt_device = { -+ .name = "jz-udc", -+ .id = -1, -+ .dev = { -+ .dma_mask = &jz4740_udc_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(jz4740_usb_gdt_resources), -+ .resource = jz4740_usb_gdt_resources, -+}; -+ -+/** MMC/SD controller **/ -+static struct resource jz4740_mmc_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(MSC_BASE), -+ .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = JZ_IRQ_MSC, -+ .end = JZ_IRQ_MSC, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static u64 jz4740_mmc_dmamask = ~(u32)0; -+ -+struct platform_device jz4740_mmc_device = { -+ .name = "jz-mmc", -+ .id = 0, -+ .dev = { -+ .dma_mask = &jz4740_mmc_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(jz4740_mmc_resources), -+ .resource = jz4740_mmc_resources, -+}; -+ -+static struct resource jz4740_rtc_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(RTC_BASE), -+ .end = CPHYSADDR(RTC_BASE) + 0x10, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = JZ_IRQ_RTC, -+ .end = JZ_IRQ_RTC, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+struct platform_device jz4740_rtc_device = { -+ .name = "jz4740-rtc", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(jz4740_rtc_resources), -+ .resource = jz4740_rtc_resources, -+}; -+ -+/** I2C controller **/ -+static struct resource jz4740_i2c_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(I2C_BASE), -+ .end = CPHYSADDR(I2C_BASE) + 0x10000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = JZ_IRQ_I2C, -+ .end = JZ_IRQ_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static u64 jz4740_i2c_dmamask = ~(u32)0; -+ -+struct platform_device jz4740_i2c_device = { -+ .name = "jz_i2c", -+ .id = 0, -+ .dev = { -+ .dma_mask = &jz4740_i2c_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(jz4740_i2c_resources), -+ .resource = jz4740_i2c_resources, -+}; -+ -+static struct resource jz4740_nand_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(EMC_BASE), -+ .end = CPHYSADDR(EMC_BASE) + 0x10000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+struct platform_device jz4740_nand_device = { -+ .name = "jz4740-nand", -+ .num_resources = ARRAY_SIZE(jz4740_nand_resources), -+ .resource = jz4740_nand_resources, -+}; -+ -+static struct resource jz4740_framebuffer_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(LCD_BASE), -+ .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static u64 jz4740_fb_dmamask = ~(u32)0; -+ -+struct platform_device jz4740_framebuffer_device = { -+ .name = "jz4740-fb", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources), -+ .resource = jz4740_framebuffer_resources, -+ .dev = { -+ .dma_mask = &jz4740_fb_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+}; -+ -+static struct resource jz4740_i2s_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(AIC_BASE), -+ .end = CPHYSADDR(AIC_BASE) + 0x38 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+struct platform_device jz4740_i2s_device = { -+ .name = "jz4740-i2s", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(jz4740_i2s_resources), -+ .resource = jz4740_i2s_resources, -+}; -+ -+static struct resource jz4740_codec_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(AIC_BASE) + 0x80, -+ .end = CPHYSADDR(AIC_BASE) + 0x88 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+struct platform_device jz4740_codec_device = { -+ .name = "jz4740-codec", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(jz4740_codec_resources), -+ .resource = jz4740_codec_resources, -+}; -+ -+static struct resource jz4740_adc_resources[] = { -+ [0] = { -+ .start = CPHYSADDR(SADC_BASE), -+ .end = CPHYSADDR(SADC_BASE) + 0x30, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = JZ_IRQ_SADC, -+ .end = JZ_IRQ_SADC, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+struct platform_device jz4740_adc_device = { -+ .name = "jz4740-adc", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(jz4740_adc_resources), -+ .resource = jz4740_adc_resources, -+}; -+ -+struct platform_device jz4740_battery_device = { -+ .name = "jz4740-battery", -+ .id = -1, -+ .dev = { -+ .parent = &jz4740_adc_device.dev -+ }, -+}; -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/pm.c linux-2.6.31/arch/mips/jz4740/pm.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/pm.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,97 @@ -+/* -+ * linux/arch/mips/jz4740/common/pm.c -+ * -+ * JZ4740 Power Management Routines -+ * -+ * Copyright (C) 2006 Ingenic Semiconductor Inc. -+ * Author: <jlwei@ingenic.cn> -+ * -+ * This program is free software; you can distribute 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 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 <linux/init.h> -+#include <linux/pm.h> -+#include <linux/sysctl.h> -+#include <linux/suspend.h> -+#include <asm/jzsoc.h> -+ -+extern void jz4740_intc_suspend(void); -+extern void jz4740_intc_resume(void); -+extern void jz_gpiolib_suspend(void); -+extern void jz_gpiolib_resume(void); -+ -+static int jz_pm_enter(suspend_state_t state) -+{ -+ unsigned long delta; -+ unsigned long nfcsr = REG_EMC_NFCSR; -+ uint32_t scr = REG_CPM_SCR; -+ uint32_t sleep_gpio_save[7*3]; -+ -+ /* Preserve current time */ -+ delta = xtime.tv_sec - REG_RTC_RSR; -+ -+ /* Disable nand flash */ -+ REG_EMC_NFCSR = ~0xff; -+ -+ udelay(100); -+ -+ /*stop udc and usb*/ -+ REG_CPM_SCR &= ~( 1<<6 | 1<<7); -+ REG_CPM_SCR |= 0<<6 | 1<<7; -+ -+ jz_gpiolib_suspend(); -+ jz4740_intc_suspend(); -+ -+ /* Enter SLEEP mode */ -+ REG_CPM_LCR &= ~CPM_LCR_LPM_MASK; -+ REG_CPM_LCR |= CPM_LCR_LPM_SLEEP; -+ __asm__(".set\tmips3\n\t" -+ "wait\n\t" -+ ".set\tmips0"); -+ -+ /* Restore to IDLE mode */ -+ REG_CPM_LCR &= ~CPM_LCR_LPM_MASK; -+ REG_CPM_LCR |= CPM_LCR_LPM_IDLE; -+ -+ /* Restore nand flash control register */ -+ REG_EMC_NFCSR = nfcsr; -+ -+ jz4740_intc_resume(); -+ jz_gpiolib_resume(); -+ -+ /* Restore sleep control register */ -+ REG_CPM_SCR = scr; -+ -+ /* Restore current time */ -+ xtime.tv_sec = REG_RTC_RSR + delta; -+ -+ return 0; -+} -+ -+static struct platform_suspend_ops jz_pm_ops = { -+ .valid = suspend_valid_only_mem, -+ .enter = jz_pm_enter, -+}; -+ -+/* -+ * Initialize power interface -+ */ -+int __init jz_pm_init(void) -+{ -+ suspend_set_ops(&jz_pm_ops); -+ return 0; -+ -+} -+late_initcall(jz_pm_init); -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/proc.c linux-2.6.31/arch/mips/jz4740/proc.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/proc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/proc.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,308 @@ -+/* -+ * linux/arch/mips/jz4740/proc.c -+ * -+ * /proc/jz/ procfs for jz4740 on-chip modules. -+ * -+ * Copyright (C) 2006 Ingenic Semiconductor Inc. -+ * Author: <jlwei@ingenic.cn> -+ * -+ * This program is free software; you can distribute 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 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 <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/irq.h> -+#include <linux/sysctl.h> -+#include <linux/proc_fs.h> -+#include <linux/page-flags.h> -+#include <asm/uaccess.h> -+#include <asm/pgtable.h> -+#include <asm/jzsoc.h> -+ -+//#define DEBUG 1 -+#undef DEBUG -+ -+ -+struct proc_dir_entry *proc_jz_root; -+ -+ -+/* -+ * EMC Modules -+ */ -+static int emc_read_proc (char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int len = 0; -+ -+ len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4); -+ len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4); -+ len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR); -+ len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR); -+ len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR); -+ return len; -+} -+ -+/* -+ * Power Manager Module -+ */ -+static int pmc_read_proc (char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int len = 0; -+ unsigned long lcr = REG_CPM_LCR; -+ unsigned long clkgr = REG_CPM_CLKGR; -+ -+ len += sprintf (page+len, "Low Power Mode : %s\n", -+ ((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_IDLE)) ? -+ "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_SLEEP)) ? -+ "SLEEP" : "HIBERNATE")); -+ len += sprintf (page+len, "Doze Mode : %s\n", -+ (lcr & CPM_LCR_DOZE_ON) ? "on" : "off"); -+ if (lcr & CPM_LCR_DOZE_ON) -+ len += sprintf (page+len, " duty : %d\n", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)); -+ len += sprintf (page+len, "IPU : %s\n", -+ (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running"); -+ len += sprintf (page+len, "DMAC : %s\n", -+ (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running"); -+ len += sprintf (page+len, "UHC : %s\n", -+ (clkgr & CPM_CLKGR_UHC) ? "stopped" : "running"); -+ len += sprintf (page+len, "UDC : %s\n", -+ (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running"); -+ len += sprintf (page+len, "LCD : %s\n", -+ (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running"); -+ len += sprintf (page+len, "CIM : %s\n", -+ (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running"); -+ len += sprintf (page+len, "SADC : %s\n", -+ (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running"); -+ len += sprintf (page+len, "MSC : %s\n", -+ (clkgr & CPM_CLKGR_MSC) ? "stopped" : "running"); -+ len += sprintf (page+len, "AIC1 : %s\n", -+ (clkgr & CPM_CLKGR_AIC1) ? "stopped" : "running"); -+ len += sprintf (page+len, "AIC2 : %s\n", -+ (clkgr & CPM_CLKGR_AIC2) ? "stopped" : "running"); -+ len += sprintf (page+len, "SSI : %s\n", -+ (clkgr & CPM_CLKGR_SSI) ? "stopped" : "running"); -+ len += sprintf (page+len, "I2C : %s\n", -+ (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running"); -+ len += sprintf (page+len, "RTC : %s\n", -+ (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running"); -+ len += sprintf (page+len, "TCU : %s\n", -+ (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running"); -+ len += sprintf (page+len, "UART1 : %s\n", -+ (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running"); -+ len += sprintf (page+len, "UART0 : %s\n", -+ (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running"); -+ return len; -+} -+ -+static int pmc_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ REG_CPM_CLKGR = simple_strtoul(buffer, 0, 16); -+ return count; -+} -+ -+/* -+ * Clock Generation Module -+ */ -+#define TO_MHZ(x) (x/1000000),(x%1000000)/10000 -+#define TO_KHZ(x) (x/1000),(x%1000)/10 -+ -+static int cgm_read_proc (char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int len = 0; -+ unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */ -+ unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */ -+ unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; -+ unsigned int od[4] = {1, 2, 2, 4}; -+ -+ len += sprintf (page+len, "CPPCR : 0x%08x\n", cppcr); -+ len += sprintf (page+len, "CPCCR : 0x%08x\n", cpccr); -+ len += sprintf (page+len, "PLL : %s\n", -+ (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF"); -+ len += sprintf (page+len, "m:n:o : %d:%d:%d\n", -+ __cpm_get_pllm() + 2, -+ __cpm_get_plln() + 2, -+ od[__cpm_get_pllod()] -+ ); -+ len += sprintf (page+len, "C:H:M:P : %d:%d:%d:%d\n", -+ div[__cpm_get_cdiv()], -+ div[__cpm_get_hdiv()], -+ div[__cpm_get_mdiv()], -+ div[__cpm_get_pdiv()] -+ ); -+ len += sprintf (page+len, "PLL Freq : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pllout())); -+ len += sprintf (page+len, "CCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_cclk())); -+ len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_hclk())); -+ len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mclk())); -+ len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pclk())); -+ len += sprintf (page+len, "LCDCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_lcdclk())); -+ len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(__cpm_get_pixclk())); -+ len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_i2sclk())); -+ len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_usbclk())); -+ len += sprintf (page+len, "MSCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk())); -+ len += sprintf (page+len, "EXTALCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk())); -+ len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_rtcclk())); -+ -+ return len; -+} -+ -+static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ REG_CPM_CPCCR = simple_strtoul(buffer, 0, 16); -+ return count; -+} -+ -+ -+extern void local_flush_tlb_all(void); -+ -+/* CP0 hazard avoidance. */ -+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ -+ "nop; nop; nop; nop; nop; nop;\n\t" \ -+ ".set reorder\n\t") -+void show_tlb(void) -+{ -+#define ASID_MASK 0xFF -+ -+ unsigned long flags; -+ unsigned int old_ctx; -+ unsigned int entry; -+ unsigned int entrylo0, entrylo1, entryhi; -+ unsigned int pagemask; -+ -+ local_irq_save(flags); -+ -+ /* Save old context */ -+ old_ctx = (read_c0_entryhi() & 0xff); -+ -+ printk("TLB content:\n"); -+ entry = 0; -+ while(entry < 32) { -+ write_c0_index(entry); -+ BARRIER; -+ tlb_read(); -+ BARRIER; -+ entryhi = read_c0_entryhi(); -+ entrylo0 = read_c0_entrylo0(); -+ entrylo1 = read_c0_entrylo1(); -+ pagemask = read_c0_pagemask(); -+ printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); -+ printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); -+ printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); -+ -+ printk("\t\tpagemask=0x%08x", pagemask); -+ printk("\tentryhi=0x%08x\n", entryhi); -+ printk("\t\tentrylo0=0x%08x", entrylo0); -+ printk("\tentrylo1=0x%08x\n", entrylo1); -+ -+ entry++; -+ } -+ BARRIER; -+ write_c0_entryhi(old_ctx); -+ -+ local_irq_restore(flags); -+} -+ -+/* -+ * UDC hotplug -+ */ -+#ifdef CONFIG_JZ_UDC_HOTPLUG -+extern int jz_udc_active; /* defined in drivers/char/jzchar/jz_udc_hotplug.c */ -+#endif -+ -+#ifndef GPIO_UDC_HOTPLUG -+#define GPIO_UDC_HOTPLUG 86 -+#endif -+ -+static int udc_read_proc(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int len = 0; -+ -+ if (__gpio_get_pin(GPIO_UDC_HOTPLUG)) { -+ -+#ifdef CONFIG_JZ_UDC_HOTPLUG -+ -+ /* Cable has connected, wait for disconnection. */ -+ __gpio_as_irq_fall_edge(GPIO_UDC_HOTPLUG); -+ -+ if (jz_udc_active) -+ len += sprintf (page+len, "CONNECT_CABLE\n"); -+ else -+ len += sprintf (page+len, "CONNECT_POWER\n"); -+#else -+ len += sprintf (page+len, "CONNECT\n"); -+#endif -+ } -+ else { -+ -+#ifdef CONFIG_JZ_UDC_HOTPLUG -+ /* Cable has disconnected, wait for connection. */ -+ __gpio_as_irq_rise_edge(GPIO_UDC_HOTPLUG); -+#endif -+ -+ len += sprintf (page+len, "REMOVE\n"); -+ } -+ -+ return len; -+} -+ -+/* -+ * /proc/jz/xxx entry -+ * -+ */ -+static int __init jz_proc_init(void) -+{ -+ struct proc_dir_entry *res; -+ unsigned int virt_addr, i; -+ -+ proc_jz_root = proc_mkdir("jz", 0); -+ -+ /* External Memory Controller */ -+ res = create_proc_entry("emc", 0644, proc_jz_root); -+ if (res) { -+ res->read_proc = emc_read_proc; -+ res->write_proc = NULL; -+ res->data = NULL; -+ } -+ -+ /* Power Management Controller */ -+ res = create_proc_entry("pmc", 0644, proc_jz_root); -+ if (res) { -+ res->read_proc = pmc_read_proc; -+ res->write_proc = pmc_write_proc; -+ res->data = NULL; -+ } -+ -+ /* Clock Generation Module */ -+ res = create_proc_entry("cgm", 0644, proc_jz_root); -+ if (res) { -+ res->read_proc = cgm_read_proc; -+ res->write_proc = cgm_write_proc; -+ res->data = NULL; -+ } -+ -+ /* udc hotplug */ -+ res = create_proc_entry("udc", 0644, proc_jz_root); -+ if (res) { -+ res->read_proc = udc_read_proc; -+ res->write_proc = NULL; -+ res->data = NULL; -+ } -+ -+ return 0; -+} -+ -+__initcall(jz_proc_init); -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/prom.c linux-2.6.31/arch/mips/jz4740/prom.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/prom.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,198 @@ -+/* -+ * -+ * BRIEF MODULE DESCRIPTION -+ * PROM library initialisation code, supports YAMON and U-Boot. -+ * -+ * Copyright 2000, 2001, 2006 MontaVista Software Inc. -+ * Author: MontaVista Software, Inc. -+ * ppopov@mvista.com or source@mvista.com -+ * -+ * This file was derived from Carsten Langgaard's -+ * arch/mips/mips-boards/xx files. -+ * -+ * Carsten Langgaard, carstenl@mips.com -+ * Copyright (C) 1999,2000 MIPS Technologies, 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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 <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/string.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/jzsoc.h> -+ -+/* #define DEBUG_CMDLINE */ -+ -+int prom_argc; -+char **prom_argv, **prom_envp; -+ -+char * prom_getcmdline(void) -+{ -+ return &(arcs_cmdline[0]); -+} -+ -+void prom_init_cmdline(void) -+{ -+ char *cp; -+ int actr; -+ -+ actr = 1; /* Always ignore argv[0] */ -+ -+ cp = &(arcs_cmdline[0]); -+ while(actr < prom_argc) { -+ strcpy(cp, prom_argv[actr]); -+ cp += strlen(prom_argv[actr]); -+ *cp++ = ' '; -+ actr++; -+ } -+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ -+ --cp; -+ if (prom_argc > 1) -+ *cp = '\0'; -+ -+} -+ -+ -+char *prom_getenv(char *envname) -+{ -+#if 0 -+ /* -+ * Return a pointer to the given environment variable. -+ * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". -+ */ -+ -+ char **env = prom_envp; -+ int i = strlen(envname); -+ int yamon = (*env && strchr(*env, '=') == NULL); -+ -+ while (*env) { -+ if (yamon) { -+ if (strcmp(envname, *env++) == 0) -+ return *env; -+ } else { -+ if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') -+ return *env + i + 1; -+ } -+ env++; -+ } -+#endif -+ return NULL; -+} -+ -+inline unsigned char str2hexnum(unsigned char c) -+{ -+ if(c >= '0' && c <= '9') -+ return c - '0'; -+ if(c >= 'a' && c <= 'f') -+ return c - 'a' + 10; -+ if(c >= 'A' && c <= 'F') -+ return c - 'A' + 10; -+ return 0; /* foo */ -+} -+ -+inline void str2eaddr(unsigned char *ea, unsigned char *str) -+{ -+ int i; -+ -+ for(i = 0; i < 6; i++) { -+ unsigned char num; -+ -+ if((*str == '.') || (*str == ':')) -+ str++; -+ num = str2hexnum(*str++) << 4; -+ num |= (str2hexnum(*str++)); -+ ea[i] = num; -+ } -+} -+ -+int get_ethernet_addr(char *ethernet_addr) -+{ -+ char *ethaddr_str; -+ -+ ethaddr_str = prom_getenv("ethaddr"); -+ if (!ethaddr_str) { -+ printk("ethaddr not set in boot prom\n"); -+ return -1; -+ } -+ str2eaddr(ethernet_addr, ethaddr_str); -+ -+#if 0 -+ { -+ int i; -+ -+ printk("get_ethernet_addr: "); -+ for (i=0; i<5; i++) -+ printk("%02x:", (unsigned char)*(ethernet_addr+i)); -+ printk("%02x\n", *(ethernet_addr+i)); -+ } -+#endif -+ -+ return 0; -+} -+ -+void __init prom_free_prom_memory(void) -+{ -+} -+ -+void __init prom_init(void) -+{ -+ unsigned char *memsize_str; -+ unsigned long memsize; -+ -+ prom_argc = (int) fw_arg0; -+ prom_argv = (char **) fw_arg1; -+ prom_envp = (char **) fw_arg2; -+ -+ mips_machtype = MACH_INGENIC_JZ4740; -+ -+ prom_init_cmdline(); -+ memsize_str = prom_getenv("memsize"); -+ if (!memsize_str) { -+ memsize = 0x04000000; -+ } else { -+ memsize = simple_strtol(memsize_str, NULL, 0); -+ } -+ add_memory_region(0, memsize, BOOT_MEM_RAM); -+} -+ -+/* used by early printk */ -+void prom_putchar(char c) -+{ -+ volatile u8 *uart_lsr = (volatile u8 *)(UART0_BASE + OFF_LSR); -+ volatile u8 *uart_tdr = (volatile u8 *)(UART0_BASE + OFF_TDR); -+ -+ /* Wait for fifo to shift out some bytes */ -+ while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) ); -+ -+ *uart_tdr = (u8)c; -+} -+ -+const char *get_system_type(void) -+{ -+ return "JZ4740"; -+} -+ -+EXPORT_SYMBOL(prom_getcmdline); -+EXPORT_SYMBOL(get_ethernet_addr); -+EXPORT_SYMBOL(str2eaddr); -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/reset.c linux-2.6.31/arch/mips/jz4740/reset.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/reset.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/reset.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,48 @@ -+/* -+ * linux/arch/mips/jz4740/reset.c -+ * -+ * JZ4740 reset routines. -+ * -+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. -+ * Author: <yliu@ingenic.cn> -+ * -+ * 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 <linux/sched.h> -+#include <linux/mm.h> -+#include <asm/io.h> -+#include <asm/pgtable.h> -+#include <asm/processor.h> -+#include <asm/reboot.h> -+#include <asm/system.h> -+#include <asm/jzsoc.h> -+ -+void jz_restart(char *command) -+{ -+ printk(KERN_NOTICE "Restarting after 4 ms\n"); -+ REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN; -+ REG_WDT_TCNT = 0; -+ REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */ -+ REG_TCU_TSCR = TCU_TSSR_WDTSC; /* enable wdt clock */ -+ REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */ -+ while (1); -+} -+ -+void jz_halt(void) -+{ -+ /* Put CPU to power down mode */ -+ while (!(REG_RTC_RCR & RTC_RCR_WRDY)); -+ REG_RTC_HCR = RTC_HCR_PD; -+ -+ while (1) -+ __asm__(".set\tmips3\n\t" -+ "wait\n\t" -+ ".set\tmips0"); -+} -+ -+void jz_power_off(void) -+{ -+ jz_halt(); -+} -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/setup.c linux-2.6.31/arch/mips/jz4740/setup.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/setup.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,180 @@ -+/* -+ * linux/arch/mips/jz4740/common/setup.c -+ * -+ * JZ4740 common setup routines. -+ * -+ * Copyright (C) 2006 Ingenic Semiconductor Inc. -+ * -+ * This program is free software; you can distribute 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 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 <linux/init.h> -+#include <linux/string.h> -+#include <linux/kernel.h> -+#include <linux/io.h> -+#include <linux/irq.h> -+#include <linux/ioport.h> -+#include <linux/tty.h> -+#include <linux/serial.h> -+#include <linux/serial_core.h> -+#include <linux/serial_8250.h> -+ -+#include <asm/cpu.h> -+#include <asm/bootinfo.h> -+#include <asm/irq.h> -+#include <asm/mipsregs.h> -+#include <asm/reboot.h> -+#include <asm/pgtable.h> -+#include <asm/time.h> -+#include <asm/jzsoc.h> -+ -+#ifdef CONFIG_PM -+#include <asm/suspend.h> -+#endif -+ -+#ifdef CONFIG_PC_KEYB -+#include <asm/keyboard.h> -+#endif -+ -+jz_clocks_t jz_clocks; -+ -+extern char * __init prom_getcmdline(void); -+extern void __init jz_board_setup(void); -+extern void jz_restart(char *); -+extern void jz_halt(void); -+extern void jz_power_off(void); -+extern void jz_time_init(void); -+ -+static void __init sysclocks_setup(void) -+{ -+#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */ -+ jz_clocks.cclk = __cpm_get_cclk(); -+ jz_clocks.hclk = __cpm_get_hclk(); -+ jz_clocks.pclk = __cpm_get_pclk(); -+ jz_clocks.mclk = __cpm_get_mclk(); -+ jz_clocks.lcdclk = __cpm_get_lcdclk(); -+ jz_clocks.pixclk = __cpm_get_pixclk(); -+ jz_clocks.i2sclk = __cpm_get_i2sclk(); -+ jz_clocks.usbclk = __cpm_get_usbclk(); -+ jz_clocks.mscclk = __cpm_get_mscclk(); -+ jz_clocks.extalclk = __cpm_get_extalclk(); -+ jz_clocks.rtcclk = __cpm_get_rtcclk(); -+#else -+ -+#define FPGACLK 8000000 -+ -+ jz_clocks.cclk = FPGACLK; -+ jz_clocks.hclk = FPGACLK; -+ jz_clocks.pclk = FPGACLK; -+ jz_clocks.mclk = FPGACLK; -+ jz_clocks.lcdclk = FPGACLK; -+ jz_clocks.pixclk = FPGACLK; -+ jz_clocks.i2sclk = FPGACLK; -+ jz_clocks.usbclk = FPGACLK; -+ jz_clocks.mscclk = FPGACLK; -+ jz_clocks.extalclk = FPGACLK; -+ jz_clocks.rtcclk = FPGACLK; -+#endif -+ -+ printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n", -+ (jz_clocks.cclk + 500000) / 1000000, -+ (jz_clocks.hclk + 500000) / 1000000, -+ (jz_clocks.pclk + 500000) / 1000000, -+ (jz_clocks.mclk + 500000) / 1000000); -+} -+ -+static void __init soc_cpm_setup(void) -+{ -+ /* Enable CKO to external memory */ -+ __cpm_enable_cko(); -+ -+ /* CPU enters IDLE mode when executing 'wait' instruction */ -+ __cpm_idle_mode(); -+ -+ /* Setup system clocks */ -+ sysclocks_setup(); -+} -+ -+static void __init soc_harb_setup(void) -+{ -+// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */ -+// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */ -+// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */ -+} -+ -+static void __init soc_emc_setup(void) -+{ -+} -+ -+static void __init soc_dmac_setup(void) -+{ -+ __dmac_enable_module(); -+} -+ -+static void __init jz_soc_setup(void) -+{ -+ soc_cpm_setup(); -+ soc_harb_setup(); -+ soc_emc_setup(); -+ soc_dmac_setup(); -+} -+ -+static void __init jz_serial_setup(void) -+{ -+#ifdef CONFIG_SERIAL_8250 -+ struct uart_port s; -+ REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */ -+ memset(&s, 0, sizeof(s)); -+ s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; -+ s.iotype = SERIAL_IO_MEM; -+ s.regshift = 2; -+ s.uartclk = jz_clocks.extalclk ; -+ -+ s.line = 0; -+ s.membase = (u8 *)UART0_BASE; -+ s.irq = JZ_IRQ_UART0; -+ if (early_serial_setup(&s) != 0) { -+ printk(KERN_ERR "Serial ttyS0 setup failed!\n"); -+ } -+ -+ s.line = 1; -+ s.membase = (u8 *)UART1_BASE; -+ s.irq = JZ_IRQ_UART1; -+ if (early_serial_setup(&s) != 0) { -+ printk(KERN_ERR "Serial ttyS1 setup failed!\n"); -+ } -+#endif -+} -+ -+void __init plat_mem_setup(void) -+{ -+ char *argptr; -+ -+ argptr = prom_getcmdline(); -+ -+ /* IO/MEM resources. Which will be the addtion value in `inX' and -+ * `outX' macros defined in asm/io.h */ -+ set_io_port_base(0); -+ ioport_resource.start = 0x00000000; -+ ioport_resource.end = 0xffffffff; -+ iomem_resource.start = 0x00000000; -+ iomem_resource.end = 0xffffffff; -+ -+ _machine_restart = jz_restart; -+ _machine_halt = jz_halt; -+ pm_power_off = jz_power_off; -+ jz_soc_setup(); -+ jz_serial_setup(); -+} -+ -diff -ruN linux-2.6.31-vanilla/arch/mips/jz4740/time.c linux-2.6.31/arch/mips/jz4740/time.c ---- linux-2.6.31-vanilla/arch/mips/jz4740/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/arch/mips/jz4740/time.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,159 @@ -+/* -+ * linux/arch/mips/jz4740/time.c -+ * -+ * Setting up the clock on the JZ4740 boards. -+ * -+ * Copyright (C) 2008 Ingenic Semiconductor Inc. -+ * Author: <jlwei@ingenic.cn> -+ * -+ * This program is free software; you can distribute 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 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 <linux/types.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/clockchips.h> -+ -+#include <asm/time.h> -+#include <asm/jzsoc.h> -+ -+/* This is for machines which generate the exact clock. */ -+ -+#define JZ_TIMER_CHAN 0 -+#define JZ_TIMER_IRQ JZ_IRQ_TCU0 -+ -+#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */ -+ -+static struct clocksource clocksource_jz; /* Jz clock source */ -+static struct clock_event_device jz_clockevent_device; /* Jz clock event */ -+ -+void (*jz_timer_callback)(void); -+ -+static irqreturn_t jz_timer_interrupt(int irq, void *dev_id) -+{ -+ struct clock_event_device *cd = dev_id; -+ -+ REG_TCU_TFCR = 1 << JZ_TIMER_CHAN; /* ACK timer */ -+ -+ if (jz_timer_callback) -+ jz_timer_callback(); -+ -+ cd->event_handler(cd); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction jz_irqaction = { -+ .handler = jz_timer_interrupt, -+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, -+ .name = "jz-timerirq", -+}; -+ -+ -+cycle_t jz_get_cycles(void) -+{ -+ /* convert jiffes to jz timer cycles */ -+ return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + REG_TCU_TCNT(JZ_TIMER_CHAN)); -+} -+ -+static struct clocksource clocksource_jz = { -+ .name = "jz_clocksource", -+ .rating = 300, -+ .read = jz_get_cycles, -+ .mask = 0xFFFF, -+ .shift = 10, -+ .flags = CLOCK_SOURCE_WATCHDOG, -+}; -+ -+static int __init jz_clocksource_init(void) -+{ -+ clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift); -+ clocksource_register(&clocksource_jz); -+ return 0; -+} -+ -+static int jz_set_next_event(unsigned long evt, -+ struct clock_event_device *unused) -+{ -+ return 0; -+} -+ -+static void jz_set_mode(enum clock_event_mode mode, -+ struct clock_event_device *evt) -+{ -+ switch (mode) { -+ case CLOCK_EVT_MODE_PERIODIC: -+ break; -+ case CLOCK_EVT_MODE_ONESHOT: -+ case CLOCK_EVT_MODE_UNUSED: -+ case CLOCK_EVT_MODE_SHUTDOWN: -+ break; -+ case CLOCK_EVT_MODE_RESUME: -+ break; -+ } -+} -+ -+static struct clock_event_device jz_clockevent_device = { -+ .name = "jz-clockenvent", -+ .features = CLOCK_EVT_FEAT_PERIODIC, -+// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */ -+ -+ /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ -+ .mult = 1, -+ .rating = 300, -+ .irq = JZ_TIMER_IRQ, -+ .set_mode = jz_set_mode, -+ .set_next_event = jz_set_next_event, -+}; -+ -+static void __init jz_clockevent_init(void) -+{ -+ struct clock_event_device *cd = &jz_clockevent_device; -+ unsigned int cpu = smp_processor_id(); -+ -+ cd->cpumask = cpumask_of(cpu); -+ clockevents_register_device(cd); -+} -+ -+static void __init jz_timer_setup(void) -+{ -+ jz_clocksource_init(); /* init jz clock source */ -+ jz_clockevent_init(); /* init jz clock event */ -+ -+ /* -+ * Make irqs happen for the system timer -+ */ -+ jz_irqaction.dev_id = &jz_clockevent_device; -+ setup_irq(JZ_TIMER_IRQ, &jz_irqaction); -+} -+ -+ -+void __init plat_time_init(void) -+{ -+ unsigned int latch; -+ /* Init timer */ -+ latch = ( JZ_TIMER_CLOCK + (HZ>>1)) / HZ; -+ -+ REG_TCU_TCSR(JZ_TIMER_CHAN) = TCU_TCSR_PRESCALE16 | TCU_TCSR_EXT_EN; -+ REG_TCU_TCNT(JZ_TIMER_CHAN) = 0; -+ REG_TCU_TDHR(JZ_TIMER_CHAN) = 0; -+ REG_TCU_TDFR(JZ_TIMER_CHAN) = latch; -+ -+ REG_TCU_TMSR = (1 << (JZ_TIMER_CHAN + 16)); /* mask half irq */ -+ REG_TCU_TMCR = (1 << JZ_TIMER_CHAN); /* unmask full irq */ -+ REG_TCU_TSCR = (1 << JZ_TIMER_CHAN); /* enable timer clock */ -+ REG_TCU_TESR = (1 << JZ_TIMER_CHAN); /* start counting up */ -+ -+ jz_timer_setup(); -+} -diff -ruN linux-2.6.31-vanilla/drivers/char/defkeymap.c linux-2.6.31/drivers/char/defkeymap.c ---- linux-2.6.31-vanilla/drivers/char/defkeymap.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/char/defkeymap.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,438 @@ -+/* Do not edit this file! It was automatically generated by */ -+/* loadkeys --mktable defkeymap.map > defkeymap.c */ -+ -+#include <linux/types.h> -+#include <linux/keyboard.h> -+#include <linux/kd.h> -+ -+u_short plain_map[NR_KEYS] = { -+ 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, -+ 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, -+ 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, -+ 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, -+ 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, -+ 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, -+ 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf701, 0xf30c, -+ 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, -+ 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, -+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, -+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, -+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short shift_map[NR_KEYS] = { -+ 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, -+ 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, -+ 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, -+ 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, -+ 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, -+ 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, -+ 0xfb42, 0xfb4e, 0xfb4d, 0xf03b, 0xf03a, 0xf03f, 0xf701, 0xf30c, -+ 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, -+ 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, -+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, -+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, -+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short altgr_map[NR_KEYS] = { -+ 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, -+ 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf07e, 0xf200, 0xf200, -+ 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a, -+ 0xf028, 0xf029, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf0b0, 0xf0a8, -+ 0xf0a4, 0xf02d, 0xf05f, 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf200, -+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf039, 0xf030, 0xf916, 0xfb76, -+ 0xf915, 0xf03c, 0xf03e, 0xf027, 0xf022, 0xf200, 0xf701, 0xf30c, -+ 0xf703, 0xf200, 0xf207, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, -+ 0xf036, 0xf037, 0xf038, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911, -+ 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, -+ 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, -+ 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short ctrl_map[NR_KEYS] = { -+ 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, -+ 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200, -+ 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, -+ 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013, -+ 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, -+ 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, -+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf701, 0xf30c, -+ 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, -+ 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307, -+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, -+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a, -+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short shift_ctrl_map[NR_KEYS] = { -+ 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, -+ 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, -+ 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, -+ 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, -+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, -+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf701, 0xf30c, -+ 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, -+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, -+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short alt_map[NR_KEYS] = { -+ 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, -+ 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, -+ 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, -+ 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, -+ 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, -+ 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, -+ 0xf862, 0xf86e, 0xf86d, 0xf200, 0xf200, 0xf82f, 0xf701, 0xf30c, -+ 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, -+ 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907, -+ 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, -+ 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, -+ 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short ctrl_alt_map[NR_KEYS] = { -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, -+ 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, -+ 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, -+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, -+ 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf701, 0xf30c, -+ 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, -+ 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307, -+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, -+ 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a, -+ 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+static u_short ctr_map[NR_KEYS] = { -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf033, 0xf200, 0xf200, -+ 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xf037, 0xf038, -+ 0xf039, 0xfb70, 0xf200, 0xf200, 0xf201, 0xf702, 0xfb61, 0xfb73, -+ 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xf034, 0xf035, 0xf036, 0xf200, -+ 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, -+ 0xfb62, 0xf031, 0xf032, 0xf200, 0xf200, 0xf030, 0xf701, 0xf30c, -+ 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, -+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, -+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf30e, 0xf707, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, -+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, -+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -+}; -+ -+ushort *key_maps[MAX_NR_KEYMAPS] = { -+ plain_map, shift_map, altgr_map, 0, -+ ctrl_map, shift_ctrl_map, 0, 0, -+ alt_map, 0, 0, 0, -+ ctrl_alt_map, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ ctr_map, 0 -+}; -+ -+unsigned int keymap_count = 8; -+ -+/* -+ * Philosophy: most people do not define more strings, but they who do -+ * often want quite a lot of string space. So, we statically allocate -+ * the default and allocate dynamically in chunks of 512 bytes. -+ */ -+ -+char func_buf[] = { -+ '\033', '[', '[', 'A', 0, -+ '\033', '[', '[', 'B', 0, -+ '\033', '[', '[', 'C', 0, -+ '\033', '[', '[', 'D', 0, -+ '\033', '[', '[', 'E', 0, -+ '\033', '[', '1', '7', '~', 0, -+ '\033', '[', '1', '8', '~', 0, -+ '\033', '[', '1', '9', '~', 0, -+ '\033', '[', '2', '0', '~', 0, -+ '\033', '[', '2', '1', '~', 0, -+ '\033', '[', '2', '3', '~', 0, -+ '\033', '[', '2', '4', '~', 0, -+ '\033', '[', '2', '5', '~', 0, -+ '\033', '[', '2', '6', '~', 0, -+ '\033', '[', '2', '8', '~', 0, -+ '\033', '[', '2', '9', '~', 0, -+ '\033', '[', '3', '1', '~', 0, -+ '\033', '[', '3', '2', '~', 0, -+ '\033', '[', '3', '3', '~', 0, -+ '\033', '[', '3', '4', '~', 0, -+ '\033', '[', '1', '~', 0, -+ '\033', '[', '2', '~', 0, -+ '\033', '[', '3', '~', 0, -+ '\033', '[', '4', '~', 0, -+ '\033', '[', '5', '~', 0, -+ '\033', '[', '6', '~', 0, -+ '\033', '[', 'M', 0, -+ '\033', '[', 'P', 0, -+}; -+ -+char *funcbufptr = func_buf; -+int funcbufsize = sizeof(func_buf); -+int funcbufleft = 0; /* space left */ -+ -+char *func_table[MAX_NR_FUNC] = { -+ func_buf + 0, -+ func_buf + 5, -+ func_buf + 10, -+ func_buf + 15, -+ func_buf + 20, -+ func_buf + 25, -+ func_buf + 31, -+ func_buf + 37, -+ func_buf + 43, -+ func_buf + 49, -+ func_buf + 55, -+ func_buf + 61, -+ func_buf + 67, -+ func_buf + 73, -+ func_buf + 79, -+ func_buf + 85, -+ func_buf + 91, -+ func_buf + 97, -+ func_buf + 103, -+ func_buf + 109, -+ func_buf + 115, -+ func_buf + 120, -+ func_buf + 125, -+ func_buf + 130, -+ func_buf + 135, -+ func_buf + 140, -+ func_buf + 145, -+ 0, -+ 0, -+ func_buf + 149, -+ 0, -+}; -+ -+struct kbdiacr accent_table[MAX_DIACR] = { -+ {'`', 'A', '\300'}, {'`', 'a', '\340'}, -+ {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, -+ {'^', 'A', '\302'}, {'^', 'a', '\342'}, -+ {'~', 'A', '\303'}, {'~', 'a', '\343'}, -+ {'"', 'A', '\304'}, {'"', 'a', '\344'}, -+ {'O', 'A', '\305'}, {'o', 'a', '\345'}, -+ {'0', 'A', '\305'}, {'0', 'a', '\345'}, -+ {'A', 'A', '\305'}, {'a', 'a', '\345'}, -+ {'A', 'E', '\306'}, {'a', 'e', '\346'}, -+ {',', 'C', '\307'}, {',', 'c', '\347'}, -+ {'`', 'E', '\310'}, {'`', 'e', '\350'}, -+ {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, -+ {'^', 'E', '\312'}, {'^', 'e', '\352'}, -+ {'"', 'E', '\313'}, {'"', 'e', '\353'}, -+ {'`', 'I', '\314'}, {'`', 'i', '\354'}, -+ {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, -+ {'^', 'I', '\316'}, {'^', 'i', '\356'}, -+ {'"', 'I', '\317'}, {'"', 'i', '\357'}, -+ {'-', 'D', '\320'}, {'-', 'd', '\360'}, -+ {'~', 'N', '\321'}, {'~', 'n', '\361'}, -+ {'`', 'O', '\322'}, {'`', 'o', '\362'}, -+ {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, -+ {'^', 'O', '\324'}, {'^', 'o', '\364'}, -+ {'~', 'O', '\325'}, {'~', 'o', '\365'}, -+ {'"', 'O', '\326'}, {'"', 'o', '\366'}, -+ {'/', 'O', '\330'}, {'/', 'o', '\370'}, -+ {'`', 'U', '\331'}, {'`', 'u', '\371'}, -+ {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, -+ {'^', 'U', '\333'}, {'^', 'u', '\373'}, -+ {'"', 'U', '\334'}, {'"', 'u', '\374'}, -+ {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, -+ {'T', 'H', '\336'}, {'t', 'h', '\376'}, -+ {'s', 's', '\337'}, {'"', 'y', '\377'}, -+ {'s', 'z', '\337'}, {'i', 'j', '\377'}, -+}; -+ -+unsigned int accent_table_size = 68; -diff -ruN linux-2.6.31-vanilla/drivers/misc/jz4740-adc.c linux-2.6.31/drivers/misc/jz4740-adc.c ---- linux-2.6.31-vanilla/drivers/misc/jz4740-adc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/misc/jz4740-adc.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,362 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ4720/JZ4740 SoC ADC driver -+ * -+ * 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. -+ * -+ * 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. -+ * -+ * This driver is meant to synchronize access to the adc core for the battery -+ * and touchscreen driver. Thus these drivers should use the adc driver as a -+ * parent. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/spinlock.h> -+#include <linux/interrupt.h> -+#include <linux/jz4740-adc.h> -+ -+#define JZ_REG_ADC_ENABLE 0x00 -+#define JZ_REG_ADC_CFG 0x04 -+#define JZ_REG_ADC_CTRL 0x08 -+#define JZ_REG_ADC_STATUS 0x0C -+#define JZ_REG_ADC_SAME 0x10 -+#define JZ_REG_ADC_WAIT 0x14 -+#define JZ_REG_ADC_TOUCH 0x18 -+#define JZ_REG_ADC_BATTERY 0x1C -+#define JZ_REG_ADC_ADCIN 0x20 -+ -+#define JZ_ADC_ENABLE_TOUCH BIT(2) -+#define JZ_ADC_ENABLE_BATTERY BIT(1) -+#define JZ_ADC_ENABLE_ADCIN BIT(0) -+ -+#define JZ_ADC_CFG_SPZZ BIT(31) -+#define JZ_ADC_CFG_EX_IN BIT(30) -+#define JZ_ADC_CFG_DNUM_MASK (0x7 << 16) -+#define JZ_ADC_CFG_DMA_ENABLE BIT(15) -+#define JZ_ADC_CFG_XYZ_MASK (0x2 << 13) -+#define JZ_ADC_CFG_SAMPLE_NUM_MASK (0x7 << 10) -+#define JZ_ADC_CFG_CLKDIV (0xf << 5) -+#define JZ_ADC_CFG_BAT_MB BIT(4) -+ -+#define JZ_ADC_CFG_DNUM_OFFSET 16 -+#define JZ_ADC_CFG_XYZ_OFFSET 13 -+#define JZ_ADC_CFG_SAMPLE_NUM_OFFSET 10 -+#define JZ_ADC_CFG_CLKDIV_OFFSET 5 -+ -+#define JZ_ADC_IRQ_PENDOWN BIT(4) -+#define JZ_ADC_IRQ_PENUP BIT(3) -+#define JZ_ADC_IRQ_TOUCH BIT(2) -+#define JZ_ADC_IRQ_BATTERY BIT(1) -+#define JZ_ADC_IRQ_ADCIN BIT(0) -+ -+#define JZ_ADC_TOUCH_TYPE1 BIT(31) -+#define JZ_ADC_TOUCH_DATA1_MASK 0xfff -+#define JZ_ADC_TOUCH_TYPE0 BIT(15) -+#define JZ_ADC_TOUCH_DATA0_MASK 0xfff -+ -+#define JZ_ADC_BATTERY_MASK 0xfff -+ -+#define JZ_ADC_ADCIN_MASK 0xfff -+ -+struct jz4740_adc { -+ struct resource *mem; -+ void __iomem *base; -+ -+ int irq; -+ -+ struct completion bat_completion; -+ struct completion adc_completion; -+ -+ spinlock_t lock; -+}; -+ -+static irqreturn_t jz4740_adc_irq(int irq, void *data) -+{ -+ struct jz4740_adc *adc = data; -+ uint8_t status; -+ -+ status = readb(adc->base + JZ_REG_ADC_STATUS); -+ -+ if (status & JZ_ADC_IRQ_BATTERY) -+ complete(&adc->bat_completion); -+ if (status & JZ_ADC_IRQ_ADCIN) -+ complete(&adc->adc_completion); -+ -+ writeb(0xff, adc->base + JZ_REG_ADC_STATUS); -+ -+ return IRQ_HANDLED; -+} -+ -+static void jz4740_adc_enable_irq(struct jz4740_adc *adc, int irq) -+{ -+ unsigned long flags; -+ uint8_t val; -+ -+ spin_lock_irqsave(&adc->lock, flags); -+ -+ val = readb(adc->base + JZ_REG_ADC_CTRL); -+ val &= ~irq; -+ writeb(val, adc->base + JZ_REG_ADC_CTRL); -+ -+ spin_unlock_irqrestore(&adc->lock, flags); -+} -+ -+static void jz4740_adc_disable_irq(struct jz4740_adc *adc, int irq) -+{ -+ unsigned long flags; -+ uint8_t val; -+ -+ spin_lock_irqsave(&adc->lock, flags); -+ -+ val = readb(adc->base + JZ_REG_ADC_CTRL); -+ val |= irq; -+ writeb(val, adc->base + JZ_REG_ADC_CTRL); -+ -+ spin_unlock_irqrestore(&adc->lock, flags); -+} -+ -+static void jz4740_adc_enable_adc(struct jz4740_adc *adc, int engine) -+{ -+ unsigned long flags; -+ uint8_t val; -+ -+ spin_lock_irqsave(&adc->lock, flags); -+ -+ val = readb(adc->base + JZ_REG_ADC_ENABLE); -+ val |= engine; -+ writeb(val, adc->base + JZ_REG_ADC_ENABLE); -+ -+ spin_unlock_irqrestore(&adc->lock, flags); -+} -+ -+static void jz4740_adc_disable_adc(struct jz4740_adc *adc, int engine) -+{ -+ unsigned long flags; -+ uint8_t val; -+ -+ spin_lock_irqsave(&adc->lock, flags); -+ -+ val = readb(adc->base + JZ_REG_ADC_ENABLE); -+ val &= ~engine; -+ writeb(val, adc->base + JZ_REG_ADC_ENABLE); -+ -+ spin_unlock_irqrestore(&adc->lock, flags); -+} -+ -+static inline void jz4740_adc_set_cfg(struct jz4740_adc *adc, uint32_t mask, -+uint32_t val) -+{ -+ unsigned long flags; -+ uint32_t cfg; -+ -+ spin_lock_irqsave(&adc->lock, flags); -+ -+ cfg = readl(adc->base + JZ_REG_ADC_CFG); -+ -+ cfg &= ~mask; -+ cfg |= val; -+ -+ writel(cfg, adc->base + JZ_REG_ADC_CFG); -+ -+ spin_unlock_irqrestore(&adc->lock, flags); -+} -+ -+long jz4740_adc_read_battery_voltage(struct device *dev, -+ enum jz_adc_battery_scale scale) -+{ -+ struct jz4740_adc *adc = dev_get_drvdata(dev); -+ unsigned long t; -+ long long voltage; -+ uint16_t val; -+ -+ if (!adc) -+ return -ENODEV; -+ -+ if (scale == JZ_ADC_BATTERY_SCALE_2V5) -+ jz4740_adc_set_cfg(adc, JZ_ADC_CFG_BAT_MB, JZ_ADC_CFG_BAT_MB); -+ else -+ jz4740_adc_set_cfg(adc, JZ_ADC_CFG_BAT_MB, 0); -+ -+ jz4740_adc_enable_irq(adc, JZ_ADC_IRQ_BATTERY); -+ jz4740_adc_enable_adc(adc, JZ_ADC_ENABLE_BATTERY); -+ -+ t = wait_for_completion_interruptible_timeout(&adc->bat_completion, -+ HZ); -+ -+ jz4740_adc_disable_irq(adc, JZ_ADC_IRQ_BATTERY); -+ -+ if (t <= 0) { -+ jz4740_adc_disable_adc(adc, JZ_ADC_ENABLE_BATTERY); -+ return t ? t : -ETIMEDOUT; -+ } -+ -+ val = readw(adc->base + JZ_REG_ADC_BATTERY); -+ -+ if (scale == JZ_ADC_BATTERY_SCALE_2V5) -+ voltage = (((long long)val) * 2500000LL) >> 12LL; -+ else -+ voltage = ((((long long)val) * 7395000LL) >> 12LL) + 33000LL; -+ -+ return voltage; -+} -+EXPORT_SYMBOL_GPL(jz4740_adc_read_battery_voltage); -+ -+static ssize_t jz4740_adc_read_adcin(struct device *dev, -+ struct device_attribute *dev_attr, -+ char *buf) -+{ -+ struct jz4740_adc *adc = dev_get_drvdata(dev); -+ unsigned long t; -+ uint16_t val; -+ -+ jz4740_adc_enable_irq(adc, JZ_ADC_IRQ_ADCIN); -+ jz4740_adc_enable_adc(adc, JZ_ADC_ENABLE_ADCIN); -+ -+ t = wait_for_completion_interruptible_timeout(&adc->adc_completion, -+ HZ); -+ -+ jz4740_adc_disable_irq(adc, JZ_ADC_IRQ_ADCIN); -+ -+ if (t <= 0) { -+ jz4740_adc_disable_adc(adc, JZ_ADC_ENABLE_ADCIN); -+ return t ? t : -ETIMEDOUT; -+ } -+ -+ val = readw(adc->base + JZ_REG_ADC_ADCIN); -+ -+ return sprintf(buf, "%d\n", val); -+} -+ -+static DEVICE_ATTR(adcin, S_IRUGO, jz4740_adc_read_adcin, NULL); -+ -+static int __devinit jz4740_adc_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct jz4740_adc *adc; -+ -+ adc = kmalloc(sizeof(*adc), GFP_KERNEL); -+ -+ adc->irq = platform_get_irq(pdev, 0); -+ -+ if (adc->irq < 0) { -+ ret = adc->irq; -+ dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); -+ goto err_free; -+ } -+ -+ adc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ if (!adc->mem) { -+ ret = -ENOENT; -+ dev_err(&pdev->dev, "Failed to get platform mmio resource\n"); -+ goto err_free; -+ } -+ -+ adc->mem = request_mem_region(adc->mem->start, resource_size(adc->mem), -+ pdev->name); -+ -+ if (!adc->mem) { -+ ret = -EBUSY; -+ dev_err(&pdev->dev, "Failed to request mmio memory region\n"); -+ goto err_free; -+ } -+ -+ adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem)); -+ -+ if (!adc->base) { -+ ret = -EBUSY; -+ dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); -+ goto err_release_mem_region; -+ } -+ -+ -+ init_completion(&adc->bat_completion); -+ init_completion(&adc->adc_completion); -+ -+ spin_lock_init(&adc->lock); -+ -+ platform_set_drvdata(pdev, adc); -+ -+ ret = request_irq(adc->irq, jz4740_adc_irq, 0, pdev->name, adc); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); -+ goto err_iounmap; -+ } -+ -+ ret = device_create_file(&pdev->dev, &dev_attr_adcin); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to create sysfs file: %d\n", ret); -+ goto err_free_irq; -+ } -+ -+ writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); -+ writeb(0xff, adc->base + JZ_REG_ADC_CTRL); -+ -+ return 0; -+ -+err_free_irq: -+ free_irq(adc->irq, adc); -+err_iounmap: -+ platform_set_drvdata(pdev, NULL); -+ iounmap(adc->base); -+err_release_mem_region: -+ release_mem_region(adc->mem->start, resource_size(adc->mem)); -+err_free: -+ kfree(adc); -+ -+ return ret; -+} -+ -+static int __devexit jz4740_adc_remove(struct platform_device *pdev) -+{ -+ struct jz4740_adc *adc = platform_get_drvdata(pdev); -+ -+ device_remove_file(&pdev->dev, &dev_attr_adcin); -+ -+ free_irq(adc->irq, adc); -+ -+ iounmap(adc->base); -+ release_mem_region(adc->mem->start, resource_size(adc->mem)); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ kfree(adc); -+ -+ return 0; -+} -+ -+struct platform_driver jz4740_adc_driver = { -+ .probe = jz4740_adc_probe, -+ .remove = jz4740_adc_remove, -+ .driver = { -+ .name = "jz4740-adc", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init jz4740_adc_init(void) -+{ -+ return platform_driver_register(&jz4740_adc_driver); -+} -+module_init(jz4740_adc_init); -+ -+static void __exit jz4740_adc_exit(void) -+{ -+ platform_driver_unregister(&jz4740_adc_driver); -+} -+module_exit(jz4740_adc_exit); -+ -+MODULE_DESCRIPTION("JZ4720/JZ4740 SoC ADC driver"); -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:jz4740-adc"); -+MODULE_ALIAS("platform:jz4720-adc"); -diff -ruN linux-2.6.31-vanilla/drivers/mmc/host/jz_mmc.c linux-2.6.31/drivers/mmc/host/jz_mmc.c ---- linux-2.6.31-vanilla/drivers/mmc/host/jz_mmc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/mmc/host/jz_mmc.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,994 @@ -+/* -+ * linux/drivers/mmc/jz_mmc.c - JZ SD/MMC driver -+ * -+ * Copyright (C) 2005 - 2008 Ingenic Semiconductor 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 <linux/dma-mapping.h> -+#include <linux/mmc/host.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/ioport.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/interrupt.h> -+#include <linux/dma-mapping.h> -+#include <linux/mmc/host.h> -+#include <linux/mmc/mmc.h> -+#include <linux/mmc/sd.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mm.h> -+#include <linux/signal.h> -+#include <linux/pm.h> -+#include <linux/scatterlist.h> -+ -+#include <asm/io.h> -+#include <asm/scatterlist.h> -+#include <asm/jzsoc.h> -+ -+#include "jz_mmc.h" -+ -+#define DRIVER_NAME "jz-mmc" -+ -+#define NR_SG 1 -+ -+#if defined(CONFIG_SOC_JZ4725) || defined(CONFIG_SOC_JZ4720) -+#undef USE_DMA -+#else -+#define USE_DMA -+#endif -+ -+struct jz_mmc_host { -+ struct mmc_host *mmc; -+ spinlock_t lock; -+ struct { -+ int len; -+ int dir; -+ } dma; -+ struct { -+ int index; -+ int offset; -+ int len; -+ } pio; -+ int irq; -+ unsigned int clkrt; -+ unsigned int cmdat; -+ unsigned int imask; -+ unsigned int power_mode; -+ struct jz_mmc_platform_data *pdata; -+ struct mmc_request *mrq; -+ struct mmc_command *cmd; -+ struct mmc_data *data; -+ dma_addr_t sg_dma; -+ struct jzsoc_dma_desc *sg_cpu; -+ unsigned int dma_len; -+ unsigned int dma_dir; -+ struct pm_dev *pmdev; -+}; -+ -+static int r_type = 0; -+ -+#define MMC_IRQ_MASK() \ -+do { \ -+ REG_MSC_IMASK = 0xff; \ -+ REG_MSC_IREG = 0xff; \ -+} while (0) -+ -+static int rxdmachan = 0; -+static int txdmachan = 0; -+static int mmc_slot_enable = 0; -+ -+/* Stop the MMC clock and wait while it happens */ -+static inline int jz_mmc_stop_clock(void) -+{ -+ int timeout = 1000; -+ -+ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; -+ while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) { -+ timeout--; -+ if (timeout == 0) -+ return 0; -+ udelay(1); -+ } -+ return MMC_NO_ERROR; -+} -+ -+/* Start the MMC clock and operation */ -+static inline int jz_mmc_start_clock(void) -+{ -+ REG_MSC_STRPCL = -+ MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; -+ return MMC_NO_ERROR; -+} -+ -+static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate) -+{ -+ u32 clkrt; -+ u32 clk_src = is_sd ? 24000000 : 20000000; -+ -+ clkrt = 0; -+ while (rate < clk_src) { -+ clkrt++; -+ clk_src >>= 1; -+ } -+ return clkrt; -+} -+ -+/* Select the MMC clock frequency */ -+static int jz_mmc_set_clock(u32 rate) -+{ -+ int clkrt; -+ -+ jz_mmc_stop_clock(); -+ __cpm_select_msc_clk(1); /* select clock source from CPM */ -+ clkrt = jz_mmc_calc_clkrt(1, rate); -+ REG_MSC_CLKRT = clkrt; -+ return MMC_NO_ERROR; -+} -+ -+static void jz_mmc_enable_irq(struct jz_mmc_host *host, unsigned int mask) -+{ -+ unsigned long flags; -+ spin_lock_irqsave(&host->lock, flags); -+ host->imask &= ~mask; -+ REG_MSC_IMASK = host->imask; -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void jz_mmc_disable_irq(struct jz_mmc_host *host, unsigned int mask) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ host->imask |= mask; -+ REG_MSC_IMASK = host->imask; -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+void jz_set_dma_block_size(int dmanr, int nbyte); -+ -+#ifdef USE_DMA -+static inline void -+jz_mmc_start_dma(int chan, unsigned long phyaddr, int count, int mode) -+{ -+ unsigned long flags; -+ -+ flags = claim_dma_lock(); -+ disable_dma(chan); -+ clear_dma_ff(chan); -+ jz_set_dma_block_size(chan, 32); -+ set_dma_mode(chan, mode); -+ set_dma_addr(chan, phyaddr); -+ set_dma_count(chan, count + 31); -+ enable_dma(chan); -+ release_dma_lock(flags); -+} -+ -+static irqreturn_t jz_mmc_dma_rx_callback(int irq, void *devid) -+{ -+ int chan = rxdmachan; -+ -+ disable_dma(chan); -+ if (__dmac_channel_address_error_detected(chan)) { -+ printk(KERN_DEBUG "%s: DMAC address error.\n", -+ __FUNCTION__); -+ __dmac_channel_clear_address_error(chan); -+ } -+ if (__dmac_channel_transmit_end_detected(chan)) { -+ __dmac_channel_clear_transmit_end(chan); -+ } -+ return IRQ_HANDLED; -+} -+static irqreturn_t jz_mmc_dma_tx_callback(int irq, void *devid) -+{ -+ int chan = txdmachan; -+ -+ disable_dma(chan); -+ if (__dmac_channel_address_error_detected(chan)) { -+ printk(KERN_DEBUG "%s: DMAC address error.\n", -+ __FUNCTION__); -+ __dmac_channel_clear_address_error(chan); -+ } -+ if (__dmac_channel_transmit_end_detected(chan)) { -+ __dmac_channel_clear_transmit_end(chan); -+ } -+ return IRQ_HANDLED; -+} -+ -+/* Prepare DMA to start data transfer from the MMC card */ -+static void jz_mmc_rx_setup_data(struct jz_mmc_host *host, -+ struct mmc_data *data) -+{ -+ unsigned int nob = data->blocks; -+ int channelrx = rxdmachan; -+ int i; -+ u32 size; -+ -+ if (data->flags & MMC_DATA_STREAM) -+ nob = 0xffff; -+ -+ REG_MSC_NOB = nob; -+ REG_MSC_BLKLEN = data->blksz; -+ size = nob * data->blksz; -+ -+ if (data->flags & MMC_DATA_READ) { -+ host->dma.dir = DMA_FROM_DEVICE; -+ } else { -+ host->dma.dir = DMA_TO_DEVICE; -+ } -+ -+ host->dma.len = -+ dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, -+ host->dma.dir); -+ -+ for (i = 0; i < host->dma.len; i++) { -+ host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); -+ host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]); -+ dma_cache_wback_inv((unsigned long) -+ CKSEG0ADDR(sg_dma_address(data->sg)) + -+ data->sg->offset, -+ host->sg_cpu[i].dcmd); -+ jz_mmc_start_dma(channelrx, host->sg_cpu[i].dtadr, -+ host->sg_cpu[i].dcmd, DMA_MODE_READ); -+ } -+} -+ -+/* Prepare DMA to start data transfer from the MMC card */ -+static void jz_mmc_tx_setup_data(struct jz_mmc_host *host, -+ struct mmc_data *data) -+{ -+ unsigned int nob = data->blocks; -+ int channeltx = txdmachan; -+ int i; -+ u32 size; -+ -+ if (data->flags & MMC_DATA_STREAM) -+ nob = 0xffff; -+ -+ REG_MSC_NOB = nob; -+ REG_MSC_BLKLEN = data->blksz; -+ size = nob * data->blksz; -+ -+ if (data->flags & MMC_DATA_READ) { -+ host->dma.dir = DMA_FROM_DEVICE; -+ } else { -+ host->dma.dir = DMA_TO_DEVICE; -+ } -+ -+ host->dma.len = -+ dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, -+ host->dma.dir); -+ -+ for (i = 0; i < host->dma.len; i++) { -+ host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); -+ host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]); -+ dma_cache_wback_inv((unsigned long) -+ CKSEG0ADDR(sg_dma_address(data->sg)) + -+ data->sg->offset, -+ host->sg_cpu[i].dcmd); -+ jz_mmc_start_dma(channeltx, host->sg_cpu[i].dtadr, -+ host->sg_cpu[i].dcmd, DMA_MODE_WRITE); -+ } -+} -+#else -+static void jz_mmc_receive_pio(struct jz_mmc_host *host) -+{ -+ -+ struct mmc_data *data = 0; -+ int sg_len = 0, max = 0, count = 0; -+ u32 *buf = 0; -+ struct scatterlist *sg; -+ unsigned int nob; -+ -+ data = host->mrq->data; -+ nob = data->blocks; -+ REG_MSC_NOB = nob; -+ REG_MSC_BLKLEN = data->blksz; -+ -+ max = host->pio.len; -+ if (host->pio.index < host->dma.len) { -+ sg = &data->sg[host->pio.index]; -+ buf = sg_virt(sg) + host->pio.offset; -+ -+ /* This is the space left inside the buffer */ -+ sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; -+ /* Check to if we need less then the size of the sg_buffer */ -+ if (sg_len < max) max = sg_len; -+ } -+ max = max / 4; -+ for(count = 0; count < max; count++) { -+ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY) -+ ; -+ *buf++ = REG_MSC_RXFIFO; -+ } -+ host->pio.len -= count; -+ host->pio.offset += count; -+ -+ if (sg_len && count == sg_len) { -+ host->pio.index++; -+ host->pio.offset = 0; -+ } -+} -+ -+static void jz_mmc_send_pio(struct jz_mmc_host *host) -+{ -+ -+ struct mmc_data *data = 0; -+ int sg_len, max, count = 0; -+ u32 *wbuf = 0; -+ struct scatterlist *sg; -+ unsigned int nob; -+ -+ data = host->mrq->data; -+ nob = data->blocks; -+ -+ REG_MSC_NOB = nob; -+ REG_MSC_BLKLEN = data->blksz; -+ -+ /* This is the pointer to the data buffer */ -+ sg = &data->sg[host->pio.index]; -+ wbuf = sg_virt(sg) + host->pio.offset; -+ -+ /* This is the space left inside the buffer */ -+ sg_len = data->sg[host->pio.index].length - host->pio.offset; -+ -+ /* Check to if we need less then the size of the sg_buffer */ -+ max = (sg_len > host->pio.len) ? host->pio.len : sg_len; -+ max = max / 4; -+ for(count = 0; count < max; count++ ) { -+ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL) -+ ; -+ REG_MSC_TXFIFO = *wbuf++; -+ } -+ -+ host->pio.len -= count; -+ host->pio.offset += count; -+ -+ if (count == sg_len) { -+ host->pio.index++; -+ host->pio.offset = 0; -+ } -+} -+ -+static int -+jz_mmc_prepare_data(struct jz_mmc_host *host, struct mmc_data *data) -+{ -+ int datalen = data->blocks * data->blksz; -+ -+ host->dma.dir = DMA_BIDIRECTIONAL; -+ host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg, -+ data->sg_len, host->dma.dir); -+ if (host->dma.len == 0) -+ return -ETIMEDOUT; -+ -+ host->pio.index = 0; -+ host->pio.offset = 0; -+ host->pio.len = datalen; -+ return 0; -+} -+#endif -+ -+static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat); -+ -+static void jz_mmc_finish_request(struct jz_mmc_host *host, struct mmc_request *mrq) -+{ -+ jz_mmc_stop_clock(); -+ host->mrq = NULL; -+ host->cmd = NULL; -+ host->data = NULL; -+ mmc_request_done(host->mmc, mrq); -+} -+ -+static void jz_mmc_start_cmd(struct jz_mmc_host *host, -+ struct mmc_command *cmd, unsigned int cmdat) -+{ -+ u32 timeout = 0x3fffff; -+ unsigned int stat; -+ struct jz_mmc_host *hst = host; -+ WARN_ON(host->cmd != NULL); -+ host->cmd = cmd; -+ -+ /* stop MMC clock */ -+ jz_mmc_stop_clock(); -+ -+ /* mask interrupts */ -+ REG_MSC_IMASK = 0xff; -+ -+ /* clear status */ -+ REG_MSC_IREG = 0xff; -+ -+ if (cmd->flags & MMC_RSP_BUSY) -+ cmdat |= MSC_CMDAT_BUSY; -+ -+#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) -+ switch (RSP_TYPE(mmc_resp_type(cmd))) { -+ case RSP_TYPE(MMC_RSP_R1): /* r1,r1b, r6, r7 */ -+ cmdat |= MSC_CMDAT_RESPONSE_R1; -+ r_type = 1; -+ break; -+ case RSP_TYPE(MMC_RSP_R3): -+ cmdat |= MSC_CMDAT_RESPONSE_R3; -+ r_type = 1; -+ break; -+ case RSP_TYPE(MMC_RSP_R2): -+ cmdat |= MSC_CMDAT_RESPONSE_R2; -+ r_type = 2; -+ break; -+ default: -+ break; -+ } -+ REG_MSC_CMD = cmd->opcode; -+ -+ /* Set argument */ -+#ifdef CONFIG_JZ_MMC_BUS_1 -+ if (cmd->opcode == 6) { -+ /* set 1 bit sd card bus*/ -+ if (cmd->arg ==2) -+ REG_MSC_ARG = 0; -+ -+ /* set 1 bit mmc card bus*/ -+ if (cmd->arg == 0x3b70101) -+ REG_MSC_ARG = 0x3b70001; -+ } else -+ REG_MSC_ARG = cmd->arg; -+#else -+ REG_MSC_ARG = cmd->arg; -+#endif -+ -+ /* Set command */ -+ REG_MSC_CMDAT = cmdat; -+ -+ /* Send command */ -+ jz_mmc_start_clock(); -+ -+ while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES)) -+ ; -+ -+ REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear irq flag */ -+ if (cmd->opcode == 12) { -+ while (timeout-- && !(REG_MSC_IREG & MSC_IREG_PRG_DONE)) -+ ; -+ REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */ -+ } -+ if (!mmc_slot_enable) { -+ /* It seems that MSC can't report the MSC_STAT_TIME_OUT_RES when -+ * card was removed. We force to return here. -+ */ -+ cmd->error = -ETIMEDOUT; -+ jz_mmc_finish_request(hst, hst->mrq); -+ return; -+ } -+ -+ if (SD_IO_SEND_OP_COND == cmd->opcode) { -+ /* -+ * Don't support SDIO card currently. -+ */ -+ cmd->error = -ETIMEDOUT; -+ jz_mmc_finish_request(hst, hst->mrq); -+ return; -+ } -+ -+ /* Check for status */ -+ stat = REG_MSC_STAT; -+ jz_mmc_cmd_done(hst, stat); -+ if (host->data) { -+ if (cmd->opcode == MMC_WRITE_BLOCK || cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) -+#ifdef USE_DMA -+ jz_mmc_tx_setup_data(host, host->data); -+#else -+ jz_mmc_send_pio(host); -+ else -+ jz_mmc_receive_pio(host); -+#endif -+ } -+} -+ -+static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat) -+{ -+ struct mmc_command *cmd = host->cmd; -+ int i, temp[16]; -+ u8 *buf; -+ u32 data, v, w1, w2; -+ -+ if (!cmd) -+ return 0; -+ -+ host->cmd = NULL; -+ buf = (u8 *) temp; -+ switch (r_type) { -+ case 1: -+ { -+ data = REG_MSC_RES; -+ buf[0] = (data >> 8) & 0xff; -+ buf[1] = data & 0xff; -+ data = REG_MSC_RES; -+ buf[2] = (data >> 8) & 0xff; -+ buf[3] = data & 0xff; -+ data = REG_MSC_RES; -+ buf[4] = data & 0xff; -+ cmd->resp[0] = -+ buf[1] << 24 | buf[2] << 16 | buf[3] << 8 | -+ buf[4]; -+ break; -+ } -+ case 2: -+ { -+ data = REG_MSC_RES; -+ v = data & 0xffff; -+ for (i = 0; i < 4; i++) { -+ data = REG_MSC_RES; -+ w1 = data & 0xffff; -+ data = REG_MSC_RES; -+ w2 = data & 0xffff; -+ cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8; -+ v = w2; -+ } -+ break; -+ } -+ case 0: -+ break; -+ } -+ if (stat & MSC_STAT_TIME_OUT_RES) { -+ printk("MSC_STAT_TIME_OUT_RES\n"); -+ cmd->error = -ETIMEDOUT; -+ } else if (stat & MSC_STAT_CRC_RES_ERR && cmd->flags & MMC_RSP_CRC) { -+ printk("MSC_STAT_CRC\n"); -+ if (cmd->opcode == MMC_ALL_SEND_CID || -+ cmd->opcode == MMC_SEND_CSD || -+ cmd->opcode == MMC_SEND_CID) { -+ /* a bogus CRC error can appear if the msb of -+ the 15 byte response is a one */ -+ if ((cmd->resp[0] & 0x80000000) == 0) -+ cmd->error = -EILSEQ; -+ } -+ } -+ /* -+ * Did I mention this is Sick. We always need to -+ * discard the upper 8 bits of the first 16-bit word. -+ */ -+ if (host->data && cmd->error == 0) -+ jz_mmc_enable_irq(host, MSC_IMASK_DATA_TRAN_DONE); -+ else -+ jz_mmc_finish_request(host, host->mrq); -+ -+ return 1; -+} -+ -+static int jz_mmc_data_done(struct jz_mmc_host *host, unsigned int stat) -+{ -+ struct mmc_data *data = host->data; -+ -+ if (!data) -+ return 0; -+ REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ -+ jz_mmc_stop_clock(); -+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, -+ host->dma_dir); -+ if (stat & MSC_STAT_TIME_OUT_READ) { -+ printk("MMC/SD timeout, MMC_STAT 0x%x\n", stat); -+ data->error = -ETIMEDOUT; -+ } else if (REG_MSC_STAT & -+ (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR)) { -+ printk("MMC/SD CRC error, MMC_STAT 0x%x\n", stat); -+ data->error = -EILSEQ; -+ } -+ /* -+ * There appears to be a hardware design bug here. There seems to -+ * be no way to find out how much data was transferred to the card. -+ * This means that if there was an error on any block, we mark all -+ * data blocks as being in error. -+ */ -+ if (data->error == 0) -+ data->bytes_xfered = data->blocks * data->blksz; -+ else -+ data->bytes_xfered = 0; -+ -+ jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE); -+ host->data = NULL; -+ if (host->mrq->stop) { -+ jz_mmc_stop_clock(); -+ jz_mmc_start_cmd(host, host->mrq->stop, 0); -+ } else { -+ jz_mmc_finish_request(host, host->mrq); -+ } -+ return 1; -+} -+ -+static void jz_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct jz_mmc_host *host = mmc_priv(mmc); -+ unsigned int cmdat; -+ -+ /* stop MMC clock */ -+ jz_mmc_stop_clock(); -+ -+ /* Save current request for the future processing */ -+ host->mrq = mrq; -+ host->data = mrq->data; -+ cmdat = host->cmdat; -+ host->cmdat &= ~MSC_CMDAT_INIT; -+ -+ if (mrq->data) { -+ cmdat &= ~MSC_CMDAT_BUSY; -+#ifdef USE_DMA -+ if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) -+ -+ cmdat |= -+ MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | -+ MSC_CMDAT_DMA_EN; -+ else { -+#ifdef CONFIG_JZ_MMC_BUS_1 -+ cmdat &= ~MSC_CMDAT_BUS_WIDTH_4BIT; -+ cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | -+ MSC_CMDAT_DMA_EN; -+#else -+ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_DMA_EN; -+#endif -+ } -+ if (mrq->data->flags & MMC_DATA_WRITE) -+ cmdat |= MSC_CMDAT_WRITE; -+ -+ if (mrq->data->flags & MMC_DATA_STREAM) -+ cmdat |= MSC_CMDAT_STREAM_BLOCK; -+ if (mrq->cmd->opcode != MMC_WRITE_BLOCK -+ && mrq->cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK) -+ jz_mmc_rx_setup_data(host, mrq->data); -+#else /*USE_DMA*/ -+ -+ if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) -+ cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; -+ else { -+#ifdef CONFIG_JZ_MMC_BUS_1 -+ cmdat &= ~MSC_CMDAT_BUS_WIDTH_4BIT; -+ cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; -+#else -+ cmdat |= MSC_CMDAT_DATA_EN; -+#endif -+ } -+ if (mrq->data->flags & MMC_DATA_WRITE) -+ cmdat |= MSC_CMDAT_WRITE; -+ -+ if (mrq->data->flags & MMC_DATA_STREAM) -+ cmdat |= MSC_CMDAT_STREAM_BLOCK; -+ jz_mmc_prepare_data(host, host->data); -+#endif /*USE_DMA*/ -+ } -+ jz_mmc_start_cmd(host, mrq->cmd, cmdat); -+} -+ -+static irqreturn_t jz_mmc_irq(int irq, void *devid) -+{ -+ struct jz_mmc_host *host = devid; -+ unsigned int ireg; -+ int handled = 0; -+ -+ ireg = REG_MSC_IREG; -+ -+ if (ireg) { -+ unsigned stat = REG_MSC_STAT; -+ if (ireg & MSC_IREG_DATA_TRAN_DONE) -+ handled |= jz_mmc_data_done(host, stat); -+ } -+ return IRQ_RETVAL(handled); -+} -+ -+/* Returns true if MMC slot is empty */ -+static int jz_mmc_slot_is_empty(int slot) -+{ -+ int empty; -+ -+ empty = (__msc_card_detected(slot) == 0) ? 1 : 0; -+ -+ if (empty) { -+ /* wait for card insertion */ -+#ifdef CONFIG_MIPS_JZ4740_LYRA -+ __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN); -+#else -+ __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN); -+#endif -+ } else { -+ /* wait for card removal */ -+#ifdef CONFIG_MIPS_JZ4740_LYRA -+ __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN); -+#else -+ __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN); -+#endif -+ } -+ -+ return empty; -+} -+ -+static irqreturn_t jz_mmc_detect_irq(int irq, void *devid) -+{ -+ struct jz_mmc_host *host = (struct jz_mmc_host *) devid; -+ -+ if (jz_mmc_slot_is_empty(0)) { -+ mmc_slot_enable = 0; -+ mmc_detect_change(host->mmc, 50); -+ } else { -+ mmc_slot_enable = 1; -+ mmc_detect_change(host->mmc, 50); -+ } -+ return IRQ_HANDLED; -+} -+ -+static int jz_mmc_get_ro(struct mmc_host *mmc) -+{ -+ struct jz_mmc_host *host = mmc_priv(mmc); -+ -+ if (host->pdata && host->pdata->get_ro) -+ return host->pdata->get_ro(mmc_dev(mmc)); -+ /* Host doesn't support read only detection so assume writeable */ -+ return 0; -+} -+ -+/* set clock and power */ -+static void jz_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct jz_mmc_host *host = mmc_priv(mmc); -+ -+ if (ios->clock) -+ jz_mmc_set_clock(ios->clock); -+ else -+ jz_mmc_stop_clock(); -+ -+ if (host->power_mode != ios->power_mode) { -+ host->power_mode = ios->power_mode; -+ -+ if (ios->power_mode == MMC_POWER_ON) -+ host->cmdat |= CMDAT_INIT; -+ } -+ -+ if ((ios->bus_width == MMC_BUS_WIDTH_4) || (ios->bus_width == MMC_BUS_WIDTH_8)) -+ host->cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT; -+ else -+ host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_4BIT; -+} -+ -+static const struct mmc_host_ops jz_mmc_ops = { -+ .request = jz_mmc_request, -+ .get_ro = jz_mmc_get_ro, -+ .set_ios = jz_mmc_set_ios, -+}; -+ -+static int jz_mmc_probe(struct platform_device *pdev) -+{ -+ int retval; -+ struct mmc_host *mmc; -+ struct jz_mmc_host *host = NULL; -+ int irq; -+ struct resource *r; -+ -+ __gpio_as_msc(); -+ __msc_init_io(); -+ __msc_enable_power(); -+ -+ __msc_reset(); -+ -+ /* On reset, stop MMC clock */ -+ jz_mmc_stop_clock(); -+ -+ MMC_IRQ_MASK(); -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ irq = platform_get_irq(pdev, 0); -+ if (!r || irq < 0) -+ return -ENXIO; -+ -+ r = request_mem_region(r->start, SZ_4K, DRIVER_NAME); -+ if (!r) -+ return -EBUSY; -+ -+ mmc = mmc_alloc_host(sizeof(struct jz_mmc_host), &pdev->dev); -+ if (!mmc) { -+ retval = -ENOMEM; -+ goto out; -+ } -+ mmc->ops = &jz_mmc_ops; -+ mmc->f_min = MMC_CLOCK_SLOW; -+ mmc->f_max = SD_CLOCK_FAST; -+ /* -+ * We can do SG-DMA, but we don't because we never know how much -+ * data we successfully wrote to the card. -+ */ -+ mmc->max_phys_segs = NR_SG; -+ /* -+ * Our hardware DMA can handle a maximum of one page per SG entry. -+ */ -+ mmc->max_seg_size = PAGE_SIZE; -+ /* -+ * Block length register is 10 bits. -+ */ -+ mmc->max_blk_size = 1023; -+ /* -+ * Block count register is 16 bits. -+ */ -+ mmc->max_blk_count = 65535; -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ host->pdata = pdev->dev.platform_data; -+ mmc->ocr_avail = host->pdata ? -+ host->pdata->ocr_mask : MMC_VDD_32_33 | MMC_VDD_33_34; -+ host->mmc->caps = -+ MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED -+ | MMC_CAP_MMC_HIGHSPEED; -+ /* -+ *MMC_CAP_4_BIT_DATA (1 << 0) The host can do 4 bit transfers -+ * -+ */ -+ host->sg_cpu = -+ dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, -+ GFP_KERNEL); -+ if (!host->sg_cpu) { -+ retval = -ENOMEM; -+ goto out; -+ } -+ spin_lock_init(&host->lock); -+ host->irq = JZ_IRQ_MSC; -+ host->imask = 0xff; -+ /* -+ * Ensure that the host controller is shut down, and setup -+ * with our defaults. -+ */ -+ retval = request_irq(JZ_IRQ_MSC, jz_mmc_irq, 0, "MMC/SD", host); -+ if (retval) { -+ printk(KERN_ERR "MMC/SD: can't request MMC/SD IRQ\n"); -+ return retval; -+ } -+ jz_mmc_slot_is_empty(0); -+ /* Request card detect interrupt */ -+ -+ retval = request_irq(MSC_HOTPLUG_IRQ, jz_mmc_detect_irq, 0, //SA_INTERRUPT, -+ "MMC card detect", host); -+ if (retval) { -+ printk(KERN_ERR "MMC/SD: can't request card detect IRQ\n"); -+ goto err1; -+ } -+#ifdef USE_DMA -+ /* Request MMC Rx DMA channel */ -+ rxdmachan = -+ jz_request_dma(DMA_ID_MSC_RX, "MMC Rx", jz_mmc_dma_rx_callback, -+ 0, host); -+ if (rxdmachan < 0) { -+ printk(KERN_ERR "jz_request_dma failed for MMC Rx\n"); -+ goto err2; -+ } -+ -+ /* Request MMC Tx DMA channel */ -+ txdmachan = -+ jz_request_dma(DMA_ID_MSC_TX, "MMC Tx", jz_mmc_dma_tx_callback, -+ 0, host); -+ if (txdmachan < 0) { -+ printk(KERN_ERR "jz_request_dma failed for MMC Tx\n"); -+ goto err3; -+ } -+#endif -+ platform_set_drvdata(pdev, mmc); -+ mmc_add_host(mmc); -+ printk("JZ SD/MMC card driver registered\n"); -+ -+ /* Detect card during initialization */ -+#ifdef CONFIG_SOC_JZ4740 -+ if (!jz_mmc_slot_is_empty(0)) { -+ mmc_slot_enable = 1; -+ mmc_detect_change(host->mmc, 0); -+ } -+#endif -+ return 0; -+ -+err1:free_irq(JZ_IRQ_MSC, &host); -+#ifdef USE_DMA -+ err2:jz_free_dma(rxdmachan); -+ err3:jz_free_dma(txdmachan); -+#endif -+out: -+ if (host) { -+ if (host->sg_cpu) -+ dma_free_coherent(&pdev->dev, PAGE_SIZE, -+ host->sg_cpu, host->sg_dma); -+ } -+ if (mmc) -+ mmc_free_host(mmc); -+ return -1; -+} -+ -+static int jz_mmc_remove(struct platform_device *pdev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ if (mmc) { -+ struct jz_mmc_host *host = mmc_priv(mmc); -+ -+ if (host->pdata && host->pdata->exit) -+ host->pdata->exit(&pdev->dev, mmc); -+ -+ mmc_remove_host(mmc); -+ -+ jz_mmc_stop_clock(); -+ __msc_disable_power(); -+ jz_free_dma(rxdmachan); -+ jz_free_dma(txdmachan); -+ free_irq(JZ_IRQ_MSC, host); -+ mmc_free_host(mmc); -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+pm_message_t state; -+static int jz_mmc_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(dev); -+ int ret = 0; -+ -+ __msc_disable_power(); -+ if (mmc) -+ ret = mmc_suspend_host(mmc, state); -+ -+ return ret; -+} -+ -+static int jz_mmc_resume(struct platform_device *dev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(dev); -+ int ret = 0; -+#if 0 -+ /*for sandisk BB0807011816D and other strange cards*/ -+ int i; -+ -+ for(i = 104; i < 110; i++) -+ __gpio_as_input(i); -+ -+ /* perhaps you should mdelay more */ -+ mdelay(1000); -+ __gpio_as_msc(); -+#endif -+ __msc_init_io(); -+ __msc_enable_power(); -+ __msc_reset(); -+ -+ if (!jz_mmc_slot_is_empty(0)) { -+ mmc_slot_enable = 1; -+ mmc_detect_change(mmc, 10); -+ } -+ -+ if (mmc) -+ ret = mmc_resume_host(mmc); -+ -+ return ret; -+} -+#else -+#define jz_mmc_suspend NULL -+#define jz_mmc_resume NULL -+#endif -+ -+static struct platform_driver jz_mmc_driver = { -+ .probe = jz_mmc_probe, -+ .remove = jz_mmc_remove, -+ .suspend = jz_mmc_suspend, -+ .resume = jz_mmc_resume, -+ .driver = { -+ .name = DRIVER_NAME, -+ }, -+}; -+ -+static int __init jz_mmc_init(void) -+{ -+ return platform_driver_register(&jz_mmc_driver); -+} -+ -+static void __exit jz_mmc_exit(void) -+{ -+ platform_driver_unregister(&jz_mmc_driver); -+} -+ -+module_init(jz_mmc_init); -+module_exit(jz_mmc_exit); -+ -+MODULE_DESCRIPTION("JZ47XX SD/Multimedia Card Interface Driver"); -+MODULE_LICENSE("GPL"); -diff -ruN linux-2.6.31-vanilla/drivers/mmc/host/jz_mmc.h linux-2.6.31/drivers/mmc/host/jz_mmc.h ---- linux-2.6.31-vanilla/drivers/mmc/host/jz_mmc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/mmc/host/jz_mmc.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,65 @@ -+#ifndef __JZ_MMC_H__ -+#define __JZ_MMC_H__ -+ -+#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ -+#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ -+#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ -+#define MMC_NO_ERROR 0 -+/* Extra MMC commands for state control */ -+/* Use negative numbers to disambiguate */ -+#define MMC_CIM_RESET -1 -+#define MMC_SET_CLOCK 100 -+ -+typedef struct jzsoc_dma_desc { -+ volatile u32 ddadr; /* Points to the next descriptor + flags */ -+ volatile u32 dsadr; /* DSADR value for the current transfer */ -+ volatile u32 dtadr; /* DTADR value for the current transfer */ -+ volatile u32 dcmd; /* DCMD value for the current transfer */ -+} jzsoc_dma_desc; -+ -+ -+ -+ -+#include <linux/interrupt.h> -+ -+struct device; -+struct mmc_host; -+ -+struct jz_mmc_platform_data { -+ unsigned int ocr_mask; /* available voltages */ -+ unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */ -+ int (*init)(struct device *, irq_handler_t , void *); -+ int (*get_ro)(struct device *); -+ void (*setpower)(struct device *, unsigned int); -+ void (*exit)(struct device *, void *); -+}; -+ -+//extern void pxa_set_mci_info(struct pxamci_platform_data *info); -+ -+ -+ -+#define SZ_1K 0x00000400 -+#define SZ_4K 0x00001000 -+#define SZ_8K 0x00002000 -+#define SZ_16K 0x00004000 -+#define SZ_64K 0x00010000 -+#define SZ_128K 0x00020000 -+#define SZ_256K 0x00040000 -+#define SZ_512K 0x00080000 -+ -+#define SZ_1M 0x00100000 -+#define SZ_2M 0x00200000 -+#define SZ_4M 0x00400000 -+#define SZ_8M 0x00800000 -+#define SZ_16M 0x01000000 -+#define SZ_32M 0x02000000 -+#define SZ_64M 0x04000000 -+#define SZ_128M 0x08000000 -+#define SZ_256M 0x10000000 -+#define SZ_512M 0x20000000 -+ -+#define SZ_1G 0x40000000 -+#define SZ_2G 0x80000000 -+ -+ -+#endif /* __JZ_MMC_H__ */ -diff -ruN linux-2.6.31-vanilla/drivers/mtd/nand/jz4740_nand.c linux-2.6.31/drivers/mtd/nand/jz4740_nand.c ---- linux-2.6.31-vanilla/drivers/mtd/nand/jz4740_nand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/mtd/nand/jz4740_nand.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,418 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ4720/JZ4740 SoC NAND controller driver -+ * -+ * 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. -+ * -+ * 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 <linux/ioport.h> -+#include <linux/platform_device.h> -+ -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/nand.h> -+#include <linux/mtd/partitions.h> -+ -+#include <linux/mtd/jz4740_nand.h> -+#include <linux/gpio.h> -+ -+#define JZ_REG_NAND_CTRL 0x50 -+#define JZ_REG_NAND_ECC_CTRL 0x100 -+#define JZ_REG_NAND_DATA 0x104 -+#define JZ_REG_NAND_PAR0 0x108 -+#define JZ_REG_NAND_PAR1 0x10C -+#define JZ_REG_NAND_PAR2 0x110 -+#define JZ_REG_NAND_IRQ_STAT 0x114 -+#define JZ_REG_NAND_IRQ_CTRL 0x118 -+#define JZ_REG_NAND_ERR(x) (0x11C + (x << 2)) -+ -+#define JZ_NAND_ECC_CTRL_PAR_READY BIT(4) -+#define JZ_NAND_ECC_CTRL_ENCODING BIT(3) -+#define JZ_NAND_ECC_CTRL_RS BIT(2) -+#define JZ_NAND_ECC_CTRL_RESET BIT(1) -+#define JZ_NAND_ECC_CTRL_ENABLE BIT(0) -+ -+#define JZ_NAND_STATUS_ERR_COUNT (BIT(31) | BIT(30) | BIT(29)) -+#define JZ_NAND_STATUS_PAD_FINISH BIT(4) -+#define JZ_NAND_STATUS_DEC_FINISH BIT(3) -+#define JZ_NAND_STATUS_ENC_FINISH BIT(2) -+#define JZ_NAND_STATUS_UNCOR_ERROR BIT(1) -+#define JZ_NAND_STATUS_ERROR BIT(0) -+ -+#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT(x << 1) -+#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT((x << 1) + 1) -+ -+#define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000) -+#define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000) -+#define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000) -+ -+struct jz_nand { -+ struct mtd_info mtd; -+ struct nand_chip chip; -+ void __iomem *base; -+ struct resource *mem; -+ -+ struct jz_nand_platform_data *pdata; -+}; -+ -+static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) -+{ -+ return container_of(mtd, struct jz_nand, mtd); -+} -+ -+static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) -+{ -+ struct jz_nand *nand = mtd_to_jz_nand(mtd); -+ struct nand_chip *chip = mtd->priv; -+ uint32_t reg; -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE)); -+ if (ctrl & NAND_ALE) -+ chip->IO_ADDR_W = JZ_NAND_ADDR_ADDR; -+ else if (ctrl & NAND_CLE) -+ chip->IO_ADDR_W = JZ_NAND_CMD_ADDR; -+ else -+ chip->IO_ADDR_W = JZ_NAND_DATA_ADDR; -+ -+ reg = readl(nand->base + JZ_REG_NAND_CTRL); -+ if ( ctrl & NAND_NCE ) -+ reg |= JZ_NAND_CTRL_ASSERT_CHIP(0); -+ else -+ reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0); -+ writel(reg, nand->base + JZ_REG_NAND_CTRL); -+ } -+ if (dat != NAND_CMD_NONE) -+ writeb(dat, chip->IO_ADDR_W); -+} -+ -+static int jz_nand_dev_ready(struct mtd_info *mtd) -+{ -+ struct jz_nand *nand = mtd_to_jz_nand(mtd); -+ return gpio_get_value_cansleep(nand->pdata->busy_gpio); -+} -+ -+static void jz_nand_hwctl(struct mtd_info *mtd, int mode) -+{ -+ struct jz_nand *nand = mtd_to_jz_nand(mtd); -+ uint32_t reg; -+ -+ -+ writel(0, nand->base + JZ_REG_NAND_IRQ_STAT); -+ reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); -+ -+ reg |= JZ_NAND_ECC_CTRL_RESET; -+ reg |= JZ_NAND_ECC_CTRL_ENABLE; -+ reg |= JZ_NAND_ECC_CTRL_RS; -+ -+ switch(mode) { -+ case NAND_ECC_READ: -+ reg &= ~JZ_NAND_ECC_CTRL_ENCODING; -+ break; -+ case NAND_ECC_WRITE: -+ reg |= JZ_NAND_ECC_CTRL_ENCODING; -+ break; -+ default: -+ break; -+ } -+ -+ writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); -+} -+ -+static int jz_nand_calculate_ecc_rs(struct mtd_info* mtd, const uint8_t* dat, -+ uint8_t *ecc_code) -+{ -+ struct jz_nand *nand = mtd_to_jz_nand(mtd); -+ uint32_t reg, status; -+ int i; -+ -+ do { -+ status = readl(nand->base + JZ_REG_NAND_IRQ_STAT); -+ } while(!(status & JZ_NAND_STATUS_ENC_FINISH)); -+ -+ reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); -+ reg &= ~JZ_NAND_ECC_CTRL_ENABLE; -+ writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); -+ -+ for (i = 0; i < 9; ++i) { -+ ecc_code[i] = readb(nand->base + JZ_REG_NAND_PAR0 + i); -+ } -+ -+ return 0; -+} -+ -+static void correct_data(uint8_t *dat, int index, int mask) -+{ -+ int offset = index & 0x7; -+ uint16_t data; -+ printk("correct: "); -+ -+ index += (index >> 3); -+ -+ data = dat[index]; -+ data |= dat[index+1] << 8; -+ -+ printk("0x%x -> ", data); -+ -+ mask ^= (data >> offset) & 0x1ff; -+ data &= ~(0x1ff << offset); -+ data |= (mask << offset); -+ -+ printk("0x%x\n", data); -+ -+ dat[index] = data & 0xff; -+ dat[index+1] = (data >> 8) & 0xff; -+} -+ -+static int jz_nand_correct_ecc_rs(struct mtd_info* mtd, uint8_t *dat, -+ uint8_t *read_ecc, uint8_t *calc_ecc) -+{ -+ struct jz_nand *nand = mtd_to_jz_nand(mtd); -+ int i, error_count, index; -+ uint32_t reg, status, error; -+ -+ for(i = 0; i < 9; ++i) { -+ if (read_ecc[i] != 0xff) -+ break; -+ } -+ if (i == 9) { -+ for (i = 0; i < nand->chip.ecc.size; ++i) { -+ if (dat[i] != 0xff) -+ break; -+ } -+ if (i == nand->chip.ecc.size) -+ return 0; -+ } -+ -+ for(i = 0; i < 9; ++i) -+ writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i); -+ -+ reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); -+ reg |= JZ_NAND_ECC_CTRL_PAR_READY; -+ writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); -+ -+ do { -+ status = readl(nand->base + JZ_REG_NAND_IRQ_STAT); -+ } while (!(status & JZ_NAND_STATUS_DEC_FINISH)); -+ -+ reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); -+ reg &= ~JZ_NAND_ECC_CTRL_ENABLE; -+ writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); -+ -+ if (status & JZ_NAND_STATUS_ERROR) { -+ if (status & JZ_NAND_STATUS_UNCOR_ERROR) { -+ printk("uncorrectable ecc:"); -+ for(i = 0; i < 9; ++i) -+ printk(" 0x%x", read_ecc[i]); -+ printk("\n"); -+ printk("uncorrectable data:"); -+ for(i = 0; i < 32; ++i) -+ printk(" 0x%x", dat[i]); -+ printk("\n"); -+ return -1; -+ } -+ -+ error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; -+ -+ printk("error_count: %d %x\n", error_count, status); -+ -+ for(i = 0; i < error_count; ++i) { -+ error = readl(nand->base + JZ_REG_NAND_ERR(i)); -+ index = ((error >> 16) & 0x1ff) - 1; -+ if (index >= 0 && index < 512) { -+ correct_data(dat, index, error & 0x1ff); -+ } -+ } -+ -+ return error_count; -+ } -+ -+ return 0; -+} -+ -+ -+ -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+static const char *part_probes[] = {"cmdline", NULL}; -+#endif -+ -+static int __devinit jz_nand_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct jz_nand *nand; -+ struct nand_chip *chip; -+ struct mtd_info *mtd; -+ struct jz_nand_platform_data *pdata = pdev->dev.platform_data; -+#ifdef CONFIG_MTD_PARTITIONS -+ struct mtd_partition *partition_info; -+ int num_partitions = 0; -+#endif -+ -+ nand = kzalloc(sizeof(*nand), GFP_KERNEL); -+ if (!nand) { -+ dev_err(&pdev->dev, "Failed to allocate device structure.\n"); -+ return -ENOMEM; -+ } -+ -+ nand->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!nand->mem) { -+ dev_err(&pdev->dev, "Failed to get platform mmio memory\n"); -+ ret = -ENOENT; -+ goto err_free; -+ } -+ -+ nand->mem = request_mem_region(nand->mem->start, resource_size(nand->mem), -+ pdev->name); -+ -+ if (!nand->mem) { -+ dev_err(&pdev->dev, "Failed to request mmio memory region\n"); -+ ret = -EBUSY; -+ goto err_free; -+ } -+ -+ nand->base = ioremap(nand->mem->start, resource_size(nand->mem)); -+ -+ if (!nand->base) { -+ dev_err(&pdev->dev, "Faild to ioremap mmio memory region\n"); -+ ret = -EBUSY; -+ goto err_release_mem; -+ } -+ -+ if (pdata && gpio_is_valid(pdata->busy_gpio)) { -+ ret = gpio_request(pdata->busy_gpio, "jz nand busy line"); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to request busy gpio %d: %d\n", -+ pdata->busy_gpio, ret); -+ goto err_iounmap; -+ } -+ } -+ -+ mtd = &nand->mtd; -+ chip = &nand->chip; -+ mtd->priv = chip; -+ mtd->owner = THIS_MODULE; -+ mtd->name = "jz4740-nand"; -+ -+ chip->ecc.hwctl = jz_nand_hwctl; -+ -+ chip->ecc.calculate = jz_nand_calculate_ecc_rs; -+ chip->ecc.correct = jz_nand_correct_ecc_rs; -+ chip->ecc.mode = NAND_ECC_HW; -+ chip->ecc.size = 512; -+ chip->ecc.bytes = 9; -+ if (pdata) -+ chip->ecc.layout = pdata->ecc_layout; -+ -+ chip->chip_delay = 50; -+ chip->cmd_ctrl = jz_nand_cmd_ctrl; -+ -+ if (pdata && gpio_is_valid(pdata->busy_gpio)) -+ chip->dev_ready = jz_nand_dev_ready; -+ -+ chip->IO_ADDR_R = JZ_NAND_DATA_ADDR; -+ chip->IO_ADDR_W = JZ_NAND_DATA_ADDR; -+ -+ nand->pdata = pdata; -+ platform_set_drvdata(pdev, nand); -+ -+ ret = nand_scan_ident(mtd, 1); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to scan nand\n"); -+ goto err_gpio_free; -+ } -+ -+ if (pdata && pdata->ident_callback) { -+ pdata->ident_callback(pdev, chip, &pdata->partitions, &pdata->num_partitions); -+ } -+ -+ ret = nand_scan_tail(mtd); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to scan nand\n"); -+ goto err_gpio_free; -+ } -+ -+#ifdef CONFIG_MTD_PARTITIONS -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+ num_partitions = parse_mtd_partitions(mtd, part_probes, -+ &partition_info, 0); -+#endif -+ if (num_partitions <= 0 && pdata) { -+ num_partitions = pdata->num_partitions; -+ partition_info = pdata->partitions; -+ } -+ -+ if (num_partitions > 0) -+ ret = add_mtd_partitions(mtd, partition_info, num_partitions); -+ else -+#endif -+ ret = add_mtd_device(mtd); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to add mtd device\n"); -+ goto err_nand_release; -+ } -+ -+ dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n"); -+ -+ return 0; -+err_nand_release: -+ nand_release(&nand->mtd); -+err_gpio_free: -+ platform_set_drvdata(pdev, NULL); -+ gpio_free(pdata->busy_gpio); -+err_iounmap: -+ iounmap(nand->base); -+err_release_mem: -+ release_mem_region(nand->mem->start, resource_size(nand->mem)); -+err_free: -+ kfree(nand); -+ return ret; -+} -+ -+static void __devexit jz_nand_remove(struct platform_device *pdev) -+{ -+ struct jz_nand *nand = platform_get_drvdata(pdev); -+ -+ nand_release(&nand->mtd); -+ -+ iounmap(nand->base); -+ -+ release_mem_region(nand->mem->start, resource_size(nand->mem)); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(nand); -+} -+ -+struct platform_driver jz_nand_driver = { -+ .probe = jz_nand_probe, -+ .remove = __devexit_p(jz_nand_probe), -+ .driver = { -+ .name = "jz4740-nand", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init jz_nand_init(void) -+{ -+ return platform_driver_register(&jz_nand_driver); -+} -+module_init(jz_nand_init); -+ -+static void __exit jz_nand_exit(void) -+{ -+ platform_driver_unregister(&jz_nand_driver); -+} -+module_exit(jz_nand_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_DESCRIPTION("NAND controller driver for JZ4720/JZ4740 SoC"); -+MODULE_ALIAS("platform:jz4740-nand"); -+MODULE_ALIAS("platform:jz4720-nand"); -diff -ruN linux-2.6.31-vanilla/drivers/power/jz4740-battery.c linux-2.6.31/drivers/power/jz4740-battery.c ---- linux-2.6.31-vanilla/drivers/power/jz4740-battery.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/power/jz4740-battery.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,471 @@ -+/* -+ * Battery measurement code for Ingenic JZ SOC. -+ * -+ * based on tosa_battery.c -+ * -+ * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com> -+ * Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com> -+ * -+ * 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 <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/power_supply.h> -+#include <linux/delay.h> -+#include <linux/spinlock.h> -+#include <linux/interrupt.h> -+#include <linux/platform_device.h> -+#include <linux/gpio.h> -+ -+#include <linux/power/jz4740-battery.h> -+#include <linux/jz4740-adc.h> -+ -+struct jz_battery_info { -+ struct power_supply usb; -+ struct power_supply bat; -+ struct power_supply ac; -+ int bat_status; -+ struct jz_batt_info *pdata; -+ struct mutex work_lock; -+ struct workqueue_struct *monitor_wqueue; -+ struct delayed_work bat_work; -+}; -+ -+#define ps_to_jz_battery(x) container_of((x), struct jz_battery_info, bat); -+ -+/********************************************************************* -+ * Power -+ *********************************************************************/ -+ -+ -+static int jz_get_power_prop(struct jz_battery_info *bat_info, -+ struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ int gpio; -+ -+ if (bat_info == 0 || bat_info->pdata == 0) -+ return -EINVAL; -+ gpio = (psy->type == POWER_SUPPLY_TYPE_MAINS) ? -+ bat_info->pdata->dc_dect_gpio : -+ bat_info->pdata->usb_dect_gpio; -+ if (!gpio_is_valid(gpio)) -+ return -EINVAL; -+ switch (psp) { -+ case POWER_SUPPLY_PROP_ONLINE: -+ val->intval = !gpio_get_value(gpio); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int jz_usb_get_power_prop(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ struct jz_battery_info *bat_info = container_of(psy, struct jz_battery_info, usb); -+ return jz_get_power_prop(bat_info, psy, psp, val); -+} -+ -+static int jz_ac_get_power_prop(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ struct jz_battery_info *bat_info = container_of(psy, struct jz_battery_info, ac); -+ return jz_get_power_prop(bat_info, psy, psp, val); -+} -+ -+ -+static enum power_supply_property jz_power_props[] = { -+ POWER_SUPPLY_PROP_ONLINE, -+}; -+ -+static struct power_supply jz_ac = { -+ .name = "ac", -+ .type = POWER_SUPPLY_TYPE_MAINS, -+ .properties = jz_power_props, -+ .num_properties = ARRAY_SIZE(jz_power_props), -+ .get_property = jz_ac_get_power_prop, -+}; -+ -+static struct power_supply jz_usb = { -+ .name = "usb", -+ .type = POWER_SUPPLY_TYPE_USB, -+ .properties = jz_power_props, -+ .num_properties = ARRAY_SIZE(jz_power_props), -+ .get_property = jz_usb_get_power_prop, -+}; -+ -+ -+/********************************************************************* -+ * Battery properties -+ *********************************************************************/ -+ -+static long jz_read_bat(struct power_supply *psy) -+{ -+ struct jz_battery_info *bat_info = ps_to_jz_battery(psy); -+ enum jz_adc_battery_scale scale; -+ -+ if (bat_info->pdata->max_voltag > 2500000) -+ scale = JZ_ADC_BATTERY_SCALE_7V5; -+ else -+ scale = JZ_ADC_BATTERY_SCALE_2V5; -+ -+ return jz4740_adc_read_battery_voltage(psy->dev->parent->parent, scale); -+} -+ -+static int jz_bat_get_capacity(struct power_supply *psy) -+{ -+ int ret; -+ struct jz_battery_info *bat_info = ps_to_jz_battery(psy); -+ -+ ret = jz_read_bat(psy); -+ -+ if (ret < 0) -+ return ret; -+ -+ ret = (ret - bat_info->pdata->min_voltag) * 100 -+ / (bat_info->pdata->max_voltag - bat_info->pdata->min_voltag); -+ -+ if (ret > 100) -+ ret = 100; -+ else if (ret < 0) -+ ret = 0; -+ -+ return ret; -+} -+ -+static int jz_bat_get_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ struct jz_battery_info *bat_info = ps_to_jz_battery(psy) -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_STATUS: -+ val->intval = bat_info->bat_status; -+ break; -+ case POWER_SUPPLY_PROP_TECHNOLOGY: -+ val->intval = bat_info->pdata->batt_tech; -+ break; -+ case POWER_SUPPLY_PROP_HEALTH: -+ if(jz_read_bat(psy) < bat_info->pdata->min_voltag) { -+ dev_dbg(psy->dev, "%s: battery is dead," -+ "voltage too low!\n", __func__); -+ val->intval = POWER_SUPPLY_HEALTH_DEAD; -+ } else { -+ dev_dbg(psy->dev, "%s: battery is good," -+ "voltage normal.\n", __func__); -+ val->intval = POWER_SUPPLY_HEALTH_GOOD; -+ } -+ break; -+ case POWER_SUPPLY_PROP_CAPACITY: -+ val->intval = jz_bat_get_capacity(psy); -+ dev_dbg(psy->dev, "%s: battery_capacity = %d\n", -+ __func__, val->intval); -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_NOW: -+ val->intval = jz_read_bat(psy); -+ if (val->intval < 0) -+ return val->intval; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MAX: -+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: -+ val->intval = bat_info->pdata->max_voltag; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: -+ val->intval = bat_info->pdata->min_voltag; -+ break; -+ case POWER_SUPPLY_PROP_PRESENT: -+ val->intval = 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static void jz_bat_external_power_changed(struct power_supply *psy) -+{ -+ struct jz_battery_info *bat_info = ps_to_jz_battery(psy); -+ -+ cancel_delayed_work(&bat_info->bat_work); -+ queue_delayed_work(bat_info->monitor_wqueue, &bat_info->bat_work, HZ / 8); -+} -+ -+static char *status_text[] = { -+ [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown", -+ [POWER_SUPPLY_STATUS_CHARGING] = "Charging", -+ [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging", -+ [POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not charging", -+}; -+ -+static void jz_bat_update(struct power_supply *psy) -+{ -+ struct jz_battery_info *bat_info = ps_to_jz_battery(psy); -+ -+ int old_status = bat_info->bat_status; -+ static unsigned long old_batt_vol = 0; -+ unsigned long batt_vol = jz_read_bat(psy); -+ -+ mutex_lock(&bat_info->work_lock); -+ -+ if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) { -+ if(!gpio_get_value(bat_info->pdata->charg_stat_gpio)) -+ bat_info->bat_status = POWER_SUPPLY_STATUS_CHARGING; -+ else -+ bat_info->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING; -+ dev_dbg(psy->dev, "%s: battery status=%s\n", -+ __func__, status_text[bat_info->bat_status]); -+ -+ if (old_status != bat_info->bat_status) { -+ dev_dbg(psy->dev, "%s %s -> %s\n", -+ psy->name, -+ status_text[old_status], -+ status_text[bat_info->bat_status]); -+ -+ power_supply_changed(psy); -+ } -+ } -+ -+ if (old_batt_vol - batt_vol > 50000) { -+ dev_dbg(psy->dev, "voltage change : %ld -> %ld\n", -+ old_batt_vol, batt_vol); -+ power_supply_changed(psy); -+ old_batt_vol = batt_vol; -+ } -+ -+ mutex_unlock(&bat_info->work_lock); -+} -+ -+static enum power_supply_property jz_bat_main_props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_HEALTH, -+ POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -+ POWER_SUPPLY_PROP_PRESENT, -+}; -+ -+struct power_supply bat_ps = { -+ .name = "battery", -+ .type = POWER_SUPPLY_TYPE_BATTERY, -+ .properties = jz_bat_main_props, -+ .num_properties = ARRAY_SIZE(jz_bat_main_props), -+ .get_property = jz_bat_get_property, -+ .external_power_changed = jz_bat_external_power_changed, -+ .use_for_apm = 1, -+}; -+ -+static void jz_bat_work(struct work_struct *work) -+{ -+ /* query interval too small will increase system workload*/ -+ const int interval = HZ * 30; -+ struct jz_battery_info *bat_info = container_of(work,struct jz_battery_info, bat_work.work); -+ -+ jz_bat_update(&bat_info->bat); -+ queue_delayed_work(bat_info->monitor_wqueue, -+ &bat_info->bat_work, interval); -+} -+ -+#ifdef CONFIG_PM -+static int jz_bat_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ struct jz_battery_info *bat_info = platform_get_drvdata(pdev); -+ -+ bat_info->bat_status = POWER_SUPPLY_STATUS_UNKNOWN; -+ -+ return 0; -+} -+ -+static int jz_bat_resume(struct platform_device *pdev) -+{ -+ struct jz_battery_info *bat_info = platform_get_drvdata(pdev); -+ -+ bat_info->bat_status = POWER_SUPPLY_STATUS_UNKNOWN; -+ -+ cancel_delayed_work(&bat_info->bat_work); -+ queue_delayed_work(bat_info->monitor_wqueue, &bat_info->bat_work, HZ/10); -+ -+ return 0; -+} -+#else -+#define jz_bat_suspend NULL -+#define jz_bat_resume NULL -+#endif -+ -+static int jz_bat_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct jz_battery_info *bat_info; -+ -+ bat_info = kzalloc(sizeof(struct jz_battery_info), GFP_KERNEL); -+ -+ if (!bat_info) { -+ return -ENOMEM; -+ } -+ -+ if (!pdev->dev.platform_data) { -+ dev_err(&pdev->dev, "Please set battery info\n"); -+ ret = -EINVAL; -+ goto err_platform_data; -+ } -+ platform_set_drvdata(pdev, bat_info); -+ bat_info->pdata = pdev->dev.platform_data; -+ bat_info->bat = bat_ps; -+ bat_info->usb = jz_usb; -+ bat_info->ac = jz_ac; -+ mutex_init(&bat_info->work_lock); -+ INIT_DELAYED_WORK(&bat_info->bat_work, jz_bat_work); -+ -+ if (gpio_is_valid(bat_info->pdata->dc_dect_gpio)) { -+ ret = gpio_request(bat_info->pdata->dc_dect_gpio, "AC/DC DECT"); -+ if (ret) { -+ dev_err(&pdev->dev, "ac/dc dect gpio request failed.\n"); -+ -+ goto err_dc_gpio_request; -+ } -+ ret = gpio_direction_input(bat_info->pdata->dc_dect_gpio); -+ if (ret) { -+ dev_err(&pdev->dev, "ac/dc dect gpio direction failed.\n"); -+ -+ goto err_dc_gpio_direction; -+ } -+ } -+ -+ if (gpio_is_valid(bat_info->pdata->usb_dect_gpio)) { -+ ret = gpio_request(bat_info->pdata->usb_dect_gpio, "USB DECT"); -+ if (ret) { -+ dev_err(&pdev->dev, "usb dect gpio request failed.\n"); -+ -+ goto err_usb_gpio_request; -+ } -+ ret = gpio_direction_input(bat_info->pdata->usb_dect_gpio); -+ if (ret) { -+ dev_err(&pdev->dev, "usb dect gpio set direction failed.\n"); -+ goto err_usb_gpio_direction; -+ } -+ -+ jz_gpio_disable_pullup(bat_info->pdata->usb_dect_gpio); -+ /* TODO: Use generic gpio is better */ -+ } -+ -+ if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) { -+ ret = gpio_request(bat_info->pdata->charg_stat_gpio, "CHARG STAT"); -+ if (ret) { -+ dev_err(&pdev->dev, "charger state gpio request failed.\n"); -+ goto err_charg_gpio_request; -+ } -+ ret = gpio_direction_input(bat_info->pdata->charg_stat_gpio); -+ if (ret) { -+ dev_err(&pdev->dev, "charger state gpio set direction failed.\n"); -+ goto err_charg_gpio_direction; -+ } -+ } -+ -+ if (gpio_is_valid(bat_info->pdata->dc_dect_gpio)) { -+ ret = power_supply_register(&pdev->dev, &bat_info->ac); -+ if (ret) { -+ dev_err(&pdev->dev, "power supply ac/dc register failed.\n"); -+ goto err_power_register_ac; -+ } -+ } -+ -+ if (gpio_is_valid(bat_info->pdata->usb_dect_gpio)) { -+ ret = power_supply_register(&pdev->dev, &bat_info->usb); -+ if (ret) { -+ dev_err(&pdev->dev, "power supply usb register failed.\n"); -+ goto err_power_register_usb; -+ } -+ } -+ -+ if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) { -+ ret = power_supply_register(&pdev->dev, &bat_info->bat); -+ if (ret) { -+ dev_err(&pdev->dev, "power supply battery register failed.\n"); -+ goto err_power_register_bat; -+ } else { -+ bat_info->monitor_wqueue = create_singlethread_workqueue("jz_battery"); -+ if (!bat_info->monitor_wqueue) { -+ return -ESRCH; -+ } -+ queue_delayed_work(bat_info->monitor_wqueue, &bat_info->bat_work, HZ * 1); -+ } -+ } -+ printk(KERN_INFO "jz_bat init success.\n"); -+ return ret; -+ -+err_power_register_bat: -+ power_supply_unregister(&bat_info->usb); -+err_power_register_usb: -+ power_supply_unregister(&bat_info->ac); -+err_power_register_ac: -+err_charg_gpio_direction: -+ gpio_free(bat_info->pdata->charg_stat_gpio); -+err_charg_gpio_request: -+err_usb_gpio_direction: -+ gpio_free(bat_info->pdata->usb_dect_gpio); -+err_usb_gpio_request: -+err_dc_gpio_direction: -+ gpio_free(bat_info->pdata->dc_dect_gpio); -+err_dc_gpio_request: -+err_platform_data: -+ kfree(bat_info); -+ return ret; -+} -+ -+static int jz_bat_remove(struct platform_device *pdev) -+{ -+ struct jz_battery_info *bat_info = platform_get_drvdata(pdev); -+ -+ if (bat_info->pdata) { -+ if (gpio_is_valid(bat_info->pdata->dc_dect_gpio)) -+ gpio_free(bat_info->pdata->dc_dect_gpio); -+ if (gpio_is_valid(bat_info->pdata->usb_dect_gpio)) -+ gpio_free(bat_info->pdata->usb_dect_gpio); -+ if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) -+ gpio_free(bat_info->pdata->charg_stat_gpio); -+ } -+ -+ power_supply_unregister(&bat_ps); -+ power_supply_unregister(&jz_ac); -+ power_supply_unregister(&jz_usb); -+ -+ return 0; -+} -+ -+static struct platform_driver jz_bat_driver = { -+ .probe = jz_bat_probe, -+ .remove = __devexit_p(jz_bat_remove), -+ .suspend = jz_bat_suspend, -+ .resume = jz_bat_resume, -+ .driver = { -+ .name = "jz4740-battery", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init jz_bat_init(void) -+{ -+ return platform_driver_register(&jz_bat_driver); -+} -+module_init(jz_bat_init); -+ -+static void __exit jz_bat_exit(void) -+{ -+ platform_driver_unregister(&jz_bat_driver); -+} -+module_exit(jz_bat_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jiejing Zhang <kzjeef@gmail.com>"); -+MODULE_DESCRIPTION("JZ4720/JZ4740 SoC battery driver"); -diff -ruN linux-2.6.31-vanilla/drivers/rtc/rtc-jz4740.c linux-2.6.31/drivers/rtc/rtc-jz4740.c ---- linux-2.6.31-vanilla/drivers/rtc/rtc-jz4740.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/rtc/rtc-jz4740.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,325 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ4720/JZ4740 SoC RTC driver -+ * -+ * 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. -+ * -+ * 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 <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/spinlock.h> -+#include <linux/rtc.h> -+ -+#define JZ_REG_RTC_CTRL 0x00 -+#define JZ_REG_RTC_SEC 0x04 -+#define JZ_REG_RTC_SEC_ALARM 0x08 -+#define JZ_REG_REGULATOR 0x0C -+ -+#define JZ_RTC_CTRL_WRDY BIT(7) -+#define JZ_RTC_CTRL_1HZ BIT(6) -+#define JZ_RTC_CTRL_1HZ_IRQ BIT(5) -+#define JZ_RTC_CTRL_AF BIT(4) -+#define JZ_RTC_CTRL_AF_IRQ BIT(3) -+#define JZ_RTC_CTRL_AE BIT(2) -+#define JZ_RTC_CTRL_ENABLE BIT(0) -+ -+struct jz4740_rtc { -+ struct resource *mem; -+ void __iomem *base; -+ -+ struct rtc_device *rtc; -+ -+ unsigned int irq; -+ -+ spinlock_t lock; -+}; -+ -+static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg) -+{ -+ return readl(rtc->base + reg); -+} -+ -+static inline void jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) -+{ -+ uint32_t ctrl; -+ do { -+ ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); -+ } while (!(ctrl & JZ_RTC_CTRL_WRDY)); -+} -+ -+ -+static inline void jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg, -+ uint32_t val) -+{ -+ jz4740_rtc_wait_write_ready(rtc); -+ writel(val, rtc->base + reg); -+} -+ -+static void jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask, -+ uint32_t val) -+{ -+ unsigned long flags; -+ uint32_t ctrl; -+ -+ spin_lock_irqsave(&rtc->lock, flags); -+ -+ ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); -+ -+ /* Don't clear interrupt flags by accident */ -+ ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF; -+ -+ ctrl &= ~mask; -+ ctrl |= val; -+ -+ jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl); -+ -+ spin_unlock_irqrestore(&rtc->lock, flags); -+} -+ -+static inline struct jz4740_rtc *dev_to_rtc(struct device *dev) -+{ -+ return dev_get_drvdata(dev); -+} -+ -+static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time) -+{ -+ struct jz4740_rtc *rtc = dev_to_rtc(dev); -+ uint32_t secs, secs2; -+ -+ secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); -+ secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); -+ -+ while (secs != secs2) { -+ secs = secs2; -+ secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); -+ } -+ -+ rtc_time_to_tm(secs, time); -+ -+ return rtc_valid_tm(time); -+} -+ -+static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs) -+{ -+ struct jz4740_rtc *rtc = dev_to_rtc(dev); -+ -+ if ((uint32_t)secs != secs) -+ return -EINVAL; -+ -+ jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs); -+ -+ return 0; -+} -+ -+static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -+{ -+ struct jz4740_rtc *rtc = dev_to_rtc(dev); -+ uint32_t secs, secs2; -+ uint32_t ctrl; -+ -+ secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); -+ secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); -+ -+ while (secs != secs2){ -+ secs = secs2; -+ secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); -+ } -+ -+ ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); -+ -+ alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE); -+ alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF); -+ -+ rtc_time_to_tm(secs, &alrm->time); -+ -+ return rtc_valid_tm(&alrm->time); -+} -+ -+static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -+{ -+ struct jz4740_rtc *rtc = dev_to_rtc(dev); -+ unsigned long secs; -+ -+ rtc_tm_to_time(&alrm->time, &secs); -+ -+ if ((uint32_t)secs != secs) -+ return -EINVAL; -+ -+ jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, (uint32_t)secs); -+ jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, -+ alrm->enabled ? JZ_RTC_CTRL_AE : 0); -+ -+ return 0; -+} -+ -+static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -+{ -+ struct jz4740_rtc *rtc = dev_to_rtc(dev); -+ jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, -+ enabled ? JZ_RTC_CTRL_1HZ_IRQ : 0); -+ return 0; -+} -+ -+ -+static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -+{ -+ struct jz4740_rtc *rtc = dev_to_rtc(dev); -+ jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, -+ enabled ? JZ_RTC_CTRL_AF_IRQ : 0); -+ return 0; -+} -+ -+static struct rtc_class_ops jz4740_rtc_ops = { -+ .read_time = jz4740_rtc_read_time, -+ .set_mmss = jz4740_rtc_set_mmss, -+ .read_alarm = jz4740_rtc_read_alarm, -+ .set_alarm = jz4740_rtc_set_alarm, -+ .update_irq_enable = jz4740_rtc_update_irq_enable, -+ .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, -+}; -+ -+static irqreturn_t jz4740_rtc_irq(int irq, void *data) -+{ -+ struct jz4740_rtc *rtc = data; -+ uint32_t ctrl; -+ unsigned long events = 0; -+ ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); -+ -+ if (ctrl & JZ_RTC_CTRL_1HZ) -+ events |= (RTC_UF | RTC_IRQF); -+ -+ if (ctrl & JZ_RTC_CTRL_AF) -+ events |= (RTC_AF | RTC_IRQF); -+ -+ rtc_update_irq(rtc->rtc, 1, events); -+ -+ jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, 0); -+ -+ return IRQ_HANDLED; -+} -+ -+static int __devinit jz4740_rtc_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct jz4740_rtc *rtc; -+ -+ rtc = kmalloc(sizeof(*rtc), GFP_KERNEL); -+ -+ rtc->irq = platform_get_irq(pdev, 0); -+ -+ if (rtc->irq < 0) { -+ ret = -ENOENT; -+ dev_err(&pdev->dev, "Failed to get platform irq\n"); -+ goto err_free; -+ } -+ -+ rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!rtc->mem) { -+ ret = -ENOENT; -+ dev_err(&pdev->dev, "Failed to get platform mmio memory\n"); -+ goto err_free; -+ } -+ -+ rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem), -+ pdev->name); -+ -+ if (!rtc->mem) { -+ ret = -EBUSY; -+ dev_err(&pdev->dev, "Failed to request mmio memory region\n"); -+ goto err_free; -+ } -+ -+ rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem)); -+ -+ if (!rtc->base) { -+ ret = -EBUSY; -+ dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); -+ goto err_release_mem_region; -+ } -+ -+ platform_set_drvdata(pdev, rtc); -+ -+ rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, -+ THIS_MODULE); -+ -+ if (IS_ERR(rtc->rtc)) { -+ ret = PTR_ERR(rtc->rtc); -+ dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret); -+ goto err_iounmap; -+ } -+ -+ ret = request_irq(rtc->irq, jz4740_rtc_irq, 0, -+ pdev->name, rtc); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret); -+ goto err_unregister_rtc; -+ } -+ printk("rtc-ctrl: %d\n", jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL)); -+ -+ return 0; -+ -+err_unregister_rtc: -+ rtc_device_unregister(rtc->rtc); -+err_iounmap: -+ platform_set_drvdata(pdev, NULL); -+ iounmap(rtc->base); -+err_release_mem_region: -+ release_mem_region(rtc->mem->start, resource_size(rtc->mem)); -+err_free: -+ kfree(rtc); -+ -+ return ret; -+} -+ -+static int __devexit jz4740_rtc_remove(struct platform_device *pdev) -+{ -+ struct jz4740_rtc *rtc = platform_get_drvdata(pdev); -+ -+ rtc_device_unregister(rtc->rtc); -+ -+ iounmap(rtc->base); -+ release_mem_region(rtc->mem->start, resource_size(rtc->mem)); -+ -+ kfree(rtc); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+struct platform_driver jz4740_rtc_driver = { -+ .probe = jz4740_rtc_probe, -+ .remove = __devexit_p(jz4740_rtc_remove), -+ .driver = { -+ .name = "jz4740-rtc", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init jz4740_rtc_init(void) -+{ -+ return platform_driver_register(&jz4740_rtc_driver); -+} -+module_init(jz4740_rtc_init); -+ -+static void __exit jz4740_rtc_exit(void) -+{ -+ platform_driver_unregister(&jz4740_rtc_driver); -+} -+module_exit(jz4740_rtc_exit); -+ -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("RTC driver for the JZ4720/JZ4740 SoC\n"); -+MODULE_ALIAS("platform:jz4740-rtc"); -+MODULE_ALIAS("platform:jz4720-rtc"); -diff -ruN linux-2.6.31-vanilla/drivers/usb/gadget/jz4740_udc.c linux-2.6.31/drivers/usb/gadget/jz4740_udc.c ---- linux-2.6.31-vanilla/drivers/usb/gadget/jz4740_udc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/usb/gadget/jz4740_udc.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,2337 @@ -+/* -+ * linux/drivers/usb/gadget/jz4740_udc.c -+ * -+ * Ingenic JZ4740 on-chip high speed USB device controller -+ * -+ * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc. -+ * Author: <jlwei@ingenic.cn> -+ * -+ * 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 device has ep0, two bulk-in/interrupt-in endpoints, and one bulk-out endpoint. -+ * -+ * - Endpoint numbering is fixed: ep0, ep1in-int, ep2in-bulk, ep1out-bulk. -+ * - DMA works with bulk-in (channel 1) and bulk-out (channel 2) endpoints. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/ioport.h> -+#include <linux/slab.h> -+#include <linux/errno.h> -+#include <linux/init.h> -+#include <linux/list.h> -+#include <linux/interrupt.h> -+#include <linux/proc_fs.h> -+#include <linux/usb.h> -+#include <linux/usb/gadget.h> -+ -+#include <asm/byteorder.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <asm/system.h> -+#include <asm/jzsoc.h> -+ -+#include "jz4740_udc.h" -+ -+#define JZ_REG_UDC_FADDR 0x00 /* Function Address 8-bit */ -+#define JZ_REG_UDC_POWER 0x01 /* Power Managemetn 8-bit */ -+#define JZ_REG_UDC_INTRIN 0x02 /* Interrupt IN 16-bit */ -+#define JZ_REG_UDC_INTROUT 0x04 /* Interrupt OUT 16-bit */ -+#define JZ_REG_UDC_INTRINE 0x06 /* Intr IN enable 16-bit */ -+#define JZ_REG_UDC_INTROUTE 0x08 /* Intr OUT enable 16-bit */ -+#define JZ_REG_UDC_INTRUSB 0x0a /* Interrupt USB 8-bit */ -+#define JZ_REG_UDC_INTRUSBE 0x0b /* Interrupt USB Enable 8-bit */ -+#define JZ_REG_UDC_FRAME 0x0c /* Frame number 16-bit */ -+#define JZ_REG_UDC_INDEX 0x0e /* Index register 8-bit */ -+#define JZ_REG_UDC_TESTMODE 0x0f /* USB test mode 8-bit */ -+ -+#define JZ_REG_UDC_CSR0 0x12 /* EP0 CSR 8-bit */ -+#define JZ_REG_UDC_INMAXP 0x10 /* EP1-2 IN Max Pkt Size 16-bit */ -+#define JZ_REG_UDC_INCSR 0x12 /* EP1-2 IN CSR LSB 8/16bit */ -+#define JZ_REG_UDC_INCSRH 0x13 /* EP1-2 IN CSR MSB 8-bit */ -+#define JZ_REG_UDC_OUTMAXP 0x14 /* EP1 OUT Max Pkt Size 16-bit */ -+#define JZ_REG_UDC_OUTCSR 0x16 /* EP1 OUT CSR LSB 8/16bit */ -+#define JZ_REG_UDC_OUTCSRH 0x17 /* EP1 OUT CSR MSB 8-bit */ -+#define JZ_REG_UDC_OUTCOUNT 0x18 /* bytes in EP0/1 OUT FIFO 16-bit */ -+ -+#define JZ_REG_UDC_EP_FIFO(x) (4 * (x) + 0x20) -+ -+#define JZ_REG_UDC_EPINFO 0x78 /* Endpoint information */ -+#define JZ_REG_UDC_RAMINFO 0x79 /* RAM information */ -+ -+#define JZ_REG_UDC_INTR 0x200 /* DMA pending interrupts */ -+#define JZ_REG_UDC_CNTL1 0x204 /* DMA channel 1 control */ -+#define JZ_REG_UDC_ADDR1 0x208 /* DMA channel 1 AHB memory addr */ -+#define JZ_REG_UDC_COUNT1 0x20c /* DMA channel 1 byte count */ -+#define JZ_REG_UDC_CNTL2 0x214 /* DMA channel 2 control */ -+#define JZ_REG_UDC_ADDR2 0x218 /* DMA channel 2 AHB memory addr */ -+#define JZ_REG_UDC_COUNT2 0x21c /* DMA channel 2 byte count */ -+ -+#ifndef DEBUG -+# define DEBUG(fmt,args...) do {} while(0) -+#endif -+#ifndef DEBUG_EP0 -+# define NO_STATES -+# define DEBUG_EP0(fmt,args...) do {} while(0) -+#endif -+#ifndef DEBUG_SETUP -+# define DEBUG_SETUP(fmt,args...) do {} while(0) -+#endif -+ -+static unsigned int udc_debug = 0; /* 0: normal mode, 1: test udc cable type mode */ -+ -+module_param(udc_debug, int, 0); -+MODULE_PARM_DESC(udc_debug, "test udc cable or power type"); -+ -+static unsigned int use_dma = 0; /* 1: use DMA, 0: use PIO */ -+ -+module_param(use_dma, int, 0); -+MODULE_PARM_DESC(use_dma, "DMA mode enable flag"); -+ -+struct jz4740_udc *the_controller; -+ -+/* -+ * Local declarations. -+ */ -+static void jz4740_ep0_kick(struct jz4740_udc *dev, struct jz4740_ep *ep); -+static void jz4740_handle_ep0(struct jz4740_udc *dev, uint32_t intr); -+ -+static void done(struct jz4740_ep *ep, struct jz4740_request *req, -+ int status); -+static void pio_irq_enable(struct jz4740_ep *ep); -+static void pio_irq_disable(struct jz4740_ep *ep); -+static void stop_activity(struct jz4740_udc *dev, -+ struct usb_gadget_driver *driver); -+static void nuke(struct jz4740_ep *ep, int status); -+static void flush(struct jz4740_ep *ep); -+static void udc_set_address(struct jz4740_udc *dev, unsigned char address); -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* inline functions of register read/write/set/clear */ -+ -+static inline uint8_t usb_readb(struct jz4740_udc *udc, size_t reg) -+{ -+ return readb(udc->base + reg); -+} -+ -+static inline uint16_t usb_readw(struct jz4740_udc *udc, size_t reg) -+{ -+ return readw(udc->base + reg); -+} -+ -+static inline uint32_t usb_readl(struct jz4740_udc *udc, size_t reg) -+{ -+ return readl(udc->base + reg); -+} -+ -+static inline void usb_writeb(struct jz4740_udc *udc, size_t reg, uint8_t val) -+{ -+ writeb(val, udc->base + reg); -+} -+ -+static inline void usb_writew(struct jz4740_udc *udc, size_t reg, uint16_t val) -+{ -+ writew(val, udc->base + reg); -+} -+ -+static inline void usb_writel(struct jz4740_udc *udc, size_t reg, uint32_t val) -+{ -+ writel(val, udc->base + reg); -+} -+ -+static inline void usb_setb(struct jz4740_udc *udc, size_t reg, uint8_t mask) -+{ -+ usb_writeb(udc, reg, usb_readb(udc, reg) | mask); -+} -+ -+static inline void usb_setw(struct jz4740_udc *udc, size_t reg, uint8_t mask) -+{ -+ usb_writew(udc, reg, usb_readw(udc, reg) | mask); -+} -+ -+static inline void usb_setl(struct jz4740_udc *udc, size_t reg, uint32_t mask) -+{ -+ usb_writel(udc, reg, usb_readl(udc, reg) | mask); -+} -+ -+static inline void usb_clearb(struct jz4740_udc *udc, size_t reg, uint8_t mask) -+{ -+ usb_writeb(udc, reg, usb_readb(udc, reg) & ~mask); -+} -+ -+static inline void usb_clearw(struct jz4740_udc *udc, size_t reg, uint16_t mask) -+{ -+ usb_writew(udc, reg, usb_readw(udc, reg) & ~mask); -+} -+ -+static inline void usb_clearl(struct jz4740_udc *udc, size_t reg, uint32_t mask) -+{ -+ usb_writel(udc, reg, usb_readl(udc, reg) & ~mask); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static inline void jz_udc_set_index(struct jz4740_udc *udc, uint8_t index) -+{ -+ usb_writeb(udc, JZ_REG_UDC_INDEX, index); -+} -+ -+static inline void jz_udc_select_ep(struct jz4740_ep *ep) -+{ -+ jz_udc_set_index(ep->dev, ep_index(ep)); -+} -+ -+static inline int write_packet(struct jz4740_ep *ep, -+ struct jz4740_request *req, int max) -+{ -+ uint8_t *buf; -+ int length, nlong, nbyte; -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ buf = req->req.buf + req->req.actual; -+ prefetch(buf); -+ -+ length = req->req.length - req->req.actual; -+ length = min(length, max); -+ req->req.actual += length; -+ -+ DEBUG("Write %d (max %d), fifo %x\n", length, max, ep->fifo); -+ -+ nlong = length >> 2; -+ nbyte = length & 0x3; -+ while (nlong--) { -+ usb_writel(ep->dev, ep->fifo, *((uint32_t *)buf)); -+ buf += 4; -+ } -+ while (nbyte--) { -+ usb_writeb(ep->dev, ep->fifo, *buf++); -+ } -+ -+ return length; -+} -+ -+static inline int read_packet(struct jz4740_ep *ep, -+ struct jz4740_request *req, int count) -+{ -+ uint8_t *buf; -+ int length, nlong, nbyte; -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ buf = req->req.buf + req->req.actual; -+ prefetchw(buf); -+ -+ length = req->req.length - req->req.actual; -+ length = min(length, count); -+ req->req.actual += length; -+ -+ DEBUG("Read %d, fifo %x\n", length, ep->fifo); -+ -+ nlong = length >> 2; -+ nbyte = length & 0x3; -+ while (nlong--) { -+ *((uint32_t *)buf) = usb_readl(ep->dev, ep->fifo); -+ buf += 4; -+ } -+ while (nbyte--) { -+ *buf++ = usb_readb(ep->dev, ep->fifo); -+ } -+ -+ return length; -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* -+ * udc_disable - disable USB device controller -+ */ -+static void udc_disable(struct jz4740_udc *dev) -+{ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ udc_set_address(dev, 0); -+ -+ /* Disable interrupts */ -+ usb_writew(dev, JZ_REG_UDC_INTRINE, 0); -+ usb_writew(dev, JZ_REG_UDC_INTROUTE, 0); -+ usb_writeb(dev, JZ_REG_UDC_INTRUSBE, 0); -+ -+ /* Disable DMA */ -+ usb_writel(dev, JZ_REG_UDC_CNTL1, 0); -+ usb_writel(dev, JZ_REG_UDC_CNTL2, 0); -+ -+ /* Disconnect from usb */ -+ usb_clearb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN); -+ -+ /* Disable the USB PHY */ -+#ifdef CONFIG_SOC_JZ4740 -+ REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE; -+#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) -+ REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE; -+#endif -+ -+ dev->ep0state = WAIT_FOR_SETUP; -+ dev->gadget.speed = USB_SPEED_UNKNOWN; -+ -+ return; -+} -+ -+/* -+ * udc_reinit - initialize software state -+ */ -+static void udc_reinit(struct jz4740_udc *dev) -+{ -+ int i; -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ /* device/ep0 records init */ -+ INIT_LIST_HEAD(&dev->gadget.ep_list); -+ INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); -+ dev->ep0state = WAIT_FOR_SETUP; -+ -+ for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { -+ struct jz4740_ep *ep = &dev->ep[i]; -+ -+ if (i != 0) -+ list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); -+ -+ INIT_LIST_HEAD(&ep->queue); -+ ep->desc = 0; -+ ep->stopped = 0; -+ ep->pio_irqs = 0; -+ } -+} -+ -+/* until it's enabled, this UDC should be completely invisible -+ * to any USB host. -+ */ -+static void udc_enable(struct jz4740_udc *dev) -+{ -+ int i; -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ /* UDC state is incorrect - Added by River */ -+ if (dev->state != UDC_STATE_ENABLE) { -+ return; -+ } -+ -+ dev->gadget.speed = USB_SPEED_UNKNOWN; -+ -+ /* Flush FIFO for each */ -+ for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { -+ struct jz4740_ep *ep = &dev->ep[i]; -+ -+ jz_udc_set_index(dev, ep_index(ep)); -+ flush(ep); -+ } -+ -+ /* Set this bit to allow the UDC entering low-power mode when -+ * there are no actions on the USB bus. -+ * UDC still works during this bit was set. -+ */ -+ __cpm_stop_udc(); -+ -+ /* Enable the USB PHY */ -+#ifdef CONFIG_SOC_JZ4740 -+ REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; -+#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) -+ REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE; -+#endif -+ -+ /* Disable interrupts */ -+/* usb_writew(dev, JZ_REG_UDC_INTRINE, 0); -+ usb_writew(dev, JZ_REG_UDC_INTROUTE, 0); -+ usb_writeb(dev, JZ_REG_UDC_INTRUSBE, 0);*/ -+ -+ /* Enable interrupts */ -+ usb_setw(dev, JZ_REG_UDC_INTRINE, USB_INTR_EP0); -+ usb_setb(dev, JZ_REG_UDC_INTRUSBE, USB_INTR_RESET); -+ /* Don't enable rest of the interrupts */ -+ /* usb_setw(dev, JZ_REG_UDC_INTRINE, USB_INTR_INEP1 | USB_INTR_INEP2); -+ usb_setw(dev, JZ_REG_UDC_INTROUTE, USB_INTR_OUTEP1); */ -+ -+ /* Enable SUSPEND */ -+ /* usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_SUSPENDM); */ -+ -+ /* Enable HS Mode */ -+ usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_HSENAB); -+ -+ /* Let host detect UDC: -+ * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this -+ * transistor on and pull the USBDP pin HIGH. -+ */ -+ usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN); -+ -+ return; -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* keeping it simple: -+ * - one bus driver, initted first; -+ * - one function driver, initted second -+ */ -+ -+/* -+ * Register entry point for the peripheral controller driver. -+ */ -+ -+int usb_gadget_register_driver(struct usb_gadget_driver *driver) -+{ -+ struct jz4740_udc *dev = the_controller; -+ int retval; -+ -+ if (!driver || !driver->bind) { -+ return -EINVAL; -+ } -+ -+ if (!dev) { -+ return -ENODEV; -+ } -+ -+ if (dev->driver) { -+ return -EBUSY; -+ } -+ -+ /* hook up the driver */ -+ dev->driver = driver; -+ dev->gadget.dev.driver = &driver->driver; -+ -+ retval = driver->bind(&dev->gadget); -+ if (retval) { -+ DEBUG("%s: bind to driver %s --> error %d\n", dev->gadget.name, -+ driver->driver.name, retval); -+ dev->driver = 0; -+ return retval; -+ } -+ -+ /* then enable host detection and ep0; and we're ready -+ * for set_configuration as well as eventual disconnect. -+ */ -+ udc_enable(dev); -+ -+ DEBUG("%s: registered gadget driver '%s'\n", dev->gadget.name, -+ driver->driver.name); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(usb_gadget_register_driver); -+ -+static void stop_activity(struct jz4740_udc *dev, -+ struct usb_gadget_driver *driver) -+{ -+ int i; -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ /* don't disconnect drivers more than once */ -+ if (dev->gadget.speed == USB_SPEED_UNKNOWN) -+ driver = 0; -+ dev->gadget.speed = USB_SPEED_UNKNOWN; -+ -+ /* prevent new request submissions, kill any outstanding requests */ -+ for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { -+ struct jz4740_ep *ep = &dev->ep[i]; -+ -+ ep->stopped = 1; -+ -+ jz_udc_set_index(dev, ep_index(ep)); -+ nuke(ep, -ESHUTDOWN); -+ } -+ -+ /* report disconnect; the driver is already quiesced */ -+ if (driver) { -+ spin_unlock(&dev->lock); -+ driver->disconnect(&dev->gadget); -+ spin_lock(&dev->lock); -+ } -+ -+ /* re-init driver-visible data structures */ -+ udc_reinit(dev); -+} -+ -+ -+/* -+ * Unregister entry point for the peripheral controller driver. -+ */ -+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -+{ -+ struct jz4740_udc *dev = the_controller; -+ unsigned long flags; -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ if (!dev) -+ return -ENODEV; -+ if (!driver || driver != dev->driver) -+ return -EINVAL; -+ if (!driver->unbind) -+ return -EBUSY; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->driver = 0; -+ stop_activity(dev, driver); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ driver->unbind(&dev->gadget); -+ -+ udc_disable(dev); -+ -+ DEBUG("unregistered driver '%s'\n", driver->driver.name); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(usb_gadget_unregister_driver); -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* -+ * Starting DMA using mode 1 -+ */ -+static void kick_dma(struct jz4740_ep *ep, struct jz4740_request *req) -+{ -+ struct jz4740_udc *dev = ep->dev; -+ uint32_t count = req->req.length; -+ uint32_t physaddr = virt_to_phys((void *)req->req.buf); -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ jz_udc_select_ep(ep); -+ -+ if (ep_is_in(ep)) { /* Bulk-IN transfer using DMA channel 1 */ -+ ep->reg_addr = JZ_REG_UDC_ADDR1; -+ -+ dma_cache_wback_inv((unsigned long)req->req.buf, count); -+ -+ pio_irq_enable(ep); -+ -+ usb_writeb(dev, JZ_REG_UDC_INCSRH, -+ USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE); -+ -+ usb_writel(dev, JZ_REG_UDC_ADDR1, physaddr); -+ usb_writel(dev, JZ_REG_UDC_COUNT1, count); -+ usb_writel(dev, JZ_REG_UDC_CNTL1, USB_CNTL_ENA | USB_CNTL_DIR_IN | USB_CNTL_MODE_1 | -+ USB_CNTL_INTR_EN | USB_CNTL_BURST_16 | USB_CNTL_EP(ep_index(ep))); -+ } -+ else { /* Bulk-OUT transfer using DMA channel 2 */ -+ ep->reg_addr = JZ_REG_UDC_ADDR2; -+ -+ dma_cache_wback_inv((unsigned long)req->req.buf, count); -+ -+ pio_irq_enable(ep); -+ -+ usb_setb(dev, JZ_REG_UDC_OUTCSRH, -+ USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); -+ -+ usb_writel(dev, JZ_REG_UDC_ADDR2, physaddr); -+ usb_writel(dev, JZ_REG_UDC_COUNT2, count); -+ usb_writel(dev, JZ_REG_UDC_CNTL2, USB_CNTL_ENA | USB_CNTL_MODE_1 | -+ USB_CNTL_INTR_EN | USB_CNTL_BURST_16 | USB_CNTL_EP(ep_index(ep))); -+ } -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+/** Write request to FIFO (max write == maxp size) -+ * Return: 0 = still running, 1 = completed, negative = errno -+ * NOTE: INDEX register must be set for EP -+ */ -+static int write_fifo(struct jz4740_ep *ep, struct jz4740_request *req) -+{ -+ struct jz4740_udc *dev = ep->dev; -+ uint32_t max, csr; -+ uint32_t physaddr = virt_to_phys((void *)req->req.buf); -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ max = le16_to_cpu(ep->desc->wMaxPacketSize); -+ -+ if (use_dma) { -+ uint32_t dma_count; -+ -+ /* DMA interrupt generated due to the last packet loaded into the FIFO */ -+ -+ dma_count = usb_readl(dev, ep->reg_addr) - physaddr; -+ req->req.actual += dma_count; -+ -+ if (dma_count % max) { -+ /* If the last packet is less than MAXP, set INPKTRDY manually */ -+ usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY); -+ } -+ -+ done(ep, req, 0); -+ if (list_empty(&ep->queue)) { -+ pio_irq_disable(ep); -+ return 1; -+ } -+ else { -+ /* advance the request queue */ -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ kick_dma(ep, req); -+ return 0; -+ } -+ } -+ -+ /* -+ * PIO mode handling starts here ... -+ */ -+ -+ csr = usb_readb(dev, ep->csr); -+ -+ if (!(csr & USB_INCSR_FFNOTEMPT)) { -+ unsigned count; -+ int is_last, is_short; -+ -+ count = write_packet(ep, req, max); -+ usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY); -+ -+ /* last packet is usually short (or a zlp) */ -+ if (unlikely(count != max)) -+ is_last = is_short = 1; -+ else { -+ if (likely(req->req.length != req->req.actual) -+ || req->req.zero) -+ is_last = 0; -+ else -+ is_last = 1; -+ /* interrupt/iso maxpacket may not fill the fifo */ -+ is_short = unlikely(max < ep_maxpacket(ep)); -+ } -+ -+ DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__, -+ ep->ep.name, count, -+ is_last ? "/L" : "", is_short ? "/S" : "", -+ req->req.length - req->req.actual, req); -+ -+ /* requests complete when all IN data is in the FIFO */ -+ if (is_last) { -+ done(ep, req, 0); -+ if (list_empty(&ep->queue)) { -+ pio_irq_disable(ep); -+ } -+ return 1; -+ } -+ } else { -+ DEBUG("Hmm.. %d ep FIFO is not empty!\n", ep_index(ep)); -+ } -+ -+ return 0; -+} -+ -+/** Read to request from FIFO (max read == bytes in fifo) -+ * Return: 0 = still running, 1 = completed, negative = errno -+ * NOTE: INDEX register must be set for EP -+ */ -+static int read_fifo(struct jz4740_ep *ep, struct jz4740_request *req) -+{ -+ struct jz4740_udc *dev = ep->dev; -+ uint32_t csr; -+ unsigned count, is_short; -+ uint32_t physaddr = virt_to_phys((void *)req->req.buf); -+ -+ if (use_dma) { -+ uint32_t dma_count; -+ -+ /* DMA interrupt generated due to a packet less than MAXP loaded into the FIFO */ -+ -+ dma_count = usb_readl(dev, ep->reg_addr) - physaddr; -+ req->req.actual += dma_count; -+ -+ /* Disable interrupt and DMA */ -+ pio_irq_disable(ep); -+ usb_writel(dev, JZ_REG_UDC_CNTL2, 0); -+ -+ /* Read all bytes from this packet */ -+ count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT); -+ count = read_packet(ep, req, count); -+ -+ if (count) { -+ /* If the last packet is greater than zero, clear OUTPKTRDY manually */ -+ usb_clearb(dev, ep->csr, USB_OUTCSR_OUTPKTRDY); -+ } -+ done(ep, req, 0); -+ -+ if (!list_empty(&ep->queue)) { -+ /* advance the request queue */ -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ kick_dma(ep, req); -+ } -+ -+ return 1; -+ } -+ -+ /* -+ * PIO mode handling starts here ... -+ */ -+ -+ /* make sure there's a packet in the FIFO. */ -+ csr = usb_readb(dev, ep->csr); -+ if (!(csr & USB_OUTCSR_OUTPKTRDY)) { -+ DEBUG("%s: Packet NOT ready!\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ /* read all bytes from this packet */ -+ count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT); -+ -+ is_short = (count < ep->ep.maxpacket); -+ -+ count = read_packet(ep, req, count); -+ -+ DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n", -+ ep->ep.name, csr, count, -+ is_short ? "/S" : "", req, req->req.actual, req->req.length); -+ -+ /* Clear OutPktRdy */ -+ usb_clearb(dev, ep->csr, USB_OUTCSR_OUTPKTRDY); -+ -+ /* completion */ -+ if (is_short || req->req.actual == req->req.length) { -+ done(ep, req, 0); -+ -+ if (list_empty(&ep->queue)) -+ pio_irq_disable(ep); -+ return 1; -+ } -+ -+ /* finished that packet. the next one may be waiting... */ -+ return 0; -+} -+ -+/* -+ * done - retire a request; caller blocked irqs -+ * INDEX register is preserved to keep same -+ */ -+static void done(struct jz4740_ep *ep, struct jz4740_request *req, int status) -+{ -+ unsigned int stopped = ep->stopped; -+ unsigned long flags; -+ uint32_t index; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, ep); -+ list_del_init(&req->queue); -+ -+ if (likely(req->req.status == -EINPROGRESS)) -+ req->req.status = status; -+ else -+ status = req->req.status; -+ -+ if (status && status != -ESHUTDOWN) -+ DEBUG("complete %s req %p stat %d len %u/%u\n", -+ ep->ep.name, &req->req, status, -+ req->req.actual, req->req.length); -+ -+ /* don't modify queue heads during completion callback */ -+ ep->stopped = 1; -+ /* Read current index (completion may modify it) */ -+ spin_lock_irqsave(&ep->dev->lock, flags); -+ index = usb_readb(ep->dev, JZ_REG_UDC_INDEX); -+ -+ req->req.complete(&ep->ep, &req->req); -+ -+ /* Restore index */ -+ jz_udc_set_index(ep->dev, index); -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+ ep->stopped = stopped; -+} -+ -+/** Enable EP interrupt */ -+static void pio_irq_enable(struct jz4740_ep *ep) -+{ -+ uint8_t index = ep_index(ep); -+ struct jz4740_udc *dev = ep->dev; -+ DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT"); -+ -+ if (ep_is_in(ep)) { -+ switch (index) { -+ case 1: -+ case 2: -+ usb_setw(dev, JZ_REG_UDC_INTRINE, BIT(index)); -+ dev->in_mask |= BIT(index); -+ break; -+ default: -+ DEBUG("Unknown endpoint: %d\n", index); -+ break; -+ } -+ } -+ else { -+ switch (index) { -+ case 1: -+ usb_setw(dev, JZ_REG_UDC_INTROUTE, BIT(index)); -+ dev->out_mask |= BIT(index); -+ break; -+ default: -+ DEBUG("Unknown endpoint: %d\n", index); -+ break; -+ } -+ } -+} -+ -+/** Disable EP interrupt */ -+static void pio_irq_disable(struct jz4740_ep *ep) -+{ -+ uint8_t index = ep_index(ep); -+ struct jz4740_udc *dev = ep->dev; -+ -+ DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT"); -+ -+ if (ep_is_in(ep)) { -+ switch (ep_index(ep)) { -+ case 1: -+ case 2: -+ usb_clearw(ep->dev, JZ_REG_UDC_INTRINE, BIT(index)); -+ dev->in_mask &= ~BIT(index); -+ break; -+ default: -+ DEBUG("Unknown endpoint: %d\n", index); -+ break; -+ } -+ } -+ else { -+ switch (ep_index(ep)) { -+ case 1: -+ usb_clearw(ep->dev, JZ_REG_UDC_INTROUTE, BIT(index)); -+ dev->out_mask &= ~BIT(index); -+ break; -+ default: -+ DEBUG("Unknown endpoint: %d\n", index); -+ break; -+ } -+ } -+} -+ -+/* -+ * nuke - dequeue ALL requests -+ */ -+static void nuke(struct jz4740_ep *ep, int status) -+{ -+ struct jz4740_request *req; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, ep); -+ -+ /* Flush FIFO */ -+ flush(ep); -+ -+ /* called with irqs blocked */ -+ while (!list_empty(&ep->queue)) { -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ done(ep, req, status); -+ } -+ -+ /* Disable IRQ if EP is enabled (has descriptor) */ -+ if (ep->desc) -+ pio_irq_disable(ep); -+} -+ -+/** Flush EP FIFO -+ * NOTE: INDEX register must be set before this call -+ */ -+static void flush(struct jz4740_ep *ep) -+{ -+ DEBUG("%s: %s\n", __FUNCTION__, ep->ep.name); -+ -+ switch (ep->type) { -+ case ep_bulk_in: -+ case ep_interrupt: -+ usb_setb(ep->dev, ep->csr, USB_INCSR_FF); -+ break; -+ case ep_bulk_out: -+ usb_setb(ep->dev, ep->csr, USB_OUTCSR_FF); -+ break; -+ case ep_control: -+ break; -+ } -+} -+ -+/** -+ * jz4740_in_epn - handle IN interrupt -+ */ -+static void jz4740_in_epn(struct jz4740_udc *dev, uint32_t ep_idx, uint32_t intr) -+{ -+ uint32_t csr; -+ struct jz4740_ep *ep = &dev->ep[ep_idx + 1]; -+ struct jz4740_request *req; -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ jz_udc_set_index(dev, ep_index(ep)); -+ -+ csr = usb_readb(dev, ep->csr); -+ DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr); -+ -+ if (csr & USB_INCSR_SENTSTALL) { -+ DEBUG("USB_INCSR_SENTSTALL\n"); -+ usb_clearb(dev, ep->csr, USB_INCSR_SENTSTALL); -+ return; -+ } -+ -+ if (!ep->desc) { -+ DEBUG("%s: NO EP DESC\n", __FUNCTION__); -+ return; -+ } -+ -+ if (list_empty(&ep->queue)) -+ req = 0; -+ else -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ -+ DEBUG("req: %p\n", req); -+ -+ if (!req) -+ return; -+ -+ write_fifo(ep, req); -+} -+ -+/* -+ * Bulk OUT (recv) -+ */ -+static void jz4740_out_epn(struct jz4740_udc *dev, uint32_t ep_idx, uint32_t intr) -+{ -+ struct jz4740_ep *ep = &dev->ep[ep_idx]; -+ struct jz4740_request *req; -+ -+ DEBUG("%s: %d\n", __FUNCTION__, ep_idx); -+ -+ jz_udc_set_index(dev, ep_index(ep)); -+ if (ep->desc) { -+ uint32_t csr; -+ -+ if (use_dma) { -+ /* DMA starts here ... */ -+ if (list_empty(&ep->queue)) -+ req = 0; -+ else -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ -+ if (req) -+ read_fifo(ep, req); -+ return; -+ } -+ -+ /* -+ * PIO mode starts here ... -+ */ -+ -+ while ((csr = usb_readb(dev, ep->csr)) & -+ (USB_OUTCSR_OUTPKTRDY | USB_OUTCSR_SENTSTALL)) { -+ DEBUG("%s: %x\n", __FUNCTION__, csr); -+ -+ if (csr & USB_OUTCSR_SENTSTALL) { -+ DEBUG("%s: stall sent, flush fifo\n", -+ __FUNCTION__); -+ /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */ -+ flush(ep); -+ } else if (csr & USB_OUTCSR_OUTPKTRDY) { -+ if (list_empty(&ep->queue)) -+ req = 0; -+ else -+ req = -+ list_entry(ep->queue.next, -+ struct jz4740_request, -+ queue); -+ -+ if (!req) { -+ DEBUG("%s: NULL REQ %d\n", -+ __FUNCTION__, ep_idx); -+ break; -+ } else { -+ read_fifo(ep, req); -+ } -+ } -+ } -+ } else { -+ /* Throw packet away.. */ -+ DEBUG("%s: ep %p ep_indx %d No descriptor?!?\n", __FUNCTION__, ep, ep_idx); -+ flush(ep); -+ } -+} -+ -+/** Halt specific EP -+ * Return 0 if success -+ * NOTE: Sets INDEX register to EP ! -+ */ -+static int jz4740_set_halt(struct usb_ep *_ep, int value) -+{ -+ struct jz4740_udc *dev; -+ struct jz4740_ep *ep; -+ unsigned long flags; -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (unlikely(!_ep || (!ep->desc && ep->type != ep_control))) { -+ DEBUG("%s, bad ep\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dev = ep->dev; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ jz_udc_select_ep(ep); -+ -+ DEBUG("%s, ep %d, val %d\n", __FUNCTION__, ep_index(ep), value); -+ -+ if (ep_index(ep) == 0) { -+ /* EP0 */ -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SENDSTALL); -+ } else if (ep_is_in(ep)) { -+ uint32_t csr = usb_readb(dev, ep->csr); -+ if (value && ((csr & USB_INCSR_FFNOTEMPT) -+ || !list_empty(&ep->queue))) { -+ /* -+ * Attempts to halt IN endpoints will fail (returning -EAGAIN) -+ * if any transfer requests are still queued, or if the controller -+ * FIFO still holds bytes that the host hasnÂ’t collected. -+ */ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ DEBUG -+ ("Attempt to halt IN endpoint failed (returning -EAGAIN) %d %d\n", -+ (csr & USB_INCSR_FFNOTEMPT), -+ !list_empty(&ep->queue)); -+ return -EAGAIN; -+ } -+ flush(ep); -+ if (value) { -+ usb_setb(dev, ep->csr, USB_INCSR_SENDSTALL); -+ } -+ else { -+ usb_clearb(dev, ep->csr, USB_INCSR_SENDSTALL); -+ usb_setb(dev, ep->csr, USB_INCSR_CDT); -+ } -+ } else { -+ -+ flush(ep); -+ if (value) { -+ usb_setb(dev, ep->csr, USB_OUTCSR_SENDSTALL); -+ } -+ else { -+ usb_clearb(dev, ep->csr, USB_OUTCSR_SENDSTALL); -+ usb_setb(dev, ep->csr, USB_OUTCSR_CDT); -+ } -+ } -+ -+ if (value) { -+ ep->stopped = 1; -+ } else { -+ ep->stopped = 0; -+ } -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ DEBUG("%s %s halted\n", _ep->name, value == 0 ? "NOT" : "IS"); -+ -+ return 0; -+} -+ -+ -+static int jz4740_ep_enable(struct usb_ep *_ep, -+ const struct usb_endpoint_descriptor *desc) -+{ -+ struct jz4740_ep *ep; -+ struct jz4740_udc *dev; -+ unsigned long flags; -+ uint32_t max, csrh = 0; -+ -+ DEBUG("%s: trying to enable %s\n", __FUNCTION__, _ep->name); -+ -+ if (!_ep || !desc) -+ return -EINVAL; -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (ep->desc || ep->type == ep_control -+ || desc->bDescriptorType != USB_DT_ENDPOINT -+ || ep->bEndpointAddress != desc->bEndpointAddress) { -+ DEBUG("%s, bad ep or descriptor\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ /* xfer types must match, except that interrupt ~= bulk */ -+ if (ep->bmAttributes != desc->bmAttributes -+ && ep->bmAttributes != USB_ENDPOINT_XFER_BULK -+ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { -+ DEBUG("%s, %s type mismatch\n", __FUNCTION__, _ep->name); -+ return -EINVAL; -+ } -+ -+ dev = ep->dev; -+ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { -+ DEBUG("%s, bogus device state\n", __FUNCTION__); -+ return -ESHUTDOWN; -+ } -+ -+ max = le16_to_cpu(desc->wMaxPacketSize); -+ -+ spin_lock_irqsave(&ep->dev->lock, flags); -+ -+ /* Configure the endpoint */ -+ jz_udc_set_index(dev, desc->bEndpointAddress & 0x0F); -+ if (ep_is_in(ep)) { -+ usb_writew(dev, JZ_REG_UDC_INMAXP, max); -+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { -+ case USB_ENDPOINT_XFER_BULK: -+ case USB_ENDPOINT_XFER_INT: -+ csrh &= ~USB_INCSRH_ISO; -+ break; -+ case USB_ENDPOINT_XFER_ISOC: -+ csrh |= USB_INCSRH_ISO; -+ break; -+ } -+ usb_writeb(dev, JZ_REG_UDC_INCSRH, csrh); -+ } -+ else { -+ usb_writew(dev, JZ_REG_UDC_OUTMAXP, max); -+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { -+ case USB_ENDPOINT_XFER_BULK: -+ csrh &= ~USB_OUTCSRH_ISO; -+ break; -+ case USB_ENDPOINT_XFER_INT: -+ csrh &= ~USB_OUTCSRH_ISO; -+ csrh |= USB_OUTCSRH_DNYT; -+ break; -+ case USB_ENDPOINT_XFER_ISOC: -+ csrh |= USB_OUTCSRH_ISO; -+ break; -+ } -+ usb_writeb(dev, JZ_REG_UDC_OUTCSRH, csrh); -+ } -+ -+ -+ ep->stopped = 0; -+ ep->desc = desc; -+ ep->pio_irqs = 0; -+ ep->ep.maxpacket = max; -+ -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+ -+ /* Reset halt state (does flush) */ -+ jz4740_set_halt(_ep, 0); -+ -+ DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name); -+ -+ return 0; -+} -+ -+/** Disable EP -+ * NOTE: Sets INDEX register -+ */ -+static int jz4740_ep_disable(struct usb_ep *_ep) -+{ -+ struct jz4740_ep *ep; -+ unsigned long flags; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, _ep); -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (!_ep || !ep->desc) { -+ DEBUG("%s, %s not enabled\n", __FUNCTION__, -+ _ep ? ep->ep.name : NULL); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&ep->dev->lock, flags); -+ -+ jz_udc_select_ep(ep); -+ -+ /* Nuke all pending requests (does flush) */ -+ nuke(ep, -ESHUTDOWN); -+ -+ /* Disable ep IRQ */ -+ pio_irq_disable(ep); -+ -+ ep->desc = 0; -+ ep->stopped = 1; -+ -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+ -+ DEBUG("%s: disabled %s\n", __FUNCTION__, _ep->name); -+ return 0; -+} -+ -+static struct usb_request *jz4740_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) -+{ -+ struct jz4740_request *req; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, ep); -+ -+ req = kzalloc(sizeof(*req), gfp_flags); -+ if (!req) -+ return 0; -+ -+ INIT_LIST_HEAD(&req->queue); -+ -+ return &req->req; -+} -+ -+static void jz4740_free_request(struct usb_ep *ep, struct usb_request *_req) -+{ -+ struct jz4740_request *req; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, ep); -+ -+ req = container_of(_req, struct jz4740_request, req); -+ WARN_ON(!list_empty(&req->queue)); -+ kfree(req); -+} -+ -+/*--------------------------------------------------------------------*/ -+ -+/** Queue one request -+ * Kickstart transfer if needed -+ * NOTE: Sets INDEX register -+ */ -+static int jz4740_queue(struct usb_ep *_ep, struct usb_request *_req, -+ gfp_t gfp_flags) -+{ -+ struct jz4740_request *req; -+ struct jz4740_ep *ep; -+ struct jz4740_udc *dev; -+ unsigned long flags; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, _ep); -+ -+ req = container_of(_req, struct jz4740_request, req); -+ if (unlikely -+ (!_req || !_req->complete || !_req->buf -+ || !list_empty(&req->queue))) { -+ DEBUG("%s, bad params\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (unlikely(!_ep || (!ep->desc && ep->type != ep_control))) { -+ DEBUG("%s, bad ep\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dev = ep->dev; -+ if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { -+ DEBUG("%s, bogus device state %p\n", __FUNCTION__, dev->driver); -+ return -ESHUTDOWN; -+ } -+ -+ DEBUG("%s queue req %p, len %d buf %p\n", _ep->name, _req, _req->length, -+ _req->buf); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ _req->status = -EINPROGRESS; -+ _req->actual = 0; -+ -+ /* kickstart this i/o queue? */ -+ DEBUG("Add to %d Q %d %d\n", ep_index(ep), list_empty(&ep->queue), -+ ep->stopped); -+ if (list_empty(&ep->queue) && likely(!ep->stopped)) { -+ uint32_t csr; -+ -+ if (unlikely(ep_index(ep) == 0)) { -+ /* EP0 */ -+ list_add_tail(&req->queue, &ep->queue); -+ jz4740_ep0_kick(dev, ep); -+ req = 0; -+ } else if (use_dma) { -+ /* DMA */ -+ kick_dma(ep, req); -+ } -+ /* PIO */ -+ else if (ep_is_in(ep)) { -+ /* EP1 & EP2 */ -+ jz_udc_set_index(dev, ep_index(ep)); -+ csr = usb_readb(dev, ep->csr); -+ pio_irq_enable(ep); -+ if (!(csr & USB_INCSR_FFNOTEMPT)) { -+ if (write_fifo(ep, req) == 1) -+ req = 0; -+ } -+ } else { -+ /* EP1 */ -+ jz_udc_set_index(dev, ep_index(ep)); -+ csr = usb_readb(dev, ep->csr); -+ pio_irq_enable(ep); -+ if (csr & USB_OUTCSR_OUTPKTRDY) { -+ if (read_fifo(ep, req) == 1) -+ req = 0; -+ } -+ } -+ } -+ -+ /* pio or dma irq handler advances the queue. */ -+ if (likely(req != 0)) -+ list_add_tail(&req->queue, &ep->queue); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return 0; -+} -+ -+/* dequeue JUST ONE request */ -+static int jz4740_dequeue(struct usb_ep *_ep, struct usb_request *_req) -+{ -+ struct jz4740_ep *ep; -+ struct jz4740_request *req; -+ unsigned long flags; -+ -+ DEBUG("%s, %p\n", __FUNCTION__, _ep); -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (!_ep || ep->type == ep_control) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&ep->dev->lock, flags); -+ -+ /* make sure it's actually queued on this endpoint */ -+ list_for_each_entry(req, &ep->queue, queue) { -+ if (&req->req == _req) -+ break; -+ } -+ if (&req->req != _req) { -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+ return -EINVAL; -+ } -+ done(ep, req, -ECONNRESET); -+ -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+ return 0; -+} -+ -+/** Return bytes in EP FIFO -+ * NOTE: Sets INDEX register to EP -+ */ -+static int jz4740_fifo_status(struct usb_ep *_ep) -+{ -+ uint32_t csr; -+ int count = 0; -+ struct jz4740_ep *ep; -+ unsigned long flags; -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (!_ep) { -+ DEBUG("%s, bad ep\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ DEBUG("%s, %d\n", __FUNCTION__, ep_index(ep)); -+ -+ /* LPD can't report unclaimed bytes from IN fifos */ -+ if (ep_is_in(ep)) -+ return -EOPNOTSUPP; -+ -+ spin_lock_irqsave(&ep->dev->lock, flags); -+ jz_udc_set_index(ep->dev, ep_index(ep)); -+ -+ csr = usb_readb(ep->dev, ep->csr); -+ if (ep->dev->gadget.speed != USB_SPEED_UNKNOWN || -+ csr & 0x1) { -+ count = usb_readw(ep->dev, JZ_REG_UDC_OUTCOUNT); -+ } -+ -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+ -+ return count; -+} -+ -+/** Flush EP FIFO -+ * NOTE: Sets INDEX register to EP -+ */ -+static void jz4740_fifo_flush(struct usb_ep *_ep) -+{ -+ struct jz4740_ep *ep; -+ unsigned long flags; -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ ep = container_of(_ep, struct jz4740_ep, ep); -+ if (unlikely(!_ep || (!ep->desc && ep->type == ep_control))) { -+ DEBUG("%s, bad ep\n", __FUNCTION__); -+ return; -+ } -+ -+ spin_lock_irqsave(&ep->dev->lock, flags); -+ -+ jz_udc_set_index(ep->dev, ep_index(ep)); -+ flush(ep); -+ -+ spin_unlock_irqrestore(&ep->dev->lock, flags); -+} -+ -+/****************************************************************/ -+/* End Point 0 related functions */ -+/****************************************************************/ -+ -+/* return: 0 = still running, 1 = completed, negative = errno */ -+static int write_fifo_ep0(struct jz4740_ep *ep, struct jz4740_request *req) -+{ -+ uint32_t max; -+ unsigned count; -+ int is_last; -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ max = ep_maxpacket(ep); -+ -+ count = write_packet(ep, req, max); -+ -+ /* last packet is usually short (or a zlp) */ -+ if (unlikely(count != max)) -+ is_last = 1; -+ else { -+ if (likely(req->req.length != req->req.actual) || req->req.zero) -+ is_last = 0; -+ else -+ is_last = 1; -+ } -+ -+ DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __FUNCTION__, -+ ep->ep.name, count, -+ is_last ? "/L" : "", req->req.length - req->req.actual, req); -+ -+ /* requests complete when all IN data is in the FIFO */ -+ if (is_last) { -+ done(ep, req, 0); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static inline int jz4740_fifo_read(struct jz4740_ep *ep, -+ unsigned char *cp, int max) -+{ -+ int bytes; -+ int count = usb_readw(ep->dev, JZ_REG_UDC_OUTCOUNT); -+ -+ if (count > max) -+ count = max; -+ bytes = count; -+ while (count--) -+ *cp++ = usb_readb(ep->dev, ep->fifo); -+ -+ return bytes; -+} -+ -+static inline void jz4740_fifo_write(struct jz4740_ep *ep, -+ unsigned char *cp, int count) -+{ -+ DEBUG("fifo_write: %d %d\n", ep_index(ep), count); -+ while (count--) -+ usb_writeb(ep->dev, ep->fifo, *cp++); -+} -+ -+static int read_fifo_ep0(struct jz4740_ep *ep, struct jz4740_request *req) -+{ -+ struct jz4740_udc *dev = ep->dev; -+ uint32_t csr; -+ uint8_t *buf; -+ unsigned bufferspace, count, is_short; -+ -+ DEBUG_EP0("%s\n", __FUNCTION__); -+ -+ csr = usb_readb(dev, JZ_REG_UDC_CSR0); -+ if (!(csr & USB_CSR0_OUTPKTRDY)) -+ return 0; -+ -+ buf = req->req.buf + req->req.actual; -+ prefetchw(buf); -+ bufferspace = req->req.length - req->req.actual; -+ -+ /* read all bytes from this packet */ -+ if (likely(csr & USB_CSR0_OUTPKTRDY)) { -+ count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT); -+ req->req.actual += min(count, bufferspace); -+ } else /* zlp */ -+ count = 0; -+ -+ is_short = (count < ep->ep.maxpacket); -+ DEBUG_EP0("read %s %02x, %d bytes%s req %p %d/%d\n", -+ ep->ep.name, csr, count, -+ is_short ? "/S" : "", req, req->req.actual, req->req.length); -+ -+ while (likely(count-- != 0)) { -+ uint8_t byte = (uint8_t)usb_readl(dev, ep->fifo); -+ -+ if (unlikely(bufferspace == 0)) { -+ /* this happens when the driver's buffer -+ * is smaller than what the host sent. -+ * discard the extra data. -+ */ -+ if (req->req.status != -EOVERFLOW) -+ DEBUG_EP0("%s overflow %d\n", ep->ep.name, -+ count); -+ req->req.status = -EOVERFLOW; -+ } else { -+ *buf++ = byte; -+ bufferspace--; -+ } -+ } -+ -+ /* completion */ -+ if (is_short || req->req.actual == req->req.length) { -+ done(ep, req, 0); -+ return 1; -+ } -+ -+ /* finished that packet. the next one may be waiting... */ -+ return 0; -+} -+ -+/** -+ * udc_set_address - set the USB address for this device -+ * @address: -+ * -+ * Called from control endpoint function after it decodes a set address setup packet. -+ */ -+static void udc_set_address(struct jz4740_udc *dev, unsigned char address) -+{ -+ DEBUG_EP0("%s: %d\n", __FUNCTION__, address); -+ -+ dev->usb_address = address; -+ usb_writeb(dev, JZ_REG_UDC_FADDR, address); -+} -+ -+/* -+ * DATA_STATE_RECV (USB_CSR0_OUTPKTRDY) -+ * - if error -+ * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL bits -+ * - else -+ * set USB_CSR0_SVDOUTPKTRDY bit -+ if last set USB_CSR0_DATAEND bit -+ */ -+static void jz4740_ep0_out(struct jz4740_udc *dev, uint32_t csr, int kickstart) -+{ -+ struct jz4740_request *req; -+ struct jz4740_ep *ep = &dev->ep[0]; -+ int ret; -+ -+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); -+ -+ if (list_empty(&ep->queue)) -+ req = 0; -+ else -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ -+ if (req) { -+ if (req->req.length == 0) { -+ DEBUG_EP0("ZERO LENGTH OUT!\n"); -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); -+ dev->ep0state = WAIT_FOR_SETUP; -+ return; -+ } else if (kickstart) { -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY)); -+ return; -+ } -+ ret = read_fifo_ep0(ep, req); -+ if (ret) { -+ /* Done! */ -+ DEBUG_EP0("%s: finished, waiting for status\n", -+ __FUNCTION__); -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); -+ dev->ep0state = WAIT_FOR_SETUP; -+ } else { -+ /* Not done yet.. */ -+ DEBUG_EP0("%s: not finished\n", __FUNCTION__); -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); -+ } -+ } else { -+ DEBUG_EP0("NO REQ??!\n"); -+ } -+} -+ -+/* -+ * DATA_STATE_XMIT -+ */ -+static int jz4740_ep0_in(struct jz4740_udc *dev, uint32_t csr) -+{ -+ struct jz4740_request *req; -+ struct jz4740_ep *ep = &dev->ep[0]; -+ int ret, need_zlp = 0; -+ -+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); -+ -+ if (list_empty(&ep->queue)) -+ req = 0; -+ else -+ req = list_entry(ep->queue.next, struct jz4740_request, queue); -+ -+ if (!req) { -+ DEBUG_EP0("%s: NULL REQ\n", __FUNCTION__); -+ return 0; -+ } -+ -+ if (req->req.length == 0) { -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); -+ dev->ep0state = WAIT_FOR_SETUP; -+ return 1; -+ } -+ -+ if (req->req.length - req->req.actual == EP0_MAXPACKETSIZE) { -+ /* Next write will end with the packet size, */ -+ /* so we need zero-length-packet */ -+ need_zlp = 1; -+ } -+ -+ ret = write_fifo_ep0(ep, req); -+ -+ if (ret == 1 && !need_zlp) { -+ /* Last packet */ -+ DEBUG_EP0("%s: finished, waiting for status\n", __FUNCTION__); -+ -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); -+ dev->ep0state = WAIT_FOR_SETUP; -+ } else { -+ DEBUG_EP0("%s: not finished\n", __FUNCTION__); -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_INPKTRDY); -+ } -+ -+ if (need_zlp) { -+ DEBUG_EP0("%s: Need ZLP!\n", __FUNCTION__); -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_INPKTRDY); -+ dev->ep0state = DATA_STATE_NEED_ZLP; -+ } -+ -+ return 1; -+} -+ -+static int jz4740_handle_get_status(struct jz4740_udc *dev, -+ struct usb_ctrlrequest *ctrl) -+{ -+ struct jz4740_ep *ep0 = &dev->ep[0]; -+ struct jz4740_ep *qep; -+ int reqtype = (ctrl->bRequestType & USB_RECIP_MASK); -+ uint16_t val = 0; -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ -+ if (reqtype == USB_RECIP_INTERFACE) { -+ /* This is not supported. -+ * And according to the USB spec, this one does nothing.. -+ * Just return 0 -+ */ -+ DEBUG_SETUP("GET_STATUS: USB_RECIP_INTERFACE\n"); -+ } else if (reqtype == USB_RECIP_DEVICE) { -+ DEBUG_SETUP("GET_STATUS: USB_RECIP_DEVICE\n"); -+ val |= (1 << 0); /* Self powered */ -+ /*val |= (1<<1); *//* Remote wakeup */ -+ } else if (reqtype == USB_RECIP_ENDPOINT) { -+ int ep_num = (ctrl->wIndex & ~USB_DIR_IN); -+ -+ DEBUG_SETUP -+ ("GET_STATUS: USB_RECIP_ENDPOINT (%d), ctrl->wLength = %d\n", -+ ep_num, ctrl->wLength); -+ -+ if (ctrl->wLength > 2 || ep_num > 3) -+ return -EOPNOTSUPP; -+ -+ qep = &dev->ep[ep_num]; -+ if (ep_is_in(qep) != ((ctrl->wIndex & USB_DIR_IN) ? 1 : 0) -+ && ep_index(qep) != 0) { -+ return -EOPNOTSUPP; -+ } -+ -+ jz_udc_set_index(dev, ep_index(qep)); -+ -+ /* Return status on next IN token */ -+ switch (qep->type) { -+ case ep_control: -+ val = -+ (usb_readb(dev, qep->csr) & USB_CSR0_SENDSTALL) == -+ USB_CSR0_SENDSTALL; -+ break; -+ case ep_bulk_in: -+ case ep_interrupt: -+ val = -+ (usb_readb(dev, qep->csr) & USB_INCSR_SENDSTALL) == -+ USB_INCSR_SENDSTALL; -+ break; -+ case ep_bulk_out: -+ val = -+ (usb_readb(dev, qep->csr) & USB_OUTCSR_SENDSTALL) == -+ USB_OUTCSR_SENDSTALL; -+ break; -+ } -+ -+ /* Back to EP0 index */ -+ jz_udc_set_index(dev, 0); -+ -+ DEBUG_SETUP("GET_STATUS, ep: %d (%x), val = %d\n", ep_num, -+ ctrl->wIndex, val); -+ } else { -+ DEBUG_SETUP("Unknown REQ TYPE: %d\n", reqtype); -+ return -EOPNOTSUPP; -+ } -+ -+ /* Clear "out packet ready" */ -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); -+ /* Put status to FIFO */ -+ jz4740_fifo_write(ep0, (uint8_t *)&val, sizeof(val)); -+ /* Issue "In packet ready" */ -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); -+ -+ return 0; -+} -+ -+/* -+ * WAIT_FOR_SETUP (OUTPKTRDY) -+ * - read data packet from EP0 FIFO -+ * - decode command -+ * - if error -+ * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL bits -+ * - else -+ * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND bits -+ */ -+static void jz4740_ep0_setup(struct jz4740_udc *dev, uint32_t csr) -+{ -+ struct jz4740_ep *ep = &dev->ep[0]; -+ struct usb_ctrlrequest ctrl; -+ int i; -+ -+ DEBUG_SETUP("%s: %x\n", __FUNCTION__, csr); -+ -+ /* Nuke all previous transfers */ -+ nuke(ep, -EPROTO); -+ -+ /* read control req from fifo (8 bytes) */ -+ jz4740_fifo_read(ep, (unsigned char *)&ctrl, 8); -+ -+ DEBUG_SETUP("SETUP %02x.%02x v%04x i%04x l%04x\n", -+ ctrl.bRequestType, ctrl.bRequest, -+ ctrl.wValue, ctrl.wIndex, ctrl.wLength); -+ -+ /* Set direction of EP0 */ -+ if (likely(ctrl.bRequestType & USB_DIR_IN)) { -+ ep->bEndpointAddress |= USB_DIR_IN; -+ } else { -+ ep->bEndpointAddress &= ~USB_DIR_IN; -+ } -+ -+ /* Handle some SETUP packets ourselves */ -+ switch (ctrl.bRequest) { -+ case USB_REQ_SET_ADDRESS: -+ if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) -+ break; -+ -+ DEBUG_SETUP("USB_REQ_SET_ADDRESS (%d)\n", ctrl.wValue); -+ udc_set_address(dev, ctrl.wValue); -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); -+ return; -+ -+ case USB_REQ_SET_CONFIGURATION: -+ if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) -+ break; -+ -+ DEBUG_SETUP("USB_REQ_SET_CONFIGURATION (%d)\n", ctrl.wValue); -+/* usb_setb(JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));*/ -+ -+ /* Enable RESUME and SUSPEND interrupts */ -+ usb_setb(dev, JZ_REG_UDC_INTRUSBE, (USB_INTR_RESUME | USB_INTR_SUSPEND)); -+ break; -+ -+ case USB_REQ_SET_INTERFACE: -+ if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) -+ break; -+ -+ DEBUG_SETUP("USB_REQ_SET_INTERFACE (%d)\n", ctrl.wValue); -+/* usb_setb(JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));*/ -+ break; -+ -+ case USB_REQ_GET_STATUS: -+ if (jz4740_handle_get_status(dev, &ctrl) == 0) -+ return; -+ -+ case USB_REQ_CLEAR_FEATURE: -+ case USB_REQ_SET_FEATURE: -+ if (ctrl.bRequestType == USB_RECIP_ENDPOINT) { -+ struct jz4740_ep *qep; -+ int ep_num = (ctrl.wIndex & 0x0f); -+ -+ /* Support only HALT feature */ -+ if (ctrl.wValue != 0 || ctrl.wLength != 0 -+ || ep_num > 3 || ep_num < 1) -+ break; -+ -+ qep = &dev->ep[ep_num]; -+ spin_unlock(&dev->lock); -+ if (ctrl.bRequest == USB_REQ_SET_FEATURE) { -+ DEBUG_SETUP("SET_FEATURE (%d)\n", -+ ep_num); -+ jz4740_set_halt(&qep->ep, 1); -+ } else { -+ DEBUG_SETUP("CLR_FEATURE (%d)\n", -+ ep_num); -+ jz4740_set_halt(&qep->ep, 0); -+ } -+ spin_lock(&dev->lock); -+ -+ jz_udc_set_index(dev, 0); -+ -+ /* Reply with a ZLP on next IN token */ -+ usb_setb(dev, JZ_REG_UDC_CSR0, -+ (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); -+ return; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* gadget drivers see class/vendor specific requests, -+ * {SET,GET}_{INTERFACE,DESCRIPTOR,CONFIGURATION}, -+ * and more. -+ */ -+ if (dev->driver) { -+ /* device-2-host (IN) or no data setup command, process immediately */ -+ spin_unlock(&dev->lock); -+ -+ i = dev->driver->setup(&dev->gadget, &ctrl); -+ spin_lock(&dev->lock); -+ -+ if (unlikely(i < 0)) { -+ /* setup processing failed, force stall */ -+ DEBUG_SETUP -+ (" --> ERROR: gadget setup FAILED (stalling), setup returned %d\n", -+ i); -+ jz_udc_set_index(dev, 0); -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL)); -+ -+ /* ep->stopped = 1; */ -+ dev->ep0state = WAIT_FOR_SETUP; -+ } -+ else { -+ DEBUG_SETUP("gadget driver setup ok (%d)\n", ctrl.wLength); -+/* if (!ctrl.wLength) { -+ usb_setb(JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); -+ }*/ -+ } -+ } -+} -+ -+/* -+ * DATA_STATE_NEED_ZLP -+ */ -+static void jz4740_ep0_in_zlp(struct jz4740_udc *dev, uint32_t csr) -+{ -+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); -+ -+ usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); -+ dev->ep0state = WAIT_FOR_SETUP; -+} -+ -+/* -+ * handle ep0 interrupt -+ */ -+static void jz4740_handle_ep0(struct jz4740_udc *dev, uint32_t intr) -+{ -+ struct jz4740_ep *ep = &dev->ep[0]; -+ uint32_t csr; -+ -+ DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); -+ /* Set index 0 */ -+ jz_udc_set_index(dev, 0); -+ csr = usb_readb(dev, JZ_REG_UDC_CSR0); -+ -+ DEBUG_EP0("%s: csr = %x state = \n", __FUNCTION__, csr);//, state_names[dev->ep0state]); -+ -+ /* -+ * if SENT_STALL is set -+ * - clear the SENT_STALL bit -+ */ -+ if (csr & USB_CSR0_SENTSTALL) { -+ DEBUG_EP0("%s: USB_CSR0_SENTSTALL is set: %x\n", __FUNCTION__, csr); -+ usb_clearb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SENDSTALL | USB_CSR0_SENTSTALL); -+ nuke(ep, -ECONNABORTED); -+ dev->ep0state = WAIT_FOR_SETUP; -+ return; -+ } -+ -+ /* -+ * if a transfer is in progress && INPKTRDY and OUTPKTRDY are clear -+ * - fill EP0 FIFO -+ * - if last packet -+ * - set IN_PKT_RDY | DATA_END -+ * - else -+ * set IN_PKT_RDY -+ */ -+ if (!(csr & (USB_CSR0_INPKTRDY | USB_CSR0_OUTPKTRDY))) { -+ DEBUG_EP0("%s: INPKTRDY and OUTPKTRDY are clear\n", -+ __FUNCTION__); -+ -+ switch (dev->ep0state) { -+ case DATA_STATE_XMIT: -+ DEBUG_EP0("continue with DATA_STATE_XMIT\n"); -+ jz4740_ep0_in(dev, csr); -+ return; -+ case DATA_STATE_NEED_ZLP: -+ DEBUG_EP0("continue with DATA_STATE_NEED_ZLP\n"); -+ jz4740_ep0_in_zlp(dev, csr); -+ return; -+ default: -+ /* Stall? */ -+// DEBUG_EP0("Odd state!! state = %s\n", -+// state_names[dev->ep0state]); -+ dev->ep0state = WAIT_FOR_SETUP; -+ /* nuke(ep, 0); */ -+ /* usb_setb(ep->csr, USB_CSR0_SENDSTALL); */ -+// break; -+ return; -+ } -+ } -+ -+ /* -+ * if SETUPEND is set -+ * - abort the last transfer -+ * - set SERVICED_SETUP_END_BIT -+ */ -+ if (csr & USB_CSR0_SETUPEND) { -+ DEBUG_EP0("%s: USB_CSR0_SETUPEND is set: %x\n", __FUNCTION__, csr); -+ -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDSETUPEND); -+ nuke(ep, 0); -+ dev->ep0state = WAIT_FOR_SETUP; -+ } -+ -+ /* -+ * if USB_CSR0_OUTPKTRDY is set -+ * - read data packet from EP0 FIFO -+ * - decode command -+ * - if error -+ * set SVDOUTPKTRDY | DATAEND | SENDSTALL bits -+ * - else -+ * set SVDOUTPKTRDY | DATAEND bits -+ */ -+ if (csr & USB_CSR0_OUTPKTRDY) { -+ -+ DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __FUNCTION__, -+ csr); -+ -+ switch (dev->ep0state) { -+ case WAIT_FOR_SETUP: -+ DEBUG_EP0("WAIT_FOR_SETUP\n"); -+ jz4740_ep0_setup(dev, csr); -+ break; -+ -+ case DATA_STATE_RECV: -+ DEBUG_EP0("DATA_STATE_RECV\n"); -+ jz4740_ep0_out(dev, csr, 0); -+ break; -+ -+ default: -+ /* send stall? */ -+ DEBUG_EP0("strange state!! 2. send stall? state = %d\n", -+ dev->ep0state); -+ break; -+ } -+ } -+} -+ -+static void jz4740_ep0_kick(struct jz4740_udc *dev, struct jz4740_ep *ep) -+{ -+ uint32_t csr; -+ -+ jz_udc_set_index(dev, 0); -+ -+ DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); -+ -+ /* Clear "out packet ready" */ -+ -+ if (ep_is_in(ep)) { -+ usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); -+ csr = usb_readb(dev, JZ_REG_UDC_CSR0); -+ dev->ep0state = DATA_STATE_XMIT; -+ jz4740_ep0_in(dev, csr); -+ } else { -+ csr = usb_readb(dev, JZ_REG_UDC_CSR0); -+ dev->ep0state = DATA_STATE_RECV; -+ jz4740_ep0_out(dev, csr, 1); -+ } -+} -+ -+/** Handle USB RESET interrupt -+ */ -+static void jz4740_reset_irq(struct jz4740_udc *dev) -+{ -+ dev->gadget.speed = (usb_readb(dev, JZ_REG_UDC_POWER) & USB_POWER_HSMODE) ? -+ USB_SPEED_HIGH : USB_SPEED_FULL; -+ -+ DEBUG_SETUP("%s: address = %d, speed = %s\n", __FUNCTION__, dev->usb_address, -+ (dev->gadget.speed == USB_SPEED_HIGH) ? "HIGH":"FULL" ); -+} -+ -+/* -+ * jz4740 usb device interrupt handler. -+ */ -+static irqreturn_t jz4740_udc_irq(int irq, void *_dev) -+{ -+ struct jz4740_udc *dev = _dev; -+ uint8_t index; -+ -+ uint32_t intr_usb = usb_readb(dev, JZ_REG_UDC_INTRUSB) & 0x7; /* mask SOF */ -+ uint32_t intr_in = usb_readw(dev, JZ_REG_UDC_INTRIN); -+ uint32_t intr_out = usb_readw(dev, JZ_REG_UDC_INTROUT); -+ uint32_t intr_dma = usb_readb(dev, JZ_REG_UDC_INTR); -+ -+ if (!intr_usb && !intr_in && !intr_out && !intr_dma) -+ return IRQ_HANDLED; -+ -+ -+ DEBUG("intr_out=%x intr_in=%x intr_usb=%x\n", -+ intr_out, intr_in, intr_usb); -+ -+ spin_lock(&dev->lock); -+ index = usb_readb(dev, JZ_REG_UDC_INDEX); -+ -+ /* Check for resume from suspend mode */ -+ if ((intr_usb & USB_INTR_RESUME) && -+ (usb_readb(dev, JZ_REG_UDC_INTRUSBE) & USB_INTR_RESUME)) { -+ DEBUG("USB resume\n"); -+ dev->driver->resume(&dev->gadget); /* We have suspend(), so we must have resume() too. */ -+ } -+ -+ /* Check for system interrupts */ -+ if (intr_usb & USB_INTR_RESET) { -+ DEBUG("USB reset\n"); -+ jz4740_reset_irq(dev); -+ } -+ -+ /* Check for endpoint 0 interrupt */ -+ if (intr_in & USB_INTR_EP0) { -+ DEBUG("USB_INTR_EP0 (control)\n"); -+ jz4740_handle_ep0(dev, intr_in); -+ } -+ -+ /* Check for Bulk-IN DMA interrupt */ -+ if (intr_dma & 0x1) { -+ int ep_num; -+ struct jz4740_ep *ep; -+ ep_num = (usb_readl(dev, JZ_REG_UDC_CNTL1) >> 4) & 0xf; -+ ep = &dev->ep[ep_num + 1]; -+ jz_udc_set_index(dev, ep_num); -+ usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY); -+/* jz4740_in_epn(dev, ep_num, intr_in);*/ -+ } -+ -+ /* Check for Bulk-OUT DMA interrupt */ -+ if (intr_dma & 0x2) { -+ int ep_num; -+ ep_num = (usb_readl(dev, JZ_REG_UDC_CNTL2) >> 4) & 0xf; -+ jz4740_out_epn(dev, ep_num, intr_out); -+ } -+ -+ /* Check for each configured endpoint interrupt */ -+ if (intr_in & USB_INTR_INEP1) { -+ DEBUG("USB_INTR_INEP1\n"); -+ jz4740_in_epn(dev, 1, intr_in); -+ } -+ -+ if (intr_in & USB_INTR_INEP2) { -+ DEBUG("USB_INTR_INEP2\n"); -+ jz4740_in_epn(dev, 2, intr_in); -+ } -+ -+ if (intr_out & USB_INTR_OUTEP1) { -+ DEBUG("USB_INTR_OUTEP1\n"); -+ jz4740_out_epn(dev, 1, intr_out); -+ } -+ -+ /* Check for suspend mode */ -+ if ((intr_usb & USB_INTR_SUSPEND) && -+ (usb_readb(dev, JZ_REG_UDC_INTRUSBE) & USB_INTR_SUSPEND)) { -+ DEBUG("USB suspend\n"); -+ dev->driver->suspend(&dev->gadget); -+ /* Host unloaded from us, can do something, such as flushing -+ the NAND block cache etc. */ -+ } -+ -+ jz_udc_set_index(dev, index); -+ -+ spin_unlock(&dev->lock); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* Common functions - Added by River */ -+static struct jz4740_udc udc_dev; -+ -+static inline struct jz4740_udc *gadget_to_udc(struct usb_gadget *gadget) -+{ -+ return container_of(gadget, struct jz4740_udc, gadget); -+} -+/* End added */ -+ -+static int jz4740_udc_get_frame(struct usb_gadget *_gadget) -+{ -+ DEBUG("%s, %p\n", __FUNCTION__, _gadget); -+ return usb_readw(gadget_to_udc(_gadget), JZ_REG_UDC_FRAME); -+} -+ -+static int jz4740_udc_wakeup(struct usb_gadget *_gadget) -+{ -+ /* host may not have enabled remote wakeup */ -+ /*if ((UDCCS0 & UDCCS0_DRWF) == 0) -+ return -EHOSTUNREACH; -+ udc_set_mask_UDCCR(UDCCR_RSM); */ -+ return -ENOTSUPP; -+} -+ -+static int jz4740_udc_pullup(struct usb_gadget *_gadget, int on) -+{ -+ struct jz4740_udc *udc = gadget_to_udc(_gadget); -+ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ if (on) { -+ udc->state = UDC_STATE_ENABLE; -+ udc_enable(udc); -+ } else { -+ udc->state = UDC_STATE_DISABLE; -+ udc_disable(udc); -+ } -+ -+ local_irq_restore(flags); -+ -+ return 0; -+} -+ -+static const struct usb_gadget_ops jz4740_udc_ops = { -+ .get_frame = jz4740_udc_get_frame, -+ .wakeup = jz4740_udc_wakeup, -+ .pullup = jz4740_udc_pullup, -+ /* current versions must always be self-powered */ -+}; -+ -+static struct usb_ep_ops jz4740_ep_ops = { -+ .enable = jz4740_ep_enable, -+ .disable = jz4740_ep_disable, -+ -+ .alloc_request = jz4740_alloc_request, -+ .free_request = jz4740_free_request, -+ -+ .queue = jz4740_queue, -+ .dequeue = jz4740_dequeue, -+ -+ .set_halt = jz4740_set_halt, -+ .fifo_status = jz4740_fifo_status, -+ .fifo_flush = jz4740_fifo_flush, -+}; -+ -+ -+/*-------------------------------------------------------------------------*/ -+ -+static struct jz4740_udc udc_dev = { -+ .usb_address = 0, -+ .gadget = { -+ .ops = &jz4740_udc_ops, -+ .ep0 = &udc_dev.ep[0].ep, -+ .name = "jz-udc", -+ .dev = { -+ .init_name = "gadget", -+ }, -+ }, -+ -+ /* control endpoint */ -+ .ep[0] = { -+ .ep = { -+ .name = "ep0", -+ .ops = &jz4740_ep_ops, -+ .maxpacket = EP0_MAXPACKETSIZE, -+ }, -+ .dev = &udc_dev, -+ -+ .bEndpointAddress = 0, -+ .bmAttributes = 0, -+ -+ .type = ep_control, -+ .fifo = JZ_REG_UDC_EP_FIFO(0), -+ .csr = JZ_REG_UDC_CSR0, -+ }, -+ -+ /* bulk out endpoint */ -+ .ep[1] = { -+ .ep = { -+ .name = "ep1out-bulk", -+ .ops = &jz4740_ep_ops, -+ .maxpacket = EPBULK_MAXPACKETSIZE, -+ }, -+ .dev = &udc_dev, -+ -+ .bEndpointAddress = 1, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+ -+ .type = ep_bulk_out, -+ .fifo = JZ_REG_UDC_EP_FIFO(1), -+ .csr = JZ_REG_UDC_OUTCSR, -+ }, -+ -+ /* bulk in endpoint */ -+ .ep[2] = { -+ .ep = { -+ .name = "ep1in-bulk", -+ .ops = &jz4740_ep_ops, -+ .maxpacket = EPBULK_MAXPACKETSIZE, -+ }, -+ .dev = &udc_dev, -+ -+ .bEndpointAddress = 1 | USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+ -+ .type = ep_bulk_in, -+ .fifo = JZ_REG_UDC_EP_FIFO(1), -+ .csr = JZ_REG_UDC_INCSR, -+ }, -+ -+ /* interrupt in endpoint */ -+ .ep[3] = { -+ .ep = { -+ .name = "ep2in-int", -+ .ops = &jz4740_ep_ops, -+ .maxpacket = EPINTR_MAXPACKETSIZE, -+ }, -+ .dev = &udc_dev, -+ -+ .bEndpointAddress = 2 | USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_XFER_INT, -+ -+ .type = ep_interrupt, -+ .fifo = JZ_REG_UDC_EP_FIFO(2), -+ .csr = JZ_REG_UDC_INCSR, -+ }, -+}; -+ -+static void gadget_release(struct device *_dev) -+{ -+} -+ -+ -+static int jz4740_udc_probe(struct platform_device *pdev) -+{ -+ struct jz4740_udc *dev = &udc_dev; -+ int ret; -+ -+ spin_lock_init(&dev->lock); -+ the_controller = dev; -+ -+ dev->dev = &pdev->dev; -+ dev_set_name(&dev->gadget.dev, "gadget"); -+ dev->gadget.dev.parent = &pdev->dev; -+ dev->gadget.dev.dma_mask = pdev->dev.dma_mask; -+ dev->gadget.dev.release = gadget_release; -+ -+ ret = device_register(&dev->gadget.dev); -+ if (ret) -+ return ret; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ dev->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ if (!dev->mem) { -+ ret = -ENOENT; -+ dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); -+ goto err_device_unregister; -+ } -+ -+ dev->mem = request_mem_region(dev->mem->start, resource_size(dev->mem), pdev->name); -+ -+ if (!dev->mem) { -+ ret = -EBUSY; -+ dev_err(&pdev->dev, "Failed to request mmio memory region\n"); -+ goto err_device_unregister; -+ } -+ -+ dev->base = ioremap(dev->mem->start, resource_size(dev->mem)); -+ -+ if (!dev->base) { -+ ret = -EBUSY; -+ dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); -+ goto err_release_mem_region; -+ } -+ -+ dev->irq = platform_get_irq(pdev, 0); -+ -+ ret = request_irq(dev->irq, jz4740_udc_irq, IRQF_DISABLED, -+ pdev->name, dev); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); -+ goto err_iounmap; -+ } -+ -+ udc_disable(dev); -+ udc_reinit(dev); -+ -+ return 0; -+ -+err_iounmap: -+ iounmap(dev->base); -+err_release_mem_region: -+ release_mem_region(dev->mem->start, resource_size(dev->mem)); -+err_device_unregister: -+ device_unregister(&dev->gadget.dev); -+ platform_set_drvdata(pdev, NULL); -+ -+ the_controller = 0; -+ -+ return ret; -+} -+ -+static int jz4740_udc_remove(struct platform_device *pdev) -+{ -+ struct jz4740_udc *dev = platform_get_drvdata(pdev); -+ -+ if (dev->driver) -+ return -EBUSY; -+ -+ udc_disable(dev); -+#ifdef UDC_PROC_FILE -+ remove_proc_entry(proc_node_name, NULL); -+#endif -+ -+ free_irq(dev->irq, dev); -+ iounmap(dev->base); -+ release_mem_region(dev->mem->start, resource_size(dev->mem)); -+ -+ platform_set_drvdata(pdev, NULL); -+ device_unregister(&dev->gadget.dev); -+ the_controller = NULL; -+ -+ return 0; -+} -+ -+static struct platform_driver udc_driver = { -+ .probe = jz4740_udc_probe, -+ .remove = jz4740_udc_remove, -+ .driver = { -+ .name = "jz-udc", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+/*-------------------------------------------------------------------------*/ -+ -+static int __init udc_init (void) -+{ -+ return platform_driver_register(&udc_driver); -+} -+ -+static void __exit udc_exit (void) -+{ -+ platform_driver_unregister(&udc_driver); -+} -+ -+module_init(udc_init); -+module_exit(udc_exit); -+ -+MODULE_DESCRIPTION("JZ4740 USB Device Controller"); -+MODULE_AUTHOR("Wei Jianli <jlwei@ingenic.cn>"); -+MODULE_LICENSE("GPL"); -diff -ruN linux-2.6.31-vanilla/drivers/usb/gadget/jz4740_udc.h linux-2.6.31/drivers/usb/gadget/jz4740_udc.h ---- linux-2.6.31-vanilla/drivers/usb/gadget/jz4740_udc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/usb/gadget/jz4740_udc.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,97 @@ -+/* -+ * linux/drivers/usb/gadget/jz4740_udc.h -+ * -+ * Ingenic JZ4740 on-chip high speed USB device controller -+ * -+ * Copyright (C) 2006 Ingenic Semiconductor Inc. -+ * Author: <jlwei@ingenic.cn> -+ * -+ * 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 __USB_GADGET_JZ4740_H__ -+#define __USB_GADGET_JZ4740_H__ -+ -+/*-------------------------------------------------------------------------*/ -+ -+// Max packet size -+#define EP0_MAXPACKETSIZE 64 -+#define EPBULK_MAXPACKETSIZE 512 -+#define EPINTR_MAXPACKETSIZE 64 -+ -+#define UDC_MAX_ENDPOINTS 4 -+ -+/*-------------------------------------------------------------------------*/ -+ -+typedef enum ep_type { -+ ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt -+} ep_type_t; -+ -+struct jz4740_ep { -+ struct usb_ep ep; -+ struct jz4740_udc *dev; -+ -+ const struct usb_endpoint_descriptor *desc; -+ unsigned long pio_irqs; -+ -+ uint8_t stopped; -+ uint8_t bEndpointAddress; -+ uint8_t bmAttributes; -+ -+ ep_type_t type; -+ size_t fifo; -+ u32 csr; -+ -+ uint32_t reg_addr; -+ struct list_head queue; -+}; -+ -+struct jz4740_request { -+ struct usb_request req; -+ struct list_head queue; -+}; -+ -+enum ep0state { -+ WAIT_FOR_SETUP, /* between STATUS ack and SETUP report */ -+ DATA_STATE_XMIT, /* data tx stage */ -+ DATA_STATE_NEED_ZLP, /* data tx zlp stage */ -+ WAIT_FOR_OUT_STATUS, /* status stages */ -+ DATA_STATE_RECV, /* data rx stage */ -+}; -+ -+/* For function binding with UDC Disable - Added by River */ -+typedef enum { -+ UDC_STATE_ENABLE = 0, -+ UDC_STATE_DISABLE, -+}udc_state_t; -+ -+struct jz4740_udc { -+ struct usb_gadget gadget; -+ struct usb_gadget_driver *driver; -+ struct device *dev; -+ spinlock_t lock; -+ -+ enum ep0state ep0state; -+ struct jz4740_ep ep[UDC_MAX_ENDPOINTS]; -+ -+ unsigned char usb_address; -+ -+ udc_state_t state; -+ -+ struct resource *mem; -+ void __iomem *base; -+ int irq; -+ uint32_t in_mask; -+ uint32_t out_mask; -+}; -+ -+extern struct jz4740_udc *the_controller; -+ -+#define ep_is_in(EP) (((EP)->bEndpointAddress&USB_DIR_IN)==USB_DIR_IN) -+#define ep_maxpacket(EP) ((EP)->ep.maxpacket) -+#define ep_index(EP) ((EP)->bEndpointAddress&0xF) -+ -+#endif /* __USB_GADGET_JZ4740_H__ */ -diff -ruN linux-2.6.31-vanilla/drivers/usb/gadget/udc_hotplug.h linux-2.6.31/drivers/usb/gadget/udc_hotplug.h ---- linux-2.6.31-vanilla/drivers/usb/gadget/udc_hotplug.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/usb/gadget/udc_hotplug.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,50 @@ -+/* -+ * Ingenic USB Device Contoller Hotplug External Interfaces -+ */ -+ -+#ifndef __UDC_HOTPLUG_H__ -+#define __UDC_HOTPLUG_H__ -+ -+#include <linux/notifier.h> -+ -+typedef enum { -+ BROADCAST_TYPE_STATE = 0, -+ BROADCAST_TYPE_EVENT, -+}udc_hotplug_broadcast_type_t; -+ -+typedef enum { -+ EVENT_STATE_OFFLINE = 0, -+ EVENT_STATE_ONLINE, -+}udc_hotplug_event_state_t; -+ -+typedef enum { -+ EVENT_TYPE_USB = 0, -+ EVENT_TYPE_CABLE, -+}udc_hotplug_event_type_t; -+ -+enum { -+ EVENT_FLAG_UDC_PHY_TOUCHED = 0, -+}; -+ -+typedef struct { -+ udc_hotplug_event_type_t type; -+ udc_hotplug_event_state_t state; -+ unsigned long flags; -+}udc_hotplug_event_t; -+ -+/* Register notifier */ -+int udc_hotplug_register_notifier(struct notifier_block *n, int request_state); -+ -+/* Unregister notifier */ -+int udc_hotplug_unregister_notifier(struct notifier_block *n); -+ -+/* Start keep alive */ -+int udc_hotplug_start_keep_alive(unsigned long timer_interval_in_jiffies, unsigned long counter_limit); -+ -+/* Do keep alive */ -+void udc_hotplug_do_keep_alive(void); -+ -+/* Stop keep alive */ -+void udc_hotplug_stop_keep_alive(void); -+ -+#endif /* Define __UDC_HOTPLUG_H__ */ -diff -ruN linux-2.6.31-vanilla/drivers/usb/gadget/udc_hotplug_core.c linux-2.6.31/drivers/usb/gadget/udc_hotplug_core.c ---- linux-2.6.31-vanilla/drivers/usb/gadget/udc_hotplug_core.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/usb/gadget/udc_hotplug_core.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,836 @@ -+/* -+ * Ingenic USB Device Controller Hotplug Core Function -+ * Detection mechanism and code are based on the old version of udc_hotplug.c -+ */ -+ -+#include <linux/sched.h> -+#include <linux/module.h> -+#include <linux/notifier.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/err.h> -+#include <linux/wait.h> -+#include <linux/kthread.h> -+#include <linux/timer.h> -+ -+#include <asm/jzsoc.h> -+ -+#include "udc_hotplug.h" -+ -+#define PFX "jz_hotplug_udc" -+ -+#define D(msg, fmt...) \ -+// printk(KERN_ERR PFX": %s(): "msg, __func__, ##fmt); -+ -+/* HAVE_DETECT_SYNC -+ Provide a lock like seqlock keep the synchronization between the start and the end of a detection, -+ If the lock seems not synchronous(new interrupt comes, when doing our detection) in the end of a detection, -+ the result of the detection is discarded. No event will be broadcast, and the detection will be restarted. -+ -+ Use to filter out more significant events when the interrupt is too noisy. -+*/ -+ -+//#define HAVE_DETECT_SYNC 1 -+ -+#if defined (HAVE_DETECT_SYNC) -+#define NR_RESTART_TIMES 3 -+#define NR_JIFFIES_SLEEP_BEFORE_RESTART 7 -+#endif -+ -+#define NR_GPIO_STABLE_TIMES 50 -+#define NR_JIFFIES_USB_DETECT_WAIT 11 -+ -+#define DEFAULT_KEEP_ALIVE_TIMER_INTERVAL (2 * HZ) -+#define DEFAULT_KEEP_ALIVE_COUNTER_LIMIT 2 -+ -+#define UDC_HOTPLUG_PIN GPIO_UDC_HOTPLUG -+#define UDC_HOTPLUG_IRQ (IRQ_GPIO_0 + UDC_HOTPLUG_PIN) -+ -+/* UDC State bits */ -+enum { -+ /* Online state. */ -+ BIT_CABLE_ONLINE = 0, -+ BIT_USB_ONLINE, -+ -+ /* State changed ?*/ -+ BIT_CABLE_CHANGE, -+ BIT_USB_CHANGE, -+ -+ /* What detection will be done ? */ -+ BIT_DO_CABLE_DETECT, -+ BIT_DO_USB_DETECT, -+ -+ /* What detection is requested ? */ -+ BIT_REQUEST_CABLE_DETECT, -+ BIT_REQUEST_USB_DETECT, -+ -+ /* Indicate whether a detection is finisned. */ -+ BIT_USB_DETECT_DONE, -+ BIT_CABLE_DETECT_DONE, -+ -+ BIT_UDC_PHY_TOUCHED, -+ -+ /* Keep alive */ -+ BIT_KEEP_ALIVE, -+ BIT_KEEP_ALIVE_TIMEOUT, -+}; -+ -+struct uh_data { -+ /* Notifier */ -+ struct blocking_notifier_head notifier_head; -+ -+ /* Thread */ -+ struct task_struct *kthread; -+ -+ /* Wait queue */ -+ wait_queue_head_t kthread_wq; /* Kernel thread sleep here. */ -+ wait_queue_head_t wq; /* Others sleep here. */ -+ -+ /* UDC State */ -+ unsigned long state; -+ -+ /* Current Event */ -+ udc_hotplug_event_t cur_uh_event; -+ -+#if defined (HAVE_DETECT_SYNC) -+ /* Sync seq */ -+ unsigned long irq_sync_seq; -+ unsigned long our_sync_seq; -+#endif -+ -+ /* Keep alive */ -+ struct timer_list keep_alive_timer; -+ -+ unsigned long keep_alive_counter_limit; -+ unsigned long keep_alive_timer_interval; -+ unsigned long keep_alive_counter; -+}; -+ -+static struct uh_data *g_puh_data = NULL; -+ -+#if defined (HAVE_DETECT_SYNC) -+/* Seq sync function */ -+ -+static inline int is_seq_sync(struct uh_data *uh) -+{ -+ return (uh->our_sync_seq == uh->irq_sync_seq); -+} -+ -+static inline void reset_seq(struct uh_data *uh) -+{ -+ uh->our_sync_seq = uh->irq_sync_seq = 0; -+ -+ return; -+} -+ -+static inline void sync_seq(struct uh_data *uh) -+{ -+ uh->our_sync_seq = uh->irq_sync_seq; -+ -+ return; -+} -+#endif -+ -+/* Call kernel thread to detect. */ -+static inline void start_detect(struct uh_data *uh) -+{ -+ D("called.\n"); -+ -+#if defined (HAVE_DETECT_SYNC) -+ uh->irq_sync_seq ++; -+#endif -+ -+ wake_up_process(uh->kthread); -+ -+ return; -+} -+ -+static void wait_gpio_pin_stable(struct uh_data *uh) -+{ -+ unsigned long pin = 0; -+ int i = 1; -+ -+ pin = __gpio_get_pin(UDC_HOTPLUG_PIN); -+ -+ while (i < NR_GPIO_STABLE_TIMES) { -+ if (__gpio_get_pin(UDC_HOTPLUG_PIN) != pin) { -+ pin = __gpio_get_pin(UDC_HOTPLUG_PIN); -+ i = 1; -+ }else -+ i++; -+ -+ sleep_on_timeout(&uh->wq, 1); -+ } -+ -+ return; -+} -+ -+/* Do cable detection */ -+static void cable_detect(struct uh_data *uh) -+{ -+ D("Wait pin stable.\n"); -+ -+ /* Wait GPIO pin stable first. */ -+ wait_gpio_pin_stable(uh); -+ -+ if (__gpio_get_pin(UDC_HOTPLUG_PIN)) { -+ D("Cable online.\n"); -+ -+ if (!test_and_set_bit(BIT_CABLE_ONLINE, &uh->state)) { -+ D("Cable state change to online.\n"); -+ -+ set_bit(BIT_CABLE_CHANGE, &uh->state); -+ } -+ }else { -+ D("Cable offline.\n"); -+ -+ /* Clear keep alive bit. */ -+ clear_bit(BIT_KEEP_ALIVE, &uh->state); -+ -+ if (test_and_clear_bit(BIT_CABLE_ONLINE, &uh->state)) { -+ D("Cable state change to offline.\n"); -+ -+ set_bit(BIT_CABLE_CHANGE, &uh->state); -+ } -+ } -+ -+ set_bit(BIT_CABLE_DETECT_DONE, &uh->state); -+ -+ return; -+} -+ -+/* Really do USB detection */ -+static int do_usb_detect(struct uh_data *uh) -+{ -+ u32 intr_usb; -+ int rv; -+ -+ D("called.\n"); -+ -+ __intc_mask_irq(IRQ_UDC); -+ -+ /* Now enable PHY to start detect */ -+#ifdef CONFIG_SOC_JZ4740 -+ REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; -+#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) -+ REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE; -+#endif -+ /* Clear IRQs */ -+ REG16(USB_REG_INTRINE) = 0; -+ REG16(USB_REG_INTROUTE) = 0; -+ REG8(USB_REG_INTRUSBE) = 0; -+ -+ /* disable UDC IRQs first */ -+ REG16(USB_REG_INTRINE) = 0; -+ REG16(USB_REG_INTROUTE) = 0; -+ REG8(USB_REG_INTRUSBE) = 0; -+ -+ /* Disable DMA */ -+ REG32(USB_REG_CNTL1) = 0; -+ REG32(USB_REG_CNTL2) = 0; -+ -+ /* Enable HS Mode */ -+ REG8(USB_REG_POWER) |= USB_POWER_HSENAB; -+ /* Enable soft connect */ -+ REG8(USB_REG_POWER) |= USB_POWER_SOFTCONN; -+ -+ D("enable phy! %x %x %x %x %x\n", -+ REG8(USB_REG_POWER), -+ REG_CPM_OPCR, -+ REG16(USB_REG_INTRINE), -+ REG16(USB_REG_INTROUTE), -+ REG8(USB_REG_INTRUSBE)); -+ -+ /* Wait a moment. */ -+ sleep_on_timeout(&uh->wq, NR_JIFFIES_USB_DETECT_WAIT); -+ -+ intr_usb = REG8(USB_REG_INTRUSB); -+ if ((intr_usb & USB_INTR_RESET) || -+ (intr_usb & USB_INTR_RESUME) || -+ (intr_usb & USB_INTR_SUSPEND)) -+ { -+ rv = 1; -+ } -+ else -+ { -+ rv = 0; -+ } -+ -+ /* Detect finish ,clean every thing */ -+ /* Disconnect from usb */ -+ REG8(USB_REG_POWER) &= ~USB_POWER_SOFTCONN; -+ /* Disable the USB PHY */ -+#ifdef CONFIG_SOC_JZ4740 -+ REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE; -+#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) -+ REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE; -+#endif -+ /* Clear IRQs */ -+ REG16(USB_REG_INTRINE) = 0; -+ REG16(USB_REG_INTROUTE) = 0; -+ REG8(USB_REG_INTRUSBE) = 0; -+ __intc_ack_irq(IRQ_UDC); -+ __intc_unmask_irq(IRQ_UDC); -+ -+ mdelay(1); -+ -+ return rv; -+} -+ -+/* Do USB bus protocol detection */ -+static void usb_detect(struct uh_data *uh) -+{ -+ int rv = 0; -+ -+ D("Called.\n"); -+ -+ /* If the cable has already been offline, we just pass the real USB detection. */ -+ if (test_bit(BIT_CABLE_ONLINE, &uh->state)) { -+ -+ D("Do real detection.\n"); -+ -+ rv = do_usb_detect(uh); -+ set_bit(BIT_UDC_PHY_TOUCHED, &uh->state); -+ }else{ -+ clear_bit(BIT_UDC_PHY_TOUCHED, &uh->state); -+ D("No need to do real detection.\n"); -+ } -+ -+ if (rv) { -+ if (!test_and_set_bit(BIT_USB_ONLINE, &uh->state)) -+ set_bit(BIT_USB_CHANGE, &uh->state); -+ }else{ -+ /* Clear keep alive bit. */ -+ clear_bit(BIT_KEEP_ALIVE, &uh->state); -+ -+ if (test_and_clear_bit(BIT_USB_ONLINE, &uh->state)) -+ set_bit(BIT_USB_CHANGE, &uh->state); -+ } -+ -+ set_bit(BIT_USB_DETECT_DONE, &uh->state); -+ return; -+} -+ -+/* USB is active ? */ -+static int usb_is_active(void) -+{ -+ unsigned long tmp; -+ -+ tmp = REG16(USB_REG_FRAME); -+ -+ mdelay(2); /* USB 1.1 Frame length is 1ms, USB 2.0 HS Frame length is 125us */ -+ -+ rmb(); -+ -+ return tmp == REG16(USB_REG_FRAME) ? 0 : 1; -+} -+ -+/* Broadcast event to notifier */ -+static void do_broadcast_event(struct uh_data *uh) -+{ -+ udc_hotplug_event_t *e = &uh->cur_uh_event; -+ -+ /* Collect Information */ -+ if (test_and_clear_bit(BIT_CABLE_CHANGE, &uh->state)) { -+ e->type = EVENT_TYPE_CABLE; -+ e->state = (test_bit(BIT_CABLE_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE: EVENT_STATE_OFFLINE; -+ e->flags = 0; -+ -+ D("Broadcast cable event -> State: %s.\n", (e->state == EVENT_STATE_ONLINE ? "Online" : "Offline")); -+ -+ /* Kick chain. */ -+ blocking_notifier_call_chain(&uh->notifier_head, BROADCAST_TYPE_EVENT, e); -+ } -+ -+ if (test_and_clear_bit(BIT_USB_CHANGE, &uh->state)) { -+ e->type = EVENT_TYPE_USB; -+ e->state = (test_bit(BIT_USB_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE : EVENT_STATE_OFFLINE; -+ e->flags = 0; -+ -+ if (test_bit(BIT_UDC_PHY_TOUCHED, &uh->state)) { -+ set_bit(EVENT_FLAG_UDC_PHY_TOUCHED, &e->flags); -+ } -+ -+ D("Broadcast USB event -> State: %s.\n", (e->state == EVENT_STATE_ONLINE ? "Online" : "Offline")); -+ -+ /* Kick chain. */ -+ blocking_notifier_call_chain(&uh->notifier_head, BROADCAST_TYPE_EVENT, e); -+ } -+ -+ return; -+} -+ -+/* Handle pending request */ -+static inline void handle_request(struct uh_data *uh) -+{ -+ if (test_and_clear_bit(BIT_REQUEST_CABLE_DETECT, &uh->state)) -+ set_bit(BIT_DO_CABLE_DETECT, &uh->state); -+ -+ if (test_and_clear_bit(BIT_REQUEST_USB_DETECT, &uh->state)) -+ set_bit(BIT_DO_USB_DETECT, &uh->state); -+ -+ return; -+} -+ -+/* Have pending request ? */ -+static inline int pending_request(struct uh_data *uh) -+{ -+ if (test_bit(BIT_REQUEST_CABLE_DETECT, &uh->state) || test_bit(BIT_REQUEST_USB_DETECT, &uh->state)) -+ return 1; -+ else -+ return 0; -+} -+ -+#if defined (HAVE_DETECT_SYNC) -+static void prepare_restart(struct uh_data *uh, wait_queue_head_t *wq) -+{ -+ -+ D("Called.\n"); -+ -+ if (test_bit(BIT_CABLE_DETECT_DONE, &uh->state)) -+ set_bit(BIT_DO_CABLE_DETECT, &uh->state); -+ -+ if (test_bit(BIT_USB_DETECT_DONE, &uh->state)) -+ set_bit(BIT_DO_USB_DETECT, &uh->state); -+ -+ sleep_on_timeout(wq, NR_JIFFIES_SLEEP_BEFORE_RESTART); -+ -+ sync_seq(uh); -+ -+ return; -+} -+ -+/* Called from kernel thread */ -+static void udc_pnp_detect(struct uh_data *uh) -+{ -+ int nr_restart = 0; -+ -+ D("Do UDC detection.\n"); -+ -+ while (nr_restart != NR_RESTART_TIMES) { -+ /* Do cable detection ? */ -+ if (test_bit(BIT_DO_CABLE_DETECT, &uh->state)) { -+ D("Do cable detection.\n"); -+ -+ cable_detect(uh); -+ } -+ -+ /* Need restart ? */ -+ if (!is_seq_sync(uh)) { -+ nr_restart ++; -+ -+ prepare_restart(uh, &uh->wq); -+ continue; -+ } -+ -+ /* Do USB detection ? */ -+ if (test_bit(BIT_DO_USB_DETECT, &uh->state)) { -+ D("Do USB detection.\n"); -+ -+ usb_detect(uh); -+ } -+ -+ /* Need restart ? */ -+ if (!is_seq_sync(uh)) { -+ nr_restart ++; -+ -+ prepare_restart(uh, &uh->wq); -+ continue; -+ } -+ -+ /* Done */ -+ D("Done.\n"); -+ -+ clear_bit(BIT_DO_CABLE_DETECT, &uh->state); -+ clear_bit(BIT_DO_USB_DETECT, &uh->state); -+ -+ break; -+ } -+ -+ return; -+} -+ -+static inline void broadcast_event(struct uh_data *uh) -+{ -+ /* Sync ? */ -+ if (is_seq_sync(uh)) { -+ D("Sync -> Broadcast event.\n"); -+ -+ do_broadcast_event(uh); -+ }else{ -+ D("Not sync -> Prepare restarting.\n"); -+ -+ prepare_restart(uh, &uh->kthread_wq); -+ } -+} -+ -+static inline void udc_pnp_thread_sleep(struct uh_data *uh) -+{ -+ /* Sync ? -> Sleep. */ -+ if ( !pending_request(uh) || is_seq_sync(uh)) { -+ D("Sleep.\n"); -+ -+ sleep_on(&uh->kthread_wq); -+ } -+ -+ return; -+} -+ -+#else /* !HAVE_DETECT_SYNC */ -+ -+/* Called from kernel thread */ -+static void udc_pnp_detect(struct uh_data *uh) -+{ -+ D("Do UDC detection.\n"); -+ -+ /* Do cable detection ? */ -+ if (test_bit(BIT_DO_CABLE_DETECT, &uh->state)) { -+ D("Do cable detection.\n"); -+ -+ cable_detect(uh); -+ } -+ -+ /* Do USB detection ? */ -+ if (test_bit(BIT_DO_USB_DETECT, &uh->state)) { -+ D("Do USB detection.\n"); -+ -+ usb_detect(uh); -+ } -+ -+ /* Done */ -+ D("Done.\n"); -+ -+ clear_bit(BIT_DO_CABLE_DETECT, &uh->state); -+ clear_bit(BIT_DO_USB_DETECT, &uh->state); -+ -+ return; -+} -+ -+static inline void broadcast_event(struct uh_data *uh) -+{ -+ D("Broadcast event.\n"); -+ -+ do_broadcast_event(uh); -+ -+ return; -+} -+ -+static inline void udc_pnp_thread_sleep(struct uh_data *uh) -+{ -+ if (!pending_request(uh)) { -+ D("Sleep.\n"); -+ -+ sleep_on(&uh->kthread_wq); -+ } -+ -+ return; -+} -+#endif /* HAVE_DETECT_SYNC */ -+ -+/* Kernel thread */ -+static int udc_pnp_thread(void *data) -+{ -+ struct uh_data *uh = (struct uh_data *)data; -+ -+ while (!kthread_should_stop()) { -+ /* Sleep. */ -+ udc_pnp_thread_sleep(uh); -+ -+ D("Running.\n"); -+ -+ if (kthread_should_stop()) -+ break; -+ -+#if defined (HAVE_DETECT_SYNC) -+ /* Sync */ -+ sync_seq(uh); -+#endif -+ -+ D("Will do UDC detection.\n"); -+ -+ handle_request(uh); -+ -+ /* Do detect */ -+ udc_pnp_detect(uh); -+ -+ D("Done.\n"); -+ -+ /* Broadcast event. */ -+ broadcast_event(uh); -+ } -+ -+ D("Exit.\n"); -+ -+ return 0; -+} -+ -+static irqreturn_t udc_pnp_irq(int irq, void *dev_id) -+{ -+ struct uh_data *uh = (struct uh_data *)dev_id; -+ -+ D("called.\n"); -+ -+ /* clear interrupt pending status */ -+ __gpio_ack_irq(UDC_HOTPLUG_PIN); -+ -+ set_bit(BIT_REQUEST_CABLE_DETECT, &uh->state); -+ set_bit(BIT_REQUEST_USB_DETECT, &uh->state); -+ -+ start_detect(uh); -+ -+ return IRQ_HANDLED; -+} -+ -+static void __init init_gpio(struct uh_data *uh) -+{ -+ /* get current pin level */ -+ __gpio_disable_pull(UDC_HOTPLUG_PIN); -+ __gpio_as_input(UDC_HOTPLUG_PIN); -+ udelay(1); -+ -+ cable_detect(uh); -+ -+ /* Because of every plug IN/OUT action will casue more than one interrupt, -+ So whether rising trigger or falling trigger method can both start the detection. -+ */ -+ -+ __gpio_as_irq_rise_edge(UDC_HOTPLUG_PIN); -+ -+ if (test_bit(BIT_CABLE_ONLINE, &uh->state)) { -+ D("Cable Online -> Do start detection.\n"); -+ -+ set_bit(BIT_REQUEST_CABLE_DETECT, &uh->state); -+ set_bit(BIT_REQUEST_USB_DETECT, &uh->state); -+ -+ start_detect(uh); -+ }else{ -+ D("Cable Offline.\n"); -+ } -+ -+ return; -+} -+ -+/* ---------------------------------------------------------------------------------- */ -+/* Export routines */ -+static void udc_hotplug_keep_alive_timer_func(unsigned long data) -+{ -+ struct uh_data *uh = (struct uh_data *)data; -+ -+ D("Timer running.\n"); -+ -+ /* Decrease the counter. */ -+ if (test_bit(BIT_KEEP_ALIVE, &uh->state) && !(--uh->keep_alive_counter)) { -+ -+ if (!usb_is_active()) { -+ D("Timeout.\n"); -+ -+ set_bit(BIT_KEEP_ALIVE_TIMEOUT, &uh->state); -+ -+ clear_bit(BIT_USB_ONLINE, &uh->state); -+ set_bit(BIT_USB_CHANGE, &uh->state); -+ -+ /* No detection needed. We just want to broadcast our event. */ -+ start_detect(uh); -+ } -+ } -+ -+ /* Set next active time. */ -+ if (test_bit(BIT_KEEP_ALIVE, &uh->state) && !test_bit(BIT_KEEP_ALIVE_TIMEOUT, &uh->state)) -+ mod_timer(&uh->keep_alive_timer, uh->keep_alive_timer_interval + jiffies); -+ else -+ D("Timer will stop.\n"); -+ -+ return; -+} -+ -+int udc_hotplug_register_notifier(struct notifier_block *n, int request_state) -+{ -+ struct uh_data *uh = g_puh_data; -+ -+ udc_hotplug_event_t e; -+ -+ D("Register notifier: 0x%p.\n", (void *)n); -+ -+ /* Notifer will be registered is requesting current state. */ -+ if (request_state) { -+ -+ BUG_ON(!n->notifier_call); -+ -+ /* Cable State */ -+ e.type = EVENT_TYPE_CABLE; -+ e.state = (test_bit(BIT_CABLE_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE: EVENT_STATE_OFFLINE; -+ -+ n->notifier_call(n, BROADCAST_TYPE_STATE, &e); -+ -+ /* USB State */ -+ e.type = EVENT_TYPE_USB; -+ e.state = (test_bit(BIT_CABLE_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE: EVENT_STATE_OFFLINE; -+ -+ n->notifier_call(n, BROADCAST_TYPE_STATE, &e); -+ } -+ -+ return blocking_notifier_chain_register(&uh->notifier_head, n); -+ -+}EXPORT_SYMBOL(udc_hotplug_register_notifier); -+ -+int udc_hotplug_unregister_notifier(struct notifier_block *n) -+{ -+ struct uh_data *uh = g_puh_data; -+ -+ D("Unregister notifier: 0x%p.\n", (void *)n); -+ -+ return blocking_notifier_chain_unregister(&uh->notifier_head, n); -+ -+}EXPORT_SYMBOL(udc_hotplug_unregister_notifier); -+ -+/* Start keep alive, 0 - Use default value */ -+int udc_hotplug_start_keep_alive(unsigned long timer_interval_in_jiffies, unsigned long counter_limit) -+{ -+ struct uh_data *uh = g_puh_data; -+ -+ /* Already started. */ -+ if (test_and_set_bit(BIT_KEEP_ALIVE, &uh->state)) -+ return 0; -+ -+ if (timer_interval_in_jiffies) -+ uh->keep_alive_timer_interval = timer_interval_in_jiffies; -+ else -+ uh->keep_alive_timer_interval = DEFAULT_KEEP_ALIVE_TIMER_INTERVAL; -+ -+ if (counter_limit) -+ uh->keep_alive_counter_limit = counter_limit; -+ else -+ uh->keep_alive_counter_limit = DEFAULT_KEEP_ALIVE_COUNTER_LIMIT; -+ -+ uh->keep_alive_counter = uh->keep_alive_counter_limit; -+ -+ /* Active our timer. */ -+ return mod_timer(&uh->keep_alive_timer, 3 + jiffies); -+ -+}EXPORT_SYMBOL(udc_hotplug_start_keep_alive); -+ -+void udc_hotplug_do_keep_alive(void) -+{ -+ struct uh_data *uh = g_puh_data; -+ -+ D("Keep alive.\n"); -+ -+ /* Reset counter */ -+ uh->keep_alive_counter = uh->keep_alive_counter_limit; -+ -+ /* We are alive again. */ -+ if (test_and_clear_bit(BIT_KEEP_ALIVE_TIMEOUT, &uh->state)) { -+ D("Reactive timer.\n"); -+ -+ /* Active timer. */ -+ set_bit(BIT_KEEP_ALIVE, &uh->state); -+ mod_timer(&uh->keep_alive_timer, 3 + jiffies); -+ } -+ -+ return; -+}EXPORT_SYMBOL(udc_hotplug_do_keep_alive); -+ -+void udc_hotplug_stop_keep_alive(void) -+{ -+ struct uh_data *uh = g_puh_data; -+ -+ clear_bit(BIT_KEEP_ALIVE, &uh->state); -+ -+ return; -+ -+}EXPORT_SYMBOL(udc_hotplug_stop_keep_alive); -+ -+/* ----------------------------------------------------------------------------- */ -+ -+/* -+ * Module init and exit -+ */ -+static int __init udc_hotplug_init(void) -+{ -+ struct uh_data *uh; -+ -+ unsigned long status = 0; -+ -+ int rv; -+ -+ g_puh_data = (struct uh_data *)kzalloc(sizeof(struct uh_data), GFP_KERNEL); -+ if (!g_puh_data) { -+ printk(KERN_ERR PFX": Failed to allocate memory.\n"); -+ return -ENOMEM; -+ } -+ -+ uh = g_puh_data; -+ -+ set_bit(1, &status); -+ -+ BLOCKING_INIT_NOTIFIER_HEAD(&uh->notifier_head); -+ -+ init_waitqueue_head(&uh->kthread_wq); -+ init_waitqueue_head(&uh->wq); -+ -+ init_timer(&uh->keep_alive_timer); -+ -+ uh->keep_alive_timer.function = udc_hotplug_keep_alive_timer_func; -+ uh->keep_alive_timer.expires = jiffies - 1; /* Add a stopped timer */ -+ uh->keep_alive_timer.data = (unsigned long)uh; -+ -+ add_timer(&uh->keep_alive_timer); -+ -+#if defined (HAVE_DETECT_SYNC) -+ reset_seq(uh); -+#endif -+ -+ /* Create pnp thread and register IRQ */ -+ uh->kthread = kthread_run(udc_pnp_thread, uh, "kudcd"); -+ if (IS_ERR(uh->kthread)) { -+ printk(KERN_ERR PFX": Failed to create system monitor thread.\n"); -+ rv = PTR_ERR(uh->kthread); -+ goto err; -+ } -+ -+ set_bit(2, &status); -+ -+ rv = request_irq(UDC_HOTPLUG_IRQ, udc_pnp_irq, IRQF_DISABLED, "udc_pnp", uh); -+ if (rv) { -+ printk(KERN_ERR PFX": Could not get udc hotplug irq %d\n", UDC_HOTPLUG_IRQ); -+ goto err; -+ } -+ -+ init_gpio(uh); -+ -+#if defined (HAVE_DETECT_SYNC) -+ printk(KERN_ERR PFX": Registered(HAVE_DETECT_SYNC).\n"); -+#else -+ printk(KERN_ERR PFX": Registered.\n"); -+#endif -+ return 0; -+ -+err: -+ if (test_bit(2, &status)) { -+ kthread_stop(uh->kthread); -+ } -+ -+ if (test_bit(1, &status)) { -+ kfree(g_puh_data); -+ } -+ -+ return rv; -+} -+ -+static void __exit udc_hotplug_exit(void) -+{ -+ free_irq(UDC_HOTPLUG_IRQ, g_puh_data); -+ -+ kthread_stop(g_puh_data->kthread); -+ -+ kfree(g_puh_data); -+ -+ return; -+} -+ -+module_init(udc_hotplug_init); -+module_exit(udc_hotplug_exit); -+ -+MODULE_AUTHOR("River Wang <zwang@ingenic.cn>"); -+MODULE_LICENSE("GPL"); -diff -ruN linux-2.6.31-vanilla/drivers/video/backlight/gpm940b0.c linux-2.6.31/drivers/video/backlight/gpm940b0.c ---- linux-2.6.31-vanilla/drivers/video/backlight/gpm940b0.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/video/backlight/gpm940b0.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,253 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ4720/JZ4740 SoC LCD framebuffer driver -+ * -+ * 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. -+ * -+ * 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 <linux/module.h> -+#include <linux/spi/spi.h> -+#include <linux/lcd.h> -+#include <linux/backlight.h> -+#include <linux/delay.h> -+ -+struct gpm940b0 { -+ struct spi_device *spi; -+ struct lcd_device *lcd; -+ struct backlight_device *bl; -+ unsigned enabled:1; -+}; -+ -+static int gpm940b0_write_reg(struct spi_device *spi, uint8_t reg, -+ uint8_t data) -+{ -+ uint8_t buf[2]; -+ buf[0] = ((reg & 0x40) << 1) | (reg & 0x3f); -+ buf[1] = data; -+ -+ return spi_write(spi, buf, sizeof(buf)); -+} -+ -+static void gpm940b0_power_disable(struct gpm940b0 *gpm940b0) -+{ -+ int ret = gpm940b0_write_reg(gpm940b0->spi, 0x5, 0xc6) ; -+ if (ret < 0) -+ printk("Failed to disable power: %d\n", ret); -+} -+ -+static void gpm940b0_power_enable(struct gpm940b0 *gpm940b0) -+{ -+ gpm940b0_write_reg(gpm940b0->spi, 0x5, 0xc7); -+} -+ -+ -+static int gpm940b0_set_power(struct lcd_device *lcd, int power) -+{ -+ struct gpm940b0 *gpm940b0 = lcd_get_data(lcd); -+ -+ switch (power) { -+ case FB_BLANK_UNBLANK: -+ gpm940b0->enabled = 1; -+ gpm940b0_power_enable(gpm940b0); -+ break; -+ default: -+ gpm940b0->enabled = 0; -+ gpm940b0_power_disable(gpm940b0); -+ break; -+ } -+ return 0; -+} -+ -+static int gpm940b0_set_contrast(struct lcd_device *lcd, int contrast) -+{ -+ struct gpm940b0 *gpm940b0 = lcd_get_data(lcd); -+ gpm940b0_write_reg(gpm940b0->spi, 0x0d, contrast); -+ return 0; -+} -+ -+static int gpm940b0_set_mode(struct lcd_device *lcd, struct fb_videomode *mode) -+{ -+ if (mode->xres != 320 && mode->yres != 240) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+/* -+int gpm940b0_bl_update_status(struct backlight_device *bl) -+{ -+ struct gpm940b0 *gpm940b0 = bl_get_data(bl); -+ -+ gpm940b0->reg5 &= ~0x38; -+ gpm940b0->reg5 |= ((bl->props.brightness << 3) & 0x38); -+ -+ gpm940b0_write_reg(gpm940b0->spi, 0x5, gpm940b0->reg5); -+ -+ return 0; -+}*/ -+ -+static ssize_t reg_write(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ char *buf2; -+ uint32_t reg = simple_strtoul(buf, &buf2, 10); -+ uint32_t val = simple_strtoul(buf2 + 1, NULL, 10); -+ struct gpm940b0 *gpm940b0 = dev_get_drvdata(dev); -+ -+ if (reg < 0 || val < 0) -+ return -EINVAL; -+ -+ gpm940b0_write_reg(gpm940b0->spi, reg, val); -+ return count; -+} -+ -+static DEVICE_ATTR(reg, 0644, NULL, reg_write); -+ -+static struct lcd_ops gpm940b0_lcd_ops = { -+ .set_power = gpm940b0_set_power, -+ .set_contrast = gpm940b0_set_contrast, -+ .set_mode = gpm940b0_set_mode, -+}; -+ -+#if 0 -+static struct backlight_ops gpm940b0_bl_ops = { -+/* .get_brightness = gpm940b0_bl_get_brightness,*/ -+ .update_status = gpm940b0_bl_update_status, -+}; -+#endif -+ -+static int __devinit gpm940b0_probe(struct spi_device *spi) -+{ -+ int ret; -+ struct gpm940b0 *gpm940b0; -+ -+ gpm940b0 = kmalloc(sizeof(*gpm940b0), GFP_KERNEL); -+ -+ spi->bits_per_word = 8; -+ -+ ret = spi_setup(spi); -+ if (ret) { -+ dev_err(&spi->dev, "Failed to setup spi\n"); -+ goto err_free_gpm940b0; -+ } -+ -+ gpm940b0->spi = spi; -+ -+ gpm940b0->lcd = lcd_device_register("gpm940b0-lcd", &spi->dev, gpm940b0, -+ &gpm940b0_lcd_ops); -+ -+ if (IS_ERR(gpm940b0->lcd)) { -+ ret = PTR_ERR(gpm940b0->lcd); -+ dev_err(&spi->dev, "Failed to register lcd device: %d\n", ret); -+ goto err_free_gpm940b0; -+ } -+ -+ gpm940b0->lcd->props.max_contrast = 255; -+ -+#if 0 -+ gpm940b0->bl = backlight_device_register("gpm940b0-bl", &spi->dev, gpm940b0, -+ &gpm940b0_bl_ops); -+ -+ if (IS_ERR(gpm940b0->bl)) { -+ ret = PTR_ERR(gpm940b0->bl); -+ dev_err(&spi->dev, "Failed to register backlight device: %d\n", ret); -+ gpm940b0->bl = NULL; -+ } else { -+ gpm940b0->bl->props.max_brightness = 8; -+ gpm940b0->bl->props.brightness = 0; -+ gpm940b0->bl->props.power = FB_BLANK_UNBLANK; -+ } -+#endif -+ -+ ret = device_create_file(&spi->dev, &dev_attr_reg); -+ if (ret) -+ goto err_unregister_lcd; -+ -+ gpm940b0->enabled = 1; -+ dev_set_drvdata(&spi->dev, gpm940b0); -+ -+ gpm940b0_write_reg(spi, 0x13, 0x01); -+ gpm940b0_write_reg(spi, 0x5, 0xc7); -+ return 0; -+err_unregister_lcd: -+ lcd_device_unregister(gpm940b0->lcd); -+err_free_gpm940b0: -+ kfree(gpm940b0); -+ return ret; -+} -+ -+static int __devexit gpm940b0_remove(struct spi_device *spi) -+{ -+ struct gpm940b0 *gpm940b0 = spi_get_drvdata(spi); -+#if 0 -+ if (gpm940b0->bl) -+ backlight_device_unregister(gpm940b0->bl); -+#endif -+ -+ lcd_device_unregister(gpm940b0->lcd); -+ -+ spi_set_drvdata(spi, NULL); -+ kfree(gpm940b0); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+ -+static int gpm940b0_suspend(struct spi_device *spi, pm_message_t state) -+{ -+ struct gpm940b0 *gpm940b0 = spi_get_drvdata(spi); -+ if (gpm940b0->enabled) { -+ gpm940b0_power_disable(gpm940b0); -+ mdelay(10); -+ } -+ return 0; -+} -+ -+static int gpm940b0_resume(struct spi_device *spi) -+{ -+ struct gpm940b0 *gpm940b0 = spi_get_drvdata(spi); -+ if (gpm940b0->enabled) -+ gpm940b0_power_enable(gpm940b0); -+ return 0; -+} -+ -+#else -+#define gpm940b0_suspend NULL -+#define gpm940b0_resume NULL -+#endif -+ -+static struct spi_driver gpm940b0_driver = { -+ .driver = { -+ .name = "gpm940b0", -+ .owner = THIS_MODULE, -+ }, -+ .probe = gpm940b0_probe, -+ .remove = __devexit_p(gpm940b0_remove), -+ .suspend = gpm940b0_suspend, -+ .resume = gpm940b0_resume, -+}; -+ -+static int __init gpm940b0_init(void) -+{ -+ return spi_register_driver(&gpm940b0_driver); -+} -+module_init(gpm940b0_init); -+ -+static void __exit gpm940b0_exit(void) -+{ -+ return spi_unregister_driver(&gpm940b0_driver); -+} -+module_exit(gpm940b0_exit) -+ -+MODULE_AUTHOR("Lars-Peter Clausen"); -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("LCD and backlight controll for Giantplus GPM940B0"); -+MODULE_ALIAS("spi:gpm940b0"); -diff -ruN linux-2.6.31-vanilla/drivers/video/jz4740_fb.c linux-2.6.31/drivers/video/jz4740_fb.c ---- linux-2.6.31-vanilla/drivers/video/jz4740_fb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/drivers/video/jz4740_fb.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,486 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ4720/JZ4740 SoC LCD framebuffer driver -+ * -+ * 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. -+ * -+ * 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 <linux/types.h> -+#include <linux/platform_device.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/dma-mapping.h> -+#include <linux/jz4740_fb.h> -+ -+#include <linux/delay.h> -+ -+#define JZ_REG_LCD_CFG 0x00 -+#define JZ_REG_LCD_VSYNC 0x04 -+#define JZ_REG_LCD_HSYNC 0x08 -+#define JZ_REG_LCD_VAT 0x0C -+#define JZ_REG_LCD_DAH 0x10 -+#define JZ_REG_LCD_DAV 0x14 -+#define JZ_REG_LCD_PS 0x18 -+#define JZ_REG_LCD_CLS 0x1C -+#define JZ_REG_LCD_SPL 0x20 -+#define JZ_REG_LCD_REV 0x24 -+#define JZ_REG_LCD_CTRL 0x30 -+#define JZ_REG_LCD_STATE 0x34 -+#define JZ_REG_LCD_IID 0x38 -+#define JZ_REG_LCD_DA0 0x40 -+#define JZ_REG_LCD_SA0 0x44 -+#define JZ_REG_LCD_FID0 0x48 -+#define JZ_REG_LCD_CMD0 0x4C -+#define JZ_REG_LCD_DA1 0x50 -+#define JZ_REG_LCD_SA1 0x54 -+#define JZ_REG_LCD_FID1 0x58 -+#define JZ_REG_LCD_CMD1 0x5C -+ -+#define JZ_LCD_CFG_SLCD BIT(31) -+#define JZ_LCD_CFG_PSM BIT(23) -+#define JZ_LCD_CFG_CLSM BIT(22) -+#define JZ_LCD_CFG_SPLM BIT(21) -+#define JZ_LCD_CFG_REVM BIT(20) -+#define JZ_LCD_CFG_HSYNCM BIT(19) -+#define JZ_LCD_CFG_PCLKM BIT(18) -+#define JZ_LCD_CFG_INV BIT(17) -+#define JZ_LCD_CFG_SYNC_DIR BIT(16) -+#define JZ_LCD_CFG_PSP BIT(15) -+#define JZ_LCD_CFG_CLSP BIT(14) -+#define JZ_LCD_CFG_SPLP BIT(13) -+#define JZ_LCD_CFG_REVP BIT(12) -+#define JZ_LCD_CFG_HSYNCP BIT(11) -+#define JZ_LCD_CFG_PCLKP BIT(10) -+#define JZ_LCD_CFG_DEP BIT(9) -+#define JZ_LCD_CFG_VSYNCP BIT(8) -+#define JZ_LCD_CFG_18_BIT BIT(7) -+#define JZ_LCD_CFG_PDW BIT(5) | BIT(4) -+#define JZ_LCD_CFG_MODE_MASK 0xf -+ -+#define JZ_LCD_CTRL_BURST_4 (0x0 << 28) -+#define JZ_LCD_CTRL_BURST_8 (0x1 << 28) -+#define JZ_LCD_CTRL_BURST_16 (0x2 << 28) -+#define JZ_LCD_CTRL_RGB555 BIT(27) -+#define JZ_LCD_CTRL_OFUP BIT(26) -+#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24) -+#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24) -+#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24) -+#define JZ_LCD_CTRL_PDD_MASK (0xff << 16) -+#define JZ_LCD_CTRL_EOF_IRQ BIT(13) -+#define JZ_LCD_CTRL_SOF_IRQ BIT(12) -+#define JZ_LCD_CTRL_OFU_IRQ BIT(11) -+#define JZ_LCD_CTRL_IFU0_IRQ BIT(10) -+#define JZ_LCD_CTRL_IFU1_IRQ BIT(9) -+#define JZ_LCD_CTRL_DD_IRQ BIT(8) -+#define JZ_LCD_CTRL_QDD_IRQ BIT(7) -+#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6) -+#define JZ_LCD_CTRL_LSB_FISRT BIT(5) -+#define JZ_LCD_CTRL_DISABLE BIT(4) -+#define JZ_LCD_CTRL_ENABLE BIT(3) -+#define JZ_LCD_CTRL_BPP_1 0x0 -+#define JZ_LCD_CTRL_BPP_2 0x1 -+#define JZ_LCD_CTRL_BPP_4 0x2 -+#define JZ_LCD_CTRL_BPP_8 0x3 -+#define JZ_LCD_CTRL_BPP_15_16 0x4 -+#define JZ_LCD_CTRL_BPP_18_24 0x5 -+ -+#define JZ_LCD_CMD_SOF_IRQ BIT(15) -+#define JZ_LCD_CMD_EOF_IRQ BIT(16) -+#define JZ_LCD_CMD_ENABLE_PAL BIT(12) -+ -+#define JZ_LCD_SYNC_MASK 0x3ff -+ -+struct jzfb_framedesc { -+ uint32_t next; -+ uint32_t addr; -+ uint32_t id; -+ uint32_t cmd; -+} __attribute__((packed)); -+ -+struct jzfb { -+ struct fb_info *fb; -+ struct platform_device *pdev; -+ void __iomem *base; -+ struct resource *mem; -+ struct jz4740_fb_platform_data *pdata; -+ -+ void *devmem; -+ size_t devmem_size; -+ dma_addr_t devmem_phys; -+ void *vidmem; -+ size_t vidmem_size; -+ dma_addr_t vidmem_phys; -+ struct jzfb_framedesc *framedesc; -+ -+ uint32_t pseudo_palette[16]; -+}; -+ -+static struct fb_fix_screeninfo jzfb_fix __devinitdata = { -+ .id = "JZ4740 FB", -+ .type = FB_TYPE_PACKED_PIXELS, -+ .visual = FB_VISUAL_TRUECOLOR, -+ .xpanstep = 0, -+ .ypanstep = 0, -+ .ywrapstep = 0, -+ .accel = FB_ACCEL_NONE, -+}; -+ -+int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, -+ unsigned transp, struct fb_info *fb) -+{ -+ ((uint32_t*)fb->pseudo_palette)[regno] = red << 16 | green << 8 | blue; -+ return 0; -+} -+ -+static int jzfb_get_controller_bpp(struct jzfb *jzfb) -+{ -+ switch(jzfb->pdata->bpp) { -+ case 18: -+ case 24: -+ return 32; -+ break; -+ default: -+ return jzfb->pdata->bpp; -+ } -+} -+ -+static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb) -+{ -+ struct jzfb* jzfb = fb->par; -+ struct fb_videomode *mode = jzfb->pdata->modes; -+ int i; -+ -+ if (fb->var.bits_per_pixel != jzfb_get_controller_bpp(jzfb) && -+ fb->var.bits_per_pixel != jzfb->pdata->bpp) -+ return -EINVAL; -+ -+ for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) { -+ if (mode->xres == fb->var.xres && mode->yres == fb->var.yres) -+ break; -+ } -+ -+ if (i == jzfb->pdata->num_modes) -+ return -EINVAL; -+ -+ fb_videomode_to_var(&fb->var, fb->mode); -+ -+ switch (jzfb->pdata->bpp) { -+ case 8: -+ break; -+ case 15: -+ var->red.offset = 10; -+ var->red.length = 5; -+ var->green.offset = 6; -+ var->green.length = 5; -+ var->blue.offset = 0; -+ var->blue.length = 5; -+ break; -+ case 16: -+ var->red.offset = 11; -+ var->red.length = 5; -+ var->green.offset = 6; -+ var->green.length = 6; -+ var->blue.offset = 0; -+ var->blue.length = 5; -+ break; -+ case 18: -+ var->red.offset = 16; -+ var->red.length = 6; -+ var->green.offset = 8; -+ var->green.length = 6; -+ var->blue.offset = 0; -+ var->blue.length = 6; -+ fb->var.bits_per_pixel = 32; -+ break; -+ case 32: -+ case 24: -+ var->transp.offset = 24; -+ var->transp.length = 8; -+ var->red.offset = 16; -+ var->red.length = 8; -+ var->green.offset = 8; -+ var->green.length = 8; -+ var->blue.offset = 0; -+ var->blue.length = 8; -+ fb->var.bits_per_pixel = 32; -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int jzfb_set_par(struct fb_info *info) -+{ -+ struct jzfb* jzfb = info->par; -+ struct fb_var_screeninfo *var = &info->var; -+ uint16_t hds, vds; -+ uint16_t hde, vde; -+ uint16_t ht, vt; -+ uint32_t ctrl; -+ -+ hds = var->hsync_len + var->left_margin; -+ hde = hds + var->xres; -+ ht = hde + var->right_margin; -+ -+ vds = var->vsync_len + var->upper_margin; -+ vde = vds + var->yres; -+ vt = vde + var->lower_margin; -+ -+ writel(var->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC); -+ writel(var->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC); -+ -+ writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT); -+ -+ writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH); -+ writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV); -+ -+ ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16; -+ ctrl |= JZ_LCD_CTRL_ENABLE; -+ -+ switch (jzfb->pdata->bpp) { -+ case 1: -+ ctrl |= JZ_LCD_CTRL_BPP_1; -+ break; -+ case 2: -+ ctrl |= JZ_LCD_CTRL_BPP_2; -+ break; -+ case 4: -+ ctrl |= JZ_LCD_CTRL_BPP_4; -+ break; -+ case 8: -+ ctrl |= JZ_LCD_CTRL_BPP_8; -+ break; -+ case 15: -+ ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */ -+ case 16: -+ ctrl |= JZ_LCD_CTRL_BPP_15_16; -+ break; -+ case 18: -+ case 24: -+ case 32: -+ ctrl |= JZ_LCD_CTRL_BPP_18_24; -+ break; -+ default: -+ break; -+ } -+ writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); -+ -+ return 0; -+} -+ -+ -+static int jzfb_alloc_vidmem(struct jzfb *jzfb) -+{ -+ size_t devmem_size; -+ int max_videosize = 0; -+ struct fb_videomode *mode = jzfb->pdata->modes; -+ struct jzfb_framedesc *framedesc; -+ void *page; -+ int i; -+ -+ for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) { -+ if (max_videosize < mode->xres * mode->yres) -+ max_videosize = mode->xres * mode->yres; -+ } -+ -+ max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3; -+ -+ devmem_size = max_videosize + sizeof(struct jzfb_framedesc); -+ -+ jzfb->devmem_size = devmem_size; -+ jzfb->devmem = dma_alloc_coherent(&jzfb->pdev->dev, -+ PAGE_ALIGN(devmem_size), -+ &jzfb->devmem_phys, GFP_KERNEL); -+ -+ if (!jzfb->devmem) { -+ return -ENOMEM; -+ } -+ -+ for (page = jzfb->vidmem; -+ page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size); -+ page += PAGE_SIZE) { -+ SetPageReserved(virt_to_page(page)); -+ } -+ -+ -+ framedesc = jzfb->devmem + max_videosize; -+ jzfb->vidmem = jzfb->devmem; -+ jzfb->vidmem_phys = jzfb->devmem_phys; -+ -+ framedesc->next = jzfb->devmem_phys + max_videosize; -+ framedesc->addr = jzfb->devmem_phys; -+ framedesc->id = 0; -+ framedesc->cmd = 0; -+ framedesc->cmd |= max_videosize / 4; -+ -+ jzfb->framedesc = framedesc; -+ -+ -+ return 0; -+} -+ -+static void jzfb_free_devmem(struct jzfb *jzfb) -+{ -+ dma_free_coherent(&jzfb->pdev->dev, jzfb->devmem_size, jzfb->devmem, -+ jzfb->devmem_phys); -+} -+ -+static struct fb_ops jzfb_ops = { -+ .owner = THIS_MODULE, -+ .fb_check_var = jzfb_check_var, -+ .fb_set_par = jzfb_set_par, -+/* .fb_blank = jzfb_blank,*/ -+ .fb_fillrect = sys_fillrect, -+ .fb_copyarea = sys_copyarea, -+ .fb_imageblit = sys_imageblit, -+ .fb_setcolreg = jzfb_setcolreg, -+}; -+ -+static int __devinit jzfb_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct jzfb *jzfb; -+ struct fb_info *fb; -+ struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data; -+ struct resource *mem; -+ -+ if (!pdata) { -+ dev_err(&pdev->dev, "Missing platform data\n"); -+ return -ENOENT; -+ } -+ -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ if (!mem) { -+ dev_err(&pdev->dev, "Failed to get register memory resource\n"); -+ return -ENOENT; -+ } -+ -+ mem = request_mem_region(mem->start, resource_size(mem), pdev->name); -+ -+ if (!mem) { -+ dev_err(&pdev->dev, "Failed to request register memory region\n"); -+ return -EBUSY; -+ } -+ -+ -+ fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev); -+ -+ if (!fb) { -+ dev_err(&pdev->dev, "Failed to allocate framebuffer device\n"); -+ ret = -ENOMEM; -+ goto err_release_mem_region; -+ } -+ -+ fb->fbops = &jzfb_ops; -+ fb->flags = FBINFO_DEFAULT; -+ -+ jzfb = fb->par; -+ jzfb->pdev = pdev; -+ jzfb->pdata = pdata; -+ jzfb->mem = mem; -+ -+ jzfb->base = ioremap(mem->start, resource_size(mem)); -+ -+ if (!jzfb->base) { -+ dev_err(&pdev->dev, "Failed to ioremap register memory region\n"); -+ ret = -EBUSY; -+ goto err_framebuffer_release; -+ } -+ -+ platform_set_drvdata(pdev, jzfb); -+ -+ fb_videomode_to_modelist(pdata->modes, pdata->num_modes, -+ &fb->modelist); -+ fb->mode = pdata->modes; -+ -+ fb_videomode_to_var(&fb->var, fb->mode); -+ fb->var.bits_per_pixel = pdata->bpp; -+ jzfb_check_var(&fb->var, fb); -+ -+ ret = jzfb_alloc_vidmem(jzfb); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to allocate video memory\n"); -+ goto err_iounmap; -+ } -+ -+ fb->fix = jzfb_fix; -+ fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8; -+ fb->fix.mmio_start = mem->start; -+ fb->fix.mmio_len = resource_size(mem); -+ fb->fix.smem_start = jzfb->vidmem_phys; -+ fb->fix.smem_len = fb->fix.line_length * fb->var.yres; -+ fb->screen_base = jzfb->vidmem; -+ fb->pseudo_palette = jzfb->pseudo_palette; -+ -+ fb_alloc_cmap(&fb->cmap, 256, 0); -+ -+ jzfb_set_par(fb); -+ writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); -+ -+ ret = register_framebuffer(fb); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret); -+ goto err_free_devmem; -+ } -+ -+ return 0; -+err_free_devmem: -+ jzfb_free_devmem(jzfb); -+err_iounmap: -+ iounmap(jzfb->base); -+err_framebuffer_release: -+ framebuffer_release(fb); -+err_release_mem_region: -+ release_mem_region(mem->start, resource_size(mem)); -+ return ret; -+} -+ -+static int __devexit jzfb_remove(struct platform_device *pdev) -+{ -+ struct jzfb *jzfb = platform_get_drvdata(pdev); -+ -+ iounmap(jzfb->base); -+ release_mem_region(jzfb->mem->start, resource_size(jzfb->mem)); -+ jzfb_free_devmem(jzfb); -+ platform_set_drvdata(pdev, NULL); -+ framebuffer_release(jzfb->fb); -+ return 0; -+} -+ -+static struct platform_driver jzfb_driver = { -+ .probe = jzfb_probe, -+ .remove = __devexit_p(jzfb_remove), -+ -+ .driver = { -+ .name = "jz4740-fb", -+ }, -+}; -+ -+int __init jzfb_init(void) -+{ -+ return platform_driver_register(&jzfb_driver); -+} -+module_init(jzfb_init); -+ -+void __exit jzfb_exit(void) -+{ -+ platform_driver_unregister(&jzfb_driver); -+} -+module_exit(jzfb_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_DESCRIPTION("JZ4720/JZ4740 SoC LCD framebuffer driver"); -+MODULE_ALIAS("platform:jz4740-fb"); -+MODULE_ALIAS("platform:jz4720-fb"); -diff -ruN linux-2.6.31-vanilla/include/linux/jz4740-adc.h linux-2.6.31/include/linux/jz4740-adc.h ---- linux-2.6.31-vanilla/include/linux/jz4740-adc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/include/linux/jz4740-adc.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,25 @@ -+ -+#ifndef __LINUX_JZ4740_ADC -+#define __LINUX_JZ4740_ADC -+ -+#include <linux/device.h> -+ -+enum jz_adc_battery_scale { -+ JZ_ADC_BATTERY_SCALE_2V5, /* Mesures voltages up to 2.5V */ -+ JZ_ADC_BATTERY_SCALE_7V5, /* Mesures voltages up to 7.5V */ -+}; -+ -+/* -+ * jz4740_adc_read_battery_voltage - Read battery voltage from the ADC PBAT pin -+ * @dev: Pointer to a jz4740-adc device -+ * @scale: Whether to use 2.5V or 7.5V scale -+ * -+ * Returns: Battery voltage in mircovolts -+ * -+ * Context: Process -+*/ -+long jz4740_adc_read_battery_voltage(struct device *dev, -+ enum jz_adc_battery_scale scale); -+ -+ -+#endif -diff -ruN linux-2.6.31-vanilla/include/linux/jz4740_fb.h linux-2.6.31/include/linux/jz4740_fb.h ---- linux-2.6.31-vanilla/include/linux/jz4740_fb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/include/linux/jz4740_fb.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * -+ * 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. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __LINUX_JZ4740_FB_H -+#define __LINUX_JZ4740_FB_H -+ -+#include <linux/fb.h> -+ -+enum jz4740_fb_lcd_type { -+ JZ_LCD_TYPE_GENERIC_16_18_BIT = 0, -+ JZ_LCD_TYPE_SPECIAL_TFT_1 = 1, -+ JZ_LCD_TYPE_SPECIAL_TFT_2 = 2, -+ JZ_LCD_TYPE_SPECIAL_TFT_3 = 3, -+ JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5, -+ JZ_LCD_TYPE_INTERLACED_CCIR656 = 7, -+ JZ_LCD_TYPE_SINGLE_COLOR_STN = 8, -+ JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9, -+ JZ_LCD_TYPE_DUAL_COLOR_STN = 10, -+ JZ_LCD_TYPE_8BIT_SERIAL = 11, -+}; -+ -+/* -+* width: width of the lcd display in mm -+* height: height of the lcd display in mm -+* num_modes: size of modes -+* modes: list of valid video modes -+* bpp: bits per pixel for the lcd -+* lcd_type: lcd type -+*/ -+ -+struct jz4740_fb_platform_data { -+ unsigned int width; -+ unsigned int height; -+ -+ size_t num_modes; -+ struct fb_videomode *modes; -+ int bpp; -+ enum jz4740_fb_lcd_type lcd_type; -+}; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/include/linux/mtd/jz4740_nand.h linux-2.6.31/include/linux/mtd/jz4740_nand.h ---- linux-2.6.31-vanilla/include/linux/mtd/jz4740_nand.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/include/linux/mtd/jz4740_nand.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * JZ4720/JZ4740 SoC NAND controller driver -+ * -+ * 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. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __JZ_NAND_H__ -+#define __JZ_NAND_H__ -+ -+#include <linux/mtd/nand.h> -+#include <linux/mtd/partitions.h> -+ -+struct jz_nand_platform_data { -+ int num_partitions; -+ struct mtd_partition *partitions; -+ -+ struct nand_ecclayout *ecc_layout; -+ -+ unsigned int busy_gpio; -+ -+ void (*ident_callback)(struct platform_device *, struct nand_chip *, -+ struct mtd_partition **, int *num_partitions); -+}; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/include/linux/power/jz4740-battery.h linux-2.6.31/include/linux/power/jz4740-battery.h ---- linux-2.6.31-vanilla/include/linux/power/jz4740-battery.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/include/linux/power/jz4740-battery.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2009, Jiejing Zhang <kzjeef@gmail.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __JZ4740_BATTERY_H -+#define __JZ4740_BATTERY_H -+ -+struct jz_batt_info { -+ int dc_dect_gpio; /* GPIO port of DC charger detection */ -+ int usb_dect_gpio; /* GPIO port of USB charger detection */ -+ int charg_stat_gpio; /* GPIO port of Charger state */ -+ -+ int min_voltag; /* Mininal battery voltage in uV */ -+ int max_voltag; /* Maximum battery voltage in uV */ -+ int batt_tech; /* Battery technology */ -+}; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/sound/soc/codecs/jzcodec.c linux-2.6.31/sound/soc/codecs/jzcodec.c ---- linux-2.6.31-vanilla/sound/soc/codecs/jzcodec.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/codecs/jzcodec.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,516 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * -+ * 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. -+ * -+ * 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 <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+ -+#include <sound/core.h> -+#include <sound/pcm.h> -+#include <sound/pcm_params.h> -+#include <sound/initval.h> -+#include <sound/soc-dapm.h> -+#include <sound/soc.h> -+ -+#define JZ_REG_CODEC_1 0x0 -+#define JZ_REG_CODEC_2 0x1 -+ -+#define JZ_CODEC_1_LINE_ENABLE BIT(29) -+#define JZ_CODEC_1_MIC_ENABLE BIT(28) -+#define JZ_CODEC_1_SW1_ENABLE BIT(27) -+#define JZ_CODEC_1_ADC_ENABLE BIT(26) -+#define JZ_CODEC_1_SW2_ENABLE BIT(25) -+#define JZ_CODEC_1_DAC_ENABLE BIT(24) -+#define JZ_CODEC_1_VREF_DISABLE BIT(20) -+#define JZ_CODEC_1_VREF_AMP_DISABLE BIT(19) -+#define JZ_CODEC_1_VREF_PULL_DOWN BIT(18) -+#define JZ_CODEC_1_VREF_LOW_CURRENT BIT(17) -+#define JZ_CODEC_1_VREF_HIGH_CURRENT BIT(16) -+#define JZ_CODEC_1_HEADPHONE_DISABLE BIT(14) -+#define JZ_CODEC_1_HEADPHONE_AMP_CHANGE_ANY BIT(13) -+#define JZ_CODEC_1_HEADPHONE_CHANGE BIT(12) -+#define JZ_CODEC_1_HEADPHONE_PULL_DOWN_M BIT(11) -+#define JZ_CODEC_1_HEADPHONE_PULL_DOWN_R BIT(10) -+#define JZ_CODEC_1_HEADPHONE_POWER_DOWN_M BIT(9) -+#define JZ_CODEC_1_HEADPHONE_POWER_DOWN BIT(8) -+#define JZ_CODEC_1_SUSPEND BIT(1) -+#define JZ_CODEC_1_RESET BIT(0) -+ -+#define JZ_CODEC_1_LINE_ENABLE_OFFSET 29 -+#define JZ_CODEC_1_MIC_ENABLE_OFFSET 28 -+#define JZ_CODEC_1_SW1_ENABLE_OFFSET 27 -+#define JZ_CODEC_1_ADC_ENABLE_OFFSET 26 -+#define JZ_CODEC_1_SW2_ENABLE_OFFSET 25 -+#define JZ_CODEC_1_DAC_ENABLE_OFFSET 24 -+#define JZ_CODEC_1_HEADPHONE_DISABLE_OFFSET 14 -+#define JZ_CODEC_1_HEADPHONE_POWER_DOWN_OFFSET 8 -+ -+#define JZ_CODEC_2_INPUT_VOLUME_MASK 0x1f0000 -+#define JZ_CODEC_2_SAMPLE_RATE_MASK 0x000f00 -+#define JZ_CODEC_2_MIC_BOOST_GAIN_MASK 0x000030 -+#define JZ_CODEC_2_HEADPHONE_VOLUME_MASK 0x000003 -+ -+#define JZ_CODEC_2_INPUT_VOLUME_OFFSET 16 -+#define JZ_CODEC_2_SAMPLE_RATE_OFFSET 8 -+#define JZ_CODEC_2_MIC_BOOST_GAIN_OFFSET 4 -+#define JZ_CODEC_2_HEADPHONE_VOLUME_OFFSET 0 -+ -+struct jz_codec { -+ void __iomem *base; -+ struct resource *mem; -+ -+ uint32_t reg_cache[2]; -+ struct snd_soc_codec codec; -+}; -+ -+inline static struct jz_codec *codec_to_jz(struct snd_soc_codec *codec) -+{ -+ return container_of(codec, struct jz_codec, codec); -+} -+ -+static unsigned int jz_codec_read(struct snd_soc_codec *codec, unsigned int reg) -+{ -+ struct jz_codec *jz_codec = codec_to_jz(codec); -+ return readl(jz_codec->base + (reg << 2)); -+} -+ -+static int jz_codec_write(struct snd_soc_codec *codec, unsigned int reg, -+unsigned int val) -+{ -+ struct jz_codec *jz_codec = codec_to_jz(codec); -+ jz_codec->reg_cache[reg] = val; -+ -+ writel(val, jz_codec->base + (reg << 2)); -+ return 0; -+} -+ -+static const struct snd_kcontrol_new jz_codec_controls[] = { -+ SOC_SINGLE("Master Playback Volume", JZ_REG_CODEC_2, -+ JZ_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0), -+ SOC_SINGLE("Capture Volume", JZ_REG_CODEC_2, -+ JZ_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0), -+ SOC_SINGLE("Master Playback Switch", JZ_REG_CODEC_1, -+ JZ_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1), -+ SOC_SINGLE("Mic Capture Volume", JZ_REG_CODEC_2, -+ JZ_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0), -+}; -+ -+static const struct snd_kcontrol_new jz_codec_output_controls[] = { -+ SOC_DAPM_SINGLE("Bypass Switch", JZ_REG_CODEC_1, -+ JZ_CODEC_1_SW1_ENABLE_OFFSET, 1, 0), -+ SOC_DAPM_SINGLE("DAC Switch", JZ_REG_CODEC_1, -+ JZ_CODEC_1_SW2_ENABLE_OFFSET, 1, 0), -+}; -+ -+static const struct snd_kcontrol_new jz_codec_input_controls[] = -+{ -+ SOC_DAPM_SINGLE("Line Capture Switch", JZ_REG_CODEC_1, -+ JZ_CODEC_1_LINE_ENABLE_OFFSET, 1, 0), -+ SOC_DAPM_SINGLE("Mic Capture Switch", JZ_REG_CODEC_1, -+ JZ_CODEC_1_MIC_ENABLE_OFFSET, 1, 0), -+}; -+ -+static const struct snd_soc_dapm_widget jz_codec_dapm_widgets[] = { -+ SND_SOC_DAPM_ADC("ADC", "Capture", JZ_REG_CODEC_1, -+ JZ_CODEC_1_ADC_ENABLE_OFFSET, 0), -+ SND_SOC_DAPM_DAC("DAC", "Playback", JZ_REG_CODEC_1, -+ JZ_CODEC_1_DAC_ENABLE_OFFSET, 0), -+ -+ SND_SOC_DAPM_MIXER("Output Mixer", JZ_REG_CODEC_1, -+ JZ_CODEC_1_HEADPHONE_POWER_DOWN_OFFSET, 1, -+ jz_codec_output_controls, -+ ARRAY_SIZE(jz_codec_output_controls)), -+ -+ SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0, -+ jz_codec_input_controls, -+ ARRAY_SIZE(jz_codec_input_controls)), -+ SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0), -+ -+ SND_SOC_DAPM_OUTPUT("LOUT"), -+ SND_SOC_DAPM_OUTPUT("ROUT"), -+ -+ SND_SOC_DAPM_INPUT("MIC"), -+ SND_SOC_DAPM_INPUT("LIN"), -+ SND_SOC_DAPM_INPUT("RIN"), -+}; -+ -+static const struct snd_soc_dapm_route jz_codec_dapm_routes[] = { -+ -+ {"Line Input", NULL, "LIN"}, -+ {"Line Input", NULL, "RIN"}, -+ -+ {"Input Mixer", "Line Capture Switch", "Line Input"}, -+ {"Input Mixer", "Mic Capture Switch", "MIC"}, -+ -+ {"ADC", NULL, "Input Mixer"}, -+ -+ {"Output Mixer", "Bypass Switch", "Input Mixer"}, -+ {"Output Mixer", "DAC Switch", "DAC"}, -+ -+ {"LOUT", NULL, "Output Mixer"}, -+ {"ROUT", NULL, "Output Mixer"}, -+}; -+ -+static int jz_codec_hw_params(struct snd_pcm_substream *substream, struct -+snd_pcm_hw_params *params, struct snd_soc_dai *dai) -+{ -+ uint32_t val; -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_device *socdev = rtd->socdev; -+ struct snd_soc_codec *codec = socdev->card->codec; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S8: -+ case SNDRV_PCM_FORMAT_S16_LE: -+ case SNDRV_PCM_FORMAT_S18_3LE: -+ break; -+ default: -+ return -EINVAL; -+ break; -+ } -+ -+ switch (params_rate(params)) { -+ case 8000: -+ val = 0; -+ break; -+ case 11025: -+ val = 1; -+ break; -+ case 12000: -+ val = 2; -+ break; -+ case 16000: -+ val = 3; -+ break; -+ case 22050: -+ val = 4; -+ break; -+ case 24000: -+ val = 5; -+ break; -+ case 32000: -+ val = 6; -+ break; -+ case 44100: -+ val = 7; -+ break; -+ case 48000: -+ val = 8; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ val <<= JZ_CODEC_2_SAMPLE_RATE_OFFSET; -+ -+ snd_soc_update_bits(codec, JZ_REG_CODEC_2, -+ JZ_CODEC_2_SAMPLE_RATE_MASK, val); -+ -+ return 0; -+} -+ -+static int jz_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -+{ -+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBM_CFM: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int jz_codec_set_sysclk(struct snd_soc_dai *codec_dai, -+ int clk_id, unsigned int freq, int dir) -+{ -+ return 0; -+} -+ -+ -+static struct snd_soc_dai_ops jz_codec_dai_ops = { -+ .hw_params = jz_codec_hw_params, -+ .set_fmt = jz_codec_set_fmt, -+/* .set_clkdiv = jz_codec_set_clkdiv,*/ -+ .set_sysclk = jz_codec_set_sysclk, -+}; -+ -+struct snd_soc_dai jz_codec_dai = { -+ .name = "jz-codec", -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_44100, -+ .formats = SNDRV_PCM_FORMAT_S18_3LE, -+ }, -+ .capture = { -+ .stream_name = "Capture", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_44100, -+ .formats = SNDRV_PCM_FORMAT_S16_LE, -+ }, -+ .ops = &jz_codec_dai_ops, -+ .symmetric_rates = 1, -+}; -+EXPORT_SYMBOL_GPL(jz_codec_dai); -+ -+static int jz_codec_set_bias_level(struct snd_soc_codec *codec, -+ enum snd_soc_bias_level level) -+{ -+ -+ if (codec->bias_level == SND_SOC_BIAS_OFF && level != SND_SOC_BIAS_OFF) { -+ snd_soc_update_bits(codec, JZ_REG_CODEC_1, -+ JZ_CODEC_1_RESET, JZ_CODEC_1_RESET); -+ udelay(2); -+ -+ snd_soc_update_bits(codec, JZ_REG_CODEC_1, -+ JZ_CODEC_1_SUSPEND | JZ_CODEC_1_RESET, 0); -+ } -+ switch (level) { -+ case SND_SOC_BIAS_ON: -+ snd_soc_update_bits(codec, JZ_REG_CODEC_1, -+ JZ_CODEC_1_VREF_DISABLE | JZ_CODEC_1_VREF_AMP_DISABLE | -+ JZ_CODEC_1_HEADPHONE_POWER_DOWN_M | -+ JZ_CODEC_1_VREF_LOW_CURRENT | JZ_CODEC_1_VREF_HIGH_CURRENT, -+ 0); -+ break; -+ case SND_SOC_BIAS_PREPARE: -+ snd_soc_update_bits(codec, JZ_REG_CODEC_1, -+ JZ_CODEC_1_VREF_LOW_CURRENT | JZ_CODEC_1_VREF_HIGH_CURRENT, -+ JZ_CODEC_1_VREF_LOW_CURRENT | JZ_CODEC_1_VREF_HIGH_CURRENT); -+ break; -+ case SND_SOC_BIAS_STANDBY: -+ snd_soc_update_bits(codec, JZ_REG_CODEC_1, -+ JZ_CODEC_1_VREF_DISABLE | JZ_CODEC_1_VREF_AMP_DISABLE, -+ JZ_CODEC_1_VREF_DISABLE | JZ_CODEC_1_VREF_AMP_DISABLE); -+ break; -+ case SND_SOC_BIAS_OFF: -+ snd_soc_update_bits(codec, JZ_REG_CODEC_1, -+ JZ_CODEC_1_SUSPEND, JZ_CODEC_1_SUSPEND); -+ break; -+ } -+ codec->bias_level = level; -+ -+ return 0; -+} -+ -+ -+static struct snd_soc_codec *jz_codec_codec; -+ -+static int jz_codec_dev_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct snd_soc_device *socdev = platform_get_drvdata(pdev); -+ struct snd_soc_codec *codec = jz_codec_codec; -+ -+ BUG_ON(!codec); -+ -+ socdev->card->codec = codec; -+ -+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret); -+ goto err; -+ } -+ snd_soc_add_controls(codec, jz_codec_controls, -+ ARRAY_SIZE(jz_codec_controls)); -+ -+ snd_soc_dapm_new_controls(codec, jz_codec_dapm_widgets, -+ ARRAY_SIZE(jz_codec_dapm_widgets)); -+ -+ snd_soc_dapm_add_routes(codec, jz_codec_dapm_routes, -+ ARRAY_SIZE(jz_codec_dapm_routes)); -+ -+ snd_soc_dapm_new_widgets(codec); -+ -+ ret = snd_soc_init_card(socdev); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register card\n"); -+ goto err; -+ } -+ -+ return 0; -+ -+err: -+ snd_soc_free_pcms(socdev); -+ snd_soc_dapm_free(socdev); -+ -+ return ret; -+} -+ -+static int jz_codec_dev_remove(struct platform_device *pdev) -+{ -+ struct snd_soc_device *socdev = platform_get_drvdata(pdev); -+ snd_soc_free_pcms(socdev); -+ snd_soc_dapm_free(socdev); -+ -+ return 0; -+} -+ -+struct snd_soc_codec_device soc_codec_dev_jzcodec = { -+ .probe = jz_codec_dev_probe, -+ .remove = jz_codec_dev_remove, -+}; -+EXPORT_SYMBOL_GPL(soc_codec_dev_jzcodec); -+ -+static int __devinit jz_codec_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct jz_codec *jz_codec; -+ struct snd_soc_codec *codec; -+ -+ jz_codec = kzalloc(sizeof(*jz_codec), GFP_KERNEL); -+ -+ if (!jz_codec) -+ return -ENOMEM; -+ -+ jz_codec->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ if (!jz_codec->mem) { -+ dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); -+ ret = -ENOENT; -+ goto err_free_jz_codec; -+ } -+ -+ jz_codec->mem = request_mem_region(jz_codec->mem->start, -+ resource_size(jz_codec->mem), pdev->name); -+ -+ if (!jz_codec->mem) { -+ dev_err(&pdev->dev, "Failed to request mmio memory region\n"); -+ ret = -EBUSY; -+ goto err_free_jz_codec; -+ } -+ -+ jz_codec->base = ioremap(jz_codec->mem->start, resource_size(jz_codec->mem)); -+ -+ if (!jz_codec->base) { -+ dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); -+ ret = -EBUSY; -+ goto err_release_mem_region; -+ } -+ -+ jz_codec_dai.dev = &pdev->dev; -+ -+ codec = &jz_codec->codec; -+ -+ codec->dev = &pdev->dev; -+ codec->name = "jz-codec"; -+ codec->owner = THIS_MODULE; -+ -+ codec->read = jz_codec_read; -+ codec->write = jz_codec_write; -+ codec->set_bias_level = jz_codec_set_bias_level; -+ codec->bias_level = SND_SOC_BIAS_OFF; -+ -+ codec->dai = &jz_codec_dai; -+ codec->num_dai = 1; -+ -+ codec->reg_cache = jz_codec->reg_cache; -+ codec->reg_cache_size = 2; -+ -+ codec->private_data = jz_codec; -+ -+ mutex_init(&codec->mutex); -+ INIT_LIST_HEAD(&codec->dapm_widgets); -+ INIT_LIST_HEAD(&codec->dapm_paths); -+ -+ jz_codec_codec = codec; -+ -+ platform_set_drvdata(pdev, jz_codec); -+ ret = snd_soc_register_codec(codec); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register codec\n"); -+ goto err_iounmap; -+ } -+ -+ ret = snd_soc_register_dai(&jz_codec_dai); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register codec dai\n"); -+ goto err_unregister_codec; -+ } -+ -+ jz_codec_set_bias_level (codec, SND_SOC_BIAS_STANDBY); -+ -+ return 0; -+err_unregister_codec: -+ snd_soc_unregister_codec(codec); -+err_iounmap: -+ iounmap(jz_codec->base); -+err_release_mem_region: -+ release_mem_region(jz_codec->mem->start, resource_size(jz_codec->mem)); -+err_free_jz_codec: -+ kfree(jz_codec); -+ -+ return ret; -+} -+ -+static int __devexit jz_codec_remove(struct platform_device *pdev) -+{ -+ struct jz_codec *jz_codec = platform_get_drvdata(pdev); -+ -+ snd_soc_unregister_dai(&jz_codec_dai); -+ snd_soc_unregister_codec(&jz_codec->codec); -+ -+ iounmap(jz_codec->base); -+ release_mem_region(jz_codec->mem->start, resource_size(jz_codec->mem)); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(jz_codec); -+ -+ return 0; -+} -+ -+static struct platform_driver jz_codec_driver = { -+ .probe = jz_codec_probe, -+ .remove = __devexit_p(jz_codec_remove), -+ .driver = { -+ .name = "jz4740-codec", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init jz_codec_init(void) -+{ -+ return platform_driver_register(&jz_codec_driver); -+} -+module_init(jz_codec_init); -+ -+static void __exit jz_codec_exit(void) -+{ -+ platform_driver_unregister(&jz_codec_driver); -+} -+module_exit(jz_codec_exit); -+ -+MODULE_DESCRIPTION("JZ4720/JZ4740 SoC internal codec driver"); -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:jz-codec"); -diff -ruN linux-2.6.31-vanilla/sound/soc/codecs/jzcodec.h linux-2.6.31/sound/soc/codecs/jzcodec.h ---- linux-2.6.31-vanilla/sound/soc/codecs/jzcodec.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/codecs/jzcodec.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * -+ * 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. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _ICODEC_H -+#define _ICODEC_H -+ -+#define JZCODEC_SYSCLK 0 -+ -+extern struct snd_soc_dai jz_codec_dai; -+extern struct snd_soc_codec_device soc_codec_dev_jzcodec; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/Kconfig linux-2.6.31/sound/soc/jz4740/Kconfig ---- linux-2.6.31-vanilla/sound/soc/jz4740/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/Kconfig 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,21 @@ -+config SND_JZ4740_SOC -+ tristate "SoC Audio for Ingenic JZ4740 SoC" -+ depends on SOC_JZ4740 && SND_SOC -+ help -+ Say Y or M if you want to add support for codecs attached to -+ the Jz4740 AC97, I2S or SSP interface. You will also need -+ to select the audio interfaces to support below. -+ -+config SND_JZ4740_SOC_QI_LB60 -+ tristate "SoC Audio support for Qi Hardware Ben Nanonote" -+ depends on SND_JZ4740_SOC && JZ4740_QI_LB60 -+ select SND_JZ4740_SOC_I2S -+ select SND_SOC_JZCODEC -+ help -+ Say Y if you want to add support for SoC audio of internal codec on Ingenic Jz4740 QI_LB60 board. -+ -+config SND_JZ4740_SOC_I2S -+ depends on SND_JZ4740_SOC -+ tristate "SoC Audio (I2S protocol) for Ingenic jz4740 chip" -+ help -+ Say Y if you want to use I2S protocol and I2S codec on Ingenic Jz4740 QI_LB60 board. -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/Makefile linux-2.6.31/sound/soc/jz4740/Makefile ---- linux-2.6.31-vanilla/sound/soc/jz4740/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/Makefile 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,13 @@ -+# -+# Jz4740 Platform Support -+# -+snd-soc-jz4740-objs := jz4740-pcm.o -+snd-soc-jz4740-i2s-objs := jz4740-i2s.o -+ -+obj-$(CONFIG_SND_JZ4740_SOC) += snd-soc-jz4740.o -+obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o -+ -+# Jz4740 Machine Support -+snd-soc-qi-lb60-objs := qi_lb60.o -+ -+obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-i2s.c linux-2.6.31/sound/soc/jz4740/jz4740-i2s.c ---- linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-i2s.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/jz4740-i2s.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,309 @@ -+/* -+ * 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. -+ * -+ * Jiejing Zhang(kzjeef(at)gmail.com) 2009: Make jz soc sound card -+ * loaded by soc-core. -+ */ -+ -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/device.h> -+#include <linux/delay.h> -+#include <sound/core.h> -+#include <sound/pcm.h> -+#include <sound/pcm_params.h> -+#include <sound/initval.h> -+#include <sound/soc.h> -+ -+#include "jz4740-pcm.h" -+#include "jz4740-i2s.h" -+ -+static struct jz4740_dma_client jz4740_dma_client_out = { -+ .name = "I2S PCM Stereo out" -+}; -+ -+static struct jz4740_dma_client jz4740_dma_client_in = { -+ .name = "I2S PCM Stereo in" -+}; -+ -+static struct jz4740_pcm_dma_params jz4740_i2s_pcm_stereo_out = { -+ .client = &jz4740_dma_client_out, -+ .channel = DMA_ID_AIC_TX, -+ .dma_addr = AIC_DR, -+ .dma_size = 2, -+}; -+ -+static struct jz4740_pcm_dma_params jz4740_i2s_pcm_stereo_in = { -+ .client = &jz4740_dma_client_in, -+ .channel = DMA_ID_AIC_RX, -+ .dma_addr = AIC_DR, -+ .dma_size = 2, -+}; -+ -+static int jz4740_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -+{ -+ /*struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;*/ -+ -+ return 0; -+} -+ -+static int jz4740_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, -+ unsigned int fmt) -+{ -+ /* interface format */ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ /* 1 : ac97 , 0 : i2s */ -+ break; -+ case SND_SOC_DAIFMT_LEFT_J: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ /* 0 : slave */ -+ break; -+ case SND_SOC_DAIFMT_CBM_CFS: -+ /* 1 : master */ -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+/* -+* Set Jz4740 Clock source -+*/ -+static int jz4740_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai, -+ int clk_id, unsigned int freq, int dir) -+{ -+ return 0; -+} -+ -+static void jz4740_snd_tx_ctrl(int on) -+{ -+ if (on) { -+ /* enable replay */ -+ __i2s_enable_transmit_dma(); -+ __i2s_enable_replay(); -+ __i2s_enable(); -+ -+ } else { -+ /* disable replay & capture */ -+ __i2s_disable_replay(); -+ __i2s_disable_record(); -+ __i2s_disable_receive_dma(); -+ __i2s_disable_transmit_dma(); -+ __i2s_disable(); -+ } -+} -+ -+static void jz4740_snd_rx_ctrl(int on) -+{ -+ if (on) { -+ /* enable capture */ -+ __i2s_enable_receive_dma(); -+ __i2s_enable_record(); -+ __i2s_enable(); -+ -+ } else { -+ /* disable replay & capture */ -+ __i2s_disable_replay(); -+ __i2s_disable_record(); -+ __i2s_disable_receive_dma(); -+ __i2s_disable_transmit_dma(); -+ __i2s_disable(); -+ } -+} -+ -+static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; -+ /* int channels = params_channels(params); */ -+ -+ jz4740_snd_rx_ctrl(0); -+ jz4740_snd_rx_ctrl(0); -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ cpu_dai->dma_data = &jz4740_i2s_pcm_stereo_out; -+ /*if (channels == 1) -+ __aic_enable_mono2stereo(); -+ else -+ __aic_disable_mono2stereo();*/ -+ } else -+ cpu_dai->dma_data = &jz4740_i2s_pcm_stereo_in; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S8: -+ __i2s_set_transmit_trigger(4); -+ __i2s_set_receive_trigger(3); -+ __i2s_set_oss_sample_size(8); -+ __i2s_set_iss_sample_size(8); -+ break; -+ case SNDRV_PCM_FORMAT_S16_LE: -+ /* playback sample:16 bits, burst:16 bytes */ -+ __i2s_set_transmit_trigger(4); -+ /* capture sample:16 bits, burst:16 bytes */ -+ __i2s_set_receive_trigger(3); -+ __i2s_set_oss_sample_size(16); -+ __i2s_set_iss_sample_size(16); -+ break; -+ } -+ -+ return 0; -+} -+ -+static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) -+{ -+ int ret = 0; -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -+ jz4740_snd_rx_ctrl(1); -+ else -+ jz4740_snd_tx_ctrl(1); -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -+ jz4740_snd_rx_ctrl(0); -+ else -+ jz4740_snd_tx_ctrl(0); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -+{ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ } else { -+ } -+ -+ return; -+} -+ -+static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) -+{ -+ __i2s_internal_codec(); -+ __i2s_as_slave(); -+ __i2s_select_i2s(); -+ __aic_select_i2s(); -+ mdelay(2); -+ -+ __i2s_disable(); -+ __i2s_reset(); -+ mdelay(2); -+ -+ __i2s_disable(); -+ __i2s_internal_codec(); -+ __i2s_as_slave(); -+ __i2s_select_i2s(); -+ __aic_select_i2s(); -+ __i2s_set_oss_sample_size(16); -+ __i2s_set_iss_sample_size(16); -+ __aic_play_lastsample(); -+ -+ __i2s_disable_record(); -+ __i2s_disable_replay(); -+ __i2s_disable_loopback(); -+ __i2s_set_transmit_trigger(7); -+ __i2s_set_receive_trigger(7); -+ -+ jz4740_snd_tx_ctrl(0); -+ jz4740_snd_rx_ctrl(0); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int jz4740_i2s_suspend(struct snd_soc_dai *dai) -+{ -+ if (!dai->active) -+ return 0; -+ -+ return 0; -+} -+ -+static int jz4740_i2s_resume(struct snd_soc_dai *dai) -+{ -+ if (!dai->active) -+ return 0; -+ -+ return 0; -+} -+ -+#else -+#define jz4740_i2s_suspend NULL -+#define jz4740_i2s_resume NULL -+#endif -+ -+#define JZ4740_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ -+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ -+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ -+ SNDRV_PCM_RATE_48000) -+ -+struct snd_soc_dai_ops snd_jz4740_i2s_dai_ops = { -+ .startup = jz4740_i2s_startup, -+ .shutdown = jz4740_i2s_shutdown, -+ .trigger = jz4740_i2s_trigger, -+ .hw_params = jz4740_i2s_hw_params, -+ .set_fmt = jz4740_i2s_set_dai_fmt, -+ .set_sysclk = jz4740_i2s_set_dai_sysclk, -+}; -+ -+struct snd_soc_dai jz4740_i2s_dai = { -+ .name = "jz4740-i2s", -+ .id = 0, -+ .probe = jz4740_i2s_probe, -+ .suspend = jz4740_i2s_suspend, -+ .resume = jz4740_i2s_resume, -+ .playback = { -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = JZ4740_I2S_RATES, -+ .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, -+ }, -+ .capture = { -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = JZ4740_I2S_RATES, -+ .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, -+ }, -+ .ops = &snd_jz4740_i2s_dai_ops, -+}; -+ -+EXPORT_SYMBOL_GPL(jz4740_i2s_dai); -+ -+static int __init jz4740_i2s_init(void) -+{ -+ return snd_soc_register_dai(&jz4740_i2s_dai); -+} -+ -+static void __exit jz4740_i2s_exit(void) -+{ -+ snd_soc_unregister_dai(&jz4740_i2s_dai); -+} -+ -+module_init(jz4740_i2s_init); -+module_exit(jz4740_i2s_exit); -+ -+/* Module information */ -+MODULE_AUTHOR("Richard, cjfeng@ingenic.cn, www.ingenic.cn"); -+MODULE_DESCRIPTION("jz4740 I2S SoC Interface"); -+MODULE_LICENSE("GPL"); -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-i2s.h linux-2.6.31/sound/soc/jz4740/jz4740-i2s.h ---- linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-i2s.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/jz4740-i2s.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,18 @@ -+/* -+ * 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 _JZ4740_I2S_H -+#define _JZ4740_I2S_H -+ -+/* jz4740 DAI ID's */ -+#define JZ4740_DAI_I2S 0 -+ -+/* I2S clock */ -+#define JZ4740_I2S_SYSCLK 0 -+ -+extern struct snd_soc_dai jz4740_i2s_dai; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-pcm.c linux-2.6.31/sound/soc/jz4740/jz4740-pcm.c ---- linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-pcm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/jz4740-pcm.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,686 @@ -+/* -+ * -+ * 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 <linux/module.h> -+#include <linux/interrupt.h> -+#include <linux/init.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <linux/dma-mapping.h> -+ -+#include <sound/core.h> -+#include <sound/pcm.h> -+#include <sound/pcm_params.h> -+#include <sound/soc.h> -+ -+#include <asm/io.h> -+#include "jz4740-pcm.h" -+ -+static long sum_bytes = 0; -+static int first_transfer = 0; -+static int printk_flag = 0; -+static int tran_bit = 0; -+#ifdef CONFIG_SND_OSSEMUL -+static int hw_params_cnt = 0; -+#endif -+ -+static struct jz4740_dma_client jz4740_dma_client_out = { -+ .name = "I2S PCM Stereo out" -+}; -+ -+static struct jz4740_dma_client jz4740_dma_client_in = { -+ .name = "I2S PCM Stereo in" -+}; -+ -+static struct jz4740_pcm_dma_params jz4740_i2s_pcm_stereo_out = { -+ .client = &jz4740_dma_client_out, -+ .channel = DMA_ID_AIC_TX, -+ .dma_addr = AIC_DR, -+ .dma_size = 2, -+}; -+ -+static struct jz4740_pcm_dma_params jz4740_i2s_pcm_stereo_in = { -+ .client = &jz4740_dma_client_in, -+ .channel = DMA_ID_AIC_RX, -+ .dma_addr = AIC_DR, -+ .dma_size = 2, -+}; -+ -+ -+struct jz4740_dma_buf_aic { -+ struct jz4740_dma_buf_aic *next; -+ int size; /* buffer size in bytes */ -+ dma_addr_t data; /* start of DMA data */ -+ dma_addr_t ptr; /* where the DMA got to [1] */ -+ void *id; /* client's id */ -+}; -+ -+struct jz4740_runtime_data { -+ spinlock_t lock; -+ int state; -+ int aic_dma_flag; /* start dma transfer or not */ -+ unsigned int dma_loaded; -+ unsigned int dma_limit; -+ unsigned int dma_period; -+ dma_addr_t dma_start; -+ dma_addr_t dma_pos; -+ dma_addr_t dma_end; -+ struct jz4740_pcm_dma_params *params; -+ -+ dma_addr_t user_cur_addr; /* user current write buffer start address */ -+ unsigned int user_cur_len; /* user current write buffer length */ -+ -+ /* buffer list and information */ -+ struct jz4740_dma_buf_aic *curr; /* current dma buffer */ -+ struct jz4740_dma_buf_aic *next; /* next buffer to load */ -+ struct jz4740_dma_buf_aic *end; /* end of queue */ -+ -+}; -+ -+/* identify hardware playback capabilities */ -+static const struct snd_pcm_hardware jz4740_pcm_hardware = { -+ .info = SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_BLOCK_TRANSFER, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S8, -+ .rates = SNDRV_PCM_RATE_8000_48000/*0x3fe*/, -+ .rate_min = 8000, -+ .rate_min = 48000, -+ .channels_min = 2, -+ .channels_max = 2, -+ .buffer_bytes_max = 128 * 1024,//16 * 1024 -+ .period_bytes_min = PAGE_SIZE, -+ .period_bytes_max = PAGE_SIZE * 2, -+ .periods_min = 2, -+ .periods_max = 128,//16, -+ .fifo_size = 32, -+}; -+ -+/* jz4740__dma_buf_enqueue -+ * -+ * queue an given buffer for dma transfer. -+ * -+ * data the physical address of the buffer data -+ * size the size of the buffer in bytes -+ * -+*/ -+static int jz4740_dma_buf_enqueue(struct jz4740_runtime_data *prtd, dma_addr_t data, int size) -+{ -+ struct jz4740_dma_buf_aic *aic_buf; -+ -+ aic_buf = kzalloc(sizeof(struct jz4740_dma_buf_aic), GFP_KERNEL); -+ if (aic_buf == NULL) { -+ printk("aic buffer allocate failed,no memory!\n"); -+ return -ENOMEM; -+ } -+ aic_buf->next = NULL; -+ aic_buf->data = aic_buf->ptr = data; -+ aic_buf->size = size; -+ if( prtd->curr == NULL) { -+ prtd->curr = aic_buf; -+ prtd->end = aic_buf; -+ prtd->next = NULL; -+ } else { -+ if (prtd->end == NULL) -+ printk("prtd->end is NULL\n"); -+ prtd->end->next = aic_buf; -+ prtd->end = aic_buf; -+ } -+ -+ /* if necessary, update the next buffer field */ -+ if (prtd->next == NULL) -+ prtd->next = aic_buf; -+ -+ return 0; -+} -+ -+ -+void audio_start_dma(struct jz4740_runtime_data *prtd, int mode) -+{ -+ unsigned long flags; -+ struct jz4740_dma_buf_aic *aic_buf; -+ int channel; -+ -+ switch (mode) { -+ case DMA_MODE_WRITE: -+ /* free cur aic_buf */ -+ if (first_transfer == 1) { -+ first_transfer = 0; -+ } else { -+ aic_buf = prtd->curr; -+ if (aic_buf != NULL) { -+ prtd->curr = aic_buf->next; -+ prtd->next = aic_buf->next; -+ aic_buf->next = NULL; -+ kfree(aic_buf); -+ aic_buf = NULL; -+ } -+ } -+ -+ aic_buf = prtd->next; -+ channel = prtd->params->channel; -+ if (aic_buf) { -+ disable_dma(channel); -+ jz_set_alsa_dma(channel, mode, tran_bit); -+ set_dma_addr(channel, aic_buf->data); -+ set_dma_count(channel, aic_buf->size); -+ enable_dma(channel); -+ prtd->aic_dma_flag |= AIC_START_DMA; -+ } else { -+ printk("next buffer is NULL for playback\n"); -+ prtd->aic_dma_flag &= ~AIC_START_DMA; -+ return; -+ } -+ break; -+ case DMA_MODE_READ: -+ /* free cur aic_buf */ -+ if (first_transfer == 1) { -+ first_transfer = 0; -+ } else { -+ aic_buf = prtd->curr; -+ if (aic_buf != NULL) { -+ prtd->curr = aic_buf->next; -+ prtd->next = aic_buf->next; -+ aic_buf->next = NULL; -+ kfree(aic_buf); -+ aic_buf = NULL; -+ } -+ } -+ -+ aic_buf = prtd->next; -+ channel = prtd->params->channel; -+ -+ if (aic_buf) { -+ disable_dma(channel); -+ jz_set_alsa_dma(channel, mode, tran_bit); -+ set_dma_addr(channel, aic_buf->data); -+ set_dma_count(channel, aic_buf->size); -+ enable_dma(channel); -+ prtd->aic_dma_flag |= AIC_START_DMA; -+ } else { -+ printk("next buffer is NULL for capture\n"); -+ prtd->aic_dma_flag &= ~AIC_START_DMA; -+ return; -+ } -+ break; -+ } -+ /* dump_jz_dma_channel(channel); */ -+} -+ -+/* -+ * place a dma buffer onto the queue for the dma system to handle. -+*/ -+static void jz4740_pcm_enqueue(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd = runtime->private_data; -+ /*struct snd_dma_buffer *buf = &substream->dma_buffer;*/ -+ dma_addr_t pos = prtd->dma_pos; -+ int ret; -+ -+ while (prtd->dma_loaded < prtd->dma_limit) { -+ unsigned long len = prtd->dma_period; -+ -+ if ((pos + len) > prtd->dma_end) { -+ len = prtd->dma_end - pos; -+ } -+ ret = jz4740_dma_buf_enqueue(prtd, pos, len); -+ if (ret == 0) { -+ prtd->dma_loaded++; -+ pos += prtd->dma_period; -+ if (pos >= prtd->dma_end) -+ pos = prtd->dma_start; -+ } else -+ break; -+ } -+ -+ prtd->dma_pos = pos; -+} -+ -+/* -+ * call the function:jz4740_pcm_dma_irq() after DMA has transfered the current buffer -+ */ -+static irqreturn_t jz4740_pcm_dma_irq(int dma_ch, void *dev_id) -+{ -+ struct snd_pcm_substream *substream = dev_id; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd = runtime->private_data; -+ /*struct jz4740_dma_buf_aic *aic_buf = prtd->curr;*/ -+ int channel = prtd->params->channel; -+ unsigned long flags; -+ -+ disable_dma(channel); -+ prtd->aic_dma_flag &= ~AIC_START_DMA; -+ /* must clear TT bit in DCCSR to avoid interrupt again */ -+ if (__dmac_channel_transmit_end_detected(channel)) { -+ __dmac_channel_clear_transmit_end(channel); -+ } -+ if (__dmac_channel_transmit_halt_detected(channel)) { -+ __dmac_channel_clear_transmit_halt(channel); -+ } -+ -+ if (__dmac_channel_address_error_detected(channel)) { -+ __dmac_channel_clear_address_error(channel); -+ } -+ -+ if (substream) -+ snd_pcm_period_elapsed(substream); -+ -+ spin_lock(&prtd->lock); -+ prtd->dma_loaded--; -+ if (prtd->state & ST_RUNNING) { -+ jz4740_pcm_enqueue(substream); -+ } -+ spin_unlock(&prtd->lock); -+ -+ local_irq_save(flags); -+ if (prtd->state & ST_RUNNING) { -+ if (prtd->dma_loaded) { -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ audio_start_dma(prtd, DMA_MODE_WRITE); -+ else -+ audio_start_dma(prtd, DMA_MODE_READ); -+ } -+ } -+ local_irq_restore(flags); -+ return IRQ_HANDLED; -+} -+ -+/* some parameter about DMA operation */ -+static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd = runtime->private_data; -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct jz4740_pcm_dma_params *dma = &jz4740_i2s_pcm_stereo_out; -+ size_t totbytes = params_buffer_bytes(params); -+ int ret; -+ -+ if (!dma) -+ return 0; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S8: -+ tran_bit = 8; -+ break; -+ case SNDRV_PCM_FORMAT_S16_LE: -+ tran_bit = 16; -+ break; -+ } -+ -+ /* prepare DMA */ -+ prtd->params = dma; -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ret = jz_request_dma(DMA_ID_AIC_TX, prtd->params->client->name, -+ jz4740_pcm_dma_irq, IRQF_DISABLED, substream); -+ if (ret < 0) -+ return ret; -+ prtd->params->channel = ret; -+ } else { -+ ret = jz_request_dma(DMA_ID_AIC_RX, prtd->params->client->name, -+ jz4740_pcm_dma_irq, IRQF_DISABLED, substream); -+ if (ret < 0) -+ return ret; -+ prtd->params->channel = ret; -+ } -+ -+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); -+ runtime->dma_bytes = totbytes; -+ -+ spin_lock_irq(&prtd->lock); -+ prtd->dma_loaded = 0; -+ prtd->aic_dma_flag = 0; -+ prtd->dma_limit = runtime->hw.periods_min; -+ prtd->dma_period = params_period_bytes(params); -+ prtd->dma_start = runtime->dma_addr; -+ prtd->dma_pos = prtd->dma_start; -+ prtd->dma_end = prtd->dma_start + totbytes; -+ prtd->curr = NULL; -+ prtd->next = NULL; -+ prtd->end = NULL; -+ sum_bytes = 0; -+ first_transfer = 1; -+ printk_flag = 0; -+ -+ __dmac_disable_descriptor(prtd->params->channel); -+ __dmac_channel_disable_irq(prtd->params->channel); -+ spin_unlock_irq(&prtd->lock); -+ return ret; -+} -+ -+static int jz4740_pcm_hw_free(struct snd_pcm_substream *substream) -+{ -+ struct jz4740_runtime_data *prtd = substream->runtime->private_data; -+ -+ snd_pcm_set_runtime_buffer(substream, NULL); -+ if (prtd->params) { -+ jz_free_dma(prtd->params->channel); -+ prtd->params = NULL; -+ } -+ -+ return 0; -+} -+ -+/* set some dma para for playback/capture */ -+static int jz4740_dma_ctrl(int channel) -+{ -+ -+ disable_dma(channel); -+ -+ /* must clear TT bit in DCCSR to avoid interrupt again */ -+ if (__dmac_channel_transmit_end_detected(channel)) { -+ __dmac_channel_clear_transmit_end(channel); -+ } -+ if (__dmac_channel_transmit_halt_detected(channel)) { -+ __dmac_channel_clear_transmit_halt(channel); -+ } -+ -+ if (__dmac_channel_address_error_detected(channel)) { -+ __dmac_channel_clear_address_error(channel); -+ } -+ -+ return 0; -+ -+} -+ -+static int jz4740_pcm_prepare(struct snd_pcm_substream *substream) -+{ -+ struct jz4740_runtime_data *prtd = substream->runtime->private_data; -+ int ret = 0; -+ -+ /* return if this is a bufferless transfer e.g */ -+ if (!prtd->params) -+ return 0; -+ -+ /* flush the DMA channel and DMA channel bit check */ -+ jz4740_dma_ctrl(prtd->params->channel); -+ prtd->dma_loaded = 0; -+ prtd->dma_pos = prtd->dma_start; -+ -+ /* enqueue dma buffers */ -+ jz4740_pcm_enqueue(substream); -+ -+ return ret; -+ -+} -+ -+static int jz4740_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd = runtime->private_data; -+ -+ int ret = 0; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ prtd->state |= ST_RUNNING; -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ audio_start_dma(prtd, DMA_MODE_WRITE); -+ } else { -+ audio_start_dma(prtd, DMA_MODE_READ); -+ } -+ -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ prtd->state &= ~ST_RUNNING; -+ break; -+ -+ case SNDRV_PCM_TRIGGER_RESUME: -+ printk(" RESUME \n"); -+ break; -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ printk(" RESTART \n"); -+ break; -+ -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static snd_pcm_uframes_t -+jz4740_pcm_pointer(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd = runtime->private_data; -+ struct jz4740_dma_buf_aic *aic_buf = prtd->curr; -+ long count,res; -+ -+ dma_addr_t ptr; -+ snd_pcm_uframes_t x; -+ int channel = prtd->params->channel; -+ -+ spin_lock(&prtd->lock); -+#if 1 -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ count = get_dma_residue(channel); -+ count = aic_buf->size - count; -+ ptr = aic_buf->data + count; -+ res = ptr - prtd->dma_start; -+ } else { -+ count = get_dma_residue(channel); -+ count = aic_buf->size - count; -+ ptr = aic_buf->data + count; -+ res = ptr - prtd->dma_start; -+ } -+ -+# else -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ if ((prtd->aic_dma_flag & AIC_START_DMA) == 0) { -+ count = get_dma_residue(channel); -+ count = aic_buf->size - count; -+ ptr = aic_buf->data + count; -+ REG_DMAC_DSAR(channel) = ptr; -+ res = ptr - prtd->dma_start; -+ } else { -+ ptr = REG_DMAC_DSAR(channel); -+ if (ptr == 0x0) -+ printk("\ndma address is 00000000 in running!\n"); -+ res = ptr - prtd->dma_start; -+ } -+ } else { -+ if ((prtd->aic_dma_flag & AIC_START_DMA) == 0) { -+ count = get_dma_residue(channel); -+ count = aic_buf->size - count; -+ ptr = aic_buf->data + count; -+ REG_DMAC_DTAR(channel) = ptr; -+ res = ptr - prtd->dma_start; -+ } else { -+ ptr = REG_DMAC_DTAR(channel); -+ if (ptr == 0x0) -+ printk("\ndma address is 00000000 in running!\n"); -+ res = ptr - prtd->dma_start; -+ } -+ } -+#endif -+ spin_unlock(&prtd->lock); -+ x = bytes_to_frames(runtime, res); -+ if (x == runtime->buffer_size) -+ x = 0; -+ -+ return x; -+} -+ -+static int jz4740_pcm_open(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd; -+ -+#ifdef CONFIG_SND_OSSEMUL -+ hw_params_cnt = 0; -+#endif -+ snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware); -+ prtd = kzalloc(sizeof(struct jz4740_runtime_data), GFP_KERNEL); -+ if (prtd == NULL) -+ return -ENOMEM; -+ -+ spin_lock_init(&prtd->lock); -+ -+ runtime->private_data = prtd; -+ REG_AIC_I2SCR = 0x10; -+ return 0; -+} -+ -+static int jz4740_pcm_close(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct jz4740_runtime_data *prtd = runtime->private_data; -+ struct jz4740_dma_buf_aic *aic_buf = NULL; -+ -+#ifdef CONFIG_SND_OSSEMUL -+ hw_params_cnt = 0; -+#endif -+ -+ if (prtd) -+ aic_buf = prtd->curr; -+ -+ while (aic_buf != NULL) { -+ prtd->curr = aic_buf->next; -+ prtd->next = aic_buf->next; -+ aic_buf->next = NULL; -+ kfree(aic_buf); -+ aic_buf = NULL; -+ aic_buf = prtd->curr; -+ } -+ -+ if (prtd) { -+ prtd->curr = NULL; -+ prtd->next = NULL; -+ prtd->end = NULL; -+ kfree(prtd); -+ } -+ -+ return 0; -+} -+ -+static int jz4740_pcm_mmap(struct snd_pcm_substream *substream, -+ struct vm_area_struct *vma) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ return remap_pfn_range(vma, vma->vm_start, -+ substream->dma_buffer.addr >> PAGE_SHIFT, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot); -+} -+ -+struct snd_pcm_ops jz4740_pcm_ops = { -+ .open = jz4740_pcm_open, -+ .close = jz4740_pcm_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = jz4740_pcm_hw_params, -+ .hw_free = jz4740_pcm_hw_free, -+ .prepare = jz4740_pcm_prepare, -+ .trigger = jz4740_pcm_trigger, -+ .pointer = jz4740_pcm_pointer, -+ .mmap = jz4740_pcm_mmap, -+}; -+ -+static int jz4740_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -+{ -+ struct snd_pcm_substream *substream = pcm->streams[stream].substream; -+ struct snd_dma_buffer *buf = &substream->dma_buffer; -+ size_t size = jz4740_pcm_hardware.buffer_bytes_max; -+ buf->dev.type = SNDRV_DMA_TYPE_DEV; -+ buf->dev.dev = pcm->card->dev; -+ buf->private_data = NULL; -+ -+ /*buf->area = dma_alloc_coherent(pcm->card->dev, size, -+ &buf->addr, GFP_KERNEL);*/ -+ buf->area = dma_alloc_noncoherent(pcm->card->dev, size, -+ &buf->addr, GFP_KERNEL); -+ if (!buf->area) -+ return -ENOMEM; -+ buf->bytes = size; -+ return 0; -+} -+ -+static void jz4740_pcm_free_dma_buffers(struct snd_pcm *pcm) -+{ -+ struct snd_pcm_substream *substream; -+ struct snd_dma_buffer *buf; -+ int stream; -+ -+ for (stream = 0; stream < 2; stream++) { -+ substream = pcm->streams[stream].substream; -+ if (!substream) -+ continue; -+ -+ buf = &substream->dma_buffer; -+ if (!buf->area) -+ continue; -+ -+ dma_free_noncoherent(pcm->card->dev, buf->bytes, -+ buf->area, buf->addr); -+ buf->area = NULL; -+ } -+} -+ -+static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32); -+ -+int jz4740_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, -+ struct snd_pcm *pcm) -+{ -+ int ret = 0; -+ -+ printk("pcm new\n"); -+ -+ if (!card->dev->dma_mask) -+ card->dev->dma_mask = &jz4740_pcm_dmamask; -+ if (!card->dev->coherent_dma_mask) -+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32); -+ -+ if (dai->playback.channels_min) { -+ ret = jz4740_pcm_preallocate_dma_buffer(pcm, -+ SNDRV_PCM_STREAM_PLAYBACK); -+ if (ret) -+ goto out; -+ } -+ -+ if (dai->capture.channels_min) { -+ ret = jz4740_pcm_preallocate_dma_buffer(pcm, -+ SNDRV_PCM_STREAM_CAPTURE); -+ if (ret) -+ goto out; -+ } -+ out: -+ -+ return ret; -+} -+ -+struct snd_soc_platform jz4740_soc_platform = { -+ .name = "jz4740-audio", -+ .pcm_ops = &jz4740_pcm_ops, -+ .pcm_new = jz4740_pcm_new, -+ .pcm_free = jz4740_pcm_free_dma_buffers, -+}; -+ -+EXPORT_SYMBOL_GPL(jz4740_soc_platform); -+ -+static int __init jz4740_soc_platform_init(void) -+{ -+ return snd_soc_register_platform(&jz4740_soc_platform); -+} -+module_init(jz4740_soc_platform_init); -+ -+static void __exit jz4740_soc_platform_exit(void) -+{ -+ snd_soc_unregister_platform(&jz4740_soc_platform); -+} -+module_exit(jz4740_soc_platform_exit); -+ -+MODULE_AUTHOR("Richard"); -+MODULE_DESCRIPTION("Ingenic Jz4740 PCM DMA module"); -+MODULE_LICENSE("GPL"); -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-pcm.h linux-2.6.31/sound/soc/jz4740/jz4740-pcm.h ---- linux-2.6.31-vanilla/sound/soc/jz4740/jz4740-pcm.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/jz4740-pcm.h 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,33 @@ -+/* -+ * -+ * 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 _JZ4740_PCM_H -+#define _JZ4740_PCM_H -+ -+#include <asm/jzsoc.h> -+ -+#define ST_RUNNING (1<<0) -+#define ST_OPENED (1<<1) -+ -+#define AIC_START_DMA (1<<0) -+#define AIC_END_DMA (1<<1) -+ -+struct jz4740_dma_client { -+ char *name; -+}; -+ -+struct jz4740_pcm_dma_params { -+ struct jz4740_dma_client *client; /* stream identifier */ -+ int channel; /* Channel ID */ -+ dma_addr_t dma_addr; -+ int dma_size; /* Size of the DMA transfer */ -+}; -+ -+/* platform data */ -+extern struct snd_soc_platform jz4740_soc_platform; -+ -+#endif -diff -ruN linux-2.6.31-vanilla/sound/soc/jz4740/qi_lb60.c linux-2.6.31/sound/soc/jz4740/qi_lb60.c ---- linux-2.6.31-vanilla/sound/soc/jz4740/qi_lb60.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31/sound/soc/jz4740/qi_lb60.c 2009-11-19 19:00:26.000000000 +0100 -@@ -0,0 +1,182 @@ -+/* -+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> -+ * -+ * 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. -+ * -+ * 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 <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/timer.h> -+#include <linux/interrupt.h> -+#include <linux/platform_device.h> -+#include <sound/core.h> -+#include <sound/pcm.h> -+#include <sound/soc.h> -+#include <sound/soc-dapm.h> -+#include <linux/gpio.h> -+ -+#include "../codecs/jzcodec.h" -+#include "jz4740-pcm.h" -+#include "jz4740-i2s.h" -+ -+ -+#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29) -+#define QI_LB60_AMP_GPIO JZ_GPIO_PORTD(4) -+ -+static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, -+ struct snd_kcontrol *ctrl, int event) -+{ -+ int on = 0; -+ if (event & SND_SOC_DAPM_POST_PMU) -+ on = 1; -+ else if (event & SND_SOC_DAPM_PRE_PMD) -+ on = 0; -+ -+ gpio_set_value(QI_LB60_SND_GPIO, on); -+ gpio_set_value(QI_LB60_AMP_GPIO, on); -+ -+ return 0; -+} -+ -+static const struct snd_soc_dapm_widget qi_lb60_widgets[] = { -+ SND_SOC_DAPM_SPK("Speaker", qi_lb60_spk_event), -+ SND_SOC_DAPM_MIC("Mic", NULL), -+}; -+ -+static const struct snd_soc_dapm_route qi_lb60_routes[] = { -+ {"Mic", NULL, "MIC"}, -+ {"Speaker", NULL, "LOUT"}, -+ {"Speaker", NULL, "ROUT"}, -+}; -+ -+#define QI_LB60_DAIFMT (SND_SOC_DAIFMT_I2S | \ -+ SND_SOC_DAIFMT_NB_NF | \ -+ SND_SOC_DAIFMT_CBM_CFM) -+ -+static int qi_lb60_codec_init(struct snd_soc_codec *codec) -+{ -+ int ret; -+ struct snd_soc_dai *cpu_dai = codec->socdev->card->dai_link->cpu_dai; -+ struct snd_soc_dai *codec_dai = codec->socdev->card->dai_link->codec_dai; -+ -+ snd_soc_dapm_nc_pin(codec, "LIN"); -+ snd_soc_dapm_nc_pin(codec, "RIN"); -+ -+ ret = snd_soc_dai_set_fmt(codec_dai, QI_LB60_DAIFMT); -+ if (ret < 0) { -+ dev_err(codec->dev, "Failed to set codec dai format: %d\n", ret); -+ return ret; -+ } -+ -+ ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT); -+ if (ret < 0) { -+ dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret); -+ return ret; -+ } -+ -+ ret = snd_soc_dai_set_sysclk(codec_dai, JZCODEC_SYSCLK, 111, -+ SND_SOC_CLOCK_IN); -+ if (ret < 0) { -+ dev_err(codec->dev, "Failed to set codec dai sysclk: %d\n", ret); -+ return ret; -+ } -+ -+ snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets)); -+ -+ snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes)); -+ -+ snd_soc_dapm_sync(codec); -+ -+ return 0; -+} -+ -+static struct snd_soc_dai_link qi_lb60_dai = { -+ .name = "jz-codec", -+ .stream_name = "JZCODEC", -+ .cpu_dai = &jz4740_i2s_dai, -+ .codec_dai = &jz_codec_dai, -+ .init = qi_lb60_codec_init, -+}; -+ -+static struct snd_soc_card qi_lb60 = { -+ .name = "QI LB60", -+ .dai_link = &qi_lb60_dai, -+ .num_links = 1, -+ .platform = &jz4740_soc_platform, -+}; -+ -+static struct snd_soc_device qi_lb60_snd_devdata = { -+ .card = &qi_lb60, -+ .codec_dev = &soc_codec_dev_jzcodec, -+}; -+ -+static struct platform_device *qi_lb60_snd_device; -+ -+static int __init qi_lb60_init(void) -+{ -+ int ret; -+ -+ qi_lb60_snd_device = platform_device_alloc("soc-audio", -1); -+ -+ if (!qi_lb60_snd_device) -+ return -ENOMEM; -+ -+ -+ ret = gpio_request(QI_LB60_SND_GPIO, "SND"); -+ if (ret) { -+ pr_err("qi_lb60 snd: Failed to request SND GPIO(%d): %d\n", -+ QI_LB60_SND_GPIO, ret); -+ goto err_device_put; -+ } -+ -+ ret = gpio_request(QI_LB60_AMP_GPIO, "AMP"); -+ if (ret) { -+ pr_err("qi_lb60 snd: Failed to request AMP GPIO(%d): %d\n", -+ QI_LB60_AMP_GPIO, ret); -+ goto err_gpio_free_snd; -+ } -+ -+ gpio_direction_output(JZ_GPIO_PORTB(29), 0); -+ gpio_direction_output(JZ_GPIO_PORTD(4), 0); -+ -+ platform_set_drvdata(qi_lb60_snd_device, &qi_lb60_snd_devdata); -+ qi_lb60_snd_devdata.dev = &qi_lb60_snd_device->dev; -+ ret = platform_device_add(qi_lb60_snd_device); -+ if (ret) { -+ pr_err("qi_lb60 snd: Failed to add snd soc device: %d\n", ret); -+ goto err_unset_pdata; -+ } -+ -+ return 0; -+ -+err_unset_pdata: -+ platform_set_drvdata(qi_lb60_snd_device, NULL); -+/*err_gpio_free_amp:*/ -+ gpio_free(QI_LB60_AMP_GPIO); -+err_gpio_free_snd: -+ gpio_free(QI_LB60_SND_GPIO); -+err_device_put: -+ platform_device_put(qi_lb60_snd_device); -+ -+ return ret; -+} -+module_init(qi_lb60_init); -+ -+static void __exit qi_lb60_exit(void) -+{ -+ gpio_free(QI_LB60_AMP_GPIO); -+ gpio_free(QI_LB60_SND_GPIO); -+ platform_device_unregister(qi_lb60_snd_device); -+} -+module_exit(qi_lb60_exit); -+ -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support"); -+MODULE_LICENSE("GPL v2"); |