1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-12-28 17:03:20 +02:00

xburst: Remove 2.6.31 files, patches and config

This commit is contained in:
Lars-Peter Clausen 2010-01-11 23:00:10 +01:00
parent 33d1ef1f3a
commit 6be23bb131
83 changed files with 0 additions and 27747 deletions

View File

@ -1,406 +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=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BASE_SMALL=0
CONFIG_BATTERY_JZ4740=y
# CONFIG_BCM47XX 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_CONSOLE_TRANSLATIONS=y
# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_CPU_CAVIUM_OCTEON is not set
CONFIG_CPU_FREQ=y
# CONFIG_CPU_FREQ_DEBUG is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_JZ=y
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_LOONGSON2 is not set
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# 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=y
CONFIG_FB_JZ4740=y
# CONFIG_FB_JZSOC is not set
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FIRMWARE_EDID is not set
CONFIG_FONTS=y
# 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_FORCE_MAX_ZONEORDER=12
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FREEZER=y
# CONFIG_FSNOTIFY is not set
# CONFIG_FW_LOADER is not set
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=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 is not set
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_I2C is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
CONFIG_INPUT=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_GPIO_BUTTONS is not set
CONFIG_INPUT_KEYBOARD=y
# CONFIG_INPUT_YEALINK is not set
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_MULTICAST is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_RARP is not set
CONFIG_IRQ_CPU=y
CONFIG_JBD=y
CONFIG_JZ4740_ADC=y
CONFIG_JZ4740_QI_LB60=y
# CONFIG_JZ4740_N526 is not set
CONFIG_JZRISC=y
CONFIG_JZSOC=y
CONFIG_KALLSYMS=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_KEYBOARD_LKKBD is not set
CONFIG_KEYBOARD_MATRIX=y
# 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=y
CONFIG_LCD_GPM940B0=y
# CONFIG_LCD_ILI9320 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_PTYS=y
CONFIG_LEGACY_PTY_COUNT=2
# CONFIG_LEMOTE_FULONG is not set
CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCK_KERNEL=y
CONFIG_LOGO=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=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MAC80211_DEFAULT_PS_VALUE=0
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
CONFIG_MACH_JZ=y
# 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=y
# CONFIG_MIPS_COBALT is not set
# CONFIG_MIPS_FPU_EMU 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_MMC=y
CONFIG_MMC_BLOCK=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_JZ=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_MODVERSIONS=y
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_JZ4740=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_UBI=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_NETDEV_1000 is not set
# CONFIG_NETFILTER is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
# CONFIG_NET_ETHERNET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_NEW_LEDS is not set
CONFIG_NLS=y
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_1=y
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=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_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_PM=y
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PREEMPT=y
# CONFIG_PREEMPT_NONE is not set
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=y
CONFIG_SECCOMP=y
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
CONFIG_SERIO_SERPORT=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=y
# CONFIG_SND_EMU10K1_SEQ is not set
CONFIG_SND_JACK=y
CONFIG_SND_JZ4740_SOC=y
CONFIG_SND_JZ4740_SOC_I2S=y
CONFIG_SND_JZ4740_SOC_QI_LB60=y
CONFIG_SND_MIXER_OSS=y
# CONFIG_SND_OPL3_LIB_SEQ is not set
# CONFIG_SND_OPL4_LIB_SEQ is not set
CONFIG_SND_PCM=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_RAWMIDI_SEQ is not set
# CONFIG_SND_SBAWE_SEQ is not set
CONFIG_SND_SOC=y
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_SOC_JZCODEC=y
CONFIG_SND_TIMER=y
CONFIG_SOC_JZ4740=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
CONFIG_SPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MASTER=y
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SQUASHFS is not set
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=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_UBIFS_FS=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_ZLIB=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_CDC_COMPOSITE is not set
CONFIG_USB_ETH=y
CONFIG_USB_ETH_RNDIS=y
# CONFIG_USB_FILE_STORAGE is not set
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGETFS 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_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_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_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=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=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,56 +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>
/*
* Frequencies of on-board oscillators
*/
#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */
#define JZ_EXTAL_RTC 32768 /* RTC extal freq: 32.768 KHz */
/*
* GPIO
*/
#define GPIO_DC_DETE_N JZ_GPIO_PORTC(26)
#define GPIO_CHARG_STAT_N JZ_GPIO_PORTC(27)
#define GPIO_LED_EN JZ_GPIO_PORTC(28)
#define GPIO_LCD_CS JZ_GPIO_PORTC(21)
#define GPIO_DISP_OFF_N JZ_GPIO_PORTD(21)
#define GPIO_PWM JZ_GPIO_PORTD(27)
#define GPIO_WAKEUP_N JZ_GPIO_PORTD(29)
#define GPIO_AMP_EN JZ_GPIO_PORTD(4)
#define GPIO_SD_CD_N JZ_GPIO_PORTD(0)
#define GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(2)
#define GPIO_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,306 +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>
#ifndef JZ_EXTAL
//#define JZ_EXTAL 3686400 /* 3.6864 MHz */
#define JZ_EXTAL 12000000 /* 3.6864 MHz */
#endif
#ifndef JZ_EXTAL2
#define JZ_EXTAL2 32768 /* 32.768 KHz */
#endif
/***************************************************************************
* CPM
***************************************************************************/
#define __cpm_get_pllm() \
((REG_CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT)
#define __cpm_get_plln() \
((REG_CPM_CPPCR & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT)
#define __cpm_get_pllod() \
((REG_CPM_CPPCR & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT)
#define __cpm_get_cdiv() \
((REG_CPM_CPCCR & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT)
#define __cpm_get_hdiv() \
((REG_CPM_CPCCR & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT)
#define __cpm_get_pdiv() \
((REG_CPM_CPCCR & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT)
#define __cpm_get_mdiv() \
((REG_CPM_CPCCR & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT)
#define __cpm_get_ldiv() \
((REG_CPM_CPCCR & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT)
#define __cpm_get_udiv() \
((REG_CPM_CPCCR & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT)
#define __cpm_get_i2sdiv() \
((REG_CPM_I2SCDR & CPM_I2SCDR_I2SDIV_MASK) >> CPM_I2SCDR_I2SDIV_BIT)
#define __cpm_get_pixdiv() \
((REG_CPM_LPCDR & CPM_LPCDR_PIXDIV_MASK) >> CPM_LPCDR_PIXDIV_BIT)
#define __cpm_get_mscdiv() \
((REG_CPM_MSCCDR & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT)
#define __cpm_get_uhcdiv() \
((REG_CPM_UHCCDR & CPM_UHCCDR_UHCDIV_MASK) >> CPM_UHCCDR_UHCDIV_BIT)
#define __cpm_get_ssidiv() \
((REG_CPM_SSICCDR & CPM_SSICDR_SSICDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT)
#define __cpm_set_cdiv(v) \
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | ((v) << (CPM_CPCCR_CDIV_BIT)))
#define __cpm_set_hdiv(v) \
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | ((v) << (CPM_CPCCR_HDIV_BIT)))
#define __cpm_set_pdiv(v) \
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | ((v) << (CPM_CPCCR_PDIV_BIT)))
#define __cpm_set_mdiv(v) \
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | ((v) << (CPM_CPCCR_MDIV_BIT)))
#define __cpm_set_ldiv(v) \
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT)))
#define __cpm_set_udiv(v) \
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | ((v) << (CPM_CPCCR_UDIV_BIT)))
#define __cpm_set_i2sdiv(v) \
(REG_CPM_I2SCDR = (REG_CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | ((v) << (CPM_I2SCDR_I2SDIV_BIT)))
#define __cpm_set_pixdiv(v) \
(REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT)))
#define __cpm_set_mscdiv(v) \
(REG_CPM_MSCCDR = (REG_CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | ((v) << (CPM_MSCCDR_MSCDIV_BIT)))
#define __cpm_set_uhcdiv(v) \
(REG_CPM_UHCCDR = (REG_CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | ((v) << (CPM_UHCCDR_UHCDIV_BIT)))
#define __cpm_ssiclk_select_exclk() \
(REG_CPM_SSICDR &= ~CPM_SSICDR_SCS)
#define __cpm_ssiclk_select_pllout() \
(REG_CPM_SSICDR |= CPM_SSICDR_SCS)
#define __cpm_set_ssidiv(v) \
(REG_CPM_SSICDR = (REG_CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT)))
#define __cpm_select_i2sclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_I2CS)
#define __cpm_select_i2sclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_I2CS)
#define __cpm_enable_cko() (REG_CPM_CPCCR |= CPM_CPCCR_CLKOEN)
#define __cpm_select_usbclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_UCS)
#define __cpm_select_usbclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_UCS)
#define __cpm_enable_pll_change() (REG_CPM_CPCCR |= CPM_CPCCR_CE)
#define __cpm_pllout_direct() (REG_CPM_CPCCR |= CPM_CPCCR_PCS)
#define __cpm_pllout_div2() (REG_CPM_CPCCR &= ~CPM_CPCCR_PCS)
#define __cpm_pll_is_on() (REG_CPM_CPPCR & CPM_CPPCR_PLLS)
#define __cpm_pll_bypass() (REG_CPM_CPPCR |= CPM_CPPCR_PLLBP)
#define __cpm_pll_enable() (REG_CPM_CPPCR |= CPM_CPPCR_PLLEN)
#define __cpm_get_cclk_doze_duty() \
((REG_CPM_LCR & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)
#define __cpm_set_cclk_doze_duty(v) \
(REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_DOZE_DUTY_MASK) | ((v) << (CPM_LCR_DOZE_DUTY_BIT)))
#define __cpm_doze_mode() (REG_CPM_LCR |= CPM_LCR_DOZE_ON)
#define __cpm_idle_mode() \
(REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_IDLE)
#define __cpm_sleep_mode() \
(REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP)
#define __cpm_stop_all() (REG_CPM_CLKGR = 0x7fff)
#define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1)
#define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC)
#define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU)
#define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC)
#define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC)
#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
#define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM)
#define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC)
#define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC)
#define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1)
#define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2)
#define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI)
#define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C)
#define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC)
#define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU)
#define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0)
#define __cpm_start_all() (REG_CPM_CLKGR = 0x0)
#define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1)
#define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC)
#define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU)
#define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC)
#define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC)
#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
#define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM)
#define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC)
#define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC)
#define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1)
#define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2)
#define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI)
#define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C)
#define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC)
#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
#define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0)
#define __cpm_get_o1st() \
((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT)
#define __cpm_set_o1st(v) \
(REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT)))
#define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND)
#define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE)
/*
* JZ4740 clocks structure
*/
typedef struct {
unsigned int cclk; /* CPU clock */
unsigned int hclk; /* System bus clock */
unsigned int pclk; /* Peripheral bus clock */
unsigned int mclk; /* Flash/SRAM/SDRAM clock */
unsigned int lcdclk; /* LCDC module clock */
unsigned int pixclk; /* LCD pixel clock */
unsigned int i2sclk; /* AIC module clock */
unsigned int usbclk; /* USB module clock */
unsigned int mscclk; /* MSC module clock */
unsigned int extalclk; /* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
unsigned int rtcclk; /* RTC clock for CPM,INTC,RTC,TCU,WDT */
} jz_clocks_t;
extern jz_clocks_t jz_clocks;
/* PLL output frequency */
static __inline__ unsigned int __cpm_get_pllout(void)
{
unsigned long m, n, no, pllout;
unsigned long cppcr = REG_CPM_CPPCR;
unsigned long od[4] = {1, 2, 2, 4};
if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
m = __cpm_get_pllm() + 2;
n = __cpm_get_plln() + 2;
no = od[__cpm_get_pllod()];
pllout = ((JZ_EXTAL) / (n * no)) * m;
} else
pllout = JZ_EXTAL;
return pllout;
}
/* PLL output frequency for MSC/I2S/LCD/USB */
static __inline__ unsigned int __cpm_get_pllout2(void)
{
if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
return __cpm_get_pllout();
else
return __cpm_get_pllout()/2;
}
/* CPU core clock */
static __inline__ unsigned int __cpm_get_cclk(void)
{
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_cdiv()];
}
/* AHB system bus clock */
static __inline__ unsigned int __cpm_get_hclk(void)
{
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_hdiv()];
}
/* Memory bus clock */
static __inline__ unsigned int __cpm_get_mclk(void)
{
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_mdiv()];
}
/* APB peripheral bus clock */
static __inline__ unsigned int __cpm_get_pclk(void)
{
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_pdiv()];
}
/* LCDC module clock */
static __inline__ unsigned int __cpm_get_lcdclk(void)
{
return __cpm_get_pllout2() / (__cpm_get_ldiv() + 1);
}
/* LCD pixel clock */
static __inline__ unsigned int __cpm_get_pixclk(void)
{
return __cpm_get_pllout2() / (__cpm_get_pixdiv() + 1);
}
/* I2S clock */
static __inline__ unsigned int __cpm_get_i2sclk(void)
{
if (REG_CPM_CPCCR & CPM_CPCCR_I2CS) {
return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1);
}
else {
return JZ_EXTAL;
}
}
/* USB clock */
static __inline__ unsigned int __cpm_get_usbclk(void)
{
if (REG_CPM_CPCCR & CPM_CPCCR_UCS) {
return __cpm_get_pllout2() / (__cpm_get_udiv() + 1);
}
else {
return JZ_EXTAL;
}
}
/* MSC clock */
static __inline__ unsigned int __cpm_get_mscclk(void)
{
return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1);
}
/* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
static __inline__ unsigned int __cpm_get_extalclk(void)
{
return JZ_EXTAL;
}
/* RTC clock for CPM,INTC,RTC,TCU,WDT */
static __inline__ unsigned int __cpm_get_rtcclk(void)
{
return JZ_EXTAL2;
}
/*
* Output 24MHz for SD and 16MHz for MMC.
*/
static inline void __cpm_select_msc_clk(int sd)
{
unsigned int pllout2 = __cpm_get_pllout2();
unsigned int div = 0;
if (sd) {
div = pllout2 / 24000000;
}
else {
div = pllout2 / 16000000;
}
REG_CPM_MSCCDR = div - 1;
}
int jz_init_clocks(unsigned long ext_rate);
#endif /* __ASM_JZ4740_CLOCK_H__ */

View File

@ -1,89 +0,0 @@
/*
* linux/include/asm-mips/mach-jz4740/dma.h
*
* JZ4740 DMA definition.
*
* Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc.
*
* Author: <lhhuang@ingenic.cn>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_JZ4740_DMA_H__
#define __ASM_JZ4740_DMA_H__
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,40 +0,0 @@
#ifndef __JZ4740_IRQ_H__
#define __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,38 +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
/* Add other platform definition here ... */
/*------------------------------------------------------------------
* Follows are related to platform definitions
*/
#include <asm/mach-jz4740/serial.h>
#endif /* __ASM_JZ4740_H__ */

View File

@ -1,19 +0,0 @@
#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,675 +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
/*************************************************************************
* CPM (Clock reset and Power control Management)
*************************************************************************/
#define CPM_CPCCR (CPM_BASE+0x00)
#define CPM_CPPCR (CPM_BASE+0x10)
#define CPM_I2SCDR (CPM_BASE+0x60)
#define CPM_LPCDR (CPM_BASE+0x64)
#define CPM_MSCCDR (CPM_BASE+0x68)
#define CPM_UHCCDR (CPM_BASE+0x6C)
#define CPM_SSICDR (CPM_BASE+0x74)
#define CPM_LCR (CPM_BASE+0x04)
#define CPM_CLKGR (CPM_BASE+0x20)
#define CPM_SCR (CPM_BASE+0x24)
#define CPM_HCR (CPM_BASE+0x30)
#define CPM_HWFCR (CPM_BASE+0x34)
#define CPM_HRCR (CPM_BASE+0x38)
#define CPM_HWCR (CPM_BASE+0x3c)
#define CPM_HWSR (CPM_BASE+0x40)
#define CPM_HSPR (CPM_BASE+0x44)
#define CPM_RSR (CPM_BASE+0x08)
#define REG_CPM_CPCCR REG32(CPM_CPCCR)
#define REG_CPM_CPPCR REG32(CPM_CPPCR)
#define REG_CPM_I2SCDR REG32(CPM_I2SCDR)
#define REG_CPM_LPCDR REG32(CPM_LPCDR)
#define REG_CPM_MSCCDR REG32(CPM_MSCCDR)
#define REG_CPM_UHCCDR REG32(CPM_UHCCDR)
#define REG_CPM_SSICDR REG32(CPM_SSICDR)
#define REG_CPM_LCR REG32(CPM_LCR)
#define REG_CPM_CLKGR REG32(CPM_CLKGR)
#define REG_CPM_SCR REG32(CPM_SCR)
#define REG_CPM_HCR REG32(CPM_HCR)
#define REG_CPM_HWFCR REG32(CPM_HWFCR)
#define REG_CPM_HRCR REG32(CPM_HRCR)
#define REG_CPM_HWCR REG32(CPM_HWCR)
#define REG_CPM_HWSR REG32(CPM_HWSR)
#define REG_CPM_HSPR REG32(CPM_HSPR)
#define REG_CPM_RSR REG32(CPM_RSR)
/* Clock Control Register */
#define CPM_CPCCR_I2CS (1 << 31)
#define CPM_CPCCR_CLKOEN (1 << 30)
#define CPM_CPCCR_UCS (1 << 29)
#define CPM_CPCCR_UDIV_BIT 23
#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT)
#define CPM_CPCCR_CE (1 << 22)
#define CPM_CPCCR_PCS (1 << 21)
#define CPM_CPCCR_LDIV_BIT 16
#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT)
#define CPM_CPCCR_MDIV_BIT 12
#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT)
#define CPM_CPCCR_PDIV_BIT 8
#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT)
#define CPM_CPCCR_HDIV_BIT 4
#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT)
#define CPM_CPCCR_CDIV_BIT 0
#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT)
/* I2S Clock Divider Register */
#define CPM_I2SCDR_I2SDIV_BIT 0
#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT)
/* LCD Pixel Clock Divider Register */
#define CPM_LPCDR_PIXDIV_BIT 0
#define CPM_LPCDR_PIXDIV_MASK (0x7ff << CPM_LPCDR_PIXDIV_BIT)
/* MSC Clock Divider Register */
#define CPM_MSCCDR_MSCDIV_BIT 0
#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT)
/* UHC Clock Divider Register */
#define CPM_UHCCDR_UHCDIV_BIT 0
#define CPM_UHCCDR_UHCDIV_MASK (0xf << CPM_UHCCDR_UHCDIV_BIT)
/* SSI Clock Divider Register */
#define CPM_SSICDR_SCS (1<<31) /* SSI clock source selection, 0:EXCLK, 1: PLL */
#define CPM_SSICDR_SSIDIV_BIT 0
#define CPM_SSICDR_SSIDIV_MASK (0xf << CPM_SSICDR_SSIDIV_BIT)
/* PLL Control Register */
#define CPM_CPPCR_PLLM_BIT 23
#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT)
#define CPM_CPPCR_PLLN_BIT 18
#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT)
#define CPM_CPPCR_PLLOD_BIT 16
#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT)
#define CPM_CPPCR_PLLS (1 << 10)
#define CPM_CPPCR_PLLBP (1 << 9)
#define CPM_CPPCR_PLLEN (1 << 8)
#define CPM_CPPCR_PLLST_BIT 0
#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT)
/* Low Power Control Register */
#define CPM_LCR_DOZE_DUTY_BIT 3
#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT)
#define CPM_LCR_DOZE_ON (1 << 2)
#define CPM_LCR_LPM_BIT 0
#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT)
#define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT)
#define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT)
/* Clock Gate Register */
#define CPM_CLKGR_UART1 (1 << 15)
#define CPM_CLKGR_UHC (1 << 14)
#define CPM_CLKGR_IPU (1 << 13)
#define CPM_CLKGR_DMAC (1 << 12)
#define CPM_CLKGR_UDC (1 << 11)
#define CPM_CLKGR_LCD (1 << 10)
#define CPM_CLKGR_CIM (1 << 9)
#define CPM_CLKGR_SADC (1 << 8)
#define CPM_CLKGR_MSC (1 << 7)
#define CPM_CLKGR_AIC1 (1 << 6)
#define CPM_CLKGR_AIC2 (1 << 5)
#define CPM_CLKGR_SSI (1 << 4)
#define CPM_CLKGR_I2C (1 << 3)
#define CPM_CLKGR_RTC (1 << 2)
#define CPM_CLKGR_TCU (1 << 1)
#define CPM_CLKGR_UART0 (1 << 0)
/* Sleep Control Register */
#define CPM_SCR_O1ST_BIT 8
#define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT)
#define CPM_SCR_USBPHY_ENABLE (1 << 6)
#define CPM_SCR_OSC_ENABLE (1 << 4)
/* Hibernate Control Register */
#define CPM_HCR_PD (1 << 0)
/* Wakeup Filter Counter Register in Hibernate Mode */
#define CPM_HWFCR_TIME_BIT 0
#define CPM_HWFCR_TIME_MASK (0x3ff << CPM_HWFCR_TIME_BIT)
/* Reset Counter Register in Hibernate Mode */
#define CPM_HRCR_TIME_BIT 0
#define CPM_HRCR_TIME_MASK (0x7f << CPM_HRCR_TIME_BIT)
/* Wakeup Control Register in Hibernate Mode */
#define CPM_HWCR_WLE_LOW (0 << 2)
#define CPM_HWCR_WLE_HIGH (1 << 2)
#define CPM_HWCR_PIN_WAKEUP (1 << 1)
#define CPM_HWCR_RTC_WAKEUP (1 << 0)
/* Wakeup Status Register in Hibernate Mode */
#define CPM_HWSR_WSR_PIN (1 << 1)
#define CPM_HWSR_WSR_RTC (1 << 0)
/* Reset Status Register */
#define CPM_RSR_HR (1 << 2)
#define CPM_RSR_WR (1 << 1)
#define CPM_RSR_PR (1 << 0)
/*************************************************************************
* 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,35 +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_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,28 +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_PROC_FS) += proc.o
# board specific support
obj-$(CONFIG_JZ4740_PAVO) += board-pavo.o
obj-$(CONFIG_JZ4740_LEO) += board-leo.o
obj-$(CONFIG_JZ4740_LYRA) += board-lyra.o
obj-$(CONFIG_JZ4725_DIPPER) += board-dipper.o
obj-$(CONFIG_JZ4720_VIRGO) += board-virgo.o
obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
obj-$(CONFIG_JZ4740_N526) += board-n526.o
# PM support
obj-$(CONFIG_PM) +=pm.o
# CPU Frequency scaling support
obj-$(CONFIG_CPU_FREQ_JZ) +=cpufreq.o

View File

@ -1,158 +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/power/jz4740-battery.h>
#include <linux/mmc/jz4740_mmc.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 = 8 * 0x100000,
.size = 504 * 0x100000,
},
{ .name = "NAND DATA partition",
.offset = 512 * 0x100000,
.size = 512 * 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,
};
/* Battery */
/*static struct jz_batt_info n526_battery_pdata = {
.dc_dect_gpio = GPIO_DC_DETE_N,
.usb_dect_gpio = GPIO_USB_DETE,
.charg_stat_gpio = GPIO_CHARG_STAT_N,
.min_voltag = 3600000,
.max_voltag = 4200000,
.batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
};*/
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 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,
};
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));
}
static int __init n526_init_platform_devices(void)
{
jz4740_nand_device.dev.platform_data = &n526_nand_pdata;
/* jz4740_battery_device.dev.platform_data = &n526_battery_pdata;*/
jz4740_mmc_device.dev.platform_data = &n526_mmc_pdata;
return platform_add_devices(jz_platform_devices,
ARRAY_SIZE(jz_platform_devices));
}
extern int jz_gpiolib_init(void);
extern int jz_init_clocks(unsigned long extal);
static int __init n526_board_setup(void)
{
if (jz_gpiolib_init())
panic("Failed to initalize jz gpio\n");
jz_init_clocks(12000000);
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,385 +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/mmc/jz4740_mmc.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,
.pixclock = 700000,
.left_margin = 140,
.right_margin = 273,
.upper_margin = 20,
.lower_margin = 2,
.hsync_len = 1,
.vsync_len = 1,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
.width = 60,
.height = 45,
.num_modes = ARRAY_SIZE(qi_lb60_video_modes),
.modes = qi_lb60_video_modes,
.bpp = 24,
.lcd_type = JZ_LCD_TYPE_8BIT_SERIAL,
};
struct spi_gpio_platform_data spigpio_platform_data = {
.sck = JZ_GPIO_PORTC(23),
.mosi = JZ_GPIO_PORTC(22),
.miso = JZ_GPIO_PORTC(22),
.num_chipselect = 1,
};
static struct platform_device spigpio_device = {
.name = "spi_gpio",
.id = 1,
.dev = {
.platform_data = &spigpio_platform_data,
},
};
static struct spi_board_info qi_lb60_spi_board_info[] = {
{
.modalias = "gpm940b0",
.controller_data = (void*)JZ_GPIO_PORTC(21),
.chip_select = 0,
.bus_num = 1,
.max_speed_hz = 30 * 1000,
},
};
/* Battery */
static struct jz_batt_info qi_lb60_battery_pdata = {
.dc_dect_gpio = GPIO_DC_DETE_N,
.usb_dect_gpio = GPIO_USB_DETE,
.charg_stat_gpio = GPIO_CHARG_STAT_N,
.min_voltag = 3600000,
.max_voltag = 4200000,
.batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
};
/* GPIO Key: power */
static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = {
[0] = {
.code = KEY_POWER,
.gpio = GPIO_WAKEUP_N,
.active_low = 1,
.desc = "Power",
.wakeup = 1,
},
};
static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = {
.nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons),
.buttons = qi_lb60_gpio_keys_buttons,
};
static struct platform_device qi_lb60_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &qi_lb60_gpio_keys_data,
}
};
static struct 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,
};
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));
}
extern int jz_gpiolib_init(void);
extern int jz_init_clocks(unsigned long extal);
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");
jz_init_clocks(12000000);
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,781 +0,0 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/err.h>
#define JZ_REG_CLOCK_CTRL 0x00
#define JZ_REG_CLOCK_PLL 0x10
#define JZ_REG_CLOCK_GATE 0x20
#define JZ_REG_CLOCK_I2S 0x60
#define JZ_REG_CLOCK_LCD 0x64
#define JZ_REG_CLOCK_MMC 0x68
#define JZ_REG_CLOCK_UHC 0x6C
#define JZ_REG_CLOCK_SPI 0x74
#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000
#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
#define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000
#define JZ_CLOCK_CTRL_UDIV_OFFSET 23
#define JZ_CLOCK_CTRL_LDIV_OFFSET 16
#define JZ_CLOCK_CTRL_MDIV_OFFSET 12
#define JZ_CLOCK_CTRL_PDIV_OFFSET 8
#define JZ_CLOCK_CTRL_HDIV_OFFSET 4
#define JZ_CLOCK_CTRL_CDIV_OFFSET 0
#define JZ_CLOCK_GATE_UART0 BIT(0)
#define JZ_CLOCK_GATE_TCU BIT(1)
#define JZ_CLOCK_GATE_RTC BIT(2)
#define JZ_CLOCK_GATE_I2C BIT(3)
#define JZ_CLOCK_GATE_SPI BIT(4)
#define JZ_CLOCK_GATE_AIC_PCLK BIT(5)
#define JZ_CLOCK_GATE_AIC BIT(6)
#define JZ_CLOCK_GATE_MMC BIT(7)
#define JZ_CLOCK_GATE_ADC BIT(8)
#define JZ_CLOCK_GATE_CIM BIT(9)
#define JZ_CLOCK_GATE_LCD BIT(10)
#define JZ_CLOCK_GATE_UDC BIT(11)
#define JZ_CLOCK_GATE_DMAC BIT(12)
#define JZ_CLOCK_GATE_IPU BIT(13)
#define JZ_CLOCK_GATE_UHC BIT(14)
#define JZ_CLOCK_GATE_UART1 BIT(15)
#define JZ_CLOCK_I2S_DIV_MASK 0x01ff
#define JZ_CLOCK_LCD_DIV_MASK 0x01ff
#define JZ_CLOCK_MMC_DIV_MASK 0x001f
#define JZ_CLOCK_UHC_DIV_MASK 0x000f
#define JZ_CLOCK_SPI_SRC_PLL BIT(31)
#define JZ_CLOCK_SPI_DIV_MASK 0x000f
#define JZ_CLOCK_PLL_M_MASK 0x01ff
#define JZ_CLOCK_PLL_N_MASK 0x001f
#define JZ_CLOCK_PLL_OD_MASK 0x0003
#define JZ_CLOCK_PLL_STABLE BIT(10)
#define JZ_CLOCK_PLL_BYPASS BIT(9)
#define JZ_CLOCK_PLL_ENABLED BIT(8)
#define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f
#define JZ_CLOCK_PLL_M_OFFSET 23
#define JZ_CLOCK_PLL_N_OFFSET 18
#define JZ_CLOCK_PLL_OD_OFFSET 16
static void __iomem *jz_clock_base;
static spinlock_t jz_clock_lock;
static LIST_HEAD(jz_clocks);
struct clk {
const char *name;
struct clk* parent;
uint32_t gate_bit;
unsigned long (*get_rate)(struct clk* clk);
unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
int (*set_rate)(struct clk* clk, unsigned long rate);
int (*enable)(struct clk* clk);
int (*disable)(struct clk* clk);
int (*set_parent)(struct clk* clk, struct clk *parent);
struct list_head list;
};
struct main_clk {
struct clk clk;
uint32_t div_offset;
};
struct divided_clk {
struct clk clk;
uint32_t reg;
uint32_t mask;
};
struct static_clk {
struct clk clk;
unsigned long rate;
};
static uint32_t jz_clk_reg_read(int reg)
{
return readl(jz_clock_base + reg);
}
static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
{
uint32_t val2;
spin_lock(&jz_clock_lock);
val2 = readl(jz_clock_base + reg);
val2 &= ~mask;
val2 |= val;
writel(val2, jz_clock_base + reg);
spin_unlock(&jz_clock_lock);
}
static void jz_clk_reg_set_bits(int reg, uint32_t mask)
{
uint32_t val;
spin_lock(&jz_clock_lock);
val = readl(jz_clock_base + reg);
val |= mask;
writel(val, jz_clock_base + reg);
spin_unlock(&jz_clock_lock);
}
static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
{
uint32_t val;
spin_lock(&jz_clock_lock);
val = readl(jz_clock_base + reg);
val &= ~mask;
writel(val, jz_clock_base + reg);
spin_unlock(&jz_clock_lock);
}
static int jz_clk_enable_gating(struct clk *clk)
{
jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
return 0;
}
static int jz_clk_disable_gating(struct clk *clk)
{
jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
return 0;
}
static unsigned long jz_clk_static_get_rate(struct clk *clk)
{
return ((struct static_clk*)clk)->rate;
}
static int jz_clk_ko_enable(struct clk* clk)
{
jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
return 0;
}
static int jz_clk_ko_disable(struct clk* clk)
{
jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
return 0;
}
static const int pllno[] = {1, 2, 2, 4};
static unsigned long jz_clk_pll_get_rate(struct clk *clk)
{
uint32_t val;
int m;
int n;
int od;
val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
if (val & JZ_CLOCK_PLL_BYPASS)
return clk_get_rate(clk->parent);
m = ((val >> 23) & 0x1ff) + 2;
n = ((val >> 18) & 0x1f) + 2;
od = (val >> 16) & 0x3;
return clk_get_rate(clk->parent) * (m / n) / pllno[od];
}
static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
{
uint32_t reg;
reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
if (reg & JZ_CLOCK_CTRL_PLL_HALF)
return jz_clk_pll_get_rate(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 static_clk jz_clk_ext = {
.clk = {
.name = "ext",
.get_rate = jz_clk_static_get_rate,
},
};
static struct clk jz_clk_pll = {
.name = "pll",
.parent = &jz_clk_ext.clk,
.get_rate = jz_clk_pll_get_rate,
};
static struct clk jz_clk_pll_half = {
.name = "pll half",
.parent = &jz_clk_pll,
.get_rate = jz_clk_pll_half_get_rate,
};
static struct main_clk jz_clk_cpu = {
.clk = {
.name = "cclk",
.parent = &jz_clk_pll,
.get_rate = jz_clk_main_get_rate,
.set_rate = jz_clk_main_set_rate,
.round_rate = jz_clk_main_round_rate,
},
.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
};
static struct main_clk jz_clk_memory = {
.clk = {
.name = "mclk",
.parent = &jz_clk_pll,
.get_rate = jz_clk_main_get_rate,
.set_rate = jz_clk_main_set_rate,
.round_rate = jz_clk_main_round_rate,
},
.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
};
static struct main_clk jz_clk_high_speed_peripheral = {
.clk = {
.name = "hclk",
.parent = &jz_clk_pll,
.get_rate = jz_clk_main_get_rate,
.set_rate = jz_clk_main_set_rate,
.round_rate = jz_clk_main_round_rate,
},
.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
};
static struct main_clk jz_clk_low_speed_peripheral = {
.clk = {
.name = "pclk",
.parent = &jz_clk_pll,
.get_rate = jz_clk_main_get_rate,
.set_rate = jz_clk_main_set_rate,
},
.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
};
static struct clk jz_clk_ko = {
.name = "cko",
.parent = &jz_clk_memory.clk,
.enable = jz_clk_ko_enable,
.disable = jz_clk_ko_disable,
};
static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
{
if (parent == &jz_clk_pll)
jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
else if(parent == &jz_clk_ext.clk)
jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
else
return -EINVAL;
clk->parent = parent;
return 0;
}
static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
{
if (parent == &jz_clk_pll_half)
jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
else if(parent == &jz_clk_ext.clk)
jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
else
return -EINVAL;
clk->parent = parent;
return 0;
}
static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
{
if (parent == &jz_clk_pll_half)
jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
else if(parent == &jz_clk_ext.clk)
jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
else
return -EINVAL;
clk->parent = parent;
return 0;
}
static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
{
int div;
if (clk->parent == &jz_clk_ext.clk)
return -EINVAL;
div = clk_get_rate(clk->parent) / rate - 1;
if (div < 0)
div = 0;
else if (div > 63)
div = 63;
jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
JZ_CLOCK_CTRL_UDIV_MASK);
return 0;
}
static unsigned long jz_clk_udc_get_rate(struct clk *clk)
{
int div;
if (clk->parent == &jz_clk_ext.clk)
return clk_get_rate(clk->parent);
div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
div += 1;
return clk_get_rate(clk->parent) / div;
}
static unsigned long jz_clk_divided_get_rate(struct clk *clk)
{
struct divided_clk *dclk = (struct divided_clk*)clk;
int div;
if (clk->parent == &jz_clk_ext.clk)
return clk_get_rate(clk->parent);
div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
return clk_get_rate(clk->parent) / div;
}
static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
{
struct divided_clk *dclk = (struct divided_clk*)clk;
int div;
if (clk->parent == &jz_clk_ext.clk)
return -EINVAL;
div = clk_get_rate(clk->parent) / rate - 1;
if (div < 0)
div = 0;
else if(div > dclk->mask)
div = dclk->mask;
jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
return 0;
}
static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
{
int div;
unsigned long parent_rate = jz_clk_pll_half_get_rate(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 struct clk jz_clk_ld = {
.name = "lcd",
.parent = &jz_clk_pll_half,
.set_rate = jz_clk_ldclk_set_rate,
.get_rate = jz_clk_ldclk_get_rate,
.round_rate = jz_clk_ldclk_round_rate,
};
static struct divided_clk jz_clk_lp = {
.clk = {
.name = "lcd_pclk",
.parent = &jz_clk_pll_half,
},
.reg = JZ_REG_CLOCK_LCD,
.mask = JZ_CLOCK_LCD_DIV_MASK,
};
static struct clk jz_clk_cim_mclk = {
.name = "cim_mclk",
.parent = &jz_clk_high_speed_peripheral.clk,
};
static struct static_clk jz_clk_cim_pclk = {
.clk = {
.name = "cim_pclk",
.gate_bit = JZ_CLOCK_GATE_CIM,
.get_rate = jz_clk_static_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
},
};
static struct divided_clk jz_clk_i2s = {
.clk = {
.name = "i2s",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_AIC,
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.set_parent = jz_clk_i2s_set_parent,
},
.reg = JZ_REG_CLOCK_I2S,
.mask = JZ_CLOCK_I2S_DIV_MASK,
};
static struct divided_clk jz_clk_mmc = {
.clk = {
.name = "mmc",
.parent = &jz_clk_pll_half,
.gate_bit = JZ_CLOCK_GATE_MMC,
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
},
.reg = JZ_REG_CLOCK_MMC,
.mask = JZ_CLOCK_MMC_DIV_MASK,
};
static struct divided_clk jz_clk_uhc = {
.clk = {
.name = "uhc",
.parent = &jz_clk_pll_half,
.gate_bit = JZ_CLOCK_GATE_UHC,
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
},
.reg = JZ_REG_CLOCK_UHC,
.mask = JZ_CLOCK_UHC_DIV_MASK,
};
static struct clk jz_clk_udc = {
.name = "udc",
.parent = &jz_clk_ext.clk,
.set_parent = jz_clk_udc_set_parent,
.set_rate = jz_clk_udc_set_rate,
.get_rate = jz_clk_udc_get_rate,
};
static struct divided_clk jz_clk_spi = {
.clk = {
.name = "spi",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_SPI,
.set_rate = jz_clk_divided_set_rate,
.get_rate = jz_clk_divided_get_rate,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
.set_parent = jz_clk_spi_set_parent,
},
.reg = JZ_REG_CLOCK_SPI,
.mask = JZ_CLOCK_SPI_DIV_MASK,
};
static struct clk jz_clk_uart0 = {
.name = "uart0",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_UART0,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
};
static struct clk jz_clk_uart1 = {
.name = "uart1",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_UART1,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
};
static struct clk jz_clk_dma = {
.name = "dma",
.parent = &jz_clk_high_speed_peripheral.clk,
.gate_bit = JZ_CLOCK_GATE_UART0,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
};
static struct clk jz_clk_ipu = {
.name = "ipu",
.parent = &jz_clk_high_speed_peripheral.clk,
.gate_bit = JZ_CLOCK_GATE_IPU,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
};
static struct clk jz_clk_adc = {
.name = "adc",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_ADC,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
};
static struct clk jz_clk_i2c = {
.name = "i2c",
.parent = &jz_clk_ext.clk,
.gate_bit = JZ_CLOCK_GATE_I2C,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
};
static struct static_clk jz_clk_rtc = {
.clk = {
.name = "rtc",
.gate_bit = JZ_CLOCK_GATE_RTC,
.enable = jz_clk_enable_gating,
.disable = jz_clk_disable_gating,
},
.rate = 32768,
};
int clk_enable(struct clk *clk)
{
if (!clk->enable)
return -EINVAL;
return clk->enable(clk);
}
EXPORT_SYMBOL_GPL(clk_enable);
void clk_disable(struct clk *clk)
{
if (clk->disable)
clk->disable(clk);
}
EXPORT_SYMBOL_GPL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
if (clk->get_rate)
return clk->get_rate(clk);
if (clk->parent)
return clk_get_rate(clk->parent);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
if (!clk->set_rate)
return -EINVAL;
return clk->set_rate(clk, rate);
}
EXPORT_SYMBOL_GPL(clk_set_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
if (clk->round_rate)
return clk->round_rate(clk, rate);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(clk_round_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
int ret;
if (!clk->set_parent)
return -EINVAL;
clk->disable(clk);
ret = clk->set_parent(clk, parent);
clk->enable(clk);
return ret;
}
EXPORT_SYMBOL_GPL(clk_set_parent);
struct clk *clk_get(struct device *dev, const char *name)
{
struct clk *clk;
list_for_each_entry(clk, &jz_clocks, list) {
if (strcmp(clk->name, name) == 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);
}
static void clk_register_clks(void)
{
clk_add(&jz_clk_ext.clk);
clk_add(&jz_clk_pll);
clk_add(&jz_clk_pll_half);
clk_add(&jz_clk_cpu.clk);
clk_add(&jz_clk_high_speed_peripheral.clk);
clk_add(&jz_clk_low_speed_peripheral.clk);
clk_add(&jz_clk_ko);
clk_add(&jz_clk_ld);
clk_add(&jz_clk_lp.clk);
clk_add(&jz_clk_cim_mclk);
clk_add(&jz_clk_cim_pclk.clk);
clk_add(&jz_clk_i2s.clk);
clk_add(&jz_clk_mmc.clk);
clk_add(&jz_clk_uhc.clk);
clk_add(&jz_clk_udc);
clk_add(&jz_clk_uart0);
clk_add(&jz_clk_uart1);
clk_add(&jz_clk_dma);
clk_add(&jz_clk_ipu);
clk_add(&jz_clk_adc);
clk_add(&jz_clk_i2c);
clk_add(&jz_clk_rtc.clk);
}
int jz_init_clocks(unsigned long ext_rate)
{
uint32_t val;
jz_clock_base = ioremap(0x10000000, 0x100);
if (!jz_clock_base)
return -EBUSY;
jz_clk_ext.rate = ext_rate;
val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
if (val & JZ_CLOCK_SPI_SRC_PLL)
jz_clk_spi.clk.parent = &jz_clk_pll_half;
val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
jz_clk_i2s.clk.parent = &jz_clk_pll_half;
if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
jz_clk_udc.parent = &jz_clk_pll_half;
clk_register_clks();
return 0;
}
EXPORT_SYMBOL_GPL(jz_init_clocks);

View File

@ -1,582 +0,0 @@
/*
* linux/arch/mips/jz4740/cpufreq.c
*
* cpufreq driver for JZ4740
*
* Copyright (c) 2006-2007 Ingenic Semiconductor Inc.
* Author: <lhhuang@ingenic.cn>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <asm/mach-jz4740/regs.h>
#include <asm/mach-jz4740/clock.h>
#include <asm/processor.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
"cpufreq-jz4740", msg)
#undef CHANGE_PLL
#define PLL_UNCHANGED 0
#define PLL_GOES_UP 1
#define PLL_GOES_DOWN 2
#define PLL_WAIT_500NS (500*(__cpm_get_cclk()/1000000000))
/* Saved the boot-time parameters */
static struct {
/* SDRAM parameters */
unsigned int mclk; /* memory clock, KHz */
unsigned int tras; /* RAS pulse width, cycles of mclk */
unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */
unsigned int tpc; /* RAS Precharge time, cycles of mclk */
unsigned int trwl; /* Write Precharge Time, cycles of mclk */
unsigned int trc; /* RAS Cycle Time, cycles of mclk */
unsigned int rtcor; /* Refresh Time Constant */
unsigned int sdram_initialized;
/* LCD parameters */
unsigned int lcd_clk; /* LCD clock, Hz */
unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */
unsigned int lcd_clks_initialized;
} boot_config;
struct jz4740_freq_percpu_info {
struct cpufreq_frequency_table table[7];
};
static struct jz4740_freq_percpu_info jz4740_freq_table;
/*
* This contains the registers value for an operating point.
* If only part of a register needs to change then there is
* a mask value for that register.
* When going to a new operating point the current register
* value is ANDed with the ~mask and ORed with the new value.
*/
struct dpm_regs {
u32 cpccr; /* Clock Freq Control Register */
u32 cpccr_mask; /* Clock Freq Control Register mask */
u32 cppcr; /* PLL1 Control Register */
u32 cppcr_mask; /* PLL1 Control Register mask */
u32 pll_up_flag; /* New PLL freq is higher than current or not */
};
static void
jz_init_boot_config(void)
{
if (!boot_config.lcd_clks_initialized) {
/* the first time to scale pll */
boot_config.lcd_clk = __cpm_get_lcdclk();
boot_config.lcdpix_clk = __cpm_get_pixclk();
boot_config.lcd_clks_initialized = 1;
}
if (!boot_config.sdram_initialized) {
/* the first time to scale frequencies */
unsigned int dmcr, rtcor;
unsigned int tras, rcd, tpc, trwl, trc;
dmcr = REG_EMC_DMCR;
rtcor = REG_EMC_RTCOR;
tras = (dmcr >> 13) & 0x7;
rcd = (dmcr >> 11) & 0x3;
tpc = (dmcr >> 8) & 0x7;
trwl = (dmcr >> 5) & 0x3;
trc = (dmcr >> 2) & 0x7;
boot_config.mclk = __cpm_get_mclk() / 1000;
boot_config.tras = tras + 4;
boot_config.rcd = rcd + 1;
boot_config.tpc = tpc + 1;
boot_config.trwl = trwl + 1;
boot_config.trc = trc * 2 + 1;
boot_config.rtcor = rtcor;
boot_config.sdram_initialized = 1;
}
}
static void jz_update_dram_rtcor(unsigned int new_mclk)
{
unsigned int rtcor;
new_mclk /= 1000;
rtcor = boot_config.rtcor * new_mclk / boot_config.mclk;
rtcor--;
if (rtcor < 1) rtcor = 1;
if (rtcor > 255) rtcor = 255;
REG_EMC_RTCOR = rtcor;
REG_EMC_RTCNT = rtcor;
}
static void jz_update_dram_dmcr(unsigned int new_mclk)
{
unsigned int dmcr;
unsigned int tras, rcd, tpc, trwl, trc;
unsigned int valid_time, new_time; /* ns */
new_mclk /= 1000;
tras = boot_config.tras * new_mclk / boot_config.mclk;
rcd = boot_config.rcd * new_mclk / boot_config.mclk;
tpc = boot_config.tpc * new_mclk / boot_config.mclk;
trwl = boot_config.trwl * new_mclk / boot_config.mclk;
trc = boot_config.trc * new_mclk / boot_config.mclk;
/* Validation checking */
valid_time = (boot_config.tras * 1000000) / boot_config.mclk;
new_time = (tras * 1000000) / new_mclk;
if (new_time < valid_time) tras += 1;
valid_time = (boot_config.rcd * 1000000) / boot_config.mclk;
new_time = (rcd * 1000000) / new_mclk;
if (new_time < valid_time) rcd += 1;
valid_time = (boot_config.tpc * 1000000) / boot_config.mclk;
new_time = (tpc * 1000000) / new_mclk;
if (new_time < valid_time) tpc += 1;
valid_time = (boot_config.trwl * 1000000) / boot_config.mclk;
new_time = (trwl * 1000000) / new_mclk;
if (new_time < valid_time) trwl += 1;
valid_time = (boot_config.trc * 1000000) / boot_config.mclk;
new_time = (trc * 1000000) / new_mclk;
if (new_time < valid_time) trc += 2;
tras = (tras < 4) ? 4: tras;
tras = (tras > 11) ? 11: tras;
tras -= 4;
rcd = (rcd < 1) ? 1: rcd;
rcd = (rcd > 4) ? 4: rcd;
rcd -= 1;
tpc = (tpc < 1) ? 1: tpc;
tpc = (tpc > 8) ? 8: tpc;
tpc -= 1;
trwl = (trwl < 1) ? 1: trwl;
trwl = (trwl > 4) ? 4: trwl;
trwl -= 1;
trc = (trc < 1) ? 1: trc;
trc = (trc > 15) ? 15: trc;
trc /= 2;
dmcr = REG_EMC_DMCR;
dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK);
dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT));
REG_EMC_DMCR = dmcr;
}
static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk)
{
/* No risk, no fun: run with interrupts on! */
if (new_mclk > cur_mclk) {
/* We're going FASTER, so first update TRAS, RCD, TPC, TRWL
* and TRC of DMCR before changing the frequency.
*/
jz_update_dram_dmcr(new_mclk);
} else {
/* We're going SLOWER: first update RTCOR value
* before changing the frequency.
*/
jz_update_dram_rtcor(new_mclk);
}
}
static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk)
{
/* No risk, no fun: run with interrupts on! */
if (new_mclk > cur_mclk) {
/* We're going FASTER, so update RTCOR
* after changing the frequency
*/
jz_update_dram_rtcor(new_mclk);
} else {
/* We're going SLOWER: so update TRAS, RCD, TPC, TRWL
* and TRC of DMCR after changing the frequency.
*/
jz_update_dram_dmcr(new_mclk);
}
}
static void jz_scale_divisors(struct dpm_regs *regs)
{
unsigned int cpccr;
unsigned int cur_mclk, new_mclk;
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
unsigned int tmp = 0, wait = PLL_WAIT_500NS;
cpccr = REG_CPM_CPCCR;
cpccr &= ~((unsigned long)regs->cpccr_mask);
cpccr |= regs->cpccr;
cpccr |= CPM_CPCCR_CE; /* update immediately */
cur_mclk = __cpm_get_mclk();
new_mclk = __cpm_get_pllout() / div[(cpccr & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT];
/* Update some DRAM parameters before changing frequency */
jz_update_dram_prev(cur_mclk, new_mclk);
/* update register to change the clocks.
* align this code to a cache line.
*/
__asm__ __volatile__(
".set noreorder\n\t"
".align 5\n"
"sw %1,0(%0)\n\t"
"li %3,0\n\t"
"1:\n\t"
"bne %3,%2,1b\n\t"
"addi %3, 1\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
".set reorder\n\t"
:
: "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp));
/* Update some other DRAM parameters after changing frequency */
jz_update_dram_post(cur_mclk, new_mclk);
}
#ifdef CHANGE_PLL
/* Maintain the LCD clock and pixel clock */
static void jz_scale_lcd_divisors(struct dpm_regs *regs)
{
unsigned int new_pll, new_lcd_div, new_lcdpix_div;
unsigned int cpccr;
unsigned int tmp = 0, wait = PLL_WAIT_500NS;
if (!boot_config.lcd_clks_initialized) return;
new_pll = __cpm_get_pllout();
new_lcd_div = new_pll / boot_config.lcd_clk;
new_lcdpix_div = new_pll / boot_config.lcdpix_clk;
if (new_lcd_div < 1)
new_lcd_div = 1;
if (new_lcd_div > 16)
new_lcd_div = 16;
if (new_lcdpix_div < 1)
new_lcdpix_div = 1;
if (new_lcdpix_div > 512)
new_lcdpix_div = 512;
// REG_CPM_CPCCR2 = new_lcdpix_div - 1;
cpccr = REG_CPM_CPCCR;
cpccr &= ~CPM_CPCCR_LDIV_MASK;
cpccr |= ((new_lcd_div - 1) << CPM_CPCCR_LDIV_BIT);
cpccr |= CPM_CPCCR_CE; /* update immediately */
/* update register to change the clocks.
* align this code to a cache line.
*/
__asm__ __volatile__(
".set noreorder\n\t"
".align 5\n"
"sw %1,0(%0)\n\t"
"li %3,0\n\t"
"1:\n\t"
"bne %3,%2,1b\n\t"
"addi %3, 1\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
".set reorder\n\t"
:
: "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp));
}
static void jz_scale_pll(struct dpm_regs *regs)
{
unsigned int cppcr;
unsigned int cur_mclk, new_mclk, new_pll;
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
int od[] = {1, 2, 2, 4};
cppcr = REG_CPM_CPPCR;
cppcr &= ~(regs->cppcr_mask | CPM_CPPCR_PLLS | CPM_CPPCR_PLLEN | CPM_CPPCR_PLLST_MASK);
regs->cppcr &= ~CPM_CPPCR_PLLEN;
cppcr |= (regs->cppcr | 0xff);
/* Update some DRAM parameters before changing frequency */
new_pll = JZ_EXTAL * ((cppcr>>23)+2) / ((((cppcr>>18)&0x1f)+2) * od[(cppcr>>16)&0x03]);
cur_mclk = __cpm_get_mclk();
new_mclk = new_pll / div[(REG_CPM_CPCCR>>CPM_CPCCR_MDIV_BIT) & 0xf];
/*
* Update some SDRAM parameters
*/
jz_update_dram_prev(cur_mclk, new_mclk);
/*
* Update PLL, align code to cache line.
*/
cppcr |= CPM_CPPCR_PLLEN;
__asm__ __volatile__(
".set noreorder\n\t"
".align 5\n"
"sw %1,0(%0)\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
".set reorder\n\t"
:
: "r" (CPM_CPPCR), "r" (cppcr));
/* Update some other DRAM parameters after changing frequency */
jz_update_dram_post(cur_mclk, new_mclk);
}
#endif
static void jz4740_transition(struct dpm_regs *regs)
{
/*
* Get and save some boot-time conditions.
*/
jz_init_boot_config();
#ifdef CHANGE_PLL
/*
* Disable LCD before scaling pll.
* LCD and LCD pixel clocks should not be changed even if the PLL
* output frequency has been changed.
*/
REG_LCD_CTRL &= ~LCD_CTRL_ENA;
/*
* Stop module clocks before scaling PLL
*/
__cpm_stop_eth();
__cpm_stop_aic(1);
__cpm_stop_aic(2);
#endif
/* ... add more as necessary */
if (regs->pll_up_flag == PLL_GOES_UP) {
/* the pll frequency is going up, so change dividors first */
jz_scale_divisors(regs);
#ifdef CHANGE_PLL
jz_scale_pll(regs);
#endif
}
else if (regs->pll_up_flag == PLL_GOES_DOWN) {
/* the pll frequency is going down, so change pll first */
#ifdef CHANGE_PLL
jz_scale_pll(regs);
#endif
jz_scale_divisors(regs);
}
else {
/* the pll frequency is unchanged, so change divisors only */
jz_scale_divisors(regs);
}
#ifdef CHANGE_PLL
/*
* Restart module clocks before scaling PLL
*/
__cpm_start_eth();
__cpm_start_aic(1);
__cpm_start_aic(2);
/* ... add more as necessary */
/* Scale the LCD divisors after scaling pll */
if (regs->pll_up_flag != PLL_UNCHANGED) {
jz_scale_lcd_divisors(regs);
}
/* Enable LCD controller */
REG_LCD_CTRL &= ~LCD_CTRL_DIS;
REG_LCD_CTRL |= LCD_CTRL_ENA;
#endif
}
extern unsigned int idle_times;
static unsigned int jz4740_freq_get(unsigned int cpu)
{
return (__cpm_get_cclk() / 1000);
}
static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs)
{
int n2FR[33] = {
0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
9
};
int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */
unsigned int div_of_cclk, new_freq, i;
regs->pll_up_flag = PLL_UNCHANGED;
regs->cpccr_mask = CPM_CPCCR_CDIV_MASK | CPM_CPCCR_HDIV_MASK | CPM_CPCCR_PDIV_MASK | CPM_CPCCR_MDIV_MASK;
new_freq = jz4740_freq_table.table[index].frequency;
do {
div_of_cclk = __cpm_get_pllout() / (1000 * new_freq);
} while (div_of_cclk==0);
if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) {
for(i = 1; i<4; i++) {
div[i] = 3;
}
} else {
for(i = 1; i<4; i++) {
div[i] = 2;
}
}
for(i = 0; i<4; i++) {
div[i] *= div_of_cclk;
}
dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]);
regs->cpccr =
(n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
(n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
(n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
(n2FR[div[3]] << CPM_CPCCR_MDIV_BIT);
return div_of_cclk;
}
static void jz4740_set_cpu_divider_index(unsigned int cpu, unsigned int index)
{
unsigned long divisor, old_divisor;
struct cpufreq_freqs freqs;
struct dpm_regs regs;
old_divisor = __cpm_get_pllout() / __cpm_get_cclk();
divisor = index_to_divisor(index, &regs);
freqs.old = __cpm_get_cclk() / 1000;
freqs.new = __cpm_get_pllout() / (1000 * divisor);
freqs.cpu = cpu;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (old_divisor != divisor)
jz4740_transition(&regs);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
static int jz4740_freq_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int new_index = 0;
if (cpufreq_frequency_table_target(policy,
&jz4740_freq_table.table[0],
target_freq, relation, &new_index))
return -EINVAL;
jz4740_set_cpu_divider_index(policy->cpu, new_index);
dprintk("new frequency is %d KHz (REG_CPM_CPCCR:0x%x)\n", __cpm_get_cclk() / 1000, REG_CPM_CPCCR);
return 0;
}
static int jz4740_freq_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy,
&jz4740_freq_table.table[0]);
}
static int __init jz4740_cpufreq_driver_init(struct cpufreq_policy *policy)
{
struct cpufreq_frequency_table *table = &jz4740_freq_table.table[0];
unsigned int MAX_FREQ;
dprintk(KERN_INFO "Jz4740 cpufreq driver\n");
if (policy->cpu != 0)
return -EINVAL;
policy->cur = MAX_FREQ = __cpm_get_cclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = MAX_FREQ/8;
policy->cpuinfo.max_freq = MAX_FREQ;
policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */
table[0].index = 0;
table[0].frequency = MAX_FREQ/8;
table[1].index = 1;
table[1].frequency = MAX_FREQ/6;
table[2].index = 2;
table[2].frequency = MAX_FREQ/4;
table[3].index = 3;
table[3].frequency = MAX_FREQ/3;
table[4].index = 4;
table[4].frequency = MAX_FREQ/2;
table[5].index = 5;
table[5].frequency = MAX_FREQ;
table[6].index = 6;
table[6].frequency = CPUFREQ_TABLE_END;
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
cpufreq_frequency_table_get_attr(table, policy->cpu); /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */
#endif
return cpufreq_frequency_table_cpuinfo(policy, table);
}
static struct cpufreq_driver cpufreq_jz4740_driver = {
// .flags = CPUFREQ_STICKY,
.init = jz4740_cpufreq_driver_init,
.verify = jz4740_freq_verify,
.target = jz4740_freq_target,
.get = jz4740_freq_get,
.name = "jz4740",
};
static int __init jz4740_cpufreq_init(void)
{
return cpufreq_register_driver(&cpufreq_jz4740_driver);
}
static void __exit jz4740_cpufreq_exit(void)
{
cpufreq_unregister_driver(&cpufreq_jz4740_driver);
}
module_init(jz4740_cpufreq_init);
module_exit(jz4740_cpufreq_exit);
MODULE_AUTHOR("Regen <lhhuang@ingenic.cn>");
MODULE_DESCRIPTION("cpufreq driver for Jz4740");
MODULE_LICENSE("GPL");

View File

@ -1,338 +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;
}
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;
}
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,
};
#if 0
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,490 +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>
#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);
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_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);
jz_gpio_irq_unmask(irq);
desc->status &= ~IRQ_MASKED;
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),
};
static int jz_gpio_suspend(struct sys_device *dev, pm_message_t state)
{
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));
}
return 0;
}
static int jz_gpio_resume(struct sys_device *dev)
{
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));
}
return 0;
}
static struct sysdev_class jz_gpio_sysdev = {
.name = "JZ4740 GPIO",
.suspend = jz_gpio_suspend,
.resume = jz_gpio_resume,
};
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);
}
}
sysdev_class_register(&jz_gpio_sysdev);
printk("JZ GPIO initalized\n");
return 0;
}

View File

@ -1,137 +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 <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 void intc_irq_end(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
intc_irq_unmask(irq);
}
}
static int intc_irq_set_wake(unsigned int irq, unsigned int on)
{
if (on)
jz_intc_wakeup |= IRQ_BIT(irq);
else
jz_intc_wakeup &= ~IRQ_BIT(irq);
return 0;
}
static struct irq_chip intc_irq_type = {
.name = "INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
.ack = intc_irq_ack,
.set_wake = intc_irq_set_wake,
};
static irqreturn_t jz4740_cascade(int irq, void *data)
{
uint32_t irq_reg;
irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
if (irq_reg) {
generic_handle_irq(ffs(irq_reg) - 1 + JZ_IRQ_BASE);
return IRQ_HANDLED;
}
return 0;
}
static struct irqaction jz4740_cascade_action = {
.handler = jz4740_cascade,
.name = "JZ4740 cascade interrupt"
};
void __init arch_init_irq(void)
{
int i;
mips_cpu_irq_init();
jz_intc_base = ioremap(JZ_REG_BASE_INTC, 0x14);
for (i = JZ_IRQ_BASE; i < JZ_IRQ_BASE + 32; i++) {
intc_irq_mask(i);
set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
}
setup_irq(2, &jz4740_cascade_action);
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
if (pending & STATUSF_IP2)
jz4740_cascade(2, NULL);
else if(pending & STATUSF_IP3)
do_IRQ(3);
else
spurious_interrupt();
}
/* TODO: Use sysdev */
void jz4740_intc_suspend(void)
{
jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
}
void jz4740_intc_resume(void)
{
writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
}

View File

@ -1,241 +0,0 @@
/*
* Platform device support for Jz4740 SoC.
*
* Copyright 2007, <yliu@ingenic.cn>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/resource.h>
#include <asm/mach-jz4740/platform.h>
#include <asm/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) + 0x10,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = JZ_IRQ_RTC,
.end = JZ_IRQ_RTC,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device jz4740_rtc_device = {
.name = "jz4740-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(jz4740_rtc_resources),
.resource = jz4740_rtc_resources,
};
/** I2C controller **/
static struct resource jz4740_i2c_resources[] = {
[0] = {
.start = CPHYSADDR(I2C_BASE),
.end = CPHYSADDR(I2C_BASE) + 0x10000 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = JZ_IRQ_I2C,
.end = JZ_IRQ_I2C,
.flags = IORESOURCE_IRQ,
}
};
static u64 jz4740_i2c_dmamask = ~(u32)0;
struct platform_device jz4740_i2c_device = {
.name = "jz_i2c",
.id = 0,
.dev = {
.dma_mask = &jz4740_i2c_dmamask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(jz4740_i2c_resources),
.resource = jz4740_i2c_resources,
};
static struct resource jz4740_nand_resources[] = {
[0] = {
.start = CPHYSADDR(EMC_BASE),
.end = CPHYSADDR(EMC_BASE) + 0x10000 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device jz4740_nand_device = {
.name = "jz4740-nand",
.num_resources = ARRAY_SIZE(jz4740_nand_resources),
.resource = jz4740_nand_resources,
};
static struct resource jz4740_framebuffer_resources[] = {
[0] = {
.start = CPHYSADDR(LCD_BASE),
.end = CPHYSADDR(LCD_BASE) + 0x10000 - 1,
.flags = IORESOURCE_MEM,
},
};
static u64 jz4740_fb_dmamask = ~(u32)0;
struct platform_device jz4740_framebuffer_device = {
.name = "jz4740-fb",
.id = -1,
.num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
.resource = jz4740_framebuffer_resources,
.dev = {
.dma_mask = &jz4740_fb_dmamask,
.coherent_dma_mask = 0xffffffff,
},
};
static struct resource jz4740_i2s_resources[] = {
[0] = {
.start = CPHYSADDR(AIC_BASE),
.end = CPHYSADDR(AIC_BASE) + 0x38 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device jz4740_i2s_device = {
.name = "jz4740-i2s",
.id = -1,
.num_resources = ARRAY_SIZE(jz4740_i2s_resources),
.resource = jz4740_i2s_resources,
};
static struct resource jz4740_codec_resources[] = {
[0] = {
.start = CPHYSADDR(AIC_BASE) + 0x80,
.end = CPHYSADDR(AIC_BASE) + 0x88 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device jz4740_codec_device = {
.name = "jz4740-codec",
.id = -1,
.num_resources = ARRAY_SIZE(jz4740_codec_resources),
.resource = jz4740_codec_resources,
};
static struct resource jz4740_adc_resources[] = {
[0] = {
.start = CPHYSADDR(SADC_BASE),
.end = CPHYSADDR(SADC_BASE) + 0x30,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = JZ_IRQ_SADC,
.end = JZ_IRQ_SADC,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device jz4740_adc_device = {
.name = "jz4740-adc",
.id = -1,
.num_resources = ARRAY_SIZE(jz4740_adc_resources),
.resource = jz4740_adc_resources,
};
struct platform_device jz4740_battery_device = {
.name = "jz4740-battery",
.id = -1,
.dev = {
.parent = &jz4740_adc_device.dev
},
};

View File

@ -1,85 +0,0 @@
/*
* linux/arch/mips/jz4740/common/pm.c
*
* JZ4740 Power Management Routines
*
* Copyright (C) 2006 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
*/
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/suspend.h>
#include <asm/mach-jz4740/regs.h>
extern void jz4740_intc_suspend(void);
extern void jz4740_intc_resume(void);
static int jz_pm_enter(suspend_state_t state)
{
unsigned long nfcsr = REG_EMC_NFCSR;
uint32_t scr = REG_CPM_SCR;
/* Disable nand flash */
REG_EMC_NFCSR = ~0xff;
udelay(100);
/*stop udc and usb*/
REG_CPM_SCR &= ~( 1<<6 | 1<<7);
REG_CPM_SCR |= 0<<6 | 1<<7;
jz4740_intc_suspend();
/* Enter SLEEP mode */
REG_CPM_LCR &= ~CPM_LCR_LPM_MASK;
REG_CPM_LCR |= CPM_LCR_LPM_SLEEP;
__asm__(".set\tmips3\n\t"
"wait\n\t"
".set\tmips0");
/* Restore to IDLE mode */
REG_CPM_LCR &= ~CPM_LCR_LPM_MASK;
REG_CPM_LCR |= CPM_LCR_LPM_IDLE;
/* Restore nand flash control register */
REG_EMC_NFCSR = nfcsr;
jz4740_intc_resume();
/* Restore sleep control register */
REG_CPM_SCR = scr;
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,256 +0,0 @@
/*
* linux/arch/mips/jz4740/proc.c
*
* /proc/jz/ procfs for jz4740 on-chip modules.
*
* Copyright (C) 2006 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/page-flags.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/mach-jz4740/regs.h>
#include <asm/mach-jz4740/clock.h>
//#define DEBUG 1
#undef DEBUG
struct proc_dir_entry *proc_jz_root;
/*
* EMC Modules
*/
static int emc_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = 0;
len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4);
len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4);
len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR);
len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR);
len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR);
return len;
}
/*
* Power Manager Module
*/
static int pmc_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = 0;
unsigned long lcr = REG_CPM_LCR;
unsigned long clkgr = REG_CPM_CLKGR;
len += sprintf (page+len, "Low Power Mode : %s\n",
((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_IDLE)) ?
"IDLE" : (((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_SLEEP)) ?
"SLEEP" : "HIBERNATE"));
len += sprintf (page+len, "Doze Mode : %s\n",
(lcr & CPM_LCR_DOZE_ON) ? "on" : "off");
if (lcr & CPM_LCR_DOZE_ON)
len += sprintf (page+len, " duty : %d\n", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT));
len += sprintf (page+len, "IPU : %s\n",
(clkgr & CPM_CLKGR_IPU) ? "stopped" : "running");
len += sprintf (page+len, "DMAC : %s\n",
(clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running");
len += sprintf (page+len, "UHC : %s\n",
(clkgr & CPM_CLKGR_UHC) ? "stopped" : "running");
len += sprintf (page+len, "UDC : %s\n",
(clkgr & CPM_CLKGR_UDC) ? "stopped" : "running");
len += sprintf (page+len, "LCD : %s\n",
(clkgr & CPM_CLKGR_LCD) ? "stopped" : "running");
len += sprintf (page+len, "CIM : %s\n",
(clkgr & CPM_CLKGR_CIM) ? "stopped" : "running");
len += sprintf (page+len, "SADC : %s\n",
(clkgr & CPM_CLKGR_SADC) ? "stopped" : "running");
len += sprintf (page+len, "MSC : %s\n",
(clkgr & CPM_CLKGR_MSC) ? "stopped" : "running");
len += sprintf (page+len, "AIC1 : %s\n",
(clkgr & CPM_CLKGR_AIC1) ? "stopped" : "running");
len += sprintf (page+len, "AIC2 : %s\n",
(clkgr & CPM_CLKGR_AIC2) ? "stopped" : "running");
len += sprintf (page+len, "SSI : %s\n",
(clkgr & CPM_CLKGR_SSI) ? "stopped" : "running");
len += sprintf (page+len, "I2C : %s\n",
(clkgr & CPM_CLKGR_I2C) ? "stopped" : "running");
len += sprintf (page+len, "RTC : %s\n",
(clkgr & CPM_CLKGR_RTC) ? "stopped" : "running");
len += sprintf (page+len, "TCU : %s\n",
(clkgr & CPM_CLKGR_TCU) ? "stopped" : "running");
len += sprintf (page+len, "UART1 : %s\n",
(clkgr & CPM_CLKGR_UART1) ? "stopped" : "running");
len += sprintf (page+len, "UART0 : %s\n",
(clkgr & CPM_CLKGR_UART0) ? "stopped" : "running");
return len;
}
static int pmc_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
{
REG_CPM_CLKGR = simple_strtoul(buffer, 0, 16);
return count;
}
/*
* Clock Generation Module
*/
#define TO_MHZ(x) (x/1000000),(x%1000000)/10000
#define TO_KHZ(x) (x/1000),(x%1000)/10
static int cgm_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = 0;
unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */
unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */
unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
unsigned int od[4] = {1, 2, 2, 4};
len += sprintf (page+len, "CPPCR : 0x%08x\n", cppcr);
len += sprintf (page+len, "CPCCR : 0x%08x\n", cpccr);
len += sprintf (page+len, "PLL : %s\n",
(cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF");
len += sprintf (page+len, "m:n:o : %d:%d:%d\n",
__cpm_get_pllm() + 2,
__cpm_get_plln() + 2,
od[__cpm_get_pllod()]
);
len += sprintf (page+len, "C:H:M:P : %d:%d:%d:%d\n",
div[__cpm_get_cdiv()],
div[__cpm_get_hdiv()],
div[__cpm_get_mdiv()],
div[__cpm_get_pdiv()]
);
len += sprintf (page+len, "PLL Freq : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pllout()));
len += sprintf (page+len, "CCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_cclk()));
len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_hclk()));
len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mclk()));
len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pclk()));
len += sprintf (page+len, "LCDCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_lcdclk()));
len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(__cpm_get_pixclk()));
len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_i2sclk()));
len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_usbclk()));
len += sprintf (page+len, "MSCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk()));
len += sprintf (page+len, "EXTALCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk()));
len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_rtcclk()));
return len;
}
static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
{
REG_CPM_CPCCR = simple_strtoul(buffer, 0, 16);
return count;
}
extern void local_flush_tlb_all(void);
/* CP0 hazard avoidance. */
#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
"nop; nop; nop; nop; nop; nop;\n\t" \
".set reorder\n\t")
void show_tlb(void)
{
#define ASID_MASK 0xFF
unsigned long flags;
unsigned int old_ctx;
unsigned int entry;
unsigned int entrylo0, entrylo1, entryhi;
unsigned int pagemask;
local_irq_save(flags);
/* Save old context */
old_ctx = (read_c0_entryhi() & 0xff);
printk("TLB content:\n");
entry = 0;
while(entry < 32) {
write_c0_index(entry);
BARRIER;
tlb_read();
BARRIER;
entryhi = read_c0_entryhi();
entrylo0 = read_c0_entrylo0();
entrylo1 = read_c0_entrylo1();
pagemask = read_c0_pagemask();
printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK);
printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : "");
printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : "");
printk("\t\tpagemask=0x%08x", pagemask);
printk("\tentryhi=0x%08x\n", entryhi);
printk("\t\tentrylo0=0x%08x", entrylo0);
printk("\tentrylo1=0x%08x\n", entrylo1);
entry++;
}
BARRIER;
write_c0_entryhi(old_ctx);
local_irq_restore(flags);
}
/*
* /proc/jz/xxx entry
*
*/
static int __init jz_proc_init(void)
{
struct proc_dir_entry *res;
proc_jz_root = proc_mkdir("jz", 0);
/* External Memory Controller */
res = create_proc_entry("emc", 0644, proc_jz_root);
if (res) {
res->read_proc = emc_read_proc;
res->write_proc = NULL;
res->data = NULL;
}
/* Power Management Controller */
res = create_proc_entry("pmc", 0644, proc_jz_root);
if (res) {
res->read_proc = pmc_read_proc;
res->write_proc = pmc_write_proc;
res->data = NULL;
}
/* Clock Generation Module */
res = create_proc_entry("cgm", 0644, proc_jz_root);
if (res) {
res->read_proc = cgm_read_proc;
res->write_proc = cgm_write_proc;
res->data = NULL;
}
return 0;
}
__initcall(jz_proc_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,50 +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>
void jz_restart(char *command)
{
printk(KERN_NOTICE "Restarting after 4 ms\n");
REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN;
REG_WDT_TCNT = 0;
REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */
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,107 +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/regs.h>
#include <asm/mach-jz4740/clock.h>
#include <asm/mach-jz4740/serial.h>
extern char *__init prom_getcmdline(void);
extern void __init jz_board_setup(void);
extern void jz_restart(char *);
extern void jz_halt(void);
extern void jz_power_off(void);
extern void jz_time_init(void);
static void __init soc_cpm_setup(void)
{
/* Enable CKO to external memory */
__cpm_enable_cko();
/* CPU enters IDLE mode when executing 'wait' instruction */
__cpm_idle_mode();
}
static void __init jz_serial_setup(void)
{
#ifdef CONFIG_SERIAL_8250
struct uart_port s;
REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */
memset(&s, 0, sizeof(s));
s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
s.iotype = SERIAL_IO_MEM;
s.regshift = 2;
s.uartclk = JZ_EXTAL;
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;
soc_cpm_setup();
jz_serial_setup();
}

View File

@ -1,263 +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>
#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_clocksource_counter;
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);
writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
}
static void jz4740_timer_disable(unsigned int timer)
{
writel(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;
struct clk *ext_clk;
jz4740_timer_base = ioremap(CPHYSADDR(TCU_BASE), 0x100);
if (!jz4740_timer_base) {
printk(KERN_ERR "Failed to ioremap timer registers");
return;
}
/*ext_clk = clk_get(NULL, "ext");
clk_rate = clk_get_rate(ext_clk) >> 4;
clk_put(ext_clk);*/
clk_rate = JZ_EXTAL >> 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,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,362 +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/jz4740-adc.h>
#define JZ_REG_ADC_ENABLE 0x00
#define JZ_REG_ADC_CFG 0x04
#define JZ_REG_ADC_CTRL 0x08
#define JZ_REG_ADC_STATUS 0x0C
#define JZ_REG_ADC_SAME 0x10
#define JZ_REG_ADC_WAIT 0x14
#define JZ_REG_ADC_TOUCH 0x18
#define JZ_REG_ADC_BATTERY 0x1C
#define JZ_REG_ADC_ADCIN 0x20
#define JZ_ADC_ENABLE_TOUCH BIT(2)
#define JZ_ADC_ENABLE_BATTERY BIT(1)
#define JZ_ADC_ENABLE_ADCIN BIT(0)
#define JZ_ADC_CFG_SPZZ BIT(31)
#define JZ_ADC_CFG_EX_IN BIT(30)
#define JZ_ADC_CFG_DNUM_MASK (0x7 << 16)
#define JZ_ADC_CFG_DMA_ENABLE BIT(15)
#define JZ_ADC_CFG_XYZ_MASK (0x2 << 13)
#define JZ_ADC_CFG_SAMPLE_NUM_MASK (0x7 << 10)
#define JZ_ADC_CFG_CLKDIV (0xf << 5)
#define JZ_ADC_CFG_BAT_MB BIT(4)
#define JZ_ADC_CFG_DNUM_OFFSET 16
#define JZ_ADC_CFG_XYZ_OFFSET 13
#define JZ_ADC_CFG_SAMPLE_NUM_OFFSET 10
#define JZ_ADC_CFG_CLKDIV_OFFSET 5
#define JZ_ADC_IRQ_PENDOWN BIT(4)
#define JZ_ADC_IRQ_PENUP BIT(3)
#define JZ_ADC_IRQ_TOUCH BIT(2)
#define JZ_ADC_IRQ_BATTERY BIT(1)
#define JZ_ADC_IRQ_ADCIN BIT(0)
#define JZ_ADC_TOUCH_TYPE1 BIT(31)
#define JZ_ADC_TOUCH_DATA1_MASK 0xfff
#define JZ_ADC_TOUCH_TYPE0 BIT(15)
#define JZ_ADC_TOUCH_DATA0_MASK 0xfff
#define JZ_ADC_BATTERY_MASK 0xfff
#define JZ_ADC_ADCIN_MASK 0xfff
struct jz4740_adc {
struct resource *mem;
void __iomem *base;
int irq;
struct completion bat_completion;
struct completion adc_completion;
spinlock_t lock;
};
static irqreturn_t jz4740_adc_irq(int irq, void *data)
{
struct jz4740_adc *adc = data;
uint8_t status;
status = readb(adc->base + JZ_REG_ADC_STATUS);
if (status & JZ_ADC_IRQ_BATTERY)
complete(&adc->bat_completion);
if (status & JZ_ADC_IRQ_ADCIN)
complete(&adc->adc_completion);
writeb(0xff, adc->base + JZ_REG_ADC_STATUS);
return IRQ_HANDLED;
}
static void jz4740_adc_enable_irq(struct jz4740_adc *adc, int irq)
{
unsigned long flags;
uint8_t val;
spin_lock_irqsave(&adc->lock, flags);
val = readb(adc->base + JZ_REG_ADC_CTRL);
val &= ~irq;
writeb(val, adc->base + JZ_REG_ADC_CTRL);
spin_unlock_irqrestore(&adc->lock, flags);
}
static void jz4740_adc_disable_irq(struct jz4740_adc *adc, int irq)
{
unsigned long flags;
uint8_t val;
spin_lock_irqsave(&adc->lock, flags);
val = readb(adc->base + JZ_REG_ADC_CTRL);
val |= irq;
writeb(val, adc->base + JZ_REG_ADC_CTRL);
spin_unlock_irqrestore(&adc->lock, flags);
}
static void jz4740_adc_enable_adc(struct jz4740_adc *adc, int engine)
{
unsigned long flags;
uint8_t val;
spin_lock_irqsave(&adc->lock, flags);
val = readb(adc->base + JZ_REG_ADC_ENABLE);
val |= engine;
writeb(val, adc->base + JZ_REG_ADC_ENABLE);
spin_unlock_irqrestore(&adc->lock, flags);
}
static void jz4740_adc_disable_adc(struct jz4740_adc *adc, int engine)
{
unsigned long flags;
uint8_t val;
spin_lock_irqsave(&adc->lock, flags);
val = readb(adc->base + JZ_REG_ADC_ENABLE);
val &= ~engine;
writeb(val, adc->base + JZ_REG_ADC_ENABLE);
spin_unlock_irqrestore(&adc->lock, flags);
}
static inline void jz4740_adc_set_cfg(struct jz4740_adc *adc, uint32_t mask,
uint32_t val)
{
unsigned long flags;
uint32_t cfg;
spin_lock_irqsave(&adc->lock, flags);
cfg = readl(adc->base + JZ_REG_ADC_CFG);
cfg &= ~mask;
cfg |= val;
writel(cfg, adc->base + JZ_REG_ADC_CFG);
spin_unlock_irqrestore(&adc->lock, flags);
}
long jz4740_adc_read_battery_voltage(struct device *dev,
enum jz_adc_battery_scale scale)
{
struct jz4740_adc *adc = dev_get_drvdata(dev);
unsigned long t;
long long voltage;
uint16_t val;
if (!adc)
return -ENODEV;
if (scale == JZ_ADC_BATTERY_SCALE_2V5)
jz4740_adc_set_cfg(adc, JZ_ADC_CFG_BAT_MB, JZ_ADC_CFG_BAT_MB);
else
jz4740_adc_set_cfg(adc, JZ_ADC_CFG_BAT_MB, 0);
jz4740_adc_enable_irq(adc, JZ_ADC_IRQ_BATTERY);
jz4740_adc_enable_adc(adc, JZ_ADC_ENABLE_BATTERY);
t = wait_for_completion_interruptible_timeout(&adc->bat_completion,
HZ);
jz4740_adc_disable_irq(adc, JZ_ADC_IRQ_BATTERY);
if (t <= 0) {
jz4740_adc_disable_adc(adc, JZ_ADC_ENABLE_BATTERY);
return t ? t : -ETIMEDOUT;
}
val = readw(adc->base + JZ_REG_ADC_BATTERY);
if (scale == JZ_ADC_BATTERY_SCALE_2V5)
voltage = (((long long)val) * 2500000LL) >> 12LL;
else
voltage = ((((long long)val) * 7395000LL) >> 12LL) + 33000LL;
return voltage;
}
EXPORT_SYMBOL_GPL(jz4740_adc_read_battery_voltage);
static ssize_t jz4740_adc_read_adcin(struct device *dev,
struct device_attribute *dev_attr,
char *buf)
{
struct jz4740_adc *adc = dev_get_drvdata(dev);
unsigned long t;
uint16_t val;
jz4740_adc_enable_irq(adc, JZ_ADC_IRQ_ADCIN);
jz4740_adc_enable_adc(adc, JZ_ADC_ENABLE_ADCIN);
t = wait_for_completion_interruptible_timeout(&adc->adc_completion,
HZ);
jz4740_adc_disable_irq(adc, JZ_ADC_IRQ_ADCIN);
if (t <= 0) {
jz4740_adc_disable_adc(adc, JZ_ADC_ENABLE_ADCIN);
return t ? t : -ETIMEDOUT;
}
val = readw(adc->base + JZ_REG_ADC_ADCIN);
return sprintf(buf, "%d\n", val);
}
static DEVICE_ATTR(adcin, S_IRUGO, jz4740_adc_read_adcin, NULL);
static int __devinit jz4740_adc_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_adc *adc;
adc = kmalloc(sizeof(*adc), GFP_KERNEL);
adc->irq = platform_get_irq(pdev, 0);
if (adc->irq < 0) {
ret = adc->irq;
dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
goto err_free;
}
adc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!adc->mem) {
ret = -ENOENT;
dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
goto err_free;
}
adc->mem = request_mem_region(adc->mem->start, resource_size(adc->mem),
pdev->name);
if (!adc->mem) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
goto err_free;
}
adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem));
if (!adc->base) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
goto err_release_mem_region;
}
init_completion(&adc->bat_completion);
init_completion(&adc->adc_completion);
spin_lock_init(&adc->lock);
platform_set_drvdata(pdev, adc);
ret = request_irq(adc->irq, jz4740_adc_irq, 0, pdev->name, adc);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
goto err_iounmap;
}
ret = device_create_file(&pdev->dev, &dev_attr_adcin);
if (ret) {
dev_err(&pdev->dev, "Failed to create sysfs file: %d\n", ret);
goto err_free_irq;
}
writeb(0x00, adc->base + JZ_REG_ADC_ENABLE);
writeb(0xff, adc->base + JZ_REG_ADC_CTRL);
return 0;
err_free_irq:
free_irq(adc->irq, adc);
err_iounmap:
platform_set_drvdata(pdev, NULL);
iounmap(adc->base);
err_release_mem_region:
release_mem_region(adc->mem->start, resource_size(adc->mem));
err_free:
kfree(adc);
return ret;
}
static int __devexit jz4740_adc_remove(struct platform_device *pdev)
{
struct jz4740_adc *adc = platform_get_drvdata(pdev);
device_remove_file(&pdev->dev, &dev_attr_adcin);
free_irq(adc->irq, adc);
iounmap(adc->base);
release_mem_region(adc->mem->start, resource_size(adc->mem));
platform_set_drvdata(pdev, NULL);
kfree(adc);
return 0;
}
struct platform_driver jz4740_adc_driver = {
.probe = jz4740_adc_probe,
.remove = jz4740_adc_remove,
.driver = {
.name = "jz4740-adc",
.owner = THIS_MODULE,
},
};
static int __init jz4740_adc_init(void)
{
return platform_driver_register(&jz4740_adc_driver);
}
module_init(jz4740_adc_init);
static void __exit jz4740_adc_exit(void)
{
platform_driver_unregister(&jz4740_adc_driver);
}
module_exit(jz4740_adc_exit);
MODULE_DESCRIPTION("JZ4720/JZ4740 SoC ADC driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:jz4740-adc");
MODULE_ALIAS("platform:jz4720-adc");

View File

@ -1,955 +0,0 @@
/*
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
* JZ7420/JZ4740 GPIO SD/MMC 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/mmc/host.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/scatterlist.h>
#include <linux/clk.h>
#include <linux/mmc/jz4740_mmc.h>
#include <linux/gpio.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
#define JZ_REG_MMC_STRPCL 0x00
#define JZ_REG_MMC_STATUS 0x04
#define JZ_REG_MMC_CLKRT 0x08
#define JZ_REG_MMC_CMDAT 0x0C
#define JZ_REG_MMC_RESTO 0x10
#define JZ_REG_MMC_RDTO 0x14
#define JZ_REG_MMC_BLKLEN 0x18
#define JZ_REG_MMC_NOB 0x1C
#define JZ_REG_MMC_SNOB 0x20
#define JZ_REG_MMC_IMASK 0x24
#define JZ_REG_MMC_IREG 0x28
#define JZ_REG_MMC_CMD 0x2C
#define JZ_REG_MMC_ARG 0x30
#define JZ_REG_MMC_RESP_FIFO 0x34
#define JZ_REG_MMC_RXFIFO 0x38
#define JZ_REG_MMC_TXFIFO 0x3C
#define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7)
#define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6)
#define JZ_MMC_STRPCL_START_READWAIT BIT(5)
#define JZ_MMC_STRPCL_STOP_READWAIT BIT(4)
#define JZ_MMC_STRPCL_RESET BIT(3)
#define JZ_MMC_STRPCL_START_OP BIT(2)
#define JZ_MMC_STRPCL_CLOCK_CONTROL BIT(1) | BIT(0)
#define JZ_MMC_STRPCL_CLOCK_STOP BIT(0)
#define JZ_MMC_STRPCL_CLOCK_START BIT(1)
#define JZ_MMC_STATUS_IS_RESETTING BIT(15)
#define JZ_MMC_STATUS_SDIO_INT_ACTIVE BIT(14)
#define JZ_MMC_STATUS_PRG_DONE BIT(13)
#define JZ_MMC_STATUS_DATA_TRAN_DONE BIT(12)
#define JZ_MMC_STATUS_END_CMD_RES BIT(11)
#define JZ_MMC_STATUS_DATA_FIFO_AFULL BIT(10)
#define JZ_MMC_STATUS_IS_READWAIT BIT(9)
#define JZ_MMC_STATUS_CLK_EN BIT(8)
#define JZ_MMC_STATUS_DATA_FIFO_FULL BIT(7)
#define JZ_MMC_STATUS_DATA_FIFO_EMPTY BIT(6)
#define JZ_MMC_STATUS_CRC_RES_ERR BIT(5)
#define JZ_MMC_STATUS_CRC_READ_ERROR BIT(4)
#define JZ_MMC_STATUS_TIMEOUT_WRITE BIT(3)
#define JZ_MMC_STATUS_CRC_WRITE_ERROR BIT(2)
#define JZ_MMC_STATUS_TIMEOUT_RES BIT(1)
#define JZ_MMC_STATUS_TIMEOUT_READ BIT(0)
#define JZ_MMC_STATUS_READ_ERROR_MASK (BIT(4) | BIT(0))
#define JZ_MMC_STATUS_WRITE_ERROR_MASK (BIT(3) | BIT(2))
#define JZ_MMC_CMDAT_IO_ABORT BIT(11)
#define JZ_MMC_CMDAT_BUS_WIDTH_4BIT BIT(10)
#define JZ_MMC_CMDAT_DMA_EN BIT(8)
#define JZ_MMC_CMDAT_INIT BIT(7)
#define JZ_MMC_CMDAT_BUSY BIT(6)
#define JZ_MMC_CMDAT_STREAM BIT(5)
#define JZ_MMC_CMDAT_WRITE BIT(4)
#define JZ_MMC_CMDAT_DATA_EN BIT(3)
#define JZ_MMC_CMDAT_RESPONSE_FORMAT BIT(2) | BIT(1) | BIT(0)
#define JZ_MMC_CMDAT_RSP_R1 1
#define JZ_MMC_CMDAT_RSP_R2 2
#define JZ_MMC_CMDAT_RSP_R3 3
#define JZ_MMC_IRQ_SDIO BIT(7)
#define JZ_MMC_IRQ_TXFIFO_WR_REQ BIT(6)
#define JZ_MMC_IRQ_RXFIFO_RD_REQ BIT(5)
#define JZ_MMC_IRQ_END_CMD_RES BIT(2)
#define JZ_MMC_IRQ_PRG_DONE BIT(1)
#define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0)
#define JZ_MMC_CLK_RATE 24000000
struct jz4740_mmc_host {
struct mmc_host *mmc;
struct platform_device *pdev;
struct jz4740_mmc_platform_data *pdata;
struct clk *clk;
int irq;
int card_detect_irq;
struct resource *mem;
void __iomem *base;
struct mmc_request *req;
struct mmc_command *cmd;
int max_clock;
uint32_t cmdat;
uint16_t irq_mask;
spinlock_t lock;
struct timer_list clock_timer;
struct timer_list timeout_timer;
unsigned waiting:1;
};
static void jz4740_mmc_cmd_done(struct jz4740_mmc_host *host);
static void jz4740_mmc_enable_irq(struct jz4740_mmc_host *host, unsigned int irq)
{
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
host->irq_mask &= ~irq;
writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
spin_unlock_irqrestore(&host->lock, flags);
}
static void jz4740_mmc_disable_irq(struct jz4740_mmc_host *host, unsigned int irq)
{
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
host->irq_mask |= irq;
writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
spin_unlock_irqrestore(&host->lock, flags);
}
static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host, bool start_transfer)
{
uint16_t val = JZ_MMC_STRPCL_CLOCK_START;
if (start_transfer)
val |= JZ_MMC_STRPCL_START_OP;
writew(val, host->base + JZ_REG_MMC_STRPCL);
}
static void jz4740_mmc_clock_disable(struct jz4740_mmc_host *host)
{
uint16_t status;
writew(JZ_MMC_STRPCL_CLOCK_STOP, host->base + JZ_REG_MMC_STRPCL);
do {
status = readl(host->base + JZ_REG_MMC_STATUS);
} while (status & JZ_MMC_STATUS_CLK_EN);
}
static void jz4740_mmc_reset(struct jz4740_mmc_host *host)
{
writew(JZ_MMC_STRPCL_RESET, host->base + JZ_REG_MMC_STRPCL);
udelay(10);
while(readw(host->base + JZ_REG_MMC_STATUS) & JZ_MMC_STATUS_IS_RESETTING);
}
static void jz4740_mmc_request_done(struct jz4740_mmc_host *host)
{
struct mmc_request *req;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
req = host->req;
host->req = NULL;
host->waiting = 0;
spin_unlock_irqrestore(&host->lock, flags);
if (!unlikely(req))
return;
/* if (req->cmd->error != 0) {
printk("error\n");
jz4740_mmc_reset(host);
}*/
mmc_request_done(host->mmc, req);
}
static void jz4740_mmc_write_data(struct jz4740_mmc_host *host, struct mmc_data *data) {
struct scatterlist *sg;
uint32_t *sg_pointer;
int status;
size_t i, j;
for (sg = data->sg; sg; sg = sg_next(sg)) {
sg_pointer = sg_virt(sg);
i = sg->length / 4;
j = i >> 3;
i = i & 0x7;
while (j) {
do {
status = readw(host->base + JZ_REG_MMC_IREG);
} while (!(status & JZ_MMC_IRQ_TXFIFO_WR_REQ));
writew(JZ_MMC_IRQ_TXFIFO_WR_REQ, host->base + JZ_REG_MMC_IREG);
writel(sg_pointer[0], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[1], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[2], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[3], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[4], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[5], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[6], host->base + JZ_REG_MMC_TXFIFO);
writel(sg_pointer[7], host->base + JZ_REG_MMC_TXFIFO);
sg_pointer += 8;
--j;
}
if (i) {
do {
status = readw(host->base + JZ_REG_MMC_IREG);
} while (!(status & JZ_MMC_IRQ_TXFIFO_WR_REQ));
writew(JZ_MMC_IRQ_TXFIFO_WR_REQ, host->base + JZ_REG_MMC_IREG);
while (i) {
writel(*sg_pointer, host->base + JZ_REG_MMC_TXFIFO);
++sg_pointer;
--i;
}
}
data->bytes_xfered += sg->length;
}
status = readl(host->base + JZ_REG_MMC_STATUS);
if (status & JZ_MMC_STATUS_WRITE_ERROR_MASK)
goto err;
writew(JZ_MMC_IRQ_TXFIFO_WR_REQ, host->base + JZ_REG_MMC_IREG);
do {
status = readl(host->base + JZ_REG_MMC_STATUS);
} while ((status & JZ_MMC_STATUS_DATA_TRAN_DONE) == 0);
writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG);
return;
err:
if(status & (JZ_MMC_STATUS_TIMEOUT_WRITE)) {
host->req->cmd->error = -ETIMEDOUT;
data->error = -ETIMEDOUT;
} else {
host->req->cmd->error = -EILSEQ;
data->error = -EILSEQ;
}
}
static void jz4740_mmc_timeout(unsigned long data)
{
struct jz4740_mmc_host *host = (struct jz4740_mmc_host*)data;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
if (!host->waiting) {
spin_unlock_irqrestore(&host->lock, flags);
return;
}
host->waiting = 0;
spin_unlock_irqrestore(&host->lock, flags);
host->req->cmd->error = -ETIMEDOUT;
jz4740_mmc_request_done(host);
}
static void jz4740_mmc_read_data(struct jz4740_mmc_host *host, struct mmc_data *data) {
struct scatterlist *sg;
uint32_t *sg_pointer;
uint32_t d;
uint16_t status = 0;
size_t i, j;
for (sg = data->sg; sg; sg = sg_next(sg)) {
sg_pointer = sg_virt(sg);
i = sg->length;
j = i >> 5;
i = i & 0x1f;
while (j) {
do {
status = readw(host->base + JZ_REG_MMC_IREG);
} while (!(status & JZ_MMC_IRQ_RXFIFO_RD_REQ));
writew(JZ_MMC_IRQ_RXFIFO_RD_REQ, host->base + JZ_REG_MMC_IREG);
sg_pointer[0] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[1] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[2] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[3] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[4] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[5] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[6] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer[7] = readl(host->base + JZ_REG_MMC_RXFIFO);
sg_pointer += 8;
--j;
}
while (i >= 4) {
do {
status = readl(host->base + JZ_REG_MMC_STATUS);
} while ((status & JZ_MMC_STATUS_DATA_FIFO_EMPTY));
*sg_pointer = readl(host->base + JZ_REG_MMC_RXFIFO);
++sg_pointer;
i -= 4;
}
if (i > 0) {
d = readl(host->base + JZ_REG_MMC_RXFIFO);
memcpy(sg_pointer, &d, i);
}
data->bytes_xfered += sg->length;
flush_dcache_page(sg_page(sg));
}
status = readl(host->base + JZ_REG_MMC_STATUS);
if (status & JZ_MMC_STATUS_READ_ERROR_MASK)
goto err;
/* For whatever reason there is sometime one word more in the fifo then
* requested */
while ((status & JZ_MMC_STATUS_DATA_FIFO_EMPTY) == 0) {
d = readl(host->base + JZ_REG_MMC_RXFIFO);
status = readl(host->base + JZ_REG_MMC_STATUS);
}
return;
err:
if(status & JZ_MMC_STATUS_TIMEOUT_READ) {
host->req->cmd->error = -ETIMEDOUT;
data->error = -ETIMEDOUT;
} else {
host->req->cmd->error = -EILSEQ;
data->error = -EILSEQ;
}
}
static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
{
struct jz4740_mmc_host *host = (struct jz4740_mmc_host*)devid;
if (host->cmd->error)
jz4740_mmc_request_done(host);
else
jz4740_mmc_cmd_done(host);
return IRQ_HANDLED;
}
static irqreturn_t jz_mmc_irq(int irq, void *devid)
{
struct jz4740_mmc_host *host = devid;
uint16_t irq_reg, status, tmp;
unsigned long flags;
irqreturn_t ret = IRQ_HANDLED;
irq_reg = readw(host->base + JZ_REG_MMC_IREG);
tmp = irq_reg;
spin_lock(&host->lock);
irq_reg &= ~host->irq_mask;
spin_unlock(&host->lock);
if (irq_reg & JZ_MMC_IRQ_SDIO) {
writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG);
mmc_signal_sdio_irq(host->mmc);
}
if (!host->req || !host->cmd) {
goto handled;
}
spin_lock_irqsave(&host->lock, flags);
if (!host->waiting) {
spin_unlock_irqrestore(&host->lock, flags);
goto handled;
}
host->waiting = 0;
spin_unlock_irqrestore(&host->lock, flags);
del_timer(&host->timeout_timer);
status = readl(host->base + JZ_REG_MMC_STATUS);
if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
host->cmd->error = -ETIMEDOUT;
} else if (status & JZ_MMC_STATUS_CRC_RES_ERR) {
host->cmd->error = -EIO;
} else if(status & (JZ_MMC_STATUS_CRC_READ_ERROR |
JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
host->cmd->data->error = -EIO;
} else if(status & (JZ_MMC_STATUS_CRC_READ_ERROR |
JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
host->cmd->data->error = -EIO;
}
if (irq_reg & JZ_MMC_IRQ_END_CMD_RES) {
jz4740_mmc_disable_irq(host, JZ_MMC_IRQ_END_CMD_RES);
writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
ret = IRQ_WAKE_THREAD;
}
return ret;
handled:
writew(0xff, host->base + JZ_REG_MMC_IREG);
return IRQ_HANDLED;
}
static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate) {
int div = 0;
int real_rate = host->max_clock;
jz4740_mmc_clock_disable(host);
while ((real_rate >> 1) >= rate && div < 7) {
++div;
real_rate >>= 1;
}
clk_set_rate(host->clk, JZ_MMC_CLK_RATE);
writew(div, host->base + JZ_REG_MMC_CLKRT);
return real_rate;
}
static void jz4740_mmc_read_response(struct jz4740_mmc_host *host, struct mmc_command *cmd)
{
int i;
uint16_t tmp;
if (cmd->flags & MMC_RSP_136) {
tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO);
for (i = 0; i < 4; ++i) {
cmd->resp[i] = tmp << 24;
cmd->resp[i] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) << 8;
tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO);
cmd->resp[i] |= tmp >> 8;
}
} else {
cmd->resp[0] = readw(host->base + JZ_REG_MMC_RESP_FIFO) << 24;
cmd->resp[0] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) << 8;
cmd->resp[0] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) & 0xff;
}
}
static void jz4740_mmc_send_command(struct jz4740_mmc_host *host, struct mmc_command *cmd)
{
uint32_t cmdat = host->cmdat;
host->cmdat &= ~JZ_MMC_CMDAT_INIT;
jz4740_mmc_clock_disable(host);
host->cmd = cmd;
if (cmd->flags & MMC_RSP_BUSY)
cmdat |= JZ_MMC_CMDAT_BUSY;
switch (mmc_resp_type(cmd)) {
case MMC_RSP_R1B:
case MMC_RSP_R1:
cmdat |= JZ_MMC_CMDAT_RSP_R1;
break;
case MMC_RSP_R2:
cmdat |= JZ_MMC_CMDAT_RSP_R2;
break;
case MMC_RSP_R3:
cmdat |= JZ_MMC_CMDAT_RSP_R3;
break;
default:
break;
}
if (cmd->data) {
cmdat |= JZ_MMC_CMDAT_DATA_EN;
if (cmd->data->flags & MMC_DATA_WRITE)
cmdat |= JZ_MMC_CMDAT_WRITE;
if (cmd->data->flags & MMC_DATA_STREAM)
cmdat |= JZ_MMC_CMDAT_STREAM;
writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN);
writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB);
}
writeb(cmd->opcode, host->base + JZ_REG_MMC_CMD);
writel(cmd->arg, host->base + JZ_REG_MMC_ARG);
writel(cmdat, host->base + JZ_REG_MMC_CMDAT);
host->waiting = 1;
jz4740_mmc_clock_enable(host, 1);
mod_timer(&host->timeout_timer, 4*HZ);
}
static void jz4740_mmc_cmd_done(struct jz4740_mmc_host *host)
{
uint32_t status;
struct mmc_command *cmd = host->req->cmd;
struct mmc_request *req = host->req;
status = readl(host->base + JZ_REG_MMC_STATUS);
if (cmd->flags & MMC_RSP_PRESENT)
jz4740_mmc_read_response(host, cmd);
if (cmd->data) {
if (cmd->data->flags & MMC_DATA_READ)
jz4740_mmc_read_data(host, cmd->data);
else
jz4740_mmc_write_data(host, cmd->data);
}
if (req->stop) {
jz4740_mmc_send_command(host, req->stop);
do {
status = readl(host->base + JZ_REG_MMC_STATUS);
} while ((status & JZ_MMC_STATUS_PRG_DONE) == 0);
writew(JZ_MMC_IRQ_PRG_DONE, host->base + JZ_REG_MMC_IREG);
}
jz4740_mmc_request_done(host);
}
static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
{
struct jz4740_mmc_host *host = mmc_priv(mmc);
host->req = req;
writew(0xffff, host->base + JZ_REG_MMC_IREG);
writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
jz4740_mmc_enable_irq(host, JZ_MMC_IRQ_END_CMD_RES);
jz4740_mmc_send_command(host, req->cmd);
}
static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct jz4740_mmc_host *host = mmc_priv(mmc);
if (ios->clock)
jz4740_mmc_set_clock_rate(host, ios->clock);
switch(ios->power_mode) {
case MMC_POWER_UP:
if (gpio_is_valid(host->pdata->gpio_power))
gpio_set_value(host->pdata->gpio_power,
!host->pdata->power_active_low);
host->cmdat |= JZ_MMC_CMDAT_INIT;
clk_enable(host->clk);
break;
case MMC_POWER_ON:
break;
default:
if (gpio_is_valid(host->pdata->gpio_power))
gpio_set_value(host->pdata->gpio_power,
host->pdata->power_active_low);
clk_disable(host->clk);
break;
}
switch(ios->bus_width) {
case MMC_BUS_WIDTH_1:
host->cmdat &= ~JZ_MMC_CMDAT_BUS_WIDTH_4BIT;
break;
case MMC_BUS_WIDTH_4:
host->cmdat |= JZ_MMC_CMDAT_BUS_WIDTH_4BIT;
break;
default:
dev_err(&host->pdev->dev, "Invalid bus width: %d\n", ios->bus_width);
}
}
static int jz4740_mmc_get_ro(struct mmc_host *mmc)
{
struct jz4740_mmc_host *host = mmc_priv(mmc);
if (!gpio_is_valid(host->pdata->gpio_read_only))
return -ENOSYS;
return gpio_get_value(host->pdata->gpio_read_only) ^
host->pdata->read_only_active_low;
}
static int jz4740_mmc_get_cd(struct mmc_host *mmc)
{
struct jz4740_mmc_host *host = mmc_priv(mmc);
if (!gpio_is_valid(host->pdata->gpio_card_detect))
return -ENOSYS;
return gpio_get_value(host->pdata->gpio_card_detect) ^
host->pdata->card_detect_active_low;
}
static irqreturn_t jz4740_mmc_card_detect_irq(int irq, void *devid)
{
struct jz4740_mmc_host *host = devid;
mmc_detect_change(host->mmc, HZ / 3);
return IRQ_HANDLED;
}
static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct jz4740_mmc_host *host = mmc_priv(mmc);
if (enable)
jz4740_mmc_enable_irq(host, JZ_MMC_IRQ_SDIO);
else
jz4740_mmc_disable_irq(host, JZ_MMC_IRQ_SDIO);
}
static const struct mmc_host_ops jz4740_mmc_ops = {
.request = jz4740_mmc_request,
.set_ios = jz4740_mmc_set_ios,
.get_ro = jz4740_mmc_get_ro,
.get_cd = jz4740_mmc_get_cd,
.enable_sdio_irq = jz4740_mmc_enable_sdio_irq,
};
static const struct jz_gpio_bulk_request jz4740_mmc_pins[] = {
JZ_GPIO_BULK_PIN(MSC_CMD),
JZ_GPIO_BULK_PIN(MSC_CLK),
JZ_GPIO_BULK_PIN(MSC_DATA0),
JZ_GPIO_BULK_PIN(MSC_DATA1),
JZ_GPIO_BULK_PIN(MSC_DATA2),
JZ_GPIO_BULK_PIN(MSC_DATA3),
};
static int __devinit jz4740_mmc_request_gpios(struct platform_device *pdev)
{
int ret;
struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
if (!pdata)
return 0;
if (gpio_is_valid(pdata->gpio_card_detect)) {
ret = gpio_request(pdata->gpio_card_detect, "MMC detect change");
if (ret) {
dev_err(&pdev->dev, "Failed to request detect change gpio\n");
goto err;
}
gpio_direction_input(pdata->gpio_card_detect);
}
if (gpio_is_valid(pdata->gpio_read_only)) {
ret = gpio_request(pdata->gpio_read_only, "MMC read only");
if (ret) {
dev_err(&pdev->dev, "Failed to request read only gpio: %d\n", ret);
goto err_free_gpio_card_detect;
}
gpio_direction_input(pdata->gpio_read_only);
}
if (gpio_is_valid(pdata->gpio_power)) {
ret = gpio_request(pdata->gpio_power, "MMC power");
if (ret) {
dev_err(&pdev->dev, "Failed to request power gpio: %d\n", ret);
goto err_free_gpio_read_only;
}
gpio_direction_output(pdata->gpio_power, pdata->power_active_low);
}
return 0;
err_free_gpio_read_only:
if (gpio_is_valid(pdata->gpio_read_only))
gpio_free(pdata->gpio_read_only);
err_free_gpio_card_detect:
if (gpio_is_valid(pdata->gpio_card_detect))
gpio_free(pdata->gpio_card_detect);
err:
return ret;
}
static void jz4740_mmc_free_gpios(struct platform_device *pdev)
{
struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
if (!pdata)
return;
if (gpio_is_valid(pdata->gpio_power))
gpio_free(pdata->gpio_power);
if (gpio_is_valid(pdata->gpio_read_only))
gpio_free(pdata->gpio_read_only);
if (gpio_is_valid(pdata->gpio_card_detect))
gpio_free(pdata->gpio_card_detect);
}
static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
{
int ret;
struct mmc_host *mmc;
struct jz4740_mmc_host *host;
struct jz4740_mmc_platform_data *pdata;
pdata = pdev->dev.platform_data;
mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev);
if (!mmc) {
dev_err(&pdev->dev, "Failed to alloc mmc host structure\n");
return -ENOMEM;
}
host = mmc_priv(mmc);
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0) {
ret = host->irq;
dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
goto err_free_host;
}
host->clk = clk_get(&pdev->dev, "mmc");
if (!host->clk) {
ret = -ENOENT;
dev_err(&pdev->dev, "Failed to get mmc clock\n");
goto err_free_host;
}
host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!host->mem) {
ret = -ENOENT;
dev_err(&pdev->dev, "Failed to get base platform memory\n");
goto err_clk_put;
}
host->mem = request_mem_region(host->mem->start, resource_size(host->mem),
pdev->name);
if (!host->mem) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to request base memory region\n");
goto err_clk_put;
}
host->base = ioremap_nocache(host->mem->start, resource_size(host->mem));
if (!host->base) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to ioremap base memory\n");
goto err_release_mem_region;
}
if (pdata && pdata->data_1bit)
ret = jz_gpio_bulk_request(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3);
else
ret = jz_gpio_bulk_request(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins));
if (ret) {
dev_err(&pdev->dev, "Failed to request function pins: %d\n", ret);
goto err_iounmap;
}
ret = jz4740_mmc_request_gpios(pdev);
if (ret)
goto err_gpio_bulk_free;
mmc->ops = &jz4740_mmc_ops;
mmc->f_min = JZ_MMC_CLK_RATE / 128;
mmc->f_max = JZ_MMC_CLK_RATE;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
mmc->caps = (pdata && pdata->data_1bit) ? 0 : MMC_CAP_4_BIT_DATA;
mmc->caps |= MMC_CAP_SDIO_IRQ;
mmc->max_seg_size = 4096;
mmc->max_phys_segs = 128;
mmc->max_blk_size = (1 << 10) - 1;
mmc->max_blk_count = (1 << 15) - 1;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
host->mmc = mmc;
host->pdev = pdev;
host->pdata = pdata;
host->max_clock = JZ_MMC_CLK_RATE;
spin_lock_init(&host->lock);
host->irq_mask = 0xffff;
host->card_detect_irq = gpio_to_irq(pdata->gpio_card_detect);
if (host->card_detect_irq < 0) {
dev_warn(&pdev->dev, "Failed to get irq for card detect gpio\n");
} else {
ret = request_irq(host->card_detect_irq,
jz4740_mmc_card_detect_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC/SD detect changed", host);
if (ret) {
dev_err(&pdev->dev, "Failed to request card detect irq");
goto err_free_gpios;
}
}
ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, IRQF_DISABLED, "MMC/SD", host);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
goto err_free_card_detect_irq;
}
jz4740_mmc_reset(host);
jz4740_mmc_clock_disable(host);
setup_timer(&host->timeout_timer, jz4740_mmc_timeout, (unsigned long)host);
platform_set_drvdata(pdev, host);
ret = mmc_add_host(mmc);
if (ret) {
dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret);
goto err_free_irq;
}
printk("JZ SD/MMC card driver registered\n");
return 0;
err_free_irq:
free_irq(host->irq, host);
err_free_card_detect_irq:
if (host->card_detect_irq >= 0)
free_irq(host->card_detect_irq, host);
err_free_gpios:
jz4740_mmc_free_gpios(pdev);
err_gpio_bulk_free:
if (pdata && pdata->data_1bit)
jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3);
else
jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins));
err_iounmap:
iounmap(host->base);
err_release_mem_region:
release_mem_region(host->mem->start, resource_size(host->mem));
err_clk_put:
clk_put(host->clk);
err_free_host:
platform_set_drvdata(pdev, NULL);
mmc_free_host(mmc);
return ret;
}
static int jz4740_mmc_remove(struct platform_device *pdev)
{
struct jz4740_mmc_host *host = platform_get_drvdata(pdev);
struct jz4740_mmc_platform_data *pdata = host->pdata;
del_timer_sync(&host->timeout_timer);
jz4740_mmc_disable_irq(host, 0xff);
jz4740_mmc_reset(host);
mmc_remove_host(host->mmc);
free_irq(host->irq, host);
if (host->card_detect_irq >= 0)
free_irq(host->card_detect_irq, host);
jz4740_mmc_free_gpios(pdev);
if (pdata && pdata->data_1bit)
jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3);
else
jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins));
iounmap(host->base);
release_mem_region(host->mem->start, resource_size(host->mem));
clk_put(host->clk);
platform_set_drvdata(pdev, NULL);
mmc_free_host(host->mmc);
return 0;
}
#ifdef CONFIG_PM
static int jz4740_mmc_suspend(struct device *dev)
{
struct jz4740_mmc_host *host = dev_get_drvdata(dev);
struct jz4740_mmc_platform_data *pdata = host->pdata;
mmc_suspend_host(host->mmc, PMSG_SUSPEND);
if (pdata && pdata->data_1bit)
jz_gpio_bulk_suspend(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3);
else
jz_gpio_bulk_suspend(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins));
return 0;
}
static int jz4740_mmc_resume(struct device *dev)
{
struct jz4740_mmc_host *host = dev_get_drvdata(dev);
struct jz4740_mmc_platform_data *pdata = host->pdata;
if (pdata && pdata->data_1bit)
jz_gpio_bulk_resume(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3);
else
jz_gpio_bulk_resume(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins));
mmc_resume_host(host->mmc);
return 0;
}
struct dev_pm_ops jz4740_mmc_pm_ops = {
.suspend = jz4740_mmc_suspend,
.resume = jz4740_mmc_resume,
.poweroff = jz4740_mmc_suspend,
.restore = jz4740_mmc_resume,
};
#define jz4740_mmc_PM_OPS (&jz4740_mmc_pm_ops)
#else
#define jz4740_mmc_PM_OPS NULL
#endif
static struct platform_driver jz4740_mmc_driver = {
.probe = jz4740_mmc_probe,
.remove = jz4740_mmc_remove,
.driver = {
.name = "jz4740-mmc",
.owner = THIS_MODULE,
.pm = jz4740_mmc_PM_OPS,
},
};
static int __init jz4740_mmc_init(void) {
return platform_driver_register(&jz4740_mmc_driver);
}
module_init(jz4740_mmc_init);
static void __exit jz4740_mmc_exit(void) {
platform_driver_unregister(&jz4740_mmc_driver);
}
module_exit(jz4740_mmc_exit);
MODULE_DESCRIPTION("JZ4720/JZ4740 SD/MMC controller driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");

View File

@ -1,418 +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;
};
static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd)
{
return container_of(mtd, struct jz_nand, mtd);
}
static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
struct jz_nand *nand = mtd_to_jz_nand(mtd);
struct nand_chip *chip = mtd->priv;
uint32_t reg;
if (ctrl & NAND_CTRL_CHANGE) {
BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
if (ctrl & NAND_ALE)
chip->IO_ADDR_W = JZ_NAND_ADDR_ADDR;
else if (ctrl & NAND_CLE)
chip->IO_ADDR_W = JZ_NAND_CMD_ADDR;
else
chip->IO_ADDR_W = JZ_NAND_DATA_ADDR;
reg = readl(nand->base + JZ_REG_NAND_CTRL);
if ( ctrl & NAND_NCE )
reg |= JZ_NAND_CTRL_ASSERT_CHIP(0);
else
reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0);
writel(reg, nand->base + JZ_REG_NAND_CTRL);
}
if (dat != NAND_CMD_NONE)
writeb(dat, chip->IO_ADDR_W);
}
static int jz_nand_dev_ready(struct mtd_info *mtd)
{
struct jz_nand *nand = mtd_to_jz_nand(mtd);
return gpio_get_value_cansleep(nand->pdata->busy_gpio);
}
static void jz_nand_hwctl(struct mtd_info *mtd, int mode)
{
struct jz_nand *nand = mtd_to_jz_nand(mtd);
uint32_t reg;
writel(0, nand->base + JZ_REG_NAND_IRQ_STAT);
reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
reg |= JZ_NAND_ECC_CTRL_RESET;
reg |= JZ_NAND_ECC_CTRL_ENABLE;
reg |= JZ_NAND_ECC_CTRL_RS;
switch(mode) {
case NAND_ECC_READ:
reg &= ~JZ_NAND_ECC_CTRL_ENCODING;
break;
case NAND_ECC_WRITE:
reg |= JZ_NAND_ECC_CTRL_ENCODING;
break;
default:
break;
}
writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
}
static int jz_nand_calculate_ecc_rs(struct mtd_info* mtd, const uint8_t* dat,
uint8_t *ecc_code)
{
struct jz_nand *nand = mtd_to_jz_nand(mtd);
uint32_t reg, status;
int i;
do {
status = readl(nand->base + JZ_REG_NAND_IRQ_STAT);
} while(!(status & JZ_NAND_STATUS_ENC_FINISH));
reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
for (i = 0; i < 9; ++i) {
ecc_code[i] = readb(nand->base + JZ_REG_NAND_PAR0 + i);
}
return 0;
}
static void correct_data(uint8_t *dat, int index, int mask)
{
int offset = index & 0x7;
uint16_t data;
printk("correct: ");
index += (index >> 3);
data = dat[index];
data |= dat[index+1] << 8;
printk("0x%x -> ", data);
mask ^= (data >> offset) & 0x1ff;
data &= ~(0x1ff << offset);
data |= (mask << offset);
printk("0x%x\n", data);
dat[index] = data & 0xff;
dat[index+1] = (data >> 8) & 0xff;
}
static int jz_nand_correct_ecc_rs(struct mtd_info* mtd, uint8_t *dat,
uint8_t *read_ecc, uint8_t *calc_ecc)
{
struct jz_nand *nand = mtd_to_jz_nand(mtd);
int i, error_count, index;
uint32_t reg, status, error;
for(i = 0; i < 9; ++i) {
if (read_ecc[i] != 0xff)
break;
}
if (i == 9) {
for (i = 0; i < nand->chip.ecc.size; ++i) {
if (dat[i] != 0xff)
break;
}
if (i == nand->chip.ecc.size)
return 0;
}
for(i = 0; i < 9; ++i)
writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i);
reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
reg |= JZ_NAND_ECC_CTRL_PAR_READY;
writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
do {
status = readl(nand->base + JZ_REG_NAND_IRQ_STAT);
} while (!(status & JZ_NAND_STATUS_DEC_FINISH));
reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
if (status & JZ_NAND_STATUS_ERROR) {
if (status & JZ_NAND_STATUS_UNCOR_ERROR) {
printk("uncorrectable ecc:");
for(i = 0; i < 9; ++i)
printk(" 0x%x", read_ecc[i]);
printk("\n");
printk("uncorrectable data:");
for(i = 0; i < 32; ++i)
printk(" 0x%x", dat[i]);
printk("\n");
return -1;
}
error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29;
printk("error_count: %d %x\n", error_count, status);
for(i = 0; i < error_count; ++i) {
error = readl(nand->base + JZ_REG_NAND_ERR(i));
index = ((error >> 16) & 0x1ff) - 1;
if (index >= 0 && index < 512) {
correct_data(dat, index, error & 0x1ff);
}
}
return error_count;
}
return 0;
}
#ifdef CONFIG_MTD_CMDLINE_PARTS
static const char *part_probes[] = {"cmdline", NULL};
#endif
static int __devinit jz_nand_probe(struct platform_device *pdev)
{
int ret;
struct jz_nand *nand;
struct nand_chip *chip;
struct mtd_info *mtd;
struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *partition_info;
int num_partitions = 0;
#endif
nand = kzalloc(sizeof(*nand), GFP_KERNEL);
if (!nand) {
dev_err(&pdev->dev, "Failed to allocate device structure.\n");
return -ENOMEM;
}
nand->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!nand->mem) {
dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
ret = -ENOENT;
goto err_free;
}
nand->mem = request_mem_region(nand->mem->start, resource_size(nand->mem),
pdev->name);
if (!nand->mem) {
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
ret = -EBUSY;
goto err_free;
}
nand->base = ioremap(nand->mem->start, resource_size(nand->mem));
if (!nand->base) {
dev_err(&pdev->dev, "Faild to ioremap mmio memory region\n");
ret = -EBUSY;
goto err_release_mem;
}
if (pdata && gpio_is_valid(pdata->busy_gpio)) {
ret = gpio_request(pdata->busy_gpio, "jz nand busy line");
if (ret) {
dev_err(&pdev->dev, "Failed to request busy gpio %d: %d\n",
pdata->busy_gpio, ret);
goto err_iounmap;
}
}
mtd = &nand->mtd;
chip = &nand->chip;
mtd->priv = chip;
mtd->owner = THIS_MODULE;
mtd->name = "jz4740-nand";
chip->ecc.hwctl = jz_nand_hwctl;
chip->ecc.calculate = jz_nand_calculate_ecc_rs;
chip->ecc.correct = jz_nand_correct_ecc_rs;
chip->ecc.mode = NAND_ECC_HW;
chip->ecc.size = 512;
chip->ecc.bytes = 9;
if (pdata)
chip->ecc.layout = pdata->ecc_layout;
chip->chip_delay = 50;
chip->cmd_ctrl = jz_nand_cmd_ctrl;
if (pdata && gpio_is_valid(pdata->busy_gpio))
chip->dev_ready = jz_nand_dev_ready;
chip->IO_ADDR_R = JZ_NAND_DATA_ADDR;
chip->IO_ADDR_W = JZ_NAND_DATA_ADDR;
nand->pdata = pdata;
platform_set_drvdata(pdev, nand);
ret = nand_scan_ident(mtd, 1);
if (ret) {
dev_err(&pdev->dev, "Failed to scan nand\n");
goto err_gpio_free;
}
if (pdata && pdata->ident_callback) {
pdata->ident_callback(pdev, chip, &pdata->partitions, &pdata->num_partitions);
}
ret = nand_scan_tail(mtd);
if (ret) {
dev_err(&pdev->dev, "Failed to scan nand\n");
goto err_gpio_free;
}
#ifdef CONFIG_MTD_PARTITIONS
#ifdef CONFIG_MTD_CMDLINE_PARTS
num_partitions = parse_mtd_partitions(mtd, part_probes,
&partition_info, 0);
#endif
if (num_partitions <= 0 && pdata) {
num_partitions = pdata->num_partitions;
partition_info = pdata->partitions;
}
if (num_partitions > 0)
ret = add_mtd_partitions(mtd, partition_info, num_partitions);
else
#endif
ret = add_mtd_device(mtd);
if (ret) {
dev_err(&pdev->dev, "Failed to add mtd device\n");
goto err_nand_release;
}
dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n");
return 0;
err_nand_release:
nand_release(&nand->mtd);
err_gpio_free:
platform_set_drvdata(pdev, NULL);
gpio_free(pdata->busy_gpio);
err_iounmap:
iounmap(nand->base);
err_release_mem:
release_mem_region(nand->mem->start, resource_size(nand->mem));
err_free:
kfree(nand);
return ret;
}
static void __devexit jz_nand_remove(struct platform_device *pdev)
{
struct jz_nand *nand = platform_get_drvdata(pdev);
nand_release(&nand->mtd);
iounmap(nand->base);
release_mem_region(nand->mem->start, resource_size(nand->mem));
platform_set_drvdata(pdev, NULL);
kfree(nand);
}
struct platform_driver jz_nand_driver = {
.probe = jz_nand_probe,
.remove = __devexit_p(jz_nand_probe),
.driver = {
.name = "jz4740-nand",
.owner = THIS_MODULE,
},
};
static int __init jz_nand_init(void)
{
return platform_driver_register(&jz_nand_driver);
}
module_init(jz_nand_init);
static void __exit jz_nand_exit(void)
{
platform_driver_unregister(&jz_nand_driver);
}
module_exit(jz_nand_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("NAND controller driver for JZ4720/JZ4740 SoC");
MODULE_ALIAS("platform:jz4740-nand");
MODULE_ALIAS("platform:jz4720-nand");

View File

@ -1,471 +0,0 @@
/*
* Battery measurement code for Ingenic JZ SOC.
*
* based on tosa_battery.c
*
* Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
* Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/power_supply.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/power/jz4740-battery.h>
#include <linux/jz4740-adc.h>
struct jz_battery_info {
struct power_supply usb;
struct power_supply bat;
struct power_supply ac;
int bat_status;
struct jz_batt_info *pdata;
struct mutex work_lock;
struct workqueue_struct *monitor_wqueue;
struct delayed_work bat_work;
};
#define ps_to_jz_battery(x) container_of((x), struct jz_battery_info, bat);
/*********************************************************************
* Power
*********************************************************************/
static int jz_get_power_prop(struct jz_battery_info *bat_info,
struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int gpio;
if (bat_info == 0 || bat_info->pdata == 0)
return -EINVAL;
gpio = (psy->type == POWER_SUPPLY_TYPE_MAINS) ?
bat_info->pdata->dc_dect_gpio :
bat_info->pdata->usb_dect_gpio;
if (!gpio_is_valid(gpio))
return -EINVAL;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = !gpio_get_value(gpio);
break;
default:
return -EINVAL;
}
return 0;
}
static int jz_usb_get_power_prop(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct jz_battery_info *bat_info = container_of(psy, struct jz_battery_info, usb);
return jz_get_power_prop(bat_info, psy, psp, val);
}
static int jz_ac_get_power_prop(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct jz_battery_info *bat_info = container_of(psy, struct jz_battery_info, ac);
return jz_get_power_prop(bat_info, psy, psp, val);
}
static enum power_supply_property jz_power_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
static struct power_supply jz_ac = {
.name = "ac",
.type = POWER_SUPPLY_TYPE_MAINS,
.properties = jz_power_props,
.num_properties = ARRAY_SIZE(jz_power_props),
.get_property = jz_ac_get_power_prop,
};
static struct power_supply jz_usb = {
.name = "usb",
.type = POWER_SUPPLY_TYPE_USB,
.properties = jz_power_props,
.num_properties = ARRAY_SIZE(jz_power_props),
.get_property = jz_usb_get_power_prop,
};
/*********************************************************************
* Battery properties
*********************************************************************/
static long jz_read_bat(struct power_supply *psy)
{
struct jz_battery_info *bat_info = ps_to_jz_battery(psy);
enum jz_adc_battery_scale scale;
if (bat_info->pdata->max_voltag > 2500000)
scale = JZ_ADC_BATTERY_SCALE_7V5;
else
scale = JZ_ADC_BATTERY_SCALE_2V5;
return jz4740_adc_read_battery_voltage(psy->dev->parent->parent, scale);
}
static int jz_bat_get_capacity(struct power_supply *psy)
{
int ret;
struct jz_battery_info *bat_info = ps_to_jz_battery(psy);
ret = jz_read_bat(psy);
if (ret < 0)
return ret;
ret = (ret - bat_info->pdata->min_voltag) * 100
/ (bat_info->pdata->max_voltag - bat_info->pdata->min_voltag);
if (ret > 100)
ret = 100;
else if (ret < 0)
ret = 0;
return ret;
}
static int jz_bat_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct jz_battery_info *bat_info = ps_to_jz_battery(psy)
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = bat_info->bat_status;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = bat_info->pdata->batt_tech;
break;
case POWER_SUPPLY_PROP_HEALTH:
if(jz_read_bat(psy) < bat_info->pdata->min_voltag) {
dev_dbg(psy->dev, "%s: battery is dead,"
"voltage too low!\n", __func__);
val->intval = POWER_SUPPLY_HEALTH_DEAD;
} else {
dev_dbg(psy->dev, "%s: battery is good,"
"voltage normal.\n", __func__);
val->intval = POWER_SUPPLY_HEALTH_GOOD;
}
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = jz_bat_get_capacity(psy);
dev_dbg(psy->dev, "%s: battery_capacity = %d\n",
__func__, val->intval);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = jz_read_bat(psy);
if (val->intval < 0)
return val->intval;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
val->intval = bat_info->pdata->max_voltag;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
val->intval = bat_info->pdata->min_voltag;
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
default:
return -EINVAL;
}
return 0;
}
static void jz_bat_external_power_changed(struct power_supply *psy)
{
struct jz_battery_info *bat_info = ps_to_jz_battery(psy);
cancel_delayed_work(&bat_info->bat_work);
queue_delayed_work(bat_info->monitor_wqueue, &bat_info->bat_work, HZ / 8);
}
static char *status_text[] = {
[POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
[POWER_SUPPLY_STATUS_CHARGING] = "Charging",
[POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
[POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not charging",
};
static void jz_bat_update(struct power_supply *psy)
{
struct jz_battery_info *bat_info = ps_to_jz_battery(psy);
int old_status = bat_info->bat_status;
static unsigned long old_batt_vol = 0;
unsigned long batt_vol = jz_read_bat(psy);
mutex_lock(&bat_info->work_lock);
if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) {
if(!gpio_get_value(bat_info->pdata->charg_stat_gpio))
bat_info->bat_status = POWER_SUPPLY_STATUS_CHARGING;
else
bat_info->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
dev_dbg(psy->dev, "%s: battery status=%s\n",
__func__, status_text[bat_info->bat_status]);
if (old_status != bat_info->bat_status) {
dev_dbg(psy->dev, "%s %s -> %s\n",
psy->name,
status_text[old_status],
status_text[bat_info->bat_status]);
power_supply_changed(psy);
}
}
if (old_batt_vol - batt_vol > 50000) {
dev_dbg(psy->dev, "voltage change : %ld -> %ld\n",
old_batt_vol, batt_vol);
power_supply_changed(psy);
old_batt_vol = batt_vol;
}
mutex_unlock(&bat_info->work_lock);
}
static enum power_supply_property jz_bat_main_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_PRESENT,
};
struct power_supply bat_ps = {
.name = "battery",
.type = POWER_SUPPLY_TYPE_BATTERY,
.properties = jz_bat_main_props,
.num_properties = ARRAY_SIZE(jz_bat_main_props),
.get_property = jz_bat_get_property,
.external_power_changed = jz_bat_external_power_changed,
.use_for_apm = 1,
};
static void jz_bat_work(struct work_struct *work)
{
/* query interval too small will increase system workload*/
const int interval = HZ * 30;
struct jz_battery_info *bat_info = container_of(work,struct jz_battery_info, bat_work.work);
jz_bat_update(&bat_info->bat);
queue_delayed_work(bat_info->monitor_wqueue,
&bat_info->bat_work, interval);
}
#ifdef CONFIG_PM
static int jz_bat_suspend(struct platform_device *pdev, pm_message_t state)
{
struct jz_battery_info *bat_info = platform_get_drvdata(pdev);
bat_info->bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
return 0;
}
static int jz_bat_resume(struct platform_device *pdev)
{
struct jz_battery_info *bat_info = platform_get_drvdata(pdev);
bat_info->bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
cancel_delayed_work(&bat_info->bat_work);
queue_delayed_work(bat_info->monitor_wqueue, &bat_info->bat_work, HZ/10);
return 0;
}
#else
#define jz_bat_suspend NULL
#define jz_bat_resume NULL
#endif
static int jz_bat_probe(struct platform_device *pdev)
{
int ret = 0;
struct jz_battery_info *bat_info;
bat_info = kzalloc(sizeof(struct jz_battery_info), GFP_KERNEL);
if (!bat_info) {
return -ENOMEM;
}
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "Please set battery info\n");
ret = -EINVAL;
goto err_platform_data;
}
platform_set_drvdata(pdev, bat_info);
bat_info->pdata = pdev->dev.platform_data;
bat_info->bat = bat_ps;
bat_info->usb = jz_usb;
bat_info->ac = jz_ac;
mutex_init(&bat_info->work_lock);
INIT_DELAYED_WORK(&bat_info->bat_work, jz_bat_work);
if (gpio_is_valid(bat_info->pdata->dc_dect_gpio)) {
ret = gpio_request(bat_info->pdata->dc_dect_gpio, "AC/DC DECT");
if (ret) {
dev_err(&pdev->dev, "ac/dc dect gpio request failed.\n");
goto err_dc_gpio_request;
}
ret = gpio_direction_input(bat_info->pdata->dc_dect_gpio);
if (ret) {
dev_err(&pdev->dev, "ac/dc dect gpio direction failed.\n");
goto err_dc_gpio_direction;
}
}
if (gpio_is_valid(bat_info->pdata->usb_dect_gpio)) {
ret = gpio_request(bat_info->pdata->usb_dect_gpio, "USB DECT");
if (ret) {
dev_err(&pdev->dev, "usb dect gpio request failed.\n");
goto err_usb_gpio_request;
}
ret = gpio_direction_input(bat_info->pdata->usb_dect_gpio);
if (ret) {
dev_err(&pdev->dev, "usb dect gpio set direction failed.\n");
goto err_usb_gpio_direction;
}
jz_gpio_disable_pullup(bat_info->pdata->usb_dect_gpio);
/* TODO: Use generic gpio is better */
}
if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) {
ret = gpio_request(bat_info->pdata->charg_stat_gpio, "CHARG STAT");
if (ret) {
dev_err(&pdev->dev, "charger state gpio request failed.\n");
goto err_charg_gpio_request;
}
ret = gpio_direction_input(bat_info->pdata->charg_stat_gpio);
if (ret) {
dev_err(&pdev->dev, "charger state gpio set direction failed.\n");
goto err_charg_gpio_direction;
}
}
if (gpio_is_valid(bat_info->pdata->dc_dect_gpio)) {
ret = power_supply_register(&pdev->dev, &bat_info->ac);
if (ret) {
dev_err(&pdev->dev, "power supply ac/dc register failed.\n");
goto err_power_register_ac;
}
}
if (gpio_is_valid(bat_info->pdata->usb_dect_gpio)) {
ret = power_supply_register(&pdev->dev, &bat_info->usb);
if (ret) {
dev_err(&pdev->dev, "power supply usb register failed.\n");
goto err_power_register_usb;
}
}
if (gpio_is_valid(bat_info->pdata->charg_stat_gpio)) {
ret = power_supply_register(&pdev->dev, &bat_info->bat);
if (ret) {
dev_err(&pdev->dev, "power supply battery register failed.\n");
goto err_power_register_bat;
} else {
bat_info->monitor_wqueue = create_singlethread_workqueue("jz_battery");
if (!bat_info->monitor_wqueue) {
return -ESRCH;
}
queue_delayed_work(bat_info->monitor_wqueue, &bat_info->bat_work, HZ * 1);
}
}
printk(KERN_INFO "jz_bat init success.\n");
return ret;
err_power_register_bat:
power_supply_unregister(&bat_info->usb);
err_power_register_usb:
power_supply_unregister(&bat_info->ac);
err_power_register_ac:
err_charg_gpio_direction:
gpio_free(bat_info->pdata->charg_stat_gpio);
err_charg_gpio_request:
err_usb_gpio_direction:
gpio_free(bat_info->pdata->usb_dect_gpio);
err_usb_gpio_request:
err_dc_gpio_direction:
gpio_free(bat_info->pdata->dc_dect_gpio);
err_dc_gpio_request:
err_platform_data:
kfree(bat_info);
return ret;
}
static int jz_bat_remove(struct platform_device *pdev)
{
struct jz_battery_info *bat_info = platform_get_drvdata(pdev);
if (bat_info->pdata) {
if (gpio_is_valid(bat_info->pdata->dc_dect_gpio))
gpio_free(bat_info->pdata->dc_dect_gpio);
if (gpio_is_valid(bat_info->pdata->usb_dect_gpio))
gpio_free(bat_info->pdata->usb_dect_gpio);
if (gpio_is_valid(bat_info->pdata->charg_stat_gpio))
gpio_free(bat_info->pdata->charg_stat_gpio);
}
power_supply_unregister(&bat_ps);
power_supply_unregister(&jz_ac);
power_supply_unregister(&jz_usb);
return 0;
}
static struct platform_driver jz_bat_driver = {
.probe = jz_bat_probe,
.remove = __devexit_p(jz_bat_remove),
.suspend = jz_bat_suspend,
.resume = jz_bat_resume,
.driver = {
.name = "jz4740-battery",
.owner = THIS_MODULE,
},
};
static int __init jz_bat_init(void)
{
return platform_driver_register(&jz_bat_driver);
}
module_init(jz_bat_init);
static void __exit jz_bat_exit(void)
{
platform_driver_unregister(&jz_bat_driver);
}
module_exit(jz_bat_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiejing Zhang <kzjeef@gmail.com>");
MODULE_DESCRIPTION("JZ4720/JZ4740 SoC battery driver");

View File

@ -1,325 +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_REGULATOR 0x0C
#define JZ_RTC_CTRL_WRDY BIT(7)
#define JZ_RTC_CTRL_1HZ BIT(6)
#define JZ_RTC_CTRL_1HZ_IRQ BIT(5)
#define JZ_RTC_CTRL_AF BIT(4)
#define JZ_RTC_CTRL_AF_IRQ BIT(3)
#define JZ_RTC_CTRL_AE BIT(2)
#define JZ_RTC_CTRL_ENABLE BIT(0)
struct jz4740_rtc {
struct resource *mem;
void __iomem *base;
struct rtc_device *rtc;
unsigned int irq;
spinlock_t lock;
};
static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg)
{
return readl(rtc->base + reg);
}
static inline void jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
{
uint32_t ctrl;
do {
ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
} while (!(ctrl & JZ_RTC_CTRL_WRDY));
}
static inline void jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
uint32_t val)
{
jz4740_rtc_wait_write_ready(rtc);
writel(val, rtc->base + reg);
}
static void jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
uint32_t val)
{
unsigned long flags;
uint32_t ctrl;
spin_lock_irqsave(&rtc->lock, flags);
ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
/* Don't clear interrupt flags by accident */
ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF;
ctrl &= ~mask;
ctrl |= val;
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);
spin_unlock_irqrestore(&rtc->lock, flags);
}
static inline struct jz4740_rtc *dev_to_rtc(struct device *dev)
{
return dev_get_drvdata(dev);
}
static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
{
struct jz4740_rtc *rtc = dev_to_rtc(dev);
uint32_t secs, secs2;
secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
while (secs != secs2) {
secs = secs2;
secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
}
rtc_time_to_tm(secs, time);
return rtc_valid_tm(time);
}
static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs)
{
struct jz4740_rtc *rtc = dev_to_rtc(dev);
if ((uint32_t)secs != secs)
return -EINVAL;
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
return 0;
}
static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct jz4740_rtc *rtc = dev_to_rtc(dev);
uint32_t secs, secs2;
uint32_t ctrl;
secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
while (secs != secs2){
secs = secs2;
secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
}
ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE);
alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF);
rtc_time_to_tm(secs, &alrm->time);
return rtc_valid_tm(&alrm->time);
}
static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct jz4740_rtc *rtc = dev_to_rtc(dev);
unsigned long secs;
rtc_tm_to_time(&alrm->time, &secs);
if ((uint32_t)secs != secs)
return -EINVAL;
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, (uint32_t)secs);
jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE,
alrm->enabled ? JZ_RTC_CTRL_AE : 0);
return 0;
}
static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enabled)
{
struct jz4740_rtc *rtc = dev_to_rtc(dev);
jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ,
enabled ? JZ_RTC_CTRL_1HZ_IRQ : 0);
return 0;
}
static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct jz4740_rtc *rtc = dev_to_rtc(dev);
jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ,
enabled ? JZ_RTC_CTRL_AF_IRQ : 0);
return 0;
}
static struct rtc_class_ops jz4740_rtc_ops = {
.read_time = jz4740_rtc_read_time,
.set_mmss = jz4740_rtc_set_mmss,
.read_alarm = jz4740_rtc_read_alarm,
.set_alarm = jz4740_rtc_set_alarm,
.update_irq_enable = jz4740_rtc_update_irq_enable,
.alarm_irq_enable = jz4740_rtc_alarm_irq_enable,
};
static irqreturn_t jz4740_rtc_irq(int irq, void *data)
{
struct jz4740_rtc *rtc = data;
uint32_t ctrl;
unsigned long events = 0;
ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
if (ctrl & JZ_RTC_CTRL_1HZ)
events |= (RTC_UF | RTC_IRQF);
if (ctrl & JZ_RTC_CTRL_AF)
events |= (RTC_AF | RTC_IRQF);
rtc_update_irq(rtc->rtc, 1, events);
jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, 0);
return IRQ_HANDLED;
}
static int __devinit jz4740_rtc_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_rtc *rtc;
rtc = kmalloc(sizeof(*rtc), GFP_KERNEL);
rtc->irq = platform_get_irq(pdev, 0);
if (rtc->irq < 0) {
ret = -ENOENT;
dev_err(&pdev->dev, "Failed to get platform irq\n");
goto err_free;
}
rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!rtc->mem) {
ret = -ENOENT;
dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
goto err_free;
}
rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem),
pdev->name);
if (!rtc->mem) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
goto err_free;
}
rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem));
if (!rtc->base) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
goto err_release_mem_region;
}
platform_set_drvdata(pdev, rtc);
rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
goto err_iounmap;
}
ret = request_irq(rtc->irq, jz4740_rtc_irq, 0,
pdev->name, rtc);
if (ret) {
dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
goto err_unregister_rtc;
}
printk("rtc-ctrl: %d\n", jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL));
return 0;
err_unregister_rtc:
rtc_device_unregister(rtc->rtc);
err_iounmap:
platform_set_drvdata(pdev, NULL);
iounmap(rtc->base);
err_release_mem_region:
release_mem_region(rtc->mem->start, resource_size(rtc->mem));
err_free:
kfree(rtc);
return ret;
}
static int __devexit jz4740_rtc_remove(struct platform_device *pdev)
{
struct jz4740_rtc *rtc = platform_get_drvdata(pdev);
rtc_device_unregister(rtc->rtc);
iounmap(rtc->base);
release_mem_region(rtc->mem->start, resource_size(rtc->mem));
kfree(rtc);
platform_set_drvdata(pdev, NULL);
return 0;
}
struct platform_driver jz4740_rtc_driver = {
.probe = jz4740_rtc_probe,
.remove = __devexit_p(jz4740_rtc_remove),
.driver = {
.name = "jz4740-rtc",
.owner = THIS_MODULE,
},
};
static int __init jz4740_rtc_init(void)
{
return platform_driver_register(&jz4740_rtc_driver);
}
module_init(jz4740_rtc_init);
static void __exit jz4740_rtc_exit(void)
{
platform_driver_unregister(&jz4740_rtc_driver);
}
module_exit(jz4740_rtc_exit);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("RTC driver for the JZ4720/JZ4740 SoC\n");
MODULE_ALIAS("platform:jz4740-rtc");
MODULE_ALIAS("platform:jz4720-rtc");

View File

@ -1,97 +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;
};
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,50 +0,0 @@
/*
* Ingenic USB Device Contoller Hotplug External Interfaces
*/
#ifndef __UDC_HOTPLUG_H__
#define __UDC_HOTPLUG_H__
#include <linux/notifier.h>
typedef enum {
BROADCAST_TYPE_STATE = 0,
BROADCAST_TYPE_EVENT,
}udc_hotplug_broadcast_type_t;
typedef enum {
EVENT_STATE_OFFLINE = 0,
EVENT_STATE_ONLINE,
}udc_hotplug_event_state_t;
typedef enum {
EVENT_TYPE_USB = 0,
EVENT_TYPE_CABLE,
}udc_hotplug_event_type_t;
enum {
EVENT_FLAG_UDC_PHY_TOUCHED = 0,
};
typedef struct {
udc_hotplug_event_type_t type;
udc_hotplug_event_state_t state;
unsigned long flags;
}udc_hotplug_event_t;
/* Register notifier */
int udc_hotplug_register_notifier(struct notifier_block *n, int request_state);
/* Unregister notifier */
int udc_hotplug_unregister_notifier(struct notifier_block *n);
/* Start keep alive */
int udc_hotplug_start_keep_alive(unsigned long timer_interval_in_jiffies, unsigned long counter_limit);
/* Do keep alive */
void udc_hotplug_do_keep_alive(void);
/* Stop keep alive */
void udc_hotplug_stop_keep_alive(void);
#endif /* Define __UDC_HOTPLUG_H__ */

View File

@ -1,836 +0,0 @@
/*
* Ingenic USB Device Controller Hotplug Core Function
* Detection mechanism and code are based on the old version of udc_hotplug.c
*/
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/wait.h>
#include <linux/kthread.h>
#include <linux/timer.h>
#include <asm/jzsoc.h>
#include "udc_hotplug.h"
#define PFX "jz_hotplug_udc"
#define D(msg, fmt...) \
// printk(KERN_ERR PFX": %s(): "msg, __func__, ##fmt);
/* HAVE_DETECT_SYNC
Provide a lock like seqlock keep the synchronization between the start and the end of a detection,
If the lock seems not synchronous(new interrupt comes, when doing our detection) in the end of a detection,
the result of the detection is discarded. No event will be broadcast, and the detection will be restarted.
Use to filter out more significant events when the interrupt is too noisy.
*/
//#define HAVE_DETECT_SYNC 1
#if defined (HAVE_DETECT_SYNC)
#define NR_RESTART_TIMES 3
#define NR_JIFFIES_SLEEP_BEFORE_RESTART 7
#endif
#define NR_GPIO_STABLE_TIMES 50
#define NR_JIFFIES_USB_DETECT_WAIT 11
#define DEFAULT_KEEP_ALIVE_TIMER_INTERVAL (2 * HZ)
#define DEFAULT_KEEP_ALIVE_COUNTER_LIMIT 2
#define UDC_HOTPLUG_PIN GPIO_UDC_HOTPLUG
#define UDC_HOTPLUG_IRQ (IRQ_GPIO_0 + UDC_HOTPLUG_PIN)
/* UDC State bits */
enum {
/* Online state. */
BIT_CABLE_ONLINE = 0,
BIT_USB_ONLINE,
/* State changed ?*/
BIT_CABLE_CHANGE,
BIT_USB_CHANGE,
/* What detection will be done ? */
BIT_DO_CABLE_DETECT,
BIT_DO_USB_DETECT,
/* What detection is requested ? */
BIT_REQUEST_CABLE_DETECT,
BIT_REQUEST_USB_DETECT,
/* Indicate whether a detection is finisned. */
BIT_USB_DETECT_DONE,
BIT_CABLE_DETECT_DONE,
BIT_UDC_PHY_TOUCHED,
/* Keep alive */
BIT_KEEP_ALIVE,
BIT_KEEP_ALIVE_TIMEOUT,
};
struct uh_data {
/* Notifier */
struct blocking_notifier_head notifier_head;
/* Thread */
struct task_struct *kthread;
/* Wait queue */
wait_queue_head_t kthread_wq; /* Kernel thread sleep here. */
wait_queue_head_t wq; /* Others sleep here. */
/* UDC State */
unsigned long state;
/* Current Event */
udc_hotplug_event_t cur_uh_event;
#if defined (HAVE_DETECT_SYNC)
/* Sync seq */
unsigned long irq_sync_seq;
unsigned long our_sync_seq;
#endif
/* Keep alive */
struct timer_list keep_alive_timer;
unsigned long keep_alive_counter_limit;
unsigned long keep_alive_timer_interval;
unsigned long keep_alive_counter;
};
static struct uh_data *g_puh_data = NULL;
#if defined (HAVE_DETECT_SYNC)
/* Seq sync function */
static inline int is_seq_sync(struct uh_data *uh)
{
return (uh->our_sync_seq == uh->irq_sync_seq);
}
static inline void reset_seq(struct uh_data *uh)
{
uh->our_sync_seq = uh->irq_sync_seq = 0;
return;
}
static inline void sync_seq(struct uh_data *uh)
{
uh->our_sync_seq = uh->irq_sync_seq;
return;
}
#endif
/* Call kernel thread to detect. */
static inline void start_detect(struct uh_data *uh)
{
D("called.\n");
#if defined (HAVE_DETECT_SYNC)
uh->irq_sync_seq ++;
#endif
wake_up_process(uh->kthread);
return;
}
static void wait_gpio_pin_stable(struct uh_data *uh)
{
unsigned long pin = 0;
int i = 1;
pin = __gpio_get_pin(UDC_HOTPLUG_PIN);
while (i < NR_GPIO_STABLE_TIMES) {
if (__gpio_get_pin(UDC_HOTPLUG_PIN) != pin) {
pin = __gpio_get_pin(UDC_HOTPLUG_PIN);
i = 1;
}else
i++;
sleep_on_timeout(&uh->wq, 1);
}
return;
}
/* Do cable detection */
static void cable_detect(struct uh_data *uh)
{
D("Wait pin stable.\n");
/* Wait GPIO pin stable first. */
wait_gpio_pin_stable(uh);
if (__gpio_get_pin(UDC_HOTPLUG_PIN)) {
D("Cable online.\n");
if (!test_and_set_bit(BIT_CABLE_ONLINE, &uh->state)) {
D("Cable state change to online.\n");
set_bit(BIT_CABLE_CHANGE, &uh->state);
}
}else {
D("Cable offline.\n");
/* Clear keep alive bit. */
clear_bit(BIT_KEEP_ALIVE, &uh->state);
if (test_and_clear_bit(BIT_CABLE_ONLINE, &uh->state)) {
D("Cable state change to offline.\n");
set_bit(BIT_CABLE_CHANGE, &uh->state);
}
}
set_bit(BIT_CABLE_DETECT_DONE, &uh->state);
return;
}
/* Really do USB detection */
static int do_usb_detect(struct uh_data *uh)
{
u32 intr_usb;
int rv;
D("called.\n");
__intc_mask_irq(IRQ_UDC);
/* Now enable PHY to start detect */
#ifdef CONFIG_SOC_JZ4740
REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE;
#endif
/* Clear IRQs */
REG16(USB_REG_INTRINE) = 0;
REG16(USB_REG_INTROUTE) = 0;
REG8(USB_REG_INTRUSBE) = 0;
/* disable UDC IRQs first */
REG16(USB_REG_INTRINE) = 0;
REG16(USB_REG_INTROUTE) = 0;
REG8(USB_REG_INTRUSBE) = 0;
/* Disable DMA */
REG32(USB_REG_CNTL1) = 0;
REG32(USB_REG_CNTL2) = 0;
/* Enable HS Mode */
REG8(USB_REG_POWER) |= USB_POWER_HSENAB;
/* Enable soft connect */
REG8(USB_REG_POWER) |= USB_POWER_SOFTCONN;
D("enable phy! %x %x %x %x %x\n",
REG8(USB_REG_POWER),
REG_CPM_OPCR,
REG16(USB_REG_INTRINE),
REG16(USB_REG_INTROUTE),
REG8(USB_REG_INTRUSBE));
/* Wait a moment. */
sleep_on_timeout(&uh->wq, NR_JIFFIES_USB_DETECT_WAIT);
intr_usb = REG8(USB_REG_INTRUSB);
if ((intr_usb & USB_INTR_RESET) ||
(intr_usb & USB_INTR_RESUME) ||
(intr_usb & USB_INTR_SUSPEND))
{
rv = 1;
}
else
{
rv = 0;
}
/* Detect finish ,clean every thing */
/* Disconnect from usb */
REG8(USB_REG_POWER) &= ~USB_POWER_SOFTCONN;
/* Disable the USB PHY */
#ifdef CONFIG_SOC_JZ4740
REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE;
#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE;
#endif
/* Clear IRQs */
REG16(USB_REG_INTRINE) = 0;
REG16(USB_REG_INTROUTE) = 0;
REG8(USB_REG_INTRUSBE) = 0;
__intc_ack_irq(IRQ_UDC);
__intc_unmask_irq(IRQ_UDC);
mdelay(1);
return rv;
}
/* Do USB bus protocol detection */
static void usb_detect(struct uh_data *uh)
{
int rv = 0;
D("Called.\n");
/* If the cable has already been offline, we just pass the real USB detection. */
if (test_bit(BIT_CABLE_ONLINE, &uh->state)) {
D("Do real detection.\n");
rv = do_usb_detect(uh);
set_bit(BIT_UDC_PHY_TOUCHED, &uh->state);
}else{
clear_bit(BIT_UDC_PHY_TOUCHED, &uh->state);
D("No need to do real detection.\n");
}
if (rv) {
if (!test_and_set_bit(BIT_USB_ONLINE, &uh->state))
set_bit(BIT_USB_CHANGE, &uh->state);
}else{
/* Clear keep alive bit. */
clear_bit(BIT_KEEP_ALIVE, &uh->state);
if (test_and_clear_bit(BIT_USB_ONLINE, &uh->state))
set_bit(BIT_USB_CHANGE, &uh->state);
}
set_bit(BIT_USB_DETECT_DONE, &uh->state);
return;
}
/* USB is active ? */
static int usb_is_active(void)
{
unsigned long tmp;
tmp = REG16(USB_REG_FRAME);
mdelay(2); /* USB 1.1 Frame length is 1ms, USB 2.0 HS Frame length is 125us */
rmb();
return tmp == REG16(USB_REG_FRAME) ? 0 : 1;
}
/* Broadcast event to notifier */
static void do_broadcast_event(struct uh_data *uh)
{
udc_hotplug_event_t *e = &uh->cur_uh_event;
/* Collect Information */
if (test_and_clear_bit(BIT_CABLE_CHANGE, &uh->state)) {
e->type = EVENT_TYPE_CABLE;
e->state = (test_bit(BIT_CABLE_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE: EVENT_STATE_OFFLINE;
e->flags = 0;
D("Broadcast cable event -> State: %s.\n", (e->state == EVENT_STATE_ONLINE ? "Online" : "Offline"));
/* Kick chain. */
blocking_notifier_call_chain(&uh->notifier_head, BROADCAST_TYPE_EVENT, e);
}
if (test_and_clear_bit(BIT_USB_CHANGE, &uh->state)) {
e->type = EVENT_TYPE_USB;
e->state = (test_bit(BIT_USB_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE : EVENT_STATE_OFFLINE;
e->flags = 0;
if (test_bit(BIT_UDC_PHY_TOUCHED, &uh->state)) {
set_bit(EVENT_FLAG_UDC_PHY_TOUCHED, &e->flags);
}
D("Broadcast USB event -> State: %s.\n", (e->state == EVENT_STATE_ONLINE ? "Online" : "Offline"));
/* Kick chain. */
blocking_notifier_call_chain(&uh->notifier_head, BROADCAST_TYPE_EVENT, e);
}
return;
}
/* Handle pending request */
static inline void handle_request(struct uh_data *uh)
{
if (test_and_clear_bit(BIT_REQUEST_CABLE_DETECT, &uh->state))
set_bit(BIT_DO_CABLE_DETECT, &uh->state);
if (test_and_clear_bit(BIT_REQUEST_USB_DETECT, &uh->state))
set_bit(BIT_DO_USB_DETECT, &uh->state);
return;
}
/* Have pending request ? */
static inline int pending_request(struct uh_data *uh)
{
if (test_bit(BIT_REQUEST_CABLE_DETECT, &uh->state) || test_bit(BIT_REQUEST_USB_DETECT, &uh->state))
return 1;
else
return 0;
}
#if defined (HAVE_DETECT_SYNC)
static void prepare_restart(struct uh_data *uh, wait_queue_head_t *wq)
{
D("Called.\n");
if (test_bit(BIT_CABLE_DETECT_DONE, &uh->state))
set_bit(BIT_DO_CABLE_DETECT, &uh->state);
if (test_bit(BIT_USB_DETECT_DONE, &uh->state))
set_bit(BIT_DO_USB_DETECT, &uh->state);
sleep_on_timeout(wq, NR_JIFFIES_SLEEP_BEFORE_RESTART);
sync_seq(uh);
return;
}
/* Called from kernel thread */
static void udc_pnp_detect(struct uh_data *uh)
{
int nr_restart = 0;
D("Do UDC detection.\n");
while (nr_restart != NR_RESTART_TIMES) {
/* Do cable detection ? */
if (test_bit(BIT_DO_CABLE_DETECT, &uh->state)) {
D("Do cable detection.\n");
cable_detect(uh);
}
/* Need restart ? */
if (!is_seq_sync(uh)) {
nr_restart ++;
prepare_restart(uh, &uh->wq);
continue;
}
/* Do USB detection ? */
if (test_bit(BIT_DO_USB_DETECT, &uh->state)) {
D("Do USB detection.\n");
usb_detect(uh);
}
/* Need restart ? */
if (!is_seq_sync(uh)) {
nr_restart ++;
prepare_restart(uh, &uh->wq);
continue;
}
/* Done */
D("Done.\n");
clear_bit(BIT_DO_CABLE_DETECT, &uh->state);
clear_bit(BIT_DO_USB_DETECT, &uh->state);
break;
}
return;
}
static inline void broadcast_event(struct uh_data *uh)
{
/* Sync ? */
if (is_seq_sync(uh)) {
D("Sync -> Broadcast event.\n");
do_broadcast_event(uh);
}else{
D("Not sync -> Prepare restarting.\n");
prepare_restart(uh, &uh->kthread_wq);
}
}
static inline void udc_pnp_thread_sleep(struct uh_data *uh)
{
/* Sync ? -> Sleep. */
if ( !pending_request(uh) || is_seq_sync(uh)) {
D("Sleep.\n");
sleep_on(&uh->kthread_wq);
}
return;
}
#else /* !HAVE_DETECT_SYNC */
/* Called from kernel thread */
static void udc_pnp_detect(struct uh_data *uh)
{
D("Do UDC detection.\n");
/* Do cable detection ? */
if (test_bit(BIT_DO_CABLE_DETECT, &uh->state)) {
D("Do cable detection.\n");
cable_detect(uh);
}
/* Do USB detection ? */
if (test_bit(BIT_DO_USB_DETECT, &uh->state)) {
D("Do USB detection.\n");
usb_detect(uh);
}
/* Done */
D("Done.\n");
clear_bit(BIT_DO_CABLE_DETECT, &uh->state);
clear_bit(BIT_DO_USB_DETECT, &uh->state);
return;
}
static inline void broadcast_event(struct uh_data *uh)
{
D("Broadcast event.\n");
do_broadcast_event(uh);
return;
}
static inline void udc_pnp_thread_sleep(struct uh_data *uh)
{
if (!pending_request(uh)) {
D("Sleep.\n");
sleep_on(&uh->kthread_wq);
}
return;
}
#endif /* HAVE_DETECT_SYNC */
/* Kernel thread */
static int udc_pnp_thread(void *data)
{
struct uh_data *uh = (struct uh_data *)data;
while (!kthread_should_stop()) {
/* Sleep. */
udc_pnp_thread_sleep(uh);
D("Running.\n");
if (kthread_should_stop())
break;
#if defined (HAVE_DETECT_SYNC)
/* Sync */
sync_seq(uh);
#endif
D("Will do UDC detection.\n");
handle_request(uh);
/* Do detect */
udc_pnp_detect(uh);
D("Done.\n");
/* Broadcast event. */
broadcast_event(uh);
}
D("Exit.\n");
return 0;
}
static irqreturn_t udc_pnp_irq(int irq, void *dev_id)
{
struct uh_data *uh = (struct uh_data *)dev_id;
D("called.\n");
/* clear interrupt pending status */
__gpio_ack_irq(UDC_HOTPLUG_PIN);
set_bit(BIT_REQUEST_CABLE_DETECT, &uh->state);
set_bit(BIT_REQUEST_USB_DETECT, &uh->state);
start_detect(uh);
return IRQ_HANDLED;
}
static void __init init_gpio(struct uh_data *uh)
{
/* get current pin level */
__gpio_disable_pull(UDC_HOTPLUG_PIN);
__gpio_as_input(UDC_HOTPLUG_PIN);
udelay(1);
cable_detect(uh);
/* Because of every plug IN/OUT action will casue more than one interrupt,
So whether rising trigger or falling trigger method can both start the detection.
*/
__gpio_as_irq_rise_edge(UDC_HOTPLUG_PIN);
if (test_bit(BIT_CABLE_ONLINE, &uh->state)) {
D("Cable Online -> Do start detection.\n");
set_bit(BIT_REQUEST_CABLE_DETECT, &uh->state);
set_bit(BIT_REQUEST_USB_DETECT, &uh->state);
start_detect(uh);
}else{
D("Cable Offline.\n");
}
return;
}
/* ---------------------------------------------------------------------------------- */
/* Export routines */
static void udc_hotplug_keep_alive_timer_func(unsigned long data)
{
struct uh_data *uh = (struct uh_data *)data;
D("Timer running.\n");
/* Decrease the counter. */
if (test_bit(BIT_KEEP_ALIVE, &uh->state) && !(--uh->keep_alive_counter)) {
if (!usb_is_active()) {
D("Timeout.\n");
set_bit(BIT_KEEP_ALIVE_TIMEOUT, &uh->state);
clear_bit(BIT_USB_ONLINE, &uh->state);
set_bit(BIT_USB_CHANGE, &uh->state);
/* No detection needed. We just want to broadcast our event. */
start_detect(uh);
}
}
/* Set next active time. */
if (test_bit(BIT_KEEP_ALIVE, &uh->state) && !test_bit(BIT_KEEP_ALIVE_TIMEOUT, &uh->state))
mod_timer(&uh->keep_alive_timer, uh->keep_alive_timer_interval + jiffies);
else
D("Timer will stop.\n");
return;
}
int udc_hotplug_register_notifier(struct notifier_block *n, int request_state)
{
struct uh_data *uh = g_puh_data;
udc_hotplug_event_t e;
D("Register notifier: 0x%p.\n", (void *)n);
/* Notifer will be registered is requesting current state. */
if (request_state) {
BUG_ON(!n->notifier_call);
/* Cable State */
e.type = EVENT_TYPE_CABLE;
e.state = (test_bit(BIT_CABLE_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE: EVENT_STATE_OFFLINE;
n->notifier_call(n, BROADCAST_TYPE_STATE, &e);
/* USB State */
e.type = EVENT_TYPE_USB;
e.state = (test_bit(BIT_CABLE_ONLINE, &uh->state)) ? EVENT_STATE_ONLINE: EVENT_STATE_OFFLINE;
n->notifier_call(n, BROADCAST_TYPE_STATE, &e);
}
return blocking_notifier_chain_register(&uh->notifier_head, n);
}EXPORT_SYMBOL(udc_hotplug_register_notifier);
int udc_hotplug_unregister_notifier(struct notifier_block *n)
{
struct uh_data *uh = g_puh_data;
D("Unregister notifier: 0x%p.\n", (void *)n);
return blocking_notifier_chain_unregister(&uh->notifier_head, n);
}EXPORT_SYMBOL(udc_hotplug_unregister_notifier);
/* Start keep alive, 0 - Use default value */
int udc_hotplug_start_keep_alive(unsigned long timer_interval_in_jiffies, unsigned long counter_limit)
{
struct uh_data *uh = g_puh_data;
/* Already started. */
if (test_and_set_bit(BIT_KEEP_ALIVE, &uh->state))
return 0;
if (timer_interval_in_jiffies)
uh->keep_alive_timer_interval = timer_interval_in_jiffies;
else
uh->keep_alive_timer_interval = DEFAULT_KEEP_ALIVE_TIMER_INTERVAL;
if (counter_limit)
uh->keep_alive_counter_limit = counter_limit;
else
uh->keep_alive_counter_limit = DEFAULT_KEEP_ALIVE_COUNTER_LIMIT;
uh->keep_alive_counter = uh->keep_alive_counter_limit;
/* Active our timer. */
return mod_timer(&uh->keep_alive_timer, 3 + jiffies);
}EXPORT_SYMBOL(udc_hotplug_start_keep_alive);
void udc_hotplug_do_keep_alive(void)
{
struct uh_data *uh = g_puh_data;
D("Keep alive.\n");
/* Reset counter */
uh->keep_alive_counter = uh->keep_alive_counter_limit;
/* We are alive again. */
if (test_and_clear_bit(BIT_KEEP_ALIVE_TIMEOUT, &uh->state)) {
D("Reactive timer.\n");
/* Active timer. */
set_bit(BIT_KEEP_ALIVE, &uh->state);
mod_timer(&uh->keep_alive_timer, 3 + jiffies);
}
return;
}EXPORT_SYMBOL(udc_hotplug_do_keep_alive);
void udc_hotplug_stop_keep_alive(void)
{
struct uh_data *uh = g_puh_data;
clear_bit(BIT_KEEP_ALIVE, &uh->state);
return;
}EXPORT_SYMBOL(udc_hotplug_stop_keep_alive);
/* ----------------------------------------------------------------------------- */
/*
* Module init and exit
*/
static int __init udc_hotplug_init(void)
{
struct uh_data *uh;
unsigned long status = 0;
int rv;
g_puh_data = (struct uh_data *)kzalloc(sizeof(struct uh_data), GFP_KERNEL);
if (!g_puh_data) {
printk(KERN_ERR PFX": Failed to allocate memory.\n");
return -ENOMEM;
}
uh = g_puh_data;
set_bit(1, &status);
BLOCKING_INIT_NOTIFIER_HEAD(&uh->notifier_head);
init_waitqueue_head(&uh->kthread_wq);
init_waitqueue_head(&uh->wq);
init_timer(&uh->keep_alive_timer);
uh->keep_alive_timer.function = udc_hotplug_keep_alive_timer_func;
uh->keep_alive_timer.expires = jiffies - 1; /* Add a stopped timer */
uh->keep_alive_timer.data = (unsigned long)uh;
add_timer(&uh->keep_alive_timer);
#if defined (HAVE_DETECT_SYNC)
reset_seq(uh);
#endif
/* Create pnp thread and register IRQ */
uh->kthread = kthread_run(udc_pnp_thread, uh, "kudcd");
if (IS_ERR(uh->kthread)) {
printk(KERN_ERR PFX": Failed to create system monitor thread.\n");
rv = PTR_ERR(uh->kthread);
goto err;
}
set_bit(2, &status);
rv = request_irq(UDC_HOTPLUG_IRQ, udc_pnp_irq, IRQF_DISABLED, "udc_pnp", uh);
if (rv) {
printk(KERN_ERR PFX": Could not get udc hotplug irq %d\n", UDC_HOTPLUG_IRQ);
goto err;
}
init_gpio(uh);
#if defined (HAVE_DETECT_SYNC)
printk(KERN_ERR PFX": Registered(HAVE_DETECT_SYNC).\n");
#else
printk(KERN_ERR PFX": Registered.\n");
#endif
return 0;
err:
if (test_bit(2, &status)) {
kthread_stop(uh->kthread);
}
if (test_bit(1, &status)) {
kfree(g_puh_data);
}
return rv;
}
static void __exit udc_hotplug_exit(void)
{
free_irq(UDC_HOTPLUG_IRQ, g_puh_data);
kthread_stop(g_puh_data->kthread);
kfree(g_puh_data);
return;
}
module_init(udc_hotplug_init);
module_exit(udc_hotplug_exit);
MODULE_AUTHOR("River Wang <zwang@ingenic.cn>");
MODULE_LICENSE("GPL");

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,575 +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/fb.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/jz4740_fb.h>
#include <linux/delay.h>
#include <linux/clk.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_PSM BIT(23)
#define JZ_LCD_CFG_CLSM BIT(22)
#define JZ_LCD_CFG_SPLM BIT(21)
#define JZ_LCD_CFG_REVM BIT(20)
#define JZ_LCD_CFG_HSYNCM BIT(19)
#define JZ_LCD_CFG_PCLKM BIT(18)
#define JZ_LCD_CFG_INV BIT(17)
#define JZ_LCD_CFG_SYNC_DIR BIT(16)
#define JZ_LCD_CFG_PSP BIT(15)
#define JZ_LCD_CFG_CLSP BIT(14)
#define JZ_LCD_CFG_SPLP BIT(13)
#define JZ_LCD_CFG_REVP BIT(12)
#define JZ_LCD_CFG_HSYNCP BIT(11)
#define JZ_LCD_CFG_PCLKP BIT(10)
#define JZ_LCD_CFG_DEP BIT(9)
#define JZ_LCD_CFG_VSYNCP BIT(8)
#define JZ_LCD_CFG_18_BIT BIT(7)
#define JZ_LCD_CFG_PDW BIT(5) | BIT(4)
#define JZ_LCD_CFG_MODE_MASK 0xf
#define JZ_LCD_CTRL_BURST_4 (0x0 << 28)
#define JZ_LCD_CTRL_BURST_8 (0x1 << 28)
#define JZ_LCD_CTRL_BURST_16 (0x2 << 28)
#define JZ_LCD_CTRL_RGB555 BIT(27)
#define JZ_LCD_CTRL_OFUP BIT(26)
#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24)
#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24)
#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24)
#define JZ_LCD_CTRL_PDD_MASK (0xff << 16)
#define JZ_LCD_CTRL_EOF_IRQ BIT(13)
#define JZ_LCD_CTRL_SOF_IRQ BIT(12)
#define JZ_LCD_CTRL_OFU_IRQ BIT(11)
#define JZ_LCD_CTRL_IFU0_IRQ BIT(10)
#define JZ_LCD_CTRL_IFU1_IRQ BIT(9)
#define JZ_LCD_CTRL_DD_IRQ BIT(8)
#define JZ_LCD_CTRL_QDD_IRQ BIT(7)
#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6)
#define JZ_LCD_CTRL_LSB_FISRT BIT(5)
#define JZ_LCD_CTRL_DISABLE BIT(4)
#define JZ_LCD_CTRL_ENABLE BIT(3)
#define JZ_LCD_CTRL_BPP_1 0x0
#define JZ_LCD_CTRL_BPP_2 0x1
#define JZ_LCD_CTRL_BPP_4 0x2
#define JZ_LCD_CTRL_BPP_8 0x3
#define JZ_LCD_CTRL_BPP_15_16 0x4
#define JZ_LCD_CTRL_BPP_18_24 0x5
#define JZ_LCD_CMD_SOF_IRQ BIT(15)
#define JZ_LCD_CMD_EOF_IRQ BIT(16)
#define JZ_LCD_CMD_ENABLE_PAL BIT(12)
#define JZ_LCD_SYNC_MASK 0x3ff
#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;
void *devmem;
size_t devmem_size;
dma_addr_t devmem_phys;
void *vidmem;
size_t vidmem_size;
dma_addr_t vidmem_phys;
struct jzfb_framedesc *framedesc;
struct clk *ldclk;
struct clk *lpclk;
uint32_t pseudo_palette[16];
unsigned is_enabled:1;
};
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_pins[] = {
JZ_GPIO_BULK_PIN(LCD_PCLK),
JZ_GPIO_BULK_PIN(LCD_HSYNC),
JZ_GPIO_BULK_PIN(LCD_VSYNC),
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),
};
int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
unsigned transp, struct fb_info *fb)
{
((uint32_t*)fb->pseudo_palette)[regno] = red << 16 | green << 8 | blue;
return 0;
}
static int jzfb_get_controller_bpp(struct jzfb *jzfb)
{
switch(jzfb->pdata->bpp) {
case 18:
case 24:
return 32;
break;
default:
return jzfb->pdata->bpp;
}
}
static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
{
struct jzfb* jzfb = fb->par;
struct fb_videomode *mode = jzfb->pdata->modes;
int i;
if (fb->var.bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
fb->var.bits_per_pixel != jzfb->pdata->bpp)
return -EINVAL;
for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
if (mode->xres == fb->var.xres && mode->yres == fb->var.yres)
break;
}
if (i == jzfb->pdata->num_modes)
return -EINVAL;
fb_videomode_to_var(&fb->var, fb->mode);
switch (jzfb->pdata->bpp) {
case 8:
break;
case 15:
var->red.offset = 10;
var->red.length = 5;
var->green.offset = 6;
var->green.length = 5;
var->blue.offset = 0;
var->blue.length = 5;
break;
case 16:
var->red.offset = 11;
var->red.length = 5;
var->green.offset = 6;
var->green.length = 6;
var->blue.offset = 0;
var->blue.length = 5;
break;
case 18:
var->red.offset = 16;
var->red.length = 6;
var->green.offset = 8;
var->green.length = 6;
var->blue.offset = 0;
var->blue.length = 6;
fb->var.bits_per_pixel = 32;
break;
case 32:
case 24:
var->transp.offset = 24;
var->transp.length = 8;
var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
fb->var.bits_per_pixel = 32;
break;
default:
break;
}
return 0;
}
static int jzfb_set_par(struct fb_info *info)
{
struct jzfb* jzfb = info->par;
struct fb_var_screeninfo *var = &info->var;
uint16_t hds, vds;
uint16_t hde, vde;
uint16_t ht, vt;
uint32_t ctrl;
hds = var->hsync_len + var->left_margin;
hde = hds + var->xres;
ht = hde + var->right_margin;
vds = var->vsync_len + var->upper_margin;
vde = vds + var->yres;
vt = vde + var->lower_margin;
writel(var->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC);
writel(var->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC);
writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT);
writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH);
writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV);
ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16;
ctrl |= JZ_LCD_CTRL_ENABLE;
switch (jzfb->pdata->bpp) {
case 1:
ctrl |= JZ_LCD_CTRL_BPP_1;
break;
case 2:
ctrl |= JZ_LCD_CTRL_BPP_2;
break;
case 4:
ctrl |= JZ_LCD_CTRL_BPP_4;
break;
case 8:
ctrl |= JZ_LCD_CTRL_BPP_8;
break;
case 15:
ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */
case 16:
ctrl |= JZ_LCD_CTRL_BPP_15_16;
break;
case 18:
case 24:
case 32:
ctrl |= JZ_LCD_CTRL_BPP_18_24;
break;
default:
break;
}
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
return 0;
}
static int jzfb_blank(int blank_mode, struct fb_info *info)
{
struct jzfb* jzfb = info->par;
uint32_t ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
switch (blank_mode) {
case FB_BLANK_UNBLANK:
if (jzfb->is_enabled)
return 0;
jz_gpio_bulk_resume(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
clk_enable(jzfb->ldclk);
clk_enable(jzfb->lpclk);
writel(0, jzfb->base + JZ_REG_LCD_STATE);
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
ctrl |= JZ_LCD_CTRL_ENABLE;
ctrl &= ~JZ_LCD_CTRL_DISABLE;
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
jzfb->is_enabled = 1;
break;
default:
if (!jzfb->is_enabled)
return 0;
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));
clk_disable(jzfb->lpclk);
clk_disable(jzfb->ldclk);
jz_gpio_bulk_suspend(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
jzfb->is_enabled = 0;
break;
}
return 0;
}
static int jzfb_alloc_vidmem(struct jzfb *jzfb)
{
size_t devmem_size;
int max_videosize = 0;
struct fb_videomode *mode = jzfb->pdata->modes;
struct jzfb_framedesc *framedesc;
void *page;
int i;
for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
if (max_videosize < mode->xres * mode->yres)
max_videosize = mode->xres * mode->yres;
}
max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3;
devmem_size = max_videosize + sizeof(struct jzfb_framedesc);
jzfb->devmem_size = devmem_size;
jzfb->devmem = dma_alloc_coherent(&jzfb->pdev->dev,
PAGE_ALIGN(devmem_size),
&jzfb->devmem_phys, GFP_KERNEL);
if (!jzfb->devmem) {
return -ENOMEM;
}
for (page = jzfb->vidmem;
page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
page += PAGE_SIZE) {
SetPageReserved(virt_to_page(page));
}
framedesc = jzfb->devmem + max_videosize;
jzfb->vidmem = jzfb->devmem;
jzfb->vidmem_phys = jzfb->devmem_phys;
framedesc->next = jzfb->devmem_phys + max_videosize;
framedesc->addr = jzfb->devmem_phys;
framedesc->id = 0;
framedesc->cmd = 0;
framedesc->cmd |= max_videosize / 4;
jzfb->framedesc = framedesc;
return 0;
}
static void jzfb_free_devmem(struct jzfb *jzfb)
{
dma_free_coherent(&jzfb->pdev->dev, jzfb->devmem_size, jzfb->devmem,
jzfb->devmem_phys);
}
static struct fb_ops jzfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = jzfb_check_var,
.fb_set_par = jzfb_set_par,
.fb_blank = jzfb_blank,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
.fb_setcolreg = jzfb_setcolreg,
};
static int __devinit jzfb_probe(struct platform_device *pdev)
{
int ret;
struct jzfb *jzfb;
struct fb_info *fb;
struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
struct resource *mem;
if (!pdata) {
dev_err(&pdev->dev, "Missing platform data\n");
return -ENOENT;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "Failed to get register memory resource\n");
return -ENOENT;
}
mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
if (!mem) {
dev_err(&pdev->dev, "Failed to request register memory region\n");
return -EBUSY;
}
fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
if (!fb) {
dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
ret = -ENOMEM;
goto err_release_mem_region;
}
fb->fbops = &jzfb_ops;
fb->flags = FBINFO_DEFAULT;
jzfb = fb->par;
jzfb->pdev = pdev;
jzfb->pdata = pdata;
jzfb->mem = mem;
jzfb->ldclk = clk_get(&pdev->dev, "lcd");
jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
jzfb->is_enabled = 1;
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_vidmem(jzfb);
if (ret) {
dev_err(&pdev->dev, "Failed to allocate video memory\n");
goto err_iounmap;
}
fb->fix = jzfb_fix;
fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
fb->fix.mmio_start = mem->start;
fb->fix.mmio_len = resource_size(mem);
fb->fix.smem_start = jzfb->vidmem_phys;
fb->fix.smem_len = fb->fix.line_length * fb->var.yres;
fb->screen_base = jzfb->vidmem;
fb->pseudo_palette = jzfb->pseudo_palette;
fb_alloc_cmap(&fb->cmap, 256, 0);
jzfb_set_par(fb);
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
jz_gpio_bulk_request(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
ret = register_framebuffer(fb);
if (ret) {
dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
goto err_free_devmem;
}
return 0;
err_free_devmem:
jzfb_free_devmem(jzfb);
err_iounmap:
iounmap(jzfb->base);
err_framebuffer_release:
framebuffer_release(fb);
err_release_mem_region:
release_mem_region(mem->start, resource_size(mem));
return ret;
}
static int __devexit jzfb_remove(struct platform_device *pdev)
{
struct jzfb *jzfb = platform_get_drvdata(pdev);
jz_gpio_bulk_free(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
iounmap(jzfb->base);
release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
jzfb_free_devmem(jzfb);
platform_set_drvdata(pdev, NULL);
framebuffer_release(jzfb->fb);
return 0;
}
static struct platform_driver jzfb_driver = {
.probe = jzfb_probe,
.remove = __devexit_p(jzfb_remove),
.driver = {
.name = "jz4740-fb",
},
};
int __init jzfb_init(void)
{
return platform_driver_register(&jzfb_driver);
}
module_init(jzfb_init);
void __exit jzfb_exit(void)
{
platform_driver_unregister(&jzfb_driver);
}
module_exit(jzfb_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("JZ4720/JZ4740 SoC LCD framebuffer driver");
MODULE_ALIAS("platform:jz4740-fb");
MODULE_ALIAS("platform:jz4720-fb");

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,52 +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_18_BIT = 0,
JZ_LCD_TYPE_SPECIAL_TFT_1 = 1,
JZ_LCD_TYPE_SPECIAL_TFT_2 = 2,
JZ_LCD_TYPE_SPECIAL_TFT_3 = 3,
JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5,
JZ_LCD_TYPE_INTERLACED_CCIR656 = 7,
JZ_LCD_TYPE_SINGLE_COLOR_STN = 8,
JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9,
JZ_LCD_TYPE_DUAL_COLOR_STN = 10,
JZ_LCD_TYPE_8BIT_SERIAL = 11,
};
/*
* width: width of the lcd display in mm
* height: height of the lcd display in mm
* num_modes: size of modes
* modes: list of valid video modes
* bpp: bits per pixel for the lcd
* lcd_type: lcd type
*/
struct jz4740_fb_platform_data {
unsigned int width;
unsigned int height;
size_t num_modes;
struct fb_videomode *modes;
int bpp;
enum jz4740_fb_lcd_type lcd_type;
};
#endif

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) 2009, Jiejing Zhang <kzjeef@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __JZ4740_BATTERY_H
#define __JZ4740_BATTERY_H
struct jz_batt_info {
int dc_dect_gpio; /* GPIO port of DC charger detection */
int usb_dect_gpio; /* GPIO port of USB charger detection */
int charg_stat_gpio; /* GPIO port of Charger state */
int min_voltag; /* Mininal battery voltage in uV */
int max_voltag; /* Maximum battery voltage in uV */
int batt_tech; /* Battery technology */
};
#endif

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_FORMAT_S18_3LE,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_44100,
.formats = SNDRV_PCM_FORMAT_S16_LE,
},
.ops = &jz_codec_dai_ops,
.symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(jz_codec_dai);
static int jz_codec_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
if (codec->bias_level == SND_SOC_BIAS_OFF && level != SND_SOC_BIAS_OFF) {
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_RESET, JZ_CODEC_1_RESET);
udelay(2);
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_SUSPEND | JZ_CODEC_1_RESET, 0);
}
switch (level) {
case SND_SOC_BIAS_ON:
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_VREF_DISABLE | JZ_CODEC_1_VREF_AMP_DISABLE |
JZ_CODEC_1_HEADPHONE_POWER_DOWN_M |
JZ_CODEC_1_VREF_LOW_CURRENT | JZ_CODEC_1_VREF_HIGH_CURRENT,
0);
break;
case SND_SOC_BIAS_PREPARE:
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_VREF_LOW_CURRENT | JZ_CODEC_1_VREF_HIGH_CURRENT,
JZ_CODEC_1_VREF_LOW_CURRENT | JZ_CODEC_1_VREF_HIGH_CURRENT);
break;
case SND_SOC_BIAS_STANDBY:
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_VREF_DISABLE | JZ_CODEC_1_VREF_AMP_DISABLE,
JZ_CODEC_1_VREF_DISABLE | JZ_CODEC_1_VREF_AMP_DISABLE);
break;
case SND_SOC_BIAS_OFF:
snd_soc_update_bits(codec, JZ_REG_CODEC_1,
JZ_CODEC_1_SUSPEND, JZ_CODEC_1_SUSPEND);
break;
}
codec->bias_level = level;
return 0;
}
static struct snd_soc_codec *jz_codec_codec;
static int jz_codec_dev_probe(struct platform_device *pdev)
{
int ret;
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = jz_codec_codec;
BUG_ON(!codec);
socdev->card->codec = codec;
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret) {
dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
goto err;
}
snd_soc_add_controls(codec, jz_codec_controls,
ARRAY_SIZE(jz_codec_controls));
snd_soc_dapm_new_controls(codec, jz_codec_dapm_widgets,
ARRAY_SIZE(jz_codec_dapm_widgets));
snd_soc_dapm_add_routes(codec, jz_codec_dapm_routes,
ARRAY_SIZE(jz_codec_dapm_routes));
snd_soc_dapm_new_widgets(codec);
ret = snd_soc_init_card(socdev);
if (ret) {
dev_err(&pdev->dev, "Failed to register card\n");
goto err;
}
return 0;
err:
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return ret;
}
static int jz_codec_dev_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_jzcodec = {
.probe = jz_codec_dev_probe,
.remove = jz_codec_dev_remove,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_jzcodec);
static int __devinit jz_codec_probe(struct platform_device *pdev)
{
int ret;
struct jz_codec *jz_codec;
struct snd_soc_codec *codec;
jz_codec = kzalloc(sizeof(*jz_codec), GFP_KERNEL);
if (!jz_codec)
return -ENOMEM;
jz_codec->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!jz_codec->mem) {
dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
ret = -ENOENT;
goto err_free_jz_codec;
}
jz_codec->mem = request_mem_region(jz_codec->mem->start,
resource_size(jz_codec->mem), pdev->name);
if (!jz_codec->mem) {
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
ret = -EBUSY;
goto err_free_jz_codec;
}
jz_codec->base = ioremap(jz_codec->mem->start, resource_size(jz_codec->mem));
if (!jz_codec->base) {
dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
ret = -EBUSY;
goto err_release_mem_region;
}
jz_codec_dai.dev = &pdev->dev;
codec = &jz_codec->codec;
codec->dev = &pdev->dev;
codec->name = "jz-codec";
codec->owner = THIS_MODULE;
codec->read = jz_codec_read;
codec->write = jz_codec_write;
codec->set_bias_level = jz_codec_set_bias_level;
codec->bias_level = SND_SOC_BIAS_OFF;
codec->dai = &jz_codec_dai;
codec->num_dai = 1;
codec->reg_cache = jz_codec->reg_cache;
codec->reg_cache_size = 2;
codec->private_data = jz_codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
jz_codec_codec = codec;
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,29 +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_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,15 +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-n526-objs := n526.o
obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
obj-$(CONFIG_SND_JZ4740_SOC_N526) += snd-soc-n526.o

View File

@ -1,552 +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;
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);
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);
}
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, parent);
break;
case JZ4740_I2S_CLKSRC_PLL:
parent = clk_get(NULL, "pll half");
clk_set_parent(i2s->clk, parent);
ret = clk_set_rate(i2s->clk, 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)
return 0;
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);
return 0;
}
static int jz4740_i2s_resume(struct snd_soc_dai *dai)
{
struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
uint32_t conf;
if (!dai->active)
return 0;
clk_enable(i2s->clk);
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,
};
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 = clk_get(&pdev->dev, "i2s");
if (IS_ERR(i2s->clk)) {
ret = PTR_ERR(i2s->clk);
goto err_iounmap;
}
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_put(i2s->clk);
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,342 +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 (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);
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 const 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,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,661 +0,0 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -158,6 +158,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
@@ -661,6 +664,7 @@ endchoice
source "arch/mips/alchemy/Kconfig"
source "arch/mips/basler/excite/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"
@@ -1911,6 +1915,14 @@ config NR_CPUS
source "kernel/time/Kconfig"
+# the value of (max order + 1)
+config FORCE_MAX_ZONEORDER
+ prompt "MAX_ZONEORDER"
+ int
+ default "12"
+ help
+ The max memory that can be allocated = 4KB * 2^(CONFIG_FORCE_MAX_ZONEORDER - 1)
+
#
# Timer Interrupt Frequency Configuration
#
@@ -2182,6 +2194,23 @@ config BINFMT_ELF32
endmenu
+menu "CPU Frequency scaling"
+
+config CPU_FREQ_JZ
+ tristate "CPUfreq driver for JZ CPUs"
+ depends on JZSOC
+ default n
+ help
+ This enables the CPUfreq driver for JZ CPUs.
+
+ If in doubt, say N.
+
+if (CPU_FREQ_JZ)
+source "drivers/cpufreq/Kconfig"
+endif
+
+endmenu
+
menu "Power management options"
config ARCH_HIBERNATION_POSSIBLE
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -180,6 +180,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/
@@ -714,6 +722,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,$@)
@@ -743,6 +757,7 @@ install:
archclean:
@$(MAKE) $(clean)=arch/mips/boot
+ @$(MAKE) $(clean)=arch/mips/boot/compressed
@$(MAKE) $(clean)=arch/mips/lasat
define archhelp
@@ -750,6 +765,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
@@ -57,6 +57,12 @@
#define MACH_MIKROTIK_RB532 0 /* Mikrotik RouterBoard 532 */
#define MACH_MIKROTIK_RB532A 1 /* Mikrotik RouterBoard 532A */
+/*
+ * Valid machtype for group INGENIC
+ */
+#define MACH_INGENIC_JZ4720 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
@@ -127,6 +127,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
*/
@@ -217,6 +223,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/mach-generic/irq.h
+++ b/arch/mips/include/asm/mach-generic/irq.h
@@ -9,7 +9,7 @@
#define __ASM_MACH_GENERIC_IRQ_H
#ifndef NR_IRQS
-#define NR_IRQS 128
+#define NR_IRQS 256
#endif
#ifdef CONFIG_I8259
--- 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/include/asm/suspend.h
+++ b/arch/mips/include/asm/suspend.h
@@ -2,6 +2,9 @@
#define __ASM_SUSPEND_H
static inline int arch_prepare_suspend(void) { return 0; }
+#if defined(CONFIG_PM) && defined(CONFIG_JZSOC)
+extern int jz_pm_init(void);
+#endif
/* References to section boundaries */
extern const void __nosave_begin, __nosave_end;
--- 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_PR4450:
case CPU_BCM3302:
case CPU_CAVIUM_OCTEON:
+ case CPU_JZRISC:
cpu_wait = r4k_wait;
break;
@@ -888,6 +889,23 @@ 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;
+ c->isa_level = MIPS_CPU_ISA_M32R1;
+ c->tlbsize = 32;
+ __cpu_name[cpu] = "Ingenic JZRISC";
+ break;
+ default:
+ panic("Unknown Ingenic Processor ID!");
+ break;
+ }
+}
+
const char *__cpu_name[NR_CPUS];
__cpuinit void cpu_probe(void)
@@ -925,6 +943,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/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -928,6 +928,36 @@ static void __cpuinit probe_pcache(void)
c->dcache.waybit = 0;
break;
+ case CPU_JZRISC:
+ config1 = read_c0_config1();
+ config1 = (config1 >> 22) & 0x07;
+ if (config1 == 0x07)
+ config1 = 10;
+ else
+ config1 = config1 + 11;
+ config1 += 2;
+ icache_size = (1 << config1);
+ c->icache.linesz = 32;
+ c->icache.ways = 4;
+ c->icache.waybit = __ffs(icache_size / c->icache.ways);
+
+ config1 = read_c0_config1();
+ config1 = (config1 >> 13) & 0x07;
+ if (config1 == 0x07)
+ config1 = 10;
+ else
+ config1 = config1 + 11;
+ config1 += 2;
+ dcache_size = (1 << config1);
+ c->dcache.linesz = 32;
+ c->dcache.ways = 4;
+ c->dcache.waybit = __ffs(dcache_size / c->dcache.ways);
+
+ c->dcache.flags = 0;
+ c->options |= MIPS_CPU_PREFETCH;
+
+ break;
+
default:
if (!(config & MIPS_CONF_M))
panic("Don't know how to probe P-caches on this cpu.");
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -52,6 +52,8 @@ void (*_dma_cache_wback)(unsigned long s
void (*_dma_cache_inv)(unsigned long start, unsigned long size);
EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_wback);
+EXPORT_SYMBOL(_dma_cache_inv);
#endif /* CONFIG_DMA_NONCOHERENT */
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -385,6 +385,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,68 +0,0 @@
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -452,4 +452,10 @@ config MTD_NAND_SOCRATES
help
Enables support for NAND Flash chips wired onto Socrates board.
+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
@@ -40,5 +40,6 @@ obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_f
obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
+obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
nand-objs := nand_base.o nand_bbt.o
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -953,29 +953,22 @@ static int nand_read_page_hwecc(struct m
uint8_t *ecc_calc = chip->buffers->ecccalc;
uint8_t *ecc_code = chip->buffers->ecccode;
uint32_t *eccpos = chip->ecc.layout->eccpos;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- chip->ecc.hwctl(mtd, NAND_ECC_READ);
- chip->read_buf(mtd, p, eccsize);
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
- }
- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+ int stat;
for (i = 0; i < chip->ecc.total; i++)
ecc_code[i] = chip->oob_poi[eccpos[i]];
- eccsteps = chip->ecc.steps;
- p = buf;
-
- for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- int stat;
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+ chip->read_buf(mtd, p, eccsize);
stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
if (stat < 0)
mtd->ecc_stats.failed++;
else
mtd->ecc_stats.corrected += stat;
}
+
return 0;
}
@@ -1125,6 +1118,8 @@ static int nand_do_read_ops(struct mtd_i
bufpoi = aligned ? buf : chip->buffers->databuf;
if (likely(sndcmd)) {
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x00, page);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
sndcmd = 0;
}

View File

@ -1,28 +0,0 @@
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2148,6 +2148,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
@@ -126,6 +126,7 @@ obj-$(CONFIG_FB_OMAP) += oma
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
+obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o

View File

@ -1,30 +0,0 @@
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -460,6 +460,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
@@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.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,29 +0,0 @@
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -233,6 +233,17 @@ config ISL29003
This driver can also be built as a module. If so, the module
will be called isl29003.
+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
@@ -20,5 +20,6 @@ obj-$(CONFIG_SGI_GRU) += sgi-gru/
obj-$(CONFIG_HP_ILO) += hpilo.o
obj-$(CONFIG_ISL29003) += isl29003.o
obj-$(CONFIG_C2PORT) += c2port/
+obj-$(CONFIG_JZ4740_ADC) += jz4740-adc.o
obj-y += eeprom/
obj-y += cb710/

View File

@ -1,25 +0,0 @@
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -103,4 +103,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
@@ -28,3 +28,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,28 +0,0 @@
--- 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,26 +0,0 @@
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -93,6 +93,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 && BACKLIGHT_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
@@ -9,6 +9,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,164 +0,0 @@
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -194,7 +194,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,
},
@@ -401,6 +401,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);
}
@@ -2213,6 +2217,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;
@@ -2232,6 +2313,7 @@ static unsigned int serial8250_get_divis
return quot;
}
+#endif
static void
serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -2241,6 +2323,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:
@@ -2273,7 +2358,12 @@ serial8250_set_termios(struct uart_port
* Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old, 0, 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
@@ -2351,6 +2441,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) {
@@ -2385,7 +2479,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,158 +0,0 @@
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -44,6 +44,7 @@ config USB_ARCH_HAS_OHCI
default y if PPC_MPC52xx
# MIPS:
default y if SOC_AU1X00
+ default y if JZSOC
# SH:
default y if CPU_SUBTYPE_SH7720
default y if CPU_SUBTYPE_SH7721
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1857,6 +1857,25 @@ static int hub_port_reset(struct usb_hub
{
int i, status;
+#ifdef CONFIG_SOC_JZ4730
+ /*
+ * On Jz4730, we assume that the first USB port was used as device.
+ * If not, please comment next lines.
+ */
+ if (port1 == 1) {
+ return 0;
+ }
+#endif
+
+#if defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
+ /*
+ * On Jz4740 and Jz4750, the second USB port was used as device.
+ */
+ if (port1 == 2) {
+ return 0;
+ }
+#endif
+
/* Block EHCI CF initialization during the port reset.
* Some companion controllers don't like it when they mix.
*/
@@ -2818,11 +2837,35 @@ static void hub_port_connect_change(stru
le16_to_cpu(hub->descriptor->wHubCharacteristics);
struct usb_device *udev;
int status, i;
+#ifdef CONFIG_JZSOC
+ static char jzhub = 1; /* the hub first to be initialized is jzsoc on-chip hub */
+#endif
dev_dbg (hub_dev,
"port %d, status %04x, change %04x, %s\n",
port1, portstatus, portchange, portspeed (portstatus));
+#ifdef CONFIG_SOC_JZ4730
+ /*
+ * On Jz4730, we assume that the first USB port was used as device.
+ * If not, please comment next lines.
+ */
+ if ((port1 == 1) && (jzhub)) {
+ jzhub = 0;
+ return;
+ }
+#endif
+
+#if defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
+ /*
+ * On Jz4740 and Jz4750, the second USB port was used as device.
+ */
+ if ((port1 == 2) && (jzhub)) {
+ jzhub = 0;
+ return;
+ }
+#endif
+
if (hub->has_indicators) {
set_port_led(hub, port1, HUB_LED_AUTO);
hub->indicator[port1-1] = INDICATOR_AUTO;
--- 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
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
@@ -534,6 +548,10 @@ config USB_DUMMY_HCD
endchoice
+config USB_JZ_UDC_HOTPLUG
+ boolean "Ingenic USB Device Controller Hotplug Support"
+ depends on USB_GADGET_JZ4750
+
config USB_GADGET_DUALSPEED
bool
depends on USB_GADGET
@@ -541,7 +559,6 @@ config USB_GADGET_DUALSPEED
help
Means that gadget drivers should include extra descriptors
and code to handle dual-speed controllers.
-
#
# USB Gadget Drivers
#
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -27,6 +27,9 @@ 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
+
+obj-$(CONFIG_USB_JZ_UDC_HOTPLUG)+= udc_hotplug_core.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
@@ -239,6 +245,9 @@ static inline int usb_gadget_controller_
return 0x23;
else if (gadget_is_langwell(gadget))
return 0x24;
+ else if (gadget_is_jz4740(gadget))
+ return 0x25;
+
return -ENOENT;
}

View File

@ -1,103 +0,0 @@
--- 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
@@ -1748,12 +1748,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
@@ -35,6 +35,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
@@ -13,3 +13,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
@@ -176,3 +176,10 @@ 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.
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -34,6 +34,7 @@ snd-soc-wm9081-objs := wm9081.o
snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
+snd-soc-jzcodec-objs := jzcodec.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
+obj-$(CONFIG_SND_SOC_JZCODEC) += snd-soc-jzcodec.o

View File

@ -1,11 +0,0 @@
--- 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,20 +0,0 @@
--- 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,37 +0,0 @@
--- 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,241 +0,0 @@
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -215,10 +215,10 @@ void snd_soc_jack_free_gpios(struct snd_
#endif
/* codec register bit access */
-int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
- unsigned short mask, unsigned short value);
-int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
- unsigned short mask, unsigned short value);
+int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int mask, unsigned int value);
+int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int mask, unsigned int value);
int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
struct snd_ac97_bus_ops *ops, int num);
@@ -492,8 +492,8 @@ struct soc_mixer_control {
/* enumerated kcontrol */
struct soc_enum {
- unsigned short reg;
- unsigned short reg2;
+ unsigned int reg;
+ unsigned int reg2;
unsigned char shift_l;
unsigned char shift_r;
unsigned int max;
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -500,8 +500,8 @@ static int soc_pcm_hw_params(struct snd_
if (cpu_dai->ops->hw_params) {
ret = cpu_dai->ops->hw_params(substream, params, cpu_dai);
if (ret < 0) {
- printk(KERN_ERR "asoc: interface %s hw params failed\n",
- cpu_dai->name);
+ printk(KERN_ERR "asoc: interface %s hw params failed: %d\n",
+ cpu_dai->name, ret);
goto interface_err;
}
}
@@ -842,7 +842,7 @@ static void snd_soc_instantiate_card(str
* DAIs currently; we can't do this per link since some AC97
* codecs have non-AC97 DAIs.
*/
- if (!ac97)
+ if (!ac97) {
for (i = 0; i < card->num_links; i++) {
found = 0;
list_for_each_entry(dai, &dai_list, list)
@@ -856,6 +856,7 @@ static void snd_soc_instantiate_card(str
return;
}
}
+ }
/* Note that we do not current check for codec components */
@@ -1263,11 +1264,11 @@ EXPORT_SYMBOL_GPL(snd_soc_free_ac97_code
*
* Returns 1 for change else 0.
*/
-int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
- unsigned short mask, unsigned short value)
+int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int mask, unsigned int value)
{
int change;
- unsigned short old, new;
+ unsigned int old, new;
mutex_lock(&io_mutex);
old = snd_soc_read(codec, reg);
@@ -1293,11 +1294,11 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits);
*
* Returns 1 for change else 0.
*/
-int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
- unsigned short mask, unsigned short value)
+int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int mask, unsigned int value)
{
int change;
- unsigned short old, new;
+ unsigned int old, new;
mutex_lock(&io_mutex);
old = snd_soc_read(codec, reg);
@@ -1586,7 +1587,7 @@ int snd_soc_get_enum_double(struct snd_k
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val, bitmask;
+ unsigned int val, bitmask;
for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
@@ -1615,8 +1616,8 @@ int snd_soc_put_enum_double(struct snd_k
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val;
- unsigned short mask, bitmask;
+ unsigned int val;
+ unsigned int mask, bitmask;
for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
@@ -1652,7 +1653,7 @@ int snd_soc_get_value_enum_double(struct
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short reg_val, val, mux;
+ unsigned int reg_val, val, mux;
reg_val = snd_soc_read(codec, e->reg);
val = (reg_val >> e->shift_l) & e->mask;
@@ -1691,8 +1692,8 @@ int snd_soc_put_value_enum_double(struct
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val;
- unsigned short mask;
+ unsigned int val;
+ unsigned int mask;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
@@ -1852,7 +1853,7 @@ int snd_soc_put_volsw(struct snd_kcontro
int max = mc->max;
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- unsigned short val, val2, val_mask;
+ unsigned int val, val2, val_mask;
val = (ucontrol->value.integer.value[0] & mask);
if (invert)
@@ -1958,7 +1959,7 @@ int snd_soc_put_volsw_2r(struct snd_kcon
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
int err;
- unsigned short val, val2, val_mask;
+ unsigned int val, val2, val_mask;
val_mask = mask << shift;
val = (ucontrol->value.integer.value[0] & mask);
@@ -2050,7 +2051,7 @@ int snd_soc_put_volsw_s8(struct snd_kcon
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int reg = mc->reg;
int min = mc->min;
- unsigned short val;
+ unsigned int val;
val = (ucontrol->value.integer.value[0]+min) & 0xff;
val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
@@ -2251,6 +2252,7 @@ int snd_soc_register_dai(struct snd_soc_
if (!dai->ops)
dai->ops = &null_dai_ops;
+
INIT_LIST_HEAD(&dai->list);
mutex_lock(&client_mutex);
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -268,7 +268,7 @@ static int dapm_connect_mixer(struct snd
static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
{
int change, power;
- unsigned short old, new;
+ unsigned int old, new;
struct snd_soc_codec *codec = widget->codec;
/* check for valid widgets */
@@ -1246,7 +1246,6 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_route
/**
* snd_soc_dapm_new_widgets - add new dapm widgets
* @codec: audio codec
- *
* Checks the codec for any new dapm widgets and creates them if found.
*
* Returns 0 for success.
@@ -1336,7 +1335,8 @@ int snd_soc_dapm_get_volsw(struct snd_kc
ucontrol->value.integer.value[0] =
(snd_soc_read(widget->codec, reg) >> shift) & mask;
- if (shift != rshift)
+
+ if (shift != rshift)
ucontrol->value.integer.value[1] =
(snd_soc_read(widget->codec, reg) >> rshift) & mask;
if (invert) {
@@ -1372,7 +1372,7 @@ int snd_soc_dapm_put_volsw(struct snd_kc
int max = mc->max;
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- unsigned short val, val2, val_mask;
+ unsigned int val, val2, val_mask;
int ret;
val = (ucontrol->value.integer.value[0] & mask);
@@ -1436,7 +1436,7 @@ int snd_soc_dapm_get_enum_double(struct
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val, bitmask;
+ unsigned int val, bitmask;
for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
@@ -1464,8 +1464,8 @@ int snd_soc_dapm_put_enum_double(struct
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val, mux;
- unsigned short mask, bitmask;
+ unsigned int val, mux;
+ unsigned int mask, bitmask;
int ret = 0;
for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
@@ -1523,7 +1523,7 @@ int snd_soc_dapm_get_value_enum_double(s
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short reg_val, val, mux;
+ unsigned int reg_val, val, mux;
reg_val = snd_soc_read(widget->codec, e->reg);
val = (reg_val >> e->shift_l) & e->mask;
@@ -1563,8 +1563,8 @@ int snd_soc_dapm_put_value_enum_double(s
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val, mux;
- unsigned short mask;
+ unsigned int val, mux;
+ unsigned int mask;
int ret = 0;
if (ucontrol->value.enumerated.item[0] > e->max - 1)

View File

@ -1,29 +0,0 @@
--- a/drivers/video/fbmem.c 2009-10-05 13:18:19.000000000 +0200
+++ b/drivers/video/fbmem.c 2009-12-03 05:08:15.000000000 +0100
@@ -997,12 +997,12 @@
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) {
@@ -1013,6 +1013,10 @@
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,174 +0,0 @@
diff --git a/drivers/char/defkeymap.map b/drivers/char/defkeymap.map
index 50b30ca..ce141c8 100644
--- 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 underscore backslash
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 braceright asciitilde
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,47 +0,0 @@
From 855326380fbb37b294abceaa10a5596408719f52 Mon Sep 17 00:00:00 2001
From: Xiangfu Liu <xiangfu@qi-hardware.com>
Date: Thu, 26 Nov 2009 16:22:41 +0800
Subject: [PATCH] fix compile zImage
---
arch/mips/boot/compressed/Makefile | 2 +-
arch/mips/boot/compressed/misc.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 9b41329..4a313fd 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -27,7 +27,7 @@ $(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) \
+ -DLOADADDR=$(loadaddr) -I$(srctree)/arch/mips/include \
-c -o $(obj)/head.o $<
$(obj)/vmlinuz: $(OBJS) $(obj)/ld.script $(obj)/vmlinux.bin.gz $(obj)/dummy.o
diff --git a/arch/mips/boot/compressed/misc.c b/arch/mips/boot/compressed/misc.c
index 2309fee..1a3695e 100644
--- a/arch/mips/boot/compressed/misc.c
+++ b/arch/mips/boot/compressed/misc.c
@@ -102,7 +102,7 @@ static unsigned long free_mem_end_ptr;
#define HEAP_SIZE 0x10000
#include "../../../../lib/inflate.c"
-
+#if 0
static void *malloc(int size)
{
void *p;
@@ -124,6 +124,7 @@ static void *malloc(int size)
static void free(void *where)
{ /* Don't care */
}
+#endif
static void gzip_mark(void **ptr)
{
--
1.6.3.3

View File

@ -1,26 +0,0 @@
--- a/drivers/i2c/chips/Kconfig 2009-10-05 13:18:07.000000000 +0200
+++ b/drivers/i2c/chips/Kconfig 2009-12-06 19:10:10.000000000 +0100
@@ -74,4 +74,13 @@
This driver can also be built as a module. If so, the module
will be called tsl2550.
+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 2009-10-05 13:18:07.000000000 +0200
+++ b/drivers/i2c/chips/Makefile 2009-12-06 19:03:47.000000000 +0100
@@ -15,6 +15,7 @@
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_PCF8575) += pcf8575.o
obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.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