1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-07-04 20:39:49 +03:00

[xburst] Drop 2.6.32 patches

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22485 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
lars 2010-08-04 13:33:55 +00:00
parent e9a6496d35
commit caec700c9a
92 changed files with 0 additions and 29224 deletions

View File

@ -1,376 +0,0 @@
CONFIG_32BIT=y
# CONFIG_64BIT is not set
# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
# CONFIG_AR7 is not set
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ARPD is not set
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_GENERIC is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_BATTERY_JZ4740 is not set
# CONFIG_BCM47XX is not set
# CONFIG_BCM63XX is not set
CONFIG_BITREVERSE=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BRIDGE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
CONFIG_CFG80211_DEFAULT_PS_VALUE=0
CONFIG_CHARGER_GPIO=y
CONFIG_CONSOLE_TRANSLATIONS=y
# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_CPU_CAVIUM_OCTEON is not set
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_LOONGSON2E is not set
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
CONFIG_CPU_MIPS32=y
# CONFIG_CPU_MIPS64_R1 is not set
# CONFIG_CPU_MIPS64_R2 is not set
CONFIG_CPU_MIPSR1=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R5500 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_VR41XX is not set
CONFIG_CRC16=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_LZO=y
CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_EARLY_PRINTK=y
CONFIG_ELF_CORE=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_FAT_FS=y
# CONFIG_FB_JZ4740 is not set
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FONT_10x18 is not set
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_8x16 is not set
# CONFIG_FONT_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
# CONFIG_FONT_MINI_4x6 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_SUN12x22 is not set
CONFIG_FONT_SUN8x16=y
CONFIG_FONTS=y
CONFIG_FORCE_MAX_ZONEORDER=12
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FRAMEBUFFER_CONSOLE is not set
CONFIG_FREEZER=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GPIOLIB=y
# CONFIG_HAMRADIO is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_OPROFILE=y
# CONFIG_HIBERNATION is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_HW_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_GPIO_BUTTONS is not set
CONFIG_INPUT_KEYBOARD=y
CONFIG_INPUT=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_MULTICAST is not set
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_RARP is not set
CONFIG_IP_PNP=y
CONFIG_IRQ_CPU=y
CONFIG_JBD=y
# CONFIG_JZ4740_ADC is not set
# CONFIG_JZ4740_N516 is not set
# CONFIG_JZ4740_N526 is not set
# CONFIG_JZ4740_QI_LB60 is not set
CONFIG_JZRISC=y
CONFIG_JZSOC=y
CONFIG_KALLSYMS=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_LCD_GPM940B0 is not set
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_LMS283GF05 is not set
# CONFIG_LCD_LTV350QV is not set
# CONFIG_LCD_PLATFORM is not set
# CONFIG_LCD_TDO24M is not set
# CONFIG_LCD_VGG2432A4 is not set
CONFIG_LEGACY_PTY_COUNT=2
CONFIG_LEGACY_PTYS=y
CONFIG_LOCK_KERNEL=y
# CONFIG_LOGO_LINUX_CLUT224 is not set
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_OPENWRT_CLUT224 is not set
# CONFIG_LOGO is not set
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
CONFIG_MACH_JZ=y
# CONFIG_MACH_LOONGSON is not set
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_MINI_FO is not set
# CONFIG_MIPS_COBALT is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_MIPS_MACHINE is not set
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_SIM is not set
CONFIG_MIPS=y
# CONFIG_MMC_AT91 is not set
# CONFIG_MMC_ATMELMCI is not set
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_BLOCK=y
CONFIG_MMC_JZ=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC=y
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_NAND_JZ4740=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
CONFIG_MTD_NAND=y
CONFIG_MTD_UBI_BEB_RESERVE=1
# CONFIG_MTD_UBI_DEBUG is not set
# CONFIG_MTD_UBI_GLUEBI is not set
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI=y
# CONFIG_N516_LPC is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NET_ETHERNET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
# CONFIG_NEW_LEDS is not set
CONFIG_NLS_ASCII=y
CONFIG_NLS_CODEPAGE_1250=y
CONFIG_NLS_CODEPAGE_1251=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_852=y
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_CODEPAGE_949=y
CONFIG_NLS_CODEPAGE_950=y
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_ISO8859_9=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_UTF8=y
CONFIG_NLS=y
# CONFIG_NO_IOPORT is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
# CONFIG_PACKET_MMAP is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PCSPKR_PLATFORM=y
# CONFIG_PDA_POWER is not set
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_PM_SLEEP=y
CONFIG_PM=y
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT=y
CONFIG_PRINTK_TIME=y
CONFIG_RELAY=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_CMOS is not set
CONFIG_RTC_DRV_JZ4740=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_SCSI_DMA is not set
# CONFIG_SDIO_UART is not set
CONFIG_SECCOMP=y
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO=y
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
# CONFIG_SND_SOC_ALL_CODECS is not set
# CONFIG_SND_SOC_JZCODEC is not set
# CONFIG_SND_SOC_JZ4740 is not set
# CONFIG_SND_JZ4740_SOC_N516 is not set
# CONFIG_SND_JZ4740_SOC_N526 is not set
# CONFIG_SND_JZ4740_SOC_QI_LB60 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SQUASHFS is not set
# CONFIG_STAGING is not set
CONFIG_SUSPEND_FREEZER=y
CONFIG_SUSPEND=y
# CONFIG_SYN_COOKIES is not set
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_TRAD_SIGNALS=y
# CONFIG_TREE_PREEMPT_RCU is not set
CONFIG_TREE_RCU=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
# CONFIG_UBIFS_FS_DEBUG is not set
CONFIG_UBIFS_FS_LZO=y
# CONFIG_UBIFS_FS_XATTR is not set
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ZLIB=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_CDC_COMPOSITE is not set
# CONFIG_USB_ETH_EEM is not set
CONFIG_USB_ETH_RNDIS=y
CONFIG_USB_ETH=y
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_GADGET_AMD5536UDC is not set
# CONFIG_USB_GADGET_AT91 is not set
# CONFIG_USB_GADGET_ATMEL_USBA is not set
# CONFIG_USB_GADGET_CI13XXX is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
# CONFIG_USB_GADGET_DEBUG_FS is not set
CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_GADGET_DUMMY_HCD is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_GADGET_FSL_QE is not set
# CONFIG_USB_GADGET_FSL_USB2 is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_IMX is not set
CONFIG_USB_GADGET_JZ4740=y
# CONFIG_USB_GADGET_LANGWELL is not set
# CONFIG_USB_GADGET_LH7A40X is not set
# CONFIG_USB_GADGET_M66592 is not set
# CONFIG_USB_GADGET_MUSB_HDRC is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_PXA25X is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_R8A66597 is not set
# CONFIG_USB_GADGET_S3C2410 is not set
# CONFIG_USB_GADGET_S3C_HSOTG is not set
CONFIG_USB_GADGET_SELECTED=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET=y
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_G_SERIAL is not set
CONFIG_USB_JZ4740=y
# CONFIG_USB_MIDI_GADGET is not set
CONFIG_USB_SUPPORT=y
# CONFIG_USB_ZERO is not set
CONFIG_VFAT_FS=y
# CONFIG_VGA_CONSOLE is not set
# CONFIG_VLAN_8021Q is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_VT=y
# CONFIG_WATCHDOG is not set
# CONFIG_WLAN_80211 is not set
CONFIG_ZONE_DMA_FLAG=0

View File

@ -1,42 +0,0 @@
#
# 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

View File

@ -1,4 +0,0 @@
int main(void)
{
return 0;
}

View File

@ -1,85 +0,0 @@
/*
* 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

View File

@ -1,151 +0,0 @@
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) }
}

View File

@ -1,242 +0,0 @@
/*
* 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.");
}

View File

@ -1,12 +0,0 @@
#!/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

View File

@ -1,7 +0,0 @@
#!/bin/sh
HOSTNAME=`uname`
if [ "$HOSTNAME" = "Linux" ]; then
echo `ls -l $1 | awk '{print $5}'`
else
echo `ls -l $1 | awk '{print $6}'`
fi

View File

@ -1,39 +0,0 @@
/*
* linux/include/asm-mips/mach-jz4740/board-n516.h
*
* JZ4730-based N516 board definition.
*
* Copyright (C) 2009, Yauhen Kharuzhy <jekhor@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.
*/
#ifndef __ASM_JZ4740_N516_H__
#define __ASM_JZ4740_N516_H__
#include <asm/mach-jz4740/gpio.h>
/*
* GPIO
*/
#define GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(17)
#define GPIO_SD_CD_N JZ_GPIO_PORTD(7)
#define GPIO_SD_WP JZ_GPIO_PORTD(15)
#define GPIO_USB_DETECT JZ_GPIO_PORTD(19)
#define GPIO_CHARG_STAT_N JZ_GPIO_PORTD(16)
#define GPIO_LED_ENABLE JZ_GPIO_PORTD(28)
#define GPIO_LPC_INT JZ_GPIO_PORTD(14)
#define GPIO_HPHONE_DETECT JZ_GPIO_PORTD(20)
#define GPIO_SPEAKER_ENABLE JZ_GPIO_PORTD(21)
/* Display */
#define GPIO_DISPLAY_RST_L JZ_GPIO_PORTB(18)
#define GPIO_DISPLAY_RDY JZ_GPIO_PORTB(17)
#define GPIO_DISPLAY_STBY JZ_GPIO_PORTC(22)
#define GPIO_DISPLAY_ERR JZ_GPIO_PORTC(23)
#define GPIO_DISPLAY_OFF_N JZ_GPIO_PORTD(1)
#endif /* __ASM_JZ4740_N516_H__ */

View File

@ -1,51 +0,0 @@
/*
* 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>
/*
* 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_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)
#endif /* __ASM_JZ4740_QI_LB60_H__ */

View File

@ -1,31 +0,0 @@
/*
* 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__
#include <asm/mach-jz4740/regs.h>
enum jz4740_wait_mode
{
JZ4740_WAIT_MODE_IDLE,
JZ4740_WAIT_MODE_SLEEP,
};
void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
void jz4740_clock_udc_enable_auto_suspend(void);
void jz4740_clock_udc_disable_auto_suspend(void);
#endif /* __ASM_JZ4740_CLOCK_H__ */

View File

@ -1,90 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ7420/JZ4740 DMA 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 __ASM_MACH_JZ4740_DMA_H__
#define __ASM_MACH_JZ4740_DMA_H__
struct jz4740_dma_chan;
enum jz4740_dma_request_type {
JZ4740_DMA_TYPE_AUTO_REQUEST = 8,
JZ4740_DMA_TYPE_UART_TRANSMIT = 20,
JZ4740_DMA_TYPE_UART_RECEIVE = 21,
JZ4740_DMA_TYPE_SPI_TRANSMIT = 22,
JZ4740_DMA_TYPE_SPI_RECEIVE = 23,
JZ4740_DMA_TYPE_AIC_TRANSMIT = 24,
JZ4740_DMA_TYPE_AIC_RECEIVE = 25,
JZ4740_DMA_TYPE_MMC_TRANSMIT = 26,
JZ4740_DMA_TYPE_MMC_RECEIVE = 27,
JZ4740_DMA_TYPE_TCU = 28,
JZ4740_DMA_TYPE_SADC = 29,
JZ4740_DMA_TYPE_SLCD = 30,
};
enum jz4740_dma_width {
JZ4740_DMA_WIDTH_8BIT,
JZ4740_DMA_WIDTH_16BIT,
JZ4740_DMA_WIDTH_32BIT,
};
enum jz4740_dma_transfer_size {
JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0,
JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1,
JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2,
JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
};
enum jz4740_dma_flags {
JZ4740_DMA_SRC_AUTOINC = 0x2,
JZ4740_DMA_DST_AUTOINC = 0x1,
};
enum jz4740_dma_mode {
JZ4740_DMA_MODE_SINGLE = 0,
JZ4740_DMA_MODE_BLOCK = 1,
};
struct jz4740_dma_config {
enum jz4740_dma_width src_width;
enum jz4740_dma_width dst_width;
enum jz4740_dma_transfer_size transfer_size;
enum jz4740_dma_request_type request_type;
enum jz4740_dma_flags flags;
enum jz4740_dma_mode mode;
};
typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int , void *);
struct jz4740_dma_chan* jz4740_dma_request(void *dev, const char *name);
void jz4740_dma_free(struct jz4740_dma_chan *dma);
void jz4740_dma_configure(struct jz4740_dma_chan *dma,
const struct jz4740_dma_config *config);
void jz4740_dma_enable(struct jz4740_dma_chan *dma);
void jz4740_dma_disable(struct jz4740_dma_chan *dma);
void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
jz4740_dma_complete_callback_t cb);
#endif /* __ASM_JZ4740_DMA_H__ */

View File

@ -1,393 +0,0 @@
/*
* 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_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
void jz_gpio_bulk_resume(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);
int jz_gpio_port_direction_input(int port, uint32_t mask);
int jz_gpio_port_direction_output(int port, uint32_t mask);
void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
#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

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ7420/JZ4740 IRQ 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 __ASM_MACH_JZ4740_IRQ_H__
#define __ASM_MACH_JZ4740_IRQ_H__
#define MIPS_CPU_IRQ_BASE 0
#define JZ_IRQ_BASE 8
/* 1st-level interrupts */
#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 JZ_IRQ_INTC_GPIO(x) (JZ_IRQ_GPIO0 - (x))
#define JZ_IRQ_GPIO(x) (JZ_IRQ(48) + (x))
#define NR_IRQS (JZ_IRQ_GPIO(127) + 1)
#endif

View File

@ -1,35 +0,0 @@
/*
* 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/dma.h>
/*------------------------------------------------------------------
* Platform definitions
*/
#ifdef CONFIG_JZ4740_QI_LB60
#include <asm/mach-jz4740/board-qi_lb60.h>
#endif
/*------------------------------------------------------------------
* Follows are related to platform definitions
*/
#include <asm/mach-jz4740/serial.h>
#endif /* __ASM_JZ4740_H__ */

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
* JZ7420/JZ4740 platform device 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 __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

View File

@ -1,519 +0,0 @@
/*
* 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
/*************************************************************************
* 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 */
/*************************************************************************
* 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)
/*************************************************************************
* 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)
/*************************************************************************
* 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 */
#endif /* __JZ4740_REGS_H__ */

View File

@ -1,30 +0,0 @@
/*
* 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__ */

View File

@ -1,22 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 platform timer 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.
*
*/
#ifndef __ASM_MACH_JZ4740_TIMER
#define __ASM_MACH_JZ4740_TIMER
void jz4740_timer_enable_watchdog(void);
void jz4740_timer_disable_watchdog(void);
#endif

View File

@ -1,25 +0,0 @@
/*
* 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 */

View File

@ -1,40 +0,0 @@
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
config JZ4740_N516
bool "Hanvon n516 eBook reader"
select DMA_NONCOHERENT
select SOC_JZ4740
config JZ4740_N526
bool "Hanvon n526 eBook reader"
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

View File

@ -1,21 +0,0 @@
#
# 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_DEBUG_FS) += clock-debugfs.o
# board specific support
obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
obj-$(CONFIG_JZ4740_N526) += board-n526.o
# PM support
obj-$(CONFIG_PM) += pm.o

View File

@ -1,395 +0,0 @@
/*
* board-n516-display.c -- Platform device for N516 display
*
* Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com>
*
* 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.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/jz4740_fb.h>
#include <asm/mach-jz4740/platform.h>
#include <asm/mach-jz4740/board-n516.h>
#include <video/metronomefb.h>
#include <linux/console.h>
extern struct platform_device jz_lcd_device;
static struct fb_videomode n516_fb_modes[] = {
[0] = {
.name = "Metronome 800x600",
.refresh = 50,
.xres = 400,
.yres = 624,
.hsync_len = 31,
.vsync_len = 23,
.right_margin = 31,
.left_margin = 5,
.upper_margin = 1,
.lower_margin = 2,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
},
};
static struct jz4740_fb_platform_data n516_fb_pdata = {
.num_modes = ARRAY_SIZE(n516_fb_modes),
.modes = n516_fb_modes,
.bpp = 16,
.lcd_type = JZ_LCD_TYPE_GENERIC_16_BIT,
};
struct n516_board_info {
uint8_t *metromem;
size_t wfm_size;
struct fb_info *host_fbinfo; /* the host LCD controller's fbi */
unsigned int fw;
unsigned int fh;
};
static struct platform_device *n516_device;
static struct n516_board_info n516_board_info;
static int metronome_gpios[] = {
GPIO_DISPLAY_STBY,
GPIO_DISPLAY_RST_L,
GPIO_DISPLAY_RDY,
GPIO_DISPLAY_ERR,
/* GPIO_DISPLAY_OFF,*/
};
static const char *metronome_gpio_names[] = {
"Metronome STDBY",
"Metronome RST",
"Metronome RDY",
"Metronome ERR",
/* "Metronone OFF",*/
};
static int n516_enable_hostfb(bool enable)
{
int ret;
int blank = enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
acquire_console_sem();
ret = fb_blank(n516_board_info.host_fbinfo, blank);
release_console_sem();
return ret;
}
static int n516_init_metronome_gpios(struct metronomefb_par *par)
{
int i;
int ret;
for (i = 0; i < ARRAY_SIZE(metronome_gpios); ++i) {
ret = gpio_request(metronome_gpios[i], metronome_gpio_names[i]);
if (ret)
goto err;
}
gpio_direction_output(GPIO_DISPLAY_OFF, 0);
gpio_direction_output(GPIO_DISPLAY_RST_L, 0);
gpio_direction_output(GPIO_DISPLAY_STBY, 0);
gpio_direction_input(GPIO_DISPLAY_RDY);
gpio_direction_input(GPIO_DISPLAY_ERR);
return 0;
err:
for (--i; i >= 0; --i)
gpio_free(metronome_gpios[i]);
return ret;
}
static int n516_share_video_mem(struct fb_info *info)
{
int ret;
dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
dev_dbg(&n516_device->dev, "%s, info->var.xres = %u, info->var.yres = %u\n", __func__, info->var.xres, info->var.yres);
/* rough check if this is our desired fb and not something else */
if ((info->var.xres != n516_fb_pdata.modes[0].xres)
|| (info->var.yres != n516_fb_pdata.modes[0].yres))
return 0;
/* we've now been notified that we have our new fb */
n516_board_info.metromem = info->screen_base;
n516_board_info.host_fbinfo = info;
n516_enable_hostfb(false);
/* try to refcount host drv since we are the consumer after this */
if (!try_module_get(info->fbops->owner))
return -ENODEV;
/* this _add binds metronomefb to n516. metronomefb refcounts n516 */
ret = platform_device_add(n516_device);
if (ret) {
platform_device_put(n516_device);
return ret;
}
/* request our platform independent driver */
request_module("metronomefb");
return 0;
}
static int n516_unshare_video_mem(struct fb_info *info)
{
dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
if (info != n516_board_info.host_fbinfo)
return 0;
module_put(n516_board_info.host_fbinfo->fbops->owner);
return 0;
}
static int n516_fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct fb_event *evdata = data;
struct fb_info *info = evdata->info;
dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
if (event == FB_EVENT_FB_REGISTERED)
return n516_share_video_mem(info);
else if (event == FB_EVENT_FB_UNREGISTERED)
return n516_unshare_video_mem(info);
return 0;
}
static struct notifier_block n516_fb_notif = {
.notifier_call = n516_fb_notifier_callback,
};
/* this gets called as part of our init. these steps must be done now so
* that we can use set_pxa_fb_info */
static void __init n516_presetup_fb(void)
{
int padding_size;
int totalsize;
/* the frame buffer is divided as follows:
command | CRC | padding
16kb waveform data | CRC | padding
image data | CRC
*/
n516_board_info.fw = 800;
n516_board_info.fh = 624;
/* waveform must be 16k + 2 for checksum */
n516_board_info.wfm_size = roundup(16*1024 + 2, n516_board_info.fw);
padding_size = PAGE_SIZE + (4 * n516_board_info.fw);
/* total is 1 cmd , 1 wfm, padding and image */
totalsize = n516_board_info.fw + n516_board_info.wfm_size;
totalsize += padding_size + (n516_board_info.fw*n516_board_info.fh);
/* save this off because we're manipulating fw after this and
* we'll need it when we're ready to setup the framebuffer */
/* the reason we do this adjustment is because we want to acquire
* more framebuffer memory without imposing custom awareness on the
* underlying driver */
n516_fb_pdata.modes[0].yres = DIV_ROUND_UP(totalsize, n516_board_info.fw);
jz4740_framebuffer_device.dev.platform_data = &n516_fb_pdata;
platform_device_register(&jz4740_framebuffer_device);
}
/* this gets called by metronomefb as part of its init, in our case, we
* have already completed initial framebuffer init in presetup_fb so we
* can just setup the fb access pointers */
static int n516_setup_fb(struct metronomefb_par *par)
{
/* metromem was set up by the notifier in share_video_mem so now
* we can use its value to calculate the other entries */
par->metromem_cmd = (struct metromem_cmd *) n516_board_info.metromem;
par->metromem_wfm = n516_board_info.metromem + n516_board_info.fw;
par->metromem_img = par->metromem_wfm + n516_board_info.wfm_size;
par->metromem_img_csum = (u16 *) (par->metromem_img + (n516_board_info.fw * n516_board_info.fh));
par->metromem_dma = n516_board_info.host_fbinfo->fix.smem_start;
return 0;
}
static int n516_get_panel_type(void)
{
return 5;
}
static irqreturn_t n516_handle_irq(int irq, void *dev_id)
{
struct metronomefb_par *par = dev_id;
dev_dbg(&par->pdev->dev, "Metronome IRQ! RDY=%d\n", gpio_get_value(GPIO_DISPLAY_RDY));
wake_up_all(&par->waitq);
return IRQ_HANDLED;
}
static void n516_power_ctl(struct metronomefb_par *par, int cmd)
{
switch (cmd) {
case METRONOME_POWER_OFF:
gpio_set_value(GPIO_DISPLAY_OFF, 1);
n516_enable_hostfb(false);
break;
case METRONOME_POWER_ON:
gpio_set_value(GPIO_DISPLAY_OFF, 0);
n516_enable_hostfb(true);
break;
}
}
static int n516_get_rdy(struct metronomefb_par *par)
{
return gpio_get_value(GPIO_DISPLAY_RDY);
}
static int n516_get_err(struct metronomefb_par *par)
{
return gpio_get_value(GPIO_DISPLAY_ERR);
}
static int n516_setup_irq(struct fb_info *info)
{
int ret;
dev_dbg(&n516_device->dev, "ENTER %s\n", __func__);
ret = request_irq(gpio_to_irq(GPIO_DISPLAY_RDY), n516_handle_irq,
IRQF_TRIGGER_RISING,
"n516", info->par);
if (ret)
dev_err(&n516_device->dev, "request_irq failed: %d\n", ret);
return ret;
}
static void n516_set_rst(struct metronomefb_par *par, int state)
{
dev_dbg(&n516_device->dev, "ENTER %s, RDY=%d\n", __func__, gpio_get_value(GPIO_DISPLAY_RDY));
if (state)
gpio_set_value(GPIO_DISPLAY_RST_L, 1);
else
gpio_set_value(GPIO_DISPLAY_RST_L, 0);
}
static void n516_set_stdby(struct metronomefb_par *par, int state)
{
dev_dbg(&n516_device->dev, "ENTER %s, RDY=%d\n", __func__, gpio_get_value(GPIO_DISPLAY_RDY));
if (state)
gpio_set_value(GPIO_DISPLAY_STBY, 1);
else
gpio_set_value(GPIO_DISPLAY_STBY, 0);
}
static int n516_wait_event(struct metronomefb_par *par)
{
unsigned long timeout = jiffies + HZ / 20;
dev_dbg(&n516_device->dev, "ENTER1 %s, RDY=%d\n",
__func__, gpio_get_value(GPIO_DISPLAY_RDY));
while (n516_get_rdy(par) && time_before(jiffies, timeout))
schedule();
dev_dbg(&n516_device->dev, "ENTER2 %s, RDY=%d\n",
__func__, gpio_get_value(GPIO_DISPLAY_RDY));
return wait_event_timeout(par->waitq,
n516_get_rdy(par), HZ * 2) ? 0 : -EIO;
}
static int n516_wait_event_intr(struct metronomefb_par *par)
{
unsigned long timeout = jiffies + HZ/20;
dev_dbg(&n516_device->dev, "ENTER1 %s, RDY=%d\n",
__func__, gpio_get_value(GPIO_DISPLAY_RDY));
while (n516_get_rdy(par) && time_before(jiffies, timeout))
schedule();
dev_dbg(&n516_device->dev, "ENTER2 %s, RDY=%d\n",
__func__, gpio_get_value(GPIO_DISPLAY_RDY));
return wait_event_interruptible_timeout(par->waitq,
n516_get_rdy(par), HZ * 2) ? 0 : -EIO;
}
static void n516_cleanup(struct metronomefb_par *par)
{
int i;
free_irq(gpio_to_irq(GPIO_DISPLAY_RDY), par);
for (i = 0; i < ARRAY_SIZE(metronome_gpios); ++i)
gpio_free(metronome_gpios[i]);
}
static struct metronome_board n516_board __initdata = {
.owner = THIS_MODULE,
.power_ctl = n516_power_ctl,
.setup_irq = n516_setup_irq,
.setup_io = n516_init_metronome_gpios,
.setup_fb = n516_setup_fb,
.set_rst = n516_set_rst,
.get_err = n516_get_err,
.get_rdy = n516_get_rdy,
.set_stdby = n516_set_stdby,
.met_wait_event = n516_wait_event,
.met_wait_event_intr = n516_wait_event_intr,
.get_panel_type = n516_get_panel_type,
.cleanup = n516_cleanup,
};
static int __init n516_init(void)
{
int ret;
/* Keep the metronome off, until its driver is loaded */
ret = gpio_request(GPIO_DISPLAY_OFF, "Display off");
if (ret)
return ret;
gpio_direction_output(GPIO_DISPLAY_OFF, 1);
/* before anything else, we request notification for any fb
* creation events */
fb_register_client(&n516_fb_notif);
n516_device = platform_device_alloc("metronomefb", -1);
if (!n516_device)
return -ENOMEM;
/* the n516_board that will be seen by metronomefb is a copy */
platform_device_add_data(n516_device, &n516_board,
sizeof(n516_board));
n516_presetup_fb();
return 0;
}
module_init(n516_init);
MODULE_DESCRIPTION("board driver for n516 display");
MODULE_AUTHOR("Yauhen Kharuzhy");
MODULE_LICENSE("GPL");

View File

@ -1,201 +0,0 @@
/*
* linux/arch/mips/jz4740/board-516.c
*
* JZ4740 n516 board setup routines.
*
* Copyright (c) 2009, Yauhen Kharuzhy <jekhor@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.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mmc/jz4740_mmc.h>
#include <linux/mtd/jz4740_nand.h>
#include <linux/leds.h>
#include <linux/power_supply.h>
#include <linux/power/gpio-charger.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <asm/mach-jz4740/board-n516.h>
#include <asm/mach-jz4740/platform.h>
#include "clock.h"
static long n516_panic_blink(long time)
{
gpio_set_value(GPIO_LED_ENABLE, 1);
mdelay(200);
gpio_set_value(GPIO_LED_ENABLE, 0);
mdelay(200);
return 400;
}
static void __init board_gpio_setup(void)
{
/* jz_gpio_enable_pullup(JZ_GPIO_PORTD(23));
jz_gpio_enable_pullup(JZ_GPIO_PORTD(24));*/
}
static struct i2c_gpio_platform_data n516_i2c_pdata = {
.sda_pin = JZ_GPIO_PORTD(23),
.scl_pin = JZ_GPIO_PORTD(24),
.udelay = 2,
.timeout = 3 * HZ,
};
static struct platform_device n516_i2c_device = {
.name = "i2c-gpio",
.id = -1,
.dev = {
.platform_data = &n516_i2c_pdata,
},
};
static const struct i2c_board_info n516_i2c_board_info[] = {
{
.type = "LPC524",
.addr = 0x54,
},
{
.type = "lm75a",
.addr = 0x48,
}
};
static struct jz4740_mmc_platform_data n516_mmc_pdata = {
.gpio_card_detect = GPIO_SD_CD_N,
.card_detect_active_low = 1,
.gpio_read_only = -1,
.gpio_power = GPIO_SD_VCC_EN_N,
.power_active_low = 1,
};
static struct gpio_led n516_leds[] = {
{
.name = "n516:blue:power",
.gpio = GPIO_LED_ENABLE,
.default_state = LEDS_GPIO_DEFSTATE_ON,
.default_trigger = "nand-disk",
}
};
static struct gpio_led_platform_data n516_leds_pdata = {
.leds = n516_leds,
.num_leds = ARRAY_SIZE(n516_leds),
};
static struct platform_device n516_leds_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &n516_leds_pdata,
},
};
static struct mtd_partition n516_partitions[] = {
{ .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,
},
};
static struct nand_ecclayout n516_ecclayout = {
.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 jz_nand_platform_data n516_nand_pdata = {
.ecc_layout = &n516_ecclayout,
.partitions = n516_partitions,
.num_partitions = ARRAY_SIZE(n516_partitions),
.busy_gpio = 94,
};
static char *n516_batteries[] = {
"n516_battery",
};
static struct gpio_charger_platform_data n516_charger_pdata = {
.name = "usb",
.type = POWER_SUPPLY_TYPE_USB,
.gpio = GPIO_USB_DETECT,
.gpio_active_low = 1,
.batteries = n516_batteries,
.num_batteries = ARRAY_SIZE(n516_batteries),
};
static struct platform_device n516_charger_device = {
.name = "gpio-charger",
.dev = {
.platform_data = &n516_charger_pdata,
},
};
static struct platform_device *n516_devices[] __initdata = {
&jz4740_nand_device,
&n516_leds_device,
&jz4740_mmc_device,
&jz4740_i2s_device,
&jz4740_codec_device,
&jz4740_rtc_device,
&jz4740_usb_gdt_device,
&n516_i2c_device,
&n516_charger_device,
};
struct jz4740_clock_board_data jz4740_clock_bdata = {
.ext_rate = 12000000,
.rtc_rate = 32768,
};
extern int jz_gpiolib_init(void);
static int n516_setup_platform(void)
{
if (jz_gpiolib_init())
panic("Failed to initalize jz gpio\n");
jz4740_clock_init();
board_gpio_setup();
panic_blink = n516_panic_blink;
i2c_register_board_info(0, n516_i2c_board_info, ARRAY_SIZE(n516_i2c_board_info));
jz4740_mmc_device.dev.platform_data = &n516_mmc_pdata;
jz4740_nand_device.dev.platform_data = &n516_nand_pdata;
return platform_add_devices(n516_devices, ARRAY_SIZE(n516_devices));
}
arch_initcall(n516_setup_platform);

View File

@ -1,333 +0,0 @@
/*
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
* N526 eBook reader 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/init.h>
#include <linux/gpio.h>
#include <asm/mach-jz4740/platform.h>
#include <linux/mtd/jz4740_nand.h>
#include <linux/jz4740_fb.h>
#include <linux/power_supply.h>
#include <linux/mmc/jz4740_mmc.h>
#include <video/broadsheetfb.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include "clock.h"
/* NAND */
static struct nand_ecclayout n526_ecclayout = {
.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 n526_partitions[] = {
{ .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 = 16 * 0x100000,
.size = 498 * 0x100000,
},
};
static struct jz_nand_platform_data n526_nand_pdata = {
.ecc_layout = &n526_ecclayout,
.partitions = n526_partitions,
.num_partitions = ARRAY_SIZE(n526_partitions),
.busy_gpio = 94,
};
static struct jz4740_mmc_platform_data n526_mmc_pdata = {
.gpio_card_detect = JZ_GPIO_PORTD(7),
.card_detect_active_low = 1,
.gpio_read_only = -1,
.gpio_power = JZ_GPIO_PORTD(17),
.power_active_low = 1,
};
static struct gpio_led n526_leds[] = {
{
.name = "n526:blue:power",
.gpio = JZ_GPIO_PORTD(28),
.default_state = LEDS_GPIO_DEFSTATE_ON,
}
};
static struct gpio_led_platform_data n526_leds_pdata = {
.leds = n526_leds,
.num_leds = ARRAY_SIZE(n526_leds),
};
static struct platform_device n526_leds_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &n526_leds_pdata,
},
};
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(JZ_GPIO_PORTD(17));
jz_gpio_enable_pullup(JZ_GPIO_PORTD(7));
jz_gpio_disable_pullup(JZ_GPIO_PORTC(19));
jz_gpio_disable_pullup(JZ_GPIO_PORTC(20));
jz_gpio_disable_pullup(JZ_GPIO_PORTC(21));
jz_gpio_disable_pullup(JZ_GPIO_PORTC(23));
}
static const int n526_eink_ctrl_gpios[] = {
0,
JZ_GPIO_PORTC(23),
JZ_GPIO_PORTC(19),
JZ_GPIO_PORTC(20),
};
static void n526_eink_set_ctl(struct broadsheetfb_par * par, unsigned char ctrl, u8
value)
{
gpio_set_value(n526_eink_ctrl_gpios[ctrl], value);
}
static int n526_eink_wait(struct broadsheetfb_par *par)
{
wait_event(par->waitq, gpio_get_value(JZ_GPIO_PORTB(17)));
return 0;
}
static u16 n526_eink_get_hdb(struct broadsheetfb_par *par)
{
u16 value = 0;
jz_gpio_port_direction_input(JZ_GPIO_PORTC(0), 0xffff);
gpio_set_value(JZ_GPIO_PORTC(21), 0);
mdelay(100);
value = jz_gpio_port_get_value(JZ_GPIO_PORTC(0), 0xffff);
gpio_set_value(JZ_GPIO_PORTC(21), 1);
jz_gpio_port_direction_output(JZ_GPIO_PORTC(0), 0xffff);
return value;
}
static void n526_eink_set_hdb(struct broadsheetfb_par *par, u16 value)
{
jz_gpio_port_set_value(JZ_GPIO_PORTC(0), value, 0xffff);
}
static int n526_eink_init(struct broadsheetfb_par *par)
{
int i;
gpio_request(JZ_GPIO_PORTD(1), "display reset");
gpio_direction_output(JZ_GPIO_PORTD(1), 1);
mdelay(10);
gpio_set_value(JZ_GPIO_PORTD(1), 0);
gpio_request(JZ_GPIO_PORTB(18), "eink enable");
gpio_direction_output(JZ_GPIO_PORTB(18), 0);
gpio_request(JZ_GPIO_PORTB(29), "foobar");
gpio_direction_output(JZ_GPIO_PORTB(29), 1);
for(i = 1; i < ARRAY_SIZE(n526_eink_ctrl_gpios); ++i) {
gpio_request(n526_eink_ctrl_gpios[i], "eink display ctrl");
gpio_direction_output(n526_eink_ctrl_gpios[i], 0);
}
gpio_request(JZ_GPIO_PORTC(22), "foobar");
gpio_direction_input(JZ_GPIO_PORTC(22));
gpio_request(JZ_GPIO_PORTC(21), "eink nRD");
gpio_direction_output(JZ_GPIO_PORTC(21), 1);
for(i = 0; i < 16; ++i) {
gpio_request(JZ_GPIO_PORTC(i), "eink display data");
}
jz_gpio_port_direction_output(JZ_GPIO_PORTC(0), 0xffff);
gpio_set_value(JZ_GPIO_PORTB(18), 1);
return 0;
}
static irqreturn_t n526_eink_busy_irq(int irq, void *devid)
{
struct broadsheetfb_par *par = devid;
wake_up(&par->waitq);
return IRQ_HANDLED;
}
static int n526_eink_setup_irq(struct fb_info *info)
{
int ret;
struct broadsheetfb_par *par = info->par;
gpio_request(JZ_GPIO_PORTB(17), "eink busy");
gpio_direction_input(JZ_GPIO_PORTB(17));
ret = request_irq(gpio_to_irq(JZ_GPIO_PORTB(17)), n526_eink_busy_irq,
IRQF_DISABLED | IRQF_TRIGGER_RISING,
"eink busyline", par);
if (ret)
printk("n526 display: Failed to request busyline irq: %d\n", ret);
return 0;
}
static void n526_eink_cleanup(struct broadsheetfb_par *par)
{
}
static struct broadsheet_board broadsheet_pdata = {
.owner = THIS_MODULE,
.init = n526_eink_init,
.wait_for_rdy = n526_eink_wait,
.set_ctl = n526_eink_set_ctl,
.set_hdb = n526_eink_set_hdb,
.get_hdb = n526_eink_get_hdb,
.cleanup = n526_eink_cleanup,
.setup_irq = n526_eink_setup_irq,
};
static struct platform_device n526_broadsheet_device = {
.name = "broadsheetfb",
.id = -1,
.dev = {
.platform_data = &broadsheet_pdata,
},
};
static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = {
[0] = {
.code = KEY_ENTER,
.gpio = 0,
.active_low = 1,
.desc = "Power",
},
};
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 i2c_gpio_platform_data n526_i2c_pdata = {
.sda_pin = JZ_GPIO_PORTD(23),
.scl_pin = JZ_GPIO_PORTD(24),
.udelay = 2,
.timeout = 3 * HZ,
};
static struct platform_device n526_i2c_device = {
.name = "i2c-gpio",
.id = -1,
.dev = {
.platform_data = &n526_i2c_pdata,
},
};
static struct i2c_board_info n526_i2c_board_info = {
.type = "n526-lpc",
.addr = 0x54,
};
static struct platform_device *jz_platform_devices[] __initdata = {
&jz4740_usb_ohci_device,
&jz4740_usb_gdt_device,
&jz4740_mmc_device,
&jz4740_nand_device,
&jz4740_i2s_device,
&jz4740_codec_device,
&jz4740_rtc_device,
&n526_leds_device,
&n526_broadsheet_device,
&qi_lb60_gpio_keys,
&n526_i2c_device,
};
static int __init n526_init_platform_devices(void)
{
jz4740_nand_device.dev.platform_data = &n526_nand_pdata;
jz4740_mmc_device.dev.platform_data = &n526_mmc_pdata;
n526_i2c_board_info.irq = gpio_to_irq(JZ_GPIO_PORTD(14)),
i2c_register_board_info(0, &n526_i2c_board_info, 1);
return platform_add_devices(jz_platform_devices,
ARRAY_SIZE(jz_platform_devices));
}
struct jz4740_clock_board_data jz4740_clock_bdata = {
.ext_rate = 12000000,
.rtc_rate = 32768,
};
extern int jz_gpiolib_init(void);
static int __init n526_board_setup(void)
{
if (jz_gpiolib_init())
panic("Failed to initalize jz gpio\n");
jz4740_clock_init();
board_gpio_setup();
if (n526_init_platform_devices())
panic("Failed to initalize platform devices\n");
return 0;
}
arch_initcall(n526_board_setup);

View File

@ -1,424 +0,0 @@
/*
* 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 2 or later
* 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>
#include <linux/power/gpio-charger.h>
#include <linux/mmc/jz4740_mmc.h>
#include "clock.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 + 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 + 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_RIGHTALT
#define KEY_QI_VOLUP KEY_VOLUMEUP
#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN
#define KEY_QI_FN KEY_LEFTCTRL
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_RIGHTCTRL), /* 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,
.refresh = 30,
.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,
.pixclk_falling_edge = 1,
};
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_battery_platform_data qi_lb60_battery_pdata = {
.gpio_charge = GPIO_CHARG_STAT_N,
.gpio_charge_active_low = 1,
.info = {
.name = "battery",
.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
.voltage_max_design = 4200000,
.voltage_min_design = 3600000,
},
};
static char *qi_lb60_batteries[] = {
"battery",
};
static struct gpio_charger_platform_data qi_lb60_charger_pdata = {
.name = "USB",
.type = POWER_SUPPLY_TYPE_USB,
.gpio = GPIO_USB_DETE,
.gpio_active_low = 1,
.batteries = qi_lb60_batteries,
.num_batteries = ARRAY_SIZE(qi_lb60_batteries),
};
static struct platform_device qi_lb60_charger_device = {
.name = "gpio-charger",
.dev = {
.platform_data = &qi_lb60_charger_pdata,
},
};
/* 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 jz4740_mmc_platform_data qi_lb60_mmc_pdata = {
.gpio_card_detect = JZ_GPIO_PORTD(0),
.gpio_read_only = -1,
.gpio_power = JZ_GPIO_PORTD(2),
.power_active_low = 1,
};
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,
&qi_lb60_charger_device,
};
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);
}
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;
jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_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));
}
struct jz4740_clock_board_data jz4740_clock_bdata = {
.ext_rate = 12000000,
.rtc_rate = 32768,
};
extern int jz_gpiolib_init(void);
static __init int board_avt2(char *str)
{
qi_lb60_mmc_pdata.card_detect_active_low = 1;
qi_lb60_mmc_pdata.power_active_low = 1;
return 1;
}
__setup("avt2", board_avt2);
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");
jz4740_clock_init();
board_gpio_setup();
if (qi_lb60_init_platform_devices())
panic("Failed to initalize platform devices\n");
return 0;
}
arch_initcall(qi_lb60_board_setup);

View File

@ -1,109 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 SoC clock support debugfs entries
*
* 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/clk.h>
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <asm/mach-jz4740/clock.h>
#include "clock.h"
static struct dentry *jz4740_clock_debugfs;
static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
{
struct clk *clk = data;
*value = clk_is_enabled(clk);
return 0;
}
static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
{
struct clk *clk = data;
if (value)
return clk_enable(clk);
else
clk_disable(clk);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
jz4740_clock_debugfs_show_enabled,
jz4740_clock_debugfs_set_enabled,
"%llu\n");
static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
{
struct clk *clk = data;
*value = clk_get_rate(clk);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
jz4740_clock_debugfs_show_rate,
NULL,
"%llu\n");
void jz4740_clock_debugfs_add_clk(struct clk *clk)
{
if (!jz4740_clock_debugfs)
return;
clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
&jz4740_clock_debugfs_ops_rate);
debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
&jz4740_clock_debugfs_ops_enabled);
if (clk->parent) {
char parent_path[100];
snprintf(parent_path, 100, "../%s", clk->parent->name);
clk->debugfs_parent_entry = debugfs_create_symlink("parent",
clk->debugfs_entry,
parent_path);
}
}
/* TODO: Locking */
void jz4740_clock_debugfs_update_parent(struct clk *clk)
{
if (clk->debugfs_parent_entry)
debugfs_remove(clk->debugfs_parent_entry);
if (clk->parent) {
char parent_path[100];
snprintf(parent_path, 100, "../%s", clk->parent->name);
clk->debugfs_parent_entry = debugfs_create_symlink("parent",
clk->debugfs_entry,
parent_path);
} else {
clk->debugfs_parent_entry = NULL;
}
}
void jz4740_clock_debugfs_init(void)
{
jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
if (IS_ERR(jz4740_clock_debugfs))
jz4740_clock_debugfs = NULL;
}

View File

@ -1,930 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 SoC clock 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/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>
#include <asm/mach-jz4740/clock.h>
#include "clock.h"
#define JZ_REG_CLOCK_CTRL 0x00
#define JZ_REG_CLOCK_LOW_POWER 0x04
#define JZ_REG_CLOCK_PLL 0x10
#define JZ_REG_CLOCK_GATE 0x20
#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
#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 BIT(5)
#define JZ_CLOCK_GATE_I2S 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
#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
static void __iomem *jz_clock_base;
static spinlock_t jz_clock_lock;
static LIST_HEAD(jz_clocks);
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)
{
if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
return -EINVAL;
jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
return 0;
}
static int jz_clk_disable_gating(struct clk *clk)
{
if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
return -EINVAL;
jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
return 0;
}
static int jz_clk_is_enabled_gating(struct clk *clk)
{
if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
return 1;
return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
}
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 int jz_clk_ko_is_enabled(struct clk *clk)
{
return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
}
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(clk->parent);
return jz_clk_pll_get_rate(clk->parent) >> 1;
}
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(clk->parent);
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(clk->parent) / 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(clk->parent);
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 clk_ops jz_clk_static_ops = {
.get_rate = jz_clk_static_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.is_enabled = jz_clk_is_enabled_gating,
};
static struct static_clk jz_clk_ext = {
.clk = {
.name = "ext",
.gate_bit = JZ4740_CLK_NOT_GATED,
.ops = &jz_clk_static_ops,
},
};
static struct clk_ops jz_clk_pll_ops = {
.get_rate = jz_clk_static_get_rate,
};
static struct clk jz_clk_pll = {
.name = "pll",
.parent = &jz_clk_ext.clk,
.ops = &jz_clk_pll_ops,
};
static struct clk_ops jz_clk_pll_half_ops = {
.get_rate = jz_clk_pll_half_get_rate,
};
static struct clk jz_clk_pll_half = {
.name = "pll half",
.parent = &jz_clk_pll,
.ops = &jz_clk_pll_half_ops,
};
static const struct clk_ops jz_clk_main_ops = {
.get_rate = jz_clk_main_get_rate,
.set_rate = jz_clk_main_set_rate,
.round_rate = jz_clk_main_round_rate,
};
static struct main_clk jz_clk_cpu = {
.clk = {
.name = "cclk",
.parent = &jz_clk_pll,
.ops = &jz_clk_main_ops,
},
.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
};
static struct main_clk jz_clk_memory = {
.clk = {
.name = "mclk",
.parent = &jz_clk_pll,
.ops = &jz_clk_main_ops,
},
.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
};
static struct main_clk jz_clk_high_speed_peripheral = {
.clk = {
.name = "hclk",
.parent = &jz_clk_pll,
.ops = &jz_clk_main_ops,
},
.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
};
static struct main_clk jz_clk_low_speed_peripheral = {
.clk = {
.name = "pclk",
.parent = &jz_clk_pll,
.ops = &jz_clk_main_ops,
},
.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
};
static const struct clk_ops jz_clk_ko_ops = {
.enable = jz_clk_ko_enable,
.disable = jz_clk_ko_disable,
.is_enabled = jz_clk_ko_is_enabled,
};
static struct clk jz_clk_ko = {
.name = "cko",
.parent = &jz_clk_memory.clk,
.ops = &jz_clk_ko_ops,
};
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_enable(struct clk *clk)
{
jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
return 0;
}
static int jz_clk_udc_disable(struct clk *clk)
{
jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
return 0;
}
static int jz_clk_udc_is_enabled(struct clk *clk)
{
return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
}
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(clk->parent);
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(clk->parent) / 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);
return 0;
}
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(clk->parent) / (div + 1);
}
static const struct clk_ops jz_clk_ops_ld = {
.set_rate = jz_clk_ldclk_set_rate,
.get_rate = jz_clk_ldclk_get_rate,
.round_rate = jz_clk_ldclk_round_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.is_enabled = jz_clk_is_enabled_gating,
};
static struct clk jz_clk_ld = {
.name = "lcd",
.gate_bit = JZ_CLOCK_GATE_LCD,
.parent = &jz_clk_pll_half,
.ops = &jz_clk_ops_ld,
};
/* TODO: ops!!! */
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,
.ops = &jz_clk_static_ops,
},
};
static const struct clk_ops jz_clk_i2s_ops =
{
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.is_enabled = jz_clk_is_enabled_gating,
.set_parent = jz_clk_i2s_set_parent,
};
static const struct clk_ops jz_clk_spi_ops =
{
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.is_enabled = jz_clk_is_enabled_gating,
.set_parent = jz_clk_spi_set_parent,
};
static const struct clk_ops jz_clk_divided_ops =
{
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.is_enabled = jz_clk_is_enabled_gating,
};
static struct divided_clk jz4740_clock_divided_clks[] = {
{
.clk = {
.name = "lcd_pclk",
.parent = &jz_clk_pll_half,
.gate_bit = JZ4740_CLK_NOT_GATED,
.ops = &jz_clk_divided_ops,
},
.reg = JZ_REG_CLOCK_LCD,
.mask = JZ_CLOCK_LCD_DIV_MASK,
},
{
.clk = {
.name = "i2s",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_I2S,
.ops = &jz_clk_i2s_ops,
},
.reg = JZ_REG_CLOCK_I2S,
.mask = JZ_CLOCK_I2S_DIV_MASK,
},
{
.clk = {
.name = "spi",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_SPI,
.ops = &jz_clk_spi_ops,
},
.reg = JZ_REG_CLOCK_SPI,
.mask = JZ_CLOCK_SPI_DIV_MASK,
},
{
.clk = {
.name = "mmc",
.parent = &jz_clk_pll_half,
.gate_bit = JZ_CLOCK_GATE_MMC,
.ops = &jz_clk_divided_ops,
},
.reg = JZ_REG_CLOCK_MMC,
.mask = JZ_CLOCK_MMC_DIV_MASK,
},
{
.clk = {
.name = "uhc",
.parent = &jz_clk_pll_half,
.gate_bit = JZ_CLOCK_GATE_UHC,
.ops = &jz_clk_divided_ops,
},
.reg = JZ_REG_CLOCK_UHC,
.mask = JZ_CLOCK_UHC_DIV_MASK,
},
};
static const struct clk_ops jz_clk_udc_ops = {
.set_parent = jz_clk_udc_set_parent,
.set_rate = jz_clk_udc_set_rate,
.get_rate = jz_clk_udc_get_rate,
.enable = jz_clk_udc_enable,
.disable = jz_clk_udc_disable,
.is_enabled = jz_clk_udc_is_enabled,
};
static const struct clk_ops jz_clk_simple_ops = {
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.is_enabled = jz_clk_is_enabled_gating,
};
static struct clk jz4740_clock_simple_clks[] = {
{
.name = "udc",
.parent = &jz_clk_ext.clk,
.ops = &jz_clk_udc_ops,
},
{
.name = "uart0",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_UART0,
.ops = &jz_clk_simple_ops,
},
{
.name = "uart1",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_UART1,
.ops = &jz_clk_simple_ops,
},
{
.name = "dma",
.parent = &jz_clk_high_speed_peripheral.clk,
.gate_bit = JZ_CLOCK_GATE_UART0,
.ops = &jz_clk_simple_ops,
},
{
.name = "ipu",
.parent = &jz_clk_high_speed_peripheral.clk,
.gate_bit = JZ_CLOCK_GATE_IPU,
.ops = &jz_clk_simple_ops,
},
{
.name = "adc",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_ADC,
.ops = &jz_clk_simple_ops,
},
{
.name = "i2c",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_I2C,
.ops = &jz_clk_simple_ops,
},
{
.name = "aic",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_AIC,
.ops = &jz_clk_simple_ops,
},
};
static struct static_clk jz_clk_rtc = {
.clk = {
.name = "rtc",
.gate_bit = JZ_CLOCK_GATE_RTC,
.ops = &jz_clk_static_ops,
},
.rate = 32768,
};
int clk_enable(struct clk *clk)
{
if (!clk->ops->enable)
return -EINVAL;
return clk->ops->enable(clk);
}
EXPORT_SYMBOL_GPL(clk_enable);
void clk_disable(struct clk *clk)
{
if (clk->ops->disable)
clk->ops->disable(clk);
}
EXPORT_SYMBOL_GPL(clk_disable);
int clk_is_enabled(struct clk *clk)
{
if (clk->ops->is_enabled)
return clk->ops->is_enabled(clk);
return 1;
}
unsigned long clk_get_rate(struct clk *clk)
{
if (clk->ops->get_rate)
return clk->ops->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->ops->set_rate)
return -EINVAL;
return clk->ops->set_rate(clk, rate);
}
EXPORT_SYMBOL_GPL(clk_set_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
if (clk->ops->round_rate)
return clk->ops->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->ops->set_parent)
return -EINVAL;
clk_disable(clk);
ret = clk->ops->set_parent(clk, parent);
clk_enable(clk);
jz4740_clock_debugfs_update_parent(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) == 0)
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);
jz4740_clock_debugfs_add_clk(clk);
}
static void clk_register_clks(void)
{
size_t i;
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_cim_mclk);
clk_add(&jz_clk_cim_pclk.clk);
clk_add(&jz_clk_rtc.clk);
for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
clk_add(&jz4740_clock_divided_clks[i].clk);
for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
clk_add(&jz4740_clock_simple_clks[i]);
}
void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
{
switch (mode) {
case JZ4740_WAIT_MODE_IDLE:
jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
break;
case JZ4740_WAIT_MODE_SLEEP:
jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
break;
}
}
void jz4740_clock_udc_disable_auto_suspend(void)
{
jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
}
EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
void jz4740_clock_udc_enable_auto_suspend(void)
{
jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
}
EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
void jz4740_clock_suspend(void)
{
jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
}
void jz4740_clock_resume(void)
{
jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
while ((jz_clk_reg_read(JZ_REG_CLOCK_PLL) & JZ_CLOCK_PLL_STABLE) == 0);
jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
}
int jz4740_clock_init(void)
{
uint32_t val;
jz_clock_base = ioremap(CPHYSADDR(CPM_BASE), 0x100);
if (!jz_clock_base)
return -EBUSY;
spin_lock_init(&jz_clock_lock);
jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
if (val & JZ_CLOCK_SPI_SRC_PLL)
jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
jz4740_clock_debugfs_init();
clk_register_clks();
return 0;
}

View File

@ -1,75 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 SoC clock 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.
*
*/
#ifndef __JZ4740_CLOCK_H__
#define __JZ4740_CLOCK_H__
struct jz4740_clock_board_data {
unsigned long ext_rate;
unsigned long rtc_rate;
};
extern struct jz4740_clock_board_data jz4740_clock_bdata;
int jz4740_clock_init(void);
void jz4740_clock_suspend(void);
void jz4740_clock_resume(void);
struct clk;
struct clk_ops {
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 (*is_enabled)(struct clk* clk);
int (*set_parent)(struct clk* clk, struct clk *parent);
};
struct clk {
const char *name;
struct clk* parent;
uint32_t gate_bit;
const struct clk_ops *ops;
struct list_head list;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_entry;
struct dentry *debugfs_parent_entry;
#endif
};
#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
int clk_is_enabled(struct clk *clk);
#ifdef CONFIG_DEBUG_FS
void jz4740_clock_debugfs_init(void);
void jz4740_clock_debugfs_add_clk(struct clk *clk);
void jz4740_clock_debugfs_update_parent(struct clk *clk);
#else
static inline void jz4740_clock_debugfs_init(void) {};
static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
#endif
#endif

View File

@ -1,339 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 SoC DMA 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/spinlock.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <asm/mach-jz4740/dma.h>
#include <asm/mach-jz4740/regs.h>
#define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20)
#define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20)
#define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20)
#define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20)
#define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20)
#define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20)
#define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20)
#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_CTRL_NO_DESC BIT(31)
#define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6)
#define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4)
#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3)
#define JZ_DMA_STATUS_CTRL_HALT BIT(2)
#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1)
#define JZ_DMA_STATUS_CTRL_ENABLE BIT(0)
#define JZ_DMA_CMD_SRC_INC BIT(23)
#define JZ_DMA_CMD_DST_INC BIT(22)
#define JZ_DMA_CMD_RDIL_MASK (0xf << 16)
#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14)
#define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12)
#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8)
#define JZ_DMA_CMD_BLOCK_MODE BIT(7)
#define JZ_DMA_CMD_DESC_VALID BIT(4)
#define JZ_DMA_CMD_DESC_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_ENABLE BIT(0)
#define JZ_DMA_CMD_FLAGS_OFFSET 22
#define JZ_DMA_CMD_RDIL_OFFSET 16
#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
#define JZ_DMA_CMD_MODE_OFFSET 7
#define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8)
#define JZ_DMA_CTRL_HALT BIT(3)
#define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2)
#define JZ_DMA_CTRL_ENABLE BIT(0)
static void __iomem *jz4740_dma_base;
static spinlock_t jz4740_dma_lock;
static inline uint32_t jz4740_dma_read(size_t reg)
{
return readl(jz4740_dma_base + reg);
}
static inline void jz4740_dma_write(size_t reg, uint32_t val)
{
writel(val, jz4740_dma_base + reg);
}
static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
{
uint32_t val2;
val2 = jz4740_dma_read(reg);
val2 &= ~mask;
val2 |= val;
jz4740_dma_write(reg, val2);
}
struct jz4740_dma_chan {
unsigned int id;
void *dev;
const char *name;
enum jz4740_dma_flags flags;
uint32_t transfer_shift;
jz4740_dma_complete_callback_t complete_cb;
unsigned used:1;
};
#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
struct jz4740_dma_chan jz4740_dma_channels[] = {
JZ4740_DMA_CHANNEL(0),
JZ4740_DMA_CHANNEL(1),
JZ4740_DMA_CHANNEL(2),
JZ4740_DMA_CHANNEL(3),
JZ4740_DMA_CHANNEL(4),
JZ4740_DMA_CHANNEL(5),
};
struct jz4740_dma_chan* jz4740_dma_request(void *dev, const char *name)
{
unsigned int i;
struct jz4740_dma_chan *dma = NULL;
spin_lock(&jz4740_dma_lock);
for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
if (!jz4740_dma_channels[i].used) {
dma = &jz4740_dma_channels[i];
dma->used = 1;
break;
}
}
spin_unlock(&jz4740_dma_lock);
if (!dma)
return NULL;
dma->dev = dev;
dma->name = name;
return dma;
}
EXPORT_SYMBOL_GPL(jz4740_dma_request);
void jz4740_dma_configure(struct jz4740_dma_chan *dma,
const struct jz4740_dma_config *config)
{
uint32_t cmd;
uint32_t ctrl;
switch(config->transfer_size) {
case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
dma->transfer_shift = 1;
break;
case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
dma->transfer_shift = 2;
break;
case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
dma->transfer_shift = 4;
break;
case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
dma->transfer_shift = 5;
break;
default:
dma->transfer_shift = 0;
break;
}
cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
ctrl = JZ_DMA_STATUS_CTRL_NO_DESC;
ctrl |= JZ_DMA_STATUS_CTRL_HALT;
jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), ctrl);
jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
}
EXPORT_SYMBOL_GPL(jz4740_dma_configure);
void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
{
jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
}
EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
{
jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
}
EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
{
count >>= dma->transfer_shift;
jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
}
EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
jz4740_dma_complete_callback_t cb)
{
dma->complete_cb = cb;
}
EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
void jz4740_dma_free(struct jz4740_dma_chan *dma)
{
dma->dev = NULL;
dma->complete_cb = NULL;
dma->used = 0;
}
EXPORT_SYMBOL_GPL(jz4740_dma_free);
void jz4740_dma_enable(struct jz4740_dma_chan *dma)
{
jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
JZ_DMA_STATUS_CTRL_ENABLE,
JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_HALT);
jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
JZ_DMA_CTRL_ENABLE,
JZ_DMA_CTRL_ENABLE | JZ_DMA_CTRL_HALT);
}
EXPORT_SYMBOL_GPL(jz4740_dma_enable);
void jz4740_dma_disable(struct jz4740_dma_chan *dma)
{
jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
JZ_DMA_STATUS_CTRL_ENABLE);
}
EXPORT_SYMBOL_GPL(jz4740_dma_disable);
uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
{
uint32_t residue;
residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
return residue << dma->transfer_shift;
}
EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
{
uint32_t status;
status = jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
if (dma->complete_cb)
dma->complete_cb(dma, 0, dma->dev);
}
static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
{
uint32_t irq_status;
unsigned int i;
irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
for (i = 0; i < 6; ++i) {
if (irq_status & (1 << i))
jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
}
return IRQ_HANDLED;
}
#if 0
static struct jz4740_dma_config dma_test_config = {
.src_width = JZ4740_DMA_WIDTH_32BIT,
.dst_width = JZ4740_DMA_WIDTH_32BIT,
.transfer_size = JZ4740_DMA_TRANSFER_SIZE_4BYTE,
.request_type = JZ4740_DMA_TYPE_AUTO_REQUEST,
.flags = JZ4740_DMA_SRC_AUTOINC | JZ4740_DMA_DST_AUTOINC,
.mode = JZ4740_DMA_MODE_BLOCK,
};
static void jz4740_dma_test(void)
{
uint32_t *buf1, *buf2;
dma_addr_t addr1, addr2;
struct jz4740_dma_chan *dma = jz4740_dma_request(NULL, "dma test");
int i;
printk("STARTING DMA TEST\n");
buf1 = dma_alloc_coherent(NULL,
0x1000,
&addr1, GFP_KERNEL);
buf2 = dma_alloc_coherent(NULL,
0x1000,
&addr2, GFP_KERNEL);
for (i = 0; i < 0x400; ++i)
buf1[i] = i;
jz4740_dma_configure(dma, &dma_test_config);
jz4740_dma_set_src_addr(dma, addr1);
jz4740_dma_set_dst_addr(dma, addr2);
jz4740_dma_set_transfer_count(dma, 0x1000);
jz4740_dma_enable(dma);
mdelay(2000);
for (i = 0; i < 0x400; ++i) {
if (buf2[i] != i)
printk("OH MY GOD: %x %x\n", i, buf2[i]);
}
printk("DMA TEST DONE\n");
}
#endif
static int jz4740_dma_init(void)
{
unsigned int ret;
jz4740_dma_base = ioremap(CPHYSADDR(DMAC_BASE), 0x400);
if (!jz4740_dma_base)
return -EBUSY;
spin_lock_init(&jz4740_dma_lock);
ret = request_irq(JZ_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
if (ret)
printk("JZ4740 DMA: Failed to request irq: %d\n", ret);
return ret;
}
arch_initcall(jz4740_dma_init);

View File

@ -1,540 +0,0 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 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/sysdev.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/seq_file.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) (JZ_IRQ_GPIO_BASE_A + num)
#define JZ_IRQ_GPIO_B(num) (JZ_IRQ_GPIO_BASE_B + num)
#define JZ_IRQ_GPIO_C(num) (JZ_IRQ_GPIO_BASE_C + num)
#define JZ_IRQ_GPIO_D(num) (JZ_IRQ_GPIO_BASE_D + num)
#define JZ_REG_GPIO_PIN 0x00
#define JZ_REG_GPIO_DATA 0x10
#define JZ_REG_GPIO_DATA_SET 0x14
#define JZ_REG_GPIO_DATA_CLEAR 0x18
#define JZ_REG_GPIO_MASK 0x20
#define JZ_REG_GPIO_MASK_SET 0x24
#define JZ_REG_GPIO_MASK_CLEAR 0x28
#define JZ_REG_GPIO_PULL 0x30
#define JZ_REG_GPIO_PULL_SET 0x34
#define JZ_REG_GPIO_PULL_CLEAR 0x38
#define JZ_REG_GPIO_FUNC 0x40
#define JZ_REG_GPIO_FUNC_SET 0x44
#define JZ_REG_GPIO_FUNC_CLEAR 0x48
#define JZ_REG_GPIO_SELECT 0x50
#define JZ_REG_GPIO_SELECT_SET 0x54
#define JZ_REG_GPIO_SELECT_CLEAR 0x58
#define JZ_REG_GPIO_DIRECTION 0x60
#define JZ_REG_GPIO_DIRECTION_SET 0x64
#define JZ_REG_GPIO_DIRECTION_CLEAR 0x68
#define JZ_REG_GPIO_TRIGGER 0x70
#define JZ_REG_GPIO_TRIGGER_SET 0x74
#define JZ_REG_GPIO_TRIGGER_CLEAR 0x78
#define JZ_REG_GPIO_FLAG 0x80
#define JZ_REG_GPIO_FLAG_CLEAR 0x14
#define CHIP_TO_REG(chip, reg) (jz_gpio_base + (((chip)->base) << 3) + reg)
#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
#define GPIO_TO_REG(gpio, reg) (jz_gpio_base + ((gpio >> 5) << 8) + reg)
static void __iomem *jz_gpio_base;
struct jz_gpio_chip {
unsigned int irq;
unsigned int irq_base;
uint32_t wakeup;
uint32_t suspend_mask;
uint32_t edge_trigger_both;
spinlock_t lock;
struct gpio_chip gpio_chip;
struct irq_chip irq_chip;
};
static struct jz_gpio_chip *jz_irq_to_chip(unsigned int irq)
{
return get_irq_chip_data(irq);
}
static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
{
writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
}
int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
{
if (function == JZ_GPIO_FUNC_NONE) {
jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
} else {
jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
switch (function) {
case JZ_GPIO_FUNC1:
jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
break;
case JZ_GPIO_FUNC3:
jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
case JZ_GPIO_FUNC2: /* Falltrough */
jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
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_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
{
size_t i;
for (i = 0; i < num; ++i, ++request) {
jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
}
}
EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
{
size_t i;
for (i = 0; i < num; ++i, ++request) {
jz_gpio_set_function(request->gpio, request->function);
}
}
EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
void jz_gpio_enable_pullup(unsigned gpio)
{
jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
}
EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
void jz_gpio_disable_pullup(unsigned gpio)
{
jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
}
EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
}
static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
{
uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
reg += !value;
writel(BIT(gpio), reg);
}
static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
{
writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
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_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
return 0;
}
int jz_gpio_port_direction_input(int port, uint32_t mask)
{
writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
return 0;
}
EXPORT_SYMBOL(jz_gpio_port_direction_input);
int jz_gpio_port_direction_output(int port, uint32_t mask)
{
writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
return 0;
}
EXPORT_SYMBOL(jz_gpio_port_direction_output);
void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
{
writel((~value) & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
}
EXPORT_SYMBOL(jz_gpio_port_set_value);
uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
{
uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
return value & mask;
}
EXPORT_SYMBOL(jz_gpio_port_get_value);
#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)
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) + JZ_REG_GPIO_FLAG);
gpio_irq = ffs(flag) - 1;
if (chip->edge_trigger_both & BIT(gpio_irq)) {
uint32_t value = readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_PIN));
if (value & BIT(gpio_irq)) {
writel(BIT(gpio_irq),
CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DIRECTION_CLEAR));
} else {
writel(BIT(gpio_irq),
CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DIRECTION_SET));
}
}
gpio_irq += (gpio_bank << 5) + JZ_IRQ_GPIO(0);
generic_handle_irq(gpio_irq);
};
static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
{
writel(IRQ_TO_BIT(irq), IRQ_TO_REG(irq, reg));
}
static void jz_gpio_irq_mask(unsigned int irq)
{
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
};
static void jz_gpio_irq_unmask(unsigned int irq)
{
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
};
/* TODO: Check if function is gpio */
static unsigned int jz_gpio_irq_startup(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
desc->status &= ~IRQ_MASKED;
jz_gpio_irq_unmask(irq);
return 0;
}
static void jz_gpio_irq_shutdown(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
jz_gpio_irq_mask(irq);
desc->status |= IRQ_MASKED;
/* Set direction to input */
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
}
static void jz_gpio_irq_ack(unsigned int irq)
{
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
};
static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
{
struct jz_gpio_chip *chip = jz_irq_to_chip(irq);
struct irq_desc *desc = irq_to_desc(irq);
jz_gpio_irq_mask(irq);
if (flow_type == IRQ_TYPE_EDGE_BOTH) {
uint32_t value = readl(IRQ_TO_REG(irq, JZ_REG_GPIO_PIN));
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:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
break;
case IRQ_TYPE_EDGE_FALLING:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
break;
case IRQ_TYPE_LEVEL_HIGH:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
break;
case IRQ_TYPE_LEVEL_LOW:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
break;
default:
return -EINVAL;
}
if (!(desc->status & IRQ_MASKED))
jz_gpio_irq_unmask(irq);
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);
spin_lock(&chip->lock);
if (on)
chip->wakeup |= IRQ_TO_BIT(irq);
else
chip->wakeup &= ~IRQ_TO_BIT(irq);
spin_unlock(&chip->lock);
set_irq_wake(chip->irq, !!(chip->wakeup));
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 jz_gpio_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->suspend_mask = readl(GPIO_TO_REG(gpio, JZ_REG_GPIO_MASK));
writel(~(chip->wakeup), GPIO_TO_REG(gpio, JZ_REG_GPIO_MASK_SET));
writel(chip->wakeup, GPIO_TO_REG(gpio, JZ_REG_GPIO_MASK_CLEAR));
}
chip = jz_gpio_chips;
return 0;
}
int jz_gpio_resume(void)
{
struct jz_gpio_chip *chip = jz_gpio_chips;
int i;
for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) {
writel(~(chip->suspend_mask), GPIO_TO_REG(chip->gpio_chip.base,
JZ_REG_GPIO_MASK_CLEAR));
writel(chip->suspend_mask, GPIO_TO_REG(chip->gpio_chip.base,
JZ_REG_GPIO_MASK_SET));
}
return 0;
}
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);
spin_lock_init(&chip->lock);
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;
}
#ifdef CONFIG_DEBUG_FS
static int gpio_regs_show(struct seq_file *s, void *unused)
{
struct jz_gpio_chip *chip = jz_gpio_chips;
int i;
for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) {
seq_printf(s, "GPIO %d: \n", i);
seq_printf(s, "\tPin: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_PIN)));
seq_printf(s, "\tData: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DATA)));
seq_printf(s, "\tMask: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_MASK)));
seq_printf(s, "\tData: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DATA)));
seq_printf(s, "\tPull: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_PULL)));
seq_printf(s, "\tFunc: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_FUNC)));
seq_printf(s, "\tSelect: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_SELECT)));
seq_printf(s, "\tDirection: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DIRECTION)));
seq_printf(s, "\tTrigger: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_TRIGGER)));
seq_printf(s, "\tFlag: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_FLAG)));
}
return 0;
}
static int gpio_regs_open(struct inode *inode, struct file *file)
{
return single_open(file, gpio_regs_show, NULL);
}
static const struct file_operations gpio_regs_operations = {
.open = gpio_regs_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init gpio_debugfs_init(void)
{
(void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
NULL, NULL, &gpio_regs_operations);
return 0;
}
subsys_initcall(gpio_debugfs_init);
#endif

View File

@ -1,166 +0,0 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 platform IRQ 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/errno.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/io.h>
#include <asm/mipsregs.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 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,
.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);
generic_handle_irq(ffs(irq_reg) - 1 + JZ_IRQ_BASE);
return IRQ_HANDLED;
}
static struct irqaction jz4740_cascade_action = {
.handler = jz4740_cascade,
.name = "JZ4740 cascade interrupt",
.flags = IRQF_DISABLED,
};
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)
do_IRQ(2);
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);
writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
}
void jz4740_intc_resume(void)
{
writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
}
#ifdef CONFIG_DEBUG_FS
static int intc_regs_show(struct seq_file *s, void *unused)
{
seq_printf(s, "Status:\t\t%08x\n", readl(jz_intc_base + JZ_REG_INTC_STATUS));
seq_printf(s, "Mask\t\t%08x\n", readl(jz_intc_base + JZ_REG_INTC_MASK));
seq_printf(s, "Pending:\t%08x\n", readl(jz_intc_base + JZ_REG_INTC_PENDING));
return 0;
}
static int intc_regs_open(struct inode *inode, struct file *file)
{
return single_open(file, intc_regs_show, NULL);
}
static const struct file_operations intc_regs_operations = {
.open = intc_regs_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init intc_debugfs_init(void)
{
(void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
NULL, NULL, &intc_regs_operations);
return 0;
}
subsys_initcall(intc_debugfs_init);
#endif

View File

@ -1,246 +0,0 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 platform devices
*
* 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/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/mach-jz4740/regs.h>
#include <asm/mach-jz4740/irq.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 = "jz4740-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) + 0x38 - 1,
.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
},
};

View File

@ -1,65 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 SoC power management 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/init.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/suspend.h>
#include <asm/mach-jz4740/regs.h>
#include <asm/mach-jz4740/clock.h>
#include "clock.h"
extern void jz4740_intc_suspend(void);
extern void jz4740_intc_resume(void);
extern void jz_gpio_suspend(void);
extern void jz_gpio_resume(void);
static int jz_pm_enter(suspend_state_t state)
{
jz_gpio_suspend();
jz4740_intc_suspend();
jz4740_clock_suspend();
jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
__asm__(".set\tmips3\n\t"
"wait\n\t"
".set\tmips0");
jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
jz4740_clock_resume();
jz4740_intc_resume();
jz_gpio_resume();
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);

View File

@ -1,111 +0,0 @@
/*
*
* 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/mach-jz4740/regs.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, *c;
size_t i = 1;
cp = &(arcs_cmdline[0]);
while(i < prom_argc) {
c = prom_argv[i];
while (*c) {
*cp++ = *c++;
}
*cp++ = ' ';
i++;
}
if (i > 1) {
*(cp - 1) = '\0';
}
}
void __init prom_init(void)
{
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 = 0x04000000;
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void __init prom_free_prom_memory(void)
{
}
/* 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);

View File

@ -1,52 +0,0 @@
/*
* 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/mach-jz4740/regs.h>
#include <asm/mach-jz4740/timer.h>
#include <asm/mach-jz4740/jz4740.h>
#include "clock.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 = jz4740_clock_bdata.ext_rate / 1000; /* reset after 4ms */
jz4740_timer_enable_watchdog();
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();
}

View File

@ -1,97 +0,0 @@
/*
* 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/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/mach-jz4740/jz4740.h>
#include <asm/mach-jz4740/regs.h>
#include <asm/mach-jz4740/clock.h>
#include <asm/mach-jz4740/serial.h>
#include "clock.h"
extern char *__init prom_getcmdline(void);
extern void jz_restart(char *);
extern void jz_halt(void);
extern void jz_power_off(void);
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 = jz4740_clock_bdata.ext_rate;
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_serial_setup();
}

View File

@ -1,256 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 platform timer 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/interrupt.h>
#include <linux/time.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
#include <asm/mach-jz4740/irq.h>
#include <asm/mach-jz4740/jz4740.h>
#include <asm/time.h>
#include "clock.h"
#define JZ_REG_TIMER_STOP 0x1C
#define JZ_REG_TIMER_STOP_SET 0x2C
#define JZ_REG_TIMER_STOP_CLEAR 0x3C
#define JZ_REG_TIMER_ENABLE 0x10
#define JZ_REG_TIMER_ENABLE_SET 0x14
#define JZ_REG_TIMER_ENABLE_CLEAR 0x18
#define JZ_REG_TIMER_FLAG 0x20
#define JZ_REG_TIMER_FLAG_SET 0x24
#define JZ_REG_TIMER_FLAG_CLEAR 0x28
#define JZ_REG_TIMER_MASK 0x30
#define JZ_REG_TIMER_MASK_SET 0x34
#define JZ_REG_TIMER_MASK_CLEAR 0x38
#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x40)
#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x44)
#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x48)
#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x4C)
#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
#define JZ_TIMER_IRQ_FULL(x) BIT(x)
#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
static void __iomem *jz4740_timer_base;
static uint16_t jz4740_jiffies_per_tick;
void jz4740_timer_enable_watchdog(void)
{
writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
}
void jz4740_timer_disable_watchdog(void)
{
writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
}
static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
{
writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
}
static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
{
writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
}
static void jz4740_init_timer(void)
{
uint16_t val = 0;
val |= JZ_TIMER_CTRL_PRESCALE_16;
val |= JZ_TIMER_CTRL_SRC_EXT;
writew(val, jz4740_timer_base + JZ_REG_TIMER_CTRL(0));
writew(0xffff, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
writew(val, jz4740_timer_base + JZ_REG_TIMER_CTRL(1));
writew(0xffff, jz4740_timer_base + JZ_REG_TIMER_DFR(1));
}
static void jz4740_timer_enable(unsigned int timer)
{
writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
}
static void jz4740_timer_disable(unsigned int timer)
{
writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
}
static void jz4740_timer_irq_full_enable(unsigned int timer)
{
writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
}
static int jz4740_timer_irq_full_is_enabled(unsigned int timer)
{
return !(readl(jz4740_timer_base + JZ_REG_TIMER_MASK) &
JZ_TIMER_IRQ_FULL(timer));
}
static void jz4740_timer_irq_full_disable(unsigned int timer)
{
writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
}
static void jz4740_timer_irq_half_enable(unsigned int timer)
{
writel(JZ_TIMER_IRQ_HALF(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
writel(JZ_TIMER_IRQ_HALF(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
}
static void jz4740_timer_irq_half_disable(unsigned int timer)
{
writel(JZ_TIMER_IRQ_HALF(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
}
static cycle_t jz4740_clocksource_read(struct clocksource *cs)
{
uint16_t val;
val = readw(jz4740_timer_base + JZ_REG_TIMER_CNT(1));
return val;
}
static struct clocksource jz4740_clocksource = {
.name = "jz4740-timer",
.rating = 200,
.read = jz4740_clocksource_read,
.mask = CLOCKSOURCE_MASK(16),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
{
struct clock_event_device *cd = devid;
writel(JZ_TIMER_IRQ_FULL(0), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
if (cd->mode != CLOCK_EVT_MODE_PERIODIC) {
jz4740_timer_disable(0);
cd->event_handler(cd);
} else {
cd->event_handler(cd);
}
return IRQ_HANDLED;
}
static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
struct clock_event_device *cd)
{
switch(mode) {
case CLOCK_EVT_MODE_PERIODIC:
writew(0x0, jz4740_timer_base + JZ_REG_TIMER_CNT(0));
writew(jz4740_jiffies_per_tick, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
case CLOCK_EVT_MODE_RESUME:
jz4740_timer_irq_full_enable(0);
jz4740_timer_enable(0);
break;
case CLOCK_EVT_MODE_ONESHOT:
case CLOCK_EVT_MODE_SHUTDOWN:
jz4740_timer_disable(0);
break;
default:
break;
}
}
static int jz4740_clockevent_set_next(unsigned long evt, struct
clock_event_device *cd)
{
writew(0x0, jz4740_timer_base + JZ_REG_TIMER_CNT(0));
writew(evt, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
jz4740_timer_enable(0);
return 0;
}
static struct clock_event_device jz4740_clockevent = {
.name = "jz4740-timer",
.features = CLOCK_EVT_FEAT_PERIODIC,
.set_next_event = jz4740_clockevent_set_next,
.set_mode = jz4740_clockevent_set_mode,
.rating = 200,
.irq = JZ_IRQ_TCU0,
};
static struct irqaction jz_irqaction = {
.handler = jz4740_clockevent_irq,
.flags = IRQF_PERCPU | IRQF_TIMER | IRQF_DISABLED,
.name = "jz4740-timerirq",
.dev_id = &jz4740_clockevent,
};
void __init plat_time_init(void)
{
int ret;
uint32_t clk_rate;
jz4740_timer_base = ioremap(CPHYSADDR(TCU_BASE), 0x100);
if (!jz4740_timer_base) {
printk(KERN_ERR "Failed to ioremap timer registers");
return;
}
clk_rate = jz4740_clock_bdata.ext_rate >> 4;
jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
clockevent_set_clock(&jz4740_clockevent, clk_rate);
jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
jz4740_clockevent.cpumask = cpumask_of(0);
clockevents_register_device(&jz4740_clockevent);
clocksource_set_clock(&jz4740_clocksource, clk_rate);
ret = clocksource_register(&jz4740_clocksource);
if (ret)
printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
setup_irq(JZ_IRQ_TCU0, &jz_irqaction);
jz4740_init_timer();
writew(jz4740_jiffies_per_tick, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
jz4740_timer_irq_half_disable(0);
jz4740_timer_irq_full_enable(0);
jz4740_timer_enable(0);
jz4740_timer_irq_half_disable(1);
jz4740_timer_irq_full_disable(1);
jz4740_timer_enable(1);
}

View File

@ -1,422 +0,0 @@
/* 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, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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, 0xf008, 0xf200,
0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a,
0xf028, 0xf029, 0xf200, 0xf07e, 0xf201, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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, 0xf200, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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, 0xf706, 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, 0xf702, 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, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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 ctl_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, 0xf706, 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, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
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,
ctl_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;

View File

@ -1,477 +0,0 @@
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/power_supply.h>
#include <linux/suspend.h>
#include <linux/i2c.h>
#include <asm/mach-jz4740/irq.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/board-n516.h>
static int batt_level=0;
module_param(batt_level, int, 0);
struct n516_lpc_chip {
struct i2c_client *i2c_client;
struct input_dev *input;
unsigned int battery_level;
unsigned int suspending:1, can_sleep:1;
};
static struct n516_lpc_chip *the_lpc;
struct i2c_device_id n516_lpc_i2c_ids[] = {
{"LPC524", 0},
{},
};
MODULE_DEVICE_TABLE(i2c, n516_lpc_i2c_ids);
static const unsigned short normal_i2c[] = {0x54, I2C_CLIENT_END};
static const unsigned int n516_lpc_keymap[] = {
[0x01] = KEY_4,
[0x02] = KEY_3,
[0x03] = KEY_2,
[0x04] = KEY_1,
[0x05] = KEY_0,
[0x07] = KEY_9,
[0x08] = KEY_8,
[0x09] = KEY_7,
[0x0a] = KEY_6,
[0x0b] = KEY_5,
[0x0d] = KEY_PLAYPAUSE,
[0x0e] = KEY_MENU,
[0x0f] = KEY_SEARCH,
[0x10] = KEY_DIRECTION,
[0x11] = KEY_SPACE,
[0x13] = KEY_ENTER,
[0x14] = KEY_UP,
[0x15] = KEY_DOWN,
[0x16] = KEY_RIGHT,
[0x17] = KEY_LEFT,
[0x19] = KEY_PAGEDOWN,
[0x1a] = KEY_PAGEUP,
[0x1c] = KEY_POWER,
[0x1d] = KEY_ESC,
[0x1e] = KEY_SLEEP,
[0x1f] = KEY_WAKEUP,
};
static const unsigned int batt_charge[] = {0, 7, 20, 45, 65, 80, 100};
#define MAX_BAT_LEVEL 6
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(n516_lpc);
static inline int n516_bat_charging(void)
{
return !gpio_get_value(GPIO_CHARG_STAT_N);
}
static int n516_bat_get_status(struct power_supply *b)
{
if (power_supply_am_i_supplied(b)) {
if (n516_bat_charging())
return POWER_SUPPLY_STATUS_CHARGING;
else
return POWER_SUPPLY_STATUS_FULL;
} else {
return POWER_SUPPLY_STATUS_DISCHARGING;
}
}
static int n516_bat_get_charge(struct power_supply *b)
{
return batt_charge[the_lpc->battery_level];
}
static int n516_bat_get_property(struct power_supply *b,
enum power_supply_property psp,
union power_supply_propval *val)
{
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = n516_bat_get_status(b);
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
val->intval = 100;
break;
case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
val->intval = 0;
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
val->intval = n516_bat_get_charge(b);
break;
default:
return -EINVAL;
}
return 0;
}
static void n516_bat_power_changed(struct power_supply *p)
{
if (power_supply_am_i_supplied(p) && !n516_bat_charging())
the_lpc->battery_level = MAX_BAT_LEVEL;
power_supply_changed(p);
}
static enum power_supply_property n516_bat_properties[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
POWER_SUPPLY_PROP_CHARGE_NOW,
};
static struct power_supply n516_battery = {
.name = "n516-battery",
.get_property = n516_bat_get_property,
.properties = n516_bat_properties,
.num_properties = ARRAY_SIZE(n516_bat_properties),
.external_power_changed = n516_bat_power_changed,
};
static irqreturn_t n516_bat_charge_irq(int irq, void *dev)
{
struct power_supply *psy = dev;
dev_dbg(psy->dev, "Battery charging IRQ\n");
if (power_supply_am_i_supplied(psy) && !n516_bat_charging())
the_lpc->battery_level = MAX_BAT_LEVEL;
power_supply_changed(psy);
return IRQ_HANDLED;
}
static int n516_lpc_send_message(struct n516_lpc_chip *chip, unsigned char val)
{
struct i2c_client *client = chip->i2c_client;
struct i2c_msg msg = {client->addr, client->flags, 1, &val};
int ret = 0;
ret = i2c_transfer(client->adapter, &msg, 1);
return ret > 0 ? 0 : ret;
}
static void n516_key_event(struct n516_lpc_chip *chip, unsigned char keycode)
{
struct i2c_client *client = chip->i2c_client;
bool long_press = false;
if (keycode & 0x40) {
keycode &= ~0x40;
long_press = true;
}
dev_dbg(&client->dev, "keycode: 0x%02x, long_press: 0x%02x\n", keycode, (unsigned int)long_press);
if (keycode >= ARRAY_SIZE(n516_lpc_keymap) || n516_lpc_keymap[keycode] == 0)
return;
if (long_press)
input_report_key(chip->input, KEY_LEFTALT, 1);
input_report_key(chip->input, n516_lpc_keymap[keycode], 1);
input_sync(chip->input);
input_report_key(chip->input, n516_lpc_keymap[keycode], 0);
if (long_press)
input_report_key(chip->input, KEY_LEFTALT, 0);
input_sync(chip->input);
}
static void n516_battery_event(struct n516_lpc_chip *chip, unsigned char battery_level)
{
if (battery_level != chip->battery_level) {
chip->battery_level = battery_level;
power_supply_changed(&n516_battery);
}
}
static irqreturn_t n516_lpc_irq_thread(int irq, void *devid)
{
struct n516_lpc_chip *chip = (struct n516_lpc_chip*)devid;
int ret;
unsigned char raw_msg;
struct i2c_client *client = chip->i2c_client;
struct i2c_msg msg = {client->addr, client->flags | I2C_M_RD, 1, &raw_msg};
if (client->dev.power.status >= DPM_OFF)
return IRQ_HANDLED;
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret != 1) {
dev_dbg(&client->dev, "I2C error: %d\n", ret);
return IRQ_HANDLED;
}
dev_dbg(&client->dev, "msg: 0x%02x\n", raw_msg);
/* Ack wakeup event */
if ((raw_msg & ~0x40) < ARRAY_SIZE(n516_lpc_keymap))
n516_key_event(chip, raw_msg);
else if ((raw_msg >= 0x81) && (raw_msg <= 0x87))
n516_battery_event(chip, raw_msg - 0x81);
else if (raw_msg == 0x7e)
n516_lpc_send_message(chip, 0x00);
else
dev_warn(&client->dev, "Unknown message: %x\n", raw_msg);
if (chip->suspending)
chip->can_sleep = 0;
return IRQ_HANDLED;
}
static void n516_lpc_power_off(void)
{
struct i2c_client *client = the_lpc->i2c_client;
unsigned char val = 0x01;
struct i2c_msg msg = {client->addr, client->flags, 1, &val};
printk("Issue LPC POWEROFF command...\n");
while (1)
i2c_transfer(client->adapter, &msg, 1);
}
static int n516_lpc_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
{
return 0;
}
static int n516_lpc_suspend_notifier(struct notifier_block *nb,
unsigned long event,
void *dummy)
{
switch(event) {
case PM_SUSPEND_PREPARE:
the_lpc->suspending = 1;
the_lpc->can_sleep = 1;
break;
case PM_POST_SUSPEND:
the_lpc->suspending = 0;
the_lpc->can_sleep = 1;
break;
default:
return NOTIFY_DONE;
}
return NOTIFY_OK;
}
static struct notifier_block n516_lpc_notif_block = {
.notifier_call = n516_lpc_suspend_notifier,
};
static int __devinit n516_lpc_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct n516_lpc_chip *chip;
struct input_dev *input;
int ret = 0;
int i;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
the_lpc = chip;
chip->i2c_client = client;
if ((batt_level > 0) && (batt_level < ARRAY_SIZE(batt_charge)))
chip->battery_level = batt_level;
else
chip->battery_level = 1;
i2c_set_clientdata(client, chip);
ret = gpio_request(GPIO_LPC_INT, "LPC interrupt request");
if (ret) {
dev_err(&client->dev, "Unable to reguest LPC INT GPIO\n");
goto err_gpio_req_lpcint;
}
ret = gpio_request(GPIO_CHARG_STAT_N, "LPC charging status");
if (ret) {
dev_err(&client->dev, "Unable to reguest CHARG STAT GPIO\n");
goto err_gpio_req_chargstat;
}
/* Enter normal mode */
n516_lpc_send_message(chip, 0x2);
input = input_allocate_device();
if (!input) {
dev_err(&client->dev, "Unable to allocate input device\n");
ret = -ENOMEM;
goto err_input_alloc;
}
chip->input = input;
__set_bit(EV_KEY, input->evbit);
for (i = 0; i < ARRAY_SIZE(n516_lpc_keymap); i++)
__set_bit(n516_lpc_keymap[i], input->keybit);
__set_bit(KEY_LEFTALT, input->keybit);
input->name = "n516-keys";
input->phys = "n516-keys/input0";
input->dev.parent = &client->dev;
input->id.bustype = BUS_I2C;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
ret = input_register_device(input);
if (ret < 0) {
dev_err(&client->dev, "Unable to register input device\n");
goto err_input_register;
}
ret = power_supply_register(NULL, &n516_battery);
if (ret) {
dev_err(&client->dev, "Unable to register N516 battery\n");
goto err_bat_reg;
}
ret = request_threaded_irq(gpio_to_irq(GPIO_LPC_INT), NULL,
n516_lpc_irq_thread,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"lpc", chip);
if (ret) {
dev_err(&client->dev, "request_irq failed: %d\n", ret);
goto err_request_lpc_irq;
}
ret = request_irq(gpio_to_irq(GPIO_CHARG_STAT_N), n516_bat_charge_irq,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
"battery charging", &n516_battery);
if (ret) {
dev_err(&client->dev, "Unable to claim battery charging IRQ\n");
goto err_request_chrg_irq;
}
pm_power_off = n516_lpc_power_off;
ret = register_pm_notifier(&n516_lpc_notif_block);
if (ret) {
dev_err(&client->dev, "Unable to register PM notify block\n");
goto err_reg_pm_notifier;
}
device_init_wakeup(&client->dev, 1);
return 0;
unregister_pm_notifier(&n516_lpc_notif_block);
err_reg_pm_notifier:
free_irq(gpio_to_irq(GPIO_CHARG_STAT_N), &n516_battery);
err_request_chrg_irq:
free_irq(gpio_to_irq(GPIO_LPC_INT), chip);
err_request_lpc_irq:
power_supply_unregister(&n516_battery);
err_bat_reg:
input_unregister_device(input);
err_input_register:
input_free_device(input);
err_input_alloc:
gpio_free(GPIO_CHARG_STAT_N);
err_gpio_req_chargstat:
gpio_free(GPIO_LPC_INT);
err_gpio_req_lpcint:
i2c_set_clientdata(client, NULL);
kfree(chip);
return ret;
}
static int __devexit n516_lpc_remove(struct i2c_client *client)
{
struct n516_lpc_chip *chip = i2c_get_clientdata(client);
unregister_pm_notifier(&n516_lpc_notif_block);
pm_power_off = NULL;
free_irq(gpio_to_irq(GPIO_CHARG_STAT_N), &n516_battery);
free_irq(gpio_to_irq(GPIO_LPC_INT), chip);
power_supply_unregister(&n516_battery);
input_unregister_device(chip->input);
gpio_free(GPIO_CHARG_STAT_N);
gpio_free(GPIO_LPC_INT);
i2c_set_clientdata(client, NULL);
kfree(chip);
return 0;
}
#if CONFIG_PM
static int n516_lpc_suspend(struct i2c_client *client, pm_message_t msg)
{
if (!the_lpc->can_sleep)
return -EBUSY;
if (device_may_wakeup(&client->dev))
enable_irq_wake(gpio_to_irq(GPIO_LPC_INT));
return 0;
}
static int n516_lpc_resume(struct i2c_client *client)
{
if (device_may_wakeup(&client->dev))
disable_irq_wake(gpio_to_irq(GPIO_LPC_INT));
return 0;
}
#else
#define n516_lpc_suspend NULL
#define n516_lpc_resume NULL
#endif
static struct i2c_driver n516_lpc_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "n516-keys",
.owner = THIS_MODULE,
},
.probe = n516_lpc_probe,
.remove = __devexit_p(n516_lpc_remove),
.detect = n516_lpc_detect,
.id_table = n516_lpc_i2c_ids,
.address_data = &addr_data,
.suspend = n516_lpc_suspend,
.resume = n516_lpc_resume,
};
static int __init n516_lpc_init(void)
{
return i2c_add_driver(&n516_lpc_driver);
}
static void __exit n516_lpc_exit(void)
{
i2c_del_driver(&n516_lpc_driver);
}
module_init(n516_lpc_init);
module_exit(n516_lpc_exit);
MODULE_AUTHOR("Yauhen Kharuzhy");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Keys and power controller driver for N516");
MODULE_ALIAS("platform:n516-keys");

View File

@ -1,237 +0,0 @@
/*
* 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/i2c.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <asm/mach-jz4740/irq.h>
#include <asm/mach-jz4740/gpio.h>
struct n526_lpc {
struct i2c_client *client;
struct input_dev *input;
struct work_struct work;
};
static const unsigned int n526_lpc_keymap[] = {
[0x01] = KEY_PAGEUP,
[0x02] = KEY_PAGEDOWN,
[0x03] = KEY_VOLUMEUP,
[0x04] = KEY_VOLUMEDOWN,
[0x06] = KEY_1,
[0x07] = KEY_Q,
[0x08] = KEY_A,
[0x09] = KEY_Z,
[0x0a] = KEY_LEFTSHIFT,
[0x0b] = KEY_2,
[0x0c] = KEY_W,
[0x0d] = KEY_S,
[0x0e] = KEY_X,
[0x0f] = KEY_REFRESH,
[0x10] = KEY_3,
[0x11] = KEY_E,
[0x12] = KEY_D,
[0x13] = KEY_C,
[0x14] = KEY_DOCUMENTS,
[0x15] = KEY_4,
[0x16] = KEY_R,
[0x17] = KEY_F,
[0x18] = KEY_V,
[0x19] = KEY_MUTE,
[0x1a] = KEY_5,
[0x1b] = KEY_T,
[0x1c] = KEY_G,
[0x1d] = KEY_B,
[0x1e] = KEY_DELETE,
[0x1f] = KEY_6,
[0x20] = KEY_Y,
[0x21] = KEY_H,
[0x22] = KEY_N,
[0x23] = KEY_SPACE,
[0x24] = KEY_7,
[0x25] = KEY_U,
[0x26] = KEY_J,
[0x27] = KEY_M,
/* [0x28] = KEY_SYM, */
[0x29] = KEY_8,
[0x2a] = KEY_I,
[0x2b] = KEY_K,
[0x2c] = KEY_MENU,
[0x2d] = KEY_LEFT,
[0x2e] = KEY_9,
[0x2f] = KEY_O,
[0x30] = KEY_L,
[0x31] = KEY_UP,
[0x32] = KEY_DOWN,
[0x33] = KEY_0,
[0x34] = KEY_P,
[0x35] = KEY_BACKSPACE,
[0x36] = KEY_ENTER,
[0x37] = KEY_RIGHT,
};
static void n526_lpc_irq_work(struct work_struct *work)
{
int ret;
struct n526_lpc *n526_lpc = container_of(work, struct n526_lpc, work);
struct i2c_client *client = n526_lpc->client;
unsigned char raw_msg;
struct i2c_msg msg = {client->addr, client->flags | I2C_M_RD, 1, &raw_msg};
unsigned char keycode;
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret != 1) {
dev_err(&client->dev, "Failed to read lpc status\n");
}
keycode = raw_msg & 0x7f;
if (keycode < ARRAY_SIZE(n526_lpc_keymap)) {
input_report_key(n526_lpc->input, n526_lpc_keymap[keycode],
!(raw_msg & 0x80));
input_sync(n526_lpc->input);
}
}
static irqreturn_t n526_lpc_irq(int irq, void *dev_id)
{
struct n526_lpc *n526_lpc = dev_id;
schedule_work(&n526_lpc->work);
return IRQ_HANDLED;
}
static int __devinit n526_lpc_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
size_t i;
struct n526_lpc *n526_lpc;
struct input_dev *input;
n526_lpc = kmalloc(sizeof(*n526_lpc), GFP_KERNEL);
if (!n526_lpc) {
dev_err(&client->dev, "Failed to allocate device structure\n");
return -ENOMEM;
}
input = input_allocate_device();
if (!input) {
dev_err(&client->dev, "Failed to allocate input device\n");
ret = -ENOMEM;
goto err_free;
}
input->name = "n526-keys";
input->phys = "n526-keys/input0";
input->dev.parent = &client->dev;
input->id.bustype = BUS_I2C;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0001;
__set_bit(EV_KEY, input->evbit);
for (i = 0; i < ARRAY_SIZE(n526_lpc_keymap); ++i) {
if (n526_lpc_keymap[i] != 0)
__set_bit(n526_lpc_keymap[i], input->keybit);
}
ret = input_register_device(input);
if (ret) {
dev_err(&client->dev, "Failed to register input device: %d\n", ret);
goto err_free_input;
}
n526_lpc->client = client;
n526_lpc->input = input;
INIT_WORK(&n526_lpc->work, n526_lpc_irq_work);
ret = request_irq(client->irq, n526_lpc_irq, IRQF_TRIGGER_FALLING,
"n526-lpc", n526_lpc);
if (ret) {
dev_err(&client->dev, "Failed to request irq: %d\n", ret);
goto err_unregister_input;
}
i2c_set_clientdata(client, n526_lpc);
return 0;
err_unregister_input:
input_unregister_device(input);
err_free_input:
input_free_device(input);
err_free:
kfree(n526_lpc);
return ret;
}
static int n526_lpc_remove(struct i2c_client *client)
{
struct n526_lpc *n526_lpc = i2c_get_clientdata(client);
free_irq(client->irq, n526_lpc);
i2c_set_clientdata(client, NULL);
input_unregister_device(n526_lpc->input);
input_free_device(n526_lpc->input);
kfree(n526_lpc);
return 0;
}
static const struct i2c_device_id n526_lpc_id[] = {
{ "n526-lpc", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, n526_lpc_id);
static struct i2c_driver n526_lpc_driver = {
.driver = {
.name = "n526-lpc",
.owner = THIS_MODULE,
},
.probe = n526_lpc_probe,
.remove = n526_lpc_remove,
.id_table = n526_lpc_id,
};
static int __init n526_lpc_init(void)
{
return i2c_add_driver(&n526_lpc_driver);
}
module_init(n526_lpc_init);
static void __exit n526_lpc_exit(void)
{
i2c_del_driver(&n526_lpc_driver);
}
module_exit(n526_lpc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen");
MODULE_DESCRIPTION("n526 keypad driver");
MODULE_ALIAS("i2c:n526-keys");

View File

@ -1,407 +0,0 @@
/*
* 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/clk.h>
#include <linux/err.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 clk *clk;
unsigned int clk_ref;
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);
}
static inline void jz4740_adc_clk_enable(struct jz4740_adc *adc)
{
unsigned long flags;
spin_lock_irqsave(&adc->lock, flags);
if (adc->clk_ref++ == 0)
clk_enable(adc->clk);
spin_unlock_irqrestore(&adc->lock, flags);
}
static inline void jz4740_adc_clk_disable(struct jz4740_adc *adc)
{
unsigned long flags;
spin_lock_irqsave(&adc->lock, flags);
if (--adc->clk_ref == 0)
clk_disable(adc->clk);
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;
jz4740_adc_clk_enable(adc);
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);
jz4740_adc_clk_disable(adc);
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_clk_enable(adc);
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);
jz4740_adc_clk_disable(adc);
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;
}
adc->clk = clk_get(&pdev->dev, "adc");
if (IS_ERR(adc->clk)) {
ret = PTR_ERR(adc->clk);
dev_err(&pdev->dev, "Failed to get clock: %d\n", ret);
goto err_iounmap;
}
init_completion(&adc->bat_completion);
init_completion(&adc->adc_completion);
spin_lock_init(&adc->lock);
adc->clk_ref = 0;
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_clk_put;
}
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_clk_put:
clk_put(adc->clk);
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));
clk_put(adc->clk);
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");

File diff suppressed because it is too large Load Diff

View File

@ -1,441 +0,0 @@
/*
* 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;
bool is_reading;
};
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;
nand->is_reading = true;
break;
case NAND_ECC_WRITE:
reg |= JZ_NAND_ECC_CTRL_ENCODING;
nand->is_reading = false;
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;
static uint8_t all_ff_ecc[] = {0xcd, 0x9d, 0x90, 0x58, 0xf4, 0x8b, 0xff, 0xb7, 0x6f};
if (nand->is_reading)
return 0;
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);
}
/* If the written data is completly 0xff, we also want to write 0xff as
* ecc, otherwise we will get in trouble when doing subpage writes. */
if (memcmp(ecc_code, all_ff_ecc, 9) == 0) {
memset(ecc_code, 0xff, 9);
}
return 0;
}
/*#define printkd printk*/
#define printkd(...)
static void correct_data(uint8_t *dat, int index, int mask)
{
int offset = index & 0x7;
uint16_t data;
printkd("correct: ");
index += (index >> 3);
data = dat[index];
data |= dat[index+1] << 8;
printkd("0x%x -> ", data);
mask ^= (data >> offset) & 0x1ff;
data &= ~(0x1ff << offset);
data |= (mask << offset);
printkd("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;
uint32_t t;
t = read_ecc[0];
if (t == 0xff) {
for (i = 1; i < 9; ++i)
t &= read_ecc[i];
t &= dat[0];
t &= dat[nand->chip.ecc.size / 2];
t &= dat[nand->chip.ecc.size - 1];
if (t == 0xff) {
for (i = 1; i < nand->chip.ecc.size - 1; ++i)
t &= dat[i];
if (t == 0xff)
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) {
printkd("uncorrectable ecc:");
for(i = 0; i < 9; ++i)
printkd(" 0x%x", read_ecc[i]);
printkd("\n");
printkd("uncorrectable data:");
for(i = 0; i < 32; ++i)
printkd(" 0x%x", dat[i]);
printkd("\n");
return -1;
}
error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29;
printkd("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_OOB_FIRST;
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");

View File

@ -1,184 +0,0 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
* Driver for chargers indicating their status through a GPIO pin
*
* 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/types.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/power/gpio-charger.h>
struct gpio_charger {
const struct gpio_charger_platform_data *pdata;
int irq;
struct power_supply charger;
};
static irqreturn_t gpio_charger_irq(int irq, void *devid)
{
struct power_supply *charger = devid;
power_supply_changed(charger);
return IRQ_HANDLED;
}
static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy)
{
return container_of(psy, struct gpio_charger, charger);
}
static int gpio_charger_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy);
const struct gpio_charger_platform_data *pdata = gpio_charger->pdata;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = gpio_get_value(pdata->gpio);
val->intval ^= pdata->gpio_active_low;
break;
default:
return -EINVAL;
}
return 0;
}
static enum power_supply_property gpio_charger_properties[] = {
POWER_SUPPLY_PROP_ONLINE,
};
static int __devinit gpio_charger_probe(struct platform_device *pdev)
{
const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data;
struct gpio_charger *gpio_charger;
struct power_supply *charger;
int ret;
if (!pdata) {
dev_err(&pdev->dev, "No platform data");
return -EINVAL;
}
gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL);
charger = &gpio_charger->charger;
charger->name = pdata->name;
charger->type = pdata->type;
charger->properties = gpio_charger_properties;
charger->num_properties = ARRAY_SIZE(gpio_charger_properties);
charger->get_property = gpio_charger_get_property;
charger->supplied_to = pdata->batteries;
charger->num_supplicants = pdata->num_batteries;
if (gpio_is_valid(pdata->gpio)) {
ret = gpio_request(pdata->gpio, dev_name(&pdev->dev));
if (ret) {
dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret);
goto err;
}
ret = gpio_direction_input(pdata->gpio);
if (ret) {
dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret);
goto err_gpio_free;
}
gpio_charger->irq = gpio_to_irq(pdata->gpio);
if (gpio_charger->irq >= 0) {
ret = request_irq(gpio_charger->irq, gpio_charger_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
dev_name(&pdev->dev), charger);
if (ret) {
dev_warn(&pdev->dev, "Failed to request online gpio irq: %d\n", ret);
gpio_charger->irq = -1;
}
}
}
ret = power_supply_register(&pdev->dev, charger);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register power supply: %d\n", ret);
goto err_gpio_free;
}
gpio_charger->pdata = pdata;
platform_set_drvdata(pdev, gpio_charger);
return 0;
err_gpio_free:
if (gpio_is_valid(pdata->gpio)) {
if (gpio_charger->irq >= 0)
free_irq(gpio_charger->irq, charger);
gpio_free(pdata->gpio);
}
err:
return ret;
}
static int __devexit gpio_charger_remove(struct platform_device *pdev)
{
struct gpio_charger *gpio_charger = platform_get_drvdata(pdev);
const struct gpio_charger_platform_data *pdata = gpio_charger->pdata;
power_supply_unregister(&gpio_charger->charger);
if (gpio_is_valid(pdata->gpio)) {
if (gpio_charger->irq >= 0)
free_irq(gpio_charger->irq, &gpio_charger->charger);
gpio_free(pdata->gpio);
}
platform_set_drvdata(pdev, NULL);
kfree(gpio_charger);
return 0;
}
static struct platform_driver gpio_charger_driver = {
.probe = gpio_charger_probe,
.remove = __devexit_p(gpio_charger_remove),
.driver = {
.name = "gpio-charger",
.owner = THIS_MODULE,
},
};
static int __init gpio_charger_init(void)
{
return platform_driver_register(&gpio_charger_driver);
}
module_init(gpio_charger_init);
static void gpio_charger_exit(void)
{
platform_driver_unregister(&gpio_charger_driver);
}
module_exit(gpio_charger_exit);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Driver for chargers indicating their status through a gpio");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:gpio-charger");

View File

@ -1,350 +0,0 @@
/*
* Battery measurement code for Ingenic JZ SOC.
*
* Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com>
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
*
* based on tosa_battery.c
*
* Copyright (C) 2008 Marek Vasut <marek.vasut@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/interrupt.h>
#include <linux/power/jz4740-battery.h>
#include <linux/jz4740-adc.h>
struct jz_battery {
struct jz_battery_platform_data *pdata;
int charge_irq;
int status;
long voltage;
struct power_supply battery;
struct delayed_work work;
};
static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy)
{
return container_of(psy, struct jz_battery, battery);
}
static long jz_battery_read_voltage(struct jz_battery *jz_battery)
{
struct device *adc = jz_battery->battery.dev->parent->parent;
enum jz_adc_battery_scale scale;
if (jz_battery->pdata->info.voltage_max_design > 2500000)
scale = JZ_ADC_BATTERY_SCALE_7V5;
else
scale = JZ_ADC_BATTERY_SCALE_2V5;
return jz4740_adc_read_battery_voltage(adc, scale);
}
static int jz_battery_get_capacity(struct power_supply *psy)
{
struct jz_battery *jz_battery = psy_to_jz_battery(psy);
struct power_supply_info *info = &jz_battery->pdata->info;
long voltage;
int ret;
int voltage_span;
voltage = jz_battery_read_voltage(jz_battery);
if (voltage < 0)
return voltage;
voltage_span = info->voltage_max_design - info->voltage_min_design;
ret = ((voltage - info->voltage_min_design) * 100) / voltage_span;
if (ret > 100)
ret = 100;
else if (ret < 0)
ret = 0;
return ret;
}
static int jz_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct jz_battery *jz_battery = psy_to_jz_battery(psy);
struct power_supply_info *info = &jz_battery->pdata->info;
long voltage;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = jz_battery->status;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = jz_battery->pdata->info.technology;
break;
case POWER_SUPPLY_PROP_HEALTH:
voltage = jz_battery_read_voltage(jz_battery);
if (voltage < info->voltage_min_design)
val->intval = POWER_SUPPLY_HEALTH_DEAD;
else
val->intval = POWER_SUPPLY_HEALTH_GOOD;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = jz_battery_get_capacity(psy);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = jz_battery_read_voltage(jz_battery);
if (val->intval < 0)
return val->intval;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
val->intval = info->voltage_max_design;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
val->intval = info->voltage_min_design;
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
default:
return -EINVAL;
}
return 0;
}
static void jz_battery_external_power_changed(struct power_supply *psy)
{
struct jz_battery *jz_battery = psy_to_jz_battery(psy);
cancel_delayed_work(&jz_battery->work);
schedule_delayed_work(&jz_battery->work, 0);
}
static irqreturn_t jz_battery_charge_irq(int irq, void *data)
{
struct jz_battery *jz_battery = data;
cancel_delayed_work(&jz_battery->work);
schedule_delayed_work(&jz_battery->work, 0);
return IRQ_HANDLED;
}
static void jz_battery_update(struct jz_battery *jz_battery)
{
int status;
long voltage;
long voltage_difference;
bool has_changed = 0;
if (gpio_is_valid(jz_battery->pdata->gpio_charge)) {
int is_charging;
is_charging = gpio_get_value(jz_battery->pdata->gpio_charge);
is_charging ^= jz_battery->pdata->gpio_charge_active_low;
if (is_charging)
status = POWER_SUPPLY_STATUS_CHARGING;
else
status = POWER_SUPPLY_STATUS_NOT_CHARGING;
if (status != jz_battery->status) {
jz_battery->status = status;
has_changed = 1;
}
}
voltage = jz_battery_read_voltage(jz_battery);
voltage_difference = voltage - jz_battery->voltage;
if (voltage_difference > 50000 || voltage_difference < 50000) {
jz_battery->voltage = voltage;
has_changed = 1;
}
if (has_changed)
power_supply_changed(&jz_battery->battery);
}
static enum power_supply_property jz_battery_properties[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_PRESENT,
};
static void jz_battery_work(struct work_struct *work)
{
/* Too small interval will increase system workload */
const int interval = HZ * 30;
struct jz_battery *jz_battery = container_of(work, struct jz_battery,
work.work);
jz_battery_update(jz_battery);
schedule_delayed_work(&jz_battery->work, interval);
}
static int jz_battery_probe(struct platform_device *pdev)
{
int ret = 0;
struct jz_battery_platform_data *pdata = pdev->dev.platform_data;
struct jz_battery *jz_battery;
struct power_supply *battery;
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "No platform data\n");
return -EINVAL;
}
jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL);
if (!jz_battery) {
dev_err(&pdev->dev, "Failed to allocate driver structure\n");
return -ENOMEM;
}
battery = &jz_battery->battery;
battery->name = pdata->info.name;
battery->type = POWER_SUPPLY_TYPE_BATTERY;
battery->properties = jz_battery_properties;
battery->num_properties = ARRAY_SIZE(jz_battery_properties);
battery->get_property = jz_battery_get_property;
battery->external_power_changed = jz_battery_external_power_changed;
battery->use_for_apm = 1;
jz_battery->pdata = pdata;
INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work);
if (gpio_is_valid(pdata->gpio_charge)) {
ret = gpio_request(pdata->gpio_charge, dev_name(&pdev->dev));
if (ret) {
dev_err(&pdev->dev, "charger state gpio request failed.\n");
goto err_free;
}
ret = gpio_direction_input(pdata->gpio_charge);
if (ret) {
dev_err(&pdev->dev, "charger state gpio set direction failed.\n");
goto err_free_gpio;
}
jz_battery->charge_irq = gpio_to_irq(pdata->gpio_charge);
if (jz_battery->charge_irq >= 0) {
ret = request_irq(jz_battery->charge_irq,
jz_battery_charge_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
dev_name(&pdev->dev), jz_battery);
if (ret) {
dev_err(&pdev->dev, "Failed to request charge irq: %d\n", ret);
goto err_free_gpio;
}
}
} else {
jz_battery->charge_irq = -1;
}
ret = power_supply_register(&pdev->dev, &jz_battery->battery);
if (ret) {
dev_err(&pdev->dev, "power supply battery register failed.\n");
goto err_free_irq;
}
platform_set_drvdata(pdev, jz_battery);
schedule_delayed_work(&jz_battery->work, 0);
return 0;
err_free_irq:
if (jz_battery->charge_irq >= 0)
free_irq(jz_battery->charge_irq, jz_battery);
err_free_gpio:
if (gpio_is_valid(pdata->gpio_charge))
gpio_free(jz_battery->pdata->gpio_charge);
err_free:
kfree(jz_battery);
return ret;
}
static int jz_battery_remove(struct platform_device *pdev)
{
struct jz_battery *jz_battery = platform_get_drvdata(pdev);
cancel_delayed_work_sync(&jz_battery->work);
if (gpio_is_valid(jz_battery->pdata->gpio_charge)) {
if (jz_battery->charge_irq >= 0)
free_irq(jz_battery->charge_irq, jz_battery);
gpio_free(jz_battery->pdata->gpio_charge);
}
power_supply_unregister(&jz_battery->battery);
return 0;
}
#ifdef CONFIG_PM
static int jz_battery_suspend(struct platform_device *pdev, pm_message_t state)
{
struct jz_battery *jz_battery = platform_get_drvdata(pdev);
cancel_delayed_work_sync(&jz_battery->work);
jz_battery->status = POWER_SUPPLY_STATUS_UNKNOWN;
return 0;
}
static int jz_battery_resume(struct platform_device *pdev)
{
struct jz_battery *jz_battery = platform_get_drvdata(pdev);
schedule_delayed_work(&jz_battery->work, 0);
return 0;
}
#else
#define jz_battery_suspend NULL
#define jz_battery_resume NULL
#endif
static struct platform_driver jz_battery_driver = {
.probe = jz_battery_probe,
.remove = __devexit_p(jz_battery_remove),
.suspend = jz_battery_suspend,
.resume = jz_battery_resume,
.driver = {
.name = "jz4740-battery",
.owner = THIS_MODULE,
},
};
static int __init jz_battery_init(void)
{
return platform_driver_register(&jz_battery_driver);
}
module_init(jz_battery_init);
static void __exit jz_battery_exit(void)
{
platform_driver_unregister(&jz_battery_driver);
}
module_exit(jz_battery_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiejing Zhang <kzjeef@gmail.com>");
MODULE_DESCRIPTION("JZ4720/JZ4740 SoC battery driver");

View File

@ -1,333 +0,0 @@
/*
* 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_RTC_REGULATOR 0x0C
#define JZ_REG_RTC_SCRATCHPAD 0x34
#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;
uint32_t scratchpad;
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;
}
scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
if (scratchpad != 0x12345678) {
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
}
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);
free_irq(rtc->irq, rtc);
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");

View File

@ -1,99 +0,0 @@
/*
* 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;
struct clk *clk;
};
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__ */

View File

@ -1,255 +0,0 @@
/*
* 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:
mdelay(20);
gpm940b0->enabled = 1;
gpm940b0_power_enable(gpm940b0);
break;
default:
gpm940b0->enabled = 0;
gpm940b0_power_disable(gpm940b0);
mdelay(20);
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");

View File

@ -1,790 +0,0 @@
/*
* 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/console.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/jz4740_fb.h>
#include <asm/mach-jz4740/gpio.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_PS_DISABLE BIT(23)
#define JZ_LCD_CFG_CLS_DISABLE BIT(22)
#define JZ_LCD_CFG_SPL_DISABLE BIT(21)
#define JZ_LCD_CFG_REV_DISABLE 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_PS_POLARITY BIT(15)
#define JZ_LCD_CFG_CLS_POLARITY BIT(14)
#define JZ_LCD_CFG_SPL_POLARITY BIT(13)
#define JZ_LCD_CFG_REV_POLARITY BIT(12)
#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11)
#define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10)
#define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9)
#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW 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
#define JZ_LCD_STATE_DISABLED BIT(0)
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;
size_t vidmem_size;
void *vidmem;
dma_addr_t vidmem_phys;
struct jzfb_framedesc *framedesc;
dma_addr_t framedesc_phys;
struct clk *ldclk;
struct clk *lpclk;
unsigned is_enabled:1;
struct mutex lock; /* Protecting against running enable/disable in paralell */
uint32_t pseudo_palette[256];
};
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,
};
const static struct jz_gpio_bulk_request jz_lcd_ctrl_pins[] = {
JZ_GPIO_BULK_PIN(LCD_PCLK),
JZ_GPIO_BULK_PIN(LCD_HSYNC),
JZ_GPIO_BULK_PIN(LCD_VSYNC),
JZ_GPIO_BULK_PIN(LCD_DE),
JZ_GPIO_BULK_PIN(LCD_PS),
JZ_GPIO_BULK_PIN(LCD_REV),
};
const static struct jz_gpio_bulk_request jz_lcd_data_pins[] = {
JZ_GPIO_BULK_PIN(LCD_DATA0),
JZ_GPIO_BULK_PIN(LCD_DATA1),
JZ_GPIO_BULK_PIN(LCD_DATA2),
JZ_GPIO_BULK_PIN(LCD_DATA3),
JZ_GPIO_BULK_PIN(LCD_DATA4),
JZ_GPIO_BULK_PIN(LCD_DATA5),
JZ_GPIO_BULK_PIN(LCD_DATA6),
JZ_GPIO_BULK_PIN(LCD_DATA7),
JZ_GPIO_BULK_PIN(LCD_DATA8),
JZ_GPIO_BULK_PIN(LCD_DATA9),
JZ_GPIO_BULK_PIN(LCD_DATA10),
JZ_GPIO_BULK_PIN(LCD_DATA11),
JZ_GPIO_BULK_PIN(LCD_DATA12),
JZ_GPIO_BULK_PIN(LCD_DATA13),
JZ_GPIO_BULK_PIN(LCD_DATA14),
JZ_GPIO_BULK_PIN(LCD_DATA15),
JZ_GPIO_BULK_PIN(LCD_DATA16),
JZ_GPIO_BULK_PIN(LCD_DATA17),
};
static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb)
{
unsigned int num;
switch (jzfb->pdata->lcd_type) {
case JZ_LCD_TYPE_GENERIC_16_BIT:
num = 4;
break;
case JZ_LCD_TYPE_GENERIC_18_BIT:
num = 4;
break;
case JZ_LCD_TYPE_8BIT_SERIAL:
num = 3;
break;
default:
num = 0;
break;
}
return num;
}
static unsigned int jzfb_num_data_pins(struct jzfb *jzfb)
{
unsigned int num;
switch (jzfb->pdata->lcd_type) {
case JZ_LCD_TYPE_GENERIC_16_BIT:
num = 16;
break;
case JZ_LCD_TYPE_GENERIC_18_BIT:
num = 19;
break;
case JZ_LCD_TYPE_8BIT_SERIAL:
num = 8;
break;
default:
num = 0;
break;
}
return num;
}
static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
unsigned transp, struct fb_info *fb)
{
if (regno >= fb->cmap.len)
return -EINVAL;
((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;
case 15:
return 16;
default:
return jzfb->pdata->bpp;
}
}
static struct fb_videomode *jzfb_get_mode(struct jzfb* jzfb, struct fb_var_screeninfo *var)
{
size_t i;
struct fb_videomode *mode = jzfb->pdata->modes;
for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
if (mode->xres == var->xres && mode->yres == var->yres)
return mode;
}
return NULL;
}
static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
{
struct jzfb* jzfb = fb->par;
struct fb_videomode *mode;
if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
var->bits_per_pixel != jzfb->pdata->bpp)
return -EINVAL;
mode = jzfb_get_mode(jzfb, var);
if (mode == NULL)
return -EINVAL;
fb_videomode_to_var(var, 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;
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;
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;
struct fb_videomode *mode;
uint16_t hds, vds;
uint16_t hde, vde;
uint16_t ht, vt;
uint32_t ctrl;
uint32_t cfg;
unsigned long rate;
mode = jzfb_get_mode(jzfb, var);
if (mode == NULL)
return -EINVAL;
info->mode = mode;
hds = mode->hsync_len + mode->left_margin;
hde = hds + mode->xres;
ht = hde + mode->right_margin;
vds = mode->vsync_len + mode->upper_margin;
vde = vds + mode->yres;
vt = vde + mode->lower_margin;
ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16;
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;
}
cfg = 0;
cfg |= JZ_LCD_CFG_PS_DISABLE;
cfg |= JZ_LCD_CFG_CLS_DISABLE;
cfg |= JZ_LCD_CFG_SPL_DISABLE;
cfg |= JZ_LCD_CFG_REV_DISABLE;
if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
if (jzfb->pdata->pixclk_falling_edge)
cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
if (jzfb->pdata->date_enable_active_low)
cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT)
cfg |= JZ_LCD_CFG_18_BIT;
cfg |= jzfb->pdata->lcd_type & 0xf;
if (mode->pixclock) {
rate = PICOS2KHZ(mode->pixclock) * 1000;
mode->refresh = rate / vt / ht;
} else {
if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL)
rate = mode->refresh * (vt + 2 * mode->xres) * ht;
else
rate = mode->refresh * vt * ht;
mode->pixclock = KHZ2PICOS(rate / 1000);
}
mutex_lock(&jzfb->lock);
if (!jzfb->is_enabled)
clk_enable(jzfb->ldclk);
else
ctrl |= JZ_LCD_CTRL_ENABLE;
writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC);
writel(mode->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);
writel(cfg, jzfb->base + JZ_REG_LCD_CFG);
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
if (!jzfb->is_enabled)
clk_disable(jzfb->ldclk);
mutex_unlock(&jzfb->lock);
clk_set_rate(jzfb->lpclk, rate);
clk_set_rate(jzfb->ldclk, rate * 3);
return 0;
}
static void jzfb_enable(struct jzfb *jzfb)
{
uint32_t ctrl;
clk_enable(jzfb->ldclk);
jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
writel(0, jzfb->base + JZ_REG_LCD_STATE);
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
ctrl |= JZ_LCD_CTRL_ENABLE;
ctrl &= ~JZ_LCD_CTRL_DISABLE;
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
}
static void jzfb_disable(struct jzfb *jzfb)
{
uint32_t ctrl;
ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
ctrl |= JZ_LCD_CTRL_DISABLE;
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
do {
ctrl = readl(jzfb->base + JZ_REG_LCD_STATE);
} while (!(ctrl & JZ_LCD_STATE_DISABLED));
jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
clk_disable(jzfb->ldclk);
}
static int jzfb_blank(int blank_mode, struct fb_info *info)
{
struct jzfb* jzfb = info->par;
switch (blank_mode) {
case FB_BLANK_UNBLANK:
mutex_lock(&jzfb->lock);
if (jzfb->is_enabled) {
mutex_unlock(&jzfb->lock);
return 0;
}
jzfb_enable(jzfb);
jzfb->is_enabled = 1;
mutex_unlock(&jzfb->lock);
break;
default:
mutex_lock(&jzfb->lock);
if (!jzfb->is_enabled) {
mutex_unlock(&jzfb->lock);
return 0;
}
jzfb_disable(jzfb);
jzfb->is_enabled = 0;
mutex_unlock(&jzfb->lock);
break;
}
return 0;
}
static int jzfb_alloc_devmem(struct jzfb *jzfb)
{
int max_videosize = 0;
struct fb_videomode *mode = jzfb->pdata->modes;
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;
jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
sizeof(*jzfb->framedesc),
&jzfb->framedesc_phys, GFP_KERNEL);
if (!jzfb->framedesc)
return -ENOMEM;
jzfb->vidmem_size = PAGE_ALIGN(max_videosize);
jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
jzfb->vidmem_size,
&jzfb->vidmem_phys, GFP_KERNEL);
if (!jzfb->vidmem) {
goto err_free_framedesc;
}
for (page = jzfb->vidmem;
page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
page += PAGE_SIZE) {
SetPageReserved(virt_to_page(page));
}
jzfb->framedesc->next = jzfb->framedesc_phys;
jzfb->framedesc->addr = jzfb->vidmem_phys;
jzfb->framedesc->id = 0xdeafbead;
jzfb->framedesc->cmd = 0;
jzfb->framedesc->cmd |= max_videosize / 4;
return 0;
err_free_framedesc:
dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
jzfb->framedesc, jzfb->framedesc_phys);
return -ENOMEM;
}
static void jzfb_free_devmem(struct jzfb *jzfb)
{
dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
jzfb->vidmem, jzfb->vidmem_phys);
dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
jzfb->framedesc, jzfb->framedesc_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->ldclk = clk_get(&pdev->dev, "lcd");
jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
if (IS_ERR(jzfb->ldclk)) {
ret = PTR_ERR(jzfb->ldclk);
dev_err(&pdev->dev, "Faild to get device clock: %d\n", ret);
goto err_framebuffer_release;
}
if (IS_ERR(jzfb->lpclk)) {
ret = PTR_ERR(jzfb->ldclk);
dev_err(&pdev->dev, "Faild to get pixel clock: %d\n", ret);
goto err_framebuffer_release;
}
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_devmem(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);
mutex_init(&jzfb->lock);
clk_enable(jzfb->ldclk);
jzfb->is_enabled = 1;
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
jzfb_set_par(fb);
jz_gpio_bulk_request(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
jz_gpio_bulk_request(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
ret = register_framebuffer(fb);
if (ret) {
dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
goto err_free_devmem;
}
jzfb->fb = fb;
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);
jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
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;
}
#ifdef CONFIG_PM
static int jzfb_suspend(struct device *dev)
{
struct jzfb *jzfb = dev_get_drvdata(dev);
acquire_console_sem();
fb_set_suspend(jzfb->fb, 1);
release_console_sem();
mutex_lock(&jzfb->lock);
if (jzfb->is_enabled)
jzfb_disable(jzfb);
mutex_unlock(&jzfb->lock);
return 0;
}
static int jzfb_resume(struct device *dev)
{
struct jzfb *jzfb = dev_get_drvdata(dev);
clk_enable(jzfb->ldclk);
mutex_lock(&jzfb->lock);
if (jzfb->is_enabled)
jzfb_enable(jzfb);
mutex_unlock(&jzfb->lock);
acquire_console_sem();
fb_set_suspend(jzfb->fb, 0);
release_console_sem();
return 0;
}
static const struct dev_pm_ops jzfb_pm_ops = {
.suspend = jzfb_suspend,
.resume = jzfb_resume,
.poweroff = jzfb_suspend,
.restore = jzfb_resume,
};
#define JZFB_PM_OPS (&jzfb_pm_ops)
#else
#define JZFB_PM_OPS NULL
#endif
static struct platform_driver jzfb_driver = {
.probe = jzfb_probe,
.remove = __devexit_p(jzfb_remove),
.driver = {
.name = "jz4740-fb",
.pm = JZFB_PM_OPS,
},
};
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");

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
#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

View File

@ -1,58 +0,0 @@
/*
* 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_BIT = 0,
JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4),
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_DUAL_MONOCHROME_STN = 11,
JZ_LCD_TYPE_8BIT_SERIAL = 12,
};
/*
* 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;
unsigned int bpp;
enum jz4740_fb_lcd_type lcd_type;
unsigned pixclk_falling_edge:1;
unsigned date_enable_active_low:1;
};
#endif

View File

@ -1,15 +0,0 @@
#ifndef __LINUX_MMC_JZ4740_MMC
#define __LINUX_MMC_JZ4740_MMC
struct jz4740_mmc_platform_data {
int gpio_power;
int gpio_card_detect;
int gpio_read_only;
unsigned card_detect_active_low:1;
unsigned read_only_active_low:1;
unsigned power_active_low:1;
unsigned data_1bit:1;
};
#endif

View File

@ -1,34 +0,0 @@
/*
* 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

View File

@ -1,28 +0,0 @@
/*
* Copyright (C) 2010, 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_POWER_GPIO_CHARGER_H__
#define __LINUX_POWER_GPIO_CHARGER_H__
struct gpio_charger_platform_data {
const char *name;
enum power_supply_type type;
int gpio;
int gpio_active_low;
char **batteries;
size_t num_batteries;
};
#endif

View File

@ -1,24 +0,0 @@
/*
* 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_battery_platform_data {
struct power_supply_info info;
int gpio_charge; /* GPIO port of Charger state */
int gpio_charge_active_low;
};
#endif

View File

@ -1,73 +0,0 @@
/*
* metronomefb.h - definitions for the metronome framebuffer driver
*
* Copyright (C) 2008 by Jaya Kumar
*
* 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.
*
*/
#ifndef _LINUX_METRONOMEFB_H_
#define _LINUX_METRONOMEFB_H_
/* command structure used by metronome controller */
struct metromem_cmd {
u16 opcode;
u16 args[((64-2)/2)];
u16 csum;
} __attribute__((packed));
struct epd_frame;
/* struct used by metronome. board specific stuff comes from *board */
struct metronomefb_par {
struct metromem_cmd *metromem_cmd;
unsigned char *metromem_wfm;
unsigned char *metromem_img;
u16 *metromem_img_csum;
u16 *csum_table;
dma_addr_t metromem_dma;
const struct firmware *firmware;
struct fb_info *info;
struct metronome_board *board;
struct platform_device *pdev;
wait_queue_head_t waitq;
u8 frame_count;
int extra_size;
int current_wf_mode;
int current_wf_temp;
unsigned int manual_refresh_threshold;
unsigned int partial_autorefresh_interval;
const struct epd_frame *epd_frame;
u32 *fxbuckets;
u32 *fybuckets;
unsigned int partial_updates_count;
unsigned is_first_update:1;
struct mutex lock;
};
#define METRONOME_POWER_OFF 0
#define METRONOME_POWER_ON 1
/* board specific routines and data */
struct metronome_board {
struct module *owner; /* the platform device */
void (*power_ctl)(struct metronomefb_par *, int);
void (*set_rst)(struct metronomefb_par *, int);
void (*set_stdby)(struct metronomefb_par *, int);
int (*get_err)(struct metronomefb_par *);
int (*get_rdy)(struct metronomefb_par *);
void (*cleanup)(struct metronomefb_par *);
int (*met_wait_event)(struct metronomefb_par *);
int (*met_wait_event_intr)(struct metronomefb_par *);
int (*setup_irq)(struct fb_info *);
int (*setup_fb)(struct metronomefb_par *);
int (*setup_io)(struct metronomefb_par *);
int (*get_panel_type)(void);
};
#endif

View File

@ -1,520 +0,0 @@
/*
* 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_FMTBIT_S16_LE,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_44100,
.formats = SNDRV_PCM_FMTBIT_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;
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_SW2_ENABLE, JZ_CODEC_1_SW2_ENABLE);
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");

View File

@ -1,22 +0,0 @@
/*
* 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

View File

@ -1,37 +0,0 @@
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_N516
tristate "SoC Audio support for Hanvon N516 eBook reader"
depends on SND_JZ4740_SOC && JZ4740_N516
select SND_JZ4740_SOC_I2S
select SND_SOC_JZCODEC
help
Say Y if you want to enable support for SoC audio on the Hanvon N516.
config SND_JZ4740_SOC_N526
tristate "SoC Audio support for Hanvon N526 eBook reader"
depends on SND_JZ4740_SOC && JZ4740_N526
select SND_JZ4740_SOC_I2S
select SND_SOC_JZCODEC
help
Say Y if you want to enable support for SoC audio on the Hanvon N526.
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.

View File

@ -1,17 +0,0 @@
#
# 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
snd-soc-n516-objs := n516.o
snd-soc-n526-objs := n526.o
obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
obj-$(CONFIG_SND_JZ4740_SOC_N516) += snd-soc-n516.o
obj-$(CONFIG_SND_JZ4740_SOC_N526) += snd-soc-n526.o

View File

@ -1,570 +0,0 @@
/*
* Copyright (C) 2010, 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.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "jz4740-i2s.h"
#include "jz4740-pcm.h"
#define JZ_REG_AIC_CONF 0x00
#define JZ_REG_AIC_CTRL 0x04
#define JZ_REG_AIC_I2S_FMT 0x10
#define JZ_REG_AIC_FIFO_STATUS 0x14
#define JZ_REG_AIC_I2S_STATUS 0x1c
#define JZ_REG_AIC_CLK_DIV 0x30
#define JZ_REG_AIC_FIFO 0x34
#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf << 8)
#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
#define JZ_AIC_CONF_I2S BIT(4)
#define JZ_AIC_CONF_RESET BIT(3)
#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
#define JZ_AIC_CONF_ENABLE BIT(0)
#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
#define JZ_AIC_CTRL_FLUSH BIT(8)
#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16
#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
#define JZ_AIC_I2S_FMT_MSB BIT(0)
#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
#define JZ_AIC_CLK_DIV_MASK 0xf
struct jz4740_i2s {
struct resource *mem;
void __iomem *base;
dma_addr_t phys_base;
struct clk *clk_aic;
struct clk *clk_i2s;
struct jz4740_pcm_config pcm_config;
};
static struct jz4740_dma_config jz4740_i2s_dma_playback_config = {
.src_width = JZ4740_DMA_WIDTH_16BIT,
.dst_width = JZ4740_DMA_WIDTH_32BIT,
.transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE,
.request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT,
.flags = JZ4740_DMA_SRC_AUTOINC,
.mode = JZ4740_DMA_MODE_SINGLE,
};
static struct jz4740_dma_config jz4740_i2s_dma_capture_config = {
.src_width = JZ4740_DMA_WIDTH_32BIT,
.dst_width = JZ4740_DMA_WIDTH_16BIT,
.transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE,
.request_type = JZ4740_DMA_TYPE_AIC_RECEIVE,
.flags = JZ4740_DMA_DST_AUTOINC,
.mode = JZ4740_DMA_MODE_SINGLE,
};
static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, unsigned int reg)
{
return readl(i2s->base + reg);
}
static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s, unsigned
int reg, uint32_t value)
{
writel(value, i2s->base + reg);
}
static inline struct jz4740_i2s *jz4740_dai_to_i2s(struct snd_soc_dai *dai)
{
return dai->private_data;
}
static int jz4740_i2s_startup(struct snd_pcm_substream *substream, struct
snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t conf, ctrl;
if (dai->active)
return 0;
conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
conf |= JZ_AIC_CONF_ENABLE;
ctrl |= JZ_AIC_CTRL_FLUSH;
jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
clk_enable(i2s->clk_i2s);
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
return 0;
}
static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, struct
snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t conf;
if (!dai->active)
return;
conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
conf &= ~JZ_AIC_CONF_ENABLE;
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
clk_disable(i2s->clk_i2s);
}
static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
uint32_t ctrl;
uint32_t mask;
if (playback) {
mask = JZ_AIC_CTRL_ENABLE_PLAYBACK |
JZ_AIC_CTRL_ENABLE_TX_DMA;
} else {
mask = JZ_AIC_CTRL_ENABLE_CAPTURE |
JZ_AIC_CTRL_ENABLE_RX_DMA;
}
ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
ctrl |= mask;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
ctrl &= ~mask;
break;
default:
return -EINVAL;
}
jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
return 0;
}
static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t format = 0;
uint32_t conf;
conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
conf |= JZ_AIC_CONF_BIT_CLK_MASTER |
JZ_AIC_CONF_SYNC_CLK_MASTER;
format |= JZ_AIC_I2S_FMT_ENABLE_SYS_CLK;
break;
case SND_SOC_DAIFMT_CBM_CFS:
conf |= JZ_AIC_CONF_SYNC_CLK_MASTER;
break;
case SND_SOC_DAIFMT_CBS_CFM:
conf |= JZ_AIC_CONF_BIT_CLK_MASTER;
break;
case SND_SOC_DAIFMT_CBM_CFM:
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_MSB:
format |= JZ_AIC_I2S_FMT_MSB;
break;
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;
}
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
return 0;
}
static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
int sample_size;
enum jz4740_dma_width dma_width;
uint32_t ctrl;
ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
sample_size = 0;
dma_width = JZ4740_DMA_WIDTH_8BIT;
break;
case SNDRV_PCM_FORMAT_S16:
sample_size = 1;
dma_width = JZ4740_DMA_WIDTH_16BIT;
break;
default:
return -EINVAL;
}
if (playback) {
ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
} else {
ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
}
switch (params_channels(params)) {
case 2:
break;
case 1:
if (playback) {
ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
break;
}
default:
return -EINVAL;
}
jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
/* This is quite ugly, but apperently it's offical method for passing dma
* config to the pcm module */
if (playback) {
jz4740_i2s_dma_playback_config.src_width = dma_width;
i2s->pcm_config.dma_config = &jz4740_i2s_dma_playback_config;
} else {
jz4740_i2s_dma_capture_config.dst_width = dma_width;
i2s->pcm_config.dma_config = &jz4740_i2s_dma_capture_config;
}
i2s->pcm_config.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
dai->dma_data = &i2s->pcm_config;
return 0;
}
static int jz4740_i2s_set_clkdiv(struct snd_soc_dai *dai,
int div_id, int div)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
switch (div_id) {
case JZ4740_I2S_BIT_CLK:
if (div & 1 || div > 16)
return -EINVAL;
jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div - 1);
break;
default:
return -EINVAL;
}
return 0;
}
static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
int ret = 0;
struct clk *parent;
switch (clk_id) {
case JZ4740_I2S_CLKSRC_EXT:
parent = clk_get(NULL, "ext");
clk_set_parent(i2s->clk_i2s, parent);
break;
case JZ4740_I2S_CLKSRC_PLL:
parent = clk_get(NULL, "pll half");
clk_set_parent(i2s->clk_i2s, parent);
ret = clk_set_rate(i2s->clk_i2s, freq);
break;
default:
return -EINVAL;
}
clk_put(parent);
return ret;
}
static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t conf;
if (dai->active) {
conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
conf &= ~JZ_AIC_CONF_ENABLE;
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
clk_disable(i2s->clk_i2s);
}
clk_disable(i2s->clk_aic);
return 0;
}
static int jz4740_i2s_resume(struct snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t conf;
clk_enable(i2s->clk_aic);
if (dai->active) {
clk_enable(i2s->clk_i2s);
conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
conf |= JZ_AIC_CONF_ENABLE;
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
}
return 0;
}
static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t conf;
conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
JZ_AIC_CONF_I2S |
JZ_AIC_CONF_INTERNAL_CODEC;
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
return 0;
}
static struct snd_soc_dai_ops 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_fmt,
.set_clkdiv = jz4740_i2s_set_clkdiv,
.set_sysclk = jz4740_i2s_set_sysclk,
};
#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE)
struct snd_soc_dai jz4740_i2s_dai = {
.name = "jz4740-i2s",
.probe = jz4740_i2s_probe,
.playback = {
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_44100,
.formats = JZ4740_I2S_FMTS,
},
.capture = {
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_44100,
.formats = JZ4740_I2S_FMTS,
},
.symmetric_rates = 1,
.ops = &jz4740_i2s_dai_ops,
.suspend = jz4740_i2s_suspend,
.resume = jz4740_i2s_resume,
};
EXPORT_SYMBOL_GPL(jz4740_i2s_dai);
static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
{
struct jz4740_i2s *i2s;
int ret;
i2s = kzalloc(sizeof(*i2s), GFP_KERNEL);
if (!i2s)
return -ENOMEM;
i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!i2s->mem) {
ret = -ENOENT;
goto err_free;
}
i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem),
pdev->name);
if (!i2s->mem) {
ret = -EBUSY;
goto err_free;
}
i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem));
if (!i2s->base) {
ret = -EBUSY;
goto err_release_mem_region;
}
i2s->phys_base = i2s->mem->start;
jz4740_i2s_dai.private_data = i2s;
ret = snd_soc_register_dai(&jz4740_i2s_dai);
i2s->clk_aic = clk_get(&pdev->dev, "aic");
if (IS_ERR(i2s->clk_aic)) {
ret = PTR_ERR(i2s->clk_aic);
goto err_iounmap;
}
i2s->clk_i2s = clk_get(&pdev->dev, "i2s");
if (IS_ERR(i2s->clk_i2s)) {
ret = PTR_ERR(i2s->clk_i2s);
goto err_iounmap;
}
clk_enable(i2s->clk_aic);
platform_set_drvdata(pdev, i2s);
return 0;
err_iounmap:
iounmap(i2s->base);
err_release_mem_region:
release_mem_region(i2s->mem->start, resource_size(i2s->mem));
err_free:
kfree(i2s);
return ret;
}
static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev)
{
struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
snd_soc_unregister_dai(&jz4740_i2s_dai);
clk_disable(i2s->clk_aic);
clk_put(i2s->clk_i2s);
clk_put(i2s->clk_aic);
iounmap(i2s->base);
release_mem_region(i2s->mem->start, resource_size(i2s->mem));
platform_set_drvdata(pdev, NULL);
kfree(i2s);
return 0;
}
static struct platform_driver jz4740_i2s_driver = {
.probe = jz4740_i2s_dev_probe,
.remove = __devexit_p(jz4740_i2s_dev_remove),
.driver = {
.name = "jz4740-i2s",
.owner = THIS_MODULE,
},
};
static int __init jz4740_i2s_init(void)
{
return platform_driver_register(&jz4740_i2s_driver);
}
module_init(jz4740_i2s_init);
static void __exit jz4740_i2s_exit(void)
{
platform_driver_unregister(&jz4740_i2s_driver);
}
module_exit(jz4740_i2s_exit);
MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:jz4740-i2s");

View File

@ -1,18 +0,0 @@
/*
* 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
/* I2S clock source */
#define JZ4740_I2S_CLKSRC_EXT 0
#define JZ4740_I2S_CLKSRC_PLL 1
#define JZ4740_I2S_BIT_CLK 0
extern struct snd_soc_dai jz4740_i2s_dai;
#endif

View File

@ -1,345 +0,0 @@
/*
* Copyright (C) 2010, 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.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.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/mach-jz4740/dma.h>
#include "jz4740-pcm.h"
struct jz4740_runtime_data {
unsigned int dma_period;
dma_addr_t dma_start;
dma_addr_t dma_pos;
dma_addr_t dma_end;
struct jz4740_dma_chan *dma;
dma_addr_t fifo_addr;
};
/* 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,
.channels_min = 1,
.channels_max = 2,
.period_bytes_min = 32,
.period_bytes_max = 2 * PAGE_SIZE,
.periods_min = 2,
.periods_max = 128,
.buffer_bytes_max = 128 * 2 * PAGE_SIZE,
.fifo_size = 32,
};
static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd, int stream)
{
unsigned int count;
if (prtd->dma_pos + prtd->dma_period > prtd->dma_end)
count = prtd->dma_end - prtd->dma_pos;
else
count = prtd->dma_period;
jz4740_dma_disable(prtd->dma);
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
jz4740_dma_set_src_addr(prtd->dma, prtd->dma_pos);
jz4740_dma_set_dst_addr(prtd->dma, prtd->fifo_addr);
} else {
jz4740_dma_set_src_addr(prtd->dma, prtd->fifo_addr);
jz4740_dma_set_dst_addr(prtd->dma, prtd->dma_pos);
}
jz4740_dma_set_transfer_count(prtd->dma, count);
jz4740_dma_enable(prtd->dma);
prtd->dma_pos += prtd->dma_period;
if (prtd->dma_pos >= prtd->dma_end)
prtd->dma_pos = prtd->dma_start;
}
static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err,
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;
snd_pcm_period_elapsed(substream);
jz4740_pcm_start_transfer(prtd, substream->stream);
}
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_config *config;
config = rtd->dai->cpu_dai->dma_data;
if (!prtd->dma) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
prtd->dma = jz4740_dma_request(substream, "PCM Playback");
else
prtd->dma = jz4740_dma_request(substream, "PCM Capture");
}
if (!prtd->dma)
return -EBUSY;
jz4740_dma_configure(prtd->dma, config->dma_config);
prtd->fifo_addr = config->fifo_addr;
jz4740_dma_set_complete_cb(prtd->dma, jz4740_pcm_dma_transfer_done);
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params);
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 + runtime->dma_bytes;
return 0;
}
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->dma) {
jz4740_dma_free(prtd->dma);
prtd->dma = NULL;
}
return 0;
}
static int jz4740_pcm_prepare(struct snd_pcm_substream *substream)
{
struct jz4740_runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
if (!prtd->dma)
return 0;
prtd->dma_pos = prtd->dma_start;
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:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
jz4740_pcm_start_transfer(prtd, substream->stream);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
jz4740_dma_disable(prtd->dma);
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;
unsigned long count, pos;
snd_pcm_uframes_t offset;
struct jz4740_dma_chan *dma = prtd->dma;
count = jz4740_dma_get_residue(dma);
if (prtd->dma_pos == prtd->dma_start)
pos = prtd->dma_end - prtd->dma_start - count;
else
pos = prtd->dma_pos - prtd->dma_start - count;
offset = bytes_to_frames(runtime, pos);
if (offset >= runtime->buffer_size)
offset = 0;
return offset;
}
static int jz4740_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct jz4740_runtime_data *prtd;
snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware);
prtd = kzalloc(sizeof(struct jz4740_runtime_data), GFP_KERNEL);
if (prtd == NULL)
return -ENOMEM;
runtime->private_data = prtd;
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;
kfree(prtd);
return 0;
}
static int jz4740_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
return remap_pfn_range(vma, vma->vm_start,
substream->dma_buffer.addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
}
static 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_noncoherent(pcm->card->dev, size,
&buf->addr, GFP_KERNEL);
if (!buf->area)
return -ENOMEM;
buf->bytes = size;
return 0;
}
static void jz4740_pcm_free(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;
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 err;
}
if (dai->capture.channels_min) {
ret = jz4740_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto err;
}
err:
return ret;
}
struct snd_soc_platform jz4740_soc_platform = {
.name = "jz4740-pcm",
.pcm_ops = &jz4740_pcm_ops,
.pcm_new = jz4740_pcm_new,
.pcm_free = jz4740_pcm_free,
};
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("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver");
MODULE_LICENSE("GPL");

View File

@ -1,22 +0,0 @@
/*
*
* 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 <linux/dma-mapping.h>
#include <asm/mach-jz4740/dma.h>
/* platform data */
extern struct snd_soc_platform jz4740_soc_platform;
struct jz4740_pcm_config {
struct jz4740_dma_config *dma_config;
phys_addr_t fifo_addr;
};
#endif

View File

@ -1,303 +0,0 @@
/*
* Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com>
* OpenInkpot project
* Copyright (C) 2010, 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/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 <sound/jack.h>
#include <linux/gpio.h>
#include <linux/workqueue.h>
#include "../codecs/jzcodec.h"
#include "jz4740-pcm.h"
#include "jz4740-i2s.h"
#include <asm/mach-jz4740/board-n516.h>
enum {
N516_SPEAKER_AUTO = 0,
N516_SPEAKER_OFF = 1,
N516_SPEAKER_ON = 2,
};
static int n516_speaker_mode;
static struct snd_soc_codec *n516_codec;
static struct work_struct n516_headphone_work;
static void n516_ext_control(void)
{
if (!n516_codec)
return;
switch (n516_speaker_mode) {
case N516_SPEAKER_ON:
snd_soc_dapm_enable_pin(n516_codec, "Speaker");
break;
case N516_SPEAKER_OFF:
snd_soc_dapm_disable_pin(n516_codec, "Speaker");
break;
case N516_SPEAKER_AUTO:
if (snd_soc_dapm_get_pin_status(n516_codec, "Headphone"))
snd_soc_dapm_disable_pin(n516_codec, "Speaker");
else
snd_soc_dapm_enable_pin(n516_codec, "Speaker");
break;
default:
break;
}
/* signal a DAPM event */
snd_soc_dapm_sync(n516_codec);
}
static int n516_speaker_event(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *ctrl, int event)
{
int on = !SND_SOC_DAPM_EVENT_OFF(event);
gpio_set_value(GPIO_SPEAKER_ENABLE, on);
return 0;
}
static void n516_headphone_event_work(struct work_struct *work)
{
n516_ext_control();
}
static int n516_headphone_event(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *ctrl, int event)
{
/* We can't call soc_dapm_sync from a event handler */
if (event & (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD))
schedule_work(&n516_headphone_work);
return 0;
}
static const struct snd_soc_dapm_widget n516_widgets[] = {
SND_SOC_DAPM_SPK("Speaker", n516_speaker_event),
SND_SOC_DAPM_HP("Headphone", n516_headphone_event),
SND_SOC_DAPM_MIC("Mic", NULL),
};
static const struct snd_soc_dapm_route n516_routes[] = {
{"Mic", NULL, "MIC"},
{"Speaker", NULL, "LOUT"},
{"Speaker", NULL, "ROUT"},
{"Headphone", NULL, "LOUT"},
{"Headphone", NULL, "ROUT"},
};
static const char *n516_speaker_modes[] = {"Auto", "Off", "On"};
static const struct soc_enum n516_speaker_mode_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(n516_speaker_modes), n516_speaker_modes);
static int n516_get_speaker_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = n516_speaker_mode;
return 0;
}
static int n516_set_speaker_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
if (n516_speaker_mode == ucontrol->value.integer.value[0])
return 0;
n516_speaker_mode = ucontrol->value.integer.value[0];
n516_ext_control();
return 1;
}
static const struct snd_kcontrol_new n516_controls[] = {
SOC_ENUM_EXT("Speaker Function", n516_speaker_mode_enum,
n516_get_speaker_mode, n516_set_speaker_mode),
};
#define N516_DAIFMT (SND_SOC_DAIFMT_I2S | \
SND_SOC_DAIFMT_NB_NF | \
SND_SOC_DAIFMT_CBM_CFM)
static int n516_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;
n516_codec = codec;
snd_soc_dapm_nc_pin(codec, "LIN");
snd_soc_dapm_nc_pin(codec, "RIN");
ret = snd_soc_dai_set_fmt(codec_dai, N516_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, N516_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;
}
ret = snd_soc_add_controls(codec, n516_controls,
ARRAY_SIZE(n516_controls));
if (ret) {
dev_err(codec->dev, "Failed to add controls: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_new_controls(codec, n516_widgets,
ARRAY_SIZE(n516_widgets));
if (ret) {
dev_err(codec->dev, "Failed to add dapm controls: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_add_routes(codec, n516_routes, ARRAY_SIZE(n516_routes));
if (ret) {
dev_err(codec->dev, "Failed to add dapm routes: %d\n", ret);
return ret;
}
snd_soc_dapm_sync(codec);
return 0;
}
static struct snd_soc_dai_link n516_dai = {
.name = "jz-codec",
.stream_name = "JZCODEC",
.cpu_dai = &jz4740_i2s_dai,
.codec_dai = &jz_codec_dai,
.init = n516_codec_init,
};
static struct snd_soc_card n516_card = {
.name = "N516",
.dai_link = &n516_dai,
.num_links = 1,
.platform = &jz4740_soc_platform,
};
static struct snd_soc_device n516_snd_devdata = {
.card = &n516_card,
.codec_dev = &soc_codec_dev_jzcodec,
};
static struct platform_device *n516_snd_device;
static struct snd_soc_jack n516_hp_jack;
static struct snd_soc_jack_pin n516_hp_pin = {
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
};
static struct snd_soc_jack_gpio n516_hp_gpio = {
.gpio = GPIO_HPHONE_DETECT,
.name = "Headphone detect",
.report = SND_JACK_HEADPHONE,
.debounce_time = 100,
};
static int __init n516_add_headphone_jack(void)
{
int ret;
ret = snd_soc_jack_new(&n516_card, "Headphone jack",
SND_JACK_HEADPHONE, &n516_hp_jack);
if (ret)
return ret;
ret = snd_soc_jack_add_pins(&n516_hp_jack, 1, &n516_hp_pin);
if (ret)
return ret;
ret = snd_soc_jack_add_gpios(&n516_hp_jack, 1, &n516_hp_gpio);
return ret;
}
static int __init n516_init(void)
{
int ret;
n516_snd_device = platform_device_alloc("soc-audio", -1);
if (!n516_snd_device)
return -ENOMEM;
ret = gpio_request(GPIO_SPEAKER_ENABLE, "Speaker enable");
if (ret) {
pr_err("n516 snd: Failed to request SPEAKER_ENABLE GPIO(%d): %d\n",
GPIO_SPEAKER_ENABLE, ret);
goto err_device_put;
}
gpio_direction_output(GPIO_SPEAKER_ENABLE, 0);
INIT_WORK(&n516_headphone_work, n516_headphone_event_work);
platform_set_drvdata(n516_snd_device, &n516_snd_devdata);
n516_snd_devdata.dev = &n516_snd_device->dev;
ret = platform_device_add(n516_snd_device);
if (ret) {
pr_err("n516 snd: Failed to add snd soc device: %d\n", ret);
goto err_unset_pdata;
}
ret = n516_add_headphone_jack();
/* We can live without it, so just print a warning */
if (ret)
pr_warning("n516 snd: Failed to initalise headphone jack: %d\n", ret);
return 0;
err_unset_pdata:
platform_set_drvdata(n516_snd_device, NULL);
/*err_gpio_free_speaker:*/
gpio_free(GPIO_SPEAKER_ENABLE);
err_device_put:
platform_device_put(n516_snd_device);
return ret;
}
module_init(n516_init);
static void __exit n516_exit(void)
{
snd_soc_jack_free_gpios(&n516_hp_jack, 1, &n516_hp_gpio);
gpio_free(GPIO_SPEAKER_ENABLE);
platform_device_unregister(n516_snd_device);
}
module_exit(n516_exit);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC N516 Audio support");
MODULE_LICENSE("GPL v2");

View File

@ -1,169 +0,0 @@
/*
* 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 N526_AMP_EN_GPIO JZ_GPIO_PORTD(4)
static int n526_spk_event(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *ctrl, int event)
{
gpio_set_value(N526_AMP_EN_GPIO, !SND_SOC_DAPM_EVENT_OFF(event));
return 0;
}
static const struct snd_soc_dapm_widget n526_widgets[] = {
SND_SOC_DAPM_SPK("Speaker", n526_spk_event),
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Mic", NULL),
};
static const struct snd_soc_dapm_route n526_routes[] = {
{"Mic", NULL, "MIC"},
{"Speaker", NULL, "LOUT"},
{"Speaker", NULL, "ROUT"},
{"Headphone", NULL, "LOUT"},
{"Headphone", NULL, "ROUT"},
};
static const struct snd_kcontrol_new n526_controls[] = {
SOC_DAPM_PIN_SWITCH("Speaker"),
};
#define N526_DAIFMT (SND_SOC_DAIFMT_I2S | \
SND_SOC_DAIFMT_NB_NF | \
SND_SOC_DAIFMT_CBM_CFM)
static int n526_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, N526_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, N526_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, n526_widgets, ARRAY_SIZE(n526_widgets));
snd_soc_add_controls(codec, n526_controls,
ARRAY_SIZE(n526_controls));
snd_soc_dapm_add_routes(codec, n526_routes, ARRAY_SIZE(n526_routes));
snd_soc_dapm_sync(codec);
return 0;
}
static struct snd_soc_dai_link n526_dai = {
.name = "jz-codec",
.stream_name = "JZCODEC",
.cpu_dai = &jz4740_i2s_dai,
.codec_dai = &jz_codec_dai,
.init = n526_codec_init,
};
static struct snd_soc_card n526 = {
.name = "N526",
.dai_link = &n526_dai,
.num_links = 1,
.platform = &jz4740_soc_platform,
};
static struct snd_soc_device n526_snd_devdata = {
.card = &n526,
.codec_dev = &soc_codec_dev_jzcodec,
};
static struct platform_device *n526_snd_device;
static int __init n526_init(void)
{
int ret;
n526_snd_device = platform_device_alloc("soc-audio", -1);
if (!n526_snd_device)
return -ENOMEM;
ret = gpio_request(N526_AMP_EN_GPIO, "AMP");
if (ret) {
pr_err("n526 snd: Failed to request AMP GPIO(%d): %d\n",
N526_AMP_EN_GPIO, ret);
goto err_device_put;
}
gpio_direction_output(JZ_GPIO_PORTD(4), 0);
platform_set_drvdata(n526_snd_device, &n526_snd_devdata);
n526_snd_devdata.dev = &n526_snd_device->dev;
ret = platform_device_add(n526_snd_device);
if (ret) {
pr_err("n526 snd: Failed to add snd soc device: %d\n", ret);
goto err_unset_pdata;
}
return 0;
err_unset_pdata:
platform_set_drvdata(n526_snd_device, NULL);
gpio_free(N526_AMP_EN_GPIO);
err_device_put:
platform_device_put(n526_snd_device);
return ret;
}
module_init(n526_init);
static void __exit n526_exit(void)
{
gpio_free(N526_AMP_EN_GPIO);
platform_device_unregister(n526_snd_device);
}
module_exit(n526_exit);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC N526 audio support");
MODULE_LICENSE("GPL v2");

View File

@ -1,182 +0,0 @@
/*
* 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");

View File

@ -1,17 +0,0 @@
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_JZ4740=y
CONFIG_FB_METRONOME=m
CONFIG_FB_SYS_FOPS=m
CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
CONFIG_I2C=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_GPIO=y
CONFIG_JZ4740_N516=y
CONFIG_LEDS_GPIO=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_N516_LPC=y
CONFIG_NEW_LEDS=y
CONFIG_SENSORS_LM75=y
CONFIG_SOC_JZ4740=y

View File

@ -1 +0,0 @@
CONFIG_JZ4740_N516=y

View File

@ -1,567 +0,0 @@
From 42789dfb077bb7b640ee19d0e3f7808dc5318adf Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:35 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/001-core.patch
---
arch/mips/Kconfig | 29 ++++
arch/mips/Makefile | 18 +++
arch/mips/boot/Makefile | 23 +++-
arch/mips/include/asm/bootinfo.h | 6 +
arch/mips/include/asm/cpu.h | 13 ++-
arch/mips/include/asm/mach-generic/irq.h | 2 +-
arch/mips/include/asm/r4kcache.h | 231 ++++++++++++++++++++++++++++++
arch/mips/include/asm/suspend.h | 3 +
arch/mips/kernel/cpu-probe.c | 21 +++
arch/mips/mm/c-r4k.c | 30 ++++
arch/mips/mm/cache.c | 2 +
arch/mips/mm/tlbex.c | 5 +
12 files changed, 379 insertions(+), 4 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -174,6 +174,9 @@ config MACH_JAZZ
Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
Olivetti M700-10 workstations.
+config MACH_JZ
+ bool "Ingenic JZ4720/JZ4740 based machines"
+
config LASAT
bool "LASAT Networks platforms"
select CEVT_R4K
@@ -677,6 +680,7 @@ source "arch/mips/alchemy/Kconfig"
source "arch/mips/basler/excite/Kconfig"
source "arch/mips/bcm63xx/Kconfig"
source "arch/mips/jazz/Kconfig"
+source "arch/mips/jz4740/Kconfig"
source "arch/mips/lasat/Kconfig"
source "arch/mips/pmc-sierra/Kconfig"
source "arch/mips/sgi-ip27/Kconfig"
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -186,6 +186,14 @@ cflags-$(CONFIG_AR7) += -I$(srctree)/ar
load-$(CONFIG_AR7) += 0xffffffff94100000
#
+# Commond Ingenic JZ4740 series
+#
+
+core-$(CONFIG_SOC_JZ4740) += arch/mips/jz4740/
+cflags-$(CONFIG_SOC_JZ4740) += -I$(srctree)/arch/mips/include/asm/mach-jz4740
+load-$(CONFIG_SOC_JZ4740) += 0xffffffff80010000
+
+#
# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
#
core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/
@@ -704,6 +712,12 @@ makeboot =$(Q)$(MAKE) $(build)=arch/mips
all: $(all-y)
+uImage: $(vmlinux-32)
+ +@$(call makeboot,$@)
+
+zImage: $(vmlinux-32)
+ +@$(call makeboot,$@)
+
vmlinux.bin: $(vmlinux-32)
+@$(call makeboot,$@)
@@ -733,6 +747,7 @@ install:
archclean:
@$(MAKE) $(clean)=arch/mips/boot
+ @$(MAKE) $(clean)=arch/mips/boot/compressed
@$(MAKE) $(clean)=arch/mips/lasat
define archhelp
@@ -740,6 +755,9 @@ define archhelp
echo ' vmlinux.ecoff - ECOFF boot image'
echo ' vmlinux.bin - Raw binary boot image'
echo ' vmlinux.srec - SREC boot image'
+ echo ' uImage - u-boot format image (arch/$(ARCH)/boot/uImage)'
+ echo ' zImage - Compressed binary image (arch/$(ARCH)/boot/compressed/zImage)'
+ echo ' vmlinux.bin - Uncompressed binary image (arch/$(ARCH)/boot/vmlinux.bin)'
echo
echo ' These will be default as apropriate for a configured platform.'
endef
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -7,6 +7,9 @@
# Copyright (C) 2004 Maciej W. Rozycki
#
+# This one must match the LOADADDR in arch/mips/Makefile!
+LOADADDR=0x80010000
+
#
# Some DECstations need all possible sections of an ECOFF executable
#
@@ -25,7 +28,7 @@ strip-flags = $(addprefix --remove-secti
VMLINUX = vmlinux
-all: vmlinux.ecoff vmlinux.srec addinitrd
+all: vmlinux.ecoff vmlinux.srec addinitrd uImage zImage
vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
$(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
@@ -42,8 +45,24 @@ vmlinux.srec: $(VMLINUX)
$(obj)/addinitrd: $(obj)/addinitrd.c
$(HOSTCC) -o $@ $^
+uImage: $(VMLINUX) vmlinux.bin
+ rm -f $(obj)/vmlinux.bin.gz
+ gzip -9 $(obj)/vmlinux.bin
+ mkimage -A mips -O linux -T kernel -C gzip \
+ -a $(LOADADDR) -e $(shell sh ./$(obj)/tools/entry $(NM) $(VMLINUX) ) \
+ -n 'Linux-$(KERNELRELEASE)' \
+ -d $(obj)/vmlinux.bin.gz $(obj)/uImage
+ @echo ' Kernel: arch/mips/boot/$@ is ready'
+
+zImage:
+ $(Q)$(MAKE) $(build)=$(obj)/compressed loadaddr=$(LOADADDR) $@
+ @echo ' Kernel: arch/mips/boot/compressed/$@ is ready'
+
clean-files += addinitrd \
elf2ecoff \
vmlinux.bin \
vmlinux.ecoff \
- vmlinux.srec
+ vmlinux.srec \
+ vmlinux.bin.gz \
+ uImage \
+ zImage
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -69,6 +69,12 @@
#define MACH_DEXXON_GDIUM2F10 5
#define MACH_LOONGSON_END 6
+/*
+ * Valid machtype for group INGENIC
+ */
+#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */
+#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
+
#define CL_SIZE COMMAND_LINE_SIZE
extern char *system_type;
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -34,7 +34,7 @@
#define PRID_COMP_LSI 0x080000
#define PRID_COMP_LEXRA 0x0b0000
#define PRID_COMP_CAVIUM 0x0d0000
-
+#define PRID_COMP_INGENIC 0xd00000
/*
* Assigned values for the product ID register. In order to detect a
@@ -133,6 +133,12 @@
#define PRID_IMP_CAVIUM_CN52XX 0x0700
/*
+ * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
+ */
+
+#define PRID_IMP_JZRISC 0x0200
+
+/*
* Definitions for 7:0 on legacy processors
*/
@@ -224,6 +230,11 @@ enum cpu_type_enum {
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_CAVIUM_OCTEON,
+ /*
+ * Ingenic class processors
+ */
+ CPU_JZRISC, CPU_XBURST,
+
CPU_LAST
};
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -17,6 +17,58 @@
#include <asm/cpu-features.h>
#include <asm/mipsmtregs.h>
+#ifdef CONFIG_JZRISC
+
+#define K0_TO_K1() \
+do { \
+ unsigned long __k0_addr; \
+ \
+ __asm__ __volatile__( \
+ "la %0, 1f\n\t" \
+ "or %0, %0, %1\n\t" \
+ "jr %0\n\t" \
+ "nop\n\t" \
+ "1: nop\n" \
+ : "=&r"(__k0_addr) \
+ : "r" (0x20000000) ); \
+} while(0)
+
+#define K1_TO_K0() \
+do { \
+ unsigned long __k0_addr; \
+ __asm__ __volatile__( \
+ "nop;nop;nop;nop;nop;nop;nop\n\t" \
+ "la %0, 1f\n\t" \
+ "jr %0\n\t" \
+ "nop\n\t" \
+ "1: nop\n" \
+ : "=&r" (__k0_addr)); \
+} while (0)
+
+#define INVALIDATE_BTB() \
+do { \
+ unsigned long tmp; \
+ __asm__ __volatile__( \
+ ".set mips32\n\t" \
+ "mfc0 %0, $16, 7\n\t" \
+ "nop\n\t" \
+ "ori %0, 2\n\t" \
+ "mtc0 %0, $16, 7\n\t" \
+ "nop\n\t" \
+ : "=&r" (tmp)); \
+} while (0)
+
+#define SYNC_WB() __asm__ __volatile__ ("sync")
+
+#else /* CONFIG_JZRISC */
+
+#define K0_TO_K1() do { } while (0)
+#define K1_TO_K0() do { } while (0)
+#define INVALIDATE_BTB() do { } while (0)
+#define SYNC_WB() do { } while (0)
+
+#endif /* CONFIG_JZRISC */
+
/*
* This macro return a properly sign-extended address suitable as base address
* for indexed cache operations. Two issues here:
@@ -144,6 +196,7 @@ static inline void flush_icache_line_ind
{
__iflush_prologue
cache_op(Index_Invalidate_I, addr);
+ INVALIDATE_BTB();
__iflush_epilogue
}
@@ -151,6 +204,7 @@ static inline void flush_dcache_line_ind
{
__dflush_prologue
cache_op(Index_Writeback_Inv_D, addr);
+ SYNC_WB();
__dflush_epilogue
}
@@ -163,6 +217,7 @@ static inline void flush_icache_line(uns
{
__iflush_prologue
cache_op(Hit_Invalidate_I, addr);
+ INVALIDATE_BTB();
__iflush_epilogue
}
@@ -170,6 +225,7 @@ static inline void flush_dcache_line(uns
{
__dflush_prologue
cache_op(Hit_Writeback_Inv_D, addr);
+ SYNC_WB();
__dflush_epilogue
}
@@ -177,6 +233,7 @@ static inline void invalidate_dcache_lin
{
__dflush_prologue
cache_op(Hit_Invalidate_D, addr);
+ SYNC_WB();
__dflush_epilogue
}
@@ -209,6 +266,7 @@ static inline void flush_scache_line(uns
static inline void protected_flush_icache_line(unsigned long addr)
{
protected_cache_op(Hit_Invalidate_I, addr);
+ INVALIDATE_BTB();
}
/*
@@ -220,6 +278,7 @@ static inline void protected_flush_icach
static inline void protected_writeback_dcache_line(unsigned long addr)
{
protected_cache_op(Hit_Writeback_Inv_D, addr);
+ SYNC_WB();
}
static inline void protected_writeback_scache_line(unsigned long addr)
@@ -396,8 +455,10 @@ static inline void blast_##pfx##cache##l
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
+#ifndef CONFIG_JZRISC
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
+#endif
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
@@ -405,12 +466,122 @@ __BUILD_BLAST_CACHE(s, scache, Index_Wri
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16)
+#ifndef CONFIG_JZRISC
__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32)
+#endif
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16)
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32)
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64)
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
+#ifdef CONFIG_JZRISC
+
+static inline void blast_dcache32(void)
+{
+ unsigned long start = INDEX_BASE;
+ unsigned long end = start + current_cpu_data.dcache.waysize;
+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
+ unsigned long ws_end = current_cpu_data.dcache.ways <<
+ current_cpu_data.dcache.waybit;
+ unsigned long ws, addr;
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start; addr < end; addr += 0x400)
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
+
+ SYNC_WB();
+}
+
+static inline void blast_dcache32_page(unsigned long page)
+{
+ unsigned long start = page;
+ unsigned long end = page + PAGE_SIZE;
+
+ do {
+ cache32_unroll32(start,Hit_Writeback_Inv_D);
+ start += 0x400;
+ } while (start < end);
+
+ SYNC_WB();
+}
+
+static inline void blast_dcache32_page_indexed(unsigned long page)
+{
+ unsigned long indexmask = current_cpu_data.dcache.waysize - 1;
+ unsigned long start = INDEX_BASE + (page & indexmask);
+ unsigned long end = start + PAGE_SIZE;
+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
+ unsigned long ws_end = current_cpu_data.dcache.ways <<
+ current_cpu_data.dcache.waybit;
+ unsigned long ws, addr;
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start; addr < end; addr += 0x400)
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
+
+ SYNC_WB();
+}
+
+static inline void blast_icache32(void)
+{
+ unsigned long start = INDEX_BASE;
+ unsigned long end = start + current_cpu_data.icache.waysize;
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+ unsigned long ws_end = current_cpu_data.icache.ways <<
+ current_cpu_data.icache.waybit;
+ unsigned long ws, addr;
+
+ K0_TO_K1();
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start; addr < end; addr += 0x400)
+ cache32_unroll32(addr|ws,Index_Invalidate_I);
+
+ INVALIDATE_BTB();
+
+ K1_TO_K0();
+}
+
+static inline void blast_icache32_page(unsigned long page)
+{
+ unsigned long start = page;
+ unsigned long end = page + PAGE_SIZE;
+
+ K0_TO_K1();
+
+ do {
+ cache32_unroll32(start,Hit_Invalidate_I);
+ start += 0x400;
+ } while (start < end);
+
+ INVALIDATE_BTB();
+
+ K1_TO_K0();
+}
+
+static inline void blast_icache32_page_indexed(unsigned long page)
+{
+ unsigned long indexmask = current_cpu_data.icache.waysize - 1;
+ unsigned long start = INDEX_BASE + (page & indexmask);
+ unsigned long end = start + PAGE_SIZE;
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+ unsigned long ws_end = current_cpu_data.icache.ways <<
+ current_cpu_data.icache.waybit;
+ unsigned long ws, addr;
+
+ K0_TO_K1();
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start; addr < end; addr += 0x400)
+ cache32_unroll32(addr|ws,Index_Invalidate_I);
+
+ INVALIDATE_BTB();
+
+ K1_TO_K0();
+}
+
+#endif /* CONFIG_JZRISC */
+
/* build blast_xxx_range, protected_blast_xxx_range */
#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \
static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
@@ -432,13 +603,73 @@ static inline void prot##blast_##pfx##ca
__##pfx##flush_epilogue \
}
+#ifndef CONFIG_JZRISC
__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_)
+#endif
__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_)
+#ifndef CONFIG_JZRISC
__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_)
__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, )
+#endif
__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )
/* blast_inv_dcache_range */
__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
+#ifdef CONFIG_JZRISC
+
+static inline void protected_blast_dcache_range(unsigned long start,
+ unsigned long end)
+{
+ unsigned long lsize = cpu_dcache_line_size();
+ unsigned long addr = start & ~(lsize - 1);
+ unsigned long aend = (end - 1) & ~(lsize - 1);
+
+ while (1) {
+ protected_cache_op(Hit_Writeback_Inv_D, addr);
+ if (addr == aend)
+ break;
+ addr += lsize;
+ }
+ SYNC_WB();
+}
+
+static inline void protected_blast_icache_range(unsigned long start,
+ unsigned long end)
+{
+ unsigned long lsize = cpu_icache_line_size();
+ unsigned long addr = start & ~(lsize - 1);
+ unsigned long aend = (end - 1) & ~(lsize - 1);
+
+ K0_TO_K1();
+
+ while (1) {
+ protected_cache_op(Hit_Invalidate_I, addr);
+ if (addr == aend)
+ break;
+ addr += lsize;
+ }
+ INVALIDATE_BTB();
+
+ K1_TO_K0();
+}
+
+static inline void blast_dcache_range(unsigned long start,
+ unsigned long end)
+{
+ unsigned long lsize = cpu_dcache_line_size();
+ unsigned long addr = start & ~(lsize - 1);
+ unsigned long aend = (end - 1) & ~(lsize - 1);
+
+ while (1) {
+ cache_op(Hit_Writeback_Inv_D, addr);
+ if (addr == aend)
+ break;
+ addr += lsize;
+ }
+ SYNC_WB();
+}
+
+#endif /* CONFIG_JZRISC */
+
#endif /* _ASM_R4KCACHE_H */
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -160,6 +160,7 @@ void __init check_wait(void)
case CPU_BCM6348:
case CPU_BCM6358:
case CPU_CAVIUM_OCTEON:
+ case CPU_JZRISC:
cpu_wait = r4k_wait;
break;
@@ -902,6 +903,21 @@ static inline void cpu_probe_cavium(stru
}
}
+static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ c->options &= ~MIPS_CPU_COUNTER; /* JZRISC does not implement the CP0 counter. */
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_JZRISC:
+ c->cputype = CPU_JZRISC;
+ __cpu_name[cpu] = "Ingenic JZRISC";
+ break;
+ default:
+ panic("Unknown Ingenic Processor ID!");
+ break;
+ }
+}
+
const char *__cpu_name[NR_CPUS];
__cpuinit void cpu_probe(void)
@@ -939,6 +955,9 @@ __cpuinit void cpu_probe(void)
case PRID_COMP_CAVIUM:
cpu_probe_cavium(c, cpu);
break;
+ case PRID_COMP_INGENIC:
+ cpu_probe_ingenic(c, cpu);
+ break;
}
BUG_ON(!__cpu_name[cpu]);
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -389,6 +389,11 @@ static void __cpuinit build_tlb_write_en
tlbw(p);
break;
+ case CPU_JZRISC:
+ tlbw(p);
+ uasm_i_nop(p);
+ break;
+
default:
panic("No TLB refill handler yet (CPU type: %d)",
current_cpu_data.cputype);

View File

@ -1,33 +0,0 @@
From 436aee004fda70b654698aff99427abdebf6bdb9 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:37 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/050-nand.patch
---
drivers/mtd/nand/Kconfig | 6 ++++++
drivers/mtd/nand/Makefile | 1 +
drivers/mtd/nand/nand_base.c | 19 +++++++------------
3 files changed, 14 insertions(+), 12 deletions(-)
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -482,4 +482,10 @@ config MTD_NAND_W90P910
This enables the driver for the NAND Flash on evaluation board based
on w90p910.
+config MTD_NAND_JZ4740
+ tristate "Support NAND Flash device on Jz4740 board"
+ depends on SOC_JZ4740
+ help
+ Support NAND Flash device on Jz4740 board
+
endif # MTD_NAND
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -42,5 +42,6 @@ obj-$(CONFIG_MTD_NAND_SOCRATES) += socr
obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
obj-$(CONFIG_MTD_NAND_W90P910) += w90p910_nand.o
obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o
+obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
nand-objs := nand_base.o nand_bbt.o

View File

@ -1,38 +0,0 @@
From 5777849c788174f7de3bd9e14105af52f916ef5b Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:38 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/051-fb.patch
---
drivers/video/Kconfig | 9 +++++++++
drivers/video/Makefile | 1 +
2 files changed, 10 insertions(+), 0 deletions(-)
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2160,6 +2160,15 @@ config FB_BROADSHEET
and could also have been called by other names when coupled with
a bridge adapter.
+config FB_JZ4740
+ tristate "JZ47420/JZ4740 LCD framebuffer support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ help
+ Framebuffer support for the JZ4720 and JZ4740 SoC.
+
source "drivers/video/omap/Kconfig"
source "drivers/video/backlight/Kconfig"
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -128,6 +128,7 @@ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
obj-$(CONFIG_FB_MSM) += msm/
+obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o

View File

@ -1,40 +0,0 @@
From 2ec88eb0d3d2c877eff811901215390708dd03b9 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:39 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/052-rtc.patch
---
drivers/rtc/Kconfig | 11 +++++++++++
drivers/rtc/Makefile | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -469,6 +469,17 @@ config RTC_DRV_EFI
This driver can also be built as a module. If so, the module
will be called rtc-efi.
+config RTC_DRV_JZ4740
+ tristate "Ingenic JZ4720/JZ4740 SoC"
+ depends on RTC_CLASS
+ depends on SOC_JZ4740
+ help
+ If you say yes here you get support for the
+ Ingenic JZ4720/JZ4740 SoC RTC controller.
+
+ This driver can also be buillt as a module. If so, the module
+ will be called rtc-jz4740.
+
config RTC_DRV_STK17TA8
tristate "Simtek STK17TA8"
depends on RTC_CLASS
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
+obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o

View File

@ -1,39 +0,0 @@
From 7b55ff7b9fd37ac8857746603ec580d277208f01 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:40 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/053-adc.patch
---
drivers/misc/Kconfig | 11 +++++++++++
drivers/misc/Makefile | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -246,6 +246,17 @@ config EP93XX_PWM
To compile this driver as a module, choose M here: the module will
be called ep93xx_pwm.
+config JZ4740_ADC
+ tristate "Ingenic JZ4720/JZ4740 SoC ADC driver"
+ depends on SOC_JZ4740
+ help
+ If you say yes here you get support for the Ingenic JZ4720/JZ4740 SoC ADC
+ core. It is required for the JZ4720/JZ4740 battery and touchscreen driver
+ and is used to synchronize access to the adc core between those two.
+
+ This driver can also be build as a module. If so, the module will be
+ called jz4740-adc.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -21,5 +21,6 @@ obj-$(CONFIG_HP_ILO) += hpilo.o
obj-$(CONFIG_ISL29003) += isl29003.o
obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
obj-$(CONFIG_C2PORT) += c2port/
+obj-$(CONFIG_JZ4740_ADC) += jz4740-adc.o
obj-y += eeprom/
obj-y += cb710/

View File

@ -1,35 +0,0 @@
From 045c37b75e13fe84f582627f7e2f68b7fa194909 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:41 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/100-battery.patch
---
drivers/power/Kconfig | 11 +++++++++++
drivers/power/Makefile | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -110,4 +110,15 @@ config CHARGER_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
+config BATTERY_JZ4740
+ tristate "Ingenic JZ4720/JZ4740 battery"
+ depends on SOC_JZ4740
+ depends on JZ4740_ADC
+ help
+ Say Y to enable support for the battery on Ingenic JZ4720/JZ4740 based
+ boards.
+
+ This driver can be build as a module. If so, the module will be
+ called jz4740-battery.
+
endif # POWER_SUPPLY
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
+obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o

View File

@ -1,38 +0,0 @@
From 146308ee673df13fafe40aaddc799e9ad58e6ecb Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:42 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/101-mmc.patch
---
drivers/mmc/host/Kconfig | 9 +++++++++
drivers/mmc/host/Makefile | 1 +
2 files changed, 10 insertions(+), 0 deletions(-)
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -66,6 +66,15 @@ config MMC_RICOH_MMC
useless. It is safe to select this driver even if you don't
have a Ricoh based card reader.
+config MMC_JZ
+ tristate "JZ SD/Multimedia Card Interface support"
+ depends on SOC_JZ4720 || SOC_JZ4740
+ help
+ This selects the Ingenic JZ4720/JZ4740 SD/Multimedia card Interface.
+ If you have abIngenic platform with a Multimedia Card slot,
+ say Y or M here.
+
+ If unsure, say N.
To compile this driver as a module, choose M here:
the module will be called ricoh_mmc.
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -6,6 +6,7 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
+obj-$(CONFIG_MMC_JZ) += jz_mmc.o
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
obj-$(CONFIG_MMC_IMX) += imxmmc.o

View File

@ -1,36 +0,0 @@
From 060fafbe37894116fd264d15c6949f00e9f86343 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:43 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/103-lcm.patch
---
drivers/video/backlight/Kconfig | 7 +++++++
drivers/video/backlight/Makefile | 1 +
2 files changed, 8 insertions(+), 0 deletions(-)
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -100,6 +100,13 @@ config LCD_HP700
If you have an HP Jornada 700 series handheld (710/720/728)
say Y to enable LCD control driver.
+config LCD_GPM940B0
+ tristate "Giantplus GPM940B0 LCD and backlight driver"
+ depends on LCD_CLASS_DEVICE && SPI
+ default n
+ help
+ LCD and backlight driver for the Giantplus GPM940B0 LCD module.
+
#
# Backlight
#
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_LCD_PLATFORM) += platfor
obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
+obj-$(CONFIG_LCD_GPM940B0) += gpm940b0.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o

View File

@ -1,173 +0,0 @@
From 5b3f9de4171368d9a99fa4c8b8b1bcc8505fb3c6 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:44 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/103-serial.patch
---
drivers/serial/8250.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 103 insertions(+), 1 deletions(-)
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -199,7 +199,7 @@ static const struct serial8250_config ua
[PORT_16550A] = {
.name = "16550A",
.fifo_size = 16,
- .tx_loadsz = 16,
+ .tx_loadsz = 8,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO,
},
@@ -406,6 +406,10 @@ static unsigned int mem_serial_in(struct
static void mem_serial_out(struct uart_port *p, int offset, int value)
{
offset = map_8250_out_reg(p, offset) << p->regshift;
+#if defined(CONFIG_JZSOC)
+ if (offset == (UART_FCR << p->regshift))
+ value |= 0x10; /* set FCR.UUE */
+#endif
writeb(value, p->membase + offset);
}
@@ -2214,6 +2218,83 @@ static void serial8250_shutdown(struct u
serial_unlink_irq_chain(up);
}
+#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
+static unsigned short quot1[3] = {0}; /* quot[0]:baud_div, quot[1]:umr, quot[2]:uacr */
+static unsigned short * serial8250_get_divisor(struct uart_port *port, unsigned int baud)
+{
+ int err, sum, i, j;
+ int a[12], b[12];
+ unsigned short div, umr, uacr;
+ unsigned short umr_best, div_best, uacr_best;
+ long long t0, t1, t2, t3;
+
+ sum = 0;
+ umr_best = div_best = uacr_best = 0;
+ div = 1;
+
+ if ((port->uartclk % (16 * baud)) == 0) {
+ quot1[0] = port->uartclk / (16 * baud);
+ quot1[1] = 16;
+ quot1[2] = 0;
+ return quot1;
+ }
+
+ while (1) {
+ umr = port->uartclk / (baud * div);
+ if (umr > 32) {
+ div++;
+ continue;
+ }
+ if (umr < 4) {
+ break;
+ }
+ for (i = 0; i < 12; i++) {
+ a[i] = umr;
+ b[i] = 0;
+ sum = 0;
+ for (j = 0; j <= i; j++) {
+ sum += a[j];
+ }
+
+ /* the precision could be 1/2^(36) due to the value of t0 */
+ t0 = 0x1000000000LL;
+ t1 = (i + 1) * t0;
+ t2 = (sum * div) * t0;
+ t3 = div * t0;
+ do_div(t1, baud);
+ do_div(t2, port->uartclk);
+ do_div(t3, (2 * port->uartclk));
+ err = t1 - t2 - t3;
+
+ if (err > 0) {
+ a[i] += 1;
+ b[i] = 1;
+ }
+ }
+
+ uacr = 0;
+ for (i = 0; i < 12; i++) {
+ if (b[i] == 1) {
+ uacr |= 1 << i;
+ }
+ }
+
+ /* the best value of umr should be near 16, and the value of uacr should better be smaller */
+ if (abs(umr - 16) < abs(umr_best - 16) || (abs(umr - 16) == abs(umr_best - 16) && uacr_best > uacr)) {
+ div_best = div;
+ umr_best = umr;
+ uacr_best = uacr;
+ }
+ div++;
+ }
+
+ quot1[0] = div_best;
+ quot1[1] = umr_best;
+ quot1[2] = uacr_best;
+
+ return quot1;
+}
+#else
static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
{
unsigned int quot;
@@ -2233,6 +2314,7 @@ static unsigned int serial8250_get_divis
return quot;
}
+#endif
static void
serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -2242,6 +2324,9 @@ serial8250_set_termios(struct uart_port
unsigned char cval, fcr = 0;
unsigned long flags;
unsigned int baud, quot;
+#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
+ unsigned short *quot1;
+#endif
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -2276,7 +2361,12 @@ serial8250_set_termios(struct uart_port
baud = uart_get_baud_rate(port, termios, old,
port->uartclk / 16 / 0xffff,
port->uartclk / 16);
+#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
+ quot1 = serial8250_get_divisor(port, baud);
+ quot = quot1[0]; /* not usefull, just let gcc happy */
+#else
quot = serial8250_get_divisor(port, baud);
+#endif
/*
* Oxford Semi 952 rev B workaround
@@ -2354,6 +2444,10 @@ serial8250_set_termios(struct uart_port
if (up->capabilities & UART_CAP_UUE)
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
+#ifdef CONFIG_JZSOC
+ up->ier |= UART_IER_RTOIE; /* Set this flag, or very slow */
+#endif
+
serial_out(up, UART_IER, up->ier);
if (up->capabilities & UART_CAP_EFR) {
@@ -2388,7 +2482,15 @@ serial8250_set_termios(struct uart_port
serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
}
+#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
+#define UART_UMR 9
+#define UART_UACR 10
+ serial_dl_write(up, quot1[0]);
+ serial_outp(up, UART_UMR, quot1[1]);
+ serial_outp(up, UART_UACR, quot1[2]);
+#else
serial_dl_write(up, quot);
+#endif
/*
* LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR

View File

@ -1,75 +0,0 @@
From ba0e3820ee1def7c358391df293551b726fb7014 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:45 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/104-usb.patch
---
drivers/usb/Kconfig | 1 +
drivers/usb/gadget/Kconfig | 14 ++++++++++++++
drivers/usb/gadget/Makefile | 1 +
drivers/usb/gadget/gadget_chips.h | 9 +++++++++
4 files changed, 25 insertions(+), 0 deletions(-)
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -121,11 +121,25 @@ choice
#
# Integrated controllers
#
+config USB_GADGET_JZ4740
+ boolean "JZ4740 UDC"
+ depends on SOC_JZ4740
+ select USB_GADGET_SELECTED
+ select USB_GADGET_DUALSPEED
+ help
+ Select this to support the Ingenic JZ4740 processor
+ high speed USB device controller.
+
+config USB_JZ4740
+ tristate
+ depends on USB_GADGET_JZ4740
+ default USB_GADGET
config USB_GADGET_AT91
boolean "Atmel AT91 USB Device Port"
depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45
select USB_GADGET_SELECTED
+
help
Many Atmel AT91 processors (such as the AT91RM2000) have a
full speed USB Device Port with support for five configurable
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o
obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o
obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o
+obj-$(CONFIG_USB_JZ4740) += jz4740_udc.o
#
# USB gadget drivers
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -15,6 +15,12 @@
#ifndef __GADGET_CHIPS_H
#define __GADGET_CHIPS_H
+#ifdef CONFIG_USB_GADGET_JZ4740
+#define gadget_is_jz4740(g) !strcmp("ingenic_hsusb", (g)->name)
+#else
+#define gadget_is_jz4740(g) 0
+#endif
+
#ifdef CONFIG_USB_GADGET_NET2280
#define gadget_is_net2280(g) !strcmp("net2280", (g)->name)
#else
@@ -247,6 +253,9 @@ static inline int usb_gadget_controller_
return 0x24;
else if (gadget_is_r8a66597(gadget))
return 0x25;
+ else if (gadget_is_jz4740(gadget))
+ return 0x26;
+
return -ENOENT;
}

View File

@ -1,123 +0,0 @@
From bc6998405cdff2c189ad6e3e18be695087c30909 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:46 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/105-sound.patch
---
include/sound/pcm.h | 26 +++++++++++++-------------
sound/core/pcm_native.c | 7 ++++---
sound/soc/Kconfig | 1 +
sound/soc/Makefile | 1 +
sound/soc/codecs/Kconfig | 7 +++++++
sound/soc/codecs/Makefile | 2 ++
6 files changed, 28 insertions(+), 16 deletions(-)
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -113,23 +113,23 @@ struct snd_pcm_ops {
#define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */
#define SNDRV_PCM_RATE_8000 (1<<1) /* 8000Hz */
#define SNDRV_PCM_RATE_11025 (1<<2) /* 11025Hz */
-#define SNDRV_PCM_RATE_16000 (1<<3) /* 16000Hz */
-#define SNDRV_PCM_RATE_22050 (1<<4) /* 22050Hz */
-#define SNDRV_PCM_RATE_32000 (1<<5) /* 32000Hz */
-#define SNDRV_PCM_RATE_44100 (1<<6) /* 44100Hz */
-#define SNDRV_PCM_RATE_48000 (1<<7) /* 48000Hz */
-#define SNDRV_PCM_RATE_64000 (1<<8) /* 64000Hz */
-#define SNDRV_PCM_RATE_88200 (1<<9) /* 88200Hz */
-#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */
-#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */
-#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */
+#define SNDRV_PCM_RATE_12000 (1<<3) /* 12000Hz */
+#define SNDRV_PCM_RATE_16000 (1<<4) /* 16000Hz */
+#define SNDRV_PCM_RATE_22050 (1<<5) /* 22050Hz */
+#define SNDRV_PCM_RATE_24000 (1<<6) /* 24000Hz */
+#define SNDRV_PCM_RATE_32000 (1<<7) /* 32000Hz */
+#define SNDRV_PCM_RATE_44100 (1<<8) /* 44100Hz */
+#define SNDRV_PCM_RATE_48000 (1<<9) /* 48000Hz */
+#define SNDRV_PCM_RATE_64000 (1<<10) /* 64000Hz */
+#define SNDRV_PCM_RATE_88200 (1<<11) /* 88200Hz */
+#define SNDRV_PCM_RATE_96000 (1<<12) /* 96000Hz */
+#define SNDRV_PCM_RATE_176400 (1<<13) /* 176400Hz */
+#define SNDRV_PCM_RATE_192000 (1<<14) /* 192000Hz */
#define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */
#define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */
-#define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
- SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
- SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100)
+#define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|SNDRV_PCM_RATE_12000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_24000|SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100)
#define SNDRV_PCM_RATE_8000_48000 (SNDRV_PCM_RATE_8000_44100|SNDRV_PCM_RATE_48000)
#define SNDRV_PCM_RATE_8000_96000 (SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_64000|\
SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1721,12 +1721,13 @@ static int snd_pcm_hw_rule_sample_bits(s
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}
-#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
+#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 14
#error "Change this table"
#endif
-static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
- 48000, 64000, 88200, 96000, 176400, 192000 };
+static unsigned int rates[] = { 5512, 8000, 11025, 12000, 16000, 22050, 24000,
+ 32000, 44100, 48000, 64000, 88200, 96000,
+ 176400, 192000 };
const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {
.count = ARRAY_SIZE(rates),
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -36,6 +36,7 @@ source "sound/soc/s3c24xx/Kconfig"
source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
source "sound/soc/txx9/Kconfig"
+source "sound/soc/jz4740/Kconfig"
# Supported codecs
source "sound/soc/codecs/Kconfig"
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_SND_SOC) += s3c24xx/
obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += txx9/
+obj-$(CONFIG_SND_SOC) += jz4740/
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -217,6 +217,13 @@ config SND_SOC_WM9712
config SND_SOC_WM9713
tristate
+config SND_SOC_JZCODEC
+ tristate "JZ4720/JZ4740 SoC internal codec"
+ depends on SND_SOC && SOC_JZ4740
+ help
+ Say Y if you want to use internal codec on Ingenic JZ4720/JZ4740 based
+ boards.
+
# Amp
config SND_SOC_MAX9877
tristate
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -44,6 +44,7 @@ snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
+snd-soc-jzcodec-objs := jzcodec.o
# Amp
snd-soc-max9877-objs := max9877.o
@@ -94,6 +95,7 @@ obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
+obj-$(CONFIG_SND_SOC_JZCODEC) += snd-soc-jzcodec.o
# Amp
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o

View File

@ -1,21 +0,0 @@
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -30,3 +30,4 @@ obj-$(CONFIG_BATTERY_DA9030) += da9030_b
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
+obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -121,4 +121,11 @@ config BATTERY_JZ4740
This driver can be build as a module. If so, the module will be
called jz4740-battery.
+config CHARGER_GPIO
+ tristate "GPIO charger"
+ depends on GPIOLIB
+ help
+ Say Y to include support for chargers indicating their status through
+ a GPIO pin.
+
endif # POWER_SUPPLY

View File

@ -1,20 +0,0 @@
From f6bc2e17eaa2628f614a675781e9dc101084df9a Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:47 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/220-add-2gb-nand-support.patch
---
include/mtd/mtd-abi.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -135,7 +135,7 @@ struct nand_oobfree {
*/
struct nand_ecclayout {
__u32 eccbytes;
- __u32 eccpos[64];
+ __u32 eccpos[72];
__u32 oobavail;
struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
};

View File

@ -1,29 +0,0 @@
From d3699249d687dc0b4d8d4e0e5ac3f9405d31b1ac Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:47 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/300-jffs2-summery-vmalloc.patch
---
fs/jffs2/summary.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -32,7 +32,7 @@ int jffs2_sum_init(struct jffs2_sb_info
return -ENOMEM;
}
- c->summary->sum_buf = kmalloc(sum_size, GFP_KERNEL);
+ c->summary->sum_buf = vmalloc(sum_size);
if (!c->summary->sum_buf) {
JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n");
@@ -51,7 +51,7 @@ void jffs2_sum_exit(struct jffs2_sb_info
jffs2_sum_disable_collecting(c->summary);
- kfree(c->summary->sum_buf);
+ vfree(c->summary->sum_buf);
c->summary->sum_buf = NULL;
kfree(c->summary);

View File

@ -1,46 +0,0 @@
From df07ed6a52d9f6027ff1753c00b3128fa18dde31 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:48 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/400-spi-gpio-3wire.patch
---
drivers/spi/spi_gpio.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -254,9 +254,11 @@ spi_gpio_request(struct spi_gpio_platfor
if (value)
goto done;
- value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
- if (value)
- goto free_mosi;
+ if (SPI_MISO_GPIO != SPI_MOSI_GPIO) {
+ value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
+ if (value)
+ goto free_mosi;
+ }
value = spi_gpio_alloc(SPI_SCK_GPIO, label, false);
if (value)
@@ -319,7 +321,8 @@ static int __devinit spi_gpio_probe(stru
if (status < 0) {
spi_master_put(spi_gpio->bitbang.master);
gpio_free:
- gpio_free(SPI_MISO_GPIO);
+ if (SPI_MISO_GPIO != SPI_MOSI_GPIO)
+ gpio_free(SPI_MISO_GPIO);
gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
spi_master_put(master);
@@ -343,7 +346,8 @@ static int __devexit spi_gpio_remove(str
platform_set_drvdata(pdev, NULL);
- gpio_free(SPI_MISO_GPIO);
+ if (SPI_MISO_GPIO != SPI_MOSI_GPIO)
+ gpio_free(SPI_MISO_GPIO);
gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);

View File

@ -1,37 +0,0 @@
From 2d00c901d3a438c6f750f8b13b329845775ec3b5 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:50 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/420-fb-notifier-pre-post.patch
---
drivers/video/fbmem.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1008,12 +1008,12 @@ fb_set_var(struct fb_info *info, struct
int
fb_blank(struct fb_info *info, int blank)
{
- int ret = -EINVAL;
+ int ret = 0;
if (blank > FB_BLANK_POWERDOWN)
blank = FB_BLANK_POWERDOWN;
- if (info->fbops->fb_blank)
+ if (info->fbops->fb_blank && blank == FB_BLANK_UNBLANK)
ret = info->fbops->fb_blank(blank, info);
if (!ret) {
@@ -1024,6 +1024,10 @@ fb_blank(struct fb_info *info, int blank
fb_notifier_call_chain(FB_EVENT_BLANK, &event);
}
+ if (info->fbops->fb_blank && blank != FB_BLANK_UNBLANK)
+ ret = info->fbops->fb_blank(blank, info);
+
+
return ret;
}

View File

@ -1,181 +0,0 @@
From d76e6b85f28891eecded962793fb8a02cdf26f39 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:29:51 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/500-modifier-keys.patch
---
drivers/char/defkeymap.map | 74 +++++++++++++++++++++++++++++++-------------
1 files changed, 52 insertions(+), 22 deletions(-)
--- a/drivers/char/defkeymap.map
+++ b/drivers/char/defkeymap.map
@@ -1,5 +1,5 @@
# Default kernel keymap. This uses 7 modifier combinations.
-keymaps 0-2,4-5,8,12
+keymaps 0-2,4-5,8,12,64
# Change the above line into
# keymaps 0-2,4-6,8,12
# in case you want the entries
@@ -45,24 +45,38 @@ keycode 12 = minus underscor
control keycode 12 = Control_underscore
shift control keycode 12 = Control_underscore
alt keycode 12 = Meta_minus
-keycode 13 = equal plus
+keycode 13 = equal plus
alt keycode 13 = Meta_equal
+ altgr keycode 13 = asciitilde
+ ctrll keycode 13 = three
keycode 14 = Delete Delete
- control keycode 14 = BackSpace
+ altgr keycode 14 = BackSpace
alt keycode 14 = Meta_Delete
keycode 15 = Tab Tab
alt keycode 15 = Meta_Tab
keycode 16 = q
+ altgr keycode 16 = exclam
keycode 17 = w
+ altgr keycode 17 = at
keycode 18 = e
- altgr keycode 18 = Hex_E
+ altgr keycode 18 = numbersign
keycode 19 = r
+ altgr keycode 19 = dollar
keycode 20 = t
+ altgr keycode 20 = percent
keycode 21 = y
+ altgr keycode 21 = asciicircum
keycode 22 = u
+ altgr keycode 22 = ampersand
+ ctrll keycode 22 = seven
keycode 23 = i
+ altgr keycode 23 = asterisk
+ ctrll keycode 23 = eight
keycode 24 = o
+ altgr keycode 24 = parenleft
+ ctrll keycode 24 = nine
keycode 25 = p
+ altgr keycode 25 = parenright
keycode 26 = bracketleft braceleft
control keycode 26 = Escape
alt keycode 26 = Meta_bracketleft
@@ -71,19 +85,28 @@ keycode 27 = bracketright bracerigh
alt keycode 27 = Meta_bracketright
keycode 28 = Return
alt keycode 28 = Meta_Control_m
-keycode 29 = Control
+keycode 29 = CtrlL
keycode 30 = a
- altgr keycode 30 = Hex_A
+ altgr keycode 30 = U+00B0
keycode 31 = s
+ altgr keycode 31 = U+00A8
keycode 32 = d
- altgr keycode 32 = Hex_D
+ altgr keycode 32 = U+20AC
keycode 33 = f
- altgr keycode 33 = Hex_F
+ altgr keycode 33 = minus
keycode 34 = g
+ altgr keycode 34 = underscore
keycode 35 = h
+ altgr keycode 35 = braceleft
keycode 36 = j
+ altgr keycode 36 = bracketleft
+ ctrll keycode 36 = four
keycode 37 = k
+ altgr keycode 37 = bracketright
+ ctrll keycode 37 = five
keycode 38 = l
+ altgr keycode 38 = braceright
+ ctrll keycode 38 = six
keycode 39 = semicolon colon
alt keycode 39 = Meta_semicolon
keycode 40 = apostrophe quotedbl
@@ -97,58 +120,65 @@ keycode 43 = backslash bar
control keycode 43 = Control_backslash
alt keycode 43 = Meta_backslash
keycode 44 = z
+ altgr keycode 44 = nine
keycode 45 = x
+ altgr keycode 45 = zero
keycode 46 = c
altgr keycode 46 = Hex_C
keycode 47 = v
keycode 48 = b
altgr keycode 48 = Hex_B
keycode 49 = n
+ altgr keycode 49 = less
+ ctrll keycode 49 = one
keycode 50 = m
-keycode 51 = comma less
- alt keycode 51 = Meta_comma
-keycode 52 = period greater
+ altgr keycode 50 = greater
+ ctrll keycode 50 = two
+keycode 51 = comma semicolon
+ altgr keycode 51 = apostrophe
+keycode 52 = period colon
control keycode 52 = Compose
- alt keycode 52 = Meta_period
+ altgr keycode 52 = quotedbl
keycode 53 = slash question
control keycode 53 = Delete
alt keycode 53 = Meta_slash
-keycode 54 = Shift
+ ctrll keycode 53 = zero
+keycode 54 = AltGr
keycode 55 = KP_Multiply
keycode 56 = Alt
keycode 57 = space space
control keycode 57 = nul
alt keycode 57 = Meta_space
keycode 58 = Caps_Lock
-keycode 59 = F1 F11 Console_13
+keycode 59 = F1 F11 one
control keycode 59 = F1
alt keycode 59 = Console_1
control alt keycode 59 = Console_1
-keycode 60 = F2 F12 Console_14
+keycode 60 = F2 F12 two
control keycode 60 = F2
alt keycode 60 = Console_2
control alt keycode 60 = Console_2
-keycode 61 = F3 F13 Console_15
+keycode 61 = F3 F13 three
control keycode 61 = F3
alt keycode 61 = Console_3
control alt keycode 61 = Console_3
-keycode 62 = F4 F14 Console_16
+keycode 62 = F4 F14 four
control keycode 62 = F4
alt keycode 62 = Console_4
control alt keycode 62 = Console_4
-keycode 63 = F5 F15 Console_17
+keycode 63 = F5 F15 five
control keycode 63 = F5
alt keycode 63 = Console_5
control alt keycode 63 = Console_5
-keycode 64 = F6 F16 Console_18
+keycode 64 = F6 F16 six
control keycode 64 = F6
alt keycode 64 = Console_6
control alt keycode 64 = Console_6
-keycode 65 = F7 F17 Console_19
+keycode 65 = F7 F17 seven
control keycode 65 = F7
alt keycode 65 = Console_7
control alt keycode 65 = Console_7
-keycode 66 = F8 F18 Console_20
+keycode 66 = F8 F18 eight
control keycode 66 = F8
alt keycode 66 = Console_8
control alt keycode 66 = Console_8
@@ -220,7 +250,7 @@ keycode 93 =
keycode 94 =
keycode 95 =
keycode 96 = KP_Enter
-keycode 97 = Control
+keycode 97 = Control
keycode 98 = KP_Divide
keycode 99 = Control_backslash
control keycode 99 = Control_backslash

View File

@ -1,45 +0,0 @@
From 806ead1e454a8a5876b777b22ca67187c4749f32 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 11 Jan 2010 04:30:42 +0100
Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/800-n526-lpc.patch
---
drivers/i2c/chips/Kconfig | 9 +++++++++
drivers/i2c/chips/Makefile | 1 +
2 files changed, 10 insertions(+), 0 deletions(-)
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -26,4 +26,21 @@ config SENSORS_TSL2550
This driver can also be built as a module. If so, the module
will be called tsl2550.
+config N516_LPC
+ tristate "N516 keys & power controller"
+ depends on I2C
+ depends on INPUT
+ depends on POWER_SUPPLY
+ help
+ N516 keyboard & power controller driver
+
+config N526_LPC
+ tristate "N526 LPC934 coprocessor"
+ depends on JZ4740_N526
+ help
+ If you say yes here you get support for the N526s NXP LPC934 coprocessor.
+ It is used as a keyboard controllor and for power management.
+
+ If you have a N526 you probably want to say Y here.
+
endmenu
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -12,6 +12,8 @@
obj-$(CONFIG_DS1682) += ds1682.o
obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
+obj-$(CONFIG_N516_LPC) += n516-lpc.o
+obj-$(CONFIG_N526_LPC) += n526-lpc.o
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
EXTRA_CFLAGS += -DDEBUG

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BATTERY_JZ4740=y
CONFIG_CHARGER_GPIO=y
CONFIG_FB_JZ4740=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_JZ4740_ADC=y
CONFIG_JZ4740_QI_LB60=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_MATRIX=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_GPM940B0=y
CONFIG_LOGO=y
CONFIG_LOGO_OPENWRT_CLUT224=y
CONFIG_SPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MASTER=y